Szerkesztő:BinBot/tataroz.py

A Wikipédiából, a szabad enciklopédiából

Ez a script a Wikipédia:Szócikkek elavult karbantartósablonnal lapot frissíti.

# -*- coding: utf-8  -*-
"""
Ez a script kilistázza a két hétnél régebben elhelyezett tataroz, építés alatt
stb. sablonokat a Wikipédia:Szócikkek elavult karbantartósablonnal lapra.
Compat verziót igényel.
(C)(D)(E)(F)(G)(A)(H)(C) Bináris
"""

import time, datetime, re
import wikipedia as pywikibot
import pagegenerators
from binbotutils import levelez, munkanaplo # Másnak nem szükséges

HOVATEGYEM = u'Wikipédia:Szócikkek elavult karbantartósablonnal'
NOTICEBOARD = u'Wikipédia:Kocsmafal (egyéb)'
sablonok = {    # Minden nevet kisbetűvel írj! Az első szám a kiírási sorrend.
    u'építés alatt' :       (1, []),
    u'tataroz' :            (2, []),
    u'változó hír' :        (3, []),
    u'friss baleset' :      (4, []),
    u'friss haláleset' :    (5, []),
    u'friss esemény' :      (6, []),
    u'friss sportesemény' : (7, []),
    u'jövő' :               (8, []),
    u'űrhír' :              (9, []),
    }
old = 14 # Hány nap után vijjogjunk a sablonért?
site = pywikibot.getSite()
minta = re.compile(r'(\d{4})-(\d{2})-(\d{2})')
# A sectionpattern a toc.py-ból van átvéve, a sections() metódus használja.
sectionpattern = [None] # For 0th element; no header0.
for i in [1, 2, 3]:
    sectionpattern.append(re.compile(r'^={%d}[^=].*?={%d}' % (i,i)))
rowend = re.compile(r'.*\|\|\ \s*\n$') # Azonosítja a megjegyzés nélküli sorokat.
noticetext = u"""
A [[Wikipédia:Szócikkek elavult karbantartósablonnal]] lap frissült. Kérlek, segítsetek átnézni, hogy mely lapokon 
maradtak indokolatlanul a kéthetes vagy régebbi ''tataroz, építés alatt'' stb. sablonok. A korábbi frissítésekből 
eltávolíthatók az aktualitásukat vesztett sorok. Bináris képviseletében: ~~~~
"""

class templatehunter(object):
    def __init__(self):
        global hiba, sablonok
        self.ma = datetime.date(time.localtime()[0], time.localtime()[1], time.localtime()[2])
        self.mai_nap = '%d. %02d. %02d.' % (time.localtime()[0], time.localtime()[1], time.localtime()[2])
        print self.mai_nap
    
    def napokszama(self, mikor):
        # Egy match objektumot várunk.
        akkor = datetime.date(int(mikor.group(1)), int(mikor.group(2)), int(mikor.group(3)))
        delta = self.ma - akkor
        return delta.days

    def feldolgoz(self, sablon, cikk):
        hist=cikk.fullVersionHistory()
        # A 0. elem az utolsó szerkesztés; mindegyikből
        # az [1] az időbélyeg és a [3] a verzió szövege.
        utolso = minta.match(hist[0][1])
        eltelt_u = self.napokszama(utolso)
        i = 0 # Ebben biztosan megvan a sablon!
        nincs = False
        while i < len(hist)-1:
            i += 1
            if '{{%s' % sablon not in hist[i][3].lower():
                # A sablonnév után | is lehet a paramétereknek, nem csak }}!
                nincs = True #Az utolsó miatt kell
                break
        # Az i-edik változatban már nincs benne, ha break volt. (0. = utolsó)
        # Ha i == len(hist)-1, akkor a legelső változatban vagy benne volt, 
        # vagy nem. Ezért kell a nincs változó.
        if i == len(hist) - 1 and not nincs:
            k = hist[i][1]
        else:
            k = hist[i-1][1]
        kezdeti = minta.match(k)
        eltelt_k = self.napokszama(kezdeti)
        if eltelt_k >= old:
            sablonok[sablon][1].append((cikk.title(), kezdeti, eltelt_k, utolso, eltelt_u))

    def kollektor(self):
        for sablon in sablonok:
            s = pywikibot.Page(site, 'Sablon:'+sablon)
            for page in pagegenerators.ReferringPageGenerator(s, onlyTemplateInclusion=True):
                if page.namespace() == 0:
                    pywikibot.output(page.title())
                    self.feldolgoz(sablon, page)

    def datetext(self, matchobj, eltelt):
        # return u'%s.&nbsp;%s.&nbsp;%s. (%d&nbsp;napja)' % \
            # (matchobj.group(1), matchobj.group(2), matchobj.group(3), eltelt)
        # Új verzió: az aid sablonnal az aktuálisan eltelt napok számát írjuk ki.
        # TODO: az eltelt paraméter és az odavezető számítások kiirtása.
        # De előbb várjuk meg, mit lép az oldal ilyen sok sablonra.
        form = u'{0}.&nbsp;{1}.&nbsp;{2}. ({{{{aid|{0}|{1}|{2}}}}}&nbsp;napja)'
        return form.format(*matchobj.groups())

    def ujListaSzakasz(self):
        kell = False
        s = u'\n== Legalább %d napos karbantartósablonok szócikkeken (%s) ==\n\n' \
            % (old, self.mai_nap)
        for sablon in sorted(sablonok, key=lambda x: sablonok[x][0]):
            lista = sablonok[sablon][1]
            if len(lista):
                kell = True
                s += u'=== %s ===\n\n' % sablon.capitalize()
                s += u'{| {{széptáblázat-r}}\n'
                s += u'!Szócikk!!A sablon rákerült!!Utolsó módosítás!!Ide írhatsz megjegyzést\n'
                for elem in lista:
                    s += u'|-\n|{{cikktört|%s}}||' % elem[0]
                    s += self.datetext(elem[1], elem[2]) + '||'
                    s += self.datetext(elem[3], elem[4]) + '||&nbsp;\n'
                s += u'|}\n\n'
        # s += u'Készítette: ~~~~\n'
        return s if kell else None

    def sections(self, text, level):
        '''A korábbi lista takarításához kell, a toc.py-ból átvéve és átigazítva'''
        """
        This generator yields the separate sections of a page.
        Ignores any lines before the first ==title== as well as any =title= lines
        and the following part until the next ==title==
        """
        beginning = True
        where = 0 #Necessary for indexing, because section titles may occur repeatedly
        for line in text.splitlines(1):
            if sectionpattern[level].match(line) and not pywikibot.isDisabled(text,where):
                if not beginning:
                    yield section
                else:
                    beginning = False
                section = line
            elif sectionpattern[1].match(line) and not pywikibot.isDisabled(text,where):
                beginning = True
            else:
                if not beginning:
                    section += line
            where += len(line)
        if not beginning:
            yield section #The last one

    def takarit(self, text):
        # Megőrizzük az első szakaszcím előtti részt:
        firstheader = re.search(r'==[^=].*?==', text) #A sectionpattern nem jó, ^ van az elején
        newtext = text[:firstheader.start()] if firstheader else text
        # Szakaszokra bontjuk a régi lapot.
        for szakasz in self.sections(text, 2):
            # Megőrizzük az első szakaszcím előtti részt:
            firstheader = re.search(r'===[^=].*?===', szakasz) #A sectionpattern nem jó, ^ van az elején
            newsection = szakasz[:firstheader.start()] if firstheader else szakasz
            # Harmadszintű alszakaszokra bontjuk a szakaszt:
            for alszakasz in self.sections(szakasz, 3):
                kell = False # Igaz lesz, ha van megjegyzés a táblázatban.
                # Felosztás a |- és |} sorok mentén, zárójellel
                # http://docs.python.org/library/re.html#re.split
                lista = re.split(r'(\|\-\s*\n|\|\}\s*\n*)', alszakasz) 
                for i in range(len(lista)):
                    if lista[i].startswith('|-') and i < len(lista) - 1:
                    # Bízzunk benne, hogy szabályos maradt a táblázat.
                        if rowend.search(lista[i+1]):
                            lista[i] = lista[i+1] = ''
                        else:
                            kell = True
                newsection += ''.join(lista) if kell else ''
            newtext += newsection
        return newtext

    def publish(self):
        global hiba
        oldal = pywikibot.Page(site, HOVATEGYEM)
        summary = u'Hosszabb ideje a cikkeken maradt sablonok listázása bottal'
        s = self.ujListaSzakasz()
        pywikibot.output(s)
        if not s:
            pywikibot.output(u'A jelek szerint most nincs listáznivaló!')
            return
        try:
            oldtext = oldal.get()
        except NoPage:
            hiba = True
            return
        newtext = self.takarit(oldtext)
        pywikibot.output(newtext)
        try:
            oldal.put(newtext + s, comment=summary, botflag=False)
        except:
            hiba = True

        # Értesítés az egyéb kocsmafalra
        # Ez nem generál hibát, mert akkor nem lenne naplózás. Kivéve, ha nincs kocsmafal. :-)
        if not hiba:
            oldal2 = pywikibot.Page(site, NOTICEBOARD)
            sect = u'Legalább %d napos karbantartósablonok szócikkeken (%s)' \
                % (old, self.mai_nap)
            s = u'\n== %s ==\n\n' % sect
            summary2 = u'/* %s */ (új szakasz)' % sect
            try:
                oldtext = oldal2.get()
            except NoPage:
                hiba = True
                return
            try:
                oldal2.put(oldtext + s + noticetext, comment=summary2, botflag=False)
            except:
                pass


    def run(self):
        self.kollektor()
        self.publish()

if __name__=="__main__":
    try:
        hiba = False
        fatal = True
        bot = templatehunter()
        bot.run()
        fatal = False
    finally:
        levelez(fatal,hiba)
        pywikibot.stopme()