Utente:Wisbot/archivia richieste bot.py

<source lang=python>

  1. -*- coding: utf-8 -*-

""" Questo bot serve per l'archiviazione delle richieste ai bot.

"""

  1. Utente:Wiso 2007
  2. Distributed under the terms of the GPL licence

from __future__ import generators from datetime import date from time import strptime import sys, re import wikipedia, pagegenerators,config

mesi = ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno','Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre']

def mese2int(meseStr):

   try:
       return mesi.index(meseStr) + 1
   except ValueError:
       return None

def txt2date(txt,format):

   try:
       return date(*strptime(txt,format)[0:3])
   except ValueError:
       return None

class ArchiveBotBot:

   from datetime import date
   def __init__(self, pagina, paginaArchivioNameRoot, limiteFatti=21, limiteNonFatti=365):
       
       self.pagina = pagina
       self.paginaArchivioNameRoot = paginaArchivioNameRoot
       self.limiteFatti = limiteFatti
       self.limiteNonFatti = limiteNonFatti
       self.compileRegex()
       self.intestazioneArchivio = u'\n\n' % (date.today().strftime('%d %b %Y'))


   def compileRegex(self):
  1. self.regexEseguito = re.compile('[Ss]tato operazione ?:.*Template:( *1 *\')
       self.regexEseguito = re.compile('[sS]tato operazione ?: ?.*?(\{\{ ?[Ff]atto ?\}\}|'
                                  '\{\{\{1\|...Fatto...\}\}\}|'
                                  '\{\{ ?[Nn]on[ _]fatto\}\}|'
                                  '\{\{\{1\|...Non fatto...\}\}\})')
       self.regexData = re.compile(', ([0-9]{1,2} [a-z]{3} [0-9]{4}) \((CEST|CET)\)')
       self.regexParagrafo = re.compile('(?m)^=== *([^=].*?) *===$')


   def archivia(self,text,archivio1, archivio2):
       match1 = self.regexArchivio1.search(text)
       if not match1:
           wikipedia.output('NON TROVO IL PUNTO DI INSERIMENTO NELL\'ARCHIVIO')
           return None
       textout = text[:match1.start()] + archivio1 + match1.group(0)
       match2 = self.regexArchivio2.search(text)
       if not match2:
           wikipedia.output('NON TROVO IL PUNTO DI INSERIMENTO NELL\'ARCHIVIO')
           return None
       textout = textout + text[match1.end():match2.start()] + archivio2 + text[match2.start():]
       return textout        
   def trovaDate(self,text):
       regexData = self.regexData
       matchDate = regexData.finditer(text)
       date = []
       for match in matchDate:
           date.append(match.group(1))
       return date
   def splitThreads(self,text):
       regexParagrafo = self.regexParagrafo
       matchParagrafi = regexParagrafo.finditer(text)
       threads = []
       inizio = 0
       header = True
       headerText =  
       for match in matchParagrafi:
           fine = match.start()
           if (not header):
               threads.append((titolo,text[inizio:fine]))
           else:
               headerText = text[:fine]
           header = False
           titolo = match.group(1)
           inizio = match.end()
       testo = text[inizio:]
       threads.append((titolo,testo))
       return (threads,headerText)


   def valutaData(self,dataStr):
       data = txt2date(dataStr,"%d %B")
       if not data:
           data = txt2date(dataStr,"%d/%m/%Y")
       else:
           annocorrente = date.today().year
           data = data.replace(year = annocorrente)           
       if not data:
           data = txt2date(dataStr,"%H:%M, %d %b %Y (CEST)")
       if not data:
           data = txt2date(dataStr," %d %b %Y (CEST)")
       if not data:                
           data = txt2date(dataStr,"%d %B")
       if not data:
           data = txt2date(dataStr,"%d %b %Y")
       if not data:
           wikipedia.output(u'Formato non supportato %s' % dataStr)
       return data
   def dataMassima(self,date):
       dataMassima = self.valutaData(date[0])
       for dataStr in date:
           data = self.valutaData(dataStr)
           if (data < dataMassima):
               dataMassima = data
       return dataMassima
   def dataVecchiaggineMassima(self,date):
       vecchiaggineUltimaData = None
       for data in date:
           vecchiaggineData = self.valutaVecchiaggine(data)
           if (vecchiaggineData < vecchiaggineUltimaData or vecchiaggineUltimaData == None):
               vecchiaggineUltimaData = vecchiaggineData
       return vecchiaggineUltimaData
   
   def valutaVecchiaggine(self,dataStr):
       data = self.valutaData(dataStr)
       vecchiaggine = (date.today() - data).days
       return vecchiaggine
   def valutaEseguito(self,text):
       regexEseguito = self.regexEseguito
                                  
       match = regexEseguito.search(text)
       if match:
           print match.group(0)
           return True
       else:
           return False
   def archiviaLoad(self,archivio,date,testo):
       anno = self.dataMassima(date).year
       if not archivio.has_key(anno):
           archivio[anno] = []
           archivio[anno].append(self.intestazioneArchivio)
       archivio[anno].append(testo)
   def archiviaShoot(self,archivio):
       for anno in archivio.keys():
           paginaArchivioName = self.paginaArchivioNameRoot + str(anno)
           paginaArchivio =  wikipedia.Page(wikipedia.getSite(),paginaArchivioName)
           wikipedia.output(u'Recupero archivio %s' % paginaArchivio.title())
           try:
               textArchivio = paginaArchivio.get()
           except wikipedia.NoPage:
               wikipedia.output(u'Page %s not found' %paginaArchivio.title())
               wikipedia.output(u'Crea la pagina dell\'anno nuovo, con la struttura uguale a quella precedente')
               continue
           wikipedia.output('Fatto')
           wikipedia.output('----------------------------\n\n')
           
           for testo in archivio[anno]:
               textArchivio += testo
               
           wikipedia.setAction('Archivio')
           paginaArchivio.put(textArchivio)
   def contaAnni(self,archivio):
       conteggi = {}
       for anno in archivio.keys():
           conteggi[anno] = 0
           for testo in archivio[anno]:
               conteggi[anno] += 1
       return conteggi
   def aggiornaStatistiche(self,archivio):
       conteggi = self.contaAnni(archivio)
       paginaStatisticheName = self.paginaArchivioNameRoot[:-1]
       paginaStatistiche = wikipedia.Page(wikipedia.getSite(),paginaStatisticheName)
       try:
           text = paginaStatistiche.get()
       except wikipedia.NoPage:
           wikipedia.output(u'Page %s not found' %paginaStatistiche)
           return None
       totale = 0
       for anno in conteggi.keys():            
           regexAnno = re.compile(u'[Aa]nno %s ?\]\] ?\|\| ?([0-9]+)' %anno)
           match = regexAnno.search(text)
           if not match:
               wikipedia.output('\03{lightred}Anno non trovato nell\'archivio, agire manulmente. Anno: %s, conteggi: + %d\03{default}' %(anno,conteggi[anno]))
               continue
           numero = int(match.group(1))
           numero += conteggi[anno]
           totale += conteggi[anno]
           text = regexAnno.sub('Anno %s]]||%d' %(anno,numero),text)
       regexTotale = re.compile(u"Totale\|\|([0-9]+)")
       match = regexTotale.search(text)
       totale += int(match.group(1))
       text = regexTotale.sub("Totale||%d" %totale,text)
       
       regexData = re.compile(u'archiviate al .+')
       text = regexData.sub('archiviate al 23:58, 3 apr 2020 (CEST)',text)
       wikipedia.setAction('Bot: Aggiorno statistiche')
       paginaStatistiche.put(text)



   def run(self):
       wikipedia.output(u'Recupero pagina %s' % self.pagina.title())
       try:
           text = self.pagina.get()
       except wikipedia.NoPage:
           wikipedia.output(u'Page %s not found' %self.pagina.title())
           return None
       wikipedia.output(u'Fatto')
       interwiki = wikipedia.getLanguageLinks(text)
       
       text = wikipedia.removeLanguageLinks(text)
       (threads,testoCheRimane) = self.splitThreads(text)
       testiDaArchiviare = {}
       
       numeroParagrafi = 0
       numeroParagrafiArchiviati = 0


       for (paragrafo, testo) in threads:
  1. if numeroParagrafi ==1:
  2. print paragrafo
  3. print testo
           numeroParagrafi += 1
           date = self.trovaDate(testo)
           if date==[]:
               stringa_errore = '\03{lightred}ERRORE: NON RIESCO A TROVARE NESSUNA DATA NEL PARAGRAFO %s\03{default}' % paragrafo
               wikipedia.output(stringa_errore)
               testoCheRimane += u'\n=== %s ===\n%s' %(paragrafo,testo)
               continue
           data = self.dataMassima(date)            
           
           vecchiaggineUltimaData = self.dataVecchiaggineMassima(date)
           if (vecchiaggineUltimaData == None):
               print 'ERRORE'
           else:
               eseguito = self.valutaEseguito(testo)
               wikipedia.output(u'\n>>> \03{lightpurple}%s\03{default} <<<' % paragrafo)
               wikipedia.output(u'\n    Ultima data: %s' %data)
               wikipedia.output(u'    Vecchio di %d giorni' % vecchiaggineUltimaData)
               if eseguito:
                   wikipedia.output(u'    Eseguito: Si')
               else:
                   wikipedia.output(u'    Eseguito: No')
               if (vecchiaggineUltimaData > self.limiteNonFatti or (eseguito and (vecchiaggineUltimaData > self.limiteFatti))):
                   choice = wikipedia.inputChoice(u'Vuoi archiviare il paragrafo?', ['Yes', 'No'], ['y', 'N'], 'N')
                   if choice in ['y', 'Y']:
                       testo = u'\n== %s ==\n%s' %(paragrafo,testo)
                       self.archiviaLoad(testiDaArchiviare,date,testo)
                       numeroParagrafiArchiviati += 1
                   else:
                       testoCheRimane += u'\n=== %s ===%s' %(paragrafo,testo)
               else:
                   testoCheRimane += u'=== %s ===%s' %(paragrafo,testo)
       interwikiText = []
       for lang in interwiki.keys():
           interwikiText.append(u'\n%s:%s' % (lang.language(),interwiki[lang].title()))
           interwikiText.sort()
       testoCheRimane += '\n'
       for interw in interwikiText:
           testoCheRimane += interw
       wikipedia.output(u'Valutati %d paragrafi' % numeroParagrafi)
       if numeroParagrafiArchiviati != 0:
           wikipedia.output(u'Da archiviare %d paragrafi' % numeroParagrafiArchiviati)
           choice = wikipedia.inputChoice(u'Procedo?', ['Yes', 'No'], ['y', 'N'], 'N')
           if choice in ['y', 'Y']:
               wikipedia.output(testoCheRimane)
               self.archiviaShoot(testiDaArchiviare)
               wikipedia.setAction('Archivio')
               self.pagina.put(testoCheRimane)
               self.aggiornaStatistiche(testiDaArchiviare)
       else:
           wikipedia.output(u'\03{lightred}Nessun paragrafo da archiviare\03{default}')
       
           
       


def main():

   paginaName = 'Wikipedia:Bot/Richieste'
   paginaArchivioNameRoot = 'Wikipedia:Bot/Richieste/Archivio/'
   s = wikipedia.Site('it')
   pagina = wikipedia.Page(s,paginaName)
   
   
   bot = ArchiveBotBot(pagina,paginaArchivioNameRoot)
   bot.run()
               

if __name__ == "__main__":

   try:
       main()
   finally:
       wikipedia.stopme()

</lang>