Benutzer:Klexibot/Skripte: Unterschied zwischen den Versionen

Aus Klexikon – das Kinderlexikon
(Lagebeschreibung jetzt mit Kontinent, Blacklist um Schottland und Wales erweitert, + Kleinigkeiten)
(+Logbuch, +Kleinigkeiten)
Zeile 5: Zeile 5:
import mwparserfromhell
import mwparserfromhell
import locale
import locale
import datetime


# Verwende deutsches Zahlenformat mit Tausenderpunkt und Dezimalkomma
# Verwende deutsches Zahlenformat mit Tausenderpunkt und Dezimalkomma
locale.setlocale(locale.LC_NUMERIC, 'german')
locale.setlocale(locale.LC_ALL, 'german')


# Zuordnung von Wikidata-Abfrage-Feldern zu Vorlage-Parametern
# Zuordnung von Wikidata-Abfrage-Feldern zu Vorlage-Parametern
Zeile 45: Zeile 46:
     'User-Agent':f'{requests.utils.default_headers()["User-Agent"]} (Klexikon bot by User:Tkarcher)'})
     'User-Agent':f'{requests.utils.default_headers()["User-Agent"]} (Klexikon bot by User:Tkarcher)'})
data = r.json()
data = r.json()
# Initialisiere Log-Tabelle
logheader = f'== Änderungen vom {datetime.datetime.now().strftime("%c")} ==\n' + \
    '{| class="wikitable sortable"\n! Vorlage\n! Eigenschaft\n! Alter Wert\n! Neuer Wert\n'
logcontent = ''
logfooter = '|}\n\n'


# Gehe Wikidata-Tabelle Zeile für Zeile durch
# Gehe Wikidata-Tabelle Zeile für Zeile durch
Zeile 73: Zeile 80:
                     code.filter_templates()[0].get(prop).value != ''):
                     code.filter_templates()[0].get(prop).value != ''):


                    oldval = code.filter_templates()[0].get(prop).value.strip()
                    val = item[field]['value']
                     if prop == 'Einwohnerzahl':
                     if prop == 'Einwohnerzahl':
                         ew = float(item[field]['value'])
                         ew = float(val)
                         if ew > 1:
                         if ew > 1:
                             val = f'etwa {locale.format_string("%.0f", ew, grouping = True)} [[Million]]en'
                             val = f'etwa {locale.format_string("%.0f", ew, grouping = True)} [[Million]]en'
Zeile 80: Zeile 89:
                             val = f'etwa {locale.format_string("%.0f", ew * 1000000, grouping = True)}'
                             val = f'etwa {locale.format_string("%.0f", ew * 1000000, grouping = True)}'
                     elif prop == 'Fläche':
                     elif prop == 'Fläche':
                         val = locale.format_string('%i', int(item[field]['value']), grouping = True)
                         val = f'etwa {locale.format_string("%i", int(val), grouping = True)} [[Meter|Quadratkilometer]]'
                        val = f'etwa {val} [[Meter|Quadratkilometer]]'
                     elif prop == 'Staatsoberhaupt':
                     elif prop == 'Staatsoberhaupt':
                         if 'oberhaupt_bezeichnung' in item:
                         if 'oberhaupt_bezeichnung' in item:
                             val = item['oberhaupt_bezeichnung']['value'] + ' ' + item[field]['value']
                             val = f'{item["oberhaupt_bezeichnung"]["value"]} {val}'
                        else:
                            val = item[field]['value']
                     elif prop == 'Lagebeschreibung':
                     elif prop == 'Lagebeschreibung':
                         val = f'Wo das Land in {item[field]["value"]} liegt'
                         val = f'Wo das Land in {val} liegt'
                     else: val = item[field]['value']
 
                    code.filter_templates()[0].add(
                    # Speichere die Änderung nur, wenn sie aus mehr besteht als
                        f' {prop} ', f' {val}\n', preserve_spacing = False)
                    # 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)
                        logcontent += f'|- \n| [[Infobox {title}]]\n| {prop}\n| {oldval}\n| {val}\n'


         # Speichere die Änderungen, falls vorhanden, und verschiebe
         # Speichere die Änderungen, falls vorhanden, und verschiebe
Zeile 122: Zeile 132:
             page.text = str(code)
             page.text = str(code)
             page.save('Automatische Einbindung der Länder-Infobox (erste 12 Länder)')
             page.save('Automatische Einbindung der Länder-Infobox (erste 12 Länder)')
# Dokumentiere Änderungen in Logbuch
page = pywikibot.Page(site, 'Benutzer:Klexibot/Logbuch')
page.text += logheader + logcontent + logfooter
page.save('Logbuch aktualisiert')
</syntaxhighlight>
</syntaxhighlight>

Version vom 10. April 2019, 22:01 Uhr

Skript zur Aktualisierung der Länder-Infoboxen

import requests
import pywikibot
import mwparserfromhell
import locale
import datetime

# 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 Log-Tabelle
logheader = f'== Änderungen vom {datetime.datetime.now().strftime("%c")} ==\n' + \
    '{| class="wikitable sortable"\n! Vorlage\n! Eigenschaft\n! Alter Wert\n! Neuer Wert\n'
logcontent = ''
logfooter = '|}\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}}')

        # 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 != ''):

                    oldval = code.filter_templates()[0].get(prop).value.strip()
                    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)
                        logcontent += f'|- \n| [[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):

            # Speichere Vorlage
            page.text = str(code)
            page.save('Automatische Anlage der Länder-Infobox (erste 12 Länder)')

            # Ö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 (erste 12 Länder)')

# Dokumentiere Änderungen in Logbuch
page = pywikibot.Page(site, 'Benutzer:Klexibot/Logbuch')
page.text += logheader + logcontent + logfooter
page.save('Logbuch aktualisiert')