Wiki script - Dump sorgenti delle guide (Python 3): differenze tra le versioni

Da Guide@Debianizzati.Org.
Vai alla navigazione Vai alla ricerca
mNessun oggetto della modifica
(verificata per buster e inferiori)
(4 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
{{Versioni compatibili|Jessie|Testing_2015}}
{{Versioni compatibili|Jessie|Stretch|Buster}}


Questo semplice [[script]] Python 3 si occupa di effettuare il download dei sorgenti delle guide di questo Wiki.<br/>
Questo semplice [[script]] Python 3 si occupa di effettuare il download dei sorgenti delle guide di questo Wiki.<br/>
Il file creato si chiamerà "wikidump.txt" (o con qualsivoglia altro nome specificato nella variabile "NOMEFILE" del codice sorgente dello script).<br/>
Il file creato si chiamerà "wikidump.txt" (o con qualsivoglia altro nome specificato nella variabile "NOMEFILE" del codice sorgente dello script) e, se si desidera, è possibile modificare il numero di thread (variabile "NUMTHREAD") in base al numero di core/CPU della propria macchina.
 
Salvare il codice in un file di testo con nome scelto a proprio piacimento e poi eseguirlo. Ad esempio, dopo averlo chiamato "wikidump.py":
Salvare il codice in un file di testo con nome scelto a proprio piacimento e poi eseguirlo. Ad esempio, dopo averlo chiamato "wikidump.py":
<pre>
<pre>
Riga 11: Riga 12:
<pre>
<pre>
#!/usr/bin/python3
#!/usr/bin/python3
# -*- coding: utf8 -*-


import urllib.parse
import urllib.parse
Riga 16: Riga 18:
import urllib.request
import urllib.request
import json
import json
 
import queue
from threading import Thread
from collections import OrderedDict


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


def api(parametri):
def api(parametri):
Riga 33: Riga 38:
             # decodifica risposta
             # decodifica risposta
             risposta_dec = risposta.read().decode('utf-8')
             risposta_dec = risposta.read().decode('utf-8')
             # decodifica in JSON  
             # decodifica in JSON convertendo gli interi in stringhe
             dati_json = json.loads(risposta_dec)
             dati_json = json.loads(risposta_dec, parse_int=str)


             return (dati_json)
             return dati_json
                
                
         except urllib.error.URLError as e:
         except urllib.error.URLError as e:
Riga 43: Riga 48:




def getPidTitoli():
def get_pid_and_titles():
         # Restituisce due valori: il primo valore è una lista di liste con i titoli di tutte le guide del Wiki e il
         # Restituisce un dizionario con i pageid (chiavi) e, come valori,
         # pageid del tipo: [ ["pageid1", "title1"], ["pageid2", "title2"], ...]
        # una lista di titolo + contenuto della guida (inizialmente vuoto)
         # Es. ->  [ ["1234", "titolo_guida"], ["5678", "altro_titolo", ... ] ]
        # esempio:
         # 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)
         #   'pageid1' : ['titolo1', ''],
        #    'pageid2' : ['titolo2', ''],
         #   'pageid3' : ['titolo3', ''],
        #    ...
         #   ...
         # }


         all_titles_params = {
         all_titles_params = {
                                        'action' : 'query',
                            'action' : 'query',
                                        'list' : 'allpages',
                            'list' : 'allpages',
                                        'aplimit' : '500',
                            'aplimit' : '500',
                                        'apfilterredir' : 'nonredirects',
                            'apfilterredir' : 'nonredirects',
                                        'format' : 'json',
                            'format' : 'json',
                                        'apfrom' : ''
                            'apfrom' : ''
                                        }
                            }
          
          
         lista = []
         # dizionario ordinato
         lista_pid = []
         mydict = OrderedDict()
          
          
         while True:
         while True:
Riga 66: Riga 76:


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


             # esiste un blocco successivo? Il limite di un blocco è 500.
             # esiste un blocco successivo? Il limite di un blocco è 500.
Riga 79: Riga 88:
             # al titolo della prima guida del blocco successivo
             # al titolo della prima guida del blocco successivo
             all_titles_params['apfrom'] = ''.join(last)
             all_titles_params['apfrom'] = ''.join(last)
 
       
         return lista, lista_pid
         return mydict


      
      
def getContent(lista_pageid):
def get_content(dizionario):
     # accetta in ingresso una lista di tutti i pageid ( Es. [1234, 5678, 9012, ... ] )
     # accetta in ingresso il dizionario incompleto (senza contenuto delle guide)
     # e restituisce una lista di tuple. Es -> [ (content), (content), (content) ... ] di *tutte* le guide del Wiki
    # e restituisce il dizionario completo, cioè qualcosa del tipo:
    # {
    #    'pageid1' : ['titolo1', 'contenuto1'],
    #    'pageid2' : ['titolo2', 'contenuto2'],
     #   'pageid3' : ['titolo3', 'contenuto3'],
    #    ...
    #    ...
    # }
      
      
     # parametri
     # parametri
     content_ts_params = {
     content_ts_params = {
                                        'action' : 'query',
                        'action' : 'query',
                                        'prop' : 'revisions',
                        'prop' : 'revisions',
                                        'rvprop' : 'content',
                        'rvprop' : 'content',
                                        'pageids' : '',
                        'pageids' : '',
                                        'format' : 'json'
                        'format' : 'json'
                                        }
                        }
   
    # lista delle chiavi del dizionario (pageids)
    lista_pageid = list(dizionario.keys())
      
      
     # converte la lista in ingresso in una lista di liste (di max 50 valori ciascuna in
     # converte la lista appena ottenuta in una lista di liste (di max 50 valori ciascuna in
     # quanto 50 è il max valore consentito dall'API del Wiki)
     # quanto 50 è il max valore consentito dall'API del Wiki)
     # Qui viene usato il valore 40 per evitare possibili problemi
     # 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)]
     listFifty = [lista_pageid[start:start + 40] for start in range(0, len(lista_pageid), 40)]
      
      
     while True:
     q = queue.Queue()
       
            mylist = []


            for elem in listFifty:
    for elem in listFifty:
                # separatore tra gli elementi della lista (interi) è "|"
        # separatore tra gli elementi della lista è "|"
                # es. 1234, 5678, 9012 -> 1234|5678|9012
        # es. 1234, 5678, 9012 -> 1234|5678|9012
                listaid = "|".join(map(str,elem))
        listaid = "|".join(elem)
        # inserisce questa stringa in una coda
        q.put(listaid)
   
    def mythreaded_func():
        while not q.empty():
            # preleva un valore dalla coda
            mystr = q.get()
            # modifica il valore del dizionario
            content_ts_params['pageids'] = mystr
           
            d_reply = api(content_ts_params)
           
            for subelem in mystr.split('|'):           
                mycontent = d_reply['query']['pages'][subelem]['revisions'][0]['*']
                dizionario[subelem][1] = mycontent
           
            q.task_done() 
           
    for i in range(NUMTHREAD):
        t = Thread(target=mythreaded_func)
        t.start()
   
    q.join()


                # modifica il valore del dizionario
    return 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 create_dict():
    # viene restituito il dizionario completo da inviare al file 
   
    my_partial_dict = get_pid_and_titles()
    my_full_dict = get_content(my_partial_dict)
     
    return my_full_dict


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...')
print('Download delle guide...')
mytuplelist = getAll()
mydict = create_dict()




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


print("Script terminato")
       
</pre>
</pre>


[[Categoria: Wiki]]
[[Categoria: Wiki]]
[[Categoria: Python]]
[[Categoria: Python]]

Versione delle 16:26, 13 lug 2019

Debian-swirl.png Versioni Compatibili

Debian 8 "jessie"
Debian 9 "stretch"
Debian 10 "buster"

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) e, se si desidera, è possibile modificare il numero di thread (variabile "NUMTHREAD") in base al numero di core/CPU della propria macchina.

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
# -*- coding: utf8 -*-

import urllib.parse
import urllib.error
import urllib.request
import json
import queue
from threading import Thread
from collections import OrderedDict

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

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 convertendo gli interi in stringhe
            dati_json = json.loads(risposta_dec, parse_int=str)

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


def get_pid_and_titles():
        # Restituisce un dizionario con i pageid (chiavi) e, come valori,
        # una lista di titolo + contenuto della guida (inizialmente vuoto)
        # esempio:
        # {
        #    'pageid1' : ['titolo1', ''],
        #    'pageid2' : ['titolo2', ''],
        #    'pageid3' : ['titolo3', ''],
        #    ...
        #    ...
        # }

        all_titles_params = {
                            'action' : 'query',
                            'list' : 'allpages',
                            'aplimit' : '500',
                            'apfilterredir' : 'nonredirects',
                            'format' : 'json',
                            'apfrom' : ''
                            }
        
        # dizionario ordinato
        mydict = OrderedDict()
        
        while True:
            dati = api(all_titles_params)

            for x in dati['query']['allpages']:
                mydict[x['pageid']] = [x['title'], '']

            # 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 mydict

    
def get_content(dizionario):
    # accetta in ingresso il dizionario incompleto (senza contenuto delle guide)
    # e restituisce il dizionario completo, cioè qualcosa del tipo:
    # {
    #    'pageid1' : ['titolo1', 'contenuto1'],
    #    'pageid2' : ['titolo2', 'contenuto2'],
    #    'pageid3' : ['titolo3', 'contenuto3'],
    #    ...
    #    ...
    # }
    
    # parametri
    content_ts_params = {
                        'action' : 'query',
                        'prop' : 'revisions',
                        'rvprop' : 'content',
                        'pageids' : '',
                        'format' : 'json'
                        }
    
    # lista delle chiavi del dizionario (pageids)
    lista_pageid = list(dizionario.keys())
    
    # converte la lista appena ottenuta 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)]
    
    q = queue.Queue()

    for elem in listFifty:
        # separatore tra gli elementi della lista è "|"
        # es. 1234, 5678, 9012 -> 1234|5678|9012
        listaid = "|".join(elem)
        # inserisce questa stringa in una coda
        q.put(listaid)
    
    def mythreaded_func():
        while not q.empty():
            # preleva un valore dalla coda
            mystr = q.get()
            # modifica il valore del dizionario
            content_ts_params['pageids'] = mystr
            
            d_reply = api(content_ts_params)
            
            for subelem in mystr.split('|'):            
                mycontent = d_reply['query']['pages'][subelem]['revisions'][0]['*']
                dizionario[subelem][1] = mycontent
            
            q.task_done()  
            
    for i in range(NUMTHREAD):
        t = Thread(target=mythreaded_func)
        t.start()
    
    q.join()

    return dizionario


def create_dict():
    # viene restituito il dizionario completo da inviare al file  
    
    my_partial_dict = get_pid_and_titles()
    my_full_dict = get_content(my_partial_dict)
      
    return my_full_dict


print('Download delle guide...')
mydict = create_dict()


print('Scrittura sul file...')
with open(NOMEFILE, 'w', encoding='utf8') as f:
    for k,v in mydict.items():
        # parsing di caratteri non consentiti in URL (i.e. il carattere "+")
        name_parsed = urllib.parse.quote(v[0])

        url = ''.join(('guide.debianizzati.org/index.php?title=', name_parsed, '&action=edit'))
        f.write('\n'.join(('þþþþ', url, v[1], 'øøøø', '')))

print("Script terminato")