]> ToastFreeware Gitweb - philipp/winterrodeln/wrpylib.git/blob - bots/sledrun_wikitext_to_json.py
b7ba7a70e18b5f3d256455bf4d0952a82df818ff
[philipp/winterrodeln/wrpylib.git] / bots / sledrun_wikitext_to_json.py
1 #!/usr/bin/python
2 """
3 User script for pywikibot (https://gerrit.wikimedia.org/r/pywikibot/core.git), tested with version 6.6.1.
4 Put it in directory scripts/userscripts.
5
6 Create a sledrun JSON page from a sledrun wikitext page (including map).
7
8 The following generators and filters are supported:
9
10 &params;
11 """
12 import json
13
14 import mwparserfromhell
15 import pywikibot
16 from pywikibot import pagegenerators, Page
17 from pywikibot.bot import (
18     AutomaticTWSummaryBot,
19     ConfigParserBot,
20     ExistingPageBot,
21     NoRedirectPageBot,
22     SingleSiteBot,
23 )
24 from pywikibot.logging import warning
25 from pywikibot.site._namespace import BuiltinNamespace
26
27 from wrpylib.wrmwmarkup import create_sledrun_wiki, lonlat_to_json, lonlat_ele_to_json, parse_wrmap
28 from wrpylib.wrvalidators import rodelbahnbox_from_template, tristate_german_to_str, difficulty_german_to_str, \
29     avalanches_german_to_str, public_transport_german_to_str, opt_str_opt_comment_enum_to_str
30
31 from pywikibot.site import Namespace
32
33 docuReplacements = {'&params;': pagegenerators.parameterHelp}
34
35
36 class SledrunWikiTextToJsonBot(
37     SingleSiteBot,
38     ConfigParserBot,
39     ExistingPageBot,
40     NoRedirectPageBot,
41     AutomaticTWSummaryBot,
42 ):
43     def treat_page(self) -> None:
44         """Load the given page, do some changes, and save it."""
45         wikitext_content_model = 'wikitext'
46         if self.current_page.content_model != wikitext_content_model:
47             warning(f"The content model of {self.current_page.title()} is {self.current_page.content_model} "
48                     f"instead of {wikitext_content_model}.")
49             return
50
51         wikicode = mwparserfromhell.parse(self.current_page.text)
52         wikilink_list = wikicode.filter_wikilinks()
53         category_sledrun = 'Kategorie:Rodelbahn'
54         if sum(1 for c in wikilink_list if c.title == category_sledrun) == 0:
55             warning(f'The page {self.current_page.title()} does not have category {category_sledrun}.')
56             return
57
58         sledrun_json_page = Page(self.site, self.current_page.title() + '/Rodelbahn.json')
59         if sledrun_json_page.exists():
60             warning(f"{sledrun_json_page.title()} already exists, skipping {self.current_page.title()}.")
61             return
62
63         map_json_page = Page(self.site, self.current_page.title() + '/Landkarte.json')
64         if map_json_page.exists():
65             warning(f"{map_json_page.title()} already exists, skipping {self.current_page.title()}.")
66             return
67
68         map_json = None
69         v = wikicode.filter_tags(matches='wrmap')
70         if len(v) > 0:
71             map_json = parse_wrmap(str(v[0]))
72
73         sledrun_json = {
74             "name": self.current_page.title(),
75             "aliases": [],
76             "entry_under_construction": sum(1 for c in wikilink_list if c.text == 'Kategorie:In Arbeit') > 0,
77         }
78
79         for v in wikicode.get_sections(levels=[2], matches='Allgemeines'):
80             for w in v.ifilter_text(recursive=False):
81                 x = w.strip()
82                 if x:
83                     sledrun_json["description"] = str(x)
84                     break
85             break
86
87         rbb_list = wikicode.filter_templates(recursive=False, matches=lambda t: t.name.strip() == 'Rodelbahnbox')
88         if len(rbb_list) == 1:
89             rbb = rodelbahnbox_from_template(rbb_list[0])
90             v = rbb['Bild']
91             if v is not None:
92                 image_page = Page(self.site, v, ns=BuiltinNamespace.FILE)
93                 if not image_page.exists():
94                     warning(f"{image_page.title()} does not exist.")
95                 sledrun_json['image'] = v
96
97             v = rbb['Länge']
98             if v is not None:
99                 sledrun_json['length'] = v
100
101             v = rbb['Schwierigkeit']
102             if v is not None:
103                 sledrun_json['difficulty'] = difficulty_german_to_str(v)
104
105             v = rbb['Lawinen']
106             if v is not None:
107                 sledrun_json['avalanches'] = avalanches_german_to_str(v)
108
109             v, w = rbb['Betreiber']
110             if v is not None:
111                 sledrun_json['has_operator'] = v
112             if w is not None:
113                 sledrun_json['operator'] = w
114
115             v = rbb['Aufstieg möglich']
116             if v is not None:
117                 sledrun_json['walkup_possible'] = v
118
119             v, w = rbb['Aufstieg getrennt']
120             if v is not None:
121                 sledrun_json['walkup_separate'] = tristate_german_to_str(v)
122             if w is not None:
123                 sledrun_json['walkup_comment'] = w  # TODO
124
125             v = rbb['Gehzeit']
126             if v is not None:
127                 sledrun_json['walkup_time'] = v
128
129             v, w = rbb['Beleuchtungsanlage']
130             if v is not None:
131                 sledrun_json['nightlight_possible'] = tristate_german_to_str(v)
132             if w is not None:
133                 sledrun_json['nightlight_description'] = w
134
135             v = rbb['Rodelverleih']
136             if v is not None:
137                 sledrun_json['sled_rental_direct'] = v != []
138                 sledrun_json['sled_rental_description'] = opt_str_opt_comment_enum_to_str(v)
139
140             v = rbb['In Übersichtskarte']
141             if v is not None:
142                 sledrun_json['show_in_overview'] = v
143
144             v = rbb['Forumid']
145             if v is not None:
146                 sledrun_json['forum_id'] = v
147
148             v = rbb['Position']
149             if v is not None:
150                 sledrun_json['position'] = lonlat_to_json(v)
151
152             v = lonlat_ele_to_json(rbb['Position oben'], rbb['Höhe oben'])
153             if v != {}:
154                 sledrun_json['top'] = v
155
156             v = lonlat_ele_to_json(rbb['Position unten'], rbb['Höhe unten'])
157             if v != {}:
158                 sledrun_json['bottom'] = v
159
160             v = rbb['Telefonauskunft']
161             if v is not None:
162                 sledrun_json['info_phone'] = [{'phone': p, 'name': n} for p, n in v]
163
164             v = rbb['Öffentliche Anreise']
165             if v is not None:
166                 sledrun_json['public_transport'] = public_transport_german_to_str(v)
167
168         text = create_sledrun_wiki(sledrun_json, map_json)
169         summary = 'Rodelbahnbeschreibung nach Konvertierung nach und von JSON.'
170         self.put_current(text, summary=summary)
171
172
173 def main(*args: str) -> None:
174     local_args = pywikibot.handle_args(args)
175     gen_factory = pagegenerators.GeneratorFactory()
176     gen_factory.handle_args(local_args)
177     gen = gen_factory.getCombinedGenerator(preload=True)
178     if gen:
179         bot = SledrunWikiTextToJsonBot(generator=gen)
180         bot.run()
181     else:
182         pywikibot.bot.suggest_help(missing_generator=True)
183
184
185 if __name__ == '__main__':
186     main()