Szerkesztő:BinBot/piroskat-userallap.py
A nem létező kategóriákat a szerkesztői allapokról eltávolító bot. Lásd még itt.
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Ez a script a piroskat.py függeléke
Piros kategóriákat keres a Speciális:Keresett kategóriák lapon, amelyek
szerkesztői allapra vannak beillesztve. Nowikibe teszi őket, és értesíti a tulajdonost.
Megoldás:
1. Beolvasás a speclapról
2. Ellenőrzés, hogy tényleg piros-e még
3. A benn levő lapok végignézése: csak 2. névtér, és csak allap
(Feltételezzük, hogy itt alapvetően készülő cikkek vannak.)
Nem nyúlunk a userlapokhoz és a szerkesztővita-névtérhez, ott nincs is tömeges gond.
4. nowiki
5. Értesítés (a botMayEdit() figyelembe vételével!) -- ha még nem kapott egy másiknál
6. A Wikipédia:Nem létező kategóriák lap módosítása
A kategória listázásának magyarázata a piroskat.py-ban van.
(C)(D)(E)(F)(G)(A)(H)(C) Bináris. Licenc: használd egészséggel.
"""
import wikipedia as pywikibot
import catlib, re
import binbotutils #naplózás
#Globális változók:
allapok=set() #Itt gyűjtjük a javítottakat. Egy user egy allapról csak egy értesítést kap.
teszt=False #True esetén "dry" üzemmód, csak a képernyőre ír.
site=pywikibot.getSite()
BinBotEdit=0 #naplózáshoz
def CikketKeres(kat):
lista = catlib.categoryAllElementsAPI(kat)
for cim in lista[0]:
if cim['ns'] == 2:
if '/' in cim['title']:
yield cim
else:
pass #Ez userlap, egyelőre kihagyjuk.
def redCategories(number = 500, repeat = False): #number mindegy, a lenti limit számít
"""Yield Pages from Special:WantedCategories.
Félig elloptam a wikipedia.py-ból, félig átírtam, sok kísérlettel.
Hogy ez miért nincs ott megírva..."""
path='/w/index.php?title=Special:WantedCategories&limit=2500&useskin=monobook'
seen = set()
while True:
html = site.getUrl(path)
entryR = re.compile(
'<li><a href=".+?" title="(?P<title>.+?)">.+?</a>.+?</li>')
for m in entryR.finditer(html):
title = m.group('title')
if title not in seen:
seen.add(title)
try:
hol=title.index(u'(megíratlan szócikk)') #Még piros
title=title.replace(u'(megíratlan szócikk)','')
#page = pywikibot.Page(site, title)
page = catlib.Category(site, title) #Ez való a kategóriákhoz
yield page
except ValueError:
pass #Ez a kategória már elkékült
if not repeat:
break
"""
Így néz ki sima printtel:
[[Kategória:Neurotoxins (megíratlan szócikk)]] (piros)
[[Kategória:Kvantummechanika]] (kék)
[[Kategória:Finn nyelv (megíratlan szócikk)]]
"""
def NowikibeTesz(allapcim,kategoriacim):
global allapok, BinBotEdit #A hívások között maradjon meg
pywikibot.output(u'Allap: %s, %s' %(allapcim,kategoriacim))
keres=u'[[%s]]' % kategoriacim
KatCimNevterNelkul=kategoriacim[kategoriacim.find(':')+1:]
rekeres=re.compile(ur'(\[\[(Kategória|Category):%s(\|.*)?\]\])' % re.escape(KatCimNevterNelkul))
csere=r'<nowiki>\1</nowiki>'
#Műszaki kocsmafal, 2010. szept. 7.
allap=pywikibot.Page(site,allapcim)
try:
oldtext=allap.get()
except:
print u'Hát ilyen nincs, eltűnt a lap!'
oldtext=''
newtext=pywikibot.replaceExcept(oldtext,rekeres,csere,['nowiki'],caseInsensitive=True)
pywikibot.showDiff(oldtext, newtext)
#Tesztelve: Kategória/Category, és van/nincs |... a ]] előtt.
success=False #A mentés sikerét jelzi
if oldtext == newtext:
pywikibot.output(u'Nem találom a kategóriát! Vagy sablon csinálta, vagy rossz a keresőkifejezés!')
RemoveFromList(allapcim,kategoriacim, sablon=True) #Megpróbálunk megjegyzést írni a listába
elif not teszt:
try:
allap.put(newtext,u"Piros kategória nowikizése bottal")
success=True
except:
pywikibot.output(u'Nem sikerült a mentés: %s.' % allapcim)
else:
pywikibot.output(u'\03{lightred}Tesztüzem, az allapot nem mentettem: %s.\03{default}\n' % allapcim)
success=True #A további szimulációhoz
if success:
BinBotEdit+=1
if allapcim not in allapok:
UsernekUzen(allapcim,kategoriacim)
else:
pywikibot.output(u'Erről az alapról már küldtünk értesítést egy másik kategória kapcsán.')
allapok.add(allapcim) #Egy allapról csak egy értesítést küldünk
RemoveFromList(allapcim,kategoriacim)
def UzenetSzovege(allapneve):
s=u'\n\n== Allap módosítása ==\n'
s+=u'Szia! A [[%s]] allapodon a bot egy vagy több nem létező kategóriát talált. ' % allapneve
s+=u'Utólagos engedelmeddel nowikibe tettem, hogy ne zavarja a kategóriarendszer '
s+=u'karbantartását. (Lásd még ['
s+=u'http://hu.wikipedia.org/w/index.php?title=Wikip%C3%A9dia:Kocsmafal_'
s+=u'%28egy%C3%A9b%29&oldid=8395515#Piros_kateg.C3.B3ri.C3.A1k_nowikiz.C3.A9se_szerkeszt.C5.91i_allapon'
s+=u' itt].) ~~~~\n'
return(s)
def UsernekUzen(allapcim,kategoriacim):
global BinBotEdit
userlap=allapcim
while '/' in userlap:
userlap=userlap[:userlap.find('/')]
print userlap
vitalap=pywikibot.Page(site,userlap)
vitalap=vitalap.toggleTalkPage()
print vitalap.aslink()
#Na és ha átirányította?
if vitalap.isRedirectPage():
ujvitalap=vitalap.getRedirectTarget()
if ujvitalap.namespace()==3 and not ujvitalap.isRedirectPage():
vitalap=ujvitalap
print vitalap.aslink()
else: #Hibás átirányítás
pywikibot.output(u'\03{lightpurple}Hibásan átirányított vitalap, nem tudok üzenni.\03{default}')
return
if vitalap.botMayEdit('user:BinBott'):
comment=u'Értesítés bottal végzett allapszerkesztésről'
try:
text=vitalap.get()
except:
text=''
print u"\a\a\aNem sikerült betölteni a vitalapot, ellenőrizd!"
#TODO: rendesen megkivételezni, néha előfordul betöltési hiba
#létező lapnál. Addig figyelni kell, hogy ne töröljön véletlenül vitalapot.
text+=UzenetSzovege(allapcim)
#pywikibot.output(text) #Teljes vitalap képernyőre, csak debug, lassít.
if not teszt:
try:
vitalap.put(text,comment,minorEdit=False)
BinBotEdit+=1
except:
pywikibot.output(u'Nem sikerült a mentés: %s.' % vitalap.title())
else:
pywikibot.output(u'\03{lightred}Tesztüzem, a vitalapot nem mentettem: %s.\03{default}\n' % vitalap.title())
BinBotEdit+=1 #Szimuláció
else:
pywikibot.output(u'A felhasználó kizárta a botot a vitalapról, nem kap értesítést.')
def RemoveFromList(allapcim,kategoriacim,sablon=False):
#sablon jelentése: True, ha nem találtuk a lapon a kategóriát, talán sablon csinálta.
global BinBotEdit
hely=u'Wikipédia:Nem létező kategóriák'
oldal=pywikibot.Page(site,hely)
if sablon:
comment=u'A [[%s]] lapon nem találtam a [[%s]] kategóriát. Kategorizáló sablon tán?' % (allapcim,kategoriacim)
else:
comment=u'[[%s]] kihúzása [[%s]] alól bottal (ellenőrizendő)' % (allapcim,kategoriacim)
try:
oldtext=oldal.get()
except:
pywikibot.output(u'A Wikipédia:Nem létező kategóriák betöltése sikertelen, nem tudom kihúzni\n az allapot.')
return
newtext=''
keres=False #Igaz lesz, ha megtaláltuk a kategóriát, és keressük az allap címét.
oldtextsorai=oldtext.splitlines(1)
for sor in oldtextsorai:
s='*[[:'+kategoriacim
#Itt van egy kis bug, ha "xyz" a kat. neve, és van egy "xyzzz" is, akkor kétszer írja fel.
if s in sor:
keres=True
pywikibot.output(sor)
elif sor.startswith(u'*[[:Kategória')==1:
keres=False
if keres: #Most vagyunk a kategória alatt, listázva van-e a szerk. allap?
mitkeres='**[[%s]]' % allapcim
if mitkeres in sor:
pywikibot.output(u'Régi szöveg: '+sor) #%s helyettesítésre kódolási hibát ad
mitkeres=mitkeres[2:] #Már nem kell a csillag.
if sablon:
csere=mitkeres+u' (Bot: nincs meg a kategória, lehet, hogy egy sablon illesztette be.)'
else:
csere='<s>'+mitkeres+'</s>'
#debug only
#print mitkeres
#print csere
#sor.replace(mitkeres,csere) #Ez valamiért nem cseréli ki! :-((
holvan=sor.find(mitkeres)
sor=sor[:holvan]+csere+sor[holvan+len(mitkeres):]
#pywikibot.output(u'Új szöveg: '+sor) #debug only
newtext+=sor
pywikibot.showDiff(oldtext,newtext)
pywikibot.output(comment)
success=False #A mentés sikerét jelzi
if oldtext == newtext:
pywikibot.output(u'A tételt nem találtam a %s lapon.' % hely)
elif not teszt:
try:
oldal.put(newtext,comment)
success=True
except:
pywikibot.output(u'Nem sikerült a mentés: %s.' % hely)
else:
pywikibot.output(u'\03{lightred}Tesztüzem, a %s lapot nem mentettem.\03{default}\n' % hely)
success=True #A további szimulációhoz
if success:
BinBotEdit+=1
#TODO: rendesen megkivételezni, szerkesztési ütközést vizsgálni
def naplozas():
s=u'Wikipédia:Kocsmafal (egyéb)' #Majd archívot ide!
s+=u'#Piros kategóriák nowikizése szerkesztői allapon'
stat = {'fix':'','modm':0,'moda':BinBotEdit,'not':0,'skip':0,'err': 0,}
naplo=binbotutils.munkanaplo()
naplo.run(u'Nem létező kategóriák nowikizése',s,None,u'Szerkesztő:BinBot/piroskat-userallap.py', stat, teszt)
#A teszt megfelel a munkanapló screen paraméterének, csak a képernyőre ír.
if __name__ == '__main__':
if teszt:
s=u'Tesztüzem, semmit nem mentünk. Kikapcsolás a script elején.'
else:
s=u'Éles üzem,mindent menteni fogunk!'
pywikibot.output(u'\03{lightred}%s\03{default}' % s)
try:
for piros in redCategories():
for allapneve in CikketKeres(piros.title()):
NowikibeTesz(allapneve['title'], piros.title())
finally:
naplozas() #Ctrl C vagy más gond esetére