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.
6 Update a sledrun JSON page from a detail in a sledrun wikitext page.
8 The following generators and filters are supported:
15 from itertools import takewhile, dropwhile
16 from typing import Optional
19 import mwparserfromhell
20 from mwparserfromhell.nodes.extras import Parameter
23 from mwparserfromhell.nodes import Tag, Text, ExternalLink, Template, Wikilink, Heading
24 from mwparserfromhell.wikicode import Wikicode
25 from pywikibot import pagegenerators, Page
26 from pywikibot.bot import (
27 AutomaticTWSummaryBot,
33 from pywikibot.logging import warning
34 from pywikibot.site._namespace import BuiltinNamespace
35 from wrpylib.json_tools import order_json_keys
37 from wrpylib.wrmwmarkup import create_sledrun_wiki, lonlat_to_json, lonlat_ele_to_json, parse_wrmap
38 from wrpylib.wrvalidators import rodelbahnbox_from_template, tristate_german_to_str, difficulty_german_to_str, \
39 avalanches_german_to_str, public_transport_german_to_str, opt_lonlat_from_str, \
41 from wrpylib.lib_sledrun_wikitext_to_json import optional_set, get_sledrun_description, wikilink_to_json, \
44 docuReplacements = {'¶ms;': pagegenerators.parameterHelp}
47 class UpdateSledrunJsonFromWikiText(
52 AutomaticTWSummaryBot,
54 def setup(self) -> None:
55 schema = Page(self.site, 'Winterrodeln:Datenschema/Rodelbahn/V1.json')
56 assert schema.content_model == 'json'
57 self.sledrun_schema = json.loads(schema.text)
59 def treat_page(self) -> None:
60 """Load the given page, do some changes, and save it."""
61 wikitext_content_model = 'wikitext'
62 if self.current_page.content_model != wikitext_content_model:
63 warning(f"The content model of {self.current_page.title()} is {self.current_page.content_model} "
64 f"instead of {wikitext_content_model}.")
67 wikicode = mwparserfromhell.parse(self.current_page.text)
69 sledrun_json_page = Page(self.site, self.current_page.title() + '/Rodelbahn.json')
70 if not sledrun_json_page.exists():
72 sledrun_json = json.loads(sledrun_json_page.text)
73 sledrun_json_orig = json.loads(sledrun_json_page.text)
74 sledrun_json_orig_text = json.dumps(sledrun_json_orig, ensure_ascii=False, indent=4)
76 for v in wikicode.get_sections(levels=[2], matches='Allgemeines'):
77 def _gastronomy(value: str):
79 line_iter = io.StringIO(value)
80 line = next(line_iter, None)
81 while line is not None and not line.startswith("* '''Hütten''':"):
82 line = next(line_iter, None)
85 line = re.match(r"^\* '''Hütten''':\s*(.*)\s*", line).group(1)
87 line = next(line_iter, '')
88 if not line.startswith('** '):
90 line = re.match(r"^\*\*\s*(.*)\s*", line).group(1)
93 wiki = mwparserfromhell.parse(line)
94 wiki_link = next(wiki.ifilter_wikilinks(), None)
95 if isinstance(wiki_link, Wikilink):
96 g['wr_page'] = wikilink_to_json(wiki_link)
97 ext_link = next(wiki.ifilter_external_links(), None)
98 if isinstance(ext_link, ExternalLink):
99 g['weblink'] = external_link_to_json(ext_link)
100 remaining = str(Wikicode(n for n in wiki.nodes
101 if isinstance(n, (Text, Tag)) and str(n).strip() != '*')).strip()
102 match = re.match(r'(.*)\((.+)\)', remaining)
104 name, note = match.groups()
111 elif len(remaining) > 0 and remaining != '...':
112 g['name'] = remaining
115 line = next(line_iter, '')
116 if not line.startswith('** '):
118 line = re.match(r"^\*\*\s*(.*)\s*", line).group(1)
121 w = _gastronomy(str(v))
123 sledrun_json['gastronomy'] = w
125 jsonschema.validate(instance=sledrun_json, schema=self.sledrun_schema)
126 sledrun_json_ordered = order_json_keys(sledrun_json, self.sledrun_schema)
127 assert sledrun_json_ordered == sledrun_json
128 if sledrun_json == sledrun_json_orig:
130 sledrun_json_text = json.dumps(sledrun_json_ordered, ensure_ascii=False, indent=4)
131 summary = 'Gastronomie Information im Rodelbahn JSON aktualisiert vom Wikitext.'
132 self.userPut(sledrun_json_page, sledrun_json_orig_text, sledrun_json_text, summary=summary, contentmodel='json')
135 def main(*args: str) -> None:
136 local_args = pywikibot.handle_args(args)
137 gen_factory = pagegenerators.GeneratorFactory()
138 gen_factory.handle_args(local_args)
139 gen = gen_factory.getCombinedGenerator(preload=True)
141 bot = UpdateSledrunJsonFromWikiText(generator=gen)
144 pywikibot.bot.suggest_help(missing_generator=True)
147 if __name__ == '__main__':