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