Χρήστης:Lou bot/catauto/script
Μετάβαση στην πλοήγηση
Πήδηση στην αναζήτηση
#-*- coding: utf-8 -*- ################################################################# # Σκοπός: αλλαγή των κατηγοριών προτύπων του λόγου # με αυτόματη κατηγοριοποίηση χάρη στα πρότυπα τίτλων τομέα # στο ελληνικό Βικιλεξικό # # Χρησιμοποιούνται ASCII για το ελληνικό και λατινικό αλφάβητο # # Το bot χρειάζεται την pywikipedia # Σημείωση: μερικά κομμάτια του κώδικα προέρχονται # από το replace.py της pywikipedia # (run της class LectureRemplacement και main), # αλλά έχουν τροποποιηθεί ελαφρά. # #--------------------- # Παράμετροι: #--------------------- # - show : εάν 'true', οι τίτλοι παρουσιάζονται # (αλλά το script γίνεται πιο αργό) show = True # commentaire = u"Αυτόματη κατηγοριοποίηση των προτύπων των τίτλων" # ################################################################## # Τα scripts τοποθετούνται σε διαφορετικό directory # από την pywikipedia # Οι πληροφορίες χωρίζονται σε πολλά directory # 1 directory ΒΛ στο ίδιο directory με την pywikipedia # περιέχει τα directory data, temp, logs, scripts from __future__ import generators import sys, re sys.path.append('../pywikipedia') sys.path.append('../data') import os import time # Ανάκτηση των δεδομένων os.chdir('../data') from lists import majASCII, asciis, asciisation, ponctascii, ex_lang, exceptions, types, nom_types # Το αρχείο lists πρέπει να είναι παρόν στο directory data # Ανάκτηση αρχής και τέλους # Αρχείο stop st = open('stop', 'r') stop = unicode(st.read(), 'utf-8') stop = stop[:-1] st.close # Αρχείο start_page st = open('start_page', 'r') start_page = unicode(st.read(), 'utf-8') st.close os.chdir("..") # Εισαγωγή των modules της pywikipedia os.chdir('../pywikipedia') import wikipedia, pagegenerators, catlib, config, watchlist os.chdir('../wiktio') # Directory εργασίας os.chdir('temp') #----------------------------------------------------------- class LectureRemplacement: """ Ρομπότ που κάνει αντικατάσταση κειμένου """ def __init__(self, generator, acceptall = False): """ Παράμετροι: * generator - Γεννήτρια που φέρνει τις σελίδες * acceptall - Εάν "True", δεν ρωτά επιβεβαίωση σε κάθε αλλαγή """ self.generator = generator self.acceptall = acceptall def ChangeArticles(self, text, titre): """ 1) Προσθέτει τη γλώσσα στους τίτλους μερών του λόγου 2) Προσθέτει το ASCII στους τίτλους μερών του λόγου 3) Αφαιρεί τις κατηγορίες που δημιουργήθηκαν αυτόματα από τους τίτλους """ cat = False # Επαληθεύει την παρουσία κατηγοριών # Αναζητεί και απομονώνει τις κατηγορίες, εάν αυτές υπάρχουν try: text = repl(text, u"[[κατηγορία:",u"[[Κατηγορία:") # εναρμονίζει category_start = re.search(u"\[\[Κατηγορία:([^\]]*)\]\]", text).start() text = text[:category_start]+ u"{{=:cat:=}}\n" + text[category_start:] cat = True # Υπάρχουν κατηγορίες except: #Affiche(u"Δεν υπάρχουν κατηγορίες σε αυτή τη σελίδα") 0 # Διαχωρισμός τομέων γλώσσας parties = text.split("{{=") selection = u"" langues = {} # λίστα τομέων γλωσσών text_final = "" # θα περιέχει το τελικό άρθρο valeur = {} # τύπος του τομέα nombre_titre = 0 # μετρά τους τίτλους τομέων n = 0 # μετρά τις κατηγορίες difference = 0 # διαφορά ανάμεσα στις δύο μετρήσεις titrascii = '' # μετάφραση του τίτλου σε ASCII askiwi = '' error = '' titrascii_commun = '' askiwi_commun = '' error_commun = '' # τομείς γλωσσών στο άρθρο for i, p in enumerate(parties): p = replex(p, u"^[^\{](.+?=)\|.*?(\}\})", r"\1\2") trouve = re.search("=}}", p) if trouve: fin = trouve.start() nom = p[:fin] langues[nom] = "{{=" + p valeur[n] = nom else: langues["0"] = p valeur[n] = "0" n+=1 # τύποι σε κάθε τομέα γλώσσας for z, i in enumerate(langues): if i == "conv" or i == "ine": continue if i <> ":cat:" and i<>"0": # Cas particuliers ? if i in ex_lang.keys(): titrascii, askiwi, error = self.NormASCII(titre, i) elif not titrascii_commun: titrascii_commun, askiwi_commun, error_commun = self.NormASCII(titre, 0) titrascii = titrascii_commun askiwi = askiwi_commun error = error_commun else: titrascii = titrascii_commun askiwi = askiwi_commun error = error_commun typesec = langues[i].split("{{-") for m, sec in enumerate(typesec): if m<>0: sec = "{{-" + sec trouve = re.search("-.*?\}\}", sec) tit = "" if trouve: tit = sec[:trouve.end()] # D'une part s'il y a besoin d'ajouter l'ASCII if askiwi: for section in types: # τομέας με γλώσσα και ASCII (αντικαθιστά το ASCII) tit = replex(tit, "(\{\{-" + section +"-\|)"+i+"\|[^}\|=]+(\}\}|num=[0-9]\}\})", r"\1"+i+"|"+titrascii+r"\2") # τομέας με γλώσσα χωρίς ASCII (προσθέτει το ASCII) tit = replex(tit, "(\{\{-" + section +"-\|)"+i+"(\}\}|num=[0-9]\}\})", r"\1"+i+"|"+titrascii+r"\2") # τομέας χωρίς γλώσσα αλλά με ASCII (προσθέτει τη γλώσσα, αντικαθιστά το ASCII) tit = replex(tit, "(\{\{-" + section +"-\|)\|[^}\|=]+(\}\}|num=[0-9]\}\})", r"\1"+i+"|"+titrascii+r"\2") # τομέας χωρίς γλώσσα ούτε ASCII (προσθέτει γλώσσα και ASCII) tit = replex(tit, "(\{\{-" + section +"-)(\}\}|\|num=[0-9]\}\})", r"\1|"+i+"|"+titrascii+r"\2") # Διαφορετικά, εάν δεν χρειάζεται ASCII else: for section in types: # τομέας με γλώσσα και ASCII (αφαιρεί το ASCII) tit = replex(tit, "(\{\{-" + section +"-\|)"+i+"\|[^}\|=]+(\}\}|\|num=[0-9]\}\})", r"\1"+i+r"\2") # τομέας με γλώσσα χωρίς ASCII (προσθέτει τη γλώσσα) tit = replex(tit, "(\{\{-" + section +"-\|)"+i+"(\}\}|\|num=[0-9]\}\})", r"\1"+i+r"\2") # τομέας χωρίς γλώσσα αλλά με ASCII (προσθέτει γλώσσα, αφαιρεί ASCII) tit = replex(tit, "(\{\{-" + section +"-\|)\|[^}\|=]+(\}\}|\|num=[0-9]\}\})", r"\1"+i+r"\2") # τομέας χωρίς γλώσσα ούτε ASCII (προσθέτει τη γλώσσα) tit = replex(tit, "(\{\{-" + section +"-)(\}\}|\|num=[0-9]\}\})", r"\1|"+i+r"\2") typesec[m] = tit + sec[trouve.end():] else: typesec[m] = sec langues[i] = '' ; for n in range(len(typesec)): langues[i] += typesec[n] if i == ":cat:": # εάν υπάρχουν κατηγορίες langues[i] = replex(langues[i], '^.+?:cat:=\}\}', '') langues[i] = replex(langues[i], '\n\n+', '') # Συγκεντρώνει τους τομείς γλώσσας for z, i in enumerate(valeur): text_final += langues[valeur[i]] # Αφαιρεί τις γραμματικές κατηγορίες που γίνονται πια αυτόματα for ty in nom_types: text_final = replex(text_final, u"(\r\n+)?\[\[Κατηγορία:" + ty + " en .+?\]\]\n?", "") # Suppression des catégories langues seules (=seul rôle ASCII), prises en compte dans les modèles # {{Προσοχή! Δεν ισχύει παρά στα κανονικά άρθρα με τουλάχιστον έναν κανονικό τίτλο # Note : toutes les catégories contenant une minuscule sont considérées comme des langues text_final = replex(text_final, u"(\r\n+)?\[\[Κατηγορία:[a-zéèà].+?\|(.+?)\]\]\n?", "") # Άχρηστες και παρασιτικές κατηγορίες text_final = replex(text_final, u"(\r\n+)?\[\[Κατηγορία:[a-zéèà].+?\]\]\n?", "") # Καθαρίζει τα πρόσθετα κενά text_final = replex(text_final, u"\r?\n\r?\n\r?\n\r?\n?\r?\n?", "\r\n\r\n\r\n") return text_final, titrascii, error def NormASCII(self, expression, langue): """ Μεταγράφει τον όρο (όνομα του άρθρου) σε ASCII για μια σωστή κατηγοριοποίηση """ expressionA = expression # Στίξη for s, t in ponctascii: expressionA = replex(expressionA, s, t) # Μεταγραφή σε ASCII if langue: for s, t in ex_lang[langue]: expressionA = replex(expressionA, s, t) else: for s, t in asciisation: expressionA = replex(expressionA, s, t) expressionA = self.minusASCII(expressionA) expressionB = self.minusASCII(expression) error = False askiwi = False # Επαληθεύει εάν ο τίτλος είναι ήδη σε ASCII (άρα δεν χρειάζεται αντικατάσταση) if expressionA == expressionB: askiwi = False error = False print "Titre déjà en ascii :", expressionA # Επαληθεύει εάν ο νέος τίτλος είναι ολόκληρος σε ascii elif not self.isASCII(expressionA) and not langue: askiwi = False error = True print "Μη ASCII αλλαγμένος τίτλος: ", expressionA else: askiwi = True error = False return expressionA, askiwi, error def minusASCII(self, terme): """ Μετατρέπει μόνο τα ASCII σε πεζά γράμματα """ for s, t in majASCII: terme = repl(terme, s, t) return terme def isASCII(self, text): """ Επαληθεύει εάν το κείμενο περιέχει τους επιτρεπόμενους χαρακτήρες ascii """ isasc = True for i in range(len(text)): ascok = False for a in asciis: if a == text[i]: ascok = True break if ascok == False: isasc = False break return isasc def run(self): """ Κάνει τη δουλειά """ Affiche(u"Άντε να δουλέψουμε και λίγο!!") ancien= "" for page in self.generator: if page.title() == stop: Affiche(u""+stop+u" έγινε, σταματώ το bot.") break st = open('../data/start_page', 'w') st.write(page.title().encode('utf-8')) st.close try: ancien = page.get() if not page.canBeEdited(): wikipedia.output(u'Αφήνω την προστατευμένη σελίδα %s' % page.title()) except wikipedia.NoPage: wikipedia.output(u'Η σελίδα %s δεν υπάρχει' % page.title()) except wikipedia.IsRedirectPage: wikipedia.output(u'Η σελίδα %s είναι ανακατεύθυνση' % page.title()) continue titre = page.title() continuer = True for sauf in exceptions: try: if re.search(sauf, titre): continuer = False break except: Affiche("Λάθος στο " + titre + " με " + sauf) wikipedia.output("Λάθος στο " + titre + " με " + sauf) continue nouveau, ascii, error = self.ChangeArticles(ancien, titre) if error: wikipedia.output(u"Η σελίδα περιέχει χαρακτήρες που δεν αναγνωρίζονται: %s | %s" % (titre, ascii)) #conterror = wikipedia.input(u'Να συνεχίσω; (y/n)') #if (conterror == 'n' or conterror == 'N'): # break if replex(nouveau, "\r|\n", "") == replex(ancien, "\r|\n", "") or not continuer: Affiche(u"Δεν χρειάζονται αλλαγές στο %s" % titre) else: wikipedia.output('>>> %s <<<' % (titre)) Affiche('%s -> %s' % (titre, ascii)) wikipedia.output(unicode(time.strftime("%Hh%M | %D"), 'utf8')) wikipedia.showDiff(ancien, nouveau) # if difference > 0: # if difference == 1: # Affiche(u">> Προσοχή: φαίνεται πως 1 κατηγορία σβήστηκε χωρίς αντιστάθμισμα!\n") # else: # Affiche(u">> Προσοχή: φαίνεται πως %s κατηγορίες σβήστηκαν χωρίς αντιστάθμισμα!\n" % difference) # if difference < 0: # difference = -difference # if difference == 1: # Affiche(u">> Σημείωση: φαίνεται πως έλειπε 1 κατηγορία.\n") # else: # Affiche(u">> Σημείωση: φαίνεται πως έλειπαν %s κατηγορίες.\n" % difference) if not self.acceptall: choice = wikipedia.inputChoice(u'Δέχεστε τις αλλαγές?', ['Yes', 'No', 'All'], ['y', 'N', 'a'], 'N') if choice in ['a', 'A']: self.acceptall = True if self.acceptall or choice in ['y', 'Y']: page.put(nouveau, comment = commentaire, minorEdit = True) Affiche(u"Bien joué !\n") Affiche(u"Τελειώσαμε κιόλας;") def repl(original_text, old, new): """ Εργαλεία ανταλλαγής απλού κειμένου (χωρίς regular expressions) """ try: new_text = old.sub(new, original_text) except: new_text = original_text.replace(old, new) return new_text def replex(texte, avant, apres): """ Εργαλεία ανταλλαγής κειμένου με regular expressions """ avant = re.compile(avant, re.UNICODE) texte = avant.sub(apres, texte) return texte def Affiche(texte): """ Δεν εμφανίζει τα σχόλια παρά εάν "Σχόλια" είναι ενεργοποιημένο """ if show: try: print unicode(texte, 'utf-8') except: print texte # wikipedia.output(texte) return def compte(texte, motif): """ Μετρά τον αριθμό μοτίβων στο κείμενο """ occurence = 0 n=0 while n<len(texte)-len(motif): x=0 mot = u"" while x<len(motif): mot += texte[n+x] x += 1 if mot == motif: occurence +=1 n +=1 return occurence def main(): """ Μπορούν να χρησιμοποιηθούν οι εξής παράμετροι: -start -page -ref -cat -from και: -all """ acceptall = False namespaces=["0"] gen = None PageTitles = [] for arg in sys.argv[1:]: arg = wikipedia.argHandler(arg, 'catauto') if arg: if arg.startswith('-start'): if len(arg) == 6: firstPageTitle = wikipedia.input(u'Από ποια σελίδα να αρχίσω;') else: firstPageTitle = arg[7:] namespace = wikipedia.Page(wikipedia.getSite(), firstPageTitle).namespace() gen = pagegenerators.AllpagesPageGenerator(firstPageTitle, namespace) elif arg.startswith('-from'): firstPageTitle = start_page namespace = wikipedia.Page(wikipedia.getSite(), firstPageTitle).namespace() gen = pagegenerators.AllpagesPageGenerator(firstPageTitle, namespace) elif arg.startswith('-page'): if len(arg) == 5: PageTitles.append(wikipedia.input(u'Ποια σελίδα να αλλάξω;')) else: PageTitles.append(arg[6:]) pages = [wikipedia.Page(wikipedia.getSite(), PageTitle) for PageTitle in PageTitles] gen = iter(pages) elif arg.startswith('-ref'): if len(arg) == 4: referredPageTitle = wikipedia.input(u'Ποια σελίδα χρησιμεύει ως αναφορά;') else: referredPageTitle = arg[5:] referredPage = wikipedia.Page(wikipedia.getSite(), referredPageTitle) gen = pagegenerators.ReferringPageGenerator(referredPage) elif arg.startswith('-cat'): if len(arg) == 4: categoryname = wikipedia.input(u'Όνομα της κατηγορίας: ') else: categoryname = arg[5:] cat = catlib.Category(wikipedia.getSite(), 'Category:%s' % categoryname) gen = pagegenerators.CategorizedPageGenerator(cat) if arg.startswith('-all'): acceptall = True if not gen: firstPageTitle = start_page namespace = wikipedia.Page(wikipedia.getSite(), firstPageTitle).namespace() gen = pagegenerators.AllpagesPageGenerator(firstPageTitle, namespace) # syntax error, show help text from the top of this file #wikipedia.output(__doc__, 'utf-8') #wikipedia.stopme() #sys.exit() preloadingGen = pagegenerators.PreloadingGenerator(gen, pageNumber = 10) bot = LectureRemplacement(preloadingGen, acceptall) bot.run() if __name__ == "__main__": try: main() finally: wikipedia.output(u"\nΤέλος της διαδικασίας.\n") wikipedia.stopme()