Utilisateur:Daahbot/scripts/format.py
Apparence
# -*- coding: utf-8 -*- # # (C) Daniel Herding, 2004 # # Distributed under the terms of the MIT license. # #################################################################################### # # Version pas mal modifiée pour formater les articles du Wiktionnaire fr # BUT PRINCIPAL : ranger les sections des articles dans l'ordre conventionnel # Peut être éventuellement utilisé pour formater une section ciblée # (par exemple : seulement l'étymologie, seulement les traductions, etc.) # #################################################################################### __version__='$Id' from __future__ import generators import sys, re import wikipedia, pagegenerators, catlib, config from liste_langues import langues # Liste des messages msg = { 'fr':u'Robot : structure des articles', } # Log des différences (nécessite la déf difflog de wikipedia personnalisé) : dossier_log = u"log xml/format/" fichierlog = dossier_log + u"log.txt" # Attribution des clés pour les langues (dont fr, conv et car) : c=0 cl= "0000" langues2 ={} for lang in langues: langues2[cl] = lang c+=1 cl=str(c) if c<10: cl = "0" + cl if c<100: cl = "0" + cl if c<1000: cl = "0" + cl clesl = langues2.keys() clesl.sort() #for c in clesl: # print c, langues2[c], u" ; ", types_de_mot0 = ("nom", "loc-nom", "nom-pr", "adj", "loc-adj", "adj-dem", "adj-indef", "adj-num", "adj-pos", "adv", "loc-adv", "verb", "loc-verb", "pronom", "pronom-def", "pronom-indef", "pronom-int", "pronom-pos", "pronom-pers", "pronom-rel", "art", "art-def", "art-indef", "art-part", "conj", "loc-conj", "prep", "loc-prep", "onoma", "loc", "locution", "prov", "abr", "symb", "class", "part", "post", "suf", "pref", "aff") section_langue = ( (u"etym", "01"), (u"pron", "z2" ), (u"voir", "z5"), (u"réf", "z6"), (u"homo", "z3"), (u"paro", "z4") ) # Pas encore utilisé car pas décidé (et il en manque quelques uns) # Ne pas oublier de donner une clef ! # Voir format_type section_type0 = ("ortho-alt", "syn", "ant", "hyper", "hypo", "hyper", "holo", "mero", "trad", "drv", "apr", "exp", "drv-int", "apr-int") ############################################################ # Deux fonctions utiles de remplacement (dont regex) # ############################################################ def my_repl(original_text, old, new): new_text = original_text try: new_text = old.sub(new, new_text) except: new_text = new_text.replace(old, new) return new_text def my_replex(text0, old, new): old = re.compile(old, re.UNICODE) # changement : new_text = old.sub(new, text0) return new_text def balisage(text, titre): ################################################ # Cette déf balise les sections d'articles # ################################################ # I) BALISAGE DES SECTIONS DE LANGUES # A) Sections générales, langues particulières, etc. text = my_repl(text, u"{{-car-}}", u"{{=:car:=}}") #text = my_repl(text, u"{{=conv=}}", u"{{=:00002conv:=}}") #text = my_repl(text, u"{{=fr=}}", u"{{=:00003fr:=}}") # Autres langues #text = my_replex(text, u"{{=([^:]+?)=}}", r"{{=:\1:=}}") for lang in langues: text = my_repl(text, u"{{="+ lang + u"=}}", u"{{=:"+ lang + u":=}}") # Les catégories aussi : text = my_repl(text, u"[[catégorie:",u"[[Catégorie:") try: categorie_start = re.search(u"\[\[Catégorie\:([^\]]*)\]\]", text).start() text = text[:categorie_start]+ u"{{=:zz3:cat:=}}" + text[categorie_start:] # Si pas de catégories : except: try: interwiki_start = re.search(u"\[\[...?:.+?\]\]", text).start() text = text[:interwiki_start]+ u"{{=:zz3:cat:=}}" + text[interwiki_start:] except: text += u"\n{{=:zz3:cat:=}}" print "Pas de catégorie ni d'interwikis" # B) BALISAGE DES SECTIONS INTRA-LANGUES text = my_repl(text, u"{{-etym-}}", u"{{--:etym:--}}") text = my_repl(text, u"{{-pron-}}", u"{{--:pron:--}}") text = my_repl(text, u"{{-homo-}}", u"{{--:homo:--}}") text = my_repl(text, u"{{-paro-}}", u"{{--:paro:--}}") text = my_repl(text, u"{{-voir-}}", u"{{--:voir:--}}") text = my_repl(text, u"{{-réf-}}", u"{{--:réf:--}}") # Attention : types numérotés ! text = my_replex(text, u"-\|([1-9]+?)\}\}", r"-}}___num_\1__") # Et types for typ in types_de_mot0: text = my_repl(text, u"{{-"+ typ + u"-}}", u"{{--:"+ typ + u":.-}}") # C) Sections intra-type (à faire) return text def debalisage(text, titre): ############################################################ # Cette déf enlève les balises des sections d'articles # ############################################################ # Sections générales text = my_repl(text, u"{{=:car:=}}", u"{{-car-}}") #text = my_repl(text, u"{{=:00002conv:=}}", u"{{=conv=}}") #text = my_repl(text, u"{{=:00003fr:=}}", u"{{=fr=}}") text = my_replex(text, u"{{=:([^:]+?):=}}", r"{{=\1=}}") # Catégories text = my_repl(text, u"\n{{=:zz3:cat:=}}__rien__", u"") text = my_repl(text, u"{{=:zz3:cat:=}}", u"") # Sections intra-langues text = my_repl(text, u"{{--:etym:--}}", u"{{-etym-}}") text = my_repl(text, u"{{--:ron:--}}", u"{{-pron-}}") text = my_repl(text, u"{{--:homo:--}}", u"{{-homo-}}") text = my_repl(text, u"{{--:paro:--}}", u"{{-paro-}}") text = my_repl(text, u"{{--:voir:--}}", u"{{-voir-}}") text = my_repl(text, u"{{--:réf:--}}", u"{{-réf-}}") # Plus celle de la fusion des types, déf format_langue text = my_replex(text, u"{{--:(.+?):.-}}", r"{{-\1-}}") text = my_replex(text, u"{{--:(.+?):--}}", r"{{-\1-}}") # Attention : types numérotés ! text = my_replex(text,u"-}}___num_([1-9][1-9]?)__", r"-|\1}}") return text # C) Sections intra-type (à faire) def format_article(text, titre): ############################################################ # Cette déf formate la structure générale des articles # ############################################################ articles = {} catentro = {} itwentro = {} categories = u'' # Préboulot lourd : rapatrier les catégories qui trainent partout et qui font tout planter mon bot... text, catentro, itwentro = rapatri_cat(text) # I) Séparation de l'article en morceaux parties = text.split(u"{{=:") # Vérification de la teneur des sections séparées for i, p in enumerate(parties): search = re.search(u":=}}", p) # S'il le trouve : c'est une section if search: end = search.start() cle = p[:end] article = u"{{=:" + p # Si cette section n'est pas une section de catégorie : if cle <>"zz3:cat": article = format_langue(article, cle, titre) # Vérification que c'est une langue enregistrée, et dans ce cas on lui donne sa valeur for clf in clesl: if cle == langues2[clf]: cle = clf # Puis enregitrement articles[cle] = article if cle == "zz3:cat": categories = my_repl(article, u"{{=:zz3:cat:=}}", u"") # Sinon c'est le début (normalement) else: articles["0"] = p # Ajout à la section catégorie des éléments cat et int en trop articles["zz3:cat"] = format_cat(categories, titre, catentro, itwentro) resultat = u"" cles = articles.keys() cles.sort() print "\nOrdre : ", for clf in cles: if clf=="0": print "DEBUT", else: try: print langues2[clf], except: print clf, print "\n" # Recommposition de l'article fragmenté ordre simple for c in cles: #print "Tri=", repr(c) resultat += articles[c] return resultat def format_langue(text, lang, titre): ################################################################## # Cette déf formate la structure dans les sections de langue # ################################################################## # Sachant que text est une section de langue bien isolée text = my_replex(text, "\n+", "\n") # Recherche des sous-sections print "\nFormatage de la partie " + lang + " : " parties = text.split(u"{{--:") articles2 = {} # Vérification de la teneur des sections séparées types = u"" for i, n in enumerate(parties): # Types de mot ? search2 = None search2 = re.search(u":\.-}}", n) # S'il le trouve : c'est une section de type de mot if search2 <> None: finom = search2.start() nom = n[:finom] print nom, u"est une section de type" ntyp = format_type(n, lang, titre) types += (u"{{--:" + ntyp) else: #Autres sections search3 = 0 search3 = re.search(u":--}}", n) # S'il le trouve : c'est une section if search3 <> None: end2 = search3.start() cle2 = n[:end2] print cle2, u"est une section non-type, clé = ", for nom, clef in section_langue: if nom == cle2: articles2[clef] = u"{{--:" + n print clef if cle2 == "pron": articles2[clef] = format_pron(articles2[clef], lang, titre) elif cle2 == "etym": articles2[clef] = format_etym(articles2[clef], lang, titre) # Sinon c'est le début (normalement) else: if n <> u"" : cle2 = u"%i" % i articles2[cle2] = n print cle2, u" est le début de la section" # Ajout dans l'articles2 articles2["02"] = types resultat2 = u"" cles2 = articles2.keys() cles2.sort() # Donne le nouvel ordre des clés #print articles2.keys() # Recommposition de l'article fragmenté ordre simple for c in cles2: #print "Tri2=", repr(c) resultat2 += articles2[c] return resultat2 def format_type(text, lang, titre): ################################################################## # Cette déf formate la structure de la section de type de mot # # beta : juste les déf pour le moment, en attendant qu'une # # décision soit prise sur l'ordre des sous-sections. # ################################################################## print u" * Formatage des définitions :\n -> ", text0 = text # Format probablement à refaire à la main if re.search(u"\n##", text): chemf = open(u"log xml/format/bug.txt", "a") titre = u"\n" + text + u"\n" chemf.write(titre.encode('utf8')) chemf.close() text = my_replex(text, u"\n##", r"\n__dou__\n#") text = my_replex(text, u"\n#:", r"\n___ex___") # Boucle pour protéger les term num=0 while num<40: text = my_replex(text, u"\n# \{\{ébauche-déf\|(...?)\}\}", r"\n# Eb_\1__\n") text = my_replex(text, u"\n# ?\{\{(.+?)\}\}", r"\n___term_\1___\n# ") num +=1 # S'il n'y a rien sur la ligne text = my_replex(text, u"\n# ?…\n", u"\n# {{ébauche-déf|" + lang + u"}}\n") # Points en fin de phrase... # D'abord : éviter les espaces en fin de ligne text = my_replex(text, u"(\n.+?) +?(\r)", r"\1\2") text = my_replex(text, u"(\n# [^\r^\n]+?) (\n)", r"\1\2") #text = my_replex(text, u"(\n# ?)(.+?)([^\.^,^:^;^…^\r^\n^'^!^?^>])\r", r"\1\2\3.\n") text = my_replex(text, u"(\n# ?)(.+?[^\.^,^:^;^…^\r^\n^'^!^?^>^\}]) ?\n", r"\1\2.\n") text = my_replex(text, u"(\n# ?)(.+?[^\.^,^:^;^…^\r^\n^'^!^?^>^\}]) ?\n", r"\1\2.\n") # Majuscule en début de phrase... text = my_replex(text, u"(\n# ?)\[\[([^\|^A-Z]+?)\]\]", r"\1[[\2|{{subst:UCFIRST:\2}}]]") text = my_replex(text, u"(\n# ?)'''([^'^A-Z]+?)'''", r"\1'''{{subst:UCFIRST:\2}}'''") text = my_replex(text, u"(\n# ?)([^ ^\[^\{^A-Z^'^(])", r"\1{{subst:UC:\2}}") # Boucle pour déprotéger les term num=0 while num<40: text = my_replex(text, u"\n# Eb_(...?)__\.?\n", u"\n# {{ébauche-déf|" + r"\1}}\n",) text = my_replex(text, u"___term_(.+?)___\.?\n# ", r"# {{\1}}") num +=1 text = my_replex(text, u"___ex___", r"#:") text = my_replex(text, u"\n__dou__\n#", r"\n##") if text0 == text: print "aucun changement" else: print u"changements effectués" return text def format_etym(text, lang, titre): ############################################################ # pour formater la typo de la section d'étymologie # # * format des lignes (ajout point en fin de phrase # # * Ajout d'ébauche # ############################################################ print u" * Formatage de l'étymologie :\n -> ", text0 = text text = my_replex(text, u"(etym:--\}\})\r\n: ?…?\r\n", r"\1" + u"\n: {{ébauche-étym|" + lang + "}}\n") text = my_replex(text, u"(etym:--\}\})\n: ?…?\n", r"\1" + u"\n: {{ébauche-étym|" + lang + "}}\n") # Points en fin de phrase... # D'abord : éviter les espaces en fin de ligne text = my_replex(text, u"(\n.+?) +?(\r)", r"\1\2") # Ensuite : éviter les ébauches if not re.search("ébauche", text): text = my_replex(text, u"(\n: ?)(.+?)([^\.^,^;^…^\r^\n^!^?^>^}]) ?\r", r"\1\2\3.\n") if text0 == text: print "aucun changement" else: print u"changements effectués" return text def format_pron(text, lang, titre): ############################################################### # pour formater la typo de la section de prononciation : # # * format des API / SAMPA # # * Ajout d'ébauche, ou des lignes API/SAMPA si manquantes # # (même si elles sont vides # ############################################################### print u" * Formatage de la prononciation :\n -> ", text0 = text text = my_replex(text, u"\n\*? ?(\{\{API\}\}|\[\[API\]\]|\[\[w:API\|API\]\]) ?:? ?/?([^/]*?)/? ?\n", r"\n* {{API}} : /\2/\n") text = my_replex(text, u"\n\*? ?(\{\{SAMPA\}\}|\[\[SAMPA\]\]|\[\[w:SAMPA\|SAMPA\]\]) ?:? ?/?([^/]*?)/? ?\n", r"\n* {{SAMPA}} : /\2/\n") API = re.search(u"API", text) SAMPA = re.search("SAMPA", text) ebauche = re.search(u"ébauche-pron", text) if not API and not SAMPA: print "Vide : ajouts ébauche-API-SAMPA ; ", if ebauche: text = my_replex(text, u"(pron:--\}\}\r\n\{\{ébauche-pron\|...?\}\})", r"\1" + u"\n* {{API}} : //\r\n* {{SAMPA}} : //\r\n") else: text = my_replex(text, u"(pron:--\}\}\n)", r"\1" + u"{{ébauche-pron|" + lang + "}}\n* {{API}} : //\r\n* {{SAMPA}} : //\r\n") print u"+ ébauche, ", # S'il y a API mais pas de contenu : ajout ébauche if API and re.search(u"\{\{API\}\} : //|\{\{API\}\} : ?\r", text) and not ebauche: print u"ajout d'ébauche : ", #text = my_replex(text, u"(pron:--\}\}\n\* \{\{API\}\} )(: //|:)(\r\n)", r"\1\2\3" + u"{{ébauche-pron|" + lang + u"\}\}\n" + r"\2") text = my_replex(text, u"(pron:--\}\}\n)", r"\1" + u"{{ébauche-pron|" + lang + u"}}\n") # S'il y a déjà API mais pas SAMPA : ajout SAMPA if API and not SAMPA: print "ajout SAMPA ; " text = my_replex(text, u"(pron:--\}\}\n\{\{ébauche-pron\|...?\}\}\n\* \{\{API\}\} : /)([a-z]*?|[a-z]*?\.[a-z]*?|[a-z]*?\.[a-z]*?\.[a-z]*?)(/)", r"\1\2\3" + u"\n* {{SAMPA}} : " + r"/\2/") if not re.search("SAMPA", text): text = my_replex(text, u"(pron:--\}\}\n\{\{ébauche-pron\|...?\}\}\n\* \{\{API\}\} : /.*?/)", r"\1" + u"\n* {{SAMPA}} : //") if not ebauche: if not re.search("SAMPA", text): text = my_replex(text, u"(\* \{\{API\}\} : /)([a-z]*?|[a-z]*?\.[a-z]*?|[a-z]*?\.[a-z]*?\.[a-z]*?)(/)", r"\1\2\3" + u"\n* {{SAMPA}} : " + r"/\2/") if not re.search("SAMPA", text): text = my_replex(text, u"(\* \{\{API\}\} : /.*?/)", r"\1" + u"\n* {{SAMPA}} : //") # S'il y a une ébauche mais pas d'API / SAMPA : if ebauche and not API and not SAMPA: text = my_replex(text, u"(\{\{ébauche-pron\|...?\}\})", r"\1" + u"\n* {{API}} : //\n* {{SAMPA}} : //") if text0 == text: print "aucun changement" else: print u"changements effectués" return text def rapatri_cat(text): ############################################################## # pour rapatrier les cat qui se baladent... # ############################################################## print u"Recherche de catégories qui trainent :\n -> ", text0 = text # Repérage : y a-t-il des catégories qui trainent ? catbal = True catentro = [] while catbal: catbal = re.search(u"\[\[Catégorie:", text) if catbal: # Cat repérée ! Découpage, muolinage et relancé jusqu'à vidange complète debutcat = catbal.start() contenucat = text[debutcat:] fincat = re.search("\]\]", contenucat).start() contenucat = contenucat[:fincat] + "]]" catentro.append(contenucat) text = my_repl(text, contenucat, "") text = my_repl(text, "\n\n", "\n") elif catentro: print u"Catégories repêchées, ", else: print u"Pas de cat, ", # Repérage : y a-t-il des interwikis qui trainent ? itwbal = True itwentro = [] while itwbal: itwbal = re.search(u"\[\[[a-z]{2,3}:", text) if itwbal: # interwiki repérée ! Découpage, muolinage et relancé jusqu'à vidange complète debutitw = itwbal.start() contenuitw = text[debutitw:] finitw = re.search("\]\]", contenuitw).start() contenuitw = contenuitw[:finitw] + "]]" itwentro.append(contenuitw) text = my_repl(text, contenuitw, "") text = my_repl(text, "\n\n", "\n") elif itwentro: print u"Interwikis repêchées. ", else: print u"Pas d'interwiki. ", if catentro: print "cat : ", catentro, if itwentro: print "itw : ", itwentro, # A faire ci-dessus if text0 == text: print "aucun changement" else: print u"changements effectués" return text, catentro, itwentro def format_cat(text, titre, catentro, itwentro): ############################################################## # pour formater la liste des catégories et des interwikis # ############################################################## print u"\nFormatage des catégories :\n -> ", # Ajout des catégories et interwikis qui trainaient #Réunion des cat et interwikis : catot = u'' itot = u'' for cati in catentro: catot += cati for it in itwentro: itot += it text = text + catot + itot text0 = text text = my_replex(text, u"\[\[(C|c)at(e|é)gor(ie|y):([^]]+?)\]\]", r"[[-cat:\4:tac-]]") parties = text.split(u"[[") list_cat = u'' list_itw = u'' ncat=0 nitw=0 for i, p in enumerate(parties): # Nettoyage éventuel p2 = my_replex(p, u"(\n|\r|\n )", r"") # S'il le trouve : c'est une catégorie if re.search(u"-cat:", p2): ncat +=1 list_cat += u"\n[[" + p2 # Sinon : c'est un interwiki elif (p2 <> u""): nitw +=1 list_itw += u"\n[[" + p2 #print "\nlistcat : \n", list_cat #print "\nlistitw : \n", list_itw # Reconstruction des cat et itw text = "\n" if list_cat <> u'': text = text + list_cat if list_itw <> u'': text = text + "\n" + list_itw elif list_itw <> u'': text = text + list_itw text = my_replex(text, u"\[\[-cat:(.+?):tac-\]\]", u"[[Catégorie:" + r"\1]]") print ncat, " cat et ", nitw, "interwikis ; ", if text0 == text: print "aucun changement" else: print u"changements effectués" #print "CAT : \n------\n", text, "\n------\n" return text def corrections(text, titre): ############################################################ # Optionnel, pour corriger toutes sortes d'erreurs # ############################################################ # Un peu de typo complémentaire text = my_repl(text, u"\n{{-", u"\n\n{{-") text = my_repl(text, u"\n\n{{-}}", u"\n{{-}}") # Pour les liens définitions -> synonymes etc. text = my_replex(text, u"\n ?\* ?'?'?'?(.+?)'?'?'? ?\(sens (..?|..?|..?,..?|..?,..?,..?)\) :", r"\n\n'''\1''' (\2) :") text = my_replex(text, u"\n'?'?'?(.+?)'?'?'? ?\(sens (..?|..?|..?,..?|..?,..?,..?)\) :", r"\n\n'''\1''' (\2) :") text = my_replex(text, u"(-\}\})\n+('''.+?''')", r"\1\n\2") text = my_repl(text, u"\n{{=", u"\n\n{{=") text = my_repl(text, u"=}}\n\n{{-", u"=}}\n{{-") text = my_replex(text, u"(\{\{ébauche\|[^\}]+?\}\}\n)\n", r"\1") return text def corrections2(text, titre): ###################################################################### # Optionnel, autres corrections sans rapport avec la structure # ###################################################################### # Lien Wikipédia text = my_replex(text, u"\* \[\[w:(.+?)\|(.+?)]] sur Wikipédia", r"{{WP|\1|\2}}") text = my_replex(text, u"\* \[\[w:(.+?)]] sur Wikipédia", r"{{WP|\1|\1}}") text = my_replex(text, u"\n\*? ?\{\{Wikipé?e?dia\}\}", r"\n{{WP}}") # Tableau modèle simple text = my_replex(text, u'\{\| border=0 width=100%\n\|-\n\|bgcolor=.+? valign=top width=48% style="border:1px solid #aaaaaa; padding:5px;" \|\n\{\|', r'{{(}}') text = my_replex(text, u'\|\}\n\| width=1% \|\n\|bgcolor=.+? valign=top width=48% style="border:1px solid #aaaaaa; padding:5px;" \|\n\{\|', r'{{-}}') text = my_repl(text, u'|}\n|}', r'{{)}}') # Correction import allemand raté text = my_repl(text, u"/}}, ''Plural:'' {{Lauʦchrift|/", u"//") text = my_repl(text, u"/}}, ''Plural:'' {{Lauts)chrift|/", u"//") text = my_repl(text, u"/}}, {{Pl./", u"//") return text def post_corrections(text, titre): ###################################################################### # Correction pour que le bot fonctionne mieux # ###################################################################### # élimination de tous les espaces text = my_replex(text, u"[\r\n]+", u"\n") # Modèles de sections standards text = my_replex(text, u"\{\{-locution-\| ?adverbiale? ?\}\}", "{{-loc-adv-}}") text = my_replex(text, u"\{\{-locution-\| ?\}\}", "{{-loc-}}") text = my_replex(text, u"\{\{-article-\|indéfini\}\}", "{{-art-indef-}}") text = my_repl(text, u"{{-article-|indéfini}}", "{{-art-indef-}}") text = my_repl(text, u"{{-article-|indéfini}}", "{{-art-indef-}}") text = my_replex(text, u"\{\{-article-\|défini\}\}", "{{-art-def-}}") text = my_replex(text, u"\{\{-article-\|partitif\}\}", "{{-art-part-}}") text = my_replex(text, u"===?=? ?(v|V)oir aussi ?===?=?", r"{{-voir-}}") # Divers text = my_replex(text, u"(\{\{ébauche-[^\}]+?\}\}) ?(\{\{-)", r"\1\n\2") return text def processus(resultat, titre): ############################# # Processus complet # ############################# resultat = post_corrections(resultat, titre) resultat = balisage(resultat, titre) print "\n\n" + 100*"=" + "\n\n" resultat = format_article(resultat, titre) resultat = debalisage(resultat, titre) resultat = corrections(resultat, titre) resultat = corrections2(resultat, titre) # Affiche a page complète pour vérifier la mise en page titre = "\r\n" + 100*"-" + "\r\n" + resultat + "\r\n" + 100*"-" + "\r\n" wikipedia.output(titre) #print titre return resultat ################################################################## # Vérifie que le titre est bien normal (hors annexe surtout) # ################################################################## def check_titre(titre): saute = False excep = ["Annexe:", "Utilisateur:", "Discussion Utilisateur:"] for sau in excep: if re.search(sau, titre): saute = True return saute ################################################################## # Vérifie que le texte est réellement modifié (problème avec # # les regex observé) # ################################################################## def check_diff(avant, apres): saute = False avant = my_replex(avant, "\r|\n", "") apres = my_replex(apres, "\r|\n", "") if avant == apres: saute = True return saute #--------------------------------------------------------------- # Suite : normal #--------------------------------------------------------------- class ReplaceRobot: def __init__(self, generator, replacements, exceptions = [], regex = False, acceptall = False): self.generator = generator self.replacements = replacements self.exceptions = exceptions self.regex = regex self.acceptall = acceptall def checkExceptions(self, original_text): """ If one of the exceptions applies for the given text, returns the substring which matches the exception. Otherwise it returns None. """ for exception in self.exceptions: if self.regex: hit = exception.search(original_text) if hit: return hit.group(0) else: hit = original_text.find(exception) if hit != -1: return original_text[hit:hit + len(exception)] def doReplacements(self, original_text): """ Returns the text which is generated by applying all replacements to the given text. """ new_text = original_text for old, new in self.replacements: if self.regex: new_text = old.sub(new, new_text) else: new_text = new_text.replace(old, new) return new_text def run(self): """ Lance le robot. """ # Run the generator which will yield Pages which might need to be # changed. for page in self.generator: try: # Chargement depuis le wiki original_text = page.get() match = self.checkExceptions(original_text) if not page.canBeEdited(): wikipedia.output(u'Je saute la page protégée %s' % page.title()) continue except wikipedia.NoPage: wikipedia.output(u'Je n\'ai pas trouvé la page %s' % page.title()) continue except wikipedia.IsRedirectPage: continue match2 = check_titre(page.title()) # test match2 = False # SAute les pages qui ont des exceptions de contenu, de titre ou des <!-- (difficile à gérer par bot) if not re.search(u"pron", original_text): wikipedia.output(u' %s sautée car ne contient pas de prononciation' % (page.title())) chemin = open("log xml/format/nopron-.txt", "a") chemin.write("\n* [[" + page.title().encode('utf8') + "]]") chemin.close() elif match: wikipedia.output(u' %s sautée car exception' % (page.title())) elif match2: wikipedia.output(u' %s sautée car le titre n\'est pas dans le namespace général' % (page.title())) elif re.search(u"<!--", original_text): wikipedia.output(u' %s sautée car le texte contient des <!-- (logué)' % (page.title())) chemin = open("log xml/format/bug-.txt", "a") titre = page.title().encode('utf8') chemin.write("\n* [[" + titre + "]]") chemin.close() else: ################################################################# # Processus de formatage : new_text = processus(original_text, page.title()) ################################################################# if new_text == original_text: wikipedia.output(u'Aucun changements nécessaires dans %s' % page.title()) if check_diff(original_text, new_text): wikipedia.output(u'Aucun changements nécessaires dans %s (vérification de deuxième ordre)' % page.title()) else: wikipedia.output(u'<<<>>> %s <<<>>>>' % page.title()) wikipedia.showDiff(original_text, new_text) textdiff = wikipedia.textDiff(original_text, new_text, page.title()) pronoui = re.search("pron", textdiff) if not pronoui: for typ in types_de_mot0: pron1 = re.search(typ, textdiff) if pron1: pronoui = True if not pronoui: if not self.acceptall: choice = wikipedia.inputChoice(u'Pas de prononciation changée, loguer ou continuer ?', ['Log', 'Cont', 'All'], ['l', 'c', 'a'], 'N') if choice in ['c', 'C']: print "Passé sans changé ni logé" if choice in ['a', 'A']: self.acceptall = True if self.acceptall or choice in ['l', 'L']: chemin = open("log xml/format/paspron.txt", "a") titre = page.title().encode('utf8') chemin.write("\n* [[" + titre + "]]") chemin.close() elif not self.acceptall and pronoui: choice = wikipedia.inputChoice(u'Accepter les changements ?', ['Yes', 'No', 'All'], ['y', 'N', 'a'], 'N') if choice in ['a', 'A']: self.acceptall = True if pronoui: if self.acceptall or choice in ['y', 'Y']: page.put(new_text) wikipedia.logDiff(original_text, new_text, page.title(), fichierlog) def main(): gen = None # Choix de l'origine de la liste des pages à changer source = None # Un tableau qui reçoit les paramètres de la ligne de commande directement : # Le premier est le texte à changer, le second le remplacement # INUTILE POUR UNE UTILISATION AVANCEE commandline_replacements = [] # Liste de remplacements (et non pas seulement deux) replacements = [] # Textes d'exceptions exceptions = [] # Choix d'utilisation des expressions régulières pour les remplacements et les exceptions : oui/non regex = False # Remplacements prédéfinis : oui/non fix = None # the dump's path, either absolute or relative, which will be used when source # is 'xmldump'. textfilename = None # Nom de la catégorie si la liste des changements en est une categoryname = None # pages données à modifier via la ligne de commande pageNames = [] # Page de référence via sa liste de suivi referredPageName = None # Oui quand always: ou quand on demande a acceptall = False # quel namespace ? Rien par défaut pour : tous namespaces = [] # Page de départ pour le paramètre start startpage = None # Résumé par défaut msg (début de prog) wikipedia.setAction(wikipedia.translate(wikipedia.getSite(), msg)) # Lecture de la ligne de commande à la recherche d'arguments for arg in sys.argv[1:]: arg = wikipedia.argHandler(arg, 'replace') # Y a-t-il des paramètres ? if arg: # Si expressions régulières if arg == '-regex': regex = True # un fichier de texte donné elif arg.startswith('-file'): if len(arg) == 5: textfilename = wikipedia.input(u'Please enter the filename:') else: textfilename = dossier_log + arg[6:] source = 'textfile' # Une catégorie donnée elif arg.startswith('-cat'): if len(arg) == 4: categoryname = wikipedia.input(u'Please enter the category name:') else: categoryname = arg[5:] source = 'category' # Une page donnée elif arg.startswith('-page'): if len(arg) == 5: pageNames.append(wikipedia.input(u'Which page do you want to chage?')) else: pageNames.append(arg[6:]) source = 'singlepage' # Liste de suivi d'une page donnée elif arg.startswith('-ref'): if len(arg) == 4: referredPageName = wikipedia.input(u'Links to which page should be processed?') else: referredPageName = arg[5:] source = 'ref' # Pour faire toutes les pages à partir de... elif arg.startswith('-start'): if len(arg) == 6: firstPageTitle = wikipedia.input(u'Which page do you want to chage?') else: firstPageTitle = arg[7:] source = 'allpages' # Donner une exception elif arg.startswith('-except:'): exceptions.append(arg[8:]) # Pour faire un remplacement pré-défini elif arg.startswith('-fix:'): fix = arg[5:] # Ne pas demander s'il faut changer elif arg == '-always': acceptall = True # ne remplacer que dans un namespace spécifique elif arg.startswith('-namespace:'): namespaces.append(int(arg[11:])) # SINON le paramètre est enregistré dans commandline_replacements else: commandline_replacements.append(arg) # Si on a bien deux paramètres jouant le rôle de texte à remplacer et de texte de remplacement, alors on les met dans les changements à effectuer if (len(commandline_replacements) == 2 and fix == None): replacements.append((commandline_replacements[0], commandline_replacements[1])) # Fabrication d'un message automatique dans ce cas-là -... +... wikipedia.setAction(wikipedia.translate(wikipedia.getSite(), msg ) % ' (-' + commandline_replacements[0] + ' +' + commandline_replacements[1] + ')') # Si aucune source n'est donnée, on les demande #elif fix == None: # old = wikipedia.input(u'Texte à remplacer :') # new = wikipedia.input(u'Texte de remplacement :') # change = '(-' + old + ' +' + new # replacements.append((old, new)) # while True: # old = wikipedia.input(u'Tapez un nouveau texte ou bien entré pour continuer :') # if old == '': # change = change + ')' # break # new = wikipedia.input(u'Nouveau texte :') # change = change + ' & -' + old + ' +' + new # replacements.append((old, new)) # default_summary_message = wikipedia.translate(wikipedia.getSite(), msg) % change # wikipedia.output(u'Résumé par défaut : %s' % default_summary_message) # summary_message = wikipedia.input(u'Message par défaut ou taper un message personnalisé :') # if summary_message == '': # summary_message = default_summary_message # wikipedia.setAction(summary_message) #else: # Compilation des expressions pour gagner du temps if regex: for i in range(len(replacements)): old, new = replacements[i] oldR = re.compile(old, re.UNICODE) replacements[i] = oldR, new for i in range(len(exceptions)): exception = exceptions[i] exceptionR = re.compile(exception, re.UNICODE) replacements[i] = exceptionR # Création des listes des pages à changer à partir des sources # fichier texte if source == 'textfile': gen = pagegenerators.TextfilePageGenerator(textfilename) # Catégorie elif source == 'category': cat = catlib.Category(wikipedia.getSite(), categoryname) gen = pagegenerators.CategorizedPageGenerator(cat) # Une page elif source == 'singlepage': pages = [wikipedia.Page(wikipedia.getSite(), pageName) for pageName in pageNames] gen = iter(pages) # Toutes les pages elif source == 'allpages': namespace = wikipedia.Page(wikipedia.getSite(), firstPageTitle).namespace() gen = pagegenerators.AllpagesPageGenerator(firstPageTitle, namespace) # Une référence elif source == 'ref': referredPage = wikipedia.Page(wikipedia.getSite(), referredPageName) gen = pagegenerators.AllReferringPageGenerator(referredPage) # S'il n'y a aucune source : montrer l'aide elif source == None or len(commandline_replacements) not in [0, 2]: # syntax error, show help text from the top of this file wikipedia.output(__doc__, 'utf-8') wikipedia.stopme() sys.exit() # Si l'on donne un namespace, on restreint alors la liste générée avec un filtre if namespaces != []: gen = pagegenerators.NamespaceFilterPageGenerator(gen, namespaces) # On charge la liste gen, avec un nombre de... preloadingGen = pagegenerators.PreloadingGenerator(gen, pageNumber = 20) # Mise en place du robot à partir de tous les éléments donnés bot = ReplaceRobot(preloadingGen, replacements, exceptions, regex, acceptall) # Lancement ! bot.run() if __name__ == "__main__": try: main() finally: wikipedia.stopme()