Szerkesztő:BinBot/masvita.py

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

Ez a script a Wikipédia:Elavult másvitasablonok lapot frissíti.

# -*- coding: utf-8 -*-
"""
Ez a script kilistázza a másvitasablonokat a Wikipédia:Elavult másvitasablonok
lapra. -all kapcsolóval az összeset, kapcsoló nélkül csak az ellenőrizendőket.
(C)(D)(E)(F)(G)(A)(H)(C) Bináris
v1.0, 2012. december 29.: publikus alapváltozat
v1.1, 2013. március 3.: stabil változat, hibát keres és kocsmafalra ír
v1.2, 2014. január 2.: a BÜ elfekvőjére mutató találatok kizárása + örülés, ha nincs javítanivaló
"""

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

header = u'''<!-- A lapot bot frissíti. Ha változtatás szükséges, jelezd Binárisnak! -->
[[Kategória:Karbantartási gondok]]
[[Kategória:Tennivalók]]
{{tudnivalók eleje}}
Ezen az oldalon a javítandó ''\'{{sl|másvita}} sablonok''\' vannak felsorolva.
A lapot [[user:Itt BinBot beszél a toolserverről|]] frissíti minden hónap első hétfőjén.

A másvita sablon a több helyen szétszórt megbeszélések összefogására való. A karbantartása azonban csak kézzel lehetséges.
Te is segíthetsz, ha a sablonokban elhelyezett kezdődátum és az archívumok tartalomjegyzéke segítségével megkeresed
az elavult linkek új helyét. Töröld a ''foly'' paraméter értékét, és írd az archív szakasz linkjét az ''archív'' paraméterhez
a szögletes zárójelek nélkül.<br />
Ebben sokat segíthet Báthory Péter szakaszcímmásoló varázslata, amelyet a [[Speciális:Beállításaim#mw-prefsection-gadgets]]
lapon kapcsolhatsz be a Szerkesztést könnyítő segédeszközök szakaszban Könnyen másolható szakaszlinkek pontnál.<br />
Bátran javítsd az elavult sablont az archívumokban is, hiszen ez nem a megbeszélések átírása, hanem éppen ellenkezőleg,
a használhatóságukat növeli!

A táblázat első oszlopában levő lapon találod a javítandó sablont. A fejlécben a „Folyamatban” a sablon szerint folyamatban
levő vita címére, az „Archívum” a sablon szerint archivált vita címére mutat.
Kérlek, segíts ellenőrizni, hogy a bot jól elemezte-e a sablonokat és a megfelelő megjegyzést írta-e melléjük.
A hibákat a vitalapon jelezd.

Az allapokról a bot nem tudja eldönteni, hogy archívumok-e. A törlési, véleményezési, szavazási stb. allapok a lezárás után
önmaguk archívumának tekinthetők; ilyenkor a linket a ''foly'' paramétertől az ''archív'' paraméterhez áthelyezve előzhetjük
meg, hogy a bot minden futáskor fölöslegesen listázza a sablont. 
([http://hu.wikipedia.org/w/index.php?title=Wikip%C3%A9dia:Adminisztr%C3%A1torok_%C3%BCzen%C5%91fala/Int%C3%A9zked%C3%A9sek_megvitat%C3%A1sa&diff=prev&oldid=13723787 Minta])

A javított sablonokhoz tartozó táblázatsort egyszerűen töröld.

Utolsó módosítás: ~~~~~
'''
noticetext = u"""
u'\n== Elavult másvitasablonok ==\n\n'
A [[Wikipédia:Elavult másvitasablonok]] lap frissült. Kérlek, segítsetek 
aktualizálni a listázott sablonokat. Bináris képviseletében: ~~~~
"""

class masvitabot:
    def __init__(self, all):
        self.site = pywikibot.getSite()
        # Whether or not to display all templates, including those without
        # problem.
        self.all = all
        # Some regexes to analyzie the template
        self.full = re.compile(ur'(?is)\{\{másvita(.*?)\}\}')
        self.foly = re.compile(ur'(?is)foly\s*=\s*([^\|\n]*)')
        self.arch = re.compile(ur'(?is)archív\s*=\s*([^\|\n]*)')
        # A cache for getSections to speed things up (getSections is very slow)
        self.cache = dict()
        # Accepted date formats are specific for Hungarian.
        # This is faster than to get them from live wiki.
        months1 = [u'jan', u'febr', u'márc', u'ápr', u'máj', u'jún', u'júl',
                   u'aug', u'szept', u'okt', u'nov', u'dec']
        months2 = [u'január', u'február', u'március', u'április', u'május',
                   u'jú[nl]ius', u'augusztus', u'(szept|nov|dec)ember',
                   u'október']
        self.date = re.compile(
            ur'\d{4}\. (\d{1,2}\.|%s\.|%s) \d{1,2}\.' %
            ('|'.join(months1), '|'.join(months2)))
        self.kezd = re.compile(ur'(?is)kezdet\s*=\s*([^\|]*)')
        self.header = header
        self.noticetext = noticetext
        self.target = pywikibot.Page(
                        self.site, u'Wikipédia:Elavult másvitasablonok')
        self.noticeboard = pywikibot.Page(
                        self.site, u'Wikipédia:Kocsmafal (egyéb)')

    def list(self):
        template = pywikibot.Page(self.site,u'Sablon:Másvita')
        return pagegenerators.ReferringPageGenerator(template,
                                         onlyTemplateInclusion=True)

    def alterfound(self, section, title):
        # Alternative search method for the cases when primary search fails
        # Returns a boolean: found or not?
        # This is slower, so don't use in unneccessary case.
        def onespace(s):
            # Removes multiple spaces
            while '  ' in s:
                s=s.replace('  ',' ')
            return s

        try:
            # We look for the section part that was not found with primary
            # method and thus we can't get it with Page methods.
            hashindex = title.index('#')
            sectitle = title[hashindex + 1:]
            freetitle = title[:hashindex]
        except ValueError:
            return False
        # Try to retrieve info from cache, otherwise get and cache it:
        try:
            sectionlist = self.cache[freetitle]
        except KeyError:
            sections = pywikibot.Page(self.site, freetitle).getSections()
            sectionlist = [tup[3] for tup in sections]
            sectionlist.extend([onespace(tup[3]) for tup in sections])
            sectionlist = list(set(sectionlist)) # Remove duplicates
            self.cache[freetitle] = sectionlist
        # See in wikipedia.py: getSections returns a list with tuple entries:
        # (byteoffset, level, wikiline, line, anchor) -- line is what we need
        if sectitle in sectionlist:
            return True
        return False

    def slash_in_title(self, section):
        return 2 if '/' in section.sectionFreeTitle() else 1

    def found(self, title):
        """
        title is a section title in form of page#section.
        We will check it for existence.
        Return values:
         1: section part of the given title exists
         2: section found, but title contains '/' (possible archive)
         0: section part does not exist, but the title exists
        -1: if title does not exist
        10 added each time when title redirects
        """
        section = pywikibot.Page(self.site, title)
        try:
            section.get()
            return self.slash_in_title(section)
        except pywikibot.SectionError:
            # Section title is not found in the given format. But itt may still
            # be present with unwanted spaces, links etc.
            # We will search the whole page for the title
            if self.alterfound(section, title):
                return self.slash_in_title(section)
            return 0
        except pywikibot.NoPage:
            return -1
        except pywikibot.IsRedirectPage:
            pywikibot.output(section.getRedirectTarget().title())
            return self.found(section.getRedirectTarget().title()) + 10
            # This is not prepared for an infinite recursion.
            # That would mean an infinite redirect which is unlikely.

    def commenttext(self, index, foly=True):
        # index is the returned value of found().
        # foly is True if the title is a folytitle
        # value 2 is treated differently).
        if index % 10 == 1 or index % 10 == 2:
            s = u'{{zöldpipa}}'
            if index % 10 == 2 and foly:
                s += u' A cím / jelet tartalmaz. Lehet, hogy archívum.'
        elif index % 10 == 0:
            s = u'{{piroskérdés}} Nincs meg a szakasz. Archívumba került?'
        else:
            s = u'{{pirosiksz}} Nincs meg a hivatkozott lap!'
        if index > 3:
            s += u'<br>A hivatkozott lap átirányít!'
        return s

    def run(self):
        global hiba
        pagecount = 0 # How many pages contain the template?
        matchcount = 0 # How many templates are there?
        OKcount = 0 # How many problemless templates did we find?
        wikipagetext = u'{| {{széptáblázat-r}}\n' + \
            u'!style="width:25%;"|Lap címe!!style="width:25%;"|Folyamatban' + \
            u'!!style="width:25%;"|Archívum!!style="width:25%;"|Állapot\n'
        for page in self.list():
            pagecount += 1
            # pywikibot.output(page.title()) # Debug only
            text = page.get()
            for match in self.full.finditer(text):
                comment = ''
                tablerow = u'|-\n|[[%s]]\n' % page.title()
                matchcount += 1
                templtext = match.group(1)
                # pywikibot.output(templtext) # Debug only
                folytitle = archtitle = ''
                # If any of them is missing, there is no problem.
                # If both are missing, that's an error.
                try:
                    folytitle = self.foly.search(templtext).group(1)
                except AttributeError:
                    pass
                try:
                    archtitle = self.arch.search(templtext).group(1)
                except AttributeError:
                    pass
                # Debug only
                # pywikibot.output('f=[[%s]]' % folytitle.replace('\n',''))
                # pywikibot.output('a=[[%s]]' % archtitle.replace('\n',''))
                if folytitle:
                    tablerow += u'|[[%s]]\n' % folytitle.replace('\n','')
                    # print self.found(folytitle) # debug only
                    comment += self.commenttext(self.found(folytitle))
                else:
                    tablerow += u'|\n'
                if archtitle:
                    tablerow += u'|[[%s]]\n' % archtitle.replace('\n','')
                    # print self.found(archtitle) # debug only
                    comment += self.commenttext(self.found(archtitle), False)
                else:
                    tablerow += u'|\n'
                if folytitle and archtitle:
                    comment += \
                            u'<br>Hibás paraméterezés, foly és archív is van!'
                if not (folytitle or archtitle):
                    comment = u'Hiányzik mindkét paraméter (foly, archív)!'
                try:
                    kezdet = self.kezd.search(templtext).group(1)
                    try:
                        kezdet = self.date.match(kezdet).group()
                    except AttributeError:
                        # pywikibot.output(u'Hibás dátum')
                        comment += u'<br>Hibás dátumformátum: ' + kezdet
                except AttributeError:
                    # pywikibot.output(u'Hiányzó dátum!')
                    comment += u'<br>Hiányzik a kezdődátum!'
                OK = (comment == u'{{zöldpipa}}')
                #Zárjuk ki az elfekvőt, nincs aktuális tennivaló. Barkács.
                if folytitle.replace('_', ' ').startswith(u'Wikipédia:Botgazdák üzenőfala/Régóta megoldatlan feladatok') \
                        and comment == u'{{zöldpipa}} A cím / jelet tartalmaz. Lehet, hogy archívum.':
                    OK = True
                if OK:
                    OKcount += 1
                tablerow += u'|%s\n' % comment
                if self.all or not OK:
                    wikipagetext += tablerow
        pywikibot.output(u'Lapok száma: %d' % pagecount)
        pywikibot.output(u'Találok száma: %d' % matchcount)
        pywikibot.output(u'Ebből teljesen OK: %d' % OKcount)
        wikipagetext += u'|}\n'
        if matchcount == OKcount:
            wikipagetext += u'Úgy tűnik, minden rendben, nincs tennivaló!\n'
        self.header += u'<br>Lapok száma: %d\n' % pagecount
        self.header += u'<br>Sablonok száma: %d\n' % matchcount
        smile = '' if matchcount > OKcount else ' {{)}}'
        self.header += u'<br>Ellenőrizendő sablonok száma: %d%s\n' % \
                        (matchcount-OKcount, smile)
        if not self.all:
            self.header += \
                    u'<br>A problémamentes sablonok nincsenek a táblázatban.\n'
        self.header += u'{{tudnivalók vége}}\n\n'
        self.header += u'== Táblázat ==\n\n'
        try:
            self.target.put(self.header + wikipagetext,
                        u'A másvita sablonok ellenőrzése', botflag = False)
        except:
            hiba = True
        
        # Hirdetmény a kocsmafalra:
        # Egyelőre nincs rá szükség, olyan kevés újat listáz!
        return # Ezt kell kivenni, hogy beírjon.
        if not hiba:
            comment = u'/* Elavult másvitasablonok */ (új szakasz)'
            try:
                text = self.noticeboard.get()
            except NoPage:
                hiba = True
                return
            try:
                self.noticeboard.put(
                    text + self.noticetext, comment, botflag = False)
            except:
                hiba = True

def main(*args):
    all = False # Default behaviour: don't list templates with no problem
    for arg in pywikibot.handleArgs(*args):
        if arg == u'-all':
            all = True
    bot = masvitabot(all)
    bot.run()

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