Kennt ihr auch das Klexikon für Lese-Anfänger? Auf MiniKlexikon.de findet ihr mehr als 900 Artikel von A wie Aal bis Z wie Zoo.
Skripte: Unterschied zwischen den Versionen
Aus Klexikon - Das Freie Kinderlexikon
(+Logbuch, +Kleinigkeiten) |
(+besseres Logbuch, +Testlauf-Option, +Kleinigkeiten) |
||
Zeile 6: | Zeile 6: | ||
import locale | import locale | ||
import datetime | import datetime | ||
+ | |||
+ | # dryrun = True # Ausgabe des Logbuchs in der Konsole ohne Änderungen am Klexikon | ||
+ | dryrun = False # Änderungen werden direkt im Klexikon gespeichert. | ||
# Verwende deutsches Zahlenformat mit Tausenderpunkt und Dezimalkomma | # Verwende deutsches Zahlenformat mit Tausenderpunkt und Dezimalkomma | ||
Zeile 12: | Zeile 15: | ||
# Zuordnung von Wikidata-Abfrage-Feldern zu Vorlage-Parametern | # Zuordnung von Wikidata-Abfrage-Feldern zu Vorlage-Parametern | ||
fieldmap = { | fieldmap = { | ||
− | + | 'Name': 'itemLabel', | |
− | + | 'Flagge': 'safeFlaggenDatei', | |
− | + | 'Hauptstadt': 'hauptstaedte', | |
− | + | 'Amtssprache': 'amtssprachen', | |
− | + | 'Staatsoberhaupt': 'oberhaeupter', | |
− | + | 'Einwohnerzahl': 'max_ew_in_mio', | |
− | + | 'Fläche': 'max_flaeche_rund', | |
− | + | 'Lagekarte': 'safeKartenDatei', | |
− | + | 'Lagebeschreibung': 'kontinente' | |
} | } | ||
# Legt fest, welche Länder-Artikel bzw. Vorlagen-Parameter Klexibot nicht ändern soll | # Legt fest, welche Länder-Artikel bzw. Vorlagen-Parameter Klexibot nicht ändern soll | ||
blacklist = { | blacklist = { | ||
− | + | 'Eidgenossenschaft', | |
− | + | 'Deutsches Kaiserreich', | |
− | + | 'Schottland', | |
− | + | 'Wales' | |
} | } | ||
# Parameter aus dieser Liste werden nur gefüllt, falls bisher kein Wert enthalten war | # Parameter aus dieser Liste werden nur gefüllt, falls bisher kein Wert enthalten war | ||
preserved_values = { | preserved_values = { | ||
− | + | 'Lagekarte', | |
− | + | 'Lagebeschreibung' | |
} | } | ||
Zeile 44: | Zeile 47: | ||
with open('infobox_data_query.rq', 'r') as query_file: qry = query_file.read() | with open('infobox_data_query.rq', 'r') as query_file: qry = query_file.read() | ||
r = requests.get(url, params = {'format': 'json', 'query': qry }, headers = { | r = requests.get(url, params = {'format': 'json', 'query': qry }, headers = { | ||
− | + | 'User-Agent':f'{requests.utils.default_headers()["User-Agent"]} (Klexikon bot by User:Tkarcher)'}) | |
data = r.json() | data = r.json() | ||
− | # Initialisiere | + | # Initialisiere Logbuch-Eintrag |
− | logheader = f'== | + | logheader = f'== Logbuch vom {datetime.datetime.now().strftime("%c")} ==\n' |
− | + | newloghead = '=== Neu angelegte Infoboxen ===\n' | |
− | + | newlogdata = '' | |
− | + | chgloghead = '=== Änderungen an bestehenden Infoboxen ===\n' + \ | |
+ | '{| class="wikitable sortable"\n! Vorlage\n! Eigenschaft\n! Alter Wert\n! Neuer Wert\n' | ||
+ | chglogdata = '' | ||
+ | chglogfoot = '|}\n\n' | ||
# Gehe Wikidata-Tabelle Zeile für Zeile durch | # Gehe Wikidata-Tabelle Zeile für Zeile durch | ||
for item in data['results']['bindings']: | for item in data['results']['bindings']: | ||
− | + | title = item['titel_im_klexikon']['value'] | |
− | + | # Ignoriere Artikel, die in der Ausschlußliste enthalten sind | |
− | + | if title not in blacklist: | |
− | + | # Öffne Vorlagen-Seite oder lege sie neu an | |
− | + | page = pywikibot.Page(site, f'Vorlage:Infobox_{title}') | |
− | + | code = mwparserfromhell.parse(page.text) | |
− | + | # Ersetze Seiteninhalt mit {{Infobox Land}}, falls nicht vorhanden | |
− | + | if not code.filter_templates(matches = lambda n: n.name.matches ('Infobox Land')): | |
− | + | code = mwparserfromhell.parse('{{Infobox Land\n}}') | |
+ | newlogdata += f'* [[Vorlage:Infobox {title}]]\n' | ||
− | + | # Fülle alle Vorlagen-Felder | |
− | + | for prop, field in fieldmap.items(): | |
− | + | # Ignoriere Vorlagen-Parameter, die leer oder in der Ausschlußliste enthalten sind | |
− | + | if field in item and f'{title}:{prop}' not in blacklist: | |
− | + | # Ignoriere auch Parameter, die nicht überschrieben werden sollen | |
− | + | if not ( | |
− | + | prop in preserved_values and | |
− | + | code.filter_templates()[0].has(prop) and | |
− | + | code.filter_templates()[0].get(prop).value.strip() != ''): | |
− | + | oldval = code.filter_templates()[0].get(prop).value.strip() if code.filter_templates()[0].has(prop) else '' | |
− | + | val = item[field]['value'] | |
− | + | if prop == 'Einwohnerzahl': | |
− | + | ew = float(val) | |
− | + | if ew > 1: | |
− | + | val = f'etwa {locale.format_string("%.0f", ew, grouping = True)} [[Million]]en' | |
− | + | else: | |
− | + | val = f'etwa {locale.format_string("%.0f", ew * 1000000, grouping = True)}' | |
− | + | elif prop == 'Fläche': | |
− | + | val = f'etwa {locale.format_string("%i", int(val), grouping = True)} [[Meter|Quadratkilometer]]' | |
− | + | elif prop == 'Staatsoberhaupt': | |
− | + | if 'oberhaupt_bezeichnung' in item: | |
− | + | val = f'{item["oberhaupt_bezeichnung"]["value"]} {val}' | |
− | + | elif prop == 'Lagebeschreibung': | |
− | + | val = f'Wo das Land in {val} liegt' | |
− | + | # Speichere die Änderung nur, wenn sie aus mehr besteht als | |
− | + | # einer geänderten Sortierreihenfolge in der Auslistung | |
− | + | # (SPARQL 1.1 erlaubt kein ORDER BY in GROUP_CONCATs) | |
− | + | if sorted (val) != sorted (oldval): | |
− | + | code.filter_templates()[0].add (f' {prop} ', f' {val}\n', preserve_spacing = False) | |
− | + | if not newlogdata.endswith (f'* [[Vorlage:Infobox {title}]]\n'): | |
+ | chglogdata += f'|- \n| [[Vorlage:Infobox {title}]]\n| {prop}\n| {oldval}\n| {val}\n' | ||
− | + | # Speichere die Änderungen, falls vorhanden, und verschiebe | |
− | + | # Artikel ggf. zurück in Kategorie "ungeprüfte Infobox" | |
− | + | if (page.text != str(code)) and not dryrun: | |
− | + | # Speichere Vorlage | |
− | + | page.text = str(code) | |
− | + | page.save('Automatische Anlage der Länder-Infobox') | |
− | + | # Öffne Länderartikel | |
− | + | page = pywikibot.Page(site, title) | |
− | + | code = mwparserfromhell.parse(page.text) | |
− | + | # Binde Länder-Infobox ein, falls noch nicht geschehen | |
− | + | # Mit "_" und " " wegen https://github.com/earwig/mwparserfromhell/issues/216 | |
− | + | if not code.filter_templates(matches = lambda n: | |
− | + | n.name.matches ({f'Infobox_{title}', f'Infobox {title}'})): | |
− | + | code = mwparserfromhell.parse(f'{{{{Infobox_{title}}}}}\n{str(code)}') | |
− | + | # Lösche [[Kategorie:Artikel mit geprüfter Infobox]], falls vorhanden | |
− | + | if '[[Kategorie:Artikel mit geprüfter Infobox]]' in str(code): | |
− | + | code.remove ('[[Kategorie:Artikel mit geprüfter Infobox]]') | |
− | + | # Füge [[Kategorie:Artikel mit ungeprüfter Infobox]] ein, falls noch nicht geschehen | |
− | + | if '[[Kategorie:Artikel mit ungeprüfter Infobox]]' not in str(code): | |
− | + | code.append ('\n[[Kategorie:Artikel mit ungeprüfter Infobox]]') | |
− | + | # Speichere Länderartikel | |
− | + | page.text = str(code) | |
− | + | page.save('Automatische Einbindung der Länder-Infobox') | |
# Dokumentiere Änderungen in Logbuch | # Dokumentiere Änderungen in Logbuch | ||
− | page = pywikibot.Page(site, 'Benutzer:Klexibot/Logbuch') | + | log = \ |
− | page.text += | + | logheader + \ |
− | page.save('Logbuch aktualisiert') | + | newloghead + (newlogdata if newlogdata != '' else 'Es wurden keine neuen Infoboxen angelegt.\n') + \ |
+ | chgloghead + (chglogdata if chglogdata != '' else '|- \n| colspan=4 | Es wurden keine bestehenden Daten geändert.\n') + chglogfoot | ||
+ | |||
+ | if dryrun: | ||
+ | print (log) | ||
+ | else: | ||
+ | page = pywikibot.Page(site, 'Benutzer:Klexibot/Logbuch') | ||
+ | page.text += log | ||
+ | page.save('Logbuch aktualisiert') | ||
</syntaxhighlight> | </syntaxhighlight> |
Version vom 12. April 2019, 22:39 Uhr
Skript zur Aktualisierung der Länder-Infoboxen
import requests import pywikibot import mwparserfromhell import locale import datetime # dryrun = True # Ausgabe des Logbuchs in der Konsole ohne Änderungen am Klexikon dryrun = False # Änderungen werden direkt im Klexikon gespeichert. # Verwende deutsches Zahlenformat mit Tausenderpunkt und Dezimalkomma locale.setlocale(locale.LC_ALL, 'german') # Zuordnung von Wikidata-Abfrage-Feldern zu Vorlage-Parametern fieldmap = { 'Name': 'itemLabel', 'Flagge': 'safeFlaggenDatei', 'Hauptstadt': 'hauptstaedte', 'Amtssprache': 'amtssprachen', 'Staatsoberhaupt': 'oberhaeupter', 'Einwohnerzahl': 'max_ew_in_mio', 'Fläche': 'max_flaeche_rund', 'Lagekarte': 'safeKartenDatei', 'Lagebeschreibung': 'kontinente' } # Legt fest, welche Länder-Artikel bzw. Vorlagen-Parameter Klexibot nicht ändern soll blacklist = { 'Eidgenossenschaft', 'Deutsches Kaiserreich', 'Schottland', 'Wales' } # Parameter aus dieser Liste werden nur gefüllt, falls bisher kein Wert enthalten war preserved_values = { 'Lagekarte', 'Lagebeschreibung' } # Anmeldung beim Klexikon site = pywikibot.Site() # Lade Wikidata-Tabelle und speichere sie in "data"-Variable url = 'https://query.wikidata.org/sparql' with open('infobox_data_query.rq', 'r') as query_file: qry = query_file.read() r = requests.get(url, params = {'format': 'json', 'query': qry }, headers = { 'User-Agent':f'{requests.utils.default_headers()["User-Agent"]} (Klexikon bot by User:Tkarcher)'}) data = r.json() # Initialisiere Logbuch-Eintrag logheader = f'== Logbuch vom {datetime.datetime.now().strftime("%c")} ==\n' newloghead = '=== Neu angelegte Infoboxen ===\n' newlogdata = '' chgloghead = '=== Änderungen an bestehenden Infoboxen ===\n' + \ '{| class="wikitable sortable"\n! Vorlage\n! Eigenschaft\n! Alter Wert\n! Neuer Wert\n' chglogdata = '' chglogfoot = '|}\n\n' # Gehe Wikidata-Tabelle Zeile für Zeile durch for item in data['results']['bindings']: title = item['titel_im_klexikon']['value'] # Ignoriere Artikel, die in der Ausschlußliste enthalten sind if title not in blacklist: # Öffne Vorlagen-Seite oder lege sie neu an page = pywikibot.Page(site, f'Vorlage:Infobox_{title}') code = mwparserfromhell.parse(page.text) # Ersetze Seiteninhalt mit {{Infobox Land}}, falls nicht vorhanden if not code.filter_templates(matches = lambda n: n.name.matches ('Infobox Land')): code = mwparserfromhell.parse('{{Infobox Land\n}}') newlogdata += f'* [[Vorlage:Infobox {title}]]\n' # Fülle alle Vorlagen-Felder for prop, field in fieldmap.items(): # Ignoriere Vorlagen-Parameter, die leer oder in der Ausschlußliste enthalten sind if field in item and f'{title}:{prop}' not in blacklist: # Ignoriere auch Parameter, die nicht überschrieben werden sollen if not ( prop in preserved_values and code.filter_templates()[0].has(prop) and code.filter_templates()[0].get(prop).value.strip() != ''): oldval = code.filter_templates()[0].get(prop).value.strip() if code.filter_templates()[0].has(prop) else '' val = item[field]['value'] if prop == 'Einwohnerzahl': ew = float(val) if ew > 1: val = f'etwa {locale.format_string("%.0f", ew, grouping = True)} [[Million]]en' else: val = f'etwa {locale.format_string("%.0f", ew * 1000000, grouping = True)}' elif prop == 'Fläche': val = f'etwa {locale.format_string("%i", int(val), grouping = True)} [[Meter|Quadratkilometer]]' elif prop == 'Staatsoberhaupt': if 'oberhaupt_bezeichnung' in item: val = f'{item["oberhaupt_bezeichnung"]["value"]} {val}' elif prop == 'Lagebeschreibung': val = f'Wo das Land in {val} liegt' # Speichere die Änderung nur, wenn sie aus mehr besteht als # einer geänderten Sortierreihenfolge in der Auslistung # (SPARQL 1.1 erlaubt kein ORDER BY in GROUP_CONCATs) if sorted (val) != sorted (oldval): code.filter_templates()[0].add (f' {prop} ', f' {val}\n', preserve_spacing = False) if not newlogdata.endswith (f'* [[Vorlage:Infobox {title}]]\n'): chglogdata += f'|- \n| [[Vorlage:Infobox {title}]]\n| {prop}\n| {oldval}\n| {val}\n' # Speichere die Änderungen, falls vorhanden, und verschiebe # Artikel ggf. zurück in Kategorie "ungeprüfte Infobox" if (page.text != str(code)) and not dryrun: # Speichere Vorlage page.text = str(code) page.save('Automatische Anlage der Länder-Infobox') # Öffne Länderartikel page = pywikibot.Page(site, title) code = mwparserfromhell.parse(page.text) # Binde Länder-Infobox ein, falls noch nicht geschehen # Mit "_" und " " wegen https://github.com/earwig/mwparserfromhell/issues/216 if not code.filter_templates(matches = lambda n: n.name.matches ({f'Infobox_{title}', f'Infobox {title}'})): code = mwparserfromhell.parse(f'{{{{Infobox_{title}}}}}\n{str(code)}') # Lösche [[Kategorie:Artikel mit geprüfter Infobox]], falls vorhanden if '[[Kategorie:Artikel mit geprüfter Infobox]]' in str(code): code.remove ('[[Kategorie:Artikel mit geprüfter Infobox]]') # Füge [[Kategorie:Artikel mit ungeprüfter Infobox]] ein, falls noch nicht geschehen if '[[Kategorie:Artikel mit ungeprüfter Infobox]]' not in str(code): code.append ('\n[[Kategorie:Artikel mit ungeprüfter Infobox]]') # Speichere Länderartikel page.text = str(code) page.save('Automatische Einbindung der Länder-Infobox') # Dokumentiere Änderungen in Logbuch log = \ logheader + \ newloghead + (newlogdata if newlogdata != '' else 'Es wurden keine neuen Infoboxen angelegt.\n') + \ chgloghead + (chglogdata if chglogdata != '' else '|- \n| colspan=4 | Es wurden keine bestehenden Daten geändert.\n') + chglogfoot if dryrun: print (log) else: page = pywikibot.Page(site, 'Benutzer:Klexibot/Logbuch') page.text += log page.save('Logbuch aktualisiert')