Gebruiker:Dpmelderbot/dpmeldingen.py

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

def ptitel(titel):
    p = re.escape(titel)
    p = "[" + p[0] + p[0].lower() + "]" + p[1:]
    p = p.replace(" ", "[ _]")
    p = r"\[\[\s*" + p + r"\s*[]|#]"
    return p

def isskip(dptitel, backlink):
    skippatroon = re.compile(r"\[\[" + re.escape(dptitel) + r"\]\].*\[\[" + re.escape(backlink.title()) + r"\]\]")
    if skippatroon.search(wplndskips.text):
        return True
    zieartikel = re.compile(r"\{\{\s*[Zz]ie\s*artikel[^}]+" + ptitel(dptitel))
    if zieartikel.search(backlink.text) and len(re.findall(ptitel(dptitel), backlink.text)) == 1:
        return True # Artikel bevat slechts 1 link naar de dp: in de {{Zie artikel}}.
    return False

pgesch = re.compile(r"\n\| (\d+) \|\| [^|]* \|\| ([^|]*) \|\|")

def zoektoevoeger(artikel, patroon):
    gesch = artikel.getVersionHistoryTable()
    pos = 0
    oldids = []
    gebruikers = []
    dpadded = False
    stap = 1 # Zie de if na de while: deze moet daar gedefinieerd zijn.
    while not dpadded:
        geschmatch = pgesch.search(gesch, pos) # Een regel terug in de bewerkingsgeschiedenis
        if not geschmatch: # De oudste versie is dan bereikt.
            dpadded = True
            stap = 1 # De oudste gebruiker plaatste de dp-link.
            break
        pos = geschmatch.end()
        oldid = int(geschmatch.group(1))
        oldids.append(oldid)
        gebruikers.append(geschmatch.group(2))
        oldidtekst = artikel.getOldVersion(oldid)
        if oldidtekst and not re.search(patroon, oldidtekst): # Het eerste is nodig bij evt. verwijderde versies.
            if len(oldids) == 1: # De recentste versie bevat de dp-link niet:
                break
            else: # De recentste versie bevat de dp-link wel, maar een oudere versie niet:
                dpadded = True
                stap = 2 # De een-na-oudste gebruiker plaatste de dp-link.
    if dpadded:
        return {"gebruiker": gebruikers[-stap], "oldid": oldids[-stap]}
    else:
        return {"gebruiker": "", "oldid": 0}

def oldidlogged(oldid):
    with open(r'C:\Python\oldids.log') as oldidslog:
        for line in oldidslog:
            if str(oldid) in line:
                return True
        return False

def voegtoe(artikeltitel, dptoevoeger, dptitel, redirecttitel = ""):
    if dptoevoeger["gebruiker"] in dptoevoegers:
        dpi = dptoevoegers.index(dptoevoeger["gebruiker"])
        if artikeltitel in dpartikelen[dpi]:
            ai = dpartikelen[dpi].index(artikeltitel)
            dps[dpi][ai].append(dptitel)
            redirects[dpi][ai].append(redirecttitel)
        else:
            dpartikelen[dpi].append(artikeltitel)
            dps[dpi].append([dptitel])
            redirects[dpi].append([redirecttitel])
    elif dptoevoeger["gebruiker"] != "": # Verborgen gebruikersnaam, of zoektoevoeger returnde "".
        dptoevoegers.append(dptoevoeger["gebruiker"])
        dpartikelen.append([artikeltitel])
        dps.append([[dptitel]])
        redirects.append([[redirecttitel]])
    if not dptoevoeger["oldid"] in newoldids:
        newoldids.append(dptoevoeger["oldid"])

wplndd = pywikibot.Page(site, u"Wikipedia:Links naar doorverwijspagina's/data")
wplndskips = pywikibot.Page(site, u"Wikipedia:Links naar doorverwijspagina's/skips")
dptoevoegers = [] # List van unieke gebruikers die een dp-link toegevoegd hebben.
dpartikelen = [] # List van lists met voor elke dptoevoeger een list unieke artikelen waaraan ze een dp-link toegevoegd hebben.
dps = [] # 3D-list met een list van dp's voor elke combinatie van dptoevoeger en artikel.
redirects = [] # Idem voor de redirects naar dp's.
newoldids = [] # List van oldids van bewerkingen waarbij een of meerdere dp-links toegevoegd werden. Deze worden toegevoegd aan oldids.log aan het eind van dit script.
pdpsjabloon = re.compile(r"\{\{\s*[Dd](p|P|isambig)\s*(\|[^}]*)?\}\}")
for dp in wplndd.linkedPages():
    if not dp.isDisambig():
        continue
    print("Dp: " + dp.title())
    dpsjabloonadded = zoektoevoeger(dp, pdpsjabloon)
    dpheeftlinks = 0
    for backlink in dp.backlinks(namespaces = 0, follow_redirects = False):
        if backlink.isRedirectPage():
            predirect = re.compile(r"#(REDIRECT|[Rr]edirect|DOORVERWIJZING|[Dd]oorverwijzing) *\[\[" + ptitel(dp.title()) + r"\]\]")
            dpredirecter = zoektoevoeger(backlink, predirect)
            for redirectbacklink in backlink.backlinks(namespaces = 0):
                if not redirectbacklink.isDisambig() and not redirectbacklink.isRedirectPage() and not isskip(dp.title(), redirectbacklink):
                    dpheeftlinks += 1
                    dptoevoeger = zoektoevoeger(redirectbacklink, ptitel(backlink.title()))
                    # Als dit later gebeurde dan het toevoegen van {{dp}} of een alias en er nog niet eerder een melding over gestuurd is:
                    if dptoevoeger["oldid"] > dpredirecter["oldid"] and dpredirecter["oldid"] > dpsjabloonadded["oldid"] and not oldidlogged(dptoevoeger["oldid"]):
                        voegtoe(redirectbacklink.title(), dptoevoeger, dp.title(), backlink.title())
        elif not "(doorverwijspagina)" in dp.title() and not backlink.isDisambig() and not isskip(dp.title(), backlink):
            dpheeftlinks += 1
            dptoevoeger = zoektoevoeger(backlink, ptitel(dp.title()))
            if dptoevoeger["oldid"] > dpsjabloonadded["oldid"] and not oldidlogged(dptoevoeger["oldid"]):
                voegtoe(backlink.title(), dptoevoeger, dp.title())
# Eerst loggen welke edits gemeld gaan worden, ...
with open(r'C:\Python\oldids.log', 'a') as oldidslog:
    for newoldid in newoldids:
        oldidslog.write(str(newoldid) + '\n')
# ... en dan pas meldingen sturen. Dit duurt 1 minuut per melding en kan dan eventueel gestopt worden.
for i in range(len(dptoevoegers)):
    if dptoevoegers[i].startswith("2A02:"):
        continue
    bericht = "Beste " + dptoevoegers[i] + ", {{Subst:Gebruiker:Dpmelderbot/Bericht/Begin}}"
    if len(dps[i]) == 1:
        bericht +=  " Het gaat om het volgende artikel:"
    else:
        bericht += " Het gaat om de volgende artikelen:"
    for j in range(len(dpartikelen[i])):
        if len(dps[i][j]) == 1:
            bericht += "\n* Het artikel [[" + dpartikelen[i][j] + "]] bevat een [[Help:Gebruik van links|link]] naar de doorverwijspagina "
        else:
            bericht += "\n* Het artikel [[" + dpartikelen[i][j] + "]] bevat [[Help:Gebruik van links|links]] naar de volgende doorverwijspagina's: "
        for k in range(len(dps[i][j])):
            bericht += "[[" + dps[i][j][k] + "]]"
            if not redirects[i][j][k] == "":
                bericht += " (via de redirect [[" + redirects[i][j][k] + "]])"
            if k < len(dps[i][j]) - 1:
                bericht += ", "
            else:
                bericht += "."
    bericht += "\n{{Subst:Gebruiker:Dpmelderbot/Bericht/Einde}} ~~~~"
    OP = pywikibot.Page(site, u"Overleg gebruiker:" + dptoevoegers[i])
    if OP.isRedirectPage():
        OP = OP.getRedirectTarget()
    elif not OP.exists():
        OP.text = "{{Welkom3-u}}"
    OP.text += "\n\n== Melding links naar doorverwijspagina's ==\n" + bericht
    try:
        OP.save(u"Nieuw kopje aangemaakt: /* Melding links naar doorverwijspagina's */", minor=False)
    except Exception as e:
        print("Overleg gebruiker:" + dptoevoegers[i] + " kon niet gepubliceerd worden:")
        print(e.args)