Progetto:Bot/Programmi in Python per i bot/CercaNonVerificate.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Cerca le pagine nel namespace principale che non hanno la relativa pagina discussione.
Utilizza il dump in xml di wikisource per la ricerca.
I risultati li visualizza sul terminale (per adesso sono da copia-incollare a mano sul wiki).
"""
import re, codecs
import wikipedia
# sarebbe meglio se li ricavasse da file di dump...
NAMESPACES = {
'Media': -2,
'Speciale': -1,
'Discussione': 1,
'Utente': 2,
'Discussioni utente': 3,
'Wikisource': 4,
'Discussioni Wikisource': 5,
'Immagine': 6,
'Discussioni immagine': 7,
'MediaWiki': 8,
'Discussioni MediaWiki': 9,
'Template': 10,
'Discussioni template': 11,
'Aiuto': 12,
'Discussioni aiuto': 13,
'Categoria': 14,
'Discussioni categoria': 15,
'Autore': 102,
'Discussioni autore': 103,
'Progetto': 104,
'Discussioni progetto': 105,
'Portale': 106,
'Discussioni portale': 107,
'Pagina': 108,
'Discussioni pagina': 109,
'Indice': 110,
'Discussioni indice': 111,
}
class Ricercatore:
def __init__(self):
#contine associazioni: titolo - [True|False]
# titolo - True indica che ha associata una pag. discussione
# titolo - False indica che è una pagina senza pag. discussione
self.pagineNs0 = {}
# già che ci siamo, calcolo qualche "statistica".
self.info_PagineTotali = 0
self.info_PagineNs0 = 0
def _splitTitolo(self, titolo):
"""Restituisce un tupla (namespace, titolo_senza_ns).
Il namespace e` restituito come stringa oppure None se e` il principale."""
indexSeparatore = titolo.find(":")
if indexSeparatore == -1:
namespace = None
titoloSenzaNs = titolo
else:
namespace = titolo[:indexSeparatore]
if namespace not in NAMESPACES:
namespace = None
titoloSenzaNs = titolo
else:
titoloSenzaNs = titolo[indexSeparatore+1:]
return (namespace, titoloSenzaNs)
def aggiungi(self, titolo):
"""Aggiunge un titolo (con namespace); ignora i titoli di ns. che "non centrano". """
namespace, titolo = self._splitTitolo(titolo)
self.info_PagineTotali += 1
if namespace == None: # cioe` ns0
self.info_PagineNs0 += 1
if titolo not in self.pagineNs0:
self.pagineNs0[titolo] = False
if namespace == 'Discussione':
self.pagineNs0[titolo] = True
def _scartaInutili(self, titoli):
"""Elimina dalla lista le pagine che vanno bene anche senza pag. discussione:
Toglie pagine disambigua, pagine redirect, ."""
sito = wikipedia.getSite()
pagineRimanenti = []
for titolo in titoli:
print " * controllo:", titolo,
pagina = wikipedia.Page(sito, titolo)
try:
try:
testoPag = pagina.get()
if testoPag.find("{{disambigua}}")<0 and testoPag.find("{{Disambigua}}")<0:
pagineRimanenti.append(titolo)
print " : OK"
else: # e` disambigua
print " : disambigua, SALTO"
except wikipedia.IsRedirectPage, wikipedia.NoPage:
print " : redirect o cancellata, SALTO"
except:
print " --> SALTO: errore sconosciuto <--"
return pagineRimanenti
def trovati(self):
"""Restituisce le pagine del ns 0 senza relativa pag.discussione."""
paginaSenzaDescr = [ pag[0] for pag in self.pagineNs0.items() if not pag[1] ]
paginaSenzaDescr.sort()
paginaSenzaDescr = self._scartaInutili(paginaSenzaDescr)
return paginaSenzaDescr
def cerca(fileDump):
"""Cerca nel file object 'fileDump' le pagine senza pag.discussione e li visualizza.
"""
pattern = re.compile("<title>(.*?)</title>")
ricercatore = Ricercatore()
for riga in fileDump:
rigaDiTitolo = pattern.search(riga)
if rigaDiTitolo:
titolo = rigaDiTitolo.group(1)
ricercatore.aggiungi(titolo)
for titolo in ricercatore.trovati():
print titolo
print "Pagine totali:", ricercatore.info_PagineTotali
print "Pagine in ns0:", ricercatore.info_PagineNs0
def main():
"""Controlla che lo script sia invocato con gli argomenti validi, quindi chiama cerca().
"""
import sys
if len(sys.argv) != 2:
sys.stderr.write("Si deve passare come argomento il nome del file di dump.\n")
sys.exit(1)
try:
dump = codecs.open(sys.argv[1], encoding='utf-8')
except:
sys.stderr.write("Il file " + sys.argv[1] + "non esiste.\n")
sys.exit(2)
else:
cerca(dump)
sys.exit(0)
if __name__ == '__main__':
main()
[modifica] Documentazione