Progetto:Bot/Programmi in Python per i bot/cronAlebot.py

Da Wikisource.
#!/usr/bin/env python 
# -*- coding: utf-8 -*-
#$ -m bae
#$ -m ae

import os,sys
import shutil
import wikipedia
import pickle
import time
import urllib
import re
global bot,pagineToccate,ncicl
aposTipo=u'\u2019'


## versione minimale di aubrey, da far correre su toolserver in uno screen
## la gestione delle pagine Pagina:

bot="Alebot"
pagineToccate=[]
ncicl=1
autoreCitato={}
test=False
tipoStringa=type("")
tipoLista=type([])
tipoDizionario=type({})

# Parte attiva del programma
def main():
    autoreCitato=estraiSectionAc()
    print "Eseguita estrazione autoreCitato: n=",len(autoreCitato)
    argomenti=wikipedia.handleArgs()
    if argomenti==[]:
        rcSession()
    else:
        test=True
        print "Argomenti:",argomenti
        arg=argomenti[0]
        if arg.startswith("-pag:"):
            # legge una pagina e estrae tutti i nomi pagina fra doppie quadre
            lista=produci_lista(leggi_pagina(arg[5:]),"[[","]]",0)
            print lista
            
        elif arg.startswith("-file:"):
            # legge un file locale e estrae tutti i nomi pagina fra doppie quadre
            
            lista=unicode(open(arg[6:]).read(),"utf8")
            lista=produci_lista(lista,"[[","]]",0)
            print lista
        elif arg.startswith("-interattivo"):
            # legge un file locale e estrae tutti i nomi pagina fra doppie quadre
            p=""
            while not p=="fine":
                p=raw_input("pagina da elaborare (fine per finire):")
                if p!="fine":
                    p=unicode(p,"utf8")
                    elabora(wikipedia.Page("it",p))
            return
                            
            
        else:
            lista=[argomenti[0]]
            
        
        for titolo in lista:
            print "Elaboro:",titolo
            elabora(wikipedia.Page("it",titolo))
    return
    
def rcSession(pagina=None):
    '''legge irc.txt e produce una lista delle pagine nuove o editate

    '''
    if not "dati" in os.listdir(os.getcwd()):
        os.mkdir("dati")
    if not "indici" in os.listdir(os.getcwd()+"/dati"):
        os.mkdir("dati/indici")
    if pagina==None:
        lPagine=leggiIrc()
        print time.strftime("%Y-%m-%d %H:%M:%S"),": Elaboro le pagine..."
        lpPagina=lPagine[:]
        print "Elaboro dati pagine indice"
        base={}
        
        print "Elaboro ",len(lpPagina)," pagine Pagina"
        for i in lpPagina:
            elabora(i[0])
        print "Fine ciclo",time.strftime("%Y-%m-%d %H:%M:%S")
        shutil.copy("cronAlebot.out","public_html/cronAlebot.out")
    else:
        elabora(pagina)
    return

def leggiIrc():
    lista=open("public_html/irc.txt").readlines()
    f=open("public_html/irc.txt","w")
    f.write("")
    f.close()
    l1=[]
    l2=[]
    for i in lista:
        els=unicode(i,"utf-8").split("\t")
        if not els[0] in l1 and not "Alebot" in els[1]:
            l1.append(els[0])
            l2.append(els)
    for i in range(len(l2)):
        l2[i][0]=wikipedia.Page("it",l2[i][0])
    l2.sort()
    return l2 # lista di 4 par. da irc, il primo un oggetto pagina
                      

def elabora(pagina,vocabolario={},scrivi=True): # elemento e' un oggetto pagina
    if pagina.isRedirectPage():
        return
    try:
        testoPagina = pagina.get() # Taking the text of the page
    except wikipedia.NoPage: # First except, prevent empty pages
        testoPagina = ''
        print "Pagina non esistente"
        return
    
    testoPaginaCorretto=testoPagina
    print "Su: ",pagina.title().encode("utf-8")," (namespace ",pagina.namespace(),")"

    if pagina.namespace()==108: # Ns pagina

    # routine 1: correzione apostrofi
        print "Apostrofi, ",
        testoPaginaCorretto=correggiApostrofi(testoPaginaCorretto,pagina.title())
        

    # routine 2: correzione bug ultima riga
        # testoPaginaCorretto=testoPaginaCorretto.replace('\n<span class="SAL">','<span class="SAL">')
        pattern=re.compile("</span>[\n\r]+<noinclude>")
        lista=pattern.findall(testoPaginaCorretto)
        if len(lista)>0:
            bug=lista[len(lista)-1]
            print "Bug dell'ultima riga,", bug
            
            fix="</span><noinclude>"
            testoPaginaCorretto=testoPaginaCorretto.replace(bug,fix)
              
    # routine 3: espansione versi Divina Commedia
        if "[[dc|" in testoPaginaCorretto:
            print "espando versi DC, ",
            l=produci_lista(testoPaginaCorretto,"[[dc|","]]",1)
            for j in l:
                if "(Lana)" in pagina.title():
                    testoPaginaCorretto=testoPaginaCorretto.replace(j,dc(j,versione="Lana"))
                elif "(Buti)" in pagina.title():
                    testoPaginaCorretto=testoPaginaCorretto.replace(j,dc(j,versione="Buti"))
                else:
                    testoPaginaCorretto=testoPaginaCorretto.replace(j,dc(j))
                #fi
            #ffor
    # routine 4: gestione autoreCitato()
        print "autoreCitato, "
        testoPaginaCorretto=normalizzaAcPagina(testoPaginaCorretto)

    # routine 5: aggiornamento span SAL
        #disattivo gestione spanSAL
        #print "spanSal. "
        #testoPaginaCorretto=spanSal(testoPaginaCorretto,pagina.title())
        
        if testoPaginaCorretto!=testoPagina:
            print "Modifica pagina"
            if scrivi:
                #print testoPaginaCorretto
                scrivi_pagina(testoPaginaCorretto,False,pagina.title(),commento="Correzione pagina via bot")

    
    return

  

def normalizzaAcPagina(testo): ## normalizza tutti gli autoreCitato di una pagina
    if "{{autorecitato|" in testo.lower() or "{{ac|" in testo.lower():
        testo=testo.replace("{{autoreCitato|","{{AutoreCitato|")\
               .replace("{{ac|","{{AutoreCitato|")\
               .replace("{{Ac|","{{AutoreCitato|")
        listaAc=produci_lista(testo,"{{AutoreCitato|","}}",1)
        for ac in listaAc:
            acn=normalizzaAc(ac)
            testo=testo.replace(ac,acn)
        testo=testo.replace("{{ri|","{{Ri|").replace("{{Ri|","{{RigaIntestazione|")
        testo=testo.replace("{{Ac|","{{AutoreCitato|")
    return testo
    
def normalizzaAc(ac): #riceve un tl Ac e lo normalizza
   acpar=find_stringa(ac,"{{AutoreCitato|","}}").split("|")
   print "acpar:",acpar
   if len(acpar)==1:
      if leggi_pagina("Autore:"+acpar[0])>"":
         acnorm=ac
      elif acpar[0] in autoreCitato:
         acnorm=ac.replace("{{AutoreCitato|","{{AutoreCitato|"+autoreCitato[acpar[0]]+"|")
      else:
         acnorm=ac
   else:
      acnorm=ac
   return acnorm


def semantizzaPagina(pagina): # semantizzazione speciale di pagina

    paginaTalk=pagina.toggleTalkPage()
    
    if not paginaTalk.exists():
        scrivi_pagina("{{IncludiInfotesto}}\n",False,paginaTalk.title(),commento="Aggiunta IncludiInfotesto via bot")

    else:
        testoPaginaOld=paginaTalk.get()
        testoPagina=testoPaginaOld
        areaDati=find_stringa(testoPagina,'<!-- Area dati: non modificare da qui: --><onlyinclude><div style="display:none">',\
              "</div></onlyinclude><!-- a qui -->",1)
        if areaDati !="":
              testoPagina=testoPagina.replace(areaDati,"")
        if not "{{IncludiInfotesto}}" in testoPagina:
              testoPagina="{{IncludiInfotesto}}\n"+testoPagina
        if testoPagina!=testoPaginaOld:
              scrivi_pagina(testoPagina,False,paginaTalk.title(),commento="Aggiunta IncludiInfotesto via bot")

   
    return pagina

def correggiApostrofi(testoPagina,nomePagina):
    if testoPagina.count("[[") != testoPagina.count("]]"):
        open("dati/errori.txt","a").write("\nSbilanciamento quadre in: "+nomePagina.encode("utf-8"))
        print "Sbilanciamento []"
        return testoPagina
    if testoPagina.count("{{") != testoPagina.count("}}"):
        open("dati/errori.txt","a").write("\nSbilanciamento graffe in: "+nomePagina.encode("utf-8"))
        print "Sbilanciamento graffe"
        return testoPagina
    if testoPagina.count("<") != testoPagina.count(">"):
        open("dati/errori.txt","a").write("\nSbilanciamento <> in: "+nomePagina.encode("utf-8"))
        print "Sbilanciamento caratteri <>"
        return testoPagina
    print "Eseguo apos"
    tp=apos(testoPagina)
    return tp

def apos(p):
    #print p
    lista=[]
    p1=p[:]
    ne=0
    l=produci_lista(p1,u"<math>",u"</math>",1)
    for r in l:
        if not r in lista:
            el="#e"+str(ne)+"#"
            lista.append((r,el))
            p1=p1.replace(r,el)
            ne=ne+1
            #print "math",ne,
        #fi
    #ffor
    l=produci_lista(p1,u"{{{",u"}}}",1)
    for r in l:
        if not r in lista:
            el="#e"+str(ne)+"#"
            lista.append((r,el))
            p1=p1.replace(r,el)
            ne=ne+1
    #fi
    #ffor
    l=produci_lista(p1,u"<",u">",1)
    for r in l:
        if not r in lista:
            el="#e"+str(ne)+"#"
            lista.append((r,el))
            p1=p1.replace(r,el)
            ne=ne+1
        #fi
    #ffor
    l=produci_lista(p1,u"[[",u"]]",1)
    for r in l:
        if not r in lista:
            el="#e"+str(ne)+"#"
            lista.append((r,el))
            p1=p1.replace(r,el)
            ne=ne+1
            #fi
    #ffor

    l=produci_lista(p1,u"[",u"]",1)
    for r in l:
        if not r in lista:
            el="#e"+str(ne)+"#"
            lista.append((r,el))
            p1=p1.replace(r,el)
            ne=ne+1
            #print "link1",ne,
    #ffor
    l=produci_lista(p1,u"http://",u" ",1)
    for r in l:
        if not r in lista:
            el="#e"+str(ne)+"#"
            lista.append((r,el))
            p1=p1.replace(r,el)
            ne=ne+1
            #print "link2",ne,
    #ffor
    l=produci_lista(p1,u"{{",u"}}",1)
    for r in l:
        if not r in lista:
            el="#e"+str(ne)+"#"
            lista.append((r,el))
            p1=p1.replace(r,el)
            ne=ne+1
            #fi
    #ffor
    if "'''" in p1:
        p1=p1.replace("'''","#ebold#")
        lista.append(("'''","#ebold#"))
    #fi
    if "''" in p1:
        p1=p1.replace("''","#eitalic#")
        lista.append(("''","#eitalic#"))
    if not "'" in p1:
    #non vi sono apostrofi tipografici nel testo modificabile,
    #la stringa viene restituita immutata
        return p                  
    #fi
    #qui modificare p1

    p1=p1.replace(u"'",u'\u2019')
   

    lista.reverse()
    p2=p1[:]
    for r in lista:
        p2=p2.replace(r[1],r[0])
    

    #ffor
    return p2


def dc(v="[[dc|Inferno|I|1|6]]",versione=None):
    vl=find_stringa(v,"[[","]]").split("|")
    alternativo=False
    if len(vl)==6:
        if vl.pop()=="r+":
            alternativo=True
    if (len(vl)!=5) or (not vl[3].isdigit()) or (not vl[4].isdigit()):
        return v,vl
    x,cantica,canto,ini,fin=vl
    ini=eval(ini)
    fin=eval(fin)
    
    #(cantica="Inferno",canto="II",ini=1,fin=3):
    v=carica_pcl("Divina Commedia")
    base="Divina Commedia/"+cantica+"/Canto "+canto
#    print base
    for i in v:
        if i[0]==base:
            testoCanto=i[1]
            break
    #ffor
    versi=testoCanto[ini:fin+1]
    vn=ini
    for i in range(len(versi)):
        if versione=="Buti":
            versi[i]=versi[i][0:1].upper()+versi[i][1:]
            if alternativo:
                versi[i]="{{R+|#}}".replace("#",str(vn))+versi[i]+"</span>"
                if vn % 3==1:
                    versi[i]=" "*5+versi[i]
            else:
                if vn % 3==1:
                    versi[i]+="{{R|#}}".replace("#",str(vn))
                else:
                    versi[i]=" "*5+versi[i]
        elif versione=="Lana":
            versi[i]=versi[i][0:1].upper()+versi[i][1:]
            if alternativo:
                versi[i]="{{R+|#}}".replace("#",str(vn))+versi[i]+"</span>"
                if vn % 3!=1:
                    versi[i]="     "+versi[i]
            else:
                if vn % 5 ==0:
                    versi[i]="{{R|#}}".replace("#",str(vn))+versi[i]
                if vn % 3!=1:
                    versi[i]=" "*5+versi[i]
        else:
            if alternativo:
                versi[i]="{{R+|#}}".replace("#",str(vn))+versi[i]+"</span>"
                if vn % 3==0:
                    versi[i]+="\n"
            else:
                if vn % 3==0:
                    versi[i]+="{{R|#}}".replace("#",str(vn))+"\n"
        vn+=1
    versi="<poem>\n"+"\n".join(versi)+"\n</poem>"
    return versi

def leggi_pagina(nome_pagina=u"Utente:Alex brollo",site="it"):
    #site = wikipedia.getSite()
    page = wikipedia.Page(site, nome_pagina)
    try:
        text = page.get() # Taking the text of the page
    except wikipedia.NoPage: # First except, prevent empty pages
        text = ''
    except wikipedia.IsRedirectPage: # second except, prevent redirect
        text = "#REDIRECT"
    # output(u'%s is a redirect!' % pagename)

    except wikipedia.Error: # third exception, take the problem and print
        output(u"Some error, skipping..")
    #wikipedia.stopme()
    return text
                  

# Writes into it.wikisource a unicode string into a named page (full name), adding to previous content (aggiungi=True)
# or replacing it (aggiungi=False)
def scrivi_pagina(testo="",aggiungi=True,nome_pagina="Utente:Alex brollo/Sandbox",commento='Edit by '+bot,code="it"):
    cc=" (from toolserver)"
    site = wikipedia.getSite(code)
    page = wikipedia.Page(site, nome_pagina)
    if aggiungi:
        contenuto = page.get()
        try:
            page.put(newtext=contenuto+u"\n\n"+testo,comment=commento+cc,minorEdit=False)
        except wikipedia.LockedPage:
            return "Pagina bloccata"
    else:
        try:
            page.put(newtext=testo,comment=commento+cc,minorEdit=False)
        except wikipedia.LockedPage:
            return "Pagina bloccata"
    wikipedia.stopme()
    aggiornaAlebotHtml('Modificata pagina '+nome_pagina.encode("utf-8"))
    return "Fatto"

def aggiornaAlebotHtml(edit):
    html=open("public_html/alebot.html").read()
    act=find_stringa(html,"<!--da qui-->","<!--a qui-->",1)
    edits=produci_lista(act,"<li>","</li>",1)
    edits[0:0]=["<li>"+time.strftime('%x %X')+" "+edit+"</li>"]
    while len(edits)>200:
        x=edits.pop()
    testoLista="<!--da qui-->"+"\n".join(edits)+"<!--a qui-->"
    html=html.replace(act,testoLista)
    open("public_html/alebot.html","w").write(html)
    return 

# Nuova versione, gestisce i tag annidati; x e' la parte "aspecifica" del
# tag di apertura (es: {{ cercando {{Intestazione| )
def find_stringa(stringa,idi,idf,dc=0,x=None,side="left"):
    if side=="right":
        idip=stringa.rfind(idi)
    else:
        idip=stringa.find(idi)
    idfp=stringa.find(idf,idip+len(idi))+len(idf)
    if idip>-1 and idfp>0:
        if x!=None:
            while stringa[idip:idfp].count(x)>stringa[idip:idfp].count(idf):
                if stringa[idip:idfp].count(x)>stringa[idip:idfp].count(idf):
                    idfp=stringa.find(idf,idfp)+len(idf)
                
        if dc==0:
            vvalore=stringa[idip+len(idi):idfp-len(idf)]
        else:
            vvalore=stringa[idip:idfp]
    else:
        vvalore=""
    return vvalore

def produci_lista(testo,idi,idf,dc=1,inizio=None):
    t=testo[:]
    lista=[]
    while not find_stringa(t,idi,idf,1,inizio)=="":
        el=find_stringa(t,idi,idf,1,inizio)
        t=t.replace(el,"",1)
        if dc==0:
            el=find_stringa(el,idi,idf,0,inizio)
        lista.append(el)
    return lista

def carica_pcl(nome_file, folder="dati/"):
    nome_file=folder+nome_file+".pcl"
    f=open(nome_file)
    contenuto=pickle.load(f)
    f.close()
    return contenuto
def salva_pcl(variabile,nome_file="dato",folder="dati/"):
    nome_file=folder+nome_file+".pcl"
    f=open(nome_file,"w")
    pickle.dump(variabile, f)
    f.close()
    print "Variabile salvata nel file "+nome_file
    return 
    
   
def estraiSectionAc():
   ac=leggi_pagina("Template:AutoreCitato/Dati")
   l1=produci_lista(ac, "<section begin","/>",1)
   l2={}  
   for i in l1:
      autoreBreve=i.replace("<section begin=","").replace(" />","")
      autoreLungo=find_stringa(ac,i,i.replace("begin=","end="))
      l2[autoreBreve]=autoreLungo
   return l2


''' <span class="SAL">#np,#level,#user</span>
Lavori per la costruzione di una routine che scriva/aggiorni il span SAL
Pagina test: "Pagina:Le confessioni di un ottuagenario II.djvu/604"'''
def spanSal(testo,titolo): #riceve il testo di una pagina

    # calcolo codice
    sal=find_stringa(testo,"<pagequality","/>",0)
    user=find_stringa(sal,'user="','"',0)
    level=find_stringa(sal,'level="','"',0)
    numeroPagina=find_stringa(titolo+"##","/","##",0)
    sal='<span class="SAL">#np,#level,#user</span>'.replace("#np",numeroPagina).replace("#level",level).replace("#user",user)
    print sal
    if '<span class="SAL">' in testo:
        lista=produci_lista(testo,'<span class="SAL">',"</span>",1)
        for s in lista:
            testo=testo.replace(s,"")
    if "<section end" in testo:
        lista=produci_lista(testo,"<section end","/>",1)
        for i in lista:
            testo=testo.replace(i,sal+i)
    elif "\n{{nop}}" in testo:
        testo=testo.replace("\n{{nop}}",sal+"\n{{nop}}")
    else:
        testo=testo.replace("<noinclude>\n<references/>",sal +"<noinclude>\n<references/>")
    return testo
    
if __name__  == "__main__":
        try:
                main()
        except:
                wikipedia.stopme()
                raise
        else:
                wikipedia.stopme()