Usuari:RRHGbot/munic cat taules.py
De Viquipèdia
script per canviar les taules HTML dels municipis de Catalunya a templates (Template:taucatCapBE, Template:capentcat) segons Viquiprojecte Municipis de Catalunya
fa servir meta:Using_the_python_wikipediabot pyWikipedia Framework(anglès)
# -*- coding: utf-8 -*-
"""
munic_cat_taules.py
versió: 0.6 - - Localització (des|dels) ...
0.5 - - entcat: canvi condició del bucle per un cas que no es contemplava
- cas de municipis que començen per "el"
0.4 - - determinar tipus de taucat a partir de l'existència de links a imatges o de
links a detalls
- comprovació i avisos de possibles errors
en noms d'imatges i entitats de població
- revertida la supressió d'articles inicials... afegida comprovació de nom
0.3 - entcat: pot aparèixer un nucli amb el mateix nom de l'article sense enllaç
0.2 - un munt de canvis
script per convertir alguns articles de municipis de Catalunya,
que en comptes de {{taucat}} i {{entcat}} fan servir taules HTML
hi havien 737 abans de començar
Ús: munic_cat_taules.py "nom_article" [-e:"inici_entcat"] [-t:"inici_taulacat"]
* "nom_article" el nom de l'article com: "Ribera d'Ondara"
* -e:"inici_entcat" OPCIONAL inici taula entcat, per defecte: "<TABLE WIDTH"
* -t:"inici_taucat" OPCIONAL inici taula taucat, per defecte: "<table border"
NOTES: - aquest script s'ha de fer servir amb el pyWikipediaFramework
- si el programa peta és possible que no hagi trobat alguna taula en el format necessari
"""
import sys
import re
import wikipedia
# en alguns casos els caràcters especials s'han traduït a la forma &aaa; ...
def trn_chars_especials (text):
canvis = [
( u"Á", u"Á"),
( u"À", u"À"),
( u"Ç", u"Ç"),
( u"É", u"É"),
( u"È", u"È"),
( u"Ë", u"Ë"),
( u"Í", u"Í"),
( u"Ï", u"Ï"),
( u"Ó", u"Ó"),
( u"Ò", u"Ò"),
( u"Ö", u"Ö"),
( u"Ú", u"Ú"),
( u"Ù", u"Ù"),
( u"Ü", u"Ü"),
( u"á", u"á"),
( u"à", u"à"),
( u"ç", u"ç"),
( u"é", u"é"),
( u"è", u"è"),
( u"ë", u"ë"),
( u"í", u"í"),
( u"ï", u"ï"),
( u"ó", u"ó"),
( u"ò", u"ò"),
( u"ö", u"ö"),
( u"ú", u"ú"),
( u"ù", u"ù"),
( u"ü", u"ü")
]
for canvi in canvis:
a, b = canvi
text = re.sub(a, b, text)
return text
def extreure_taula (inici, text_origen, rep):
resultat = []
ini = re.compile ( inici ) # re del text_inici_taula a cercar
if rep == 1:
fi = re.compile ( r'</TABLE>', re.IGNORECASE ) # re fi de taula 1
elif rep == 2:
fi = re.compile ( '</TABLE>.*?</TABLE>', re.DOTALL|re.IGNORECASE ) # re fi de taula 2
m = ini.search ( text_origen )
if not m : # no es troba la taula
return ("", 0, 0)
pos_ini = m.start() # posició inicial de la taula
text = text_origen[pos_ini:] # prenem part final del text
n = fi.search ( text )
pos_relativa_fi = n.end() # posició relativa final
taula = text[:pos_relativa_fi] # extreiem la taula
pos_fi = pos_ini + pos_relativa_fi # posició final (absoluta)
taula = trn_chars_especials(taula) # convertir objectes HTML &aaa; de la taula
resultat = (taula, pos_ini, pos_fi)
return resultat
def taula_a_entcat ( inici_taula, text_origen, article, num_ents ):
# comprovar que no hi sigui ja
cond_hi_es = re.compile ( u'\{\{capentcat' )
m = cond_hi_es.search ( text_origen )
if m :
return text_origen
taula, pos_ini, pos_fi = extreure_taula ( inici_taula, text_origen, 1 )
if pos_ini == pos_fi : # no s'ha trobat la taula
return text_origen
# tots els elements de la primera columna son enllaços [[ ]]
# els de la segona estan tots entre <B></B>
# és possible que alguna fila no tingui segon element
# la taula acaba en </table>
cond_segueix = re.compile ( u'(?:(?:\]\])|(?:' + article + u'</FONT>)).*(?:</TABLE>)', re.IGNORECASE|re.DOTALL )
#antiga (cal u"" per unicode...):
#cond_fila = re.compile ( '(\[\[.*?\]\]).*?(?:<B>(.*?)</B>|\[)', re.IGNORECASE|re.DOTALL )
re_text = u'((?:\[\[.*?\]\])|(?:' + article + u')).*?(?:<B>(.*?)</B>|\[)'
cond_fila = re.compile ( re_text, re.IGNORECASE|re.DOTALL )
sortida = "{{capentcat|center}}\n"
n_entt = 0
while cond_segueix.search ( taula ):
n_entt = int(n_entt) + 1
m = cond_fila.search ( taula )
col_1 = m.group(1)
col_2 = m.group(2)
if not col_2 : #si no hi ha segon element es deixa buit
col_2 = ""
sortida = sortida + "{{entcat|" + col_1 + "|" + col_2 + "}}\n"
pos = m.end() - 1
taula = taula[pos:]
sortida = sortida + "{{fientcat}}"
text_modificat = text_origen[:pos_ini] + sortida + text_origen[pos_fi:]
if int(num_ents) != n_entt :
print "\nATENCIÓ: Num. d'entitats de població no coincideix, caldrà edició manual\n"
return text_modificat
def taula_a_taucat ( inici_taula, text_origen, article ):
# comprovar que no hi sigui ja
cond_hi_es = re.compile ( u'\{\{taucatCap' )
m = cond_hi_es.search ( text_origen )
if m :
text_i_ent = (text_origen, 0)
return text_i_ent
taula, pos_ini, pos_fi = extreure_taula ( inici_taula, text_origen, 2 )
if pos_ini == pos_fi : # no s'ha trobat la taula
return (text_origen, 0)
#NOTA: hi han 2 taules, 2x</table> ... ^
#afegeixo paràmetre "rep"etició a extreure_taula() --------------|
# treiem les dades del primer camp de la descripció
# de la imatge de localització
# [[Imatge:Localització_de_Ribera d'Ondara.png|Localització de Ribera d'Ondara respecte la Segarra]]
# [[Imatge:Localització_d'Igualada.png|Localització d'Igualada respecte l'Anoia]]
# [[Imatge:Localització_de_Llívia.png|Localització_de_Llívia respecte la Baixa Cerdanya]]
cond_imatge = re.compile ( u"Imatge:.*?\|Localització[ _](.*?[ _'])(.*?) respecte (.*?[ '])(.*?)\]\]" )
# Osona no porta article (sigh...) el cas general és a dins del proper else
cond_osona = re.compile ( u"Imatge:.*?\|Localització[ _](.*?[ _'])(.*?) respecte Osona\]\]" )
# condició "del" per a municipis que comencin per "El" -> "del"
# [[Imatge:Localització del Masnou.png|Localització del Masnou respecte el Maresme]]
# [Imatge:Localització des Bòrdes.png|Localització des Bòrdes respecte la Vall d'Aran]]
# [[Imatge:Localització_dels Hostalets de Pierola.png|Localització dels Hostalets de Pierola respecte a l'Anoia]]
cond_del = re.compile ( u"Imatge:.*?\|Localització[ _]d((?:el)|(?:es)|(?:els))[ _](.*?) respecte (.*?[ '])(.*?)\]\]" )
m = cond_osona.search ( taula )
n = cond_del.search ( taula )
if m : #som a Osona
cap_1 = m.group(1)
cap_1 = re.sub("_", " ", cap_1) #canvi de "de_Lli" a "de Lli"
cap_2 = m.group(2)
cap_3 = "" #sense article
cap_4 = "Osona"
elif n :
cap_1 = "d"
cap_2 = n.group(1) + " " + n.group(2)
cap_3 = n.group(3)
cap_4 = n.group(4)
else :
m = cond_imatge.search ( taula )
cap_1 = m.group(1)
cap_1 = re.sub("_", " ", cap_1) #canvi de "de_Lli" a "de Lli"
cap_2 = m.group(2)
cap_3 = m.group(3)
cap_4 = m.group(4)
#comprovar si el nom de l'article és igual al grup (2)
#si no ho és quelcom no està be
if not re.search( article, cap_2, re.IGNORECASE ) :
sys.exit( "ERROR: Nom d'article i nom esmentat a localització no coincideixen!" )
#comprovar el tipus de taula, amb o sense bandera o escut
# si hi ha imatges o links a altres articles detallats sobre els símbols
##[[Bandera {{{1}}}{{{2}}}|En detall]]
bandera_nom_pag = "Bandera " + cap_1 + cap_2
escut_nom_pag = "Escut " + cap_1 + cap_2
te_bandera = re.search ( u"Imatge:Bandera", taula )
te_escut = re.search ( u"Imatge:Escut", taula )
pag_ban = wikipedia.Page(wikipedia.getSite(), bandera_nom_pag)
pag_esc = wikipedia.Page(wikipedia.getSite(), escut_nom_pag)
existeix_b = pag_ban.exists()
existeix_e = pag_esc.exists()
#comprovacions manuals
if existeix_b : print "existeix pàg bandera"
if existeix_e : print "existeix pàg escut"
if te_bandera : print "existeix img bandera"
if te_escut : print "existeix img escut"
tipus = ""
if te_bandera or pag_ban.exists():
tipus = tipus + "B"
if te_escut or pag_esc.exists():
tipus = tipus + "E"
sortida = "{{taucatCap" + tipus + "|" + cap_1 + "|" + cap_2 + "|" + cap_3 + "|" + cap_4 + "}}\n"
# gentilici
# <tr><td>[[Gentilici]]</td><td>XXXXX</td></tr>
cond_gentilici = re.compile ( '\[\[Gentilici\]\].*?<td>(.*?)</td>' )
m = cond_gentilici.search ( taula )
gen = m.group(1)
sortida = sortida + "{{taucatGen|" + gen + "}}\n"
# població
# <tr><td>[[Població]] ([[2001]])</td><td>486 hab.</td></tr>
# <tr><td>[[Població]] ([[2001]])</td><td>586</td></tr>
cond_pobl = re.compile ( u'\[\[Població\]\] \(\[\[(.*?)\]\]\).*?<td>(.*?)((?: hab\.)|(?:</td>))' )
m = cond_pobl.search ( taula )
any = m.group(1)
pob = m.group(2)
sortida = sortida + "{{taucatPob|" + str(any) + "|" + str(pob) + "}}\n"
# superfície
# <tr><td>[[Superfície]]</td><td>54'5 Km<sup>2</sup></td></tr>
#<tr><td>[[Àrea]]</td><td>15,44 Km<sup>2</sup></td></tr>
#<tr><td>[[Superfície]]</td><td>14'0 Km<sup>2</sup></td></tr>
#<tr><td>[[Superfície]]</td><td>8,23 km<sup>2</sup></td></tr>
cond_sup = re.compile ( u'(?:(?:\[\[Superfície\]\])|(?:\[\[Àrea\]\])).*?<td>(.*?)(?: )+[kK]m' )
m = cond_sup.search ( taula )
sup = m.group(1)
sup = re.sub("\'", ",", sup) #canvi de 54'5 a 54,5
sortida = sortida + "{{taucatSup|" + sup + "}}\n"
# densitat de població
# <tr><td>[[Densitat de població|Densitat]] ([[2001]])</td><td>8'9</td></tr>
#<tr><td>[[Densitat de població|Densitat]] ([[2005]])</td><td>15.868,86 hab/Km<sup>2</sup></td></tr>
cond_dens = re.compile ( '\|Densitat\]\] \(\[\[(.*?)\]\]\).*?<td>(.*?)(?: hab.*</sup>)*</td>' )
m = cond_dens.search ( taula )
any = m.group(1)
den = m.group(2)
den = re.sub("'", ",", den) #canvi de 8'9 a 8,9
sortida = sortida + "{{taucatDen|" + any + "|" + den + "}}\n"
# altitud
# <tr><td>[[Altitud]]</td><td>581 [[metre|m]]</td></tr>
cond_alt = re.compile ( '\[\[Altitud\]\].*?<td>(.*?)(?: )+\[\[me' )
m = cond_alt.search ( taula )
alt = m.group(1)
sortida = sortida + "{{taucatAlt|" + alt + "}}\n"
# entitats
# <tr><td>Entitats de població</td><td>13</td></tr>
cond_ent = re.compile ( u'Entitats de població.*?<td>(.*?)</td>' )
m = cond_ent.search ( taula )
ent = m.group(1)
sortida = sortida + "{{taucatEnt|" + ent + "}}\n"
sortida = sortida + "{{taucatFi}}"
text_modificat = text_origen[:pos_ini] + sortida + text_origen[pos_fi:]
# comprovem si el nom de les imatges que hi havia a la taula,
# i per consequència al servidor, era "correcte"
err_nom_img = 0
nom_img_loc = u"Localització " + cap_1 + cap_2 + "\.png"
nom_img_loc_b = re.sub ( " ", "[ _]", nom_img_loc)
print "regex nom correcte localització: " + nom_img_loc_b.encode('utf-8')
if not re.search( nom_img_loc_b, text_origen ) :
err_nom_img = 1
if te_bandera :
nom_img_ban = u"Bandera " + cap_1 + cap_2 + " \(petita\)\.png"
nom_img_ban_b = re.sub ( " ", "[ _]", nom_img_ban)
print "regex nom correcte bandera: " + nom_img_ban_b.encode('utf-8')
if not re.search( nom_img_ban_b, text_origen ) :
err_nom_img = 1
if te_escut :
nom_img_esc = u"Escut " + cap_1 + cap_2 + " \(petit\)\.png"
nom_img_esc_b = re.sub ( " ", "[ _]", nom_img_esc)
print "regex nom correcte escut: " + nom_img_esc_b.encode('utf-8')
if not re.search( nom_img_esc_b, text_origen ) :
err_nom_img = 1
vars_ret = (text_modificat, ent, err_nom_img)
return vars_ret
def main():
inici_entcat = "<TABLE WIDTH"
inici_taucat = "<table border"
article = ""
num_ents = 0 #per decidir si cal fer entcat
for arg in sys.argv[1:]:
if arg.startswith('-e:'):
inici_entcat = arg[3:]
elif arg.startswith('-t:'):
inici_taucat = arg[3:]
else:
article = arg
# msg de canvis
wikipedia.setAction( u'Robot: taules -> templates, segons [[Viquipèdia:Viquiprojecte Municipis de Catalunya|]]' )
# pillem la pàgina
if len(article):
# byte_string = unicode_string.encode(encoding)
article = article.decode('utf-8')
page = wikipedia.Page(wikipedia.getSite(), article)
text_orig = page.get()
text = text_orig
else:
sys.exit("ERROR: Falta l'article")
if len(inici_taucat) :
# taucat
text, num_ents, err_nom_img = taula_a_taucat(inici_taucat, text, article)
troba_ent = re.compile ( u'\{\{taucatEnt\|(.*?)\}\}' )
m = troba_ent.search ( text_orig )
if m :
num_ents = m.group(1)
if len(inici_entcat) and ( int(num_ents) > 1 ) :
# entcat
# enviar article (nom del municipi) en el cas que surti a la taula sense enllaç
text = taula_a_entcat(inici_entcat, text, article, num_ents)
if text_orig != text :
if err_nom_img :
print "\nATENCIÓ: El nom d'alguna imatge és incorrecte, cal comprovació manual\n"
raw_input ( "premeu ENTER per veure quins canvis es faran" )
wikipedia.showDiff(text_orig, text)
opcio = wikipedia.inputChoice(u'Vols enviar aquests canvis?', ['Si', 'No'], ['s', 'N'], 'N')
if opcio in ['s', 'S']:
page.put(text)
else :
print "No cal fer canvis en aquest"
if __name__ == "__main__":
try:
main()
finally:
wikipedia.stopme()

