Usuari:RRHGbot/munic cat taules.py
Aparença
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()