Gebruiker:Wikiwernerbot/Kroeg archieflinks.py

Uit Wikipedia, de vrije encyclopedie
import pywikibot
import re
import datetime
site = pywikibot.Site()

maanden = ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec']
tijdstempelre = re.compile(r'(\d\d?) (jan|feb|mrt|apr|mei|ju[nl]|aug|sep|okt|nov|dec) (\d{4}) (\d\d):(\d\d)')
kopjere = re.compile(r'^(=+).+\1\ *$', re.MULTILINE)

def whenplaced(titel, link):
    page = pywikibot.Page(site, titel)
    linkstart = page.text.find(link)
    tijdstempelmatch = tijdstempelre.search(page.text, linkstart)
    kopmatch = kopjere.search(page.text, linkstart)
    if not tijdstempelmatch:
        print('Geen tijdstempel gevonden na de link.')
        return None
    # Het tijdstempel moet eerder komen dan het volgende kopje:
    if kopmatch and tijdstempelmatch.start() > kopmatch.start():
        print('Het tijdstempel komt na het volgende kopje.')
        return None
    print(tijdstempelmatch.group(0))
    return tijdstempelmatch.group(0)

geschre = re.compile(r'(\d+) \|\| ([^|]*) \|\| ([^|]*) \|\| (.*)')
archiefre = re.compile(r'Wikipedia:De kroeg/Archief[/ ]\d{8}')
utcre = re.compile(r'(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)')

def zoekarchieflink(kopje, tijdstempel):
    m = tijdstempelre.search(tijdstempel)
    dag = int(m.group(1))
    maand = maanden.index(m.group(2)) + 1
    jaar = int(m.group(3))
    uur = int(m.group(4))
    minuut = int(m.group(5))
    signtijd = datetime.datetime(jaar, maand, dag, uur, minuut)
    iszomertijd = True # Nodig bij {{Afz}}, want daar staat soms geen (CE(S)T).
    if maand in [1, 2, 11, 12]:
        iszomertijd = False
    elif maand == 3:
        March31 = datetime.datetime(jaar, 3, 31, 2, 0, 0)
        if March31.weekday() == 6:
            startzomertijd = March31
        else:
            startzomertijd = March31 - datetime.timedelta(days = March31.weekday() + 1)
        if signtijd < startzomertijd:
            iszomertijd = False
    elif maand == 10:
        October31 = datetime.datetime(jaar, 10, 31, 3, 0, 0)
        if October31.weekday() == 6:
            eindzomertijd = October31
        else:
            eindzomertijd = October31 - datetime.timedelta(days = October31.weekday() + 1)
        if signtijd >= eindzomertijd:
            iszomertijd = False
    if iszomertijd:
        signtijdUTC = signtijd - datetime.timedelta(hours = 2)
    else:
        signtijdUTC = signtijd - datetime.timedelta(hours = 1)
    geschregels = kroeggesch.split('\n|----\n')
    geschregels.pop(0) # Kopregels overslaan.
    for r in range(len(geschregels)):
        utcstempel = geschre.search(geschregels[r]).group(2)
        m = utcre.search(utcstempel)
        jaar = int(m.group(1))
        maand = int(m.group(2))
        dag = int(m.group(3))
        uur = int(m.group(4))
        minuut = int(m.group(5))
        versietijdUTC = datetime.datetime(jaar, maand, dag, uur, minuut)
        if versietijdUTC < signtijdUTC:
            break
    while r > 0:
        geschmatch = geschre.search(geschregels[r])
        oudeversie = kroeg.getOldVersion(int(geschmatch.group(1)))
        esckopje = re.escape(kopje)
        if oudeversie and not re.search(r'^(=+) *' + esckopje + r' *\1 *$', oudeversie, re.MULTILINE):
            break # De eerste voorwaarde is nodig voor verborgen versies.
        if oudeversie and re.search(r'^(=+) *' + esckopje + r' *\1 *\n.*\n(=+) *' + esckopje + r' *\2 *$', oudeversie, re.DOTALL|re.MULTILINE):
            print('Het kopje ' + kopje + ' komt meermaals voor in versie ' + geschmatch.group(1) + '.')
            return None
        r -= 1
    else:
        print('Geen archivering gevonden. Nog aanwezig in de huidige versie van De kroeg?')
        return None
    if geschmatch.group(3) in ['Nlwikibots', 'Erwin85TBot']:
        archiefmatch = archiefre.search(geschmatch.group(4))
        if archiefmatch:
            print('Archivering gevonden op oldid', geschmatch.group(1))
            return archiefmatch.group(0)
    print('Is niet meer aanwezig, maar geen archivering gevonden. Zie [[Speciaal:Diff/' + geschmatch.group(1) + ']].')
    return None

def isundone(tekst, pagina):
    # Is de opgegeven tekst eerder door Wikiwernerbot toegevoegd aan de pagina?
    gesch = pagina.getVersionHistoryTable()
    geschregels = gesch.split('\n|----\n')
    for r in geschregels:
        if '|| Wikiwernerbot ||' not in r:
            continue
        oldid = geschre.search(r).group(1)
        oldrev = pagina.getOldVersion(int(oldid))
        if not oldrev:
            return True # Niet meer na te gaan.
        if tekst in oldrev:
            print('De link ' + tekst + 'is al eerder toegevoegd aan de pagina ' + pagina.title() + ': zie [[Speciaal:Diff/' + oldid + ']].')
            return True
    return False

kroeg = pywikibot.Page(site, 'Wikipedia:De kroeg')
print('Ophalen geschiedenis van Wikipedia:De kroeg ...')
kroeggesch = kroeg.getVersionHistoryTable()
print('Gereed.')
kroegkopurlre = re.compile(r'\[?https?:\/\/nl\.wikipedia\.org\/(w\/index\.php\?title=|wiki\/)Wikipedia:De_kroeg\#([^][|\s]*)')
kroegkopre = re.compile(r'\[\[\s*(W(ikipedia|p)[\s_]*:[\s_]*((De)?[ _]?kroeg|D?K))[\s_]*\#([^][|]*?)[\s_]*[]|]', re.IGNORECASE)
for backlink in kroeg.backlinks():
    if backlink.title() == 'Wikipedia:Overleg gewenst':
        continue
    if 'edit' in backlink.protection().keys() and backlink.protection()['edit'][0] == 'sysop':
        continue
    if backlink.namespace().id == 2:
        continue
    print('\n' + backlink.title())
    tekst = backlink.text
    kopmatches = kroegkopurlre.finditer(tekst)
    for m in kopmatches:
        url = m.group(0)
        print(url)
        tijdstempel = whenplaced(backlink.title(), url)
        if not tijdstempel:
            continue
        kopje = m.group(2).replace('_', ' ')
        if not url.startswith('[') and kopje[-1] in ['.', ',', ':', ';' '(', ')', '?', '!']:
            kopje = kopje[:-1]
            url = url[:-1]
        print('#', kopje)
        archieflink = zoekarchieflink(kopje, tijdstempel)
        if not archieflink:
            continue
        archiefpagina = pywikibot.Page(site, archieflink)
        if not re.search(r'^(=+) *' + re.escape(kopje) + r' *\1 *$', archiefpagina.text, re.MULTILINE):
            print('Kopje niet gevonden op', archieflink)
            continue
        archieflink = archieflink.replace(' ', '_')
        newurl = url.replace('Wikipedia:De_kroeg', archieflink)
        newurl = newurl.replace('http://', 'https://')
        if isundone(newurl, backlink):
            continue
        if url.startswith('['):
            print('Archieflink =', newurl)
            tekst = tekst.replace(url, newurl)
        else:
            print('Archieflink = [' + newurl + ' ' + url + ']')
            tekst = tekst.replace(url, '[' + newurl + ' ' + url + ']')
    kopmatches = kroegkopre.finditer(tekst)
    for m in kopmatches:
        wl = m.group(0)
        print(wl)
        tijdstempel = whenplaced(backlink.title(), wl)
        if not tijdstempel:
            continue
        kopje = m.group(5).replace('_', ' ')
        print('#', kopje)
        archieflink = zoekarchieflink(kopje, tijdstempel)
        if not archieflink:
            continue
        archiefpagina = pywikibot.Page(site, archieflink)
        if not re.search(r'^(=+) *' + re.escape(kopje) + r' *\1 *$', archiefpagina.text, re.MULTILINE):
            print('Kopje niet gevonden op', archieflink)
            continue
        newwl = wl.replace(m.group(1), archieflink)
        newwl = newwl.replace('_', ' ')
        if isundone(newwl, backlink):
            continue
        if wl.endswith('|'):
            print('Archieflink =', newwl)
            tekst = tekst.replace(wl, newwl)
        else:
            print('Archieflink =', newwl[:-1] + '|' + wl[2:])
            tekst = tekst.replace(wl, newwl[:-1] + '|' + wl[2:])
    if tekst != backlink.text:
        backlink.text = tekst
        try:
            backlink.save('Toevoegen archieflinks n.a.v. [[Wikipedia:De kroeg/Archief/20221223#Een hulpje voor Nlwikibots?|kroegdiscussie]]')
        except:
            continue