Wiki script - Dump sorgenti delle guide (Python 3)

Da Guide@Debianizzati.Org.
Versione del 14 set 2015 alle 15:56 di S3v (discussione | contributi) (nuova guida)
(diff) ← Versione meno recente | Versione attuale (diff) | Versione più recente → (diff)
Vai alla navigazione Vai alla ricerca
Debian-swirl.png Versioni Compatibili

Debian 8 "jessie"
Debian 9 "stretch"




Questo semplice script Python 3 si occupa di effettuare il download dei sorgenti delle guide di questo Wiki.
Il file creato si chiamerà "wikidump.txt" (o con qualsivoglia altro nome specificato nella variabile "NOMEFILE" del codice sorgente dello script).
Salvare il codice in un file di testo con nome scelto a proprio piacimento e poi eseguirlo. Ad esempio, dopo averlo chiamato "wikidump.py":

$ python3 wikidump.py

Script

#!/usr/bin/python3

import urllib.parse
import urllib.error
import urllib.request
import json


URL = 'http://guide.debianizzati.org/api.php'
NOMEFILE = 'wikidump.txt'

def api(parametri):
        
        # codifica parametri
        parametri_enc = urllib.parse.urlencode(parametri).encode('utf-8')
        # creazione URL
        url_req = urllib.request.Request(URL, parametri_enc)
        
        try:
            # dati risposta dal Wiki
            risposta = urllib.request.urlopen(url_req)
            # decodifica risposta
            risposta_dec = risposta.read().decode('utf-8')
            # decodifica in JSON 
            dati_json = json.loads(risposta_dec)

            return (dati_json)
               
        except urllib.error.URLError as e:
            print('Errore di connessione al Wiki')
            print(e)


def getPidTitoli():
        # Restituisce due valori: il primo valore è una lista di liste con i titoli di tutte le guide del Wiki e il
        # pageid del tipo: [ ["pageid1", "title1"], ["pageid2", "title2"], ...]
        # Es. ->  [ ["1234", "titolo_guida"], ["5678", "altro_titolo", ... ] ]
        # Come secondo valore viene restituita una lista di tutti i pageid. Es -> ["1234", "5678", "9012", ...]
        # Questo secondo valore è necessario per prelevare il contentuto della guida (contenuto, timestamp, etc)

        all_titles_params = {
                                        'action' : 'query',
                                        'list' : 'allpages',
                                        'aplimit' : '500',
                                        'apfilterredir' : 'nonredirects',
                                        'format' : 'json',
                                        'apfrom' : ''
                                        }
        
        lista = []
        lista_pid = []
        
        while True:
            dati = api(all_titles_params)

            for x in dati['query']['allpages']:
                lista.append(  x['title']  )
                lista_pid.append(x['pageid'] )

            # esiste un blocco successivo? Il limite di un blocco è 500.
            try:
                last = dati['query-continue']['allpages']['apfrom']

            except KeyError:
                break
            
            # se esiste un blocco successivo, allora 'apfrom' assume il valore corrispondente
            # al titolo della prima guida del blocco successivo
            all_titles_params['apfrom'] = ''.join(last)

        return lista, lista_pid

    
def getContent(lista_pageid):
    # accetta in ingresso una lista di tutti i pageid ( Es. [1234, 5678, 9012, ... ] )
    # e restituisce una lista di tuple. Es -> [ (content), (content), (content) ... ] di *tutte* le guide del Wiki
    
    # parametri
    content_ts_params = {
                                        'action' : 'query',
                                        'prop' : 'revisions',
                                        'rvprop' : 'content',
                                        'pageids' : '',
                                        'format' : 'json'
                                        }
    
    # converte la lista in ingresso in una lista di liste (di max 50 valori ciascuna in
    # quanto 50 è il max valore consentito dall'API del Wiki)
    # Qui viene usato il valore 40 per evitare possibili problemi
    listFifty = [lista_pageid[start:start + 40] for start in range(0, len(lista_pageid), 40)]
    
    while True:
        
            mylist = []

            for elem in listFifty:
                # separatore tra gli elementi della lista (interi) è "|"
                # es. 1234, 5678, 9012 -> 1234|5678|9012
                listaid = "|".join(map(str,elem))

                # modifica il valore del dizionario
                content_ts_params['pageids'] = listaid
                d_reply = api(content_ts_params)
                
                for subelem in elem:            
                    mycontent = d_reply['query']['pages'][str(subelem)]['revisions'][0]['*']
                    mylist.append( mycontent )
            break

    return mylist


def getAll():
    # viene restituita una lista di tuple. Es. -> [(pageid, titolo, content), (pageid, titolo, content), ... ]
    
    lista, listapid = getPidTitoli()
    listaCont = getContent(listapid)
    
    # si hanno ora due liste di tuple
    # 1) lista -> [ ("pageid", "title"), ("pageid", "title"), ("pageid", "title"), ... ]
    # 2) listaContTimest -> [ ("content"), ("content"), ... ]
    # Fondiamole in un'unica lista di tuple...
        
    l = list(zip(lista, listaCont))
    
    return(l)

print('Download delle guide...')
mytuplelist = getAll()


print('Scrittura sul file...')
with open(NOMEFILE, 'w') as f:
    for elem in mytuplelist:
        # parsing di caratteri non consentiti in URL (i.e. il carattere "+")
        name_parsed = urllib.parse.quote(elem[0])
        f.write('þþþþ\nguide.debianizzati.org/index.php?title=' + name_parsed + '&action=edit\n' + elem[1] + '\nøøøø\n')