SlideShare a Scribd company logo
1 of 56
Download to read offline
UNIVERSITÀ DEGLI STUDI DI TRIESTE
Dipartimento di Ingegneria e Architettura
Corso di Studi in Ingegneria Elettronica e Informatica
Sviluppo di un bot Telegram
per la diffusione di articoli informativi
Tesi di Laurea Triennale
Laureando:
Matteo MERZ
Relatore:
prof. Marco TESSAROTTO
_____________________________________
ANNO ACCADEMICO 2018-2019
Ringraziamenti
Desidero ringraziare con affetto la mia famiglia, sempre vicina e pronta ad aiutarmi nei momenti di
difficoltà. Il suo aiuto è stato determinante per raggiungere questo traguardo.
Sono grato a tutti gli amici, che mi hanno accompagnato durante questo percorso e con cui ho con-
diviso gioie e affanni. Un pensiero speciale va poi a Giovanna, la via di fuga per tutti i cattivi pen-
sieri, che con il suo affetto mi ha supportato in questi anni.
Un ringraziamento infine a Trieste, per avermi accolto. Con la sua bellezza mi ha spesso riempito gli
occhi e liberato la mente.
Matteo Merz
iii
iv
Indice
Capitolo 1 Introduzione........................................................................................................................1
1.1 Presentazione del progetto.........................................................................................................1
Il servizio Telegram e i chat bot.............................................................................................1
Risultati.................................................................................................................................2
Motivazioni e finalità del progetto........................................................................................2
Motivazioni e finalità del lavoro di tesi.................................................................................2
1.2 Metodo di lavoro.......................................................................................................................3
1.3 Riassunto dei capitoli successivi................................................................................................3
Capitolo 2 Analisi e progettazione........................................................................................................5
2.1 Analisi.......................................................................................................................................5
2.1.1 Analisi dei requisiti............................................................................................................5
Interfaccia utente...................................................................................................................5
Accettazione delle condizioni d’utilizzo del servizio............................................................7
Altri requisiti funzionali........................................................................................................8
Software................................................................................................................................8
Carico applicativo.................................................................................................................8
2.1.2 Elenco completo dei requisiti............................................................................................8
2.2 Progettazione...........................................................................................................................10
2.2.1 Progettazione dell’applicazione web...............................................................................10
Django.................................................................................................................................10
Gunicorn..............................................................................................................................11
Nginx...................................................................................................................................11
PostgreSQL.........................................................................................................................11
2.2.2 Progettazione del bot Telegram........................................................................................12
Lettura automatica degli articoli..........................................................................................12
2.2.3 Progettazione del parser RSS...........................................................................................12
2.2.4 Architettura complessiva.................................................................................................13
Capitolo 3 Realizzazione....................................................................................................................15
3.1 Modalità di lavoro...................................................................................................................15
Meriti...................................................................................................................................16
3.2 Applicazione web....................................................................................................................17
3.2.1 Architettura......................................................................................................................17
3.2.2 Progetto Django...............................................................................................................18
Analisi del modulo src.gfvgbo.secrets.................................................................................18
Analisi del modulo src.gfvgbo.settings................................................................................18
Analisi del modulo src.backoffice.models...........................................................................19
Analisi del modulo src.backoffice.admin............................................................................22
3.3 Bot Telegram...........................................................................................................................24
3.3.1 Architettura......................................................................................................................24
3.3.2 Interfaccia utente.............................................................................................................24
Il comando /start.................................................................................................................24
Il comando /scegli...............................................................................................................26
v
Il comando /categorie..........................................................................................................27
L’invio degli articoli............................................................................................................28
Il comando /rimanda_ultime_news......................................................................................29
Il comando /statistiche.........................................................................................................30
Il comando /help..................................................................................................................30
3.3.3 Codice.............................................................................................................................31
Analisi del modulo src.telegram_bot.regionefvg_bot..........................................................31
Elenco degli handler............................................................................................................32
Analisi del modulo src.telegram_bot.news_processing.......................................................34
Analisi del modulo src.telegram_bot.ormlayer....................................................................36
Analisi dei tempi di esecuzione con e senza cache..............................................................36
Analisi del modulo src.telegram_bot.log_utils....................................................................38
Analisi del modulo src.telegram_bot.django_settings.........................................................39
Capitolo 4 Conclusioni.......................................................................................................................41
4.1 Raggiungimento degli obiettivi...............................................................................................41
Il bot Telegram....................................................................................................................41
L’applicazione web..............................................................................................................41
Il lavoro di tesi....................................................................................................................42
4.2 Stato attuale del lavoro............................................................................................................42
4.3 Conclusioni soggettive............................................................................................................42
Appendice A.......................................................................................................................................45
Bibliografia.........................................................................................................................................47
vi
Indice delle Figure
Figura 1: Logo di Telegram.................................................................................................................1
Figura 2: Ricerca del bot dall'applicazione Telegram..........................................................................2
Figura 3: Modello di notifica................................................................................................................6
Figura 4: Metodo di accettazione dell'informativa sul trattamento dei dati personali..........................7
Figura 5: Rapporto del 18 ottobre 2019 sul traffico del dominio offertelavoro.regione.fvg.it.............8
Figura 6: Logo di Django..................................................................................................................10
Figura 7: Logo di Gunicorn...............................................................................................................11
Figura 8: Logo di Nginx....................................................................................................................11
Figura 9: Logo di PostgreSQL...........................................................................................................11
Figura 10: Logo di python-telegram-bot............................................................................................12
Figura 11: Logo tipico per i flussi web...............................................................................................12
Figura 12: Struttura complessiva del sistema......................................................................................13
Figura 13: Logo di GitHub................................................................................................................15
Figura 14: Analisi del lavoro svolto...................................................................................................16
Figura 15: Architettura dell'applicazione web.....................................................................................17
Figura 16: Struttura............................................................................................................................18
Figura 17: Schema UML delle classi..................................................................................................21
Figura 18: Elenco dei modelli inseriti nella pagina amministrativa di backoffice..............................22
Figura 19: Pagina di backoffice dedicata al modello NewsItem.........................................................22
Figura 20: Architettura del bot Telegram............................................................................................24
Figura 21: Invio dell'informativa sul trattamento dei dati personali...................................................25
Figura 22: Il bot è bloccato................................................................................................................25
Figura 23: Inserimento del titolo di studio più elevato.......................................................................26
Figura 24: Scelta delle categorie di interesse.....................................................................................26
Figura 25: Riassunto delle categorie scelte........................................................................................27
Figura 26: Elenco dei comandi relativi alle categorie........................................................................27
Figura 27: Proposta di smettere di seguire la categoria specificata....................................................27
Figura 28: Proposta di iniziare a seguire la categoria specificata.......................................................28
Figura 29: Notifica della pubblicazione di un nuovo articolo............................................................28
Figura 30: Interfaccia per l'inserimento dei commenti, Pt. 1..............................................................29
Figura 31: Interfaccia per l'inserimento dei commenti, Pt. 2..............................................................29
Figura 32: Riassunto degli articoli inviati negli ultimi dieci giorni....................................................29
Figura 33: Lettura del titolo dell'articolo selezionato.........................................................................30
Figura 34: Statistiche sugli articoli inviati negli ultimi dieci giorni...................................................30
Figura 35: Messaggio esplicativo del funzionamento del bot............................................................30
Figura 36: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni nullo.........................37
Figura 37: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni pari a 50 ms..............37
Figura 38: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni pari a 100 ms............37
vii
Indice delle Tabelle
Tabella 1: Elenco dei requisiti..............................................................................................................9
Tabella 2: Elenco dei modelli.............................................................................................................20
Tabella 3: Limiti di spam....................................................................................................................31
Tabella 4: Elenco degli handler...........................................................................................................34
Tabella 5: Livelli di rigore degli eventi...............................................................................................38
Tabella 6: Dati completi sull'analisi dell'utilizzo della cache..............................................................46
Tabella 7: Medie dei dati ricavati sull’analisi dell’utilizzo della cache...............................................46
viii
Capitolo 1
Introduzione
In questo capitolo iniziale viene introdotto il progetto in esame. Alcune parole sono dedicate alla
presentazione di Telegram e dei chat bot, altre all’ambiente in cui è stato svolto e agli obiettivi da
raggiungere. Infine è stato inserito un breve riassunto dei capitoli successivi.
1.1 Presentazione del progetto
In questo documento sarà descritto il percorso di realizzazione di un bot Telegram per la diffusione di
articoli informativi. Tale progetto rientra nei servizi offerti dalla Regione Friuli Venezia Giulia - Dire-
zione centrale lavoro, formazione, istruzione e famiglia, ed è stato avviato da Marco Tessarotto, rela-
tore di questa tesi. L’autore non ha realizzato la totalità del software che sarà presentato ma ne ha
contribuito allo sviluppo, inserendosi in una sua fase embrionale.
Prima di addentrarsi nella descrizione del lavoro svolto, saranno introdotti i chat bot di Telegram.
Il servizio Telegram e i chat bot
Telegram è un servizio di messaggistica istantanea basato sul cloud ed erogato gratuitamente. Esso è
accessibile da mobile, desktop e web, attraverso applicazioni a codice sorgente libero[1]
.
Figura 1: Logo di Telegram.
Fornisce diverse funzionalità, tra cui l’invio di messaggi con crittografia punto-punto e la possibilità
di creare dei chat bot. Ci si soffermerà evidentemente su quest’ultimo servizio.
Un chat bot è un software progettato per simulare una conversazione con un essere umano.
Nel caso di in esame si parla semplicemente di bot: un bot è un’applicazione di terze parti eseguita
all’interno di Telegram. Esso non è che un normale profilo, con la peculiarità di poter essere attivato
anche senza un numero di telefono. Gli utenti possono interagire con un bot in due modi:
• inviando comandi e messaggi in una conversazione privata con esso (il caso in esame),
oppure aggiungendolo ad un gruppo;
1
• inviando richieste da qualsiasi conversazione, gruppo o canale, tramite lo @username
del bot seguito da un’interrogazione.
Per ulteriori informazioni si rimanda alla documentazione ufficiale[2]
.
Risultati
Il risultato del progetto è il bot Telegram LavoroFVG. Il lettore può provarne personalmente le fun-
zionalità installando l’applicazione Telegram e seguendo l’indirizzo
https://telegram.me/DCLavoroFVG_bot,
oppure digitando il nome del servizio direttamente dall’applicazione nella barra di ricerca globale,
come mostrato in Figura 1.
Figura 2: Ricerca del bot dall'applicazione Telegram.
Motivazioni e finalità del progetto
Prima di chiarire motivazioni e finalità del progetto, è necessario descrivere con maggiore precisione
il contesto in cui esso si colloca.
Il portale LavoroFVG[3]
è un servizio messo a disposizione dalla Regione Friuli Venezia Giulia per la
diffusione delle offerte di lavoro e di formazione pubblicate dai Centri per l’Impiego (CPI) e da Eure-
sFVG. La sua missione è diventare il punto di riferimento per i residenti nella regione in cerca di la-
voro. In seguito si farà spesso riferimento a questo servizio con la semplice dicitura portale.
Attualmente esso è fruibile da un’applicazione mobile e dal sito web: il progetto in esame nasce dalla
necessità di un canale di comunicazione alternativo. Il servizio deve perseguire come obiettivo prin-
cipe la semplicità di installazione e di utilizzo, così da ottenere la massima diffusione possibile.
Motivazioni e finalità del lavoro di tesi
Nel paragrafo precedente si è parlato del progetto nella sua totalità. Scendendo nel particolare di que-
sto lavoro di tesi, gli obiettivi sono fondamentalmente due:
• contribuire allo sviluppo del software;
• redigere la documentazione del progetto.
Quest’ultimo obiettivo è stato realizzato attraverso la scrittura del documento in esame.
Per quanto riguarda la motivazione, è sufficiente dire che la proposta di collaborazione è nata dal re-
latore e che l’autore l’ha accettata di buon grado per motivi di interesse personale.
2
1.2 Metodo di lavoro
Lo svolgimento del lavoro, dopo una fase preliminare di studio individuale del linguaggio di pro-
grammazione Python e delle Bot API di Telegram[4]
, è stato caratterizzato da una ripetizione ciclica
delle seguenti fasi:
1. raccolta e analisi dei requisiti;
2. progettazione e scelta degli strumenti software da utilizzare nello sviluppo;
3. raccolta di informazioni su come utilizzare tali strumenti;
4. scrittura del codice.
L’ultima fase è stata accompagnata da momenti di test sul funzionamento complessivo e da riflessio-
ni sulle prestazioni del codice.
1.3 Riassunto dei capitoli successivi
Saranno dedicate alcune righe ad ogni capitolo.
Nel Capitolo 2 si parlerà delle fasi di analisi e di progettazione. Si è deciso di raggruppare in esso tut-
ti i requisiti raccolti e tutte le relative specifiche.
Nel Capitolo 3 sarà invece dato spazio alla realizzazione, con descrizioni dettagliate del funziona-
mento dei servizi creati, sia dal punto di vista dell’interfaccia utente che da quello del codice.
Infine, il Capitolo 4 conterrà le osservazioni conclusive sul lavoro svolto, indicando la situazione at-
tuale confrontata con le aspettative e i possibili sviluppi futuri.
3
4
Capitolo 2
Analisi e progettazione
In questo capitolo sarà descritta la prima parte del percorso di lavoro, ovvero quella di analisi e di
progettazione. Lo scopo è quello di fornire un elenco chiaro dei requisiti di progetto, di modo che si
possano definire gli strumenti da utilizzare e le linee guida della realizzazione.
2.1 Analisi
La fase di analisi è stata preceduta da alcune riunioni con il personale della Regione Autonoma Friuli
Venezia Giulia, Direzione centrale lavoro, formazione, istruzione e famiglia. Essendo il committente
interno, tali colloqui non si sono basati esclusivamente sulla raccolta dei requisti ma sono stati inter-
vallati da momenti di riflessione comune su quale potesse essere, visto l’obiettivo, la soluzione mi-
gliore. Scendendo nel particolare, i principali soggetti intervistati sono stati:
• la curatrice del portale LavoroFVG, che ha parlato delle modalità di inserimento e di pubbli-
cazione degli articoli;
• il tecnico informatico del portale, che ne ha descritto le principali caratteristiche e con cui si
è discussa la fattibilità delle soluzioni ideate.
Le informazioni emerse dalle riunioni sono state successivamente riassunte e riorganizzate. Il risulta-
to di tale processo è inserito nei prossimi paragrafi.
2.1.1 Analisi dei requisiti
I requisiti raccolti spaziano su vari ambiti, dall’interfaccia utente all’hardware. Per questo motivo, e
al fine di ottimizzare la comprensione del documento, si è ritenuto opportuno dividere la trattazione
in più sezioni, ognuna dedicata ad uno di essi.
Interfaccia utente
Il meccanismo di divulgazione deve avvenire attraverso una conversazione privata con l’utente sul
servizio di messaggistica Telegram. Si desidera che tale conversazione possa essere avviata non solo
dall’interno del servizio (digitando sul campo di ricerca il nome del bot e poi selezionandolo), ma an-
che attraverso un collegamento da inserire nel portale LavoroFVG.
5
Una volta effettuato con successo l’accesso al servizio, si desidera che all’utente venga notificata in
tempo reale la pubblicazione dei nuovi articoli (il bot Telegram deve essere dunque attivo in modo
continuativo). In particolare, per ognuno di essi si è interessati a notificare: titolo, un breve estratto
del contenuto, il collegamento alla pagina del portale contenente l’articolo completo e un’immagine.
Le informazioni elencate devono essere disposte come illustrato in Figura 3.
Figura 3: Modello di notifica.
L’utente deve avere la possibilità di esprimere un giudizio binario (“Mi piace” / “Non mi piace”) su-
gli articoli proposti e, nel caso volesse formulare un pensiero più complesso, è necessario che il siste-
ma supporti l’inserimento dei commenti.
Sebbene l’opzione di invio predefinita consista nel notificare a tutti gli utenti ogni articolo pubblica-
to, si chiede inoltre di implementare una procedura di selezione delle categorie di interesse, così che
il bot possa inviare le notizie appartenenti a una specifica categoria solo a quegli utenti che l’hanno
scelta. Le categorie tra cui scegliere devono essere:
• Lavoro;
• Studio, formazione e corsi;
• Mobilità all’estero;
• Eventi e recruiting;
• Offerte di lavoro;
• Collocamento mirato;
• Informazioni di servizio sui CPI;
• Bandi e avvisi dai CPI;
• Statistiche sul mondo del lavoro;
• Politiche del lavoro;
• Tirocini.
Ogni articolo deve appartenere a una o più categorie. Il bot deve essere in grado di determinare, sulla
base del contenuto dell’articolo, le categorie di appartenenza.
6
Corso per operatori CNC propedeutico
all'assunzione in importanti aziende
meccaniche.
L’Amministrazione regionale, in
collaborazione con l’azienda LMB Srl della
Società PELFA Group e CMB Solutions
Srl, ricerca addetti alla produzione con
macchine utensili CNC. Per l'acquisizione
delle competenze ricercate è... continua
Immagine
Titolo
Estratto del contenuto
(circa 30 parole)
Collegamento
Per ogni articolo inviato, infine, deve essere implementato un meccanismo di lettura automatica, ac-
cessibile attraverso un comando dedicato, che ne permetta l’ascolto dei titoli e testo.
Per quanto riguarda l’interfaccia utente dell’amministratore, invece, si richiede la possibilità di con-
trollare ogni aspetto del servizio. Si desidera in particolare poter visionare:
• il numero di utenti collegati, e per ognuno tutte le informazioni raccolte dal sistema;
• il dettaglio di ogni articolo inviato, compresi i giudizi e i commenti espressi dagli utenti;
• lo stato di invio degli articoli (già inviato, non ancora inviato, in coda) .
Deve inoltre essere possibile:
• escludere dal servizio determinate categorie di utenti (per esempio i bot), o alcuni utenti in
particolare;
• inviare un articolo a tutti gli utenti, indipendentemente dalle categorie selezionate dai singoli;
• aggiornare (aggiungere/eliminare/modificare) le categorie disponibili.
Accettazione delle condizioni d’utilizzo del servizio
Il progetto prevede un’insita problematica, ossia il trattamento di dati personali. È necessario che
l’utente, prima di poter usufruire del servizio proposto, abbia accettato un’informativa contenente le
condizioni di utilizzo del servizio e la politica di trattamento dei dati che saranno inviati durante la
comunicazione.
Si chiede di inserire un meccanismo di controllo che impedisca all’utente di utilizzare il servizio nel
caso in cui l’informativa non sia stata ancora accettata. Per gli utenti che accedono direttamente
dall’applicazione Telegram, inoltre, bisogna implementare una funzionalità che permetta loro di ac-
cettare l’informativa direttamente dall’applicazione. Per coloro che accedono dal portale, invece, è
necessario inserire una clausola di avvenuta accettazione dell’informativa prima di fornire il collega-
mento per accedere al servizio. Una descrizione grafica del meccanismo è stata inserita in Figura 4.
Figura 4: Metodo di accettazione dell'informativa sul trattamento dei dati personali.
7
Altri requisiti funzionali
Si intende inserire nel sistema delle componenti che permettano la profilazione dell’utente, finalizza-
ta a un miglioramento della qualità del servizio tramite l’analisi dei gruppi. In particolare, le informa-
zioni da raccogliere sono età e titolo di studio. L’utente non deve essere obbligato a inserire tali dati.
Software
Per la realizzazione del progetto si richiede che tutto il software utilizzato sia improntato alla filoso-
fia dell’Open Source[5]
. Analogamente, ciò che sarà sviluppato dovrà essere pubblicato con licenza
GNU Affero General Public License (AGPL) in versione 3.0[6]
.
Tutti i programmi, infine, devono poter essere eseguiti sul sistema operativo Linux.
Carico applicativo
Sono previsti indicativamente alcune decine di utenti regionali che accederanno al settore ammini-
strativo dell’applicazione.
Gli utenti del bot Telegram sono invece stimati nell’ordine di alcune decine di migliaia. Tale previsio-
ne è stata fatta sulla base del numero attuale di visitatori del portale, riportato in Figura 5.
Figura 5: Rapporto del 18 ottobre 2019 sul traffico del dominio offertelavoro.regione.fvg.it.
2.1.2 Elenco completo dei requisiti
Nella Tabella 1 sono stati elencati i requisiti raccolti. La colonna Importanza esprime il peso del re-
quisito dal punto di vista del committente; la colonna Legami evidenzia eventuali correlazioni del re-
quisito con altri nella tabella.
# Descrizione Importanza Legami
1
La divulgazione degli articoli avviene in una conversazione privata
in Telegram.
Essenziale /
2 L’utente può avviare il servizio anche attraverso il portale.
Molto
importante
/
3
L’utente riceve le notifiche della pubblicazione di nuovi articoli in
tempo reale.
Molto
importante
/
4 L’utente riceve le notifiche nel formato indicato in Figura 3.
Molto
importante
1
8
# Descrizione Importanza Legami
5
Agli articoli viene associata una traccia audio generata dalla lettura
automatica degli stessi.
Abbastanza
importante
/
6 L’utente può esprimere un feedback sugli articoli.
Molto
importante
1, 12
7 L’utente può commentare gli articoli.
Molto
importante
1, 12
8 L’utente può scegliere delle categorie di interesse. Essenziale 1, 16
9 L’amministratore può visionare il numero di utenti collegati. Essenziale /
10
L’amministratore può visionare le informazioni associate ad ogni
utente.
Molto
importante
121
11 L’amministratore può visionare ogni articolo.
Abbastanza
importante
/
12
L’amministratore può visionare i giudizi e i commenti espressi su-
gli articoli.
Molto
importante
6, 7
13 L’amministratore può visionare lo stato d’invio degli articoli. Essenziale /
14
L’amministratore può escludere alcune categorie di utenti o degli
utenti in particolare.
Abbastanza
importante
10
15
L’amministratore può inviare una comunicazione di servizio a tutti
gli utenti.
Abbastanza
importante
/
16 L’amministratore può aggiornare le categorie disponibili.
Abbastanza
importante
8
17 Il software utilizzato deve seguire la filosofia dell’Open Source[7]
. Essenziale /
18
Il software prodotto deve essere reso disponibile con licenza AGPL
in versione 3.0[8]
.
Essenziale /
19
Il software utilizzato e prodotto deve poter essere eseguito sul si-
stema operativo Linux.
Essenziale /
20
Il sistema deve supportare alcune decine di utenti del settore ammi-
nistrativo e alcune decine di migliaia di utenti del bot Telegram.
Molto
importante
/
21
Il bot Telegram chiede all’utente di inserire età e titolo di studio,
così da poterlo profilare.
Abbastanza
importante
1,
22
Il bot Telegram chiede all’utente di accettare il trattamento dei dati
personali.
Essenziale 1
23
Il bot Telegram blocca gli utenti che non hanno accettato suddetta
informativa.
Essenziale 1, 22
24
Il bot Telegram deve essere in grado di determinare le categorie di
appartenenza degli articoli.
Abbastanza
importante
1, 8
25
Il bot Telegram deve inviare gli articoli appartenenti a una determi-
nata categoria solo agli utenti interessati.
Essenziale 1, 8.
26 Il bot Telegram deve essere attivo 7 giorni su 7, 24 ore su 24.
Molto
importante
1, 3
Tabella 1: Elenco dei requisiti.
9
2.2 Progettazione
Scopi di questa sezione sono l’esposizione e la motivazione delle scelte progettuali adottate. Si cer-
cherà di associare ad ogni specifica del sistema uno o più tra i requisiti raccolti: d’ora in avanti, la di-
citura “requisito n” indicherà l’n-esimo requisito inserito nella Tabella 1.
Dall’analisi dei requisiti risulta evidente la necessità di implementare tre servizi di diversa natura:
1. un’applicazione web, in grado di fornire i servizi amministrativi (requisiti 9 → 16);
2. il bot Telegram, in grado di soddisfare le esigenze dell’utente (requisiti 1, 2, 4→ 8, 21 → 26);
3. un parser che analizzi il flusso RSS del portale LavoroFVG (requisito 3).
Conviene dunque dividere la trattazione in tre sezioni, che sviluppino rispettivamente la progettazio-
ne dell’applicazione web, quella del bot Telegram e quella del parser RSS.
2.2.1 Progettazione dell’applicazione web
Questa sezione inizia e si conclude con la presentazione degli strumenti scelti per lo sviluppo
dell’applicativo (non sono stati fatti ulteriori ragionamenti progettuali).
La prima scelta effettuata consiste nella decisione di utilizzare un framework per realizzare applica-
zioni web, ossia un’intelaiatura logica di supporto che permette di velocizzare lo sviluppo di un soft-
ware. Per le funzionalità presenti e dal momento che la Direzione centrale lo utilizza già da tempo, si
è concluso che, nel caso in esame, lo strumento più adatto fosse Django.
Nei paragrafi che seguono saranno presentati, oltre alla piattaforma appena citata, altri elementi ne-
cessari per l’esecuzione dello stesso: Gunicorn e Nginx. Infine si parlerà di PostgreSQL, l’RDBMS
in cui saranno memorizzati i dati di interesse.
Django
Django è uno strumento a codice sorgente libero interamente scritto in linguaggio Python.
Figura 6: Logo di Django.
Esso viene utilizzato, ad alto livello, per la realizzazione della struttura di applicazioni web e offre
numerose funzionalità che puntano a uno sviluppo veloce e ad un’elevata portabilità[9]
. Di grande im-
portanza, in riferimento al progetto di cui si parla in questo documento, sono in particolare il suppor-
to nativo a diversi tipi di basi di dati[10]
, tra cui PostgreSQL, e la possibilità di creare in modo automa-
tico un sito amministrativo, sulla base dei modelli definiti dallo sviluppatore (per ulteriori informa-
zioni si rimanda al capitolo 3.2.2).
La specifica della Direzione centrale è stata di utilizzare Django 2.2. Per quanto riguarda la versione
di Python, si è deciso di utilizzare la più recente[11]
supportata dal framework, ossia Python 3.7.
Nonostante Django includa un server, da utilizzare localmente in fase di sviluppo, esso non è suffi-
ciente nel caso si voglia estendere la soluzione progettata a una scala più ampia di quella casalinga (si
veda il requisito 20). Vanno dunque configurate alcune componenti esterne, che permettano il sup-
porto dell’esecuzione delle applicazioni Django.
10
Django è compatibile con vari server basati sulla WSGI[12][13]
, un’interfaccia tra server e applicazioni
web scritte in Python che promuove la portabilità delle applicazioni. Nel progetto in esame la scelta è
ricaduta su Gunicorn, nella versione 20.0.2.
Gunicorn
Gunicorn è un software a codice sorgente libero scritto in Python, che supporta nativamente Django.
Figura 7: Logo di Gunicorn.
Il suo compito consiste fondamentalmente nel tradurre le richieste HTTP dei client in chiamate se-
condo il protocollo WSGI, che l’applicazione Django possa processare e a cui rispondere[14]
.
È caldamente consigliato usare Gunicorn associato a un server proxy HTTP inverso, a causa di pro-
blematiche legate alla sicurezza. Tra i molti esistenti, in particolare, gli sviluppatori consigliano l’uti-
lizzo di Nginx[15]
. Si è scelto di seguire questo consiglio e di usare l’ultima versione disponibile, la
1.17.
Nginx
Nginx è un software, a codice sorgente libero, che può essere utilizzato come server proxy per HTTP
(diretto e inverso), per la posta elettronica o, in generale, per i protocolli di rete TCP/UDP.
Figura 8: Logo di Nginx.
Per quanto riguarda l’ambito in esame è sufficiente citarlo in veste di server proxy HTTP inverso. Le
caratteristiche principali come tale comprendono l’architettura modulare e il supporto a vari meccani-
smi di caching (per ulteriori informazioni si rimanda alla documentazione ufficiale[16]
).
PostgreSQL
Anche per lo stoccaggio dei dati è stato scelto un software a codice sorgente libero: sarà infatti utiliz-
zato l’RDBMS PostgreSQL[17]
, nella versione 10.10.
Figura 9: Logo di PostgreSQL.
Si tratta di un sistema gratuito in grado di supportare alti carichi di lavoro. L’approfondimento del
funzionamento di tale strumento non è in questa sede rilevante, in quanto viene interfacciato con Py-
thon, e quindi Django, in modo automatico grazie alla libreria psycopg2.
Si osservi come l’RDBMS non possa essere una prerogativa dell’applicazione web ma debba essere
condiviso con il bot Telegram, di modo che entrambi i sistemi possano inserire dati e effettuare inter-
rogazioni.
11
2.2.2 Progettazione del bot Telegram
Per la realizzazione di un bot Telegram esistono fondamentalmente due alternative:
• usare un linguaggio che supporti direttamente l’utilizzo delle Bot API;
• fare affidamento a delle librerie che si occupino di fornire le suddette API sotto forma di fun-
zioni dedicate.
Al fine di agevolare lo sviluppo del sistema, la Direzione centrale ha scelto di seguire la seconda stra-
da e, in particolare, di utilizzare la libreria a codice sorgente libero python-telegram-bot.
Figura 10: Logo di python-telegram-bot.
Essa fornisce un’interfaccia Python pura per le Bot API di Telegram (essendo in linguaggio Python, è
possibile interfacciarsi senza problemi anche con Django). In aggiunta a ciò, sono state implementate
alcune classi di alto livello pensate per facilitare lo sviluppo dei bot[18]
.
La versione di python-telegram-bot usata è la 12.
Lettura automatica degli articoli
Si parlerà in questo paragrafo delle specifiche per il soddisfacimento del requisito 5 (la lettura auto-
matica degli articoli). La Direzione ha deciso di fare affidamento sul servizio Google Text-to-Speech:
esso permette in modo gratuito la conversione da testo a voce grazie alla tecnologia dell’apprendi-
mento automatico[19]
.
Per sfruttare queste funzionalità Google mette a disposizioni delle API dedicate, le API Cloud Text-
to-Speech. Analogamente a quanto detto per le Bot API, si è scelto di sfruttare una libreria che ne
permettesse l’interfaccia con Python. Sarà utilizzata in particolare la libreria gTTS (Google Text-to-
Speech), nella versione 2.0.4. Per ulteriori informazioni si consulti la documentazione associata[20]
.
2.2.3 Progettazione del parser RSS
Un parser è un programma che analizza un flusso continuo di dati in ingresso, riconosce al suo inter-
no una grammatica e costruisce in base ad essa un albero che mostra i legami logici tra le varie com-
ponenti. Nel caso in esame è necessario implementare un parser RSS, in quanto il portale LavoroF-
VG mette a disposizione un flusso di questo tipo.
Figura 11: Logo tipico per i flussi web.
La Direzione ha imposto in questo senso l’utilizzo di FeedParser[21]
(versione 5.2.0), che supporta un
ampio numero di feed RSS e Atom, affiancato da Beautiful Soap (versione 4.8.1), una libreria che
mette a disposizione alcuni metodi per la navigazione, ricerca e modifica di un albero di parsing[22]
.
12
2.2.4 Architettura complessiva
In quest’ultimo paragrafo viene esposta l’architettura complessiva del sistema che si dovrà andare a
realizzare. Per semplicità di lettura, è stata riportata in forma grafica in Figura 12.
Figura 12: Struttura complessiva del sistema.
Come richiesto dal requisito 17, alla base dei vari servizi da implementare c’è OS Linux. Sono poi
state rappresentate tre diverse sezioni:
• La prima, che termina con il Servizio 1, riguarda l’applicazione web di back office. Tale parte
permette il soddisfacimento dei requisiti amministrativi;
• La seconda, il Servizio 2, riguarda il bot Telegram. Essa consente l’adempimento dei requisiti
legati all’utente fruitore del servizio;
• La terza è l’RDBMS, posizionato al centro per sottolineare il fatto che debba essere condivi-
so dai due servizi.
Si nota l’assenza del parser RSS: tale strumento non sarà ulteriormente approfondito in quanto la sua
progettazione e realizzazione sono stati seguiti interamente dal professor Marco Tessarotto. Lo stesso
discorso vale per l’implementazione della lettura automatica degli articoli.
13
Linux OS
Applicazione web
Bot Telegram
Servizio 1
Servizio 2
14
Capitolo 3
Realizzazione
In questo capitolo sarà descritto il risultato del lavoro svolto. Come già è stato fatto nel capitolo pre-
cedente, nella sezione riguardante la progettazione, anche qui sarà divisa la trattazione dell’applica-
zione web da quella del bot Telegram, al fine di migliorare la comprensione del documento. Tutto ciò
sarà preceduto da un capitolo introduttivo in cui saranno esposte le modalità attraverso le quali è
stato sviluppato il progetto.
3.1 Modalità di lavoro
La parte di programmazione associato al progetto è stata realizzata con il supporto dello strumento
GitHub[23]
. Si tratta di una piattaforma per lo sviluppo di software diffusa a livello mondiale.
Figura 13: Logo di GitHub.
Essa permette varie meccanismi a supporto della programmazione in gruppo. Degni di nota sono in
particolare la possibilità di aprire delle “diramazioni” (branches) rispetto al progetto principale, così
da poter implementare delle funzionalità senza inficiare quelle già presenti, e la possibilità di unire
intelligentemente sezioni di codice realizzate da diversi programmatori (operazione di merge).
Il codice a cui ci si riferirà in questo capitolo può essere consultato alla pagina
https://github.com/marcotessarotto/dclavorofvg-bot
Prima di continuare è bene fare una precisazione: ciò che sarà descritto nei prossimi paragrafi potreb-
be discostarsi dalla versione consultabile all’indirizzo proposto. Il motivo sta nel fatto che il progetto
è in stato di sviluppo e che, di conseguenza, i moduli su GitHub sono frequentemente aggiornati. Per
evitare equivoci, dunque, si è deciso di riferirsi alla versione del progetto del 20 novembre 2019:
https://github.com/marcotessarotto/dclavorofvg-bot/tree/
2ce6f233fe164fc33b1627780fbc472e48b13bc8
15
Meriti
GitHub permette di quantificare il lavoro eseguito dai vari contributori associati a un progetto. Per
quello in esame sono stati impostati due collaboratori, il professor Tessarotto, che ne è il proprietario,
e l’autore di questo documento. Il lavoro svolto da ognuno può essere analizzato su GitHub[24]
. In
data 28 novembre 2019 la situazione è riassunta in Figura 14.
Figura 14: Analisi del lavoro svolto.
Si indica con il termine commit la procedura che rende effettive le modiche dei moduli effettuate in
locale. Per ogni documento sul quale è stato eseguito un commit, GitHub mette a disposizione uno
strumento che permette di visualizzare gli aggiornamenti in termini di righe inserite e cancellate: per
ulteriori informazioni riguardo l’entità del lavoro svolto da ognuno dei collaboratori, dunque, è suffi-
ciente utilizzare questo strumento. Tutti i commit eseguiti dall’autore sono riassunti all’indirizzo:
https://github.com/marcotessarotto/dclavorofvg-bot/commits?author=mtt-merz.
16
3.2 Applicazione web
In questa sezione sarà analizzata la parte della realizzazione legata all’applicazione web. Lo strumen-
to è necessario per soddisfare i requisiti amministrativi espressi nella fase di analisi (capitolo 2.1).
Un primo paragrafo sarà dedicato all’architettura del sistema; nei successivi sarà dato spazio alle so-
luzioni ideate e all’analisi del codice.
3.2.1 Architettura
Riprendendo quanto detto nel paragrafo 2.2.1 del precedente capitolo, Django non è sufficiente a ge-
stire direttamente le richieste HTTPS formulate dagli utenti ma deve essere affiancato da altri stru-
menti. In questa sezione sarà dunque analizzata l’architettura del sistema, che è stata riassunta nello
schema in Figura 15.
Figura 15: Architettura dell'applicazione web.
Nginx è il servizio esposto a Internet: esso resta in ascolto sulla porta 443 per richieste HTTPS da
parte degli utenti. Si tratta di un singolo processo, in esecuzione con privilegi ridotti. Le richieste ri-
cevute da Nginx vengono poi passate a Gunicorn attraverso gli Unix socket.
Gunicorn è un processo demone eseguito dal processo init con privilegi ridotti; nel momento in cui
riceve delle richieste da Nginx usa la chiamata di sistema fork per creare dei processi figli (dei wor-
kers) che si occupano della comunicazione con Django. Il protocollo di comunicazione è il WSGI.
Django comunica poi con la base di dati in PostgreSQL attraverso psycopg2, che si occupa di tradur-
re i comandi di interrogazione dal linguaggio Python a SQL, risolvendo il conflitto d'impedenza. In
questo modo Django ricava i dati richiesti dall’utente e li rimanda indietro secondo le stesse modalità
descritte, fino a Nginx, che comunica il risultato all’utente.
Si osservi come anche il bot Telegram abbia bisogno di interfacciarsi alla base di dati e all’applica-
zione web. Esso non è stato inserito in Figura 15 solo per una questione di chiarezza dell’esposizio-
ne: le modalità secondo cui avviene tale interfaccia saranno debitamente spiegate nel paragrafo 3.3.1.
17
Applicazione
backoffice
Utente
Richiesta
HTTPS
Risposta
HTTPS
HTTPS WSGI
psycopg2
SQL
3.2.2 Progetto Django
Questa sezione è dedicata all’analisi dei moduli associati all’applicazione web.
Per facilitare la comprensione dell’argomento si è deciso di dedicare uno spazio iniziale alla spiega-
zione della struttura del progetto, riportata per comodità in Figura 16:
• La cartella src/ descrive il progetto nella sua totalità (si osser-
vi la possibilità di modificare il nome di tale cartella, non im-
portante per Django).
• Il modulo src.manage è uno strumento utilizzabile da linea di
comando che permette di interagire in vario modo con il pro-
getto. Esso non sarà in questa sede ulteriormente approfondito;
per ulteriori informazioni si consiglia di consultare la documen-
tazione ufficiale[25]
.
• La cartella src/gfvgbo descrive l’ambiente di lavoro: contiene
diversi moduli legati al funzionamento del progetto in generale,
senza riferirsi alla singola applicazione.
• La cartella src/backoffice contiene invece tutte le informa-
zioni legate alla specifica applicazione backoffice.
Si può a questo punto passare alla descrizione e al commento dei moduli di maggiore importanza.
Analisi del modulo src.gfvgbo.secrets
In questo modulo sono definite le credenziali che permettono l’accesso alla base di dati in Postgre-
SQL e all’applicazione Django.
Trattandosi di informazioni riservate, il modulo non è stato inserito sulla pagina GitHub dedicata al
progetto; tuttavia, per il corretto funzionamento del sistema, esso deve essere necessariamente pre-
sente nella seguente forma.
1 DB_NAME = [...]
2 DB_USERNAME = [...]
3 DB_PWD = [...]
4
5 SECRET_KEY = [...]
6
7 SMTP_SERVER = [...]
8 SMTP_USER = [...]
9 SMTP_PASSWORD = [...]
10
11 EMAIL_SENDER = [...]
La variabile SECRET_KEY indica il codice segreto associato al progetto Django, generato al momento
della sua creazione dal comando startproject. Essa impedisce vulnerabilità legate all’esecuzione
remota del codice e alla possibilità di escalation dei privilegi utente[26]
.
Analisi del modulo src.gfvgbo.settings
In questo modulo sono definite le impostazioni globali del progetto, che si presentano sotto forma di
variabili. Quando viene creato un nuovo progetto Django, tale modulo viene generato automatica-
18
Figura 16: Struttura.
mente, secondo determinate direttive[27]
. Nel caso di esigenze particolari, come in qeullo in esame, è
però necessario effettuare delle modifiche.
Le principali modifiche apportate riguardano:
• le impostazioni associate alla base di dati;
1 DATABASES = {
2 'default': {
3 'ENGINE': 'django.db.backends.postgresql_psycopg2',
4 'NAME': DB_NAME,
5 'USER': DB_USERNAME,
6 'PASSWORD': DB_PWD,
7 'HOST': 'localhost',
8 'PORT': '',
9 }
10 }
(le costanti DB_* sono importate dal modulo src.gfvgbo.secrets).
• il percorso in cui devono essere salvati i documenti gestiti dall’applicazione;
1 MEDIA_ROOT = '/opt/media/dclavorofvg-bot/'
2 AUDIO_ROOT = os.path.join(MEDIA_ROOT, 'audio/')
• le impostazioni del server HTTP WSGI;
1 WSGI_APPLICATION = 'gfvgbo.wsgi.application'
• l’aggiunta di backoffice tra le applicazioni installate.
Per ulteriori informazioni riguardo alle varie opzioni di configurazione è possibile consultare la docu-
mentazione ufficiale, reperibile alla voce 27 della bibliografia.
Analisi del modulo src.backoffice.models
In questo modulo sono contenuti i modelli relativi all’applicazione web backoffice. Prima di iniziare
l’analisi è bene dare una definizione di modello: esso rappresenta la singola e definitiva fonte di in-
formazione riguardo un tipo di dato che si vuole immagazzinare. Ad ogni modello, che nella base di
dati corrisponde a una relazione, sono associati dei campi, gli attributi della relazione, e alcuni com-
portamenti. Dal punto di vista pratico, ogni modello è una classe Python sottoclasse di django.db.
models.Model e ogni campo è un’istanza della classe django.db.models.Field appropriata[28]
.
In Figura 17 è stato rappresentato il diagramma UML delle classi create, in modo da facilitare la
comprensione del modulo. La Tabella 2 si occupa, riferendosi ad esso, di fornire una descrizione più
approfondita dei vari modelli.
Modello Descrizione
TelegramUser
Rappresenta un utente del servizio Telegram.
I campi user_id, username, first_name, last_name, is_bot e lan-
guage_code sono fornite da Telegram.
Il campo privacy_acceptance_mechanism indica la modalità con cui è
stato effettuato l’accesso al servizio: se direttamente tramite Telegram var-
rà “U”, se attraverso il portale “L”.
Il campo regionefvg_id, non nullo solo nel caso in cui l’accesso è stato
fatto dal portale, ha un fine d’uso interno.
19
Modello Descrizione
UserFreeText
Rappresenta un messaggio libero scritto da un utente in cui non è specifi-
cato alcun comando (i comandi iniziano con il carattere “/”).
NewsItem
Rappresenta un articolo da inviare agli utenti Telegram.
Il campo broadcast_message, se posto a True, forza la notifica di un ar-
ticolo a tutti gli utenti, indipendentemente dalle categorie scelte dai singoli.
Il campo start_publication permette di impostare una data per l’invio
di un articolo che sia diversa dal momento di caricamento dello stesso.
I campi file1, file2 e file3 sono oggetti NewsFile, ossia degli allega-
ti.
Il campo recurrent_for_new_users forza l’invio dell’articolo a tutti i
nuovi utenti Telegram nel momento in cui si iscrivono al servizio, indipen-
dentemente dalle categorie scelte.
Il campo processed indica se l’articolo è già stato spedito a tutti gli utenti
che dovevano riceverlo o se è ancora in coda d’invio.
NewsFile
Rappresenta un documento di qualsiasi tipo (immagine, documento di te-
sto, traccia audio ecc…) che è stato allegato a uno o più articoli.
NewsItemSentToUser Rappresenta l’invio di una notizia a un determinato utente.
FeedbackToNewsItem
Rappresenta un feedback espresso da un utente in riferimento a un deter-
minato articolo.
Il campo val può assumere i valori +1 e -1.
CommentToNewsItem
Rappresenta un commento scritto da un utente in riferimento a un determi-
nato articolo.
Category
Rappresenta una categoria di articoli che può essere scelta dagli utenti.
Il metodo fill_categories() serve a popolare la relazione, nel caso sia
vuota (quindi non appena il servizio è stato avviato), con le categorie pre-
impostate. Tali categorie vengono estratte dal dizionario DEFAULT_CATE-
GORIES_DICT, importato dal modulo src.backoffice.definitions.
CategoriesGroup
Rappresenta un insieme di categorie che condividono una tematica, indica-
ta nel campo name.
RssFeedItem
Rappresenta un oggetto ricevuto dal portale, in formato RSS, da processare
perché diventi un articolo da inviare.
Il campo update_parsed indica il momento in cui l’oggetto è stato pub-
blicato sul portale, o, più precisamente, il momento in cui l’applicazione ne
ha notato la presenza.
Il campo processed indica se l’oggetto è già stato trasformato in un arti-
colo oppure se deve ancora essere processato.
LogUserInteraction
Rappresenta un’interazione di un utente con il bot.
Il campo text registra qualsiasi messaggio ricevuto dal bot, che sia un co-
mando riconosciuto o un testo libero.
SystemParameter
Rappresenta un parametro di sistema (per esempio il messaggio da inviare
come risposta al comando /help).
Il metodo update_system_parameters() permette di popolare la base di
dati con i parametri di sistema preimpostati.
TextToSpeechWord
Subsitution
Rappresenta un oggetto legato alla funzionalità di lettura automatica del ti-
tolo degli articoli.
Tabella 2: Elenco dei modelli.
20
Figura 17: Schema UML delle classi.
21
Category
+ key : CharField(2)
+ name : CharField(256)
+ emoji : CharField(9)
+ desciption : CharField(256)
+ is_telegram_command : BooleanField = True
+ custom_telegram_command : CharField(64)
+ updated_at : DateTimeField
+ __str__()
+ fill_categories()
CategoriesGroup
+ name : CharField(256)
+ categories : ManyToManyField
+ add_bot_command : BooleanField = True
+ updated_at = DateTimeField
+ __str__()
NewsItemSentToUser
+ telegram_user : ForeignKey
+ news_item : ForeignKey
+ flags : CharField(4)
+ created_at : DateTimeField
+ __str__()
TelegramUser
+ user_id : BigIntegerField
+ regionefvg_id : BigIntegerField = -1
+ username : CharField(32)
+ first_name : CharField(50)
+ last_name : CharField(50)
+ is_bot : BooleanField = False
+ is_admin : BooleanField = False
+ language_code : CharField(2)
+ categories : ManyToManyField
+ age : IntegerField = -1
+ educational_level : CharField(1) = “-”
+ has_accepted_privacy_rules : BooleanField = False
+ privacy_acceptance_mechanism : CharField(1)
+ privacy_acceptance_timestamp : DataTimeField
+ enabled : BooleanField = True
+ is_text_to_speech_enabled : BooleanField = True
+ chat_state : CharField(1) = “-”
+ number_of_received_news_item : BigIntegerField = 0
+ email : CharField(256)
+ created_at : DateTimeField
+ updated_at : DateTimeField
+ __str__()
+ educational_level_verbose()
+ categories_str()
UserFreeText
+ text : CharField(1024)
+ telegram_user : ForeignKey
+ created_at : DateTimeField
+ __str__()
RssFeedItem
NewsFile
+ file_field : FileField
+ upload_date : DateTimeField
+ __str__()
NewsItem
+ title : CharField(1024)
+ title_link : CharField(1024)
+ text : CharField(2048)
+ show_all_text : BooleanField = True
+ show_first_n_words : IntegerField = 30
+ categories : ManyToManyField
+ broadcast_message : BooleanField = False
+ link : CharField(1024)
+ link_caption : CharField(1024) = “continua”
+ file1 : ForeignKey
+ file2 : ForeignKey
+ file3 : ForeignKey
+ like : BigIntegerField = 0
+ disilke : BigIntegerField = 0
+ start_publication : DataTimeField
+ recurrent_for_new_users : BooleanField = False
+ processed : BooleanField = False
+ processed_timestamp : DateTimeField
+ rss_id : CharField(256)
+ ask_comment_to_user : BooleanField = False
+ created_at : DateTimeField
+ updated_at : DateTimeField
+ __str__()
FeedbackToNewsItem
+ news : ForeignKey
+ user : ForeignKey
+ val : SmallIntegerField = 0
+ created_at : DateTimeField
+ rss_id : CharField(1024)
+ rss_title : CharField(1024)
+ rss_link : CharField(1024)
+ update_parsed : DateTimeField
+ category : ForeignKey
+ processed : BooleanField = False
+ created_at : DateTimeField
+ __str__()
+ data_feed_was_last_updated()
CommentToNewsItem
+ news : ForeignKey
+ user : ForeignKey
+ text : CharField(4096)
+ created_at : DateTimeField
+ __str__()
LogUserInteraction
+ user_id : BigIntegerField = -1
+ text : CharField(1024)
+ coming_from_user : BooleanField = True
+ created_at : DateTimeField
+ updated_at : DateTimeField
+ __str__()
SystemParameter
+ name : CharField(256)
+ value : TextField(4096)
+ comment : CharField(256)
+ __str__()
+ add_default_param()
+ update_system_parameters()
TextToSpeechWordSubstitution
+ original : CharField(64)
+ substitution : CharField(64)
+ lang : CharField(2) = “it”
+ fill_substitutions()
+ load()
0..N 1..1
0..N
0..N
0..N
0..N
0..N
1..1
1..1
1..1
1..1
1..1
0..N
0..N
0..N
0..N
0..1
0..3
1..N
0..N
0..N
Analisi del modulo src.backoffice.admin
In questo modulo sarà descritta l’interfaccia amministrativa dell’applicazione web backoffice, gene-
rata automaticamente da Django sulla base dei modelli definiti nel modulo src.backoffice.mo-
dels. La formattazione dei vari elementi e le funzionalità disponibili sono pensate per facilitare agli
amministratori la gestione dei contenuti del sito[29]
.
In Figura 18 è raffigurata la pagina principale creata per l’applicazione in esame.
Figura 18: Elenco dei modelli inseriti nella pagina amministrativa di backoffice.
Selezionando uno dei modelli elencati si apre una nuova pagina, raffigurata in Figura 19, con tutte le
istanze della classe presenti. Si farà riferimento, come caso esemplificativo, al modello NewsItem.
Figura 19: Pagina di backoffice dedicata al modello NewsItem.
È poi possibile visualizzare, ed eventualmente modificare, come suggerisce il titolo della schermata,
le informazioni legate ad una particolare istanza selezionandola dall’elenco.
Dopo questa prima fase di analisi dell’interfaccia, si passa all’analisi del codice.
22
2
1
3
4
Tutto ciò che è stato fino ad ora presentato viene creato automaticamente da Django: l’utilità di que-
sto modulo consiste semplicemente nella specifica di alcune personalizzazioni, così che l’interfaccia
sia adeguata alle proprie necessità.
Il codice che segue contiene le personalizzazioni per il modello NewsItem.
1 @admin.register(NewsItem)
2 class NewsItemAdmin(admin.ModelAdmin):
3
4 list_display = ('id', 'title', 'created_at', 'list_of_categories',
5 'processed', 'processed_timestamp', 'like', 'dislike')
6 exclude = ('like', 'dislike')
7 search_fields = ('id', 'title')
8 list_filter = ('categories',)
9
10 formfield_overrides = {
11 models.ManyToManyField: {'widget': CheckboxSelectMultiple},
12 models.CharField: {'widget': TextInput(attrs={'size': '80'})}
13 }
14
15 def list_of_categories(self, obj):
16 return ',n'.join([a.name for a in obj.categories.all()])
17
18 list_of_categories.short_description = "Categorie"
Le impostazioni di visualizzazione sono inserite in una classe dedicata, denominata per chiarezza
NewsItemAdmin, e vengono associate al modello desiderato attraverso il decoratore alla riga 1, un
metodo predisposto a tal proposito da Django.
Sono state specificate le seguenti opzioni di visualizzazione:
• alla riga 4, list_display indica i campi visibili della tabella che raccoglie tutte le istanze
della classe NewsItem. Il risultato si può apprezzare in Figura 19 nel riquadro 1;
• alla riga 7, search_fields specifica i campi sui quali vanno impostati i filtri testuali inseriti
attraverso la barra di ricerca in Figura 19 nel riquadro 2;
• alla riga 8, list_filter specifica i campi attraverso i quali si possono filtrare gli elementi
visualizzati nell’elenco. Si ottiene in questo caso una tabella posizionata sul margine destro,
come mostrato in Figura 19 nel riquadro 3;
• alla riga 6, exclude specifica i campi che vanno esclusi dalle pagine di aggiunta e di modifi-
ca degli oggetti NewsItem;
• alla riga 10, formfields_overrides permette di modificare il formato di visualizzazione
delle classi django.db.models.Field specificate, nel caso in esame ManyToManyField
(riga 11) e CharField (riga 12);
• alla riga 15, la funzione list_of_categories() specifica in che formato vanno mostrate le
categorie nella pagina mostrata in Figura 19.
Per ulteriori informazioni riguardo le opzioni di visualizzazione si consiglia di visitare la pagina della
documentazione ufficiale associata[30]
.
23
3.3 Bot Telegram
In questa sezione sarà analizzata la parte della realizzazione legata al bot Telegram.
La trattazione delle funzionalità implementate inizia con la presentazione dell’architettura del sistema
realizzato. Si passa poi all’analisi dell’interfaccia utente, in cui si spiega cosa il bot può fare, e quin-
di alla spiegazione del codice, così da comprendere come lo fa.
3.3.1 Architettura
L’architettura del bot Telegram è rappresentata in Figura 2.
Figura 20: Architettura del bot Telegram.
L’utente interagisce con il bot inviando messaggi, comandi e richieste dall’applicazione Telegram, in
versione mobile o desktop. Tali informazioni, prima di essere gestite dal sistema realizzato, sono pro-
cessate dai server Telegram, che le rendono disponibili attraverso le Bot API.
python-telegram-bot si occupa dell’interazione con le Bot API e le rende disponibile in Python.
Come era stato accennato nel capitolo 3.2.1, anche il bot Telegram ha accesso ai modelli definiti
nell’applicazione web. Il meccanismo che rende possibile ciò sarà analizzato nel dettaglio nel capito-
lo 3.3.3, all’interno del paragrafo che illustra il modulo src.telegram_bot.django_settings.
3.3.2 Interfaccia utente
Questa sezione è dedicata all’analisi, attraverso la presentazione dell’interfaccia utente, del funziona-
mento generale del bot Telegram. Altre funzionalità, disponibili esclusivamente all’amministratore o
di minore importanza, saranno descritte nel capitolo 3.3.3, con il supporto del codice.
La descrizione è accompagnata da schermate dell’applicazione in versione desktop, così che il lettore
ne possa valutare immediatamente la qualità.
Il comando /start
Premendo sul pulsante AVVIA l’utente inizia la conversazione con il bot. La prima cosa che gli sarà
chiesta riguarda l’accettazione dell’informativa sul trattamento dei dati personali. Come mostrato in
Figura 21, non appena l’utente riceve il messaggio la tastiera viene sostituita con i pulsanti ACCET-
24
Bot Telegram
DCLavoroFvg
backoffice
Utente
Scambio di
messaggi
Notifica
pubblicazione
articoli
HTTPS
psycopg2
SQL
TO e NON ACCETTO: tale accorgimento facilita l’iterazione con il bot in quanto è sufficiente pre-
mere su uno di essi per inviare la risposta.
Figura 21: Invio dell'informativa sul trattamento dei dati personali.
Per consultare le condizioni poste è sufficiente aprire l’allegato al messaggio, oppure seguire il colle-
gamento che lo precede, riportato per completezza anche in questo documento:
http://www.regione.fvg.it/rafvg/cms/RAFVG/formazione-lavoro/lavoro/allegati/
informativa_dir_lavoro_servizi_messaggistica102019.pdf
Ci sono a questo punto due possibili sviluppi:
• Se l’utente sceglie di non accettare l’informativa il bot si blocca e a qualsiasi comando inseri-
to risponderà come mostrato in Figura 22.
Figura 22: Il bot è bloccato.
L’unico modo per sbloccare il bot è inserire il comando /privacy e accettare l’informativa.
• Al contrario, nel caso in cui l’informativa sia stata accettata, il bot inizia una breve conversa-
zione per raccogliere alcune informazioni sull’utente, finalizzate alla profilazione per il mi-
glioramento del servizio. Tali informazioni sono età e titolo di studio più elevato. Si osservi
in Figura 23 come il titolo di studio vada inserito con la stessa modalità richiesta per l’accet-
tazione dell’informativa.
25
Figura 23: Inserimento del titolo di studio più elevato.
Il comando /scegli
Una volta selezionato anche il titolo di studio, l’utente viene invitato a inserire il comando /scegli,
così da selezionare, tra quelle disponibili, le categorie di suo interesse. La schermata che si presenta
all’invio del comando è riportata in Figura 24.
Figura 24: Scelta delle categorie di interesse.
In questo caso compare un secondo tipo di tastiera, i cui pulsanti sono posizionati immediatamente
sotto il messaggio inviato dal bot. Ognuno di essi funziona come un interruttore: premendoli, se la
categoria non era selezionata allora lo diventa, se lo era viene deselezionata.
26
Terminata la scelta è sufficiente premere il pulsante CHIUDI: il messaggio precedente sarà sostituito
da uno riassuntivo delle categorie scelte, riportato in Figura 25.
Figura 25: Riassunto delle categorie scelte.
A questo punto può considerarsi terminata la configurazione del servizio.
Il comando /categorie
Esistono due modalità per modificare la scelta delle categorie di interesse. La prima consiste
nell’inviare nuovamente il comando /scegli, la seconda nel digitare il comando /categorie. Nel secon-
do caso il bot risponderà come rappresentato in Figura 26.
Figura 26: Elenco dei comandi relativi alle categorie.
Selezionando uno dei comandi elencati si otterrà, in base alle categorie precedentemente selezionate,
il messaggio in Figura 27 oppure quello in Figura 28 (si è supposto di scegliere la categoria Lavoro).
Figura 27: Proposta di smettere di seguire la categoria specificata.
27
Nel primo caso la categoria era stata precedentemente selezionata e il bot chiede all’utente se deside-
ra continuare a seguirla oppure no.
Figura 28: Proposta di iniziare a seguire la categoria specificata.
Nel secondo caso la situazione è opposta a quella precedente (la categoria non era ancora stata sele-
zionata e il bot propone all’utente di iniziare a seguirla).
L’invio degli articoli
Non appena un nuovo articolo viene pubblicato sul portale, il bot invia una notifica agli utenti inte-
ressati. In Figura 29 è mostrato il formato di tale messaggio.
Figura 29: Notifica della pubblicazione di un nuovo articolo.
Si osservi la corrispondenza tra il formato della notifica e quello richiesto nei requisiti in Figura 3.
Per continuare la lettura bisogna premere il testo in blu continua (si tratta di un collegamento per la
pagina del portale contenente l’articolo completo). Si può esprimere un giudizio binario sull’utilità di
ogni articolo ricevuto premendo su uno dei due pulsanti inseriti sotto il messaggio.
28
In base all’articolo ricevuto, inoltre, è stata implementata la possibilità di inserire dei commenti, solo
dopo aver espresso il giudizio appena citato. L’interfaccia che si presenta all’utente in questa even-
tualità è mostrata in Figura 30.
Figura 30: Interfaccia per l'inserimento dei commenti, Pt. 1.
Premendo sul pulsante che compare sotto il messaggio si presenta in automatico la situazione descrit-
ta in Figura 31: l’utente è invitato a inserire il testo del commento in risposta ad un messaggio del bot
che specifica l’identificatore dell’articolo.
Figura 31: Interfaccia per l'inserimento dei commenti, Pt. 2.
Una volta formulato il commento è sufficiente inviarlo affinché venga registrato.
Il comando /rimanda_ultime_news
Inviando il comando /rimanda_ultime_news, il bot restituisce, in ordine di pubblicazione, il titolo e la
categoria degli articoli notificati negli ultimi dieci giorni, a partire dal meno recente. In Figura 32 è
stato riportato un esempio della risposta a tale comando.
Figura 32: Riassunto degli articoli inviati negli ultimi dieci giorni.
A questo punto l’utente può decidere se ricevere nuovamente la notifica di uno degli articoli elencati,
inviando il comando /mostra_ seguito dall’identificatore dell’articolo, oppure ricevere un messaggio
con una traccia audio generata dalla lettura automatica del titolo di uno degli articoli. Per usufruire di
29
questa seconda funzionalità è necessario inviare il comando /leggi_, anch’esso seguito dall’identifica-
tore dell’articolo. Il risultato è rappresentato Figura 33.
Figura 33: Lettura del titolo dell'articolo selezionato.
Il comando /statistiche
Digitando il comando /statistiche il bot invia un messaggio che riassume il numero di notizie inviate
per ogni categoria negli ultimi dieci giorni, come rappresentato in Figura 34.
Figura 34: Statistiche sugli articoli inviati negli ultimi dieci giorni.
Il comando /help
Digitando il comando /help, o, equivalentemente, il comando /aiuto, il bot invia un messaggio espli-
cativo del proprio funzionamento. Tale messaggio viene riportato in Figura 35.
Figura 35: Messaggio esplicativo del funzionamento del bot.
Nei paragrafi precedenti sono già stati analizzati tutti i comandi elencati nel messaggio.
30
3.3.3 Codice
I moduli relativi alla realizzazione del bot Telegram sono collocati nella cartella src/
telegram_bot. I principali, che saranno analizzati in questo documento, sono i seguenti:
• regionefvg_bot
• news_processing
• log_utils
• ormlayer
• django_settings
Il bot viene avviato eseguendo il modulo src.telegram_bot.regionefvg_bot.
Analisi del modulo src.telegram_bot.regionefvg_bot
Ad essere analizzato in questo paragrafo è il modulo principale del bot Telegram. Il punto di partenza
per l’analisi è il metodo main(), del quale viene riportata una parte di codice.
1 token_file = Path('token.txt')
2
3 token = os.environ.get('TOKEN') or open(token_file).read().strip()
4 mqueue = messagequeue.MessageQueue(all_burst_limit=29, all_time_limit_ms=1017)
5 request = Request(con_pool_size=8)
6
7 global global_bot_instance
8 global_bot_instance = MQBot(token, request=request, mqueue=mqueque)
9
10 updater = Updater(bot=global_bot_instance, use_context=True)
11 dp = updater.dispatcher
12
13 job_queue = updater.job_queue
14 job_minute = job_queue.run_repeating(
15 news_dispatcher,
16 interval=NEWS_CHECK_PERIOD,
17 first=0
18 )
19
20 # AGGIUNTA DEGLI HANDLER
21
22 updater.start_polling()
23 updater.idle()
Le prime righe del codice sono dedicate alla memorizzazione del codice univoco associato al bot.
Tale codice, necessario per poterlo avviare, viene fornito durante la sua creazione dal @botfather[31]
,
un bot creato da Telegram che fornisce un’interfaccia per la creazione di altri bot.
Le righe successive, dalla 4 alla 8, sono associate a un problema totalmente diverso. Esistono dei li-
miti intrinseci per inviare messaggi attraverso i bot, così da non poterli usare per inviare spam[32]
: tali
limiti, detti per questo motivo limiti di spam, sono riassunti in Tabella 3.
Numero massimo di messaggi Contesto di applicazione
30 messaggi al secondo In conversazioni private (il caso di questo bot).
20 messaggi al minuto All’interno di gruppi.
Tabella 3: Limiti di spam.
Superate queste soglie le Bot API restituiscono il messaggio di errore 429.
31
È dunque necessario implementare un meccanismo che limiti il traffico generato. La libreria python-
telegram-bot mette a disposizione a tal proposito la classe MessageQueue, definita all’interno del
modulo telegram.ext.messagequeues: essa permette di sottoporre a un determinato ritardo la
spedizione dei messaggi. Nella riga 4, sfruttando tale classe, si impone di non inviare più di 29 mes-
saggi ogni 1017 millisecondi (così da avere un margine del 5% rispetto al limite di spam).
Alla riga 8 viene definito l’oggetto Bot[33]
configurato con le informazioni fino ad ora impostate.
Alla riga 10 si inizializza, attraverso l’oggetto appena creato, l’oggetto Updater[34]
. Si tratta di una
componente fondamentale del progetto in quanto è lui a ricevere gli aggiornamenti da Telegram.
Creando tale oggetto, inoltre, viene creato automaticamente un oggetto Dispatcher[35]
(riga 11), nel
quale è possibile registrare diversi tipi di handler. Gli aggiornamenti ricevuti dall’Updater sono pas-
sati al Dispatcher, il quale a sua volta li invia a una determinata funzione di callback sulla base
dell’handler che l’aggiornamento ha stimolato.
Alla creazione dell’Updater, viene creato automaticamente anche un oggetto JobQueue[36]
(riga 13),
il quale permette di eseguire delle operazioni con un ritardo, oppure secondo un intervallo preimpo-
stato. Nel caso in esame, è necessario che il bot controlli regolarmente la presenza di nuovi articoli da
inviare: tale specifica viene soddisfatta con la riga 14 (e seguenti), in cui si impone che la funzione
news_dispatching sia eseguita ogni NEWS_CHECK_PERIOD secondi, a partire dal momento in cui il bot
viene avviato. La funzione non sarà approfondita in questo paragrafo in quanto definita nel modulo
news_processing.
Alla riga 22 viene attivato l’Updater, che si mette in ascolto per intercettare gli aggiornamenti.
Il bot rimane in ascolto fino al momento in cui riceve i segnali SIGINT o SIGTERM. Il comando inse-
rito alla riga 23 permette di evitare una terminazione brusca del bot alla ricezione di tali segnali.
Elenco degli handler
Si indica con il termine handler un metodo utilizzato per la gestione di un evento. Nel caso in esame
gli eventi gestiti sono gli aggiornamenti ricevuti da Telegram: gli handler sono quindi quelle funzioni
che rispondono alle azioni dell’utente (ad ogni tipo di azione è associato un determinato handler). Per
ulteriori informazioni sull’argomento si rimanda alla pagina dedicata della documentazione ufficiale
python-telegram-bot[37]
.
Alla riga 20 è stato inserito un commento al posto delle righe di codice riguardanti l’aggiunta dei vari
handler, in modo da non appesantire la lettura del documento. In questo paragrafo essi saranno ana-
lizzati più nel dettaglio.
Innanzitutto è bene chiarire il significato delle variabili che ogni handler riceve come parametri:
• update è un’istanza dell’oggetto Update e rappresenta un aggiornamento raccolto dall’Upda-
ter. Esso contiene vari campi legati alla natura dell’aggiornamento gestito[38]
.
• context è un’istanza dell’oggetto CallbackContext e contiene vari campi legati al contesto in
cui lo handler è stato chiamato. Per esempio, i campi chat_data e user_data possono esse-
re usati per immagazzinare dati riutilizzabili in altri handler[39]
.
Si passa dunque all’analisi degli handler. Al fine di migliorare la comprensione del documento, in Ta-
bella 4 ne è stato inserito un elenco, ognuno accompagnato da una breve descrizione.
32
Nome Tipo Descrizione
start
Command
Handler
Invia un messaggio di benvenuto all’utente.
conve
Conversation
Handler
Avvia la procedura iniziale che permette di accettare le con-
dizioni d’utilizzo del servizio e di inserire i dati per la profi-
lazione dell’utente.Il risultato è riportato in Figura 21.
privacy
Command
Handler
Nel caso in cui non sia ancora avvenuta, propone l’accetta-
zione dell’informativa con le condizioni d’utilizzo.
undo_privacy
Command
Handler
Revoca l’accettazione dell’informativa con le condizioni
d’utilizzo del servizio.
callback_privacy
Message
Handler
Memorizza la risposta dell’utente alla richiesta di accettare
l’informativa con le condizioni d’utilizzo del servizio.
callback_age
Message
Handler
Memorizza l’età inserita dall’utente.
callback_
educational_level
Message
Handler
Memorizza il titolo di studio più elevato dell’utente, nel caso
sia stato selezionato tra quelli proposti.
callback_custom_
educational_level
Message
Handler
Memorizza il titolo di studio più elevato dell’utente, nel caso
non fosse presente tra quelli proposti.
help
Command
Handler
Mostra un messaggio esplicativo delle finalità del bot e dei
comandi a disposizione dell’utente.
Il messaggio è riportato in Figura 35.
help_categories
Command
Handler
Mostra un messaggio con i comandi relativi alle categorie tra
le quali l’utente può scegliere.
Il messaggio è riportato in Figura 26.
choose_news_
categories
Command
Handler
Permette all’utente di scegliere le categorie di interesse.
Il risultato è riportato in Figura 24.
set_all_
categories
Command
Handler
Seleziona come categorie di interesse tutte quelle disponibili.
set_no_categories
Command
Handler
Deseleziona tutte le categorie di interesse.
resend_last_
processed_news
Command
Handler
Invia il titolo e l’identificatore degli articoli inviati negli ulti-
mi dieci giorni. Il risultato è riportato in Figura 32.
show_news
Message
Handler
Invia l’articolo passato per parametro dall’utente (per esem-
pio, se l’utente scrive /mostra_2 gli sarà inviata la notizia
con identificatore 2).
read_news
Message
Handler
Invia un messaggio con una traccia audio generata dalla let-
tura del titolo dell’articolo passato per parametro dall’utente.
Il messaggio è riportato in Figura 33.
audio_on
Command
Handler
Abilita l’invio delle traccie audio generate dalla lettura dei ti-
toli degli articoli.
audio_off
Command
Handler
Disabilita l’invio delle traccie audio generate dalla lettura dei
titoli degli articoli.
comment
Message
Handler
Raccoglie il commento inserito da un utente per un determi-
nato articolo.
33
Nome Tipo Descrizione
callback
Callback
Query
Handler
Gestisce i dati inviati da tutte le tastiere create sotto i mes-
saggi (quella per esprimere un giudizio binario su un artico-
lo, quella per commentare un articolo e quella per seleziona-
re le categorie di interesse).
force_send_news
Command
Handler
Forza il controllo della pubblicazione di nuovi articoli.
Questo comando è disponibile esclusivamente agli ammini-
stratori del bot.
ping
Command
Handler
Controlla lo stato dei servizi di sistema legati all’applicazio-
ne web backoffice.
Questo comando è disponibile esclusivamente agli ammini-
stratori del bot.
cleanup
Command
Handler
Elimina lo storico degli articoli spediti all’utente.
Questo comando è disponibile esclusivamente agli ammini-
stratori del bot.
stats
Command
Handler
Invia un messaggio contenente le statistiche sugli articoli in-
viati negli ultimi dieci giorni.
Il messaggio è riportato in Figura 34.
custom_command
Message
Handler
Gestisce i comandi inviati dall’utente che non sono stati ge-
stiti da alcun CommandHandler. Essi potrebbero essere sco-
nosciuti oppure ricadere nell’insieme dei comandi legati alle
categorie.
generic_message
Message
Handler
Registra i messaggi ricevuti che non sono stati gestiti da al-
cun Handler.
error_callback
Error
Handler
Gestisce vari tipi di eccezioni riscontrate nella ricezione de-
gli aggiornamenti. In particolare, sono gestiti gli errori
Unauthorized, BadRequest, TimedOut, NetworkError, Chat-
Migrated e TelegramError. Per ulteriori informazioni si con-
siglia di consultare la documentazione ufficiale[40]
.
Tabella 4: Elenco degli handler.
Analisi del modulo src.telegram_bot.news_processing
A questo modulo è delegato il compito di inviare gli articoli. Vista la complessità del processo, si è ri-
tenuto opportuno procedere per fasi.
FASE 1. La procedura viene innescata da una chiamata al metodo news_dispatcher. Esso raccoglie
gli articoli non ancora inviati, se presenti, e ne programma l’invio; effettua inoltre su ognuno dei con-
trolli, così da spedirli esclusivamente agli utenti interessati.
FASE 2. Una volta determinati gli articoli da inviare e gli utenti a cui inviarli viene invocato il meto-
do send_news_to_telegram_user. Esso riceve come parametri un oggetto NewsItem (l’articolo da
inviare), un oggetto TelegramUser (l’utente a cui inviarlo), le categorie in comune tra quelle scelte
dall’utente e quelle assegnate all’articolo e altre informazioni riguardanti il formato con cui l’articolo
dovrà essere recapitato. Esistono infatti diverse opzioni d’invio:
• se il valore della costante SHOW_CATEGORIES_IN_NEWS, definita nel modulo src.backof-
fice.definitions, è True, l’articolo inviato sarà preceduto da un messaggio contenente le
categorie passate per parametro;
• nel caso in cui il parametro title_only sia True, la notifica conterrà esclusivamente il tito-
lo dell’articolo;
34
• nel caso in cui il parametro request_feedback sia True, la notifica sarà seguita da un se-
condo messaggio che chiede all’utente di inserire un giudizio binario (“Mi piace” / “Non mi
piace”) sull’articolo ricevuto;
• nel caso in cui il parametro ask_comment sia True, l’utente avrà la possibilità, oltre che a
esprimere un giudizio binario, di formulare un commento per l’articolo ricevuto.
Questo metodo si occupa di spedire gli articoli secondo tutte le modalità presentate, ma solo nel caso
in cui non siano presenti degli allegati.
FASE 3. Entra in gioco a questo punto il metodo _send_file_using_mime_type. Esso viene invo-
cato da send_news_to_telegram_user nel caso in cui l’articolo da inviare contenga degli allegati.
In python-telegram-bot esistono delle funzioni di invio diverse in base al tipo di documento da invia-
re (per esempio nel caso di un’immagine si usa il metodo context.bot.send_photo): questo meto-
do si occupa quindi di usare la funzione corretta in base al tipo di documento da inviare (riceve tale
informazione come parametro).
Prima di continuare con l’analisi è bene introdurre un particolare comportamento di Telegram, molto
utile ai fini di questo progetto. Tale funzionalità consiste nella memorizzazione di un qualsivoglia do-
cumento, non appena viene inviato un messaggio che lo contiene come allegato, nei server di Tele-
gram. Ad esso viene associato durante la memorizzazione un codice univoco, così che, nel caso tale
documento debba essere inviato nuovamente, sia possibile farlo riferendosi solo al suo identificatore.
Tornando al caso in esame, nel momento in cui il bot invia un articolo con allegati al primo utente de-
stinatario, gli allegati rimarranno in memoria e sarà possibile inviarli agli altri utenti attraverso
l’identificatore appena nominato. È evidentemente consigliato sfruttare tale comportamento, in quan-
to si ottiene attraverso di esso un notevole risparmio di banda.
Alla fine del metodo _send_file_using_mime_type, e quindi dopo ogni invio di un messaggio
con allegato, viene invocata la funzione _lookup_file_id_in_message, di cui viene riportato una
parte del codice. Essa ha il compito di ricavare l’identificatore dell’allegato, se non era già stato rica-
vato in una chiamata precedente.
1 def _lookup_file_id_in_message(message, _file_path: str, file_id):
2
3 if file_id is not None:
4 return
5
6 _file_id = None
7 try: _file_id = message.document.file_id
8 except AttributeError:
9 try: _file_id = message.photo[0].file_id
10 except (AttributeError, IndexError) as e:
11 try: _file_id = message.animation.file_id
12 except (AttributeError, IndexError) as e:
13 try: _file_id = message.animation[0].file_id
14 except (AttributeError, IndexError, TypeError) as e:
15 try: _file_id = message.voice.file_id
16 except (AttributeError, IndexError) as e:
17 try: _file_id = message.video.file_id
18 except (AttributeError, IndexError) as e:
19 return
20
21 if _file_id is not None:
22 file_id_cache_dict[_file_path] = _file_id
23
24 return
Al metodo sono passati i seguenti parametri:
35
• l’oggetto Message contenente l’allegato;
• il percorso (locale) in cui è stato memorizzato;
• l’identificatore del file.
Se quest’ultimo campo non è vuoto significa che l’identificatore è già stato memorizzato e che non
ha senso continuare (righe 3 e 4). Nel caso contrario, si prova a memorizzarlo, in base al formato del
documento (righe 7 → 17). Se non si riscontrano errori l’identificatore viene quindi inserito nel di-
zionario file_id_cache_dict (righe 21 e 22), dal quale sarà in seguito ricavabile attraverso il
nome del percorso in cui il documento è stato memorizzato.
Analisi del modulo src.telegram_bot.ormlayer
Il modulo ormlayer permette un’interfaccia tra il bot Telegram e Django, gestore della base di dati
in PostgreSQL. In esso sono definiti tutti quei metodi che interrogano la base di dati, oppure che in-
seriscono in essa nuovi record. Essi non saranno riportanti in toto, sia per una questione di leggibilità
del documento che per il fatto che molti sono di banale comprensione. Saranno piuttosto analizzati
alcuni accorgimenti rilevanti, primo tra tutti l’implementazione di un meccanismo di caching.
A tal riguardo è stato scelto l’utilizzo di un sistema messo a disposizione direttamente da Django at-
traverso la classe django.core.cache. Esso permette di inserire in un dizionario un qualsiasi ogget-
to Python per un determinato numero di secondi[41]
. La struttura standard è la seguente:
1 from django.core.cache import cache
2 cache.set(key=key, value=value, timeout=timeout)
Alla riga 2, key indica la chiave per recuperare l’oggetto, value la variabile da immagazzinare e ti-
meout il numero di secondi per cui deve essere mantenuta in cache. Nel progetto in esame il mecca-
nismo di caching è stato usato per memorizzare gli oggetti TelegramUser, NewsItem e SystemPara-
meter.
Analisi dei tempi di esecuzione con e senza cache
Attraverso la variabile use_chache e il decoratore benchmark_decorator (definito nel modulo
log_utils), che conta, con una precisione di un nanosecondo, il tempo necessario all’esecuzione del
metodo che decora, è possibile fare dei ragionamenti sul risparmio effettivo con e senza cache. Si
analizzerà in particolare il tempo di esecuzione del metodo orm_get_telegram_user.
Per ricavare i dati necessari sono state scritte le seguenti righe di codice.
1 for i in range(100):
2 orm_get_telegram_user(telegram_user_id)
3
4 for i in range(100):
5 orm_get_telegram_user(telegram_user_id)
6 sleep(0.05)
7
8 for i in range(100):
9 orm_get_telegram_user(telegram_user_id)
10 sleep(0.10)
Nel primo ciclo (righe 1 e 2) il metodo orm_get_telegram_user in esame viene chiamato cento
volte senza interruzioni, nel secondo (righe 4 → 6) con 50 millisecondi di ritardo tra una chiamata e
l’altra e nel terzo (righe 8 → 10) con 100 millisecondi di ritardo (in totale sono trecento iterazioni).
36
Il codice è stato eseguito due volte, la prima impostando use_cache = True e la seconda con
use_cache = False. I dati prodotti, inseriti in Appendice, sono stati organizzati in tre grafici ditin-
ti, rappresentati rispettivamente in Figura 36, in Figura 37 e in Figura 38.
1 7 13 19 25 31 37 43 49 55 61 67 73 79 85 91 97
0
500000
1000000
1500000
2000000
2500000
con cache
senza cache
ns
Figura 36: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni nullo.
1 7 13 19 25 31 37 43 49 55 61 67 73 79 85 91 97
0
500000
1000000
1500000
2000000
2500000
3000000
con cache
senza cache
ns
Figura 37: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni pari a 50 ms.
1 7 13 19 25 31 37 43 49 55 61 67 73 79 85 91 97
0
500000
1000000
1500000
2000000
2500000
con cache
senza cache
ns
Figura 38: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni pari a 100 ms.
Alcune osservazioni:
• sull’asse delle ascisse è riportato il numero dell’iterazione;
• sull’asse delle ordinate il tempo di esecuzione, espresso in nanosecondi.
37
Per entrambi i casi si nota un tempo di esecuzione mediamente più basso durante il primo ciclo (circa
60 microsecondi con la cache e circa 1000 microsecondi senza). Inserendo il ritardo, invece, indiffe-
rentemente dalla sua portata, i valori si assestano a circa 210 microsecondi nel primo caso e a circa
1860 microsecondi nel secondo, per un guadagno complessivo che si stima dell’880% (quasi un ordi-
ne di grandezza).
Si osservi come sia presente un’evidente fluttuazione del tempo di esecuzione, nonostante le buone
condizioni predisposte per la misurazione. Questo fenomeno può essere imputato al linguaggio di
programmazione utilizzato, ossia Python, che non viene eseguito direttamente sul Kernel ma su una
macchina virtuale.
Dati simili possono essere ricavati anche dall’analisi di metodi diversi da orm_get_telegram_user.
Ora, è evidente come tale risultato non sia assoluto, in quando le condizioni di test non equivalgono
esattamente a quelle di utilizzo; tuttavia si tratta comunque di una considerazione interessante.
I dati presentati sono stati raccolti da un calcolatore con sistema operativo Ubuntu nella versione
18.04, CPU Intel® Core™ i5-2430M a 2.40GHz per quattro core e 3.8GiB di memoria RAM.
Analisi del modulo src.telegram_bot.log_utils
In questo modulo sono definiti gli strumenti utilizzati per l’attività di logging, ossia la registrazione
sequenziale delle operazioni di interesse effettuate dal sistema. Python, a supporto di tale attività,
mette a disposizione nella libreria di base il modulo logging[42]
: esso definisce classi e funzioni che
implementano un sistema di logging flessibile per applicazioni e librerie.
Al fine di documentare gli eventi, è necessario instanziare uno o più oggetti di tipo Logger attraverso
la funzione logging.getLogger. Nel progetto ne sono stati istanziati cinque, sulla base al modulo/
contesto di utilizzo. Il passo successivo consiste nell’impostarne il livello: nella Tabella 5 sono indi-
cati quelli disponibili, in crescente ordine di rigore. Specificando un determinato livello, si impone
che siano tracciati gli eventi appartenenti a quel livello e ai livelli superiori.
Nome Descrizione
DEBUG Fornisce informazioni dettagliate sul funzionamento del programma, tipicamente di in-
teresse nelle fasi diagnostiche.
INFO Attesta che l’esecuzione del codice non ha riscontrato problemi.
WARNING Indica l’avvenimento (o una previsione) di qualcosa di inaspettato che per ora non ha
prodotto malfunzionamenti.
ERROR Documenta la presenza di un problema più importante, a causa del quale il software non
è riuscito ad eseguire alcune funzionalità.
CRITICAL Registra l’avvenimento di un errore importante, che ha portato all’interruzione dell’ese-
cuzione del programma.
Tabella 5: Livelli di rigore degli eventi.
Usando la funzione logging.basicConfig, inoltre, è possibile modificare le opzioni predefinite del
modulo:
1 logging.basicConfig(
2 format='[%(asctime)s] %(name)s - %(levelname)s - %(message)s',
3 level=logging.INFO
4 )
38
Il campo format specifica che informazioni dovranno essere inserite nei messaggi e in quale forma-
to; il campo level specifica il livello del logger di root (ossia l’oggetto Logger dal quale sono gene-
rati tutti gli altri), che sarebbe altrimenti impostato su WARNING.
Nel modulo log_utils sono poi definiti alcuni metodi, dei quali sarà analizzato solo il precedente-
mente citato benchmark_decorator.
Ne viene riportato per chiarezza il codice.
1 def benchmark_decorator(func):
2 @wraps(func)
3 def wrapped(*args, **kwargs):
4
5 import time
6 a = time.time_ns()
7
8 try:
9 return func(*args, **kwargs)
10 finally:
11 b = time.time_ns()
12 c = b – a
13
14 benchmark_logger.debug(f"{func.__name__} dt={c / 1000} microseconds")
15 return wrapped
Esso, in qualità di decoratore, riceve come parametro (func) il metodo decorato. Senza addentrarsi
nello specifico della funzione @wraps alla riga 2, si osserva come venga registrato il momento in cui
il metodo func inizia (riga 6) e quello in cui termina (riga 11). Infine, nel caso non si siano presenta-
te delle eccezioni, viene stampata, con un logger opportuno, la durata complessiva dell’esecuzione
del metodo (riga 14).
Analisi del modulo src.telegram_bot.django_settings
Questo modulo è necessario per l’integrazione del bot Telegram con l’applicazione creata in Django.
Nel momento in cui viene avviato il modulo src.telegram_bot.regionefvg_bot, il modulo
src.telegram_bot.__init__ impone l’esecuzione delle seguenti righe di codice.
1 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_settings")
2 django.setup()
La riga 1 indica la posizione del modulo che specifica le impostazioni di Django; la riga 2 ne avvia la
configurazione, basandosi sul modulo indicato.
In tale modulo, ossia src.telegram_bot.django_settings sono riportate alcune delle imposta-
zioni definite in src.gfvgbo.settings. Quelle non riportate riguardano funzionalità che non sono
a questo livello supportate.
Perché tale integrazioni funzioni è inoltre necessario inserire in ogni modello di src.backoffice.-
models la classe Meta con l’attributo app_label posto uguale a “backoffice”. In questo modo è
possibile importare e sfruttare i modelli dell’applicazione web backoffice anche dal bot Telegram.
39
40
Capitolo 4
Conclusioni
In questo capitolo finale sarà commentato il grado di raggiungimento degli obiettivi specificati nei
capitoli precedenti, sottolineando le funzionalità ancora da sviluppare. Si parlerà poi dello stato at-
tuale del lavoro, e infine si darà spazio alle considerazioni soggettive dell’autore sul sistema creato e
sul percorso seguito per realizzarlo.
4.1 Raggiungimento degli obiettivi
Gli obiettivi posti, in particolare i requisiti espressi nel Capitolo 2, sono stati soddisfatti solo in parte.
Il bot Telegram
Il bot Telegram è attualmente in grado di notificare, anche se non in tempo reale (il ritardo è media-
mente di 30 secondi), la pubblicazione degli articoli nel portale LavoroFVG, secondo le modalità
specificate. Tuttavia non sono ancora state implementate le seguenti funzionalità:
• il bot non può determinare automaticamente le categorie degli articoli (questi dati devono es-
sere inseriti manualmente attraverso l’applicazione web);
• non è disponibile il meccanismo di profilazione, che permette la suddivisione degli utenti in
categorie, anche se c’è la possibilità di ottenere le informazioni atte allo scopo;
• l’utente non può accedere al servizio dal portale (tale operazione necessita una modifica del
sito, operazione esterna al progetto).
Nonostante queste osservazioni possano far dubitare dei risultato del progetto, è bene ricordare che è
stato realizzato un meccanismo avanzato per l’invio degli articoli, sui quali si può già esprimere feed-
back e commenti, e che l’utente ha la possibilità di scegliere le categorie di articoli da ricevere.
L’applicazione web
Come controparte, l’applicazione web realizzata soddisfa tutti i requisiti che la competono: attraverso
l’interfaccia proposta da Django, è stato possibile creare un sistema completo e adatto alle funzionali-
tà amministrative richieste, dalla supervisione degli utenti collegati alla possibilità di inviare articoli
personalizzati e messaggi di servizio.
41
Si osservi comunque che le funzionalità lasciate in sospeso non saranno abbandonate: il servizio è
ancora in fase di crescita e sarà, in sviluppi futuri, certamente soggetto a miglioramenti.
Il lavoro di tesi
In questo paragrafo sarà messo in luce il grado di raggiungimento degli obiettivi legati al lavoro di
tesi, piuttosto che al progetto in generale.
Per quanto riguarda il primo obiettivo, e quindi la collaborazione con Marco Tessarotto per lo svilup-
po del software, si può dire che sia stato soddisfatto. Il contributo dell’autore ha portato alla realizza-
zione dei seguenti elementi:
• l’interfaccia utente per la notifica degli articoli;
• i meccanismi per l’espressione dei feedback e dei commenti sugli articoli, sia dal punto di vi-
sta del bot Telegram che da quello dell’applicazione web;
• la conversazione iniziale per la raccolta dei dati sull’utente e per l’accettazione delle condi-
zioni d’utilizzo del servizio;
• il primo meccanismo di scelta delle categorie di interesse, quello che risponde all’invio del
comando /scegli;
• la personalizzazione dell’interfaccia utente dell’applicazione web, almeno per quanto riguar-
da i modelli fondamentali.
Per informazioni più accurate, in termini di codice scritto o modificato, si rimanda alla consultazione
del primo paragrafo del Capitolo 3.
Per quanto riguarda il secondo obiettivo della tesi, la documentazione del progetto, il giudizio sul
grado di raggiungimento spetta al lettore. Si ricordi solo come sia stato descritto ogni aspetto fino ad
ora implementato, ad eccezione del parser RSS.
4.2 Stato attuale del lavoro
Il sistema è in questo momento funzionante, anche se, come già è stato detto, in uno stato non defini-
tivo. Il codice che è stato prodotto è in esecuzione su un server Linux della Regione Friuli Venezia
Giulia, con le modalità e gli strumenti software descritti nel Capitolo 2 e nel Capitolo 3.
A riprova di questa affermazione si consiglia al lettore di collegarsi al bot, come indicato nel Capitolo
1, e di metterne alla prova il funzionamento. A tal proposito si ricorda che, essendo il progetto in sta-
dio di sviluppo, potrebbero essere presenti delle funzionalità nuove, non descritte in questo documen-
to, oppure leggermente diverse da quelle presentate.
4.3 Conclusioni soggettive
Il lavoro svolto ha dato l’opportunità all’autore di ampliare la preparazione offerta dal corso di studi.
È stata acquisita esperienza nell’utilizzo di strumenti software attuali e di ampia diffusione, come il
linguaggio di programmazione Python, non affrontato nei corsi, il framework per applicazioni web
Django, e l’RDBMS PostgreSQL. Certamente utile, in vista di futuri impegni lavorativi, è stato poi
l’utilizzo della piattaforma per lo sviluppo condiviso GitHub.
42
Per quanto riguarda il progetto nella sua totalità, si reputa molto formativo il fatto di aver seguito per
intero il processo che ne ha portato alla realizzazione, e quindi di aver toccato con mano le problema-
tiche legate a ciascuna fase.
Alcune parole vanno infine spese sul fine del servizio realizzato, al di là dei tecnicismi legati
all’informatica. Esso presenta un’evidente utilità sociale, in quanto aiuta gli utenti a rimanere aggior-
nati riguardo le proposte di lavoro e di formazione. Ciò testimonia come la tecnologia possa avere un
peso anche in ambiti più strettamente umanistici. È stato interessante aver toccato con mano l’impe-
gno delle istituzioni, e in particolare della regione Friuli Venezia Giulia, nel fornire servizi ai residen-
ti.
43
44
Appendice
A seguire i dati ricavati, in ns, per l’analisi delle prestazioni del metodo orm_get_telegram_user.
#
Senza l’utilizzo della cache Con l’utilizzo della cache
Δt = 0 ms Δt = 50 ms Δt = 100 ms Δt = 0 ms Δt = 50 ms Δt = 100 ms
1 1433727 1110159 1696371 122681 40767 144883
2 1743860 1911706 2225748 101120 203543 201389
3 1549094 1766323 1746225 82185 246895 202922
4 1637040 1799094 1734373 66976 211268 191901
5 1289336 2457484 1741115 64371 206999 203353
6 1261202 1761574 1877352 71564 235433 207480
7 1285138 1733231 1765150 63249 204124 214042
8 1303092 1983602 1916476 77796 208993 202471
9 1309083 1764830 1859277 71515 248628 229642
10 1104038 1752327 1983702 62317 264468 248437
11 1286831 2160765 1703094 62116 260440 205266
12 2023277 1846724 1930191 60834 197050 218642
13 1526221 1739753 1768648 60955 202752 205978
14 1185911 1766183 1811949 60925 209595 245001
15 1049223 1940400 2040579 68298 203363 199325
16 1140335 1781341 1757667 61005 202872 239340
17 895555 1697494 1777144 62147 199636 207771
18 819932 1759871 1845863 112622 215045 201680
19 1039816 1786831 1736167 91593 228951 210055
20 1174279 1734052 1911225 103565 195808 202451
21 1051268 1816367 1721739 78147 244901 227508
22 1203995 2043704 1904573 93326 251434 205566
23 898340 1964185 2007096 92474 204645 224352
24 803020 1905966 1998600 69641 221076 265770
25 966488 1826877 1947775 65454 197682 204495
26 1409352 1843438 1869166 64211 205276 239972
27 1001564 1700640 1757866 64060 254239 201980
28 924689 2259661 2028155 64481 211267 202551
29 952622 1793054 1891959 64802 200237 203263
30 1163118 1758027 1998610 73088 254679 200628
31 917977 1779908 1779958 65353 246574 247085
32 899442 2062641 1936804 65072 202972 204756
33 895445 1800748 1673067 65854 202541 203302
34 1072448 1850722 1713152 65103 213391 201409
35 1035017 1887401 1748590 64842 205065 248748
36 1013798 1811969 2048644 65373 249740 245933
37 1182224 1718162 1732520 66395 205307 203963
38 1188977 1812811 1752106 72746 154140 203333
39 1202602 1719955 1952373 65563 244470 203543
40 1726708 2081626 1855019 68408 206218 201359
41 1077016 2000884 1680312 65002 203383 201028
42 902638 1783495 1832888 65182 275158 202541
43 1041699 1733692 1818711 69150 192192 203062
44 1087987 2076477 1825184 102352 189246 203062
45 1058251 1728683 1814454 69991 204235 256703
46 1115238 1876100 1835372 65393 197111 228479
47 1169420 1748349 1895086 70042 198995 254228
48 1184248 1953906 1879936 66946 195167 201078
49 1386990 1715377 1670242 66125 230173 202821
50 1117072 1736236 2039237 74941 204505 219924
51 1170302 2151347 1700098 66645 196179 200377
52 1622693 1838769 1743239 65564 243709 201620
45
Sviluppo di un bot Telegram per la diffusione di articoli informativi
Sviluppo di un bot Telegram per la diffusione di articoli informativi
Sviluppo di un bot Telegram per la diffusione di articoli informativi

More Related Content

Similar to Sviluppo di un bot Telegram per la diffusione di articoli informativi

Evoluzione di un’applicazione mobile cross platform per il supporto domotico ...
Evoluzione di un’applicazione mobile cross platform per il supporto domotico ...Evoluzione di un’applicazione mobile cross platform per il supporto domotico ...
Evoluzione di un’applicazione mobile cross platform per il supporto domotico ...freedomotic
 
Tesi di Laurea in Informatica di Tassone Alfonso
Tesi di Laurea in Informatica di Tassone AlfonsoTesi di Laurea in Informatica di Tassone Alfonso
Tesi di Laurea in Informatica di Tassone AlfonsoAlfonso Tassone
 
Open Innovation in Trentino?Un'analisi preliminare
Open Innovation in Trentino?Un'analisi preliminareOpen Innovation in Trentino?Un'analisi preliminare
Open Innovation in Trentino?Un'analisi preliminareAlessandro Trentin
 
2020 report blockchain19
2020 report blockchain192020 report blockchain19
2020 report blockchain19Daniel Rueda H
 
Copia di importante apprendimento
Copia di importante apprendimentoCopia di importante apprendimento
Copia di importante apprendimentoiva martini
 
Copia di importante apprendimento
Copia di importante apprendimentoCopia di importante apprendimento
Copia di importante apprendimentoiva martini
 
Comunicazione in un progetto di educativa di strada con strumenti web 2.0
Comunicazione in un progetto di educativa di strada con strumenti web 2.0Comunicazione in un progetto di educativa di strada con strumenti web 2.0
Comunicazione in un progetto di educativa di strada con strumenti web 2.0Nicole Colombo
 
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...Davide Ciambelli
 
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...maik_o
 
Dispensa Interazione Uomo Macchina
Dispensa Interazione Uomo MacchinaDispensa Interazione Uomo Macchina
Dispensa Interazione Uomo MacchinaStefano Bussolon
 
La stop motion come risorsa
La stop motion come risorsaLa stop motion come risorsa
La stop motion come risorsaTania Bozhova
 
MARKETING ED ECOMMERCE NELL’EDITORIA: IL CASO TRADING LIBRARY
MARKETING ED ECOMMERCE NELL’EDITORIA: IL CASO TRADING LIBRARYMARKETING ED ECOMMERCE NELL’EDITORIA: IL CASO TRADING LIBRARY
MARKETING ED ECOMMERCE NELL’EDITORIA: IL CASO TRADING LIBRARYvantasso
 
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Raffaele Bernardi
 
Relazione laboratorio knowledge management
Relazione laboratorio knowledge managementRelazione laboratorio knowledge management
Relazione laboratorio knowledge managementAndrea Casagrande
 

Similar to Sviluppo di un bot Telegram per la diffusione di articoli informativi (20)

Evoluzione di un’applicazione mobile cross platform per il supporto domotico ...
Evoluzione di un’applicazione mobile cross platform per il supporto domotico ...Evoluzione di un’applicazione mobile cross platform per il supporto domotico ...
Evoluzione di un’applicazione mobile cross platform per il supporto domotico ...
 
Tesi di Laurea in Informatica di Tassone Alfonso
Tesi di Laurea in Informatica di Tassone AlfonsoTesi di Laurea in Informatica di Tassone Alfonso
Tesi di Laurea in Informatica di Tassone Alfonso
 
T2826552.PDF
T2826552.PDFT2826552.PDF
T2826552.PDF
 
Comunicazione in un progetto di educativa di strada con strumenti Web 2.0
Comunicazione in un progetto di educativa di strada con strumenti Web 2.0Comunicazione in un progetto di educativa di strada con strumenti Web 2.0
Comunicazione in un progetto di educativa di strada con strumenti Web 2.0
 
Open Innovation in Trentino?Un'analisi preliminare
Open Innovation in Trentino?Un'analisi preliminareOpen Innovation in Trentino?Un'analisi preliminare
Open Innovation in Trentino?Un'analisi preliminare
 
2020 report blockchain19
2020 report blockchain192020 report blockchain19
2020 report blockchain19
 
2017 04 ortelli
2017 04 ortelli2017 04 ortelli
2017 04 ortelli
 
Copia di importante apprendimento
Copia di importante apprendimentoCopia di importante apprendimento
Copia di importante apprendimento
 
Copia di importante apprendimento
Copia di importante apprendimentoCopia di importante apprendimento
Copia di importante apprendimento
 
Comunicazione in un progetto di educativa di strada con strumenti web 2.0
Comunicazione in un progetto di educativa di strada con strumenti web 2.0Comunicazione in un progetto di educativa di strada con strumenti web 2.0
Comunicazione in un progetto di educativa di strada con strumenti web 2.0
 
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
Tesi Specialistica - L'ottimizzazione delle risorse della Grid di EGEE median...
 
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
Progetto e sviluppo di un'applicazionemobile multipiattaforma per il supporto...
 
Dispensa Interazione Uomo Macchina
Dispensa Interazione Uomo MacchinaDispensa Interazione Uomo Macchina
Dispensa Interazione Uomo Macchina
 
La stop motion come risorsa
La stop motion come risorsaLa stop motion come risorsa
La stop motion come risorsa
 
Peroli_Tesi_v3.5
Peroli_Tesi_v3.5Peroli_Tesi_v3.5
Peroli_Tesi_v3.5
 
EBEC_Trento2015
EBEC_Trento2015EBEC_Trento2015
EBEC_Trento2015
 
MARKETING ED ECOMMERCE NELL’EDITORIA: IL CASO TRADING LIBRARY
MARKETING ED ECOMMERCE NELL’EDITORIA: IL CASO TRADING LIBRARYMARKETING ED ECOMMERCE NELL’EDITORIA: IL CASO TRADING LIBRARY
MARKETING ED ECOMMERCE NELL’EDITORIA: IL CASO TRADING LIBRARY
 
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
Sviluppo e realizzazione di un sistema per la manipolazione di superfici trid...
 
Relazione laboratorio knowledge management
Relazione laboratorio knowledge managementRelazione laboratorio knowledge management
Relazione laboratorio knowledge management
 
Project Management
Project Management Project Management
Project Management
 

Sviluppo di un bot Telegram per la diffusione di articoli informativi

  • 1. UNIVERSITÀ DEGLI STUDI DI TRIESTE Dipartimento di Ingegneria e Architettura Corso di Studi in Ingegneria Elettronica e Informatica Sviluppo di un bot Telegram per la diffusione di articoli informativi Tesi di Laurea Triennale Laureando: Matteo MERZ Relatore: prof. Marco TESSAROTTO _____________________________________ ANNO ACCADEMICO 2018-2019
  • 2.
  • 3. Ringraziamenti Desidero ringraziare con affetto la mia famiglia, sempre vicina e pronta ad aiutarmi nei momenti di difficoltà. Il suo aiuto è stato determinante per raggiungere questo traguardo. Sono grato a tutti gli amici, che mi hanno accompagnato durante questo percorso e con cui ho con- diviso gioie e affanni. Un pensiero speciale va poi a Giovanna, la via di fuga per tutti i cattivi pen- sieri, che con il suo affetto mi ha supportato in questi anni. Un ringraziamento infine a Trieste, per avermi accolto. Con la sua bellezza mi ha spesso riempito gli occhi e liberato la mente. Matteo Merz iii
  • 4. iv
  • 5. Indice Capitolo 1 Introduzione........................................................................................................................1 1.1 Presentazione del progetto.........................................................................................................1 Il servizio Telegram e i chat bot.............................................................................................1 Risultati.................................................................................................................................2 Motivazioni e finalità del progetto........................................................................................2 Motivazioni e finalità del lavoro di tesi.................................................................................2 1.2 Metodo di lavoro.......................................................................................................................3 1.3 Riassunto dei capitoli successivi................................................................................................3 Capitolo 2 Analisi e progettazione........................................................................................................5 2.1 Analisi.......................................................................................................................................5 2.1.1 Analisi dei requisiti............................................................................................................5 Interfaccia utente...................................................................................................................5 Accettazione delle condizioni d’utilizzo del servizio............................................................7 Altri requisiti funzionali........................................................................................................8 Software................................................................................................................................8 Carico applicativo.................................................................................................................8 2.1.2 Elenco completo dei requisiti............................................................................................8 2.2 Progettazione...........................................................................................................................10 2.2.1 Progettazione dell’applicazione web...............................................................................10 Django.................................................................................................................................10 Gunicorn..............................................................................................................................11 Nginx...................................................................................................................................11 PostgreSQL.........................................................................................................................11 2.2.2 Progettazione del bot Telegram........................................................................................12 Lettura automatica degli articoli..........................................................................................12 2.2.3 Progettazione del parser RSS...........................................................................................12 2.2.4 Architettura complessiva.................................................................................................13 Capitolo 3 Realizzazione....................................................................................................................15 3.1 Modalità di lavoro...................................................................................................................15 Meriti...................................................................................................................................16 3.2 Applicazione web....................................................................................................................17 3.2.1 Architettura......................................................................................................................17 3.2.2 Progetto Django...............................................................................................................18 Analisi del modulo src.gfvgbo.secrets.................................................................................18 Analisi del modulo src.gfvgbo.settings................................................................................18 Analisi del modulo src.backoffice.models...........................................................................19 Analisi del modulo src.backoffice.admin............................................................................22 3.3 Bot Telegram...........................................................................................................................24 3.3.1 Architettura......................................................................................................................24 3.3.2 Interfaccia utente.............................................................................................................24 Il comando /start.................................................................................................................24 Il comando /scegli...............................................................................................................26 v
  • 6. Il comando /categorie..........................................................................................................27 L’invio degli articoli............................................................................................................28 Il comando /rimanda_ultime_news......................................................................................29 Il comando /statistiche.........................................................................................................30 Il comando /help..................................................................................................................30 3.3.3 Codice.............................................................................................................................31 Analisi del modulo src.telegram_bot.regionefvg_bot..........................................................31 Elenco degli handler............................................................................................................32 Analisi del modulo src.telegram_bot.news_processing.......................................................34 Analisi del modulo src.telegram_bot.ormlayer....................................................................36 Analisi dei tempi di esecuzione con e senza cache..............................................................36 Analisi del modulo src.telegram_bot.log_utils....................................................................38 Analisi del modulo src.telegram_bot.django_settings.........................................................39 Capitolo 4 Conclusioni.......................................................................................................................41 4.1 Raggiungimento degli obiettivi...............................................................................................41 Il bot Telegram....................................................................................................................41 L’applicazione web..............................................................................................................41 Il lavoro di tesi....................................................................................................................42 4.2 Stato attuale del lavoro............................................................................................................42 4.3 Conclusioni soggettive............................................................................................................42 Appendice A.......................................................................................................................................45 Bibliografia.........................................................................................................................................47 vi
  • 7. Indice delle Figure Figura 1: Logo di Telegram.................................................................................................................1 Figura 2: Ricerca del bot dall'applicazione Telegram..........................................................................2 Figura 3: Modello di notifica................................................................................................................6 Figura 4: Metodo di accettazione dell'informativa sul trattamento dei dati personali..........................7 Figura 5: Rapporto del 18 ottobre 2019 sul traffico del dominio offertelavoro.regione.fvg.it.............8 Figura 6: Logo di Django..................................................................................................................10 Figura 7: Logo di Gunicorn...............................................................................................................11 Figura 8: Logo di Nginx....................................................................................................................11 Figura 9: Logo di PostgreSQL...........................................................................................................11 Figura 10: Logo di python-telegram-bot............................................................................................12 Figura 11: Logo tipico per i flussi web...............................................................................................12 Figura 12: Struttura complessiva del sistema......................................................................................13 Figura 13: Logo di GitHub................................................................................................................15 Figura 14: Analisi del lavoro svolto...................................................................................................16 Figura 15: Architettura dell'applicazione web.....................................................................................17 Figura 16: Struttura............................................................................................................................18 Figura 17: Schema UML delle classi..................................................................................................21 Figura 18: Elenco dei modelli inseriti nella pagina amministrativa di backoffice..............................22 Figura 19: Pagina di backoffice dedicata al modello NewsItem.........................................................22 Figura 20: Architettura del bot Telegram............................................................................................24 Figura 21: Invio dell'informativa sul trattamento dei dati personali...................................................25 Figura 22: Il bot è bloccato................................................................................................................25 Figura 23: Inserimento del titolo di studio più elevato.......................................................................26 Figura 24: Scelta delle categorie di interesse.....................................................................................26 Figura 25: Riassunto delle categorie scelte........................................................................................27 Figura 26: Elenco dei comandi relativi alle categorie........................................................................27 Figura 27: Proposta di smettere di seguire la categoria specificata....................................................27 Figura 28: Proposta di iniziare a seguire la categoria specificata.......................................................28 Figura 29: Notifica della pubblicazione di un nuovo articolo............................................................28 Figura 30: Interfaccia per l'inserimento dei commenti, Pt. 1..............................................................29 Figura 31: Interfaccia per l'inserimento dei commenti, Pt. 2..............................................................29 Figura 32: Riassunto degli articoli inviati negli ultimi dieci giorni....................................................29 Figura 33: Lettura del titolo dell'articolo selezionato.........................................................................30 Figura 34: Statistiche sugli articoli inviati negli ultimi dieci giorni...................................................30 Figura 35: Messaggio esplicativo del funzionamento del bot............................................................30 Figura 36: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni nullo.........................37 Figura 37: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni pari a 50 ms..............37 Figura 38: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni pari a 100 ms............37 vii
  • 8. Indice delle Tabelle Tabella 1: Elenco dei requisiti..............................................................................................................9 Tabella 2: Elenco dei modelli.............................................................................................................20 Tabella 3: Limiti di spam....................................................................................................................31 Tabella 4: Elenco degli handler...........................................................................................................34 Tabella 5: Livelli di rigore degli eventi...............................................................................................38 Tabella 6: Dati completi sull'analisi dell'utilizzo della cache..............................................................46 Tabella 7: Medie dei dati ricavati sull’analisi dell’utilizzo della cache...............................................46 viii
  • 9. Capitolo 1 Introduzione In questo capitolo iniziale viene introdotto il progetto in esame. Alcune parole sono dedicate alla presentazione di Telegram e dei chat bot, altre all’ambiente in cui è stato svolto e agli obiettivi da raggiungere. Infine è stato inserito un breve riassunto dei capitoli successivi. 1.1 Presentazione del progetto In questo documento sarà descritto il percorso di realizzazione di un bot Telegram per la diffusione di articoli informativi. Tale progetto rientra nei servizi offerti dalla Regione Friuli Venezia Giulia - Dire- zione centrale lavoro, formazione, istruzione e famiglia, ed è stato avviato da Marco Tessarotto, rela- tore di questa tesi. L’autore non ha realizzato la totalità del software che sarà presentato ma ne ha contribuito allo sviluppo, inserendosi in una sua fase embrionale. Prima di addentrarsi nella descrizione del lavoro svolto, saranno introdotti i chat bot di Telegram. Il servizio Telegram e i chat bot Telegram è un servizio di messaggistica istantanea basato sul cloud ed erogato gratuitamente. Esso è accessibile da mobile, desktop e web, attraverso applicazioni a codice sorgente libero[1] . Figura 1: Logo di Telegram. Fornisce diverse funzionalità, tra cui l’invio di messaggi con crittografia punto-punto e la possibilità di creare dei chat bot. Ci si soffermerà evidentemente su quest’ultimo servizio. Un chat bot è un software progettato per simulare una conversazione con un essere umano. Nel caso di in esame si parla semplicemente di bot: un bot è un’applicazione di terze parti eseguita all’interno di Telegram. Esso non è che un normale profilo, con la peculiarità di poter essere attivato anche senza un numero di telefono. Gli utenti possono interagire con un bot in due modi: • inviando comandi e messaggi in una conversazione privata con esso (il caso in esame), oppure aggiungendolo ad un gruppo; 1
  • 10. • inviando richieste da qualsiasi conversazione, gruppo o canale, tramite lo @username del bot seguito da un’interrogazione. Per ulteriori informazioni si rimanda alla documentazione ufficiale[2] . Risultati Il risultato del progetto è il bot Telegram LavoroFVG. Il lettore può provarne personalmente le fun- zionalità installando l’applicazione Telegram e seguendo l’indirizzo https://telegram.me/DCLavoroFVG_bot, oppure digitando il nome del servizio direttamente dall’applicazione nella barra di ricerca globale, come mostrato in Figura 1. Figura 2: Ricerca del bot dall'applicazione Telegram. Motivazioni e finalità del progetto Prima di chiarire motivazioni e finalità del progetto, è necessario descrivere con maggiore precisione il contesto in cui esso si colloca. Il portale LavoroFVG[3] è un servizio messo a disposizione dalla Regione Friuli Venezia Giulia per la diffusione delle offerte di lavoro e di formazione pubblicate dai Centri per l’Impiego (CPI) e da Eure- sFVG. La sua missione è diventare il punto di riferimento per i residenti nella regione in cerca di la- voro. In seguito si farà spesso riferimento a questo servizio con la semplice dicitura portale. Attualmente esso è fruibile da un’applicazione mobile e dal sito web: il progetto in esame nasce dalla necessità di un canale di comunicazione alternativo. Il servizio deve perseguire come obiettivo prin- cipe la semplicità di installazione e di utilizzo, così da ottenere la massima diffusione possibile. Motivazioni e finalità del lavoro di tesi Nel paragrafo precedente si è parlato del progetto nella sua totalità. Scendendo nel particolare di que- sto lavoro di tesi, gli obiettivi sono fondamentalmente due: • contribuire allo sviluppo del software; • redigere la documentazione del progetto. Quest’ultimo obiettivo è stato realizzato attraverso la scrittura del documento in esame. Per quanto riguarda la motivazione, è sufficiente dire che la proposta di collaborazione è nata dal re- latore e che l’autore l’ha accettata di buon grado per motivi di interesse personale. 2
  • 11. 1.2 Metodo di lavoro Lo svolgimento del lavoro, dopo una fase preliminare di studio individuale del linguaggio di pro- grammazione Python e delle Bot API di Telegram[4] , è stato caratterizzato da una ripetizione ciclica delle seguenti fasi: 1. raccolta e analisi dei requisiti; 2. progettazione e scelta degli strumenti software da utilizzare nello sviluppo; 3. raccolta di informazioni su come utilizzare tali strumenti; 4. scrittura del codice. L’ultima fase è stata accompagnata da momenti di test sul funzionamento complessivo e da riflessio- ni sulle prestazioni del codice. 1.3 Riassunto dei capitoli successivi Saranno dedicate alcune righe ad ogni capitolo. Nel Capitolo 2 si parlerà delle fasi di analisi e di progettazione. Si è deciso di raggruppare in esso tut- ti i requisiti raccolti e tutte le relative specifiche. Nel Capitolo 3 sarà invece dato spazio alla realizzazione, con descrizioni dettagliate del funziona- mento dei servizi creati, sia dal punto di vista dell’interfaccia utente che da quello del codice. Infine, il Capitolo 4 conterrà le osservazioni conclusive sul lavoro svolto, indicando la situazione at- tuale confrontata con le aspettative e i possibili sviluppi futuri. 3
  • 12. 4
  • 13. Capitolo 2 Analisi e progettazione In questo capitolo sarà descritta la prima parte del percorso di lavoro, ovvero quella di analisi e di progettazione. Lo scopo è quello di fornire un elenco chiaro dei requisiti di progetto, di modo che si possano definire gli strumenti da utilizzare e le linee guida della realizzazione. 2.1 Analisi La fase di analisi è stata preceduta da alcune riunioni con il personale della Regione Autonoma Friuli Venezia Giulia, Direzione centrale lavoro, formazione, istruzione e famiglia. Essendo il committente interno, tali colloqui non si sono basati esclusivamente sulla raccolta dei requisti ma sono stati inter- vallati da momenti di riflessione comune su quale potesse essere, visto l’obiettivo, la soluzione mi- gliore. Scendendo nel particolare, i principali soggetti intervistati sono stati: • la curatrice del portale LavoroFVG, che ha parlato delle modalità di inserimento e di pubbli- cazione degli articoli; • il tecnico informatico del portale, che ne ha descritto le principali caratteristiche e con cui si è discussa la fattibilità delle soluzioni ideate. Le informazioni emerse dalle riunioni sono state successivamente riassunte e riorganizzate. Il risulta- to di tale processo è inserito nei prossimi paragrafi. 2.1.1 Analisi dei requisiti I requisiti raccolti spaziano su vari ambiti, dall’interfaccia utente all’hardware. Per questo motivo, e al fine di ottimizzare la comprensione del documento, si è ritenuto opportuno dividere la trattazione in più sezioni, ognuna dedicata ad uno di essi. Interfaccia utente Il meccanismo di divulgazione deve avvenire attraverso una conversazione privata con l’utente sul servizio di messaggistica Telegram. Si desidera che tale conversazione possa essere avviata non solo dall’interno del servizio (digitando sul campo di ricerca il nome del bot e poi selezionandolo), ma an- che attraverso un collegamento da inserire nel portale LavoroFVG. 5
  • 14. Una volta effettuato con successo l’accesso al servizio, si desidera che all’utente venga notificata in tempo reale la pubblicazione dei nuovi articoli (il bot Telegram deve essere dunque attivo in modo continuativo). In particolare, per ognuno di essi si è interessati a notificare: titolo, un breve estratto del contenuto, il collegamento alla pagina del portale contenente l’articolo completo e un’immagine. Le informazioni elencate devono essere disposte come illustrato in Figura 3. Figura 3: Modello di notifica. L’utente deve avere la possibilità di esprimere un giudizio binario (“Mi piace” / “Non mi piace”) su- gli articoli proposti e, nel caso volesse formulare un pensiero più complesso, è necessario che il siste- ma supporti l’inserimento dei commenti. Sebbene l’opzione di invio predefinita consista nel notificare a tutti gli utenti ogni articolo pubblica- to, si chiede inoltre di implementare una procedura di selezione delle categorie di interesse, così che il bot possa inviare le notizie appartenenti a una specifica categoria solo a quegli utenti che l’hanno scelta. Le categorie tra cui scegliere devono essere: • Lavoro; • Studio, formazione e corsi; • Mobilità all’estero; • Eventi e recruiting; • Offerte di lavoro; • Collocamento mirato; • Informazioni di servizio sui CPI; • Bandi e avvisi dai CPI; • Statistiche sul mondo del lavoro; • Politiche del lavoro; • Tirocini. Ogni articolo deve appartenere a una o più categorie. Il bot deve essere in grado di determinare, sulla base del contenuto dell’articolo, le categorie di appartenenza. 6 Corso per operatori CNC propedeutico all'assunzione in importanti aziende meccaniche. L’Amministrazione regionale, in collaborazione con l’azienda LMB Srl della Società PELFA Group e CMB Solutions Srl, ricerca addetti alla produzione con macchine utensili CNC. Per l'acquisizione delle competenze ricercate è... continua Immagine Titolo Estratto del contenuto (circa 30 parole) Collegamento
  • 15. Per ogni articolo inviato, infine, deve essere implementato un meccanismo di lettura automatica, ac- cessibile attraverso un comando dedicato, che ne permetta l’ascolto dei titoli e testo. Per quanto riguarda l’interfaccia utente dell’amministratore, invece, si richiede la possibilità di con- trollare ogni aspetto del servizio. Si desidera in particolare poter visionare: • il numero di utenti collegati, e per ognuno tutte le informazioni raccolte dal sistema; • il dettaglio di ogni articolo inviato, compresi i giudizi e i commenti espressi dagli utenti; • lo stato di invio degli articoli (già inviato, non ancora inviato, in coda) . Deve inoltre essere possibile: • escludere dal servizio determinate categorie di utenti (per esempio i bot), o alcuni utenti in particolare; • inviare un articolo a tutti gli utenti, indipendentemente dalle categorie selezionate dai singoli; • aggiornare (aggiungere/eliminare/modificare) le categorie disponibili. Accettazione delle condizioni d’utilizzo del servizio Il progetto prevede un’insita problematica, ossia il trattamento di dati personali. È necessario che l’utente, prima di poter usufruire del servizio proposto, abbia accettato un’informativa contenente le condizioni di utilizzo del servizio e la politica di trattamento dei dati che saranno inviati durante la comunicazione. Si chiede di inserire un meccanismo di controllo che impedisca all’utente di utilizzare il servizio nel caso in cui l’informativa non sia stata ancora accettata. Per gli utenti che accedono direttamente dall’applicazione Telegram, inoltre, bisogna implementare una funzionalità che permetta loro di ac- cettare l’informativa direttamente dall’applicazione. Per coloro che accedono dal portale, invece, è necessario inserire una clausola di avvenuta accettazione dell’informativa prima di fornire il collega- mento per accedere al servizio. Una descrizione grafica del meccanismo è stata inserita in Figura 4. Figura 4: Metodo di accettazione dell'informativa sul trattamento dei dati personali. 7
  • 16. Altri requisiti funzionali Si intende inserire nel sistema delle componenti che permettano la profilazione dell’utente, finalizza- ta a un miglioramento della qualità del servizio tramite l’analisi dei gruppi. In particolare, le informa- zioni da raccogliere sono età e titolo di studio. L’utente non deve essere obbligato a inserire tali dati. Software Per la realizzazione del progetto si richiede che tutto il software utilizzato sia improntato alla filoso- fia dell’Open Source[5] . Analogamente, ciò che sarà sviluppato dovrà essere pubblicato con licenza GNU Affero General Public License (AGPL) in versione 3.0[6] . Tutti i programmi, infine, devono poter essere eseguiti sul sistema operativo Linux. Carico applicativo Sono previsti indicativamente alcune decine di utenti regionali che accederanno al settore ammini- strativo dell’applicazione. Gli utenti del bot Telegram sono invece stimati nell’ordine di alcune decine di migliaia. Tale previsio- ne è stata fatta sulla base del numero attuale di visitatori del portale, riportato in Figura 5. Figura 5: Rapporto del 18 ottobre 2019 sul traffico del dominio offertelavoro.regione.fvg.it. 2.1.2 Elenco completo dei requisiti Nella Tabella 1 sono stati elencati i requisiti raccolti. La colonna Importanza esprime il peso del re- quisito dal punto di vista del committente; la colonna Legami evidenzia eventuali correlazioni del re- quisito con altri nella tabella. # Descrizione Importanza Legami 1 La divulgazione degli articoli avviene in una conversazione privata in Telegram. Essenziale / 2 L’utente può avviare il servizio anche attraverso il portale. Molto importante / 3 L’utente riceve le notifiche della pubblicazione di nuovi articoli in tempo reale. Molto importante / 4 L’utente riceve le notifiche nel formato indicato in Figura 3. Molto importante 1 8
  • 17. # Descrizione Importanza Legami 5 Agli articoli viene associata una traccia audio generata dalla lettura automatica degli stessi. Abbastanza importante / 6 L’utente può esprimere un feedback sugli articoli. Molto importante 1, 12 7 L’utente può commentare gli articoli. Molto importante 1, 12 8 L’utente può scegliere delle categorie di interesse. Essenziale 1, 16 9 L’amministratore può visionare il numero di utenti collegati. Essenziale / 10 L’amministratore può visionare le informazioni associate ad ogni utente. Molto importante 121 11 L’amministratore può visionare ogni articolo. Abbastanza importante / 12 L’amministratore può visionare i giudizi e i commenti espressi su- gli articoli. Molto importante 6, 7 13 L’amministratore può visionare lo stato d’invio degli articoli. Essenziale / 14 L’amministratore può escludere alcune categorie di utenti o degli utenti in particolare. Abbastanza importante 10 15 L’amministratore può inviare una comunicazione di servizio a tutti gli utenti. Abbastanza importante / 16 L’amministratore può aggiornare le categorie disponibili. Abbastanza importante 8 17 Il software utilizzato deve seguire la filosofia dell’Open Source[7] . Essenziale / 18 Il software prodotto deve essere reso disponibile con licenza AGPL in versione 3.0[8] . Essenziale / 19 Il software utilizzato e prodotto deve poter essere eseguito sul si- stema operativo Linux. Essenziale / 20 Il sistema deve supportare alcune decine di utenti del settore ammi- nistrativo e alcune decine di migliaia di utenti del bot Telegram. Molto importante / 21 Il bot Telegram chiede all’utente di inserire età e titolo di studio, così da poterlo profilare. Abbastanza importante 1, 22 Il bot Telegram chiede all’utente di accettare il trattamento dei dati personali. Essenziale 1 23 Il bot Telegram blocca gli utenti che non hanno accettato suddetta informativa. Essenziale 1, 22 24 Il bot Telegram deve essere in grado di determinare le categorie di appartenenza degli articoli. Abbastanza importante 1, 8 25 Il bot Telegram deve inviare gli articoli appartenenti a una determi- nata categoria solo agli utenti interessati. Essenziale 1, 8. 26 Il bot Telegram deve essere attivo 7 giorni su 7, 24 ore su 24. Molto importante 1, 3 Tabella 1: Elenco dei requisiti. 9
  • 18. 2.2 Progettazione Scopi di questa sezione sono l’esposizione e la motivazione delle scelte progettuali adottate. Si cer- cherà di associare ad ogni specifica del sistema uno o più tra i requisiti raccolti: d’ora in avanti, la di- citura “requisito n” indicherà l’n-esimo requisito inserito nella Tabella 1. Dall’analisi dei requisiti risulta evidente la necessità di implementare tre servizi di diversa natura: 1. un’applicazione web, in grado di fornire i servizi amministrativi (requisiti 9 → 16); 2. il bot Telegram, in grado di soddisfare le esigenze dell’utente (requisiti 1, 2, 4→ 8, 21 → 26); 3. un parser che analizzi il flusso RSS del portale LavoroFVG (requisito 3). Conviene dunque dividere la trattazione in tre sezioni, che sviluppino rispettivamente la progettazio- ne dell’applicazione web, quella del bot Telegram e quella del parser RSS. 2.2.1 Progettazione dell’applicazione web Questa sezione inizia e si conclude con la presentazione degli strumenti scelti per lo sviluppo dell’applicativo (non sono stati fatti ulteriori ragionamenti progettuali). La prima scelta effettuata consiste nella decisione di utilizzare un framework per realizzare applica- zioni web, ossia un’intelaiatura logica di supporto che permette di velocizzare lo sviluppo di un soft- ware. Per le funzionalità presenti e dal momento che la Direzione centrale lo utilizza già da tempo, si è concluso che, nel caso in esame, lo strumento più adatto fosse Django. Nei paragrafi che seguono saranno presentati, oltre alla piattaforma appena citata, altri elementi ne- cessari per l’esecuzione dello stesso: Gunicorn e Nginx. Infine si parlerà di PostgreSQL, l’RDBMS in cui saranno memorizzati i dati di interesse. Django Django è uno strumento a codice sorgente libero interamente scritto in linguaggio Python. Figura 6: Logo di Django. Esso viene utilizzato, ad alto livello, per la realizzazione della struttura di applicazioni web e offre numerose funzionalità che puntano a uno sviluppo veloce e ad un’elevata portabilità[9] . Di grande im- portanza, in riferimento al progetto di cui si parla in questo documento, sono in particolare il suppor- to nativo a diversi tipi di basi di dati[10] , tra cui PostgreSQL, e la possibilità di creare in modo automa- tico un sito amministrativo, sulla base dei modelli definiti dallo sviluppatore (per ulteriori informa- zioni si rimanda al capitolo 3.2.2). La specifica della Direzione centrale è stata di utilizzare Django 2.2. Per quanto riguarda la versione di Python, si è deciso di utilizzare la più recente[11] supportata dal framework, ossia Python 3.7. Nonostante Django includa un server, da utilizzare localmente in fase di sviluppo, esso non è suffi- ciente nel caso si voglia estendere la soluzione progettata a una scala più ampia di quella casalinga (si veda il requisito 20). Vanno dunque configurate alcune componenti esterne, che permettano il sup- porto dell’esecuzione delle applicazioni Django. 10
  • 19. Django è compatibile con vari server basati sulla WSGI[12][13] , un’interfaccia tra server e applicazioni web scritte in Python che promuove la portabilità delle applicazioni. Nel progetto in esame la scelta è ricaduta su Gunicorn, nella versione 20.0.2. Gunicorn Gunicorn è un software a codice sorgente libero scritto in Python, che supporta nativamente Django. Figura 7: Logo di Gunicorn. Il suo compito consiste fondamentalmente nel tradurre le richieste HTTP dei client in chiamate se- condo il protocollo WSGI, che l’applicazione Django possa processare e a cui rispondere[14] . È caldamente consigliato usare Gunicorn associato a un server proxy HTTP inverso, a causa di pro- blematiche legate alla sicurezza. Tra i molti esistenti, in particolare, gli sviluppatori consigliano l’uti- lizzo di Nginx[15] . Si è scelto di seguire questo consiglio e di usare l’ultima versione disponibile, la 1.17. Nginx Nginx è un software, a codice sorgente libero, che può essere utilizzato come server proxy per HTTP (diretto e inverso), per la posta elettronica o, in generale, per i protocolli di rete TCP/UDP. Figura 8: Logo di Nginx. Per quanto riguarda l’ambito in esame è sufficiente citarlo in veste di server proxy HTTP inverso. Le caratteristiche principali come tale comprendono l’architettura modulare e il supporto a vari meccani- smi di caching (per ulteriori informazioni si rimanda alla documentazione ufficiale[16] ). PostgreSQL Anche per lo stoccaggio dei dati è stato scelto un software a codice sorgente libero: sarà infatti utiliz- zato l’RDBMS PostgreSQL[17] , nella versione 10.10. Figura 9: Logo di PostgreSQL. Si tratta di un sistema gratuito in grado di supportare alti carichi di lavoro. L’approfondimento del funzionamento di tale strumento non è in questa sede rilevante, in quanto viene interfacciato con Py- thon, e quindi Django, in modo automatico grazie alla libreria psycopg2. Si osservi come l’RDBMS non possa essere una prerogativa dell’applicazione web ma debba essere condiviso con il bot Telegram, di modo che entrambi i sistemi possano inserire dati e effettuare inter- rogazioni. 11
  • 20. 2.2.2 Progettazione del bot Telegram Per la realizzazione di un bot Telegram esistono fondamentalmente due alternative: • usare un linguaggio che supporti direttamente l’utilizzo delle Bot API; • fare affidamento a delle librerie che si occupino di fornire le suddette API sotto forma di fun- zioni dedicate. Al fine di agevolare lo sviluppo del sistema, la Direzione centrale ha scelto di seguire la seconda stra- da e, in particolare, di utilizzare la libreria a codice sorgente libero python-telegram-bot. Figura 10: Logo di python-telegram-bot. Essa fornisce un’interfaccia Python pura per le Bot API di Telegram (essendo in linguaggio Python, è possibile interfacciarsi senza problemi anche con Django). In aggiunta a ciò, sono state implementate alcune classi di alto livello pensate per facilitare lo sviluppo dei bot[18] . La versione di python-telegram-bot usata è la 12. Lettura automatica degli articoli Si parlerà in questo paragrafo delle specifiche per il soddisfacimento del requisito 5 (la lettura auto- matica degli articoli). La Direzione ha deciso di fare affidamento sul servizio Google Text-to-Speech: esso permette in modo gratuito la conversione da testo a voce grazie alla tecnologia dell’apprendi- mento automatico[19] . Per sfruttare queste funzionalità Google mette a disposizioni delle API dedicate, le API Cloud Text- to-Speech. Analogamente a quanto detto per le Bot API, si è scelto di sfruttare una libreria che ne permettesse l’interfaccia con Python. Sarà utilizzata in particolare la libreria gTTS (Google Text-to- Speech), nella versione 2.0.4. Per ulteriori informazioni si consulti la documentazione associata[20] . 2.2.3 Progettazione del parser RSS Un parser è un programma che analizza un flusso continuo di dati in ingresso, riconosce al suo inter- no una grammatica e costruisce in base ad essa un albero che mostra i legami logici tra le varie com- ponenti. Nel caso in esame è necessario implementare un parser RSS, in quanto il portale LavoroF- VG mette a disposizione un flusso di questo tipo. Figura 11: Logo tipico per i flussi web. La Direzione ha imposto in questo senso l’utilizzo di FeedParser[21] (versione 5.2.0), che supporta un ampio numero di feed RSS e Atom, affiancato da Beautiful Soap (versione 4.8.1), una libreria che mette a disposizione alcuni metodi per la navigazione, ricerca e modifica di un albero di parsing[22] . 12
  • 21. 2.2.4 Architettura complessiva In quest’ultimo paragrafo viene esposta l’architettura complessiva del sistema che si dovrà andare a realizzare. Per semplicità di lettura, è stata riportata in forma grafica in Figura 12. Figura 12: Struttura complessiva del sistema. Come richiesto dal requisito 17, alla base dei vari servizi da implementare c’è OS Linux. Sono poi state rappresentate tre diverse sezioni: • La prima, che termina con il Servizio 1, riguarda l’applicazione web di back office. Tale parte permette il soddisfacimento dei requisiti amministrativi; • La seconda, il Servizio 2, riguarda il bot Telegram. Essa consente l’adempimento dei requisiti legati all’utente fruitore del servizio; • La terza è l’RDBMS, posizionato al centro per sottolineare il fatto che debba essere condivi- so dai due servizi. Si nota l’assenza del parser RSS: tale strumento non sarà ulteriormente approfondito in quanto la sua progettazione e realizzazione sono stati seguiti interamente dal professor Marco Tessarotto. Lo stesso discorso vale per l’implementazione della lettura automatica degli articoli. 13 Linux OS Applicazione web Bot Telegram Servizio 1 Servizio 2
  • 22. 14
  • 23. Capitolo 3 Realizzazione In questo capitolo sarà descritto il risultato del lavoro svolto. Come già è stato fatto nel capitolo pre- cedente, nella sezione riguardante la progettazione, anche qui sarà divisa la trattazione dell’applica- zione web da quella del bot Telegram, al fine di migliorare la comprensione del documento. Tutto ciò sarà preceduto da un capitolo introduttivo in cui saranno esposte le modalità attraverso le quali è stato sviluppato il progetto. 3.1 Modalità di lavoro La parte di programmazione associato al progetto è stata realizzata con il supporto dello strumento GitHub[23] . Si tratta di una piattaforma per lo sviluppo di software diffusa a livello mondiale. Figura 13: Logo di GitHub. Essa permette varie meccanismi a supporto della programmazione in gruppo. Degni di nota sono in particolare la possibilità di aprire delle “diramazioni” (branches) rispetto al progetto principale, così da poter implementare delle funzionalità senza inficiare quelle già presenti, e la possibilità di unire intelligentemente sezioni di codice realizzate da diversi programmatori (operazione di merge). Il codice a cui ci si riferirà in questo capitolo può essere consultato alla pagina https://github.com/marcotessarotto/dclavorofvg-bot Prima di continuare è bene fare una precisazione: ciò che sarà descritto nei prossimi paragrafi potreb- be discostarsi dalla versione consultabile all’indirizzo proposto. Il motivo sta nel fatto che il progetto è in stato di sviluppo e che, di conseguenza, i moduli su GitHub sono frequentemente aggiornati. Per evitare equivoci, dunque, si è deciso di riferirsi alla versione del progetto del 20 novembre 2019: https://github.com/marcotessarotto/dclavorofvg-bot/tree/ 2ce6f233fe164fc33b1627780fbc472e48b13bc8 15
  • 24. Meriti GitHub permette di quantificare il lavoro eseguito dai vari contributori associati a un progetto. Per quello in esame sono stati impostati due collaboratori, il professor Tessarotto, che ne è il proprietario, e l’autore di questo documento. Il lavoro svolto da ognuno può essere analizzato su GitHub[24] . In data 28 novembre 2019 la situazione è riassunta in Figura 14. Figura 14: Analisi del lavoro svolto. Si indica con il termine commit la procedura che rende effettive le modiche dei moduli effettuate in locale. Per ogni documento sul quale è stato eseguito un commit, GitHub mette a disposizione uno strumento che permette di visualizzare gli aggiornamenti in termini di righe inserite e cancellate: per ulteriori informazioni riguardo l’entità del lavoro svolto da ognuno dei collaboratori, dunque, è suffi- ciente utilizzare questo strumento. Tutti i commit eseguiti dall’autore sono riassunti all’indirizzo: https://github.com/marcotessarotto/dclavorofvg-bot/commits?author=mtt-merz. 16
  • 25. 3.2 Applicazione web In questa sezione sarà analizzata la parte della realizzazione legata all’applicazione web. Lo strumen- to è necessario per soddisfare i requisiti amministrativi espressi nella fase di analisi (capitolo 2.1). Un primo paragrafo sarà dedicato all’architettura del sistema; nei successivi sarà dato spazio alle so- luzioni ideate e all’analisi del codice. 3.2.1 Architettura Riprendendo quanto detto nel paragrafo 2.2.1 del precedente capitolo, Django non è sufficiente a ge- stire direttamente le richieste HTTPS formulate dagli utenti ma deve essere affiancato da altri stru- menti. In questa sezione sarà dunque analizzata l’architettura del sistema, che è stata riassunta nello schema in Figura 15. Figura 15: Architettura dell'applicazione web. Nginx è il servizio esposto a Internet: esso resta in ascolto sulla porta 443 per richieste HTTPS da parte degli utenti. Si tratta di un singolo processo, in esecuzione con privilegi ridotti. Le richieste ri- cevute da Nginx vengono poi passate a Gunicorn attraverso gli Unix socket. Gunicorn è un processo demone eseguito dal processo init con privilegi ridotti; nel momento in cui riceve delle richieste da Nginx usa la chiamata di sistema fork per creare dei processi figli (dei wor- kers) che si occupano della comunicazione con Django. Il protocollo di comunicazione è il WSGI. Django comunica poi con la base di dati in PostgreSQL attraverso psycopg2, che si occupa di tradur- re i comandi di interrogazione dal linguaggio Python a SQL, risolvendo il conflitto d'impedenza. In questo modo Django ricava i dati richiesti dall’utente e li rimanda indietro secondo le stesse modalità descritte, fino a Nginx, che comunica il risultato all’utente. Si osservi come anche il bot Telegram abbia bisogno di interfacciarsi alla base di dati e all’applica- zione web. Esso non è stato inserito in Figura 15 solo per una questione di chiarezza dell’esposizio- ne: le modalità secondo cui avviene tale interfaccia saranno debitamente spiegate nel paragrafo 3.3.1. 17 Applicazione backoffice Utente Richiesta HTTPS Risposta HTTPS HTTPS WSGI psycopg2 SQL
  • 26. 3.2.2 Progetto Django Questa sezione è dedicata all’analisi dei moduli associati all’applicazione web. Per facilitare la comprensione dell’argomento si è deciso di dedicare uno spazio iniziale alla spiega- zione della struttura del progetto, riportata per comodità in Figura 16: • La cartella src/ descrive il progetto nella sua totalità (si osser- vi la possibilità di modificare il nome di tale cartella, non im- portante per Django). • Il modulo src.manage è uno strumento utilizzabile da linea di comando che permette di interagire in vario modo con il pro- getto. Esso non sarà in questa sede ulteriormente approfondito; per ulteriori informazioni si consiglia di consultare la documen- tazione ufficiale[25] . • La cartella src/gfvgbo descrive l’ambiente di lavoro: contiene diversi moduli legati al funzionamento del progetto in generale, senza riferirsi alla singola applicazione. • La cartella src/backoffice contiene invece tutte le informa- zioni legate alla specifica applicazione backoffice. Si può a questo punto passare alla descrizione e al commento dei moduli di maggiore importanza. Analisi del modulo src.gfvgbo.secrets In questo modulo sono definite le credenziali che permettono l’accesso alla base di dati in Postgre- SQL e all’applicazione Django. Trattandosi di informazioni riservate, il modulo non è stato inserito sulla pagina GitHub dedicata al progetto; tuttavia, per il corretto funzionamento del sistema, esso deve essere necessariamente pre- sente nella seguente forma. 1 DB_NAME = [...] 2 DB_USERNAME = [...] 3 DB_PWD = [...] 4 5 SECRET_KEY = [...] 6 7 SMTP_SERVER = [...] 8 SMTP_USER = [...] 9 SMTP_PASSWORD = [...] 10 11 EMAIL_SENDER = [...] La variabile SECRET_KEY indica il codice segreto associato al progetto Django, generato al momento della sua creazione dal comando startproject. Essa impedisce vulnerabilità legate all’esecuzione remota del codice e alla possibilità di escalation dei privilegi utente[26] . Analisi del modulo src.gfvgbo.settings In questo modulo sono definite le impostazioni globali del progetto, che si presentano sotto forma di variabili. Quando viene creato un nuovo progetto Django, tale modulo viene generato automatica- 18 Figura 16: Struttura.
  • 27. mente, secondo determinate direttive[27] . Nel caso di esigenze particolari, come in qeullo in esame, è però necessario effettuare delle modifiche. Le principali modifiche apportate riguardano: • le impostazioni associate alla base di dati; 1 DATABASES = { 2 'default': { 3 'ENGINE': 'django.db.backends.postgresql_psycopg2', 4 'NAME': DB_NAME, 5 'USER': DB_USERNAME, 6 'PASSWORD': DB_PWD, 7 'HOST': 'localhost', 8 'PORT': '', 9 } 10 } (le costanti DB_* sono importate dal modulo src.gfvgbo.secrets). • il percorso in cui devono essere salvati i documenti gestiti dall’applicazione; 1 MEDIA_ROOT = '/opt/media/dclavorofvg-bot/' 2 AUDIO_ROOT = os.path.join(MEDIA_ROOT, 'audio/') • le impostazioni del server HTTP WSGI; 1 WSGI_APPLICATION = 'gfvgbo.wsgi.application' • l’aggiunta di backoffice tra le applicazioni installate. Per ulteriori informazioni riguardo alle varie opzioni di configurazione è possibile consultare la docu- mentazione ufficiale, reperibile alla voce 27 della bibliografia. Analisi del modulo src.backoffice.models In questo modulo sono contenuti i modelli relativi all’applicazione web backoffice. Prima di iniziare l’analisi è bene dare una definizione di modello: esso rappresenta la singola e definitiva fonte di in- formazione riguardo un tipo di dato che si vuole immagazzinare. Ad ogni modello, che nella base di dati corrisponde a una relazione, sono associati dei campi, gli attributi della relazione, e alcuni com- portamenti. Dal punto di vista pratico, ogni modello è una classe Python sottoclasse di django.db. models.Model e ogni campo è un’istanza della classe django.db.models.Field appropriata[28] . In Figura 17 è stato rappresentato il diagramma UML delle classi create, in modo da facilitare la comprensione del modulo. La Tabella 2 si occupa, riferendosi ad esso, di fornire una descrizione più approfondita dei vari modelli. Modello Descrizione TelegramUser Rappresenta un utente del servizio Telegram. I campi user_id, username, first_name, last_name, is_bot e lan- guage_code sono fornite da Telegram. Il campo privacy_acceptance_mechanism indica la modalità con cui è stato effettuato l’accesso al servizio: se direttamente tramite Telegram var- rà “U”, se attraverso il portale “L”. Il campo regionefvg_id, non nullo solo nel caso in cui l’accesso è stato fatto dal portale, ha un fine d’uso interno. 19
  • 28. Modello Descrizione UserFreeText Rappresenta un messaggio libero scritto da un utente in cui non è specifi- cato alcun comando (i comandi iniziano con il carattere “/”). NewsItem Rappresenta un articolo da inviare agli utenti Telegram. Il campo broadcast_message, se posto a True, forza la notifica di un ar- ticolo a tutti gli utenti, indipendentemente dalle categorie scelte dai singoli. Il campo start_publication permette di impostare una data per l’invio di un articolo che sia diversa dal momento di caricamento dello stesso. I campi file1, file2 e file3 sono oggetti NewsFile, ossia degli allega- ti. Il campo recurrent_for_new_users forza l’invio dell’articolo a tutti i nuovi utenti Telegram nel momento in cui si iscrivono al servizio, indipen- dentemente dalle categorie scelte. Il campo processed indica se l’articolo è già stato spedito a tutti gli utenti che dovevano riceverlo o se è ancora in coda d’invio. NewsFile Rappresenta un documento di qualsiasi tipo (immagine, documento di te- sto, traccia audio ecc…) che è stato allegato a uno o più articoli. NewsItemSentToUser Rappresenta l’invio di una notizia a un determinato utente. FeedbackToNewsItem Rappresenta un feedback espresso da un utente in riferimento a un deter- minato articolo. Il campo val può assumere i valori +1 e -1. CommentToNewsItem Rappresenta un commento scritto da un utente in riferimento a un determi- nato articolo. Category Rappresenta una categoria di articoli che può essere scelta dagli utenti. Il metodo fill_categories() serve a popolare la relazione, nel caso sia vuota (quindi non appena il servizio è stato avviato), con le categorie pre- impostate. Tali categorie vengono estratte dal dizionario DEFAULT_CATE- GORIES_DICT, importato dal modulo src.backoffice.definitions. CategoriesGroup Rappresenta un insieme di categorie che condividono una tematica, indica- ta nel campo name. RssFeedItem Rappresenta un oggetto ricevuto dal portale, in formato RSS, da processare perché diventi un articolo da inviare. Il campo update_parsed indica il momento in cui l’oggetto è stato pub- blicato sul portale, o, più precisamente, il momento in cui l’applicazione ne ha notato la presenza. Il campo processed indica se l’oggetto è già stato trasformato in un arti- colo oppure se deve ancora essere processato. LogUserInteraction Rappresenta un’interazione di un utente con il bot. Il campo text registra qualsiasi messaggio ricevuto dal bot, che sia un co- mando riconosciuto o un testo libero. SystemParameter Rappresenta un parametro di sistema (per esempio il messaggio da inviare come risposta al comando /help). Il metodo update_system_parameters() permette di popolare la base di dati con i parametri di sistema preimpostati. TextToSpeechWord Subsitution Rappresenta un oggetto legato alla funzionalità di lettura automatica del ti- tolo degli articoli. Tabella 2: Elenco dei modelli. 20
  • 29. Figura 17: Schema UML delle classi. 21 Category + key : CharField(2) + name : CharField(256) + emoji : CharField(9) + desciption : CharField(256) + is_telegram_command : BooleanField = True + custom_telegram_command : CharField(64) + updated_at : DateTimeField + __str__() + fill_categories() CategoriesGroup + name : CharField(256) + categories : ManyToManyField + add_bot_command : BooleanField = True + updated_at = DateTimeField + __str__() NewsItemSentToUser + telegram_user : ForeignKey + news_item : ForeignKey + flags : CharField(4) + created_at : DateTimeField + __str__() TelegramUser + user_id : BigIntegerField + regionefvg_id : BigIntegerField = -1 + username : CharField(32) + first_name : CharField(50) + last_name : CharField(50) + is_bot : BooleanField = False + is_admin : BooleanField = False + language_code : CharField(2) + categories : ManyToManyField + age : IntegerField = -1 + educational_level : CharField(1) = “-” + has_accepted_privacy_rules : BooleanField = False + privacy_acceptance_mechanism : CharField(1) + privacy_acceptance_timestamp : DataTimeField + enabled : BooleanField = True + is_text_to_speech_enabled : BooleanField = True + chat_state : CharField(1) = “-” + number_of_received_news_item : BigIntegerField = 0 + email : CharField(256) + created_at : DateTimeField + updated_at : DateTimeField + __str__() + educational_level_verbose() + categories_str() UserFreeText + text : CharField(1024) + telegram_user : ForeignKey + created_at : DateTimeField + __str__() RssFeedItem NewsFile + file_field : FileField + upload_date : DateTimeField + __str__() NewsItem + title : CharField(1024) + title_link : CharField(1024) + text : CharField(2048) + show_all_text : BooleanField = True + show_first_n_words : IntegerField = 30 + categories : ManyToManyField + broadcast_message : BooleanField = False + link : CharField(1024) + link_caption : CharField(1024) = “continua” + file1 : ForeignKey + file2 : ForeignKey + file3 : ForeignKey + like : BigIntegerField = 0 + disilke : BigIntegerField = 0 + start_publication : DataTimeField + recurrent_for_new_users : BooleanField = False + processed : BooleanField = False + processed_timestamp : DateTimeField + rss_id : CharField(256) + ask_comment_to_user : BooleanField = False + created_at : DateTimeField + updated_at : DateTimeField + __str__() FeedbackToNewsItem + news : ForeignKey + user : ForeignKey + val : SmallIntegerField = 0 + created_at : DateTimeField + rss_id : CharField(1024) + rss_title : CharField(1024) + rss_link : CharField(1024) + update_parsed : DateTimeField + category : ForeignKey + processed : BooleanField = False + created_at : DateTimeField + __str__() + data_feed_was_last_updated() CommentToNewsItem + news : ForeignKey + user : ForeignKey + text : CharField(4096) + created_at : DateTimeField + __str__() LogUserInteraction + user_id : BigIntegerField = -1 + text : CharField(1024) + coming_from_user : BooleanField = True + created_at : DateTimeField + updated_at : DateTimeField + __str__() SystemParameter + name : CharField(256) + value : TextField(4096) + comment : CharField(256) + __str__() + add_default_param() + update_system_parameters() TextToSpeechWordSubstitution + original : CharField(64) + substitution : CharField(64) + lang : CharField(2) = “it” + fill_substitutions() + load() 0..N 1..1 0..N 0..N 0..N 0..N 0..N 1..1 1..1 1..1 1..1 1..1 0..N 0..N 0..N 0..N 0..1 0..3 1..N 0..N 0..N
  • 30. Analisi del modulo src.backoffice.admin In questo modulo sarà descritta l’interfaccia amministrativa dell’applicazione web backoffice, gene- rata automaticamente da Django sulla base dei modelli definiti nel modulo src.backoffice.mo- dels. La formattazione dei vari elementi e le funzionalità disponibili sono pensate per facilitare agli amministratori la gestione dei contenuti del sito[29] . In Figura 18 è raffigurata la pagina principale creata per l’applicazione in esame. Figura 18: Elenco dei modelli inseriti nella pagina amministrativa di backoffice. Selezionando uno dei modelli elencati si apre una nuova pagina, raffigurata in Figura 19, con tutte le istanze della classe presenti. Si farà riferimento, come caso esemplificativo, al modello NewsItem. Figura 19: Pagina di backoffice dedicata al modello NewsItem. È poi possibile visualizzare, ed eventualmente modificare, come suggerisce il titolo della schermata, le informazioni legate ad una particolare istanza selezionandola dall’elenco. Dopo questa prima fase di analisi dell’interfaccia, si passa all’analisi del codice. 22 2 1 3 4
  • 31. Tutto ciò che è stato fino ad ora presentato viene creato automaticamente da Django: l’utilità di que- sto modulo consiste semplicemente nella specifica di alcune personalizzazioni, così che l’interfaccia sia adeguata alle proprie necessità. Il codice che segue contiene le personalizzazioni per il modello NewsItem. 1 @admin.register(NewsItem) 2 class NewsItemAdmin(admin.ModelAdmin): 3 4 list_display = ('id', 'title', 'created_at', 'list_of_categories', 5 'processed', 'processed_timestamp', 'like', 'dislike') 6 exclude = ('like', 'dislike') 7 search_fields = ('id', 'title') 8 list_filter = ('categories',) 9 10 formfield_overrides = { 11 models.ManyToManyField: {'widget': CheckboxSelectMultiple}, 12 models.CharField: {'widget': TextInput(attrs={'size': '80'})} 13 } 14 15 def list_of_categories(self, obj): 16 return ',n'.join([a.name for a in obj.categories.all()]) 17 18 list_of_categories.short_description = "Categorie" Le impostazioni di visualizzazione sono inserite in una classe dedicata, denominata per chiarezza NewsItemAdmin, e vengono associate al modello desiderato attraverso il decoratore alla riga 1, un metodo predisposto a tal proposito da Django. Sono state specificate le seguenti opzioni di visualizzazione: • alla riga 4, list_display indica i campi visibili della tabella che raccoglie tutte le istanze della classe NewsItem. Il risultato si può apprezzare in Figura 19 nel riquadro 1; • alla riga 7, search_fields specifica i campi sui quali vanno impostati i filtri testuali inseriti attraverso la barra di ricerca in Figura 19 nel riquadro 2; • alla riga 8, list_filter specifica i campi attraverso i quali si possono filtrare gli elementi visualizzati nell’elenco. Si ottiene in questo caso una tabella posizionata sul margine destro, come mostrato in Figura 19 nel riquadro 3; • alla riga 6, exclude specifica i campi che vanno esclusi dalle pagine di aggiunta e di modifi- ca degli oggetti NewsItem; • alla riga 10, formfields_overrides permette di modificare il formato di visualizzazione delle classi django.db.models.Field specificate, nel caso in esame ManyToManyField (riga 11) e CharField (riga 12); • alla riga 15, la funzione list_of_categories() specifica in che formato vanno mostrate le categorie nella pagina mostrata in Figura 19. Per ulteriori informazioni riguardo le opzioni di visualizzazione si consiglia di visitare la pagina della documentazione ufficiale associata[30] . 23
  • 32. 3.3 Bot Telegram In questa sezione sarà analizzata la parte della realizzazione legata al bot Telegram. La trattazione delle funzionalità implementate inizia con la presentazione dell’architettura del sistema realizzato. Si passa poi all’analisi dell’interfaccia utente, in cui si spiega cosa il bot può fare, e quin- di alla spiegazione del codice, così da comprendere come lo fa. 3.3.1 Architettura L’architettura del bot Telegram è rappresentata in Figura 2. Figura 20: Architettura del bot Telegram. L’utente interagisce con il bot inviando messaggi, comandi e richieste dall’applicazione Telegram, in versione mobile o desktop. Tali informazioni, prima di essere gestite dal sistema realizzato, sono pro- cessate dai server Telegram, che le rendono disponibili attraverso le Bot API. python-telegram-bot si occupa dell’interazione con le Bot API e le rende disponibile in Python. Come era stato accennato nel capitolo 3.2.1, anche il bot Telegram ha accesso ai modelli definiti nell’applicazione web. Il meccanismo che rende possibile ciò sarà analizzato nel dettaglio nel capito- lo 3.3.3, all’interno del paragrafo che illustra il modulo src.telegram_bot.django_settings. 3.3.2 Interfaccia utente Questa sezione è dedicata all’analisi, attraverso la presentazione dell’interfaccia utente, del funziona- mento generale del bot Telegram. Altre funzionalità, disponibili esclusivamente all’amministratore o di minore importanza, saranno descritte nel capitolo 3.3.3, con il supporto del codice. La descrizione è accompagnata da schermate dell’applicazione in versione desktop, così che il lettore ne possa valutare immediatamente la qualità. Il comando /start Premendo sul pulsante AVVIA l’utente inizia la conversazione con il bot. La prima cosa che gli sarà chiesta riguarda l’accettazione dell’informativa sul trattamento dei dati personali. Come mostrato in Figura 21, non appena l’utente riceve il messaggio la tastiera viene sostituita con i pulsanti ACCET- 24 Bot Telegram DCLavoroFvg backoffice Utente Scambio di messaggi Notifica pubblicazione articoli HTTPS psycopg2 SQL
  • 33. TO e NON ACCETTO: tale accorgimento facilita l’iterazione con il bot in quanto è sufficiente pre- mere su uno di essi per inviare la risposta. Figura 21: Invio dell'informativa sul trattamento dei dati personali. Per consultare le condizioni poste è sufficiente aprire l’allegato al messaggio, oppure seguire il colle- gamento che lo precede, riportato per completezza anche in questo documento: http://www.regione.fvg.it/rafvg/cms/RAFVG/formazione-lavoro/lavoro/allegati/ informativa_dir_lavoro_servizi_messaggistica102019.pdf Ci sono a questo punto due possibili sviluppi: • Se l’utente sceglie di non accettare l’informativa il bot si blocca e a qualsiasi comando inseri- to risponderà come mostrato in Figura 22. Figura 22: Il bot è bloccato. L’unico modo per sbloccare il bot è inserire il comando /privacy e accettare l’informativa. • Al contrario, nel caso in cui l’informativa sia stata accettata, il bot inizia una breve conversa- zione per raccogliere alcune informazioni sull’utente, finalizzate alla profilazione per il mi- glioramento del servizio. Tali informazioni sono età e titolo di studio più elevato. Si osservi in Figura 23 come il titolo di studio vada inserito con la stessa modalità richiesta per l’accet- tazione dell’informativa. 25
  • 34. Figura 23: Inserimento del titolo di studio più elevato. Il comando /scegli Una volta selezionato anche il titolo di studio, l’utente viene invitato a inserire il comando /scegli, così da selezionare, tra quelle disponibili, le categorie di suo interesse. La schermata che si presenta all’invio del comando è riportata in Figura 24. Figura 24: Scelta delle categorie di interesse. In questo caso compare un secondo tipo di tastiera, i cui pulsanti sono posizionati immediatamente sotto il messaggio inviato dal bot. Ognuno di essi funziona come un interruttore: premendoli, se la categoria non era selezionata allora lo diventa, se lo era viene deselezionata. 26
  • 35. Terminata la scelta è sufficiente premere il pulsante CHIUDI: il messaggio precedente sarà sostituito da uno riassuntivo delle categorie scelte, riportato in Figura 25. Figura 25: Riassunto delle categorie scelte. A questo punto può considerarsi terminata la configurazione del servizio. Il comando /categorie Esistono due modalità per modificare la scelta delle categorie di interesse. La prima consiste nell’inviare nuovamente il comando /scegli, la seconda nel digitare il comando /categorie. Nel secon- do caso il bot risponderà come rappresentato in Figura 26. Figura 26: Elenco dei comandi relativi alle categorie. Selezionando uno dei comandi elencati si otterrà, in base alle categorie precedentemente selezionate, il messaggio in Figura 27 oppure quello in Figura 28 (si è supposto di scegliere la categoria Lavoro). Figura 27: Proposta di smettere di seguire la categoria specificata. 27
  • 36. Nel primo caso la categoria era stata precedentemente selezionata e il bot chiede all’utente se deside- ra continuare a seguirla oppure no. Figura 28: Proposta di iniziare a seguire la categoria specificata. Nel secondo caso la situazione è opposta a quella precedente (la categoria non era ancora stata sele- zionata e il bot propone all’utente di iniziare a seguirla). L’invio degli articoli Non appena un nuovo articolo viene pubblicato sul portale, il bot invia una notifica agli utenti inte- ressati. In Figura 29 è mostrato il formato di tale messaggio. Figura 29: Notifica della pubblicazione di un nuovo articolo. Si osservi la corrispondenza tra il formato della notifica e quello richiesto nei requisiti in Figura 3. Per continuare la lettura bisogna premere il testo in blu continua (si tratta di un collegamento per la pagina del portale contenente l’articolo completo). Si può esprimere un giudizio binario sull’utilità di ogni articolo ricevuto premendo su uno dei due pulsanti inseriti sotto il messaggio. 28
  • 37. In base all’articolo ricevuto, inoltre, è stata implementata la possibilità di inserire dei commenti, solo dopo aver espresso il giudizio appena citato. L’interfaccia che si presenta all’utente in questa even- tualità è mostrata in Figura 30. Figura 30: Interfaccia per l'inserimento dei commenti, Pt. 1. Premendo sul pulsante che compare sotto il messaggio si presenta in automatico la situazione descrit- ta in Figura 31: l’utente è invitato a inserire il testo del commento in risposta ad un messaggio del bot che specifica l’identificatore dell’articolo. Figura 31: Interfaccia per l'inserimento dei commenti, Pt. 2. Una volta formulato il commento è sufficiente inviarlo affinché venga registrato. Il comando /rimanda_ultime_news Inviando il comando /rimanda_ultime_news, il bot restituisce, in ordine di pubblicazione, il titolo e la categoria degli articoli notificati negli ultimi dieci giorni, a partire dal meno recente. In Figura 32 è stato riportato un esempio della risposta a tale comando. Figura 32: Riassunto degli articoli inviati negli ultimi dieci giorni. A questo punto l’utente può decidere se ricevere nuovamente la notifica di uno degli articoli elencati, inviando il comando /mostra_ seguito dall’identificatore dell’articolo, oppure ricevere un messaggio con una traccia audio generata dalla lettura automatica del titolo di uno degli articoli. Per usufruire di 29
  • 38. questa seconda funzionalità è necessario inviare il comando /leggi_, anch’esso seguito dall’identifica- tore dell’articolo. Il risultato è rappresentato Figura 33. Figura 33: Lettura del titolo dell'articolo selezionato. Il comando /statistiche Digitando il comando /statistiche il bot invia un messaggio che riassume il numero di notizie inviate per ogni categoria negli ultimi dieci giorni, come rappresentato in Figura 34. Figura 34: Statistiche sugli articoli inviati negli ultimi dieci giorni. Il comando /help Digitando il comando /help, o, equivalentemente, il comando /aiuto, il bot invia un messaggio espli- cativo del proprio funzionamento. Tale messaggio viene riportato in Figura 35. Figura 35: Messaggio esplicativo del funzionamento del bot. Nei paragrafi precedenti sono già stati analizzati tutti i comandi elencati nel messaggio. 30
  • 39. 3.3.3 Codice I moduli relativi alla realizzazione del bot Telegram sono collocati nella cartella src/ telegram_bot. I principali, che saranno analizzati in questo documento, sono i seguenti: • regionefvg_bot • news_processing • log_utils • ormlayer • django_settings Il bot viene avviato eseguendo il modulo src.telegram_bot.regionefvg_bot. Analisi del modulo src.telegram_bot.regionefvg_bot Ad essere analizzato in questo paragrafo è il modulo principale del bot Telegram. Il punto di partenza per l’analisi è il metodo main(), del quale viene riportata una parte di codice. 1 token_file = Path('token.txt') 2 3 token = os.environ.get('TOKEN') or open(token_file).read().strip() 4 mqueue = messagequeue.MessageQueue(all_burst_limit=29, all_time_limit_ms=1017) 5 request = Request(con_pool_size=8) 6 7 global global_bot_instance 8 global_bot_instance = MQBot(token, request=request, mqueue=mqueque) 9 10 updater = Updater(bot=global_bot_instance, use_context=True) 11 dp = updater.dispatcher 12 13 job_queue = updater.job_queue 14 job_minute = job_queue.run_repeating( 15 news_dispatcher, 16 interval=NEWS_CHECK_PERIOD, 17 first=0 18 ) 19 20 # AGGIUNTA DEGLI HANDLER 21 22 updater.start_polling() 23 updater.idle() Le prime righe del codice sono dedicate alla memorizzazione del codice univoco associato al bot. Tale codice, necessario per poterlo avviare, viene fornito durante la sua creazione dal @botfather[31] , un bot creato da Telegram che fornisce un’interfaccia per la creazione di altri bot. Le righe successive, dalla 4 alla 8, sono associate a un problema totalmente diverso. Esistono dei li- miti intrinseci per inviare messaggi attraverso i bot, così da non poterli usare per inviare spam[32] : tali limiti, detti per questo motivo limiti di spam, sono riassunti in Tabella 3. Numero massimo di messaggi Contesto di applicazione 30 messaggi al secondo In conversazioni private (il caso di questo bot). 20 messaggi al minuto All’interno di gruppi. Tabella 3: Limiti di spam. Superate queste soglie le Bot API restituiscono il messaggio di errore 429. 31
  • 40. È dunque necessario implementare un meccanismo che limiti il traffico generato. La libreria python- telegram-bot mette a disposizione a tal proposito la classe MessageQueue, definita all’interno del modulo telegram.ext.messagequeues: essa permette di sottoporre a un determinato ritardo la spedizione dei messaggi. Nella riga 4, sfruttando tale classe, si impone di non inviare più di 29 mes- saggi ogni 1017 millisecondi (così da avere un margine del 5% rispetto al limite di spam). Alla riga 8 viene definito l’oggetto Bot[33] configurato con le informazioni fino ad ora impostate. Alla riga 10 si inizializza, attraverso l’oggetto appena creato, l’oggetto Updater[34] . Si tratta di una componente fondamentale del progetto in quanto è lui a ricevere gli aggiornamenti da Telegram. Creando tale oggetto, inoltre, viene creato automaticamente un oggetto Dispatcher[35] (riga 11), nel quale è possibile registrare diversi tipi di handler. Gli aggiornamenti ricevuti dall’Updater sono pas- sati al Dispatcher, il quale a sua volta li invia a una determinata funzione di callback sulla base dell’handler che l’aggiornamento ha stimolato. Alla creazione dell’Updater, viene creato automaticamente anche un oggetto JobQueue[36] (riga 13), il quale permette di eseguire delle operazioni con un ritardo, oppure secondo un intervallo preimpo- stato. Nel caso in esame, è necessario che il bot controlli regolarmente la presenza di nuovi articoli da inviare: tale specifica viene soddisfatta con la riga 14 (e seguenti), in cui si impone che la funzione news_dispatching sia eseguita ogni NEWS_CHECK_PERIOD secondi, a partire dal momento in cui il bot viene avviato. La funzione non sarà approfondita in questo paragrafo in quanto definita nel modulo news_processing. Alla riga 22 viene attivato l’Updater, che si mette in ascolto per intercettare gli aggiornamenti. Il bot rimane in ascolto fino al momento in cui riceve i segnali SIGINT o SIGTERM. Il comando inse- rito alla riga 23 permette di evitare una terminazione brusca del bot alla ricezione di tali segnali. Elenco degli handler Si indica con il termine handler un metodo utilizzato per la gestione di un evento. Nel caso in esame gli eventi gestiti sono gli aggiornamenti ricevuti da Telegram: gli handler sono quindi quelle funzioni che rispondono alle azioni dell’utente (ad ogni tipo di azione è associato un determinato handler). Per ulteriori informazioni sull’argomento si rimanda alla pagina dedicata della documentazione ufficiale python-telegram-bot[37] . Alla riga 20 è stato inserito un commento al posto delle righe di codice riguardanti l’aggiunta dei vari handler, in modo da non appesantire la lettura del documento. In questo paragrafo essi saranno ana- lizzati più nel dettaglio. Innanzitutto è bene chiarire il significato delle variabili che ogni handler riceve come parametri: • update è un’istanza dell’oggetto Update e rappresenta un aggiornamento raccolto dall’Upda- ter. Esso contiene vari campi legati alla natura dell’aggiornamento gestito[38] . • context è un’istanza dell’oggetto CallbackContext e contiene vari campi legati al contesto in cui lo handler è stato chiamato. Per esempio, i campi chat_data e user_data possono esse- re usati per immagazzinare dati riutilizzabili in altri handler[39] . Si passa dunque all’analisi degli handler. Al fine di migliorare la comprensione del documento, in Ta- bella 4 ne è stato inserito un elenco, ognuno accompagnato da una breve descrizione. 32
  • 41. Nome Tipo Descrizione start Command Handler Invia un messaggio di benvenuto all’utente. conve Conversation Handler Avvia la procedura iniziale che permette di accettare le con- dizioni d’utilizzo del servizio e di inserire i dati per la profi- lazione dell’utente.Il risultato è riportato in Figura 21. privacy Command Handler Nel caso in cui non sia ancora avvenuta, propone l’accetta- zione dell’informativa con le condizioni d’utilizzo. undo_privacy Command Handler Revoca l’accettazione dell’informativa con le condizioni d’utilizzo del servizio. callback_privacy Message Handler Memorizza la risposta dell’utente alla richiesta di accettare l’informativa con le condizioni d’utilizzo del servizio. callback_age Message Handler Memorizza l’età inserita dall’utente. callback_ educational_level Message Handler Memorizza il titolo di studio più elevato dell’utente, nel caso sia stato selezionato tra quelli proposti. callback_custom_ educational_level Message Handler Memorizza il titolo di studio più elevato dell’utente, nel caso non fosse presente tra quelli proposti. help Command Handler Mostra un messaggio esplicativo delle finalità del bot e dei comandi a disposizione dell’utente. Il messaggio è riportato in Figura 35. help_categories Command Handler Mostra un messaggio con i comandi relativi alle categorie tra le quali l’utente può scegliere. Il messaggio è riportato in Figura 26. choose_news_ categories Command Handler Permette all’utente di scegliere le categorie di interesse. Il risultato è riportato in Figura 24. set_all_ categories Command Handler Seleziona come categorie di interesse tutte quelle disponibili. set_no_categories Command Handler Deseleziona tutte le categorie di interesse. resend_last_ processed_news Command Handler Invia il titolo e l’identificatore degli articoli inviati negli ulti- mi dieci giorni. Il risultato è riportato in Figura 32. show_news Message Handler Invia l’articolo passato per parametro dall’utente (per esem- pio, se l’utente scrive /mostra_2 gli sarà inviata la notizia con identificatore 2). read_news Message Handler Invia un messaggio con una traccia audio generata dalla let- tura del titolo dell’articolo passato per parametro dall’utente. Il messaggio è riportato in Figura 33. audio_on Command Handler Abilita l’invio delle traccie audio generate dalla lettura dei ti- toli degli articoli. audio_off Command Handler Disabilita l’invio delle traccie audio generate dalla lettura dei titoli degli articoli. comment Message Handler Raccoglie il commento inserito da un utente per un determi- nato articolo. 33
  • 42. Nome Tipo Descrizione callback Callback Query Handler Gestisce i dati inviati da tutte le tastiere create sotto i mes- saggi (quella per esprimere un giudizio binario su un artico- lo, quella per commentare un articolo e quella per seleziona- re le categorie di interesse). force_send_news Command Handler Forza il controllo della pubblicazione di nuovi articoli. Questo comando è disponibile esclusivamente agli ammini- stratori del bot. ping Command Handler Controlla lo stato dei servizi di sistema legati all’applicazio- ne web backoffice. Questo comando è disponibile esclusivamente agli ammini- stratori del bot. cleanup Command Handler Elimina lo storico degli articoli spediti all’utente. Questo comando è disponibile esclusivamente agli ammini- stratori del bot. stats Command Handler Invia un messaggio contenente le statistiche sugli articoli in- viati negli ultimi dieci giorni. Il messaggio è riportato in Figura 34. custom_command Message Handler Gestisce i comandi inviati dall’utente che non sono stati ge- stiti da alcun CommandHandler. Essi potrebbero essere sco- nosciuti oppure ricadere nell’insieme dei comandi legati alle categorie. generic_message Message Handler Registra i messaggi ricevuti che non sono stati gestiti da al- cun Handler. error_callback Error Handler Gestisce vari tipi di eccezioni riscontrate nella ricezione de- gli aggiornamenti. In particolare, sono gestiti gli errori Unauthorized, BadRequest, TimedOut, NetworkError, Chat- Migrated e TelegramError. Per ulteriori informazioni si con- siglia di consultare la documentazione ufficiale[40] . Tabella 4: Elenco degli handler. Analisi del modulo src.telegram_bot.news_processing A questo modulo è delegato il compito di inviare gli articoli. Vista la complessità del processo, si è ri- tenuto opportuno procedere per fasi. FASE 1. La procedura viene innescata da una chiamata al metodo news_dispatcher. Esso raccoglie gli articoli non ancora inviati, se presenti, e ne programma l’invio; effettua inoltre su ognuno dei con- trolli, così da spedirli esclusivamente agli utenti interessati. FASE 2. Una volta determinati gli articoli da inviare e gli utenti a cui inviarli viene invocato il meto- do send_news_to_telegram_user. Esso riceve come parametri un oggetto NewsItem (l’articolo da inviare), un oggetto TelegramUser (l’utente a cui inviarlo), le categorie in comune tra quelle scelte dall’utente e quelle assegnate all’articolo e altre informazioni riguardanti il formato con cui l’articolo dovrà essere recapitato. Esistono infatti diverse opzioni d’invio: • se il valore della costante SHOW_CATEGORIES_IN_NEWS, definita nel modulo src.backof- fice.definitions, è True, l’articolo inviato sarà preceduto da un messaggio contenente le categorie passate per parametro; • nel caso in cui il parametro title_only sia True, la notifica conterrà esclusivamente il tito- lo dell’articolo; 34
  • 43. • nel caso in cui il parametro request_feedback sia True, la notifica sarà seguita da un se- condo messaggio che chiede all’utente di inserire un giudizio binario (“Mi piace” / “Non mi piace”) sull’articolo ricevuto; • nel caso in cui il parametro ask_comment sia True, l’utente avrà la possibilità, oltre che a esprimere un giudizio binario, di formulare un commento per l’articolo ricevuto. Questo metodo si occupa di spedire gli articoli secondo tutte le modalità presentate, ma solo nel caso in cui non siano presenti degli allegati. FASE 3. Entra in gioco a questo punto il metodo _send_file_using_mime_type. Esso viene invo- cato da send_news_to_telegram_user nel caso in cui l’articolo da inviare contenga degli allegati. In python-telegram-bot esistono delle funzioni di invio diverse in base al tipo di documento da invia- re (per esempio nel caso di un’immagine si usa il metodo context.bot.send_photo): questo meto- do si occupa quindi di usare la funzione corretta in base al tipo di documento da inviare (riceve tale informazione come parametro). Prima di continuare con l’analisi è bene introdurre un particolare comportamento di Telegram, molto utile ai fini di questo progetto. Tale funzionalità consiste nella memorizzazione di un qualsivoglia do- cumento, non appena viene inviato un messaggio che lo contiene come allegato, nei server di Tele- gram. Ad esso viene associato durante la memorizzazione un codice univoco, così che, nel caso tale documento debba essere inviato nuovamente, sia possibile farlo riferendosi solo al suo identificatore. Tornando al caso in esame, nel momento in cui il bot invia un articolo con allegati al primo utente de- stinatario, gli allegati rimarranno in memoria e sarà possibile inviarli agli altri utenti attraverso l’identificatore appena nominato. È evidentemente consigliato sfruttare tale comportamento, in quan- to si ottiene attraverso di esso un notevole risparmio di banda. Alla fine del metodo _send_file_using_mime_type, e quindi dopo ogni invio di un messaggio con allegato, viene invocata la funzione _lookup_file_id_in_message, di cui viene riportato una parte del codice. Essa ha il compito di ricavare l’identificatore dell’allegato, se non era già stato rica- vato in una chiamata precedente. 1 def _lookup_file_id_in_message(message, _file_path: str, file_id): 2 3 if file_id is not None: 4 return 5 6 _file_id = None 7 try: _file_id = message.document.file_id 8 except AttributeError: 9 try: _file_id = message.photo[0].file_id 10 except (AttributeError, IndexError) as e: 11 try: _file_id = message.animation.file_id 12 except (AttributeError, IndexError) as e: 13 try: _file_id = message.animation[0].file_id 14 except (AttributeError, IndexError, TypeError) as e: 15 try: _file_id = message.voice.file_id 16 except (AttributeError, IndexError) as e: 17 try: _file_id = message.video.file_id 18 except (AttributeError, IndexError) as e: 19 return 20 21 if _file_id is not None: 22 file_id_cache_dict[_file_path] = _file_id 23 24 return Al metodo sono passati i seguenti parametri: 35
  • 44. • l’oggetto Message contenente l’allegato; • il percorso (locale) in cui è stato memorizzato; • l’identificatore del file. Se quest’ultimo campo non è vuoto significa che l’identificatore è già stato memorizzato e che non ha senso continuare (righe 3 e 4). Nel caso contrario, si prova a memorizzarlo, in base al formato del documento (righe 7 → 17). Se non si riscontrano errori l’identificatore viene quindi inserito nel di- zionario file_id_cache_dict (righe 21 e 22), dal quale sarà in seguito ricavabile attraverso il nome del percorso in cui il documento è stato memorizzato. Analisi del modulo src.telegram_bot.ormlayer Il modulo ormlayer permette un’interfaccia tra il bot Telegram e Django, gestore della base di dati in PostgreSQL. In esso sono definiti tutti quei metodi che interrogano la base di dati, oppure che in- seriscono in essa nuovi record. Essi non saranno riportanti in toto, sia per una questione di leggibilità del documento che per il fatto che molti sono di banale comprensione. Saranno piuttosto analizzati alcuni accorgimenti rilevanti, primo tra tutti l’implementazione di un meccanismo di caching. A tal riguardo è stato scelto l’utilizzo di un sistema messo a disposizione direttamente da Django at- traverso la classe django.core.cache. Esso permette di inserire in un dizionario un qualsiasi ogget- to Python per un determinato numero di secondi[41] . La struttura standard è la seguente: 1 from django.core.cache import cache 2 cache.set(key=key, value=value, timeout=timeout) Alla riga 2, key indica la chiave per recuperare l’oggetto, value la variabile da immagazzinare e ti- meout il numero di secondi per cui deve essere mantenuta in cache. Nel progetto in esame il mecca- nismo di caching è stato usato per memorizzare gli oggetti TelegramUser, NewsItem e SystemPara- meter. Analisi dei tempi di esecuzione con e senza cache Attraverso la variabile use_chache e il decoratore benchmark_decorator (definito nel modulo log_utils), che conta, con una precisione di un nanosecondo, il tempo necessario all’esecuzione del metodo che decora, è possibile fare dei ragionamenti sul risparmio effettivo con e senza cache. Si analizzerà in particolare il tempo di esecuzione del metodo orm_get_telegram_user. Per ricavare i dati necessari sono state scritte le seguenti righe di codice. 1 for i in range(100): 2 orm_get_telegram_user(telegram_user_id) 3 4 for i in range(100): 5 orm_get_telegram_user(telegram_user_id) 6 sleep(0.05) 7 8 for i in range(100): 9 orm_get_telegram_user(telegram_user_id) 10 sleep(0.10) Nel primo ciclo (righe 1 e 2) il metodo orm_get_telegram_user in esame viene chiamato cento volte senza interruzioni, nel secondo (righe 4 → 6) con 50 millisecondi di ritardo tra una chiamata e l’altra e nel terzo (righe 8 → 10) con 100 millisecondi di ritardo (in totale sono trecento iterazioni). 36
  • 45. Il codice è stato eseguito due volte, la prima impostando use_cache = True e la seconda con use_cache = False. I dati prodotti, inseriti in Appendice, sono stati organizzati in tre grafici ditin- ti, rappresentati rispettivamente in Figura 36, in Figura 37 e in Figura 38. 1 7 13 19 25 31 37 43 49 55 61 67 73 79 85 91 97 0 500000 1000000 1500000 2000000 2500000 con cache senza cache ns Figura 36: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni nullo. 1 7 13 19 25 31 37 43 49 55 61 67 73 79 85 91 97 0 500000 1000000 1500000 2000000 2500000 3000000 con cache senza cache ns Figura 37: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni pari a 50 ms. 1 7 13 19 25 31 37 43 49 55 61 67 73 79 85 91 97 0 500000 1000000 1500000 2000000 2500000 con cache senza cache ns Figura 38: Confronto dei tempi di esecuzione con l'intervallo tra le iterazioni pari a 100 ms. Alcune osservazioni: • sull’asse delle ascisse è riportato il numero dell’iterazione; • sull’asse delle ordinate il tempo di esecuzione, espresso in nanosecondi. 37
  • 46. Per entrambi i casi si nota un tempo di esecuzione mediamente più basso durante il primo ciclo (circa 60 microsecondi con la cache e circa 1000 microsecondi senza). Inserendo il ritardo, invece, indiffe- rentemente dalla sua portata, i valori si assestano a circa 210 microsecondi nel primo caso e a circa 1860 microsecondi nel secondo, per un guadagno complessivo che si stima dell’880% (quasi un ordi- ne di grandezza). Si osservi come sia presente un’evidente fluttuazione del tempo di esecuzione, nonostante le buone condizioni predisposte per la misurazione. Questo fenomeno può essere imputato al linguaggio di programmazione utilizzato, ossia Python, che non viene eseguito direttamente sul Kernel ma su una macchina virtuale. Dati simili possono essere ricavati anche dall’analisi di metodi diversi da orm_get_telegram_user. Ora, è evidente come tale risultato non sia assoluto, in quando le condizioni di test non equivalgono esattamente a quelle di utilizzo; tuttavia si tratta comunque di una considerazione interessante. I dati presentati sono stati raccolti da un calcolatore con sistema operativo Ubuntu nella versione 18.04, CPU Intel® Core™ i5-2430M a 2.40GHz per quattro core e 3.8GiB di memoria RAM. Analisi del modulo src.telegram_bot.log_utils In questo modulo sono definiti gli strumenti utilizzati per l’attività di logging, ossia la registrazione sequenziale delle operazioni di interesse effettuate dal sistema. Python, a supporto di tale attività, mette a disposizione nella libreria di base il modulo logging[42] : esso definisce classi e funzioni che implementano un sistema di logging flessibile per applicazioni e librerie. Al fine di documentare gli eventi, è necessario instanziare uno o più oggetti di tipo Logger attraverso la funzione logging.getLogger. Nel progetto ne sono stati istanziati cinque, sulla base al modulo/ contesto di utilizzo. Il passo successivo consiste nell’impostarne il livello: nella Tabella 5 sono indi- cati quelli disponibili, in crescente ordine di rigore. Specificando un determinato livello, si impone che siano tracciati gli eventi appartenenti a quel livello e ai livelli superiori. Nome Descrizione DEBUG Fornisce informazioni dettagliate sul funzionamento del programma, tipicamente di in- teresse nelle fasi diagnostiche. INFO Attesta che l’esecuzione del codice non ha riscontrato problemi. WARNING Indica l’avvenimento (o una previsione) di qualcosa di inaspettato che per ora non ha prodotto malfunzionamenti. ERROR Documenta la presenza di un problema più importante, a causa del quale il software non è riuscito ad eseguire alcune funzionalità. CRITICAL Registra l’avvenimento di un errore importante, che ha portato all’interruzione dell’ese- cuzione del programma. Tabella 5: Livelli di rigore degli eventi. Usando la funzione logging.basicConfig, inoltre, è possibile modificare le opzioni predefinite del modulo: 1 logging.basicConfig( 2 format='[%(asctime)s] %(name)s - %(levelname)s - %(message)s', 3 level=logging.INFO 4 ) 38
  • 47. Il campo format specifica che informazioni dovranno essere inserite nei messaggi e in quale forma- to; il campo level specifica il livello del logger di root (ossia l’oggetto Logger dal quale sono gene- rati tutti gli altri), che sarebbe altrimenti impostato su WARNING. Nel modulo log_utils sono poi definiti alcuni metodi, dei quali sarà analizzato solo il precedente- mente citato benchmark_decorator. Ne viene riportato per chiarezza il codice. 1 def benchmark_decorator(func): 2 @wraps(func) 3 def wrapped(*args, **kwargs): 4 5 import time 6 a = time.time_ns() 7 8 try: 9 return func(*args, **kwargs) 10 finally: 11 b = time.time_ns() 12 c = b – a 13 14 benchmark_logger.debug(f"{func.__name__} dt={c / 1000} microseconds") 15 return wrapped Esso, in qualità di decoratore, riceve come parametro (func) il metodo decorato. Senza addentrarsi nello specifico della funzione @wraps alla riga 2, si osserva come venga registrato il momento in cui il metodo func inizia (riga 6) e quello in cui termina (riga 11). Infine, nel caso non si siano presenta- te delle eccezioni, viene stampata, con un logger opportuno, la durata complessiva dell’esecuzione del metodo (riga 14). Analisi del modulo src.telegram_bot.django_settings Questo modulo è necessario per l’integrazione del bot Telegram con l’applicazione creata in Django. Nel momento in cui viene avviato il modulo src.telegram_bot.regionefvg_bot, il modulo src.telegram_bot.__init__ impone l’esecuzione delle seguenti righe di codice. 1 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_settings") 2 django.setup() La riga 1 indica la posizione del modulo che specifica le impostazioni di Django; la riga 2 ne avvia la configurazione, basandosi sul modulo indicato. In tale modulo, ossia src.telegram_bot.django_settings sono riportate alcune delle imposta- zioni definite in src.gfvgbo.settings. Quelle non riportate riguardano funzionalità che non sono a questo livello supportate. Perché tale integrazioni funzioni è inoltre necessario inserire in ogni modello di src.backoffice.- models la classe Meta con l’attributo app_label posto uguale a “backoffice”. In questo modo è possibile importare e sfruttare i modelli dell’applicazione web backoffice anche dal bot Telegram. 39
  • 48. 40
  • 49. Capitolo 4 Conclusioni In questo capitolo finale sarà commentato il grado di raggiungimento degli obiettivi specificati nei capitoli precedenti, sottolineando le funzionalità ancora da sviluppare. Si parlerà poi dello stato at- tuale del lavoro, e infine si darà spazio alle considerazioni soggettive dell’autore sul sistema creato e sul percorso seguito per realizzarlo. 4.1 Raggiungimento degli obiettivi Gli obiettivi posti, in particolare i requisiti espressi nel Capitolo 2, sono stati soddisfatti solo in parte. Il bot Telegram Il bot Telegram è attualmente in grado di notificare, anche se non in tempo reale (il ritardo è media- mente di 30 secondi), la pubblicazione degli articoli nel portale LavoroFVG, secondo le modalità specificate. Tuttavia non sono ancora state implementate le seguenti funzionalità: • il bot non può determinare automaticamente le categorie degli articoli (questi dati devono es- sere inseriti manualmente attraverso l’applicazione web); • non è disponibile il meccanismo di profilazione, che permette la suddivisione degli utenti in categorie, anche se c’è la possibilità di ottenere le informazioni atte allo scopo; • l’utente non può accedere al servizio dal portale (tale operazione necessita una modifica del sito, operazione esterna al progetto). Nonostante queste osservazioni possano far dubitare dei risultato del progetto, è bene ricordare che è stato realizzato un meccanismo avanzato per l’invio degli articoli, sui quali si può già esprimere feed- back e commenti, e che l’utente ha la possibilità di scegliere le categorie di articoli da ricevere. L’applicazione web Come controparte, l’applicazione web realizzata soddisfa tutti i requisiti che la competono: attraverso l’interfaccia proposta da Django, è stato possibile creare un sistema completo e adatto alle funzionali- tà amministrative richieste, dalla supervisione degli utenti collegati alla possibilità di inviare articoli personalizzati e messaggi di servizio. 41
  • 50. Si osservi comunque che le funzionalità lasciate in sospeso non saranno abbandonate: il servizio è ancora in fase di crescita e sarà, in sviluppi futuri, certamente soggetto a miglioramenti. Il lavoro di tesi In questo paragrafo sarà messo in luce il grado di raggiungimento degli obiettivi legati al lavoro di tesi, piuttosto che al progetto in generale. Per quanto riguarda il primo obiettivo, e quindi la collaborazione con Marco Tessarotto per lo svilup- po del software, si può dire che sia stato soddisfatto. Il contributo dell’autore ha portato alla realizza- zione dei seguenti elementi: • l’interfaccia utente per la notifica degli articoli; • i meccanismi per l’espressione dei feedback e dei commenti sugli articoli, sia dal punto di vi- sta del bot Telegram che da quello dell’applicazione web; • la conversazione iniziale per la raccolta dei dati sull’utente e per l’accettazione delle condi- zioni d’utilizzo del servizio; • il primo meccanismo di scelta delle categorie di interesse, quello che risponde all’invio del comando /scegli; • la personalizzazione dell’interfaccia utente dell’applicazione web, almeno per quanto riguar- da i modelli fondamentali. Per informazioni più accurate, in termini di codice scritto o modificato, si rimanda alla consultazione del primo paragrafo del Capitolo 3. Per quanto riguarda il secondo obiettivo della tesi, la documentazione del progetto, il giudizio sul grado di raggiungimento spetta al lettore. Si ricordi solo come sia stato descritto ogni aspetto fino ad ora implementato, ad eccezione del parser RSS. 4.2 Stato attuale del lavoro Il sistema è in questo momento funzionante, anche se, come già è stato detto, in uno stato non defini- tivo. Il codice che è stato prodotto è in esecuzione su un server Linux della Regione Friuli Venezia Giulia, con le modalità e gli strumenti software descritti nel Capitolo 2 e nel Capitolo 3. A riprova di questa affermazione si consiglia al lettore di collegarsi al bot, come indicato nel Capitolo 1, e di metterne alla prova il funzionamento. A tal proposito si ricorda che, essendo il progetto in sta- dio di sviluppo, potrebbero essere presenti delle funzionalità nuove, non descritte in questo documen- to, oppure leggermente diverse da quelle presentate. 4.3 Conclusioni soggettive Il lavoro svolto ha dato l’opportunità all’autore di ampliare la preparazione offerta dal corso di studi. È stata acquisita esperienza nell’utilizzo di strumenti software attuali e di ampia diffusione, come il linguaggio di programmazione Python, non affrontato nei corsi, il framework per applicazioni web Django, e l’RDBMS PostgreSQL. Certamente utile, in vista di futuri impegni lavorativi, è stato poi l’utilizzo della piattaforma per lo sviluppo condiviso GitHub. 42
  • 51. Per quanto riguarda il progetto nella sua totalità, si reputa molto formativo il fatto di aver seguito per intero il processo che ne ha portato alla realizzazione, e quindi di aver toccato con mano le problema- tiche legate a ciascuna fase. Alcune parole vanno infine spese sul fine del servizio realizzato, al di là dei tecnicismi legati all’informatica. Esso presenta un’evidente utilità sociale, in quanto aiuta gli utenti a rimanere aggior- nati riguardo le proposte di lavoro e di formazione. Ciò testimonia come la tecnologia possa avere un peso anche in ambiti più strettamente umanistici. È stato interessante aver toccato con mano l’impe- gno delle istituzioni, e in particolare della regione Friuli Venezia Giulia, nel fornire servizi ai residen- ti. 43
  • 52. 44
  • 53. Appendice A seguire i dati ricavati, in ns, per l’analisi delle prestazioni del metodo orm_get_telegram_user. # Senza l’utilizzo della cache Con l’utilizzo della cache Δt = 0 ms Δt = 50 ms Δt = 100 ms Δt = 0 ms Δt = 50 ms Δt = 100 ms 1 1433727 1110159 1696371 122681 40767 144883 2 1743860 1911706 2225748 101120 203543 201389 3 1549094 1766323 1746225 82185 246895 202922 4 1637040 1799094 1734373 66976 211268 191901 5 1289336 2457484 1741115 64371 206999 203353 6 1261202 1761574 1877352 71564 235433 207480 7 1285138 1733231 1765150 63249 204124 214042 8 1303092 1983602 1916476 77796 208993 202471 9 1309083 1764830 1859277 71515 248628 229642 10 1104038 1752327 1983702 62317 264468 248437 11 1286831 2160765 1703094 62116 260440 205266 12 2023277 1846724 1930191 60834 197050 218642 13 1526221 1739753 1768648 60955 202752 205978 14 1185911 1766183 1811949 60925 209595 245001 15 1049223 1940400 2040579 68298 203363 199325 16 1140335 1781341 1757667 61005 202872 239340 17 895555 1697494 1777144 62147 199636 207771 18 819932 1759871 1845863 112622 215045 201680 19 1039816 1786831 1736167 91593 228951 210055 20 1174279 1734052 1911225 103565 195808 202451 21 1051268 1816367 1721739 78147 244901 227508 22 1203995 2043704 1904573 93326 251434 205566 23 898340 1964185 2007096 92474 204645 224352 24 803020 1905966 1998600 69641 221076 265770 25 966488 1826877 1947775 65454 197682 204495 26 1409352 1843438 1869166 64211 205276 239972 27 1001564 1700640 1757866 64060 254239 201980 28 924689 2259661 2028155 64481 211267 202551 29 952622 1793054 1891959 64802 200237 203263 30 1163118 1758027 1998610 73088 254679 200628 31 917977 1779908 1779958 65353 246574 247085 32 899442 2062641 1936804 65072 202972 204756 33 895445 1800748 1673067 65854 202541 203302 34 1072448 1850722 1713152 65103 213391 201409 35 1035017 1887401 1748590 64842 205065 248748 36 1013798 1811969 2048644 65373 249740 245933 37 1182224 1718162 1732520 66395 205307 203963 38 1188977 1812811 1752106 72746 154140 203333 39 1202602 1719955 1952373 65563 244470 203543 40 1726708 2081626 1855019 68408 206218 201359 41 1077016 2000884 1680312 65002 203383 201028 42 902638 1783495 1832888 65182 275158 202541 43 1041699 1733692 1818711 69150 192192 203062 44 1087987 2076477 1825184 102352 189246 203062 45 1058251 1728683 1814454 69991 204235 256703 46 1115238 1876100 1835372 65393 197111 228479 47 1169420 1748349 1895086 70042 198995 254228 48 1184248 1953906 1879936 66946 195167 201078 49 1386990 1715377 1670242 66125 230173 202821 50 1117072 1736236 2039237 74941 204505 219924 51 1170302 2151347 1700098 66645 196179 200377 52 1622693 1838769 1743239 65564 243709 201620 45