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