]> ToastFreeware Gitweb - philipp/winterrodeln/wrpylib.git/blob - bots/sledrun_wikitext_to_json.py
Further work on parsing (now a map is parsed).
[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             "description": "Holadrio!",
78         }
79
80
81         rbb_list = wikicode.filter_templates(recursive=False, matches=lambda t: t.name.strip() == 'Rodelbahnbox')
82         if len(rbb_list) == 1:
83             rbb = rodelbahnbox_from_template(rbb_list[0])
84             v = rbb['Bild']
85             if v is not None:
86                 image_page = Page(self.site, v, ns=BuiltinNamespace.FILE)
87                 if image_page.exists():
88                     warning(f"{image_page.title()} does not exist.")
89                 sledrun_json['image'] = v
90
91             v = rbb['Länge']
92             if v is not None:
93                 sledrun_json['length'] = v
94
95             v = rbb['Schwierigkeit']
96             if v is not None:
97                 sledrun_json['difficulty'] = difficulty_german_to_str(v)
98
99             v = rbb['Lawinen']
100             if v is not None:
101                 sledrun_json['avalanches'] = avalanches_german_to_str(v)
102
103             v, w = rbb['Betreiber']
104             if v is not None:
105                 sledrun_json['has_operator'] = v
106             if w is not None:
107                 sledrun_json['operator'] = w
108
109             v = rbb['Aufstieg möglich']
110             if v is not None:
111                 sledrun_json['walkup_possible'] = v
112
113             v, w = rbb['Aufstieg getrennt']
114             if v is not None:
115                 sledrun_json['walkup_separate'] = tristate_german_to_str(v)
116             if w is not None:
117                 sledrun_json['walkup_comment'] = w  # TODO
118
119             v = rbb['Gehzeit']
120             if v is not None:
121                 sledrun_json['walkup_time'] = v
122
123             v, w = rbb['Beleuchtungsanlage']
124             if v is not None:
125                 sledrun_json['nightlight_possible'] = tristate_german_to_str(v)
126             if w is not None:
127                 sledrun_json['nightlight_description'] = w
128
129             v = rbb['Rodelverleih']
130             if v is not None:
131                 sledrun_json['sled_rental_direct'] = v != []
132                 sledrun_json['sled_rental_description'] = opt_str_opt_comment_enum_to_str(v)
133
134             v = rbb['In Übersichtskarte']
135             if v is not None:
136                 sledrun_json['show_in_overview'] = v
137
138             v = rbb['Forumid']
139             if v is not None:
140                 sledrun_json['forum_id'] = v
141
142             v = rbb['Position']
143             if v is not None:
144                 sledrun_json['position'] = lonlat_to_json(v)
145
146             v = lonlat_ele_to_json(rbb['Position oben'], rbb['Höhe oben'])
147             if v != {}:
148                 sledrun_json['top'] = v
149
150             v = lonlat_ele_to_json(rbb['Position unten'], rbb['Höhe unten'])
151             if v != {}:
152                 sledrun_json['bottom'] = v
153
154             v = rbb['Telefonauskunft']
155             if v is not None:
156                 sledrun_json['info_phone'] = [{'phone': p, 'name': n} for p, n in v]
157
158             v = rbb['Öffentliche Anreise']
159             if v is not None:
160                 sledrun_json['public_transport'] = public_transport_german_to_str(v)
161
162         text = create_sledrun_wiki(sledrun_json, map_json)
163         summary = 'Rodelbahnbeschreibung nach Konvertierung nach und von JSON.'
164         self.put_current(text, summary=summary)
165
166
167 def main(*args: str) -> None:
168     local_args = pywikibot.handle_args(args)
169     gen_factory = pagegenerators.GeneratorFactory()
170     gen_factory.handle_args(local_args)
171     gen = gen_factory.getCombinedGenerator(preload=True)
172     if gen:
173         bot = SledrunWikiTextToJsonBot(generator=gen)
174         bot.run()
175     else:
176         pywikibot.bot.suggest_help(missing_generator=True)
177
178
179 if __name__ == '__main__':
180     main()