# -*- coding: utf-8 -*-
import codecs, os, re, sys, urllib2
from time import strftime as formatTS
import wikipedia
"""
Este script ha estat creat per a corregir la puntuació en les referències.
* reubica punts, tancament d'interrogació i tancament d'exclamació posats arrere una referència fins al seu començament.
La sintaxi és ben simple. Només cal fer una crida al script.
Opcionalment s'admeten diversos paràmentres, alguns d'ell necessiten una valor, a continuació es mostre els paràmetres, aquells
necessiten una valor acaben amb dos punts, els elements posats entre "<>" indiquen una valor definida per l'usuari.
* -start: <títol> (Opcional) permet començar l'exploració a partir d'un determinat títol.
* -end: <títol> (Opcional) permet aturar l'exploració fins un determinat títol.
* -count: <nombre> (Opcional) permet explorar un determinat nombre de pàgines, es superposa al paràmetre -end:.
* -url: <adreça URL> (Opcional) permet canviar l'adreça URL d'on es carregarà les pàgines a explorar
per defecte és http://toolserver.org/~sk/checkwiki/cawiki/cawiki_error_list_error_061.html
la sintaxi de la pàgina haurà de ser semblant a aquesta pàgina.
* -file: <fitxer> (Opcional) permet carregar un fitxer determinat d'on s'obtindrà la llista de pàgines per a explorar.
Aquesta opció invalida el paràmetre -url:. Les pàgines han d'anar dins de dobles claudators (amb la
típica sintaxi d'un enllaç intern).
* -file (Opcional) semblant al seu precedent, carregarà automàticament el darrer fitxer creat on figuren
articles per a explorar. Aquesta opció també invalida el paràmetre -url:. Les pàgines han d'anar
dins de dobles claudators (amb la típica sintaxi d'un enllaç intern).
* -debug (Opcional) s'usa a l'hora de fer proves, per a no editar cap pàgina.
* -verbose (Opcional) permet visualitzar els canvis.
* -force (Opcional) no permet cap excepció, explorant totes les pàgines.
Una vegada acabada l'exploració es genera un registre d'aquells articles en els quals no s'ha efectuat cap canvi. El nom del
fitxer tindrà la següent aparença: referencies_sense_tocar-AAMMDD-HHMMSS.log
També es generarà un fitxer de tots aquells articles que s'han explorat, això permetrà en successives exploracions saltar
estos mateixos articles, accelerant així el procés (sempre que no s'haja introduït el paràmetre -force). El nom del fitxer
tindrà la següent aparença: referencies_tocats-AAMMDD-HHMMSS.log
"""
class Browser:
def __init__(self):
self.user_agent=u'Geni ircpybot 1.0'
self.cache_control=u'no-cache'
self.pragma=u'no-cache'
self.accept_charset='utf-8'
def getURL(self, url, user_agent=None, nocache=False, encoding=None):
#"""
#TODO: Fix 404 (and other errors) urllib2.HTTPError: HTTP Error 404: Not Found
#"""
try:
request=urllib2.Request(url)
if user_agent==None:
request.add_header('User-Agent', self.user_agent)
if nocache:
request.add_header('Cache-Control',self.cache_control)
request.add_header('Pragma',self.pragma)
if not encoding: encoding=self.accept_charset
request.add_header('Accept-Charset', encoding)
response=urllib2.urlopen(request)
text=response.read()
response.close()
return text
except:
return ""
B = Browser()
getURL = B.getURL
def getArgs(txt, params=[]):
keys=re.findall(r" (-[^ :\.]+[\.:]?)", txt)
items={}
for key in keys:
next = keys.index(key)+1
if next >= len(keys): next = len(keys)-1
nextkey=keys[next]
items[key]=txt.split(key)[1].split(nextkey)[0].strip()
if key[-1]!=":": items[key]=True
newdict = {}
for item in items:
key = item[1:]
if key[-1] in ":.": key= key[:-1]
value = items[item]
newdict.update({key: value})
for param in params:
if not newdict.has_key(param): newdict[param]=False
return newdict
def getPagesFromURL(url):
html=getURL(url)
pages=re.findall("([^\n<]+)<br />", html)
return pages
def getArticleLinks(filename):
f = codecs.open(filename,"r","utf-8")
txt=f.read()
f.close()
pages=re.findall("\[\[(.+?)(?:\|.+)?\]\]", txt)
return pages
def getLastLog(target):
dir = os.listdir(os.getcwd())
cur_filename = ""
for filename in dir:
if filename.startswith(target) and filename.endswith(".log"):
cur_filename=filename
pages = getArticleLinks(cur_filename) if cur_filename else []
return pages
def getPagesFromFile(filename):
return getLastLog(filename)
def loadReachedPages():
return getLastLog("referencies_tocats")
def order_signs(pages, first, last = None, count = None):
first = first[0].upper()+first[1:] if len(first)>1 else first.upper()
if last: last=last[0].upper()+last[1:] if len(last)>1 else last.upper()
count= int(count) if count else len(pages)
print "s'han trobat %i articles." % len(pages)
site = wikipedia.getSite()
foundFirst=False
modified, scanned = 0, 0
first_scanned, last_scanned = "", ""
unmatched, reached = [], []
for page in pages :
try:
scanned+=1
if scanned > count: break
title = unicode(page,'utf-8')
reached.append(title)
if foundFirst==False and not title.startswith(first): continue
if foundFirst==False:
if count==len(pages): count= len(pages)-scanned
scanned=1
foundFirst=True
if title in excepted: continue
page = wikipedia.Page(site, title)
if not first_scanned: first_scanned=title
wikipedia.output("%i/%i. %s" % (scanned,count,page.aslink()))
try:
txt = page.get()
except wikipedia.IsRedirectPage:
page = page.getRedirectTarget()
title = page.title()
wikipedia.output(u"\tredirigeix a [[%s]]" % page.title())
txt = page.get()
except wikipedia.NoPage:
print "\tno existeix"
continue
rpl_txt=txt
#simplest match (point and interrogation)
rpl_txt = re.sub(r'([.? ])?(<ref[^/>]*>[^<]+</ref>) *([.?])', r"\3\2", rpl_txt)
rpl_txt = re.sub(r'([.? ])?(<ref[^/]+/>) *([.?])', r"\3\2", rpl_txt)
#bang (!! is used in wikitables)
rpl_txt = re.sub(r'(!)?(<ref[^/>]*>[^<]+</ref>) *(!)([^!])', r"\3\2\4", rpl_txt)
rpl_txt = re.sub(r'(!)?(<ref[^/]+/>) *(!)([^!])', r"\3\2\4", rpl_txt)
#ref can got any other embedded tags
rpl_txt = re.sub(r'([.? ])?(<ref[^/>]*>[^<]+(?:<[^/>]+>[^<]+</[^>]+>|<[^/]+/>|<!--[^>]+>)[^<]+</ref>) *([.?])', r"\3\2", rpl_txt)
#repeated signs?
rpl_txt = re.sub(r'[.?!]([.?!])(<ref)', r"\1\2", rpl_txt)
if txt == rpl_txt : #txt == txt1 :
h = page.getVersionHistory(revCount=5)
done=False
for v in h:
summaries = ( u"Robot treu puntuació penjada després de referències",
u'Robot corregint puntuació duplicada darrere de les referències',
u'Robot corregint puntuació postposada a les referències'
)
if v[3] in summaries:
print "\tfet per "+v[2]
done=True
break
if not done and title not in unmatched:
unmatched.append(title)
print "\tno hi ha canvis"
else :
if verbose:
wikipedia.showDiff(txt,rpl_txt)
if not debug:
page.put(rpl_txt, u'Robot corregint puntuació postposada a les referències')
modified+=1
if last and title.startswith(last): break
except KeyboardInterrupt:
break
last_scanned=title
if unmatched:
print "no s'han pogut corregir els següents articles:"
log = codecs.open("referencies_sense_tocar-%s.log" % formatTS("%y%m%d-%H%M%S"),"w","utf-8")
for art in unmatched:
log.write(u"[[%s]]\r\n" % art)
wikipedia.output(art)
unmatched=len(unmatched)
log.write("\r\nTotal: %i" % unmatched)
log.close()
print "total:", unmatched
log = codecs.open("referencies_tocats-%s.log" % formatTS("%y%m%d-%H%M%S"),"w","utf-8")
for art in reached:
log.write(u"[[%s]]\r\n" % art)
reached=len(reached)
log.write("\r\nTotal: %i" % reached)
log.write("\r\nS'han explorat %i articles i s'ha corregit %i" % (scanned,modified))
log.write(u'\r\nPrimera pàgina "%s" darrera pàgina "%s"' % (first_scanned, last_scanned))
print "scanned:", scanned, "modified:", modified
log.close()
def main():
#get pages from a file
filename= params['file']
if filename:
if isinstance(filename, basestring):
pages = getPagesFromFile(filename)
else:
pages = getLastLog("referencies_sense_tocar")
#if file is missing, then get pages from an URL.
else:
url = params['url'] if params['url'] else "http://toolserver.org/~sk/checkwiki/cawiki/cawiki_error_list_error_061.html"
pages = getPagesFromURL(url)
if not pages:
print "No s'ha especificat l'origen de les pàgines a carregar."
return
#start at a specified article from the list
first = params['start'] if params['start'] else pages[0][:1]
#end scannig when exceed count
count = params['count']
#end scanning when reach page
last = params['last']
order_signs(pages, first, last, count)
if __name__ == "__main__":
params = " ".join(sys.argv)
try:
params = unicode(params, "iso-8859-1")
except UnicodeError:
try:
params = unicode(params, "utf-8")
except:
pass
#treat as globals
params = getArgs(params, ["file", "url", "start","count", "last", "force", "debug", "verbose"])
debug=params['debug']
verbose=params['verbose']
_force_complete_scan = params['force']
excepted=loadReachedPages() if not _force_complete_scan else []
main()
wikipedia.stopme()