Obiettivo del progetto¶
+Introduzione¶
Da fare
-Scrivere l’obiettivo generale del progetto.
+Lasciamo il tempo al futuro?
Scope¶
+Obiettivo¶
+L’obiettivo del progetto è la creazione di un software per fornire l’aggregazione e l’analisi di Tweet, in modo da +rilevare eventi macroscopici, locali o più semplicemente filtrarli in base a delle keyword.
+Il prodotto sarà utilizzato dal cliente e da un piccolo gruppo di suoi dipendenti per effettuare ricerche statistiche.
+Il software andrà ad integrarsi direttamente con Twitter, da cui verranno raccolti dati e su cui verranno pubblicate +allerte su di essi.
+Campo di applicazione¶
+Il software trova utilizzo principalmente in ambito statistico, essendo il suo scopo quello di raccogliere dati e +permettere di analizzarli tramite un’interfaccia grafica.
+Caratteristiche degli utenti¶
+Il software potrà essere utilizzato da utenti con una discreta esperienza nell’analisi di dati ma senza particolari +conoscenze informatiche.
+Glossario¶
+-
+
- Repository
Raccolta di tweet che soddisfano determinate condizioni.
+
+- Condizione
Predicato logico che deve essere soddisfatto da un tweet per essere raccolto in fase di raccolta dati, o per essere +contato in fase di allertamento utente.
+
+- Filtro
Predicato logico che deve essere soddisfatto da un tweet per essere visualizzato in fase di analisi dati.
+
+- Allarme
Notifica inviata all’utente attraverso un mezzo telematico, come email oppure un tweet.
+
+- Utente
Utilizzatore del software con un proprio account creato dall’amministratore della piattaforma.
+In particolare, la piattaforma prevederà due tipologie di utenti:
+-
+
- Utente regolare
Potranno eseguire attività di creazione, analisi, condivisione, archiviazione ed eliminazione dei propri repository.
+
+- Utente amministratore
Potrà effettuare tutte le attività dell’utente regolare, e in aggiunta potrà creare ed eliminare nuovi utenti +regolari.
+
+
+
Da fare
-Scrivere lo scope del progetto.
+Estendere il glossario qualora vengano incontrati altri termini.
Macro-funzionalità¶
+Il software permetterà di selezionare condizioni con cui scegliere quali tweet raccogliere:
+-
+
in base ai loro hashtag
+in base al loro autore
+in base alla loro posizione geografica (ove presente)
+in base alla loro data di pubblicazione
+
Selezionate le condizioni, l’utente potrà creare una repository: una cartella in cui verranno raccolti i tweet +soddisfacenti le condizioni richieste.
+Una volta raccolti, i tweet di una repository potranno essere analizzati in qualsiasi momento: durante l’analisi, +saranno mostrate statistiche e grafici relativi ai tweet.
+La raccolta potrà essere interrotta in qualsiasi momento archiviando il repository.
+Sarà possibile condividere una repository con altri utenti della piattaforma, permettendo loro di analizzarla.
+Infine, l’utente potrà configurare una repository in modo che gli invii una allerta qualora vengano raccolti un dato +numero di tweet in una certa finestra temporale.
+Casi d’uso¶
-Da fare
-Scrivere i casi d’uso del progetto.
-N.E.S.T. prevede tre tipologie di agenti («utenti» UML): utente, amministratore e sistema.
+![../_images/Utenti.png](../_images/Utenti.png)
I principali casi d’uso individuati durante la progettazione di N.E.S.T. sono:
+-
+
La gestione degli utenti da parte di un Amministratore:
++
+La gestione del login da parte di un Utente:
++
+La gestione delle Allerte sia dal punto di vista dell’Utente che del Sistema:
++
+La gestione della raccolta da parte dell’utente:
++
+La gestione di un repository da parte dell’utente:
++
+La visualizzazione di un repository:
++
+
Backlog generale¶
-Da fare
-Elencare qui tutte le user story del backlog, senza specificare lo sprint in cui sono state realizzate.
+Si riporta qui di seguito il Backlog definito ad inizio progetto, prima dell’avvio dello sviluppo. +Gli elementi dal bordo grigio sono le epiche:
+Nota
+Alcune user story sono state rimosse in seguito al feedback ricevuto durante il primo sprint!
Registro attività¶
-Questo registro attività delinea le attività effettuate dai membri del team e ne indica la durata.
-Nota
-Per informazioni più dettagliate sulle attività di sviluppo, si suggerisce di guardare il log dei commit di Git:
-nest:g2-progetto$ git log
-
Sprint 1: 19 Apr - 02 Mag¶
-Sprint 2: 03 Mag - 16 Mag¶
-Relazione sul progetto
-
-
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -106,6 +107,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
@@ -196,7 +198,7 @@ retrospettiva finale»
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr
- Consegna -
- Goal -
- Backlog -
- Definition of done +
- Definition of Ready +
- Definition of Done
- Registro attività
- Riunioni collettive
- Attività individuali
-
@@ -119,6 +119,8 @@
- Gitinspector
+ - Artefatti +
- Sprint review
- Sprint 1: 19 Apr - 02 Mag @@ -131,6 +133,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
@@ -203,10 +206,6 @@
La User Story è stata compresa ed accettata da tutti i membri
+I tester hanno confermato la possibilità di poterla testare
+Il Product Owner ha la visione necessaria per definirne la priorità
+Il Team è in grado di stimarla
+La User Story è indipendente o dipendente da altre a priorità maggiore
+Sviluppo completo della funzionalità richiesta
+Definizione e superamento dei test
+Bozza della documentazione della funzionalità
+Merge dei sorgenti nel branch
main
del repository Git
+-
+
- Goal +
Learn
+
+- Question +
Do team members understand the Scrum roles?
+
+- Metric +
Knowledge of Scrum roles by questions
+
+- Evaluation +
-
+
- 1 +
no idea of the Scrum roles
+
+- 5 +
perfect knowledge of the roles and their jobs
+
+
+- Chiara +
4
+
+- Giorgio +
4
+
+- Giovanni +
4
+
+- Stefano P. +
4
+
+- Lorenzo +
5
+
+- Stefano G. +
5
+
+- Flavia +
4
+
+
+-
+
- Goal +
Learn
+
+- Question +
Do team members feel they learned the process?
+
+- Metric +
Opinions from the participants
+
+- Evaluation +
-
+
- 1 +
couldn’t repeat the game
+
+- 5 +
could play the game as a Scrum Master by himself
+
+
+- Chiara +
3
+
+- Giorgio +
3
+
+- Giovanni +
4
+
+- Stefano P. +
5
+
+- Lorenzo +
3
+
+- Stefano G. +
3
+
+- Flavia +
3
+
+
+-
+
- Goal +
Learn
+
+- Question +
Does everyone keep up with the other players?
+
+- Metric +
Check during every sprint retrospective if every one is on point
+
+- Evaluation +
-
+
- 1 +
totally lost
+
+- 5 +
leads the game driving the other players
+
+
+- Chiara +
3
+
+- Giorgio +
4
+
+- Giovanni +
4
+
+- Stefano P. +
4
+
+- Lorenzo +
5
+
+- Stefano G. +
5
+
+- Flavia +
5
+
+
+-
+
- Goal +
Practice
+
+- Question +
Are the game mechanics linear and repeatable?
+
+- Metric +
Opinions from the participants
+
+- Evaluation +
-
+
- 1 +
feels the game is unrepeatable
+
+- 5 +
feels the game could be played in any situation
+
+
+- Chiara +
1
+
+- Giorgio +
2
+
+- Giovanni +
1
+
+- Stefano P. +
1
+
+- Lorenzo +
1
+
+- Stefano G. +
2
+
+- Flavia +
1
+
+
+-
+
- Goal +
Practice
+
+- Question +
Do team success in completing the game?
+
+- Metric +
Number of User Stories completed
+
+- Evaluation +
-
+
- 1 +
0 to 3 stories
+
+- 2 +
4 to 6
+
+- 3 +
7 to 9
+
+- 4 +
10 to 12
+
+- 5 +
13 to 15
+
+
+- Chiara +
5
+
+- Giorgio +
5
+
+- Giovanni +
5
+
+- Stefano P. +
5
+
+- Lorenzo +
5
+
+- Stefano G. +
5
+
+- Flavia +
5
+
+
+-
+
- Goal +
Practice
+
+- Question +
Do team members efficiently estimate during sprint planning?
+
+- Metric +
Uniformity in evaluating the size and the priority of user stories
+
+- Evaluation +
-
+
- 1 +
abnormal difference from the other players
+
+- 5 +
coherent and uniform with the group most of the time
+
+
+- Chiara +
5
+
+- Giorgio +
4
+
+- Giovanni +
5
+
+- Stefano P. +
4
+
+- Lorenzo +
5
+
+
+-
+
- Goal +
Cooperation
+
+- Question +
Do team members know each other better?
+
+- Metric +
Level of players” serenity throughout the game
+
+- Evaluation +
-
+
- 1 +
never speaks with the other players
+
+- 5 +
talks friendly to anyone in every situation
+
+
+- Chiara +
4
+
+- Giorgio +
5
+
+- Giovanni +
5
+
+- Stefano P. +
5
+
+- Lorenzo +
5
+
+- Stefano G. +
5
+
+- Flavia +
4
+
+
+-
+
- Goal +
Cooperation
+
+- Question +
Does the game let all players cooperate?
+
+- Metric +
Contribution of every player during the game
+
+- Evaluation +
-
+
- 1 +
never puts effort in doing something
+
+- 5 +
every time is willing to understand what is going on
+
+
+- Chiara +
4
+
+- Giorgio +
3
+
+- Giovanni +
3
+
+- Stefano P. +
2
+
+- Lorenzo +
3
+
+- Stefano G. +
4
+
+- Flavia +
3
+
+
+-
+
- Goal +
Cooperation
+
+- Question +
Do team member consult each other about a topic?
+
+- Metric +
Sharing of ideas
+
+- Evaluation +
-
+
- 1 +
never asks for an opinion
+
+- 5 +
wants to discuss about every topic
+
+
+- Chiara +
5
+
+- Giorgio +
5
+
+- Giovanni +
5
+
+- Stefano P. +
3
+
+- Lorenzo +
5
+
+- Stefano G. +
4
+
+- Flavia +
5
+
+
+-
+
- Goal +
Motivation
+
+- Question +
Do team members encourage collegues in need?
+
+- Metric +
Players explain something other players don’t understand
+
+- Evaluation +
-
+
- 1 +
not involved by the game
+
+- 5 +
always makes sure everyone is on point
+
+
+- Chiara +
3
+
+- Giorgio +
5
+
+- Giovanni +
5
+
+- Stefano P. +
4
+
+- Lorenzo +
5
+
+- Stefano G. +
4
+
+- Flavia +
4
+
+
+-
+
- Goal +
Motivation
+
+- Question +
Does PO help the team?
+
+- Metric +
Quality of PO’s advices to get better in the next sprints
+
+- Evaluation +
-
+
- 1 +
poor/absent advices
+
+- 5 +
wise and helpful suggestions when is required
+
+
+- Stefano G. +
4
+
+
+-
+
- Goal +
Motivation
+
+- Question +
Does the team come up with good ideas?
+
+- Metric +
Effectiveness of sprint retrospective
+
+- Evaluation +
-
+
- 1 +
doesn’t express opinions during retrospective
+
+- 5 +
feels the retrospective fundamental to express opinions
+
+
+- Chiara +
4
+
+- Giorgio +
5
+
+- Giovanni +
5
+
+- Stefano P. +
5
+
+- Lorenzo +
5
+
+- Stefano G. +
5
+
+- Flavia +
5
+
+
+-
+
- Goal +
Problem Solving
+
+- Question +
Do team members behave well when facing a problem?
+
+- Metric +
Level of the technical debt at the end of the game
+
+- Evaluation +
On the game board, if the debt pawn is on the lowest stage,the evaluation is 5, for every higher stage it decreases by 1
+
+- Chiara +
5
+
+- Giorgio +
5
+
+- Giovanni +
5
+
+- Stefano P. +
5
+
+- Lorenzo +
5
+
+- Stefano G. +
5
+
+- Flavia +
5
+
+
+-
+
- Goal +
Problem Solving
+
+- Question +
Does team organize their tasks properly?
+
+- Metric +
Average of tasks left at the end of each sprint
+
+- Evaluation +
-
+
- 1 +
21+ average tasks left
+
+- 2 +
16-20 average tasks left
+
+- 3 +
11-15 average tasks left
+
+- 4 +
6-10 average tasks left
+
+- 5 +
0-5 average tasks left
+
+
+- Chiara +
5
+
+- Giorgio +
5
+
+- Giovanni +
5
+
+- Stefano P. +
5
+
+- Lorenzo +
5
+
+
+-
+
- Goal +
Problem Solving
+
+- Question +
Does PO plan efficiently the Sprint Backlog?
+
+- Metric +
Average of tasks left at the end of each sprint
+
+- Evaluation +
-
+
- 1 +
21+ average tasks left
+
+- 2 +
16-20 average tasks left
+
+- 3 +
11-15 average tasks left
+
+- 4 +
6-10 average tasks left
+
+- 5 +
0-5 average tasks left
+
+
+- Stefano G. +
5
+
+
+- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -131,6 +132,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
diff --git a/docs/build/html/development/sprint2/index.html b/docs/build/html/development/sprint2/index.html
index 26a320c..4eaf074 100644
--- a/docs/build/html/development/sprint2/index.html
+++ b/docs/build/html/development/sprint2/index.html
@@ -13,6 +13,7 @@
+
@@ -92,7 +93,7 @@
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -131,6 +132,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
diff --git a/docs/build/html/development/sprint3/index.html b/docs/build/html/development/sprint3/index.html
index 690d37e..5f29858 100644
--- a/docs/build/html/development/sprint3/index.html
+++ b/docs/build/html/development/sprint3/index.html
@@ -13,6 +13,7 @@
+
@@ -92,7 +93,7 @@
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -132,6 +133,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
diff --git a/docs/build/html/development/suggestions.html b/docs/build/html/development/suggestions.html
index 705775b..2adfe7b 100644
--- a/docs/build/html/development/suggestions.html
+++ b/docs/build/html/development/suggestions.html
@@ -13,6 +13,7 @@
+
@@ -92,7 +93,7 @@
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -106,6 +107,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
diff --git a/docs/build/html/development/tools.html b/docs/build/html/development/tools.html
index 3b90119..d1f9763 100644
--- a/docs/build/html/development/tools.html
+++ b/docs/build/html/development/tools.html
@@ -13,6 +13,7 @@
+
@@ -92,7 +93,7 @@
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -106,6 +107,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
@@ -215,6 +217,15 @@ il miglioramento della qualità del codice del progetto.
Documentazione tecnica
Sprint 0: 04 Apr - 18 Apr¶
--Da fare
-Inserire informazioni generali sullo sprint, come inizio e fine.
-Consegna¶
La seguente documentazione è stata fornita dal cliente durante questo sprint:
@@ -215,26 +214,27 @@--Goal¶
---Da fare
-Inserire qui lo sprint goal.
--+Backlog¶
--+Da fare
-Mostrare qui lo sprint backlog di Taiga.
-+Definition of Ready¶
+Il team ha definito lo stato di Ready di una User Story in base ai seguenti criteri:
+-
+
-Definition of done¶
--+Da fare
-Inserire qui la definition of done dello sprint.
-Definition of Done¶
+La definizione di Done è stata concordata da tutto il team con il Product Owner, ed è stata così +definita:
+-
+
Risultati della partita di Scrumble¶
--+Da fare
-Trascrivere qui i risultati della partita di Scrumble.
--
+
Statistiche¶
@@ -552,10 +1167,24 @@Questa statistica è stata generata dal prof. Marcello Missiroli con Gitinspector al termine dello Sprint.
++Artefatti¶
+In questo sprint è stato realizzato il seguente documento:
+ ++Sprint review¶
+Il video di sprint review è disponibile al seguente link:
+ +Relazione sul progetto
-
-
Documentazione tecnica
Relazione sul progetto
-
-
Documentazione tecnica
Relazione sul progetto
-
-
Documentazione tecnica
Relazione sul progetto
-
-
Documentazione tecnica
Relazione sul progetto
-
-
Documentazione tecnica
È accessibile al seguente indirizzo: https://sonarqube.steffo.eu/
Documentazione tecnica
Relazione sul progetto
-
-
++ +Applicazione web centralizzata per la creazione collaborativa di interfacce grafiche moderne.
+
+Piattaforma centralizzata di messaggistica istantanea e chiamate vocali utilizzata per la comunicazione sincrona +tra i membri del team.
+
Relazione sul progetto
-
-
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -104,6 +105,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
@@ -232,8 +234,12 @@
- aid (nest_backend.database.tables.MadeOf attributo) -
- Alert (classe in nest_backend.database.tables) +
- Alert (classe built-in) + +
- alert (nest_backend.database.tables.MadeOf attributo)
-
@@ -255,11 +261,21 @@
- all_or (nest_backend.database.tables.ConditionMode attributo)
- assign (nest_backend.database.tables.OperationType attributo) + +
- associate_condition_tweet() (nel modulo nest_crawler)
- authenticate() (nel modulo nest_backend.gestione) + + +
- Authorization (classe built-in) + +
- authorizations (nest_backend.database.tables.Repository attributo)
-
@@ -278,10 +294,18 @@
- (nest_backend.database.tables.MadeOf attributo)
- - Composed (classe in nest_backend.database.tables) +
- Composed (classe built-in) + + +
- Condition (classe built-in) + +
- condition (nest_backend.database.tables.Contains attributo)
-
@@ -302,8 +326,12 @@
- ConditionType (classe in nest_backend.database.tables) -
- Contains (classe in nest_backend.database.tables) +
- Contains (classe built-in) + +
- content (nest_backend.database.tables.Condition attributo)
-
@@ -380,15 +408,21 @@
- (nest_backend.database.tables.Repository attributo)
-
+ - insert_time (nest_backend.database.tables.Tweet attributo)
- is_active (nest_backend.database.tables.Repository attributo) + +
- is_coordinate_inside_bounding_box() (nel modulo nest_crawler) + +
- is_deleted (nest_backend.database.tables.Repository attributo) + +
- is_repo_alert_triggered() (nel modulo nest_crawler)
- isAdmin (nest_backend.database.tables.User attributo) @@ -428,8 +462,12 @@
- MadeOf (classe in nest_backend.database.tables) +
- MadeOf (classe built-in) + +
- modulo @@ -503,8 +541,12 @@
- modulo
- Notification (classe in nest_backend.database.tables) +
- Notification (classe built-in) + +
- notifications (nest_backend.database.tables.Alert attributo)
- repositories (nest_backend.database.tables.Tweet attributo) -
- Repository (classe in nest_backend.database.tables) +
- Repository (classe built-in) + +
- repository (nest_backend.database.tables.Alert attributo)
-
@@ -586,6 +632,14 @@
- Tweet (classe in nest_backend.database.tables) +
- Tweet (classe built-in) + +
- tweet (nest_backend.database.tables.Composed attributo)
-
@@ -647,16 +703,20 @@
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -110,6 +111,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
diff --git a/docs/build/html/guide/installation.html b/docs/build/html/guide/installation.html
index a00fd2d..5fbbe6c 100644
--- a/docs/build/html/guide/installation.html
+++ b/docs/build/html/guide/installation.html
@@ -13,6 +13,7 @@
+
@@ -39,7 +40,7 @@
-
+
@@ -107,7 +108,7 @@
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -121,6 +122,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
@@ -474,7 +476,7 @@ esempio da adattare al proprio setup:
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -105,6 +106,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
@@ -207,8 +209,12 @@
- Obiettivo del progetto
-
-
- Scope +
- Introduzione @@ -217,12 +223,13 @@
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr
- Sprint 1: 19 Apr - 02 Mag
-
@@ -273,6 +280,7 @@
- Compilazione con Windows Powershell
+ - Struttura del database
nest_backend
- Web API in Python.gestione
- Metodi di utility.database
- Database-
@@ -287,6 +295,12 @@
nest_frontend
- Interfaccia utente in React
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -107,6 +108,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
diff --git a/docs/build/html/search.html b/docs/build/html/search.html
index da2d16d..3e5be15 100644
--- a/docs/build/html/search.html
+++ b/docs/build/html/search.html
@@ -13,6 +13,7 @@
+
@@ -93,7 +94,7 @@
- Obiettivo del progetto +
- Introduzione
- Processo di sviluppo
- Strumenti utilizzati
- Sprint 0: 04 Apr - 18 Apr @@ -107,6 +108,7 @@
- Meta-documentazione +
- Struttura del database
nest_backend
- Web API in Pythonnest_crawler
- Crawler in Pythonnest_frontend
- Interfaccia utente in React
diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js
index 3227c3c..7d4cc50 100644
--- a/docs/build/html/searchindex.js
+++ b/docs/build/html/searchindex.js
@@ -1 +1 @@
-Search.setIndex({docnames:["code/backend/index","code/crawler/index","code/frontend/index","code/meta/index","development/artifacts","development/conclusions","development/goals","development/log","development/process","development/sprint0/index","development/sprint1/index","development/sprint2/index","development/sprint3/index","development/suggestions","development/tools","guide/about","guide/installation","index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,"sphinx.ext.todo":2,sphinx:56},filenames:["code/backend/index.rst","code/crawler/index.rst","code/frontend/index.rst","code/meta/index.rst","development/artifacts.rst","development/conclusions.rst","development/goals.rst","development/log.rst","development/process.rst","development/sprint0/index.rst","development/sprint1/index.rst","development/sprint2/index.rst","development/sprint3/index.rst","development/suggestions.rst","development/tools.rst","guide/about.rst","guide/installation.rst","index.rst"],objects:{"":{nest_backend:[0,0,0,"-"],nest_crawler:[1,0,0,"-"]},"nest_backend.database":{base:[0,0,0,"-"],tables:[0,0,0,"-"]},"nest_backend.database.tables":{Alert:[0,1,1,""],Authorization:[0,1,1,""],Composed:[0,1,1,""],Condition:[0,1,1,""],ConditionMode:[0,1,1,""],ConditionType:[0,1,1,""],Contains:[0,1,1,""],MadeOf:[0,1,1,""],Notification:[0,1,1,""],OperationType:[0,1,1,""],Repository:[0,1,1,""],Tweet:[0,1,1,""],User:[0,1,1,""]},"nest_backend.database.tables.Alert":{__init__:[0,2,1,""],conditions:[0,3,1,""],evaluation_mode:[0,3,1,""],id:[0,3,1,""],limit:[0,3,1,""],name:[0,3,1,""],notifications:[0,3,1,""],repository:[0,3,1,""],repository_id:[0,3,1,""],to_json:[0,2,1,""],window_size:[0,3,1,""]},"nest_backend.database.tables.Authorization":{__init__:[0,2,1,""],email:[0,3,1,""],repository:[0,3,1,""],rid:[0,3,1,""],to_json:[0,2,1,""],user:[0,3,1,""]},"nest_backend.database.tables.Composed":{__init__:[0,2,1,""],repository:[0,3,1,""],rid:[0,3,1,""],snowflake:[0,3,1,""],tweet:[0,3,1,""]},"nest_backend.database.tables.Condition":{__init__:[0,2,1,""],alerts:[0,3,1,""],content:[0,3,1,""],id:[0,3,1,""],repository:[0,3,1,""],repository_id:[0,3,1,""],to_json:[0,2,1,""],tweets:[0,3,1,""],type:[0,3,1,""]},"nest_backend.database.tables.ConditionMode":{all_and:[0,3,1,""],all_or:[0,3,1,""]},"nest_backend.database.tables.ConditionType":{coordinates:[0,3,1,""],hashtag:[0,3,1,""],location:[0,3,1,""],place:[0,3,1,""],time:[0,3,1,""],user:[0,3,1,""]},"nest_backend.database.tables.Contains":{__init__:[0,2,1,""],cid:[0,3,1,""],condition:[0,3,1,""],snowflake:[0,3,1,""],tweet:[0,3,1,""]},"nest_backend.database.tables.MadeOf":{__init__:[0,2,1,""],aid:[0,3,1,""],alert:[0,3,1,""],cid:[0,3,1,""],condition:[0,3,1,""]},"nest_backend.database.tables.Notification":{__init__:[0,2,1,""],alert:[0,3,1,""],alert_id:[0,3,1,""],id:[0,3,1,""],ora:[0,3,1,""],to_json:[0,2,1,""]},"nest_backend.database.tables.OperationType":{assign:[0,3,1,""]},"nest_backend.database.tables.Repository":{__init__:[0,2,1,""],alerts:[0,3,1,""],authorizations:[0,3,1,""],conditions:[0,3,1,""],end:[0,3,1,""],evaluation_mode:[0,3,1,""],id:[0,3,1,""],is_active:[0,3,1,""],name:[0,3,1,""],owner:[0,3,1,""],owner_id:[0,3,1,""],start:[0,3,1,""],to_json:[0,2,1,""],tweets:[0,3,1,""]},"nest_backend.database.tables.Tweet":{__init__:[0,2,1,""],conditions:[0,3,1,""],content:[0,3,1,""],image_url:[0,3,1,""],insert_time:[0,3,1,""],location:[0,3,1,""],place:[0,3,1,""],post_time:[0,3,1,""],poster:[0,3,1,""],repositories:[0,3,1,""],snowflake:[0,3,1,""],to_json:[0,2,1,""]},"nest_backend.database.tables.User":{__init__:[0,2,1,""],authorizations:[0,3,1,""],email:[0,3,1,""],isAdmin:[0,3,1,""],owner_of:[0,3,1,""],password:[0,3,1,""],to_json:[0,2,1,""],username:[0,3,1,""]},"nest_backend.gestione":{admin_or_403:[0,4,1,""],authenticate:[0,4,1,""],error_handler:[0,4,1,""],find_user:[0,4,1,""],gen_password:[0,4,1,""],hashtag_validator:[0,4,1,""],identity:[0,4,1,""],json_error:[0,4,1,""],json_request_authorizer:[0,4,1,""],json_success:[0,4,1,""],repository_auth:[0,4,1,""]},nest_backend:{database:[0,0,0,"-"],gestione:[0,0,0,"-"]}},objnames:{"0":["py","module","Python modulo"],"1":["py","class","Python classe"],"2":["py","method","Python metodo"],"3":["py","attribute","Python attributo"],"4":["py","function","Python funzione"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:function"},terms:{"00m":11,"10h":[9,10,11],"10m":[10,11],"11h":11,"11m":11,"127":16,"12m":10,"13h":10,"13m":[10,11],"14m":10,"15h":9,"15m":[10,11],"16h":[10,11],"16m":10,"17h":11,"17m":11,"18m":[10,11],"19h":11,"19m":10,"2021":[9,10,11,15],"206":17,"20m":11,"214":17,"21m":11,"222":17,"23h":[9,10],"23m":10,"248":16,"25m":11,"26m":10,"275":17,"27h":11,"283":17,"28m":10,"291":17,"29h":10,"29m":[10,11],"30040":16,"30041":16,"301":16,"30m":[9,10,11],"32m":10,"34m":[10,11],"35m":[9,10],"36m":10,"39m":[9,11],"40m":11,"429":17,"42m":10,"443":16,"44m":11,"45m":11,"46m":10,"47m":11,"48m":10,"492":17,"51m":11,"52m":9,"56m":10,"57m":11,"58m":10,"59m":10,"63072000":16,"7c2fm2vd":16,"class":0,"else":0,"enum":0,"final":[8,17],"for":0,"function":0,"gi\u00e0":[8,10,17],"return":0,"static":14,"this":[0,16],"var":[10,16],Che:[13,17],Nello:14,Noi:15,Non:[4,17],None:0,Per:[7,10,16],Una:[3,15,16],__init__:0,abbiam:[8,17],abil:16,access:14,according:0,acme:16,actually:0,adatt:16,adds:0,adegu:[10,11],admin_or_403:0,after:16,age:16,aggiunt:[10,11],aggreg:10,aid:0,alcun:[11,16],alert:[0,11],alert_id:0,alerts:[0,9],all_and:0,all_or:0,allowed:0,allows:0,almen:3,alon:0,altre:10,altrov:[8,17],always:16,ambient:[10,11],amministr:16,analis:[9,10,14],ancor:[12,17],and:0,andat:[5,17],andrann:11,any:0,apac:17,api:[10,11,15,16,17],app:16,applic:[14,15],application:0,appost:16,approcc:11,apr:17,arch:16,are:0,artefatt:17,artifacts:17,assign:0,attiv:[16,17],attravers:[15,16,17],attributes:0,autent:[10,15],authentic:0,authentication:0,authorization:0,authorizations:0,automat:[14,16],autorizz:15,aver:16,avet:[5,13,17],avvi:16,backend:[10,15,17],background:16,backlog:17,bas:[10,17],based:16,bash:16,basic:3,bat:3,becaus:0,ben:[5,17],benven:17,bin:16,bisogn:[4,17],brainstorming:9,brev:17,bug:11,bugfixing:[10,11],build:[3,16],burndown:[8,17],cach:16,camb:[5,17],cancell:10,cap:10,cartell:[3,16],cas:[16,17],cases:[9,10],casual:16,cattur:11,cer:16,checks:0,chiam:10,chiav:10,chown:16,cid:0,classes:0,client:[9,10,11,12],clon:16,cod:[0,17],codic:[10,11,14,17],collabor:10,columns:0,com:[3,9,10,11,12,17],comand:16,combination:0,commit:7,compil:[12,17],compless:[8,10,16,17],complet:11,component:9,composed:0,compost:15,comprens:15,comun:15,conclusion:[11,17],conclusions:17,condition:0,conditionmod:0,conditions:[0,11],conditiontyp:0,condizion:[10,11,15],config:16,configur:[9,10,11,17],configuration:3,connession:16,consegn:17,consigl:16,constructed:0,constructor:0,contains:0,conten:16,content:0,continuous:3,controll:[10,14],coordinates:0,cop:16,cor:16,correct:0,corrett:16,correzion:11,cors:[10,15,17],cos:[3,4,5],costant:16,could:0,coverag:[11,14],crawler:17,cre:17,createdb:16,createuser:16,creating:16,creazion:[9,10],credentials:0,css:9,curl:16,dar:[13,17],dark:9,dashboard:[9,11],dat:[0,3,9,10,11,12,15,16],databas:[9,10,11,15,17],dbms:16,deb:10,decl_ap:0,declar:0,definit:9,definition:17,definizion:10,deline:7,dem:[11,16,17],denomin:16,depends:0,description:16,descriv:[8,17],descrizion:9,design:9,dettagl:[7,16],development:17,diagramm:9,diar:[8,17],dipendent:[3,11,17],dir:16,directory:[3,16],dirett:16,discord:9,discussion:11,dispon:[3,11,16],disponessim:3,distribu:16,divers:10,doa:16,docs:[3,16,17],document:[9,10,11,12,14],documentation:3,don:17,dop:16,doppiagg:9,dovr:16,dovrebb:16,dsjiofgvinmodfiojvbnio3erfnoiweraqugu43ghjwrevniuwerng43iugnreuwignhritmj43i43nb8i42ug0wevkwovmwigtjj:16,dur:[7,8,9,10,11,12,17],durant:[9,10,11,12],edit:16,effettu:[7,10],efficent:10,elabor:15,elenc:[6,9,17],elimin:10,email:0,enabl:16,end:0,engines:16,entit:10,entrarv:16,entri:3,enumeration:0,env:16,environment:[3,16],epic:9,error:[0,10],error_handler:0,errorunknownerror:0,esam:15,esecu:[14,16,17],esegu:[3,16],esemp:[10,16],espost:16,esse:10,esser:16,estension:17,estraiam:15,evaluation_mod:0,exampl:0,exec:16,execstart:16,explorer:10,expr:16,ext4:17,fact:0,fallimentar:11,fancy:0,farl:16,figm:9,fil:17,fin:[9,10,11,12,16,17],finc:16,find_user:0,fix:[10,11],fixtures:11,flask:[15,17],flask_config:16,forc:16,form:15,format:0,formatted:0,forn:[9,10,11,12,15,16],forwarded:16,foss:3,fram:9,framework:15,from:0,frontend:[10,11,17],full:16,fullchain:16,funzion:10,futur:15,gen_password:0,gener:[3,8,9,10,11,12,16,17],general:[9,10,11,12,17],generates:0,geolocalizz:[10,11],gest:[15,16],gestion:[10,17],giorn:14,git:[7,14,16],github:3,gitlab:[0,9,11,14,16],gnu:17,goal:17,goals:17,gratuit:11,graz:10,grooming:10,group:16,grupp:[8,17],guard:7,guid:[16,17],gunicorn:16,happy:0,hash:0,hashed:0,hashtag:[0,10],hashtag_validator:0,header:16,hom:16,hosted:14,hosting:14,html:[3,16],http:[15,16],http_host:16,https:[14,16],ide:[4,10,14,17],identity:0,illustr:16,image_url:0,immediat:15,impar:[5,17],impieg:9,implement:10,imports:0,impost:16,includ:[8,17],incontr:11,index:17,indic:[7,17],indirizz:[14,16],inerent:10,infin:3,info:10,inform:[7,9,10,11,12,16,17],informat:15,initialization:0,iniz:[9,10,11,12,17],inizial:9,inser:[4,9,10,11,12,16,17],insert_tim:0,install:[3,17],installation:17,instanc:0,integr:[3,11,16],intellij:[10,14,17],inter:16,interfacc:17,intern:[3,15,16],internet:16,interv:9,inutil:10,is_act:0,isadmin:0,isol:16,issu:11,issues:11,ital:11,its:0,json:[0,10,16],json_error:0,json_request_authorizer:0,json_success:0,jsx:15,jwt:[0,16],key:16,keys:0,kwargs:0,lasc:11,lavor:10,leg:10,librer:16,licenz:3,light:9,limit:[0,10],line:17,link:[4,8,10,11,17],linux:[3,16],littl:0,local:[10,16],location:0,log:[7,9],logg:10,login:[0,10],lookup:16,loopback:16,madeof:0,mag:17,maggior:16,mak:17,makefil:3,manag:10,management:[9,10,11,14],manipol:15,manten:16,manual:[3,16],many:0,mapped:0,marcell:[9,10,11,12,17],matc:0,max:16,membr:7,mentr:3,messag:0,met:17,method:0,metod:[10,17],mett:[8,17],miglior:[10,14],missirol:[9,10,11,12,13,17],mkdir:16,mnt:17,mockup:[9,10,11],mod:[9,10,16],model:0,modic:10,modif:[10,11,14],modul:[0,10,17],molt:16,moment:10,mostr:[9,10,11,12,15,17],mot:16,msg:0,mult:16,multilinguagg:14,nam:0,names:0,necess:16,necessar:[3,16],needs:0,nest:[7,16],nest_backend:[15,16,17],nest_crawler:[15,17],nest_frontend:[15,17],network:16,node_env:16,node_modules:16,node_version:16,nodejs:17,nom:[10,16],not:0,notification:0,notifications:[0,9],npm:16,nss:16,numer:[8,17],nuov:[11,17],nvm:16,oauth:10,obiett:17,onlin:16,only:0,oper:16,operation:0,operationtyp:0,ora:[0,9,10,11,12,16],org:16,organizz:10,original:17,orm:0,ospit:[3,14],ottimizz:16,output:10,owner:[0,16],owner_id:0,owner_of:0,pacchett:16,pagin:9,pair:10,param:0,parametr:3,parents:16,parol:10,part:[10,14,15,17],partecip:[8,17],particol:3,pass:11,password:0,payload:0,penpot:9,perc:[11,16],percors:[16,17],permett:3,pertant:16,piccol:11,pien:16,plac:0,place_id:11,planning:9,platform:0,plugin:10,poetry:[3,16],poi:3,poker:9,port:16,porting:11,poss:16,possibil:[3,16],post_tim:0,poster:0,postgres:16,postgresql:16,poter:10,powershell:17,precedent:16,predisposizion:10,preferibil:16,prem:16,prepar:11,prerequis:17,present:[0,9,10,15],prim:[3,9,10,11,16],principal:10,process:17,prod:16,prodott:9,production:16,prof:[9,10,11,12,13,17],progett:[3,7,9,10,14,16],programming:10,project:[9,10,11,14],propr:16,propriet:10,prosegu:16,prot:16,protocols:16,prov:10,proxy:17,proxypass:16,proxypassrevers:16,pubblic:[11,16],put:11,py3:16,pypoetry:16,pytest:11,python:[3,15,17],qual:[11,16],qualit:14,qualor:3,quant:16,quel:10,quell:10,query:11,quest:[3,7,9,10,11,12,16],qui:[4,6,9,10,11,12,17],raccogl:9,rappresent:16,react:[15,17],readthedocs:3,realizz:[6,10,11,15,17],recuper:15,recurs:16,ref:[8,17],refactor:10,refactoring:[10,11,14],registered:0,registr:17,relat:[3,9,17],relationships:0,relazion:10,rend:16,rep:10,report:12,repositories:[0,9],repository:[0,10,11,14],repository_auth:0,repository_id:0,reqest:0,request_schem:16,requestheader:16,required:0,resocont:9,rest:16,restitu:10,restructuredtext:3,ret:16,retrieval:10,retrospect:[10,11],retrospett:[8,11,17],returned:0,returns:0,revers:17,review:17,rewriteengin:16,rewriterul:16,riavv:16,ricerc:10,richiest:10,ricord:16,rid:0,rig:[16,17],riguard:10,rimang:16,rimozion:10,ripet:[16,17],risolt:11,risolu:11,risult:17,ritocc:[9,10],ritorn:[10,11],riusc:11,root:16,routes:17,rp_app:16,rst:17,run:[3,16],ruol:16,salv:[15,16],sar:16,scanner:11,scaric:17,scherm:17,scop:17,screenshot:[12,17],screenshots:17,script:[3,16],scritt:[3,10,15],scrittur:[10,14],scriv:[4,5,6,16,17],scrumbl:17,second:15,secret_key:16,security:16,see:16,segnal:11,segret:16,segu:[8,17],seguent:[9,10,11,12,14,16],self:14,senz:[6,17],serializabl:0,serv:16,server:[0,15,16],servernam:16,servic:16,serviz:17,session:[10,11],set:16,sets:0,setting:11,settings:9,setup:[11,16],shar:9,shell:[3,16],shouldnt:0,sicurezz:16,simpl:0,sint:16,sistem:[3,16],sit:10,snowflak:0,softw:[14,15],sol:[8,16,17],son:[6,14,16,17],sonarqub:[9,10,11,14,17],sorgent:[3,17],sostitu:16,sourc:[3,17],spec:0,specif:[0,9],specific:[6,10,17],sphinx:3,sprint0:17,sprint1:[10,17],sprint2:[11,17],sprint3:17,sprint:[6,8,17],sqlalchemy:[0,16],sqlalchemy_database_ur:16,srs:9,srv:16,sslcertificatefil:16,sslcertificatekeyfil:16,sslengin:16,standard:3,standardizz:10,start:[0,16],stat:[6,9,10,11,12,14,16,17],statist:[15,17],steff:[14,16],stess:16,stesur:[9,10],stories:9,story:[6,17],strict:16,string:[0,16],strument:[3,17],struttur:[3,10],stud:10,success:16,successful:0,such:0,suddivision:17,sugger:[7,8,16,17],suggestions:17,support:10,svilupp:[7,10,11,14,17],svolt:10,swagger:11,system:0,systemctl:16,systemd:17,tabell:17,tables:17,taig:[9,10,11,12,14,17],talvolt:16,target:[3,16],tast:16,tastier:16,team:[7,10,11],tecnic:10,temp:9,tentat:11,ter:17,termin:[9,10,11],test:[10,11,16],testing:[10,11,14],tests:11,that:0,the:[0,16],thes:0,thing:0,thingamajigs:0,tim:0,timer:17,tip:10,to_json:0,tod:12,token:16,total:[9,10,11,12],tracc:14,traduzion:11,tram:[10,16],transport:16,trascriv:[9,17],tre:15,trov:[3,17],tutt:[6,10,14,16,17],tweepy:15,tweet:[0,10,11,15],tweets:0,twitter:[9,10,15],type:[0,16],ulterior:11,ultim:[3,9,10,14],unimor:15,unit:16,usa:16,usand:[8,15,17],usat:14,use:9,used:0,user:[0,3,6,9,10,11,16,17],useradd:16,usernam:0,users:[10,11],using:0,uso:[16,17],usr:16,utent:[10,11,15],utility:17,utilizz:[10,11,16,17],valid:0,valu:0,values:0,valut:11,variabil:16,ved:[0,16],ven:10,veng:16,venv:[3,16],verif:16,verification:0,verr:16,version:[3,9,11,14,16],vide:[4,9,10,11,17],vim:16,virtual:3,virtualenv:16,virtualenvs:16,virtualhost:16,vist:[8,17],visualizz:[14,15],volt:[3,10],want:0,wantedby:16,wants:16,was:0,web:[14,15,16,17],whether:0,window_siz:0,windows:17,working:16,workingdirectory:16,you:[0,16]},titles:["
U
+ - diff --git a/docs/build/html/guide/about.html b/docs/build/html/guide/about.html index b59ad5c..282ce11 100644 --- a/docs/build/html/guide/about.html +++ b/docs/build/html/guide/about.html @@ -13,6 +13,7 @@ + @@ -96,7 +97,7 @@ Relazione sul progetto
-
-
Documentazione tecnica
Relazione sul progetto
-
-
Documentazione tecnica
Relazione sul progetto
-
-
Documentazione tecnica
Relazione sul progetto
-
-
+Cose rimaste da fare¶
@@ -309,24 +323,14 @@(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/conclusions.rst, linea 4.)
Da fare
-Scrivere l’obiettivo generale del progetto.
+Lasciamo il tempo al futuro?
(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/goals.rst, linea 4.)
Da fare
-Scrivere lo scope del progetto.
+Estendere il glossario qualora vengano incontrati altri termini.
(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/goals.rst, linea 12.)
---Da fare
-Scrivere i casi d’uso del progetto.
-(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/goals.rst, linea 20.)
---Da fare
-Elencare qui tutte le user story del backlog, senza specificare lo sprint in cui sono state realizzate.
-(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/goals.rst, linea 28.)
+(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/goals.rst, linea 64.)
Da fare
Descrivere genericamente il processo di sviluppo seguito, includendo:
@@ -341,31 +345,6 @@ retrospettiva finale»Da fare
Inserire informazioni generali sullo sprint, come inizio e fine.
(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/sprint0/index.rst, linea 4.)
---Da fare
-Inserire qui lo sprint goal.
-(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/sprint0/index.rst, linea 21.)
---Da fare
-Mostrare qui lo sprint backlog di Taiga.
-(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/sprint0/index.rst, linea 29.)
---Da fare
-Inserire qui la definition of done dello sprint.
-(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/sprint0/index.rst, linea 37.)
---Da fare
-Trascrivere qui i risultati della partita di Scrumble.
-(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/sprint0/index.rst, linea 275.)
--Da fare
-Inserire informazioni generali sullo sprint, come inizio e fine.
-(L'riga originale si trova in /mnt/tera/ext4/code/g2-progetto-2/docs/source/development/sprint1/index.rst, linea 4.)
Da fare
diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv index dcdde76..8ba9a80 100644 Binary files a/docs/build/html/objects.inv and b/docs/build/html/objects.inv differ diff --git a/docs/build/html/py-modindex.html b/docs/build/html/py-modindex.html index 13d847c..5810762 100644 --- a/docs/build/html/py-modindex.html +++ b/docs/build/html/py-modindex.html @@ -13,6 +13,7 @@ + @@ -93,7 +94,7 @@Relazione sul progetto
-
-
Documentazione tecnica
Relazione sul progetto
-
-
Documentazione tecnica
nest_backend
- Web API in Python","nest_crawler
- Crawler in Python","nest_frontend
- Interfaccia utente in React","Meta-documentazione","Artefatti","Conclusioni","Obiettivo del progetto","Registro attivit\u00e0","Processo di sviluppo","Sprint 0: 04 Apr - 18 Apr","Sprint 1: 19 Apr - 02 Mag","Sprint 2: 03 Mag - 16 Mag","Sprint 3: 17 Mag - 30 Mag","Suggerimenti relativi al corso","Strumenti utilizzati","Il progetto in breve","Installazione","N.E.S.T."],titleterms:{"final":12,altri:17,anniball:[9,10,11,12],apac:16,api:0,apr:[7,9,10],artefatt:4,attiv:[7,9,10,11,12],backend:16,backlog:[6,9,10,11,12],balugan:[9,10,11,12],bas:0,brev:15,calzolar:[9,10,11,12],cas:6,chiar:[9,10,11,12],cocc:[9,10,11,12],codic:16,colleg:17,collett:[9,10,11,12],com:16,compil:[3,16],conclusion:5,configur:16,consegn:[9,10,11,12],cors:13,cos:17,crawler:[1,16],cre:16,databas:[0,16],definition:[9,10,11,12],dem:4,dipendent:16,document:[3,17],don:[9,10,11,12],estension:0,far:[4,5,6,8,9,10,11,12,13,16,17],fil:16,flask:0,flav:[9,10,11,12],frontend:16,general:6,gestion:0,giorg:[9,10,11,12],giovann:[9,10,11,12],gitinspector:[9,10,11,12],gnu:3,goal:[9,10,11,12],goldon:[9,10,11,12],ide:3,individual:[9,10,11,12],install:16,intellij:3,interfacc:2,lorenz:[9,10,11,12],mag:[7,10,11,12],mak:3,manual:17,met:3,metod:0,minoccar:[9,10,11,12],modul:15,nest_backend:0,nest_crawler:1,nest_frontend:2,nodejs:16,nuov:16,obiett:6,part:9,percors:0,pigozz:[9,10,11,12],powershell:3,prerequis:16,process:8,progett:[6,15,17],proxy:16,python:[0,1,16],react:2,registr:[7,9,10,11,12],relat:13,relazion:17,retrospett:12,revers:16,review:[10,11],rimast:17,risult:9,riunion:[9,10,11,12],routes:0,scaric:16,scherm:12,scop:6,screenshots:15,scrumbl:9,serviz:16,sonarqub:12,sorgent:16,sprint:[7,9,10,11,12],statist:[9,10,11,12],stef:[9,10,11,12],strument:14,suddivision:15,sugger:13,svilupp:8,systemd:16,tabell:0,tables:0,tecnic:17,timer:16,uso:6,utent:[2,16,17],utility:0,utilizz:14,web:0,windows:3}}) \ No newline at end of file +Search.setIndex({docnames:["code/backend/index","code/crawler/index","code/database/index","code/frontend/index","code/meta/index","development/artifacts","development/conclusions","development/goals","development/process","development/sprint0/index","development/sprint1/index","development/sprint2/index","development/sprint3/index","development/suggestions","development/tools","guide/about","guide/installation","index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,"sphinx.ext.todo":2,sphinx:56},filenames:["code/backend/index.rst","code/crawler/index.rst","code/database/index.rst","code/frontend/index.rst","code/meta/index.rst","development/artifacts.rst","development/conclusions.rst","development/goals.rst","development/process.rst","development/sprint0/index.rst","development/sprint1/index.rst","development/sprint2/index.rst","development/sprint3/index.rst","development/suggestions.rst","development/tools.rst","guide/about.rst","guide/installation.rst","index.rst"],objects:{"":{Alert:[2,0,1,""],Authorization:[2,0,1,""],Composed:[2,0,1,""],Condition:[2,0,1,""],Contains:[2,0,1,""],MadeOf:[2,0,1,""],Notification:[2,0,1,""],Repository:[2,0,1,""],Tweet:[2,0,1,""],User:[2,0,1,""],nest_backend:[0,1,0,"-"],nest_crawler:[1,1,0,"-"]},"nest_backend.database":{base:[0,1,0,"-"],tables:[0,1,0,"-"]},"nest_backend.database.tables":{Alert:[0,0,1,""],Authorization:[0,0,1,""],Composed:[0,0,1,""],Condition:[0,0,1,""],ConditionMode:[0,0,1,""],ConditionType:[0,0,1,""],Contains:[0,0,1,""],MadeOf:[0,0,1,""],Notification:[0,0,1,""],OperationType:[0,0,1,""],Repository:[0,0,1,""],Tweet:[0,0,1,""],User:[0,0,1,""]},"nest_backend.database.tables.Alert":{__init__:[0,2,1,""],conditions:[0,3,1,""],evaluation_mode:[0,3,1,""],id:[0,3,1,""],limit:[0,3,1,""],name:[0,3,1,""],notifications:[0,3,1,""],repository:[0,3,1,""],repository_id:[0,3,1,""],to_json:[0,2,1,""],window_size:[0,3,1,""]},"nest_backend.database.tables.Authorization":{__init__:[0,2,1,""],email:[0,3,1,""],repository:[0,3,1,""],rid:[0,3,1,""],to_json:[0,2,1,""],user:[0,3,1,""]},"nest_backend.database.tables.Composed":{__init__:[0,2,1,""],repository:[0,3,1,""],rid:[0,3,1,""],snowflake:[0,3,1,""],tweet:[0,3,1,""]},"nest_backend.database.tables.Condition":{__init__:[0,2,1,""],alerts:[0,3,1,""],content:[0,3,1,""],id:[0,3,1,""],repository:[0,3,1,""],repository_id:[0,3,1,""],to_json:[0,2,1,""],tweets:[0,3,1,""],type:[0,3,1,""]},"nest_backend.database.tables.ConditionMode":{all_and:[0,3,1,""],all_or:[0,3,1,""]},"nest_backend.database.tables.ConditionType":{coordinates:[0,3,1,""],hashtag:[0,3,1,""],location:[0,3,1,""],place:[0,3,1,""],time:[0,3,1,""],user:[0,3,1,""]},"nest_backend.database.tables.Contains":{__init__:[0,2,1,""],cid:[0,3,1,""],condition:[0,3,1,""],snowflake:[0,3,1,""],tweet:[0,3,1,""]},"nest_backend.database.tables.MadeOf":{__init__:[0,2,1,""],aid:[0,3,1,""],alert:[0,3,1,""],cid:[0,3,1,""],condition:[0,3,1,""]},"nest_backend.database.tables.Notification":{__init__:[0,2,1,""],alert:[0,3,1,""],alert_id:[0,3,1,""],id:[0,3,1,""],ora:[0,3,1,""],to_json:[0,2,1,""]},"nest_backend.database.tables.OperationType":{assign:[0,3,1,""]},"nest_backend.database.tables.Repository":{__init__:[0,2,1,""],alerts:[0,3,1,""],authorizations:[0,3,1,""],conditions:[0,3,1,""],end:[0,3,1,""],evaluation_mode:[0,3,1,""],id:[0,3,1,""],is_active:[0,3,1,""],is_deleted:[0,3,1,""],name:[0,3,1,""],owner:[0,3,1,""],owner_id:[0,3,1,""],start:[0,3,1,""],to_json:[0,2,1,""],tweets:[0,3,1,""]},"nest_backend.database.tables.Tweet":{__init__:[0,2,1,""],conditions:[0,3,1,""],content:[0,3,1,""],image_url:[0,3,1,""],insert_time:[0,3,1,""],location:[0,3,1,""],place:[0,3,1,""],post_time:[0,3,1,""],poster:[0,3,1,""],repositories:[0,3,1,""],snowflake:[0,3,1,""],to_json:[0,2,1,""]},"nest_backend.database.tables.User":{__init__:[0,2,1,""],authorizations:[0,3,1,""],email:[0,3,1,""],isAdmin:[0,3,1,""],owner_of:[0,3,1,""],password:[0,3,1,""],to_json:[0,2,1,""],username:[0,3,1,""]},"nest_backend.gestione":{admin_or_403:[0,4,1,""],authenticate:[0,4,1,""],error_handler:[0,4,1,""],find_user:[0,4,1,""],gen_password:[0,4,1,""],hashtag_validator:[0,4,1,""],identity:[0,4,1,""],json_error:[0,4,1,""],json_request_authorizer:[0,4,1,""],json_success:[0,4,1,""],repository_auth:[0,4,1,""]},nest_backend:{database:[0,1,0,"-"],gestione:[0,1,0,"-"]},nest_crawler:{associate_condition_tweet:[1,4,1,""],authenticate:[1,4,1,""],is_coordinate_inside_bounding_box:[1,4,1,""],is_repo_alert_triggered:[1,4,1,""],search_repo_conditions:[1,4,1,""],send_notification_email:[1,4,1,""],send_notification_tweet:[1,4,1,""]}},objnames:{"0":["py","class","Python classe"],"1":["py","module","Python modulo"],"2":["py","method","Python metodo"],"3":["py","attribute","Python attributo"],"4":["py","function","Python funzione"]},objtypes:{"0":"py:class","1":"py:module","2":"py:method","3":"py:attribute","4":"py:function"},terms:{"00m":11,"10h":[9,10,11],"10m":[10,11],"11h":11,"11m":11,"127":16,"12h":9,"12m":10,"12worwecx":9,"13h":10,"13m":[10,11],"14m":10,"15h":9,"15m":[10,11],"16h":[10,11],"16m":10,"17h":11,"17m":11,"18m":[10,11],"19h":11,"19m":10,"2021":[9,10,11,15],"206":17,"20m":11,"214":17,"21m":11,"222":17,"23h":[9,10],"23m":10,"248":16,"25m":11,"26m":10,"27h":11,"283":17,"28m":10,"291":17,"29h":10,"29m":[10,11],"30040":16,"30041":16,"301":16,"30m":[9,10,11],"32m":10,"34m":[10,11],"35m":[9,10],"36m":10,"39m":[9,11],"40m":11,"429":17,"42m":10,"443":16,"44m":11,"45m":11,"46m":10,"47m":11,"48m":10,"492":17,"51m":11,"52m":9,"56m":10,"57m":11,"58m":10,"59m":10,"63072000":16,"7c2fm2vd":16,"andr\u00e0":7,"boolean":2,"class":[0,2],"default":2,"else":0,"enum":[0,2],"final":[8,17],"for":[0,9],"function":0,"gi\u00e0":[8,10,17],"null":2,"pu\u00f2":2,"return":0,"static":14,"super":[2,9],"this":[0,16],"var":[10,16],"with":9,Che:[13,17],Gli:[2,7],Nello:14,Noi:15,Non:[5,17],None:0,Per:[10,16],Una:[2,4,7,15,16],Uno:2,__init__:0,abbiam:[8,17],abil:16,abnormal:9,about:9,absent:9,accad:2,access:14,accett:9,according:0,account:[2,7],acme:16,actually:0,adatt:16,adds:0,adegu:[10,11],admin:2,admin_or_403:0,advices:9,after:16,age:16,agent:7,aggiunt:[7,10,11],aggreg:[7,10],aid:[0,2],alcun:[7,11,16],alert:[0,1,2,11],alert_id:[0,2],alerts:[0,9],algoritm:2,all_and:0,all_not:2,all_or:[0,2],allarm:[2,7],allert:[2,7],allowed:0,allows:0,almen:4,alon:0,altre:[9,10],altri:7,altro:2,altrov:[8,17],always:[9,16],ambient:[10,11],ambit:7,amministr:[7,16],analis:[2,7,9,10,14],analizz:7,ancor:[12,17],and:[0,2,9],andat:[6,17],andrann:11,any:[0,9],anyon:9,apac:17,apert:2,api:[10,11,15,16,17],app:16,appartenent:2,applic:[14,15,17],application:0,appost:16,approcc:11,apr:17,arch:16,archiv:[2,7],are:[0,9],artefatt:17,artifacts:17,asks:9,assign:0,associate_condition_tweet:1,attiv:[2,7,16,17],attravers:[7,15,16,17],attributes:0,autent:[10,15],authentic:[0,1],authentication:0,authorization:[0,2],authorizations:0,automat:[14,16],autor:7,autorizz:[2,15],aver:16,averag:9,avet:[6,13,17],avvi:[0,7,16],backend:[0,10,15,17],background:16,backlog:[9,17],bas:[2,7,9,10,17],based:16,bash:16,basic:4,bat:4,bcrypt:2,becaus:0,behav:9,ben:[6,17],benven:17,better:9,bin:16,bisogn:[5,17],board:9,bord:7,bozz:9,brainstorming:9,branc:9,brev:17,bug:11,bugfixing:[10,11],build:[4,16],burndown:[8,17],bytearray:2,cach:16,camb:[6,17],camp:17,cancell:10,cap:10,caratterist:17,cartell:[4,7,16],cas:[16,17],cases:[9,10],casual:16,cattur:11,centralizz:14,cer:16,cerc:2,cert:[2,7],check:9,checks:0,chiam:[10,14],chiav:10,chiusur:2,chown:16,cid:[0,2],classes:0,classific:2,client:[7,9,10,11,12],clientinterview:17,clon:16,cod:[0,17],codic:[10,11,14,17],codific:2,coherent:9,collabor:[10,14],collegues:9,colonn:2,columns:0,com:[4,7,9,10,11,12,17],comand:16,combination:0,compil:[12,17],compless:[8,10,16,17],complet:[9,11],completed:9,completing:9,component:[2,9],composed:[0,2],compost:15,comprens:15,compres:9,comun:[14,15],concess:2,conclusion:[11,17],conclusions:17,concord:9,condition:[0,2],conditionmod:0,conditions:[0,11],conditions_typ:1,conditiontyp:0,condivid:7,condivision:7,condizion:[2,7,10,11,15],conferm:9,config:16,configur:[7,9,10,11,17],configuration:4,connession:16,conoscent:7,consegn:17,consent:2,consigl:16,constructed:0,constructor:0,consult:9,cont:[2,7],contains:[0,2,17],conten:[2,16],contenent:2,conteng:2,contenitor:2,content:[0,2],contien:2,continuous:4,contribution:9,controll:[10,14],cooper:9,cooperation:9,coordin:2,coordinates:[0,2],cop:16,cor:16,correct:0,corrett:16,correzion:11,cors:[10,15,17],cos:[2,4,5,6,9],costant:16,could:[0,9],couldn:9,coverag:[11,14],crawler:[2,17],cre:[2,7,17],createdb:16,createuser:16,creating:16,creator:2,creazion:[2,7,9,10,14],credentials:0,criter:9,css:9,curl:16,dar:[13,17],dark:9,dashboard:[9,11],dat:[0,2,4,7,9,10,11,12,15,16],databas:[9,10,11,15,17],dbms:16,deb:10,debt:9,decl_ap:0,declar:0,decreases:9,defin:[7,9],definit:9,definition:17,definizion:[2,9,10],dem:[11,16,17],denomin:16,depends:0,description:16,descriv:[8,17],descrizion:9,design:9,determin:7,dettagl:16,dev:7,development:17,diagramm:9,diar:[8,17],differenc:9,dipendent:[4,7,9,11,17],dir:16,directory:[4,16],dirett:[7,16],discord:[9,14],discret:7,discuss:9,discussion:11,dispon:[0,4,9,11,16],disponessim:4,distribu:16,div:2,diven:2,divers:10,doa:16,docs:[0,4,16,17],document:[0,9,10,11,12,14],documentation:4,does:9,doesn:9,doing:9,don:17,dop:[2,16],doppiagg:9,dovr:16,dovrebb:16,driv:9,driving:9,dsjiofgvinmodfiojvbnio3erfnoiweraqugu43ghjwrevniuwerng43iugnreuwignhritmj43i43nb8i42ug0wevkwovmwigtjj:16,due:7,dur:[8,9,10,11,12,17],durant:[7,9,10,11,12],during:9,each:9,edit:16,effectiveness:9,effettu:[7,10],efficent:10,efficiently:9,effort:9,elabor:15,element:[2,7],elenc:9,elimin:[2,7,10],email:[0,2,7],enabl:16,encourag:9,end:[0,2,9],engines:16,entit:[2,10],entrarv:16,entri:4,entro:2,entry:2,enumeration:0,env:16,environment:[4,16],epic:[7,9],error:[0,10],error_handler:0,errorunknownerror:0,esam:15,esecu:[14,16,17],esegu:[2,4,7,16],esemp:[10,16],esperient:7,espost:16,esse:10,essend:7,esser:[2,7,16],essi:[2,7],esso:2,estend:[7,17],estension:17,estim:9,estraiam:15,evaluating:9,evaluation:9,evaluation_mod:[0,2],event:7,eventual:2,every:9,everyon:9,exampl:0,exec:16,execstart:16,explain:9,explorer:10,expr:16,express:9,ext4:17,facing:9,fact:0,fallimentar:11,fancy:0,farl:16,fas:7,feedback:7,feel:9,feels:9,figm:[9,14],fil:[9,17],filtr:7,fin:[10,11,12,16,17],finc:16,find_user:0,finestr:7,fix:[10,11],fixtures:11,flag:2,flask:[15,17],flask_config:16,forc:16,form:15,format:0,formatted:0,forn:[7,9,10,11,12,15,16],forwarded:16,foss:4,fram:9,framework:15,friendly:9,from:[0,9],frontend:[10,11,17],full:16,fullchain:16,fundamental:9,funzion:10,funzional:[9,17],futur:[2,7,15,17],gam:9,gen_password:0,gener:[4,8,9,10,11,12,16,17],general:[9,10,11,12,17],generates:0,geograf:7,geolocalizz:[10,11],gest:[0,15,16],gestion:[7,10,17],get:9,giorn:14,git:[9,14,16],github:4,gitlab:[0,9,11,14,16],glossar:17,gnu:17,goal:[9,17],goals:17,going:9,good:9,googl:9,grad:9,grafic:[7,14],gratuit:11,graz:10,grig:7,grooming:10,group:[9,16],grupp:[7,8,17],guid:[16,17],gunicorn:16,hann:9,happy:0,hash:0,hashed:0,hashtag:[0,2,7,10],hashtag_validator:0,header:16,help:9,helpful:9,higher:9,himself:9,hom:16,hosted:14,hosting:14,html:[4,9,16],http:[15,16],http_host:16,https:[9,14,16],ide:[5,9,10,14,17],ideas:9,identif:2,identity:0,illustr:16,image_url:[0,2],immagin:2,immediat:15,impar:[6,17],impieg:9,implement:10,imports:0,impost:[2,16],includ:[8,17],incontr:[7,11,17],index:17,indic:[2,17],indipendent:9,indirizz:[14,16],individu:7,inerent:10,infin:[4,7],info:10,inform:[2,10,11,12,16,17],informat:[7,15],initialization:0,iniz:[7,9,10,11,12,17],inizial:9,innesc:2,inoltr:2,inser:[2,5,10,11,12,16,17],insert_tim:[0,2],install:[4,17],installation:17,instanc:0,integer:2,integr:[4,7,11,16],intellij:[10,14,17],inter:16,interfacc:[7,14,17],intern:[4,15,16],internet:16,interrott:7,interv:9,introdu:17,inutil:10,invi:[2,7],involved:9,is_act:[0,2],is_coordinate_inside_bounding_box:1,is_deleted:[0,2],is_repo_alert_triggered:1,isadmin:[0,2],isol:16,ispezion:2,issu:11,issues:11,istantane:14,ital:11,its:0,jobs:9,json:[0,10,16],json_error:0,json_request_authorizer:0,json_success:0,jsx:15,jwt:[0,16],keep:9,key:16,keys:0,keyword:7,know:9,knowledg:9,kwargs:0,lasc:[7,11,17],latitud:1,lavor:10,leads:9,learn:9,learned:9,left:9,leg:[2,10],legam:2,let:9,lettur:2,level:9,librer:16,licenz:4,light:9,limit:[0,2,10],lin:9,line:17,link:[2,5,8,9,10,11,17],linux:[4,16],littl:0,local:[7,10,16],location:[0,2],log:9,logg:10,logic:7,login:[0,7,10],longitud:1,lookup:16,loopback:16,lor:7,lost:9,lowest:9,macr:17,macroscop:7,madeof:[0,2],mag:17,maggior:[9,16],mail:2,main:9,mak:17,makefil:4,makes:9,manag:10,management:[9,10,11,14],manipol:15,manten:16,manual:[4,16],many:0,mapped:0,marcell:[9,10,11,12,17],master:9,matc:0,max:16,mechanics:9,member:9,members:9,membr:[9,14],men:2,mentr:4,merg:9,mess:2,messag:0,messaggist:14,met:17,method:0,metod:[10,17],metric:9,mett:[8,17],mezz:7,miglior:[10,14],missirol:[9,10,11,12,13,17],mkdir:16,mnt:17,mockup:[9,10,11],mod:[7,9,10,14,16],model:0,modic:10,modif:[10,11,14],modul:[0,10,17],molt:16,moment:[2,7,10],most:9,mostr:[7,10,11,12,15,17],mot:16,motivation:9,msg:0,mult:16,multilinguagg:14,nam:[0,2],names:0,necess:16,necessar:[4,9,16],need:9,needs:0,nest:16,nest_backend:[15,16,17],nest_crawler:[15,17],nest_frontend:[15,17],network:16,never:9,next:9,node_env:16,node_modules:16,node_version:16,nodejs:17,nom:[2,10,16],nonexisting:17,not:[0,2,9],notif:[2,7],notification:[0,2],notifications:[0,2,9],npm:16,nss:16,number:9,numer:[2,7,8,17],nuov:[2,7,11,17],nvm:16,oauth:10,obiett:17,oggett:2,ogni:2,one:9,onlin:16,only:0,oper:16,operation:0,operationtyp:0,opinion:9,opinions:9,oppur:[2,7],opzional:2,ora:[0,2,9,10,11,12,16],orar:2,ore:2,org:16,organiz:9,organizz:10,original:17,orm:0,ospit:[4,14],other:9,ottimizz:16,output:10,ove:7,ovver:2,owner:[0,9,16],owner_id:[0,2],owner_of:0,pacchett:16,pagin:9,pair:10,param:0,parametr:4,parents:16,parol:10,part:[7,10,14,15,17],partecip:[8,17],partenz:2,participants:9,particol:[4,7],particolar:7,pass:11,password:[0,2],pawn:9,payload:0,penpot:9,perc:[11,16],percors:[16,17],perfect:9,permess:2,permett:[2,4,7],pertant:16,piattaform:[2,7,14],piccol:[7,11],pien:16,plac:[0,2],place_id:11,plan:9,planning:9,platform:0,play:9,played:9,player:9,players:9,plugin:10,poetry:[4,16],poi:4,point:9,poker:9,poor:9,port:16,porting:11,posizion:[2,7],poss:[2,16],possibil:[4,7,9,16],post:2,post_tim:[0,2],poster:[0,2],postgres:16,postgresql:16,pot:9,poter:10,potr:7,potrann:7,powershell:17,practic:9,precedent:16,predic:7,predisposizion:10,preferibil:16,prem:16,prepar:11,prerequis:17,present:[0,2,7,9,10,15],presenz:2,preved:7,prim:[2,4,7,9,10,11,16],principal:[7,10],priorit:9,priority:9,problem:9,process:[9,17],prod:16,prodott:[7,9],product:9,production:16,prof:[9,10,11,12,13,17],progett:[4,7,9,10,14,16],programming:10,project:[9,10,11,14],properly:9,propr:[7,16],propriet:10,proprietar:2,prosegu:16,prot:16,protocols:16,prov:10,proxy:17,proxypass:16,proxypassrevers:16,pubblic:[2,7,11,16],punt:7,put:11,puts:9,py3:16,pypoetry:16,pytest:11,python:[4,15,17],qual:[2,7,11,16],qualit:14,quality:9,qualor:[4,7,17],qualsias:7,quand:2,quant:16,quel:10,quell:[7,10],query:11,quest:[2,4,9,10,11,12,16],question:9,questions:9,qui:[5,7,10,11,12,17],raccogl:[7,9],raccolt:[2,7],radius:1,ragg:2,rappresent:[2,16],react:[15,17],readthedocs:4,ready:17,realizz:[9,10,11,15],recuper:15,recurs:16,ref:[8,17],refactor:10,refactoring:[10,11,14],referenc:17,registered:0,registr:17,regol:7,regolar:7,relat:[2,4,7,9,17],relationships:0,relazion:10,rend:16,rep:[2,10],repeat:9,repeatabl:9,report:12,repositories:[0,9],repository:[0,2,7,9,10,11,14],repository_auth:0,repository_id:[0,1,2],reqest:0,request_schem:16,requestheader:16,required:[0,9],resocont:9,rest:16,restitu:10,restructuredtext:4,ret:16,retrieval:10,retrospect:[9,10,11],retrospett:[8,11,17],returned:0,returns:0,revers:17,review:17,rewriteengin:16,rewriterul:16,riavv:16,ricerc:[7,10],ricev:7,richied:2,richiest:[7,9,10],ricord:16,rid:[0,2],riemp:2,rig:[16,17],righ:2,riguard:10,rilev:7,rimang:16,rimoss:7,rimozion:10,ripet:[16,17],riport:7,riserv:2,risolt:11,risolu:11,rispett:2,risult:17,ritocc:[9,10],ritorn:[10,11],riusc:11,roles:9,root:16,routes:17,rp_app:16,rst:17,run:[4,16],ruol:16,sal:2,salv:[15,16],sar:[7,16],sarann:7,scanner:11,scaric:17,scegl:7,scherm:17,scop:7,screenshot:[12,17],screenshots:17,script:[4,16],scritt:[4,10,15],scrittur:[10,14],scriv:[5,6,16,17],scrum:9,scrumbl:17,search_repo_conditions:1,second:15,secret_key:16,security:16,see:16,segnal:[2,11],segret:16,segu:[7,8,17],seguent:[2,9,10,11,12,14,16],selezion:7,self:14,semplic:7,send_notification_email:1,send_notification_tweet:1,senz:7,serenity:9,serializabl:0,serv:16,server:[0,15,16],servernam:16,servic:16,serviz:17,session:[10,11],set:16,sets:0,setting:11,settings:9,setup:[11,16],shar:9,sharing:9,shell:[4,16],shouldnt:0,sicurezz:16,simpl:0,sincron:14,sint:16,sistem:[4,7,16],sit:10,situation:9,siz:9,smallint:2,snowflak:[0,2],soddisf:7,soddisfacent:7,soddisfatt:7,softw:[7,14,15],sogl:2,sol:[8,16,17],solving:9,something:9,son:[2,7,14,16],sonarqub:[9,10,11,14,17],sorgent:[4,9,17],sostitu:16,sourc:[4,17],speaks:9,spec:0,specif:[0,9],specific:10,sphinx:4,sprint1:[10,17],sprint2:[11,17],sprint3:17,sprint:[7,8,17],sprints:9,sqlalchemy:[0,16],sqlalchemy_database_ur:16,srs:9,srv:16,sslcertificatefil:16,sslcertificatekeyfil:16,sslengin:16,stag:9,standard:4,standardizz:10,start:[0,2,16],stat:[2,7,9,10,11,12,14,16],statist:[7,15,17],stats:9,steff:[14,16],stess:16,stesur:[9,10],stim:9,stories:9,story:[7,9],strict:16,string:[0,2,16],strument:[4,17],struttur:[4,10,17],stud:10,success:[9,16],successful:0,such:0,suddivision:17,sugger:[8,16,17],suggestions:[9,17],support:10,sur:9,svilupp:[2,7,9,10,11,14,17],svolt:10,swagger:[0,11],system:0,systemctl:16,systemd:17,tabell:[2,17],tables:17,taig:[9,10,11,12,14,17],talks:9,talvolt:16,target:[4,16],tasks:9,tast:16,tastier:16,team:[9,10,11,14],technical:9,tecnic:10,telemat:7,temp:[2,7,9,17],temporal:7,ten:2,tentat:11,ter:17,termin:[7,9,10,11,17],test:[9,10,11,16],tester:9,testing:[10,11,14],tests:11,that:0,the:[0,9,16],thes:0,they:9,thing:0,thingamajigs:0,throughout:9,tim:[0,2,9],timer:17,timestamp:2,tip:[2,10],tipolog:7,to_json:0,toctre:17,tod:12,token:16,topic:9,total:[9,10,11,12],totally:9,tracc:[2,14],traduzion:11,tram:[7,10,16],transport:16,tre:[7,15],trigger:2,trov:[4,7,17],tru:2,tutt:[7,9,10,14,16],tweepy:15,tweet:[0,1,2,7,10,11,15],tweet_latitud:1,tweet_longitud:1,tweets:0,twitter:[2,7,9,10,15],type:[0,2,16],uf2up4_lneoovhzpvr77msg:9,ulterior:11,ultim:[2,4,9,10,14],uml:7,understand:9,uniform:9,uniformity:9,unimor:15,unit:16,univoc:2,unrepeatabl:9,usa:16,usand:[2,8,15,17],usat:[2,14],use:9,used:0,user:[0,2,4,7,9,10,11,16],useradd:16,usernam:[0,2],users:[10,11],using:0,uso:[16,17],usr:16,utent:[2,10,11,15],utility:17,utilizz:[2,7,10,11,16,17],valid:0,valor:2,valu:0,values:0,valut:11,varc:2,variabil:16,ved:[0,16],ven:[2,10],veng:[7,16,17],venv:[4,16],verif:16,verification:0,verr:16,verrann:7,version:[4,9,11,14,16],vide:[5,9,10,11,17],vien:2,view:9,vim:16,virtual:4,virtualenv:16,virtualenvs:16,virtualhost:16,vision:9,vist:[7,8,17],visualizz:[7,14,15],vocal:14,volt:[0,2,4,7,10],want:0,wantedby:16,wants:[9,16],was:0,web:[14,15,16,17],webserver:0,well:9,what:9,when:9,whether:0,willing:9,window_siz:[0,2],windows:17,wis:9,working:16,workingdirectory:16,you:[0,16]},titles:["nest_backend
- Web API in Python","nest_crawler
- Crawler in Python","Struttura del database","nest_frontend
- Interfaccia utente in React","Meta-documentazione","Artefatti","Conclusioni","Introduzione","Processo di sviluppo","Sprint 0: 04 Apr - 18 Apr","Sprint 1: 19 Apr - 02 Mag","Sprint 2: 03 Mag - 16 Mag","Sprint 3: 17 Mag - 30 Mag","Suggerimenti relativi al corso","Strumenti utilizzati","Il progetto in breve","Installazione","N.E.S.T."],titleterms:{"final":12,altri:17,anniball:[9,10,11,12],apac:16,api:0,applic:7,apr:[9,10],artefatt:[5,9],attiv:[9,10,11,12],backend:16,backlog:[7,10,11,12],balugan:[9,10,11,12],bas:0,brev:15,calzolar:[9,10,11,12],camp:7,caratterist:7,cas:7,chiar:[9,10,11,12],cocc:[9,10,11,12],codic:16,colleg:17,collett:[9,10,11,12],com:16,compil:[4,16],conclusion:6,configur:16,consegn:[9,10,11,12],cors:13,cos:17,crawler:[1,16],cre:16,databas:[0,2,16],definition:[9,10,11,12],dem:5,dipendent:16,document:[4,17],don:[9,10,11,12],estension:0,far:[5,6,7,8,10,11,12,13,16,17],fil:16,flask:0,flav:[9,10,11,12],frontend:16,funzional:7,general:7,gestion:0,giorg:[9,10,11,12],giovann:[9,10,11,12],gitinspector:[9,10,11,12],glossar:7,gnu:4,goal:[10,11,12],goldon:[9,10,11,12],ide:4,individual:[9,10,11,12],install:16,intellij:4,interfacc:3,introdu:7,lorenz:[9,10,11,12],macr:7,mag:[10,11,12],mak:4,manual:17,met:4,metod:0,minoccar:[9,10,11,12],modul:15,nest_backend:0,nest_crawler:1,nest_frontend:3,nodejs:16,nuov:16,obiett:7,part:9,percors:0,pigozz:[9,10,11,12],powershell:4,prerequis:16,process:8,progett:[15,17],proxy:16,python:[0,1,16],react:3,ready:9,registr:[9,10,11,12],relat:13,relazion:17,retrospett:12,revers:16,review:[9,10,11],rimast:17,risult:9,riunion:[9,10,11,12],routes:0,scaric:16,scherm:12,screenshots:15,scrumbl:9,serviz:16,sonarqub:12,sorgent:16,sprint:[9,10,11,12],statist:[9,10,11,12],stef:[9,10,11,12],strument:14,struttur:2,suddivision:15,sugger:13,svilupp:8,systemd:16,tabell:0,tables:0,tecnic:17,timer:16,uso:7,utent:[3,7,16,17],utility:0,utilizz:14,web:0,windows:4}}) \ No newline at end of file diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css new file mode 100644 index 0000000..fdea68b --- /dev/null +++ b/docs/source/_static/custom.css @@ -0,0 +1,7 @@ +dl > dd > dl { + margin-bottom: 0 !important; +} + +li > dl { + margin-bottom: 24px !important; +} \ No newline at end of file diff --git a/docs/source/code/backend/index.rst b/docs/source/code/backend/index.rst index 59e05cf..b829159 100644 --- a/docs/source/code/backend/index.rst +++ b/docs/source/code/backend/index.rst @@ -32,6 +32,8 @@ ``.routes`` - Percorsi API -------------------------- -.. automodule:: nest_backend.database.routes - :imported-members: +.. note:: + + La documentazione dei percorsi API è gestita da Swagger UI, disponibile a ``/docs`` una volta che il webserver + del backend è avviato. diff --git a/docs/source/code/crawler/index.rst b/docs/source/code/crawler/index.rst index ca1451e..2d4266a 100644 --- a/docs/source/code/crawler/index.rst +++ b/docs/source/code/crawler/index.rst @@ -2,3 +2,4 @@ ==================================== .. automodule:: nest_crawler + :imported-members: diff --git a/docs/source/code/database/index.rst b/docs/source/code/database/index.rst new file mode 100644 index 0000000..9ab1295 --- /dev/null +++ b/docs/source/code/database/index.rst @@ -0,0 +1,265 @@ +Struttura del database +====================== + +.. class:: Alert + + Un alert è un allarme impostato da un utente che si "attiva" quando un numero di tweet che rispetta certe condizioni + (poste in and oppure or) supera una certa soglia, indicata dall'utente. + + Ogni volta che l'alert si attiva, viene creata una "notifica", ovvero una entry nella tabella Notifications. + Questo permette di tenere conto del numero di volte in cui l'alert viene triggerato. + + Gli alert sono legati al repository di appartenenza, e quando uno di essi viene allertato viene inviata una mail + all'admin e pubblicato un tweet sull'account Twitter usato per le analisi. + + La tabella alert contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - id (INTEGER, PK) + - l'identificativo dell'alert + * - name (VARCHAR, NOT NULL) + - il nome dell'alert + * - limit (INTEGER, NOT NULL) + - il numero di tweet che innescano l'alert + * - window_size (INTEGER, NOT NULL) + - numero di ore in cui il limit può venire superato + * - evaluation_mode (ENUM/SMALLINT, NOT NULL) + - può essere posto a all_or oppure all_not + * - repository_id (INTEGER, FK, NOT NULL) + - + + + +.. class:: Authorization + + Una autorizzazione è un'entità che rappresenta il permesso, concesso dal creatore del repository ad un altro utente, + di ispezionare il contenuto di un repo e di eseguire analisi su di esso. + + La tabella authorization contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - rid (INTEGER, PK, FK) + - id del repository + * - email (VARCHAR, PK, FK) + - email dell'utente + +.. class:: Composed + + Composed è una tabella le cui righe indicano l'appartenenza di un Tweet ad un certo repository. + + La tabella Composed contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - rid (INTEGER, PK, FK) + - id del repository + * - snowflake (VARCHAR, PK, FK) + - id del tweet + + + +.. class:: Condition + + Una condizione è un elemento che viene usato da repository e alert per cercare e classificare i tweet. + + Le condizioni possono essere di diversi tipi: + + - **hashtag**: valore ``0``, richiede che il tweet contenga un dato hashtag + + - **time**: valore ``2``, richiede che il tweet sia stato pubblicato prima o dopo una certa data + + - **coordinates**: valore ``3``, richiede che il tweet sia stato pubblicato entro un certo raggio da delle + coordinate + + - **user**: valore ``5``, richiede che il tweet sia stato pubblicato da un dato utente + + La tabella condition contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - id (INTEGER, PK) + - id della condition + * - type (ENUM/SMALLINT, NOT NULL) + - tipo del contenuto + * - content (VARCHAR, NOT NULL) + - contenuto della condition + * - repository_id (INTEGER, FK, NOT NULL) + - + + +.. class:: Contains + + Contains è una tabella le cui righe indicano la presenza di una certa condition rispetto ad un certo tweet. + + La tabella contains contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - cid (INTEGER, PK, FK) + - id della condition + * - snowflake (VARCHAR, PK, FK) + - id del tweet + + + + +.. class:: MadeOf + + MadeOf è una tabella le cui righe indicano il legame tra un alert e una certa condition. + + La tabella madeof contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - aid (INTEGER, PK, FK) + - id dell'alert + * - cid (INTEGER, PK, FK) + - id della condition + + +.. class:: Notification + + Una notification è un'entità che consente di tenere traccia del momento in cui un certo alert si è attivato + per l'ultima volta. + + La tabella notification contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - id (INTEGER, PK) + - id della notifica + * - ora (TIMESTAMP, NOT NULL) + - timestamp di attivazione + * - alert_id (INTEGER, FK, NOT NULL) + - + + +.. class:: Repository + + Un repository è un "contenitore" di tweet, a cui sono legati alert, autorizzazioni di lettura e condizioni. + + Le condizioni possono essere messe in and oppure or, inoltre un repository può venire archiviato prima divenire + eliminato. Quando un repository non è archiviato, questo viene riempito di tweet su base oraria, cosa che non + accade se viene archiviato. + + La tabella repository contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - id (INTEGER, PK) + - id del repository + * - name (VARCHAR, NOT NULL) + - nome del repository + * - start (TIMESTAMP) + - timestamp di partenza del repository + * - end (TIMESTAMP) + - timestamp di chiusura del repository + * - is_active (BOOLEAN, NOT NULL) + - flag per segnalare se il repo è aperto o meno + * - evaluation_mode (ENUM/SMALLINT, NOT NULL) + - può essere posto a all_or oppure all_not + * - owner_id (VARCHAR, FK, NOT NULL) + - email del proprietario + * - is_deleted (BOOLEAN, NOT NULL) + - flag per segnalare se l'oggetto è eliminato o meno + + +.. class:: Tweet + + Un tweet è un'entità che viene raccolta dal componente crawler, e quando viene inserita nella base di dati viene + legata ad un repository e alle condition che contiene. Un tweet contiene informazioni relativamente a chi l'ha + creato, eventuali immagini, il tempo di creazione, il tempo di inserimento nel db e l'opzionale posizione legata + al tweet. + + La tabella tweet contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - snowflake (VARCHAR, PK) + - id univoco del tweet + * - content (VARCHAR) + - contenuto del tweet + * - location (VARCHAR) + - stringa contenente informazioni sulla posizione + * - place (VARCHAR) + - riservato per sviluppi futuri + * - poster (VARCHAR) + - informazioni sull'utente che ha creato il tweet + * - insert_time (TIMESTAMP, NOT NULL) + - timestamp dell'inserimento del tweet + * - image_url (VARCHAR) + - link alle immagini, se presenti + * - post_time (TIMESTAMP) + - timestamp relativo all'invio del tweet + + +.. class:: User + + Uno user è l'utilizzatore della piattaforma. + + E' presente di default un utente admin, il quale può creare nuovi utenti. + + La tabella user contiene le seguenti colonne: + + .. list-table:: + :header-rows: 1 + :stub-columns: 1 + :align: left + + * - + - Definizioni + * - email (VARCHAR, PK) + - email dell'utente + * - username (VARCHAR, NOT NULL) + - username dell'utente + * - password (BYTEARRAY, NOT NULL) + - sale della password, codificata usando l'algoritmo bcrypt + * - isAdmin (BOOLEAN, NOT NULL) + - true se l'utente è admin diff --git a/docs/source/conf.py b/docs/source/conf.py index 7f32002..228d6b2 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -74,8 +74,6 @@ html_theme_options = { html_static_path = ['_static'] - - # -- Intersphinx options ----------------------------------------------------- intersphinx_mapping = { @@ -93,6 +91,12 @@ intersphinx_mapping = { } +# -- Setup function ---------------------------------------------------------- + +def setup(app): + app.add_css_file('custom.css') + + # -- Extension configuration ------------------------------------------------- todo_include_todos = True @@ -105,6 +109,5 @@ autodoc_default_options = { 'member-order': 'bysource', 'special-members': '__init__', 'undoc-members': True, - 'show-inheritance': True, + 'show-inheritance': False, } - diff --git a/docs/source/development/Backlog1.PNG b/docs/source/development/Backlog1.PNG new file mode 100644 index 0000000..92bb0d5 Binary files /dev/null and b/docs/source/development/Backlog1.PNG differ diff --git a/docs/source/development/Backlog2.PNG b/docs/source/development/Backlog2.PNG new file mode 100644 index 0000000..a8a990a Binary files /dev/null and b/docs/source/development/Backlog2.PNG differ diff --git a/docs/source/development/Backlog3.PNG b/docs/source/development/Backlog3.PNG new file mode 100644 index 0000000..cc82c9b Binary files /dev/null and b/docs/source/development/Backlog3.PNG differ diff --git a/docs/source/development/Backlog4.PNG b/docs/source/development/Backlog4.PNG new file mode 100644 index 0000000..4092a71 Binary files /dev/null and b/docs/source/development/Backlog4.PNG differ diff --git a/docs/source/development/Backlog5.PNG b/docs/source/development/Backlog5.PNG new file mode 100644 index 0000000..0397503 Binary files /dev/null and b/docs/source/development/Backlog5.PNG differ diff --git a/docs/source/development/Burndown1.png b/docs/source/development/Burndown1.png new file mode 100644 index 0000000..17c6009 Binary files /dev/null and b/docs/source/development/Burndown1.png differ diff --git a/docs/source/development/Burndown2.png b/docs/source/development/Burndown2.png new file mode 100644 index 0000000..42012bf Binary files /dev/null and b/docs/source/development/Burndown2.png differ diff --git a/docs/source/development/Burndown3.png b/docs/source/development/Burndown3.png new file mode 100644 index 0000000..7dafa10 Binary files /dev/null and b/docs/source/development/Burndown3.png differ diff --git a/docs/source/development/Burndown4.png b/docs/source/development/Burndown4.png new file mode 100644 index 0000000..3f89778 Binary files /dev/null and b/docs/source/development/Burndown4.png differ diff --git a/docs/source/development/CasiUso1.PNG b/docs/source/development/CasiUso1.PNG new file mode 100644 index 0000000..f52b9c0 Binary files /dev/null and b/docs/source/development/CasiUso1.PNG differ diff --git a/docs/source/development/CasiUso2.PNG b/docs/source/development/CasiUso2.PNG new file mode 100644 index 0000000..ed7b388 Binary files /dev/null and b/docs/source/development/CasiUso2.PNG differ diff --git a/docs/source/development/CasiUso3.PNG b/docs/source/development/CasiUso3.PNG new file mode 100644 index 0000000..54a9a8b Binary files /dev/null and b/docs/source/development/CasiUso3.PNG differ diff --git a/docs/source/development/CasiUso4.PNG b/docs/source/development/CasiUso4.PNG new file mode 100644 index 0000000..86ea489 Binary files /dev/null and b/docs/source/development/CasiUso4.PNG differ diff --git a/docs/source/development/CasiUso5.PNG b/docs/source/development/CasiUso5.PNG new file mode 100644 index 0000000..adc9683 Binary files /dev/null and b/docs/source/development/CasiUso5.PNG differ diff --git a/docs/source/development/CasiUso6.PNG b/docs/source/development/CasiUso6.PNG new file mode 100644 index 0000000..7d70857 Binary files /dev/null and b/docs/source/development/CasiUso6.PNG differ diff --git a/docs/source/development/Utenti.png b/docs/source/development/Utenti.png new file mode 100644 index 0000000..732c162 Binary files /dev/null and b/docs/source/development/Utenti.png differ diff --git a/docs/source/development/goals.rst b/docs/source/development/goals.rst index 6e3c772..6e86446 100644 --- a/docs/source/development/goals.rst +++ b/docs/source/development/goals.rst @@ -1,30 +1,152 @@ -Obiettivo del progetto -====================== +Introduzione +============ .. todo:: + Lasciamo il tempo al futuro? - Scrivere l'obiettivo generale del progetto. +Obiettivo +--------- + +L'obiettivo del progetto è la creazione di un software per fornire l'aggregazione e l'analisi di `Tweet`_, in modo da +rilevare eventi *macroscopici*, *locali* o più semplicemente filtrarli in base a delle *keyword*. + +Il prodotto sarà utilizzato dal cliente e da un piccolo gruppo di suoi dipendenti per effettuare ricerche statistiche. + +Il software andrà ad integrarsi direttamente con `Twitter`_, da cui verranno raccolti dati e su cui verranno pubblicate +allerte su di essi. + +.. _Tweet: https://help.twitter.com/it/using-twitter#tweets +.. _Twitter: https://twitter.com/ -Scope ------ +Campo di applicazione +--------------------- + +Il software trova utilizzo principalmente in **ambito statistico**, essendo il suo scopo quello di raccogliere dati e +permettere di analizzarli tramite un'interfaccia grafica. + + +Caratteristiche degli utenti +---------------------------- + +Il software potrà essere utilizzato da utenti con una discreta esperienza nell'analisi di dati ma senza particolari +conoscenze informatiche. + +Glossario +--------- + +Repository + Raccolta di tweet che soddisfano determinate condizioni. + +Condizione + Predicato logico che deve essere soddisfatto da un tweet per essere raccolto in fase di raccolta dati, o per essere + contato in fase di allertamento utente. + +Filtro + Predicato logico che deve essere soddisfatto da un tweet per essere visualizzato in fase di analisi dati. + +Allarme + Notifica inviata all'utente attraverso un mezzo telematico, come email oppure un tweet. + +Utente + Utilizzatore del software con un proprio account creato dall'amministratore della piattaforma. + + In particolare, la piattaforma prevederà due tipologie di utenti: + + Utente regolare + Potranno eseguire attività di creazione, analisi, condivisione, archiviazione ed eliminazione dei propri repository. + + Utente amministratore + Potrà effettuare tutte le attività dell'utente regolare, e in aggiunta potrà creare ed eliminare nuovi utenti + regolari. + .. todo:: + Estendere il glossario qualora vengano incontrati altri termini. - Scrivere lo scope del progetto. + +Macro-funzionalità +------------------ + +Il software permetterà di selezionare **condizioni** con cui scegliere quali tweet raccogliere: + +- in base ai loro `hashtag`_ +- in base al loro autore +- in base alla loro `posizione geografica`_ (ove presente) +- in base alla loro data di pubblicazione + +Selezionate le condizioni, l'utente potrà creare una **repository**: una cartella in cui verranno raccolti i tweet +soddisfacenti le condizioni richieste. + +Una volta raccolti, i tweet di una repository potranno essere **analizzati** in qualsiasi momento: durante l'analisi, +saranno mostrate statistiche e grafici relativi ai tweet. + +La raccolta potrà essere interrotta in qualsiasi momento **archiviando** il repository. + +Sarà possibile **condividere** una repository con altri utenti della piattaforma, permettendo loro di analizzarla. + +Infine, l'utente potrà configurare una repository in modo che gli invii una **allerta** qualora vengano raccolti un dato +numero di tweet in una certa *finestra temporale*. + +.. _hashtag: https://help.twitter.com/it/using-twitter/how-to-use-hashtags +.. _posizione geografica: https://help.twitter.com/en/safety-and-security/tweet-location-settings Casi d'uso ---------- -.. todo:: +N.E.S.T. prevede tre tipologie di *agenti* ("utenti" UML): **utente**, **amministratore** e **sistema**. - Scrivere i casi d'uso del progetto. +.. image:: Utenti.png + +I principali casi d’uso individuati durante la progettazione di N.E.S.T. sono: + +- La gestione degli utenti da parte di un Amministratore: + + .. image:: CasiUso1.PNG + :width: 400 + +- La gestione del login da parte di un Utente: + + .. image:: CasiUso2.PNG + :width: 400 + +- La gestione delle Allerte sia dal punto di vista dell’Utente che del Sistema: + + .. image:: CasiUso3.PNG + :width: 800 + +- La gestione della raccolta da parte dell'utente: + + .. image:: CasiUso4.PNG + :width: 400 + +- La gestione di un repository da parte dell'utente: + + .. image:: CasiUso5.PNG + :width: 400 + +- La visualizzazione di un repository: + + .. image:: CasiUso6.PNG + :width: 400 Backlog generale ---------------- -.. todo:: +Si riporta qui di seguito il Backlog definito ad inizio progetto, prima dell’avvio dello sviluppo. +Gli elementi dal bordo grigio sono le epiche: - Elencare qui tutte le user story del backlog, senza specificare lo sprint in cui sono state realizzate. +.. note:: + Alcune user story sono state rimosse in seguito al feedback ricevuto durante il primo sprint! + +.. image:: Backlog1.PNG + +.. image:: Backlog2.PNG + +.. image:: Backlog3.PNG + +.. image:: Backlog4.PNG + +.. image:: Backlog5.PNG diff --git a/docs/source/development/log.rst b/docs/source/development/log.rst deleted file mode 100644 index 637797f..0000000 --- a/docs/source/development/log.rst +++ /dev/null @@ -1,24 +0,0 @@ -Registro attività -================= - -Questo registro attività delinea le attività effettuate dai membri del team e ne indica la durata. - -.. note:: - - Per informazioni più dettagliate sulle attività di sviluppo, si suggerisce di guardare il log dei commit di Git: - - .. code-block:: console - - nest:g2-progetto$ git log - - - -Sprint 1: 19 Apr - 02 Mag -------------------------- - - -Sprint 2: 03 Mag - 16 Mag -------------------------- - - - diff --git a/docs/source/development/process.rst b/docs/source/development/process.rst index 7c8e6d5..2e62571 100644 --- a/docs/source/development/process.rst +++ b/docs/source/development/process.rst @@ -1,11 +1,46 @@ Processo di sviluppo ==================== +Lo sviluppo è stato suddiviso in 4 sprint, ciascuno della durata di 2 settimane: +Sprint 0 - dal 5 Aprile al 18 Aprile + `Diari`_ dei partecipanti + `Retrospettiva`_ dello sprint 0 + .. _Diari: http://localhost:63342/N.E.S.T./Modulo%20unico/docs/build/html/development/sprint0/index.html#registro-attivita + .. _Retrospettiva: http://localhost:63342/N.E.S.T./Modulo%20unico/docs/build/html/development/sprint0/index.html#retrospettiva-finale +Sprint 1 - dal 19 Aprile al 2 Maggio + Burndown dello sprint 1 + .. image:: Burndown1.png + :width: 400 + `Diari`_ dei partecipanti + `Retrospettiva`_ dello sprint 1 + .. _Diari: http://localhost:63342/N.E.S.T./Modulo%20unico/docs/build/html/development/sprint1/index.html#registro-attivita + .. _Retrospettiva: http://localhost:63342/N.E.S.T./Modulo%20unico/docs/build/html/development/sprint1/index.html#retrospettiva-finale +Sprint 2 - dal 3 Maggio al 16 Maggio + Burndown dello sprint 2 + .. image:: Burndown2.png + :width: 400 + `Diari`_ dei partecipanti + `Retrospettiva`_ dello sprint 2 + .. _Diari: http://localhost:63342/N.E.S.T./Modulo%20unico/docs/build/html/development/sprint2/index.html#registro-attivita + .. _Retrospettiva: http://localhost:63342/N.E.S.T./Modulo%20unico/docs/build/html/development/sprint2/index.html#retrospettiva-finale +Sprint 3 - dal 19 Maggio al 30 Maggio + Burndown dello sprint 3 + .. image:: Burndown3.png + :width: 400 + `Diari`_ dei partecipanti + `Retrospettiva`_ dello sprint 3 + .. _Diari: http://localhost:63342/N.E.S.T./Modulo%20unico/docs/build/html/development/sprint3/index.html#registro-attivita + .. _Retrospettiva: http://localhost:63342/N.E.S.T./Modulo%20unico/docs/build/html/development/sprint3/index.html#retrospettiva-finale +In generale: + Burndown totale + .. image:: Burndown4.png + :width: 400 + .. todo:: Descrivere genericamente il processo di sviluppo seguito, includendo: - "numero e durata degli sprint, burndown complessivo, diari dei partecipanti e/o diario di gruppo, + burndown complessivo, diari dei partecipanti e/o diario di gruppo, retrospettiva finale" Visto che i diari e la retrospettiva li abbiamo già altrove, suggerirei di metterci solo un link usando ``:ref:``. diff --git a/legacy/doc/development/sprint-0/__main__.pdf b/docs/source/development/sprint0/0-result.pdf similarity index 100% rename from legacy/doc/development/sprint-0/__main__.pdf rename to docs/source/development/sprint0/0-result.pdf diff --git a/docs/source/development/sprint0/index.rst b/docs/source/development/sprint0/index.rst index 26146ad..ad9ff8f 100644 --- a/docs/source/development/sprint0/index.rst +++ b/docs/source/development/sprint0/index.rst @@ -1,11 +1,6 @@ Sprint 0: 04 Apr - 18 Apr ========================= -.. todo:: - - Inserire informazioni generali sullo sprint, come inizio e fine. - - Consegna -------- @@ -15,28 +10,28 @@ La seguente documentazione è stata fornita dal cliente durante questo sprint: - :download:`Sprint 0 <0-sprint-requirements.pdf>` -Goal ----- +Definition of Ready +------------------- -.. todo:: +Il team ha definito lo stato di Ready di una User Story in base ai seguenti criteri: - Inserire qui lo sprint goal. +* La User Story è stata compresa ed accettata da tutti i membri +* I tester hanno confermato la possibilità di poterla testare +* Il Product Owner ha la visione necessaria per definirne la priorità +* Il Team è in grado di stimarla +* La User Story è indipendente o dipendente da altre a priorità maggiore -Backlog -------- - -.. todo:: - - Mostrare qui lo sprint backlog di Taiga. - - -Definition of done +Definition of Done ------------------ -.. todo:: +La definizione di Done è stata concordata da tutto il team con il Product Owner, ed è stata così +definita: - Inserire qui la definition of done dello sprint. +* Sviluppo completo della funzionalità richiesta +* Definizione e superamento dei test +* Bozza della documentazione della funzionalità +* Merge dei sorgenti nel branch ``main`` del repository Git Registro attività @@ -171,7 +166,7 @@ Chiara Calzolari - Durata - Attività * - - - + - 12h 30m - Totale * - 2021-04-09 @@ -272,9 +267,192 @@ Lorenzo Balugani Risultati della partita di Scrumble ----------------------------------- -.. todo:: +#. :Goal: Learn + :Question: Do team members understand the Scrum roles? + :Metric: Knowledge of Scrum roles by questions + :Evaluation: :1: no idea of the Scrum roles + :5: perfect knowledge of the roles and their jobs + :Chiara: 4 + :Giorgio: 4 + :Giovanni: 4 + :Stefano P.: 4 + :Lorenzo: 5 + :Stefano G.: 5 + :Flavia: 4 - Trascrivere qui i risultati della partita di Scrumble. +#. :Goal: Learn + :Question: Do team members feel they learned the process? + :Metric: Opinions from the participants + :Evaluation: :1: couldn't repeat the game + :5: could play the game as a Scrum Master by himself + :Chiara: 3 + :Giorgio: 3 + :Giovanni: 4 + :Stefano P.: 5 + :Lorenzo: 3 + :Stefano G.: 3 + :Flavia: 3 + +#. :Goal: Learn + :Question: Does everyone keep up with the other players? + :Metric: Check during every sprint retrospective if every one is on point + :Evaluation: :1: totally lost + :5: leads the game driving the other players + :Chiara: 3 + :Giorgio: 4 + :Giovanni: 4 + :Stefano P.: 4 + :Lorenzo: 5 + :Stefano G.: 5 + :Flavia: 5 + +#. :Goal: Practice + :Question: Are the game mechanics linear and repeatable? + :Metric: Opinions from the participants + :Evaluation: :1: feels the game is unrepeatable + :5: feels the game could be played in any situation + :Chiara: 1 + :Giorgio: 2 + :Giovanni: 1 + :Stefano P.: 1 + :Lorenzo: 1 + :Stefano G.: 2 + :Flavia: 1 + +#. :Goal: Practice + :Question: Do team success in completing the game? + :Metric: Number of User Stories completed + :Evaluation: :1: 0 to 3 stories + :2: 4 to 6 + :3: 7 to 9 + :4: 10 to 12 + :5: 13 to 15 + :Chiara: 5 + :Giorgio: 5 + :Giovanni: 5 + :Stefano P.: 5 + :Lorenzo: 5 + :Stefano G.: 5 + :Flavia: 5 + +#. :Goal: Practice + :Question: Do team members efficiently estimate during sprint planning? + :Metric: Uniformity in evaluating the size and the priority of user stories + :Evaluation: :1: abnormal difference from the other players + :5: coherent and uniform with the group most of the time + :Chiara: 5 + :Giorgio: 4 + :Giovanni: 5 + :Stefano P.: 4 + :Lorenzo: 5 + +#. :Goal: Cooperation + :Question: Do team members know each other better? + :Metric: Level of players' serenity throughout the game + :Evaluation: :1: never speaks with the other players + :5: talks friendly to anyone in every situation + :Chiara: 4 + :Giorgio: 5 + :Giovanni: 5 + :Stefano P.: 5 + :Lorenzo: 5 + :Stefano G.: 5 + :Flavia: 4 + +#. :Goal: Cooperation + :Question: Does the game let all players cooperate? + :Metric: Contribution of every player during the game + :Evaluation: :1: never puts effort in doing something + :5: every time is willing to understand what is going on + :Chiara: 4 + :Giorgio: 3 + :Giovanni: 3 + :Stefano P.: 2 + :Lorenzo: 3 + :Stefano G.: 4 + :Flavia: 3 + +#. :Goal: Cooperation + :Question: Do team member consult each other about a topic? + :Metric: Sharing of ideas + :Evaluation: :1: never asks for an opinion + :5: wants to discuss about every topic + :Chiara: 5 + :Giorgio: 5 + :Giovanni: 5 + :Stefano P.: 3 + :Lorenzo: 5 + :Stefano G.: 4 + :Flavia: 5 + +#. :Goal: Motivation + :Question: Do team members encourage collegues in need? + :Metric: Players explain something other players don't understand + :Evaluation: :1: not involved by the game + :5: always makes sure everyone is on point + :Chiara: 3 + :Giorgio: 5 + :Giovanni: 5 + :Stefano P.: 4 + :Lorenzo: 5 + :Stefano G.: 4 + :Flavia: 4 + +#. :Goal: Motivation + :Question: Does PO help the team? + :Metric: Quality of PO's advices to get better in the next sprints + :Evaluation: :1: poor/absent advices + :5: wise and helpful suggestions when is required + :Stefano G.: 4 + +#. :Goal: Motivation + :Question: Does the team come up with good ideas? + :Metric: Effectiveness of sprint retrospective + :Evaluation: :1: doesn't express opinions during retrospective + :5: feels the retrospective fundamental to express opinions + :Chiara: 4 + :Giorgio: 5 + :Giovanni: 5 + :Stefano P.: 5 + :Lorenzo: 5 + :Stefano G.: 5 + :Flavia: 5 + +#. :Goal: Problem Solving + :Question: Do team members behave well when facing a problem? + :Metric: Level of the technical debt at the end of the game + :Evaluation: On the game board, if the debt pawn is on the lowest stage,the evaluation is 5, for every higher stage it decreases by 1 + :Chiara: 5 + :Giorgio: 5 + :Giovanni: 5 + :Stefano P.: 5 + :Lorenzo: 5 + :Stefano G.: 5 + :Flavia: 5 + +#. :Goal: Problem Solving + :Question: Does team organize their tasks properly? + :Metric: Average of tasks left at the end of each sprint + :Evaluation: :1: 21+ average tasks left + :2: 16-20 average tasks left + :3: 11-15 average tasks left + :4: 6-10 average tasks left + :5: 0-5 average tasks left + :Chiara: 5 + :Giorgio: 5 + :Giovanni: 5 + :Stefano P.: 5 + :Lorenzo: 5 + +#. :Goal: Problem Solving + :Question: Does PO plan efficiently the Sprint Backlog? + :Metric: Average of tasks left at the end of each sprint + :Evaluation: :1: 21+ average tasks left + :2: 16-20 average tasks left + :3: 11-15 average tasks left + :4: 6-10 average tasks left + :5: 0-5 average tasks left + :Stefano G.: 5 Statistiche @@ -286,7 +464,30 @@ Gitinspector Questa statistica è stata generata dal prof. Marcello Missiroli con `Gitinspector`_ al termine dello Sprint. -- :download:`Sprint 0 <0-stats.html>` +- :download:`0-stats.html` .. _Gitinspector: https://github.com/ejwa/gitinspector + + +Sprint Retrospective +-------------------- + + +- :download:`Sprint 0 Retrospective` + + +Sprint review +------------- + +Il video di sprint review è disponibile al seguente link: + +- https://drive.google.com/file/d/12worWEcx-uf2UP4_lnEOovHZpvR77MsG/view + + +Artefatti +--------- + +In questo sprint è stato realizzato il seguente documento: + +- :download:`Documento generale dello Sprint 0 <0-result.pdf>` diff --git a/docs/source/development/sprint0/sprint-0_retrospective.pdf b/docs/source/development/sprint0/sprint-0_retrospective.pdf new file mode 100644 index 0000000..9891a23 Binary files /dev/null and b/docs/source/development/sprint0/sprint-0_retrospective.pdf differ diff --git a/legacy/doc/doc_sprint1/Retrospective_N.E.S.T.sprint1.pdf b/docs/source/development/sprint1/1-retrospective.pdf similarity index 100% rename from legacy/doc/doc_sprint1/Retrospective_N.E.S.T.sprint1.pdf rename to docs/source/development/sprint1/1-retrospective.pdf diff --git a/docs/source/development/sprint1/BacklogSprint1.png b/docs/source/development/sprint1/BacklogSprint1.png new file mode 100644 index 0000000..832fb72 Binary files /dev/null and b/docs/source/development/sprint1/BacklogSprint1.png differ diff --git a/docs/source/development/sprint1/Chart1.png b/docs/source/development/sprint1/Chart1.png new file mode 100644 index 0000000..17c6009 Binary files /dev/null and b/docs/source/development/sprint1/Chart1.png differ diff --git a/docs/source/development/sprint1/Sprint1Task.png b/docs/source/development/sprint1/Sprint1Task.png new file mode 100644 index 0000000..e558894 Binary files /dev/null and b/docs/source/development/sprint1/Sprint1Task.png differ diff --git a/docs/source/development/sprint1/ValutazioneSMDebitoTecnico.md b/docs/source/development/sprint1/ValutazioneSMDebitoTecnico.md new file mode 100644 index 0000000..d218893 --- /dev/null +++ b/docs/source/development/sprint1/ValutazioneSMDebitoTecnico.md @@ -0,0 +1,16 @@ +# Valutazione ScrumMaster debito tecnico + +>La valutazione del debito tecnico effettuata da SonarQube è +>relativa principalmente al backend, poiché l’analisi del progetto +>sarebbe stata troppo dispendiosa a causa dell’elevato numero di +>file presente nella cartella /frontend. + +>Per quanto riguarda il backend invece il debito tecnico riscontrato +> è minore del 5% come si può verificare dal grado A attestato da +>SonarQube. + +>Un punto chiave nell’implementazione ha permesso al team [**N.E.S.T.**] +>di diminuire il debito tecnico, questo è avvenuto grazie +>all’adozione del modello architetturale REST che ha migliorato +>esponenzialmente il tempo di risposta delle richieste e la +>leggibilità del codice. diff --git a/docs/source/development/sprint1/index.rst b/docs/source/development/sprint1/index.rst index 2dae89d..4aefca2 100644 --- a/docs/source/development/sprint1/index.rst +++ b/docs/source/development/sprint1/index.rst @@ -1,11 +1,6 @@ Sprint 1: 19 Apr - 02 Mag ========================= -.. todo:: - - Inserire informazioni generali sullo sprint, come inizio e fine. - - Consegna -------- @@ -17,25 +12,47 @@ La seguente documentazione è stata fornita dal cliente durante questo sprint: Goal ---- -.. todo:: +Il **goal** per questo sprint è stato costruire una codebase facilmente mantenibile e modulare, che potesse accomodare grossi +cambiamenti nei sottomoduli senza impattare gli altri: - Inserire qui lo sprint goal. +- Dal punto di vista del **backend**: l'obiettivo è stato predisporre la struttura del database e creare le api calls per illogin degli utenti e la creazione dei repository +- Dal punto di vista del **frontend**: creare la struttura con le componenti importate da figma e implementare le schermate principali +Tutto ciò è visibile dai task completati: + +.. image:: Sprint1Task.png + :width: 400 Backlog ------- -.. todo:: +.. image:: BacklogSprint1.png + :width: 400 - Mostrare qui lo sprint backlog di Taiga. +**Burndown Chart** + +.. image:: Chart1.png + :width: 600 -Definition of done +Definition of Ready ------------------ -.. todo:: +Il team ha definito lo stato di Ready di una User Story in base ai seguenti criteri: +* La User Story è stata compresa ed accettata da tutti i membri +* I tester hanno confermato la possibilità di poterla testare +* Il Product Owner ha la visione necessaria per definirne la priorità +* Il Team è in grado di stimarla +* La User Story è indipendente o dipendente da altre a priorità maggiore - Inserire qui la definition of done dello sprint. +Definition of Done +------------------ + +La definizione di Done è stata concordata da tutto il team con il Product Owner, ed è stata così definita: +* Sviluppo completo della funzionalità richiesta +* Definizione e superamento dei test +* Bozza della documentazione della funzionalità +* Merge dei sorgenti nel branch ‘Main’ di GitLab Registro attività @@ -486,10 +503,19 @@ Questa statistica è stata generata dal prof. Marcello Missiroli con .. _Gitinspector: https://github.com/ejwa/gitinspector +Sprint retrospective +-------------------- +- :download:`Sprint 1 Retrospective <1-retrospective.pdf>` + Sprint review ------------- -.. todo:: +Il video di sprint review è disponibile al seguente link: - Inserire un link alla sprint review. +- https://drive.google.com/drive/folders/1dsis_cGCRnVgZAkZjEVIZKt4NndkycaF?usp=sharing + +Artefatti +--------- +- :download:`Valutazion SM Debito Tecnico ` +- :download:`Valutazione PO User Stories ` \ No newline at end of file diff --git a/docs/source/development/sprint1/valutazionePO__US_realizzate_o_rifiutate.md b/docs/source/development/sprint1/valutazionePO__US_realizzate_o_rifiutate.md new file mode 100644 index 0000000..c153162 --- /dev/null +++ b/docs/source/development/sprint1/valutazionePO__US_realizzate_o_rifiutate.md @@ -0,0 +1,7 @@ +Durante questo sprint non sono state ristimate le US in quanto non sono emerse al termine dello sprint0 valutazioni che lo rendessero necessario, di conseguenza non sono state neanche rivalutate le priorità. +Come product Owner ho individuato come criterio di accettazione l'esito positivo dei test, anche per il fatto che i test sono presenti in ogni US. +Durante lo sviluppo di questo primo sprint sono ovviamente emerse delle issue che sono state tracciate su taiga. +Una di queste, la #101 "L'API non è interamente REST" ha portato ad un refactoring di una parte del codice del backend, del frontend e naturalmente anche delle procedure di test, che erano già state abbozzate. La modifica comunque si è rilevata essere necessaria per rispondere appieno alle struttura tipica dei metodi REST. +Altre issue sono state inserite ma possono essere sistemate nello sprint successivo in quanto non influiscono sul funzionamento atteso in questo primo sprint. + +Un leggero ritardo sullo sviluppo del frontend non consente di chiudere alcune US, che verranno chiuse e testate nel prossimo sprint. \ No newline at end of file diff --git a/docs/source/development/sprint2/BacklogSprint2.PNG b/docs/source/development/sprint2/BacklogSprint2.PNG new file mode 100644 index 0000000..6d0a0f1 Binary files /dev/null and b/docs/source/development/sprint2/BacklogSprint2.PNG differ diff --git a/docs/source/development/sprint2/Chart2.png b/docs/source/development/sprint2/Chart2.png new file mode 100644 index 0000000..42012bf Binary files /dev/null and b/docs/source/development/sprint2/Chart2.png differ diff --git a/docs/source/development/sprint2/RetrospectiveSprint2.pdf b/docs/source/development/sprint2/RetrospectiveSprint2.pdf new file mode 100644 index 0000000..d8a974f Binary files /dev/null and b/docs/source/development/sprint2/RetrospectiveSprint2.pdf differ diff --git a/docs/source/development/sprint2/Sprint2Task.png b/docs/source/development/sprint2/Sprint2Task.png new file mode 100644 index 0000000..2a014ed Binary files /dev/null and b/docs/source/development/sprint2/Sprint2Task.png differ diff --git a/docs/source/development/sprint2/index.rst b/docs/source/development/sprint2/index.rst index edfdd26..d04c34d 100644 --- a/docs/source/development/sprint2/index.rst +++ b/docs/source/development/sprint2/index.rst @@ -1,11 +1,6 @@ Sprint 2: 03 Mag - 16 Mag ========================= -.. todo:: - - Inserire informazioni generali sullo sprint, come inizio e fine. - - Consegna -------- @@ -16,26 +11,47 @@ La seguente documentazione è stata fornita dal cliente durante questo sprint: Goal ---- +Il **goal** del secondo sprint è stato la creazione, cancellazione e modifica dei repository, ovvero permettere agli utenti +di creare repo partendo da una ricerca che rispetta determinate condizioni. -.. todo:: +Tutto ciò è visibile dai task completati: + +.. image:: Sprint2Task.png + :width: 390 - Inserire qui lo sprint goal. Backlog ------- -.. todo:: +.. image:: BacklogSprint2.png + :width: 400 - Mostrare qui lo sprint backlog di Taiga. +**Burndown Chart** + +.. image:: Chart2.png + :width: 600 -Definition of done +Definition of Ready ------------------ -.. todo:: +Il team ha definito lo stato di Ready di una User Story in base ai seguenti criteri: +* La User Story è stata compresa ed accettata da tutti i membri +* I tester hanno confermato la possibilità di poterla testare +* Il Product Owner ha la visione necessaria per definirne la priorità +* Il Team è in grado di stimarla +* La User Story è indipendente o dipendente da altre a priorità maggiore + +Definition of Done +------------------ + +La definizione di Done è stata concordata da tutto il team con il Product Owner, ed è stata così definita: +* Sviluppo completo della funzionalità richiesta +* Definizione e superamento dei test +* Bozza della documentazione della funzionalità +* Merge dei sorgenti nel branch ‘Main’ di GitLab - Inserire qui la definition of done dello sprint. Registro attività @@ -423,9 +439,14 @@ Questa statistica è stata generata dal prof. Marcello Missiroli con .. _Gitinspector: https://github.com/ejwa/gitinspector +Sprint retrospective +-------------------- +- :download:`Sprint 2 Retrospective ` + + Sprint review ------------- -.. todo:: +Il video di sprint review è disponibile al seguente link: - Inserire un link alla sprint review. +- https://drive.google.com/file/d/1x1kub-bpVJrwmGrn5LLU8ecqcbxFaoKg/view?usp=sharing diff --git a/docs/source/development/sprint3/Backlog3.png b/docs/source/development/sprint3/Backlog3.png new file mode 100644 index 0000000..e52a13c Binary files /dev/null and b/docs/source/development/sprint3/Backlog3.png differ diff --git a/docs/source/development/sprint3/Chart3.png b/docs/source/development/sprint3/Chart3.png new file mode 100644 index 0000000..7dafa10 Binary files /dev/null and b/docs/source/development/sprint3/Chart3.png differ diff --git a/docs/source/development/sprint3/Task3.png b/docs/source/development/sprint3/Task3.png new file mode 100644 index 0000000..ae657ba Binary files /dev/null and b/docs/source/development/sprint3/Task3.png differ diff --git a/docs/source/development/sprint3/index.rst b/docs/source/development/sprint3/index.rst index a5c6b82..050384c 100644 --- a/docs/source/development/sprint3/index.rst +++ b/docs/source/development/sprint3/index.rst @@ -1,11 +1,6 @@ Sprint 3: 17 Mag - 30 Mag ========================= -.. todo:: - - Inserire informazioni generali sullo sprint, come inizio e fine. - - Consegna -------- @@ -18,25 +13,52 @@ La seguente documentazione è stata fornita dal cliente durante questo sprint: Goal ---- -.. todo:: +Il **goal** del terzo Sprint è stato far funzionare il crawler, gli alert e completare tutte i task rimanenti. + +Tutto ciò è visibile dai task completati: + +.. image:: Task3.png + :width: 400 + +Grooming session +---------------- + +Sono state definite le nuove User Stories da inserire nel progetto sulla base delle nuove richieste pervenute dal cliente: analisi statistica più dettagliata, postare su Twitter, traduzione dell'interfaccia in inglese. +La richiesta relativa alle ricerche basate sulla geolocalizzazione, come già comunicato al cliente, non è stata inserita per motivi tecnici legati alle features delle API 1.1 che non permettono di eseguire query sui campi di posizione geografica. +Le nuove User Stories sono state valutate tramite il metodo dello Scrum Poker, durante il quale ogni membro ha espresso la sua valutazione. +Tutte le nuove richieste sono state accettate dal Product Owner e sono pronte ad essere inserite nello sprint di sviluppo in partenza. - Inserire qui lo sprint goal. Backlog ------- +.. image:: Backlog3.png + :width: 400 -.. todo:: +**Burndown Chart** - Mostrare qui lo sprint backlog di Taiga. +.. image:: Chart3.png + :width: 600 -Definition of done +Definition of Ready ------------------ -.. todo:: +Il team ha definito lo stato di Ready di una User Story in base ai seguenti criteri: +* La User Story è stata compresa ed accettata da tutti i membri +* I tester hanno confermato la possibilità di poterla testare +* Il Product Owner ha la visione necessaria per definirne la priorità +* Il Team è in grado di stimarla +* La User Story è indipendente o dipendente da altre a priorità maggiore - Inserire qui la definition of done dello sprint. +Definition of Done +------------------ + +La definizione di Done è stata concordata da tutto il team con il Product Owner, ed è stata così definita: +* Sviluppo completo della funzionalità richiesta +* Definizione e superamento dei test +* Bozza della documentazione della funzionalità +* Merge dei sorgenti nel branch ‘Main’ di GitLab Registro attività @@ -81,12 +103,24 @@ Stefano Goldoni - Durata - Attività * - - - + - 14h - Totale - * - - - - - + * - 21/05 + - 2.0h + - Analisi strumenti di test frontend + * - 24/05 + - 3.0h + - Inizio test alerts + * - 25/05 + - 2.5h + - Test alerts + * - 26/05 + - 3.0h + - Test + * - 28/05 + - 3.5h + - Test, refactory in base a Sonarqube Flavia Cocca @@ -117,12 +151,42 @@ Chiara Calzolari - Durata - Attività * - - - + - 17h 30m - Totale - * - - - - - + * - 17/05 + - 3.0h + - Traduzione UI + * - 17/05 + - 1.5h + - Traduzione UI + * - 18/05 + - 1.5h + - Traduzione UI + * - 20/05 + - 1.0h + - Traduzione UI + * - 22/05 + - 1.0h + - Traduzione UI + * - 24/05 + - 2.0h + - Traduzione UI + * - 24/05 + - 1.0h + - Traduzione UI + * - 25/05 + - 1.0h + - Traduzione UI + * - 27/05 + - 0.5h + - Traduzione UI + * - 28/05 + - 2.0h + - Configurazione ambiente di sviluppo + * - 28/05 + - 3.0h + - Creazione video-demo Stefano Pigozzi @@ -189,12 +253,33 @@ Lorenzo Balugani - Durata - Attività * - - - + - 22h - Totale - * - - - - - + * - 17/05 + - 4h + - Bugfixing, supporto alla localizzazione degli errori + * - 18/05 + - 3h + - Bugfixing + * - 20/05 + - 3h + - API autorizzazioni, refactoring + * - 21/05 + - 2h + - Gestione tweet, rappresentazione tweet + * - 24/05 + - 2h + - Bugfixing + * - 25/05 + - 4h + - Docs, refactoring + * - 27/05 + - 3h + - Bugfixing + * - 28/05 + - 6h + - Bugfixing Statistiche @@ -219,6 +304,9 @@ Retrospettiva finale Schermata finale di SonarQube ----------------------------- -.. todo:: +- :download:`Schermata finale Sonarqube ` - Inserire qui uno screenshot della schermata finale di SonarQube. +Demo +---- + +- https://drive.google.com/file/d/15o70Ffe51CNj8LTKHC9dGiqRVnbv9UpZ/view?usp=sharing diff --git a/docs/source/development/sprint3/sonarqube.pdf b/docs/source/development/sprint3/sonarqube.pdf new file mode 100644 index 0000000..ecda3af Binary files /dev/null and b/docs/source/development/sprint3/sonarqube.pdf differ diff --git a/docs/source/development/tools.rst b/docs/source/development/tools.rst index 0f93938..a20bd79 100644 --- a/docs/source/development/tools.rst +++ b/docs/source/development/tools.rst @@ -40,8 +40,20 @@ Nello sviluppo di N.E.S.T. sono stati usati i seguenti strumenti software: È accessibile al seguente indirizzo: https://sonarqube.steffo.eu/ +`Figma`_ + + Applicazione web centralizzata per la creazione collaborativa di interfacce grafiche moderne. + +`Discord`_ + + Piattaforma centralizzata di messaggistica istantanea e chiamate vocali utilizzata per la comunicazione sincrona + tra i membri del team. + + .. _IntelliJ IDEA Ultimate: https://www.jetbrains.com/idea/ .. _Git: https://git-scm.com/ .. _GitLab: https://about.gitlab.com/ .. _Taiga: https://www.taiga.io/ .. _SonarQube: https://www.sonarqube.org/ +.. _Figma: https://www.figma.com/ +.. _Discord: https://discord.com/ diff --git a/docs/source/index.rst b/docs/source/index.rst index a1692fc..af54e51 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -31,11 +31,18 @@ Benvenuto alla documentazione di N.E.S.T.! :caption: Documentazione tecnica code/meta/index + code/database/index code/backend/index code/crawler/index code/frontend/index +.. toctree:: + :hidden: + + development/clientinterview + + Cose rimaste da fare -------------------- diff --git a/legacy/doc/development/sprint-0/backlog.pdf b/legacy/doc/development/sprint-0/backlog.pdf deleted file mode 100644 index 56cab5b..0000000 Binary files a/legacy/doc/development/sprint-0/backlog.pdf and /dev/null differ diff --git a/legacy/doc/development/sprint-0/behavioral-diagrams.pdf b/legacy/doc/development/sprint-0/behavioral-diagrams.pdf deleted file mode 100644 index 6056884..0000000 Binary files a/legacy/doc/development/sprint-0/behavioral-diagrams.pdf and /dev/null differ diff --git a/legacy/doc/development/sprint-0/design-pattern.pdf b/legacy/doc/development/sprint-0/design-pattern.pdf deleted file mode 100644 index ebbcc27..0000000 Binary files a/legacy/doc/development/sprint-0/design-pattern.pdf and /dev/null differ diff --git a/legacy/doc/development/sprint-0/epics.pdf b/legacy/doc/development/sprint-0/epics.pdf deleted file mode 100644 index 2b91bc9..0000000 Binary files a/legacy/doc/development/sprint-0/epics.pdf and /dev/null differ diff --git a/legacy/doc/development/sprint-0/future-backlog-goal.pdf b/legacy/doc/development/sprint-0/future-backlog-goal.pdf deleted file mode 100644 index 0c2e74b..0000000 Binary files a/legacy/doc/development/sprint-0/future-backlog-goal.pdf and /dev/null differ diff --git a/legacy/doc/development/sprint-0/pages.pdf b/legacy/doc/development/sprint-0/pages.pdf deleted file mode 100644 index 190eff0..0000000 Binary files a/legacy/doc/development/sprint-0/pages.pdf and /dev/null differ diff --git a/legacy/doc/development/sprint-0/ui-mockup.md b/legacy/doc/development/sprint-0/ui-mockup.md deleted file mode 100644 index dfe5a4d..0000000 --- a/legacy/doc/development/sprint-0/ui-mockup.md +++ /dev/null @@ -1,3 +0,0 @@ -# UI Mockup - -[Disponibile su Figma](https://www.figma.com/file/CA6VnMo3NIHnqSJNZGWAvT/N.E.S.T.?node-id=12%3A4) \ No newline at end of file diff --git a/legacy/doc/development/sprint-0/ui-mockup.pdf b/legacy/doc/development/sprint-0/ui-mockup.pdf deleted file mode 100644 index 08f3c74..0000000 Binary files a/legacy/doc/development/sprint-0/ui-mockup.pdf and /dev/null differ diff --git a/legacy/doc/development/sprint-0/video.md b/legacy/doc/development/sprint-0/video.md deleted file mode 100644 index 9338c55..0000000 --- a/legacy/doc/development/sprint-0/video.md +++ /dev/null @@ -1 +0,0 @@ -https://drive.google.com/file/d/12worWEcx-uf2UP4_lnEOovHZpvR77MsG/view?usp=sharing diff --git a/legacy/doc/log/sprint-3.md b/legacy/doc/log/sprint-3.md index a508357..c000ac7 100644 --- a/legacy/doc/log/sprint-3.md +++ b/legacy/doc/log/sprint-3.md @@ -4,7 +4,7 @@ |------|-----|--------|----------| | | | | | -Totale generale di tutti i componenti: 12.5h +Totale generale di tutti i componenti: 39.5h # Log attività individuali dello Sprint 3 @@ -15,9 +15,13 @@ Stefano Goldoni - Product Owner & Tester | Data | Durata | Attività | |-------|--------|----------| -| | | | +|21/05 |2.0h |analisi strumenti di test frontend +|24/05 |3.0h |inizio test alerts +|25/05 |2.5h |test alerts +|26/05 |3.0h |test +|28/05 |3.5h |test, refactory in base a sonarqube |-------|--------| -|totale| __._h | +|totale| 14.0h | Flavia Cocca - Scrum Master & UI Designer @@ -83,8 +87,10 @@ Chiara Calzolari - UI Designer | 24/05 | 1.0h | Traduzione UI | 25/05 | 1.0h | Traduzione UI | 27/05 | 0.5h | Traduzione UI +| 28/05 | 2.0h | Configurazione ambiente di sviluppo +| 28/05 | 3.0h | Creazione video-demo |-------|--------| -|totale| 12.5h | +|totale| 17.5h | diff --git a/nest_backend/routes/repository/alerts/alert.py b/nest_backend/routes/repository/alerts/alert.py index a5f2e90..e6f65fc 100644 --- a/nest_backend/routes/repository/alerts/alert.py +++ b/nest_backend/routes/repository/alerts/alert.py @@ -4,7 +4,7 @@ from flask_jwt_extended import jwt_required, get_jwt_identity from nest_backend.gestione import * from flask_cors import cross_origin import datetime -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -150,16 +150,16 @@ def page_alert(aid): user = find_user(get_jwt_identity()) alert = Alert.query.filter_by(id=aid).first() if not alert or alert.repository.is_deleted: - return json_error("Could not find alert.", ALERT_NOT_FOUND), 404 + return json_error("Could not find alert.", errors.ALERT_NOT_FOUND), 404 if alert.repository not in [a.repository for a in user.authorizations] + user.owner_of: - return json_error("You are not authorized to proceed.", USER_NOT_AUTHORIZED), 403 + return json_error("You are not authorized to proceed.", errors.USER_NOT_AUTHORIZED), 403 if request.method == "GET": return json_success(alert.to_json()), 200 if alert.repository not in user.owner_of: - return json_error("You are not authorized to proceed.", REPOSITORY_NOT_OWNER), 403 + return json_error("You are not authorized to proceed.", errors.REPOSITORY_NOT_OWNER), 403 if request.method == "PATCH": if request.json is None: - return json_error("Missing json content.", GENERIC_NO_JSON), 400 + return json_error("Missing json content.", errors.GENERIC_NO_JSON), 400 if 'name' in request.json: alert.name = request.json['name'] @@ -171,9 +171,9 @@ def page_alert(aid): try: alert.evaluation_mode = ConditionMode(request.json['evaluation_mode']) except KeyError: - return json_error("Unknown `evaluation_mode` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `evaluation_mode` specified.", errors.GENERIC_ENUM_INVALID), 400 except Exception as e: - return json_error("Unknown error:" + str(e), GENERIC_UFO), 400 + return json_error("Unknown error:" + str(e), errors.GENERIC_UFO), 400 ext.session.commit() return json_success(alert.to_json()), 200 elif request.method == "DELETE": @@ -191,14 +191,14 @@ def page_alert(aid): ext.session.delete(alert) ext.session.commit() except Exception as e: - return json_error("Something went wrong while deleting alert.", ALERT_DELETION_FAILURE), 500 + return json_error("Something went wrong while deleting alert.", errors.ALERT_DELETION_FAILURE), 500 return json_success("Deletion completed."), 204 elif request.method == "PUT": if request.json is None: - return json_error("Missing json content.", GENERIC_NO_JSON), 400 + return json_error("Missing json content.", errors.GENERIC_NO_JSON), 400 if not json_request_authorizer(request.json, alert): - return json_error("Missing one or more parameters in alert json.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing one or more parameters in alert json.", errors.GENERIC_MISSING_FIELDS), 400 alert.limit = request.json['limit'] alert.name = request.json['name'] alert.window_size = request.json['window_size'] @@ -206,9 +206,9 @@ def page_alert(aid): try: alert.evaluation_mode = ConditionMode(mode) except KeyError: - return json_error("Unknown `evaluation_mode` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `evaluation_mode` specified.", errors.GENERIC_ENUM_INVALID), 400 except Exception as e: - return json_error("Unknown error:" + str(e), GENERIC_UFO), 400 + return json_error("Unknown error:" + str(e), errors.GENERIC_UFO), 400 if request.json['conditions'] is not None: # Wow very pythonic so much wow # Obtain list of no longer needed connections @@ -223,15 +223,15 @@ def page_alert(aid): for c in request.json['conditions']: if not c.get("id"): if (type_ := c.get("type")) is None: - return json_error("Missing `type` parameter.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing `type` parameter.", errors.GENERIC_MISSING_FIELDS), 400 try: type_ = ConditionType(type_) except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 except Exception as e: return json_error("Unknown error: " + str(e)), 400 if not (content := c.get("content")): - return json_error("Missing `content` parameter.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing `content` parameter.", errors.GENERIC_MISSING_FIELDS), 400 if type_ == ConditionType.hashtag: content = hashtag_validator(content) con = Condition(content=content, type=type_, repository_id=alert.repository_id) diff --git a/nest_backend/routes/repository/alerts/repository_alerts.py b/nest_backend/routes/repository/alerts/repository_alerts.py index 785d2f9..90b8d64 100644 --- a/nest_backend/routes/repository/alerts/repository_alerts.py +++ b/nest_backend/routes/repository/alerts/repository_alerts.py @@ -3,7 +3,7 @@ from nest_backend.database import * from flask_jwt_extended import jwt_required, get_jwt_identity from nest_backend.gestione import * from flask_cors import cross_origin -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -73,30 +73,30 @@ def page_repository_alerts(rid): repository = Repository.query.filter_by(id=rid, is_deleted=False).first() if not repository: - return json_error("Could not find repository", REPOSITORY_NOT_FOUND), 404 + return json_error("Could not find repository", errors.REPOSITORY_NOT_FOUND), 404 user = find_user(get_jwt_identity()) if user.email != repository.owner_id: - return json_error("You are not authorized.", REPOSITORY_NOT_OWNER), 403 + return json_error("You are not authorized.", errors.REPOSITORY_NOT_OWNER), 403 if request.method == "GET": return json_success([alert.to_json() for alert in repository.alerts]) if request.method == "POST": if 'name' not in request.json: - return json_error("Missing name.", ALERT_NO_NAME), 400 + return json_error("Missing name.", errors.ALERT_NO_NAME), 400 if 'limit' not in request.json: - return json_error('Missing limit', ALERT_NO_LIMIT), 400 + return json_error('Missing limit', errors.ALERT_NO_LIMIT), 400 if 'window_size' not in request.json: - return json_error('Missing window size', ALERT_NO_WINDOW), 400 + return json_error('Missing window size', errors.ALERT_NO_WINDOW), 400 if (mode := request.json.get("evaluation_mode")) is not None: try: mode = ConditionMode(mode) except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 except Exception as e: - return json_error("Unknown error:" + str(e), GENERIC_UFO), 400 + return json_error("Unknown error:" + str(e), errors.GENERIC_UFO), 400 else: - return json_error("Evaluation mode was not provided.", ALERT_NO_EVALUATION), 400 + return json_error("Evaluation mode was not provided.", errors.ALERT_NO_EVALUATION), 400 alert = Alert(name=request.json['name'], limit=request.json['limit'], window_size=request.json['window_size'], repository_id=rid, evaluation_mode=mode) @@ -105,15 +105,15 @@ def page_repository_alerts(rid): if request.json['conditions'] is not None: for condition in request.json['conditions']: if (type_ := condition.get("type")) is None: - return json_error("Missing `type` parameter.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing `type` parameter.", errors.GENERIC_MISSING_FIELDS), 400 try: type_ = ConditionType(type_) except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 except Exception as e: return json_error("Unknown error: " + str(e)), 400 if not (content := condition.get("content")): - return json_error("Missing `content` parameter.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing `content` parameter.", errors.GENERIC_MISSING_FIELDS), 400 if type_ == ConditionType.hashtag: content = hashtag_validator(content) c = Condition(content=content, type=type_) diff --git a/nest_backend/routes/repository/authorizations/authorization.py b/nest_backend/routes/repository/authorizations/authorization.py index cf6b932..0602813 100644 --- a/nest_backend/routes/repository/authorizations/authorization.py +++ b/nest_backend/routes/repository/authorizations/authorization.py @@ -3,7 +3,7 @@ from nest_backend.database import * from flask_jwt_extended import jwt_required, get_jwt_identity from nest_backend.gestione import * from flask_cors import cross_origin -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -42,12 +42,12 @@ def page_authorization(rid, email): repository = Repository.query.filter_by(id=rid, is_deleted=False).first() user = find_user(get_jwt_identity()) if not repository: - return json_error("Could not find the repository.", REPOSITORY_NOT_FOUND), 404 + return json_error("Could not find the repository.", errors.REPOSITORY_NOT_FOUND), 404 if user != repository.owner: - return json_error("You are not authorized.", USER_NOT_AUTHORIZED), 403 + return json_error("You are not authorized.", errors.USER_NOT_AUTHORIZED), 403 authorization = Authorization.query.filter_by(rid=rid, email=email).first() if not authorization: - return json_error("Could not find the authorization", AUTHORIZATION_NOT_FOUND), 404 + return json_error("Could not find the authorization", errors.AUTHORIZATION_NOT_FOUND), 404 if request.method == "DELETE": ext.session.delete(authorization) ext.session.commit() diff --git a/nest_backend/routes/repository/authorizations/repository_authorizations.py b/nest_backend/routes/repository/authorizations/repository_authorizations.py index 9afc0a2..7dd3f57 100644 --- a/nest_backend/routes/repository/authorizations/repository_authorizations.py +++ b/nest_backend/routes/repository/authorizations/repository_authorizations.py @@ -4,7 +4,7 @@ from nest_backend.gestione import repository_auth, json_error, json_success, fin from nest_backend.database import ext, User, Authorization, Repository from flask_cors import cross_origin from nest_backend.gestione import hashtag_validator -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -114,24 +114,24 @@ def page_repository_authorizations(rid): repository = Repository.query.filter_by(id=rid, is_deleted=False).first() if not repository: - return json_error("Could not find repository", REPOSITORY_NOT_FOUND), 404 + return json_error("Could not find repository", errors.REPOSITORY_NOT_FOUND), 404 user = find_user(get_jwt_identity()) if user.email != repository.owner_id: - return json_error("You are not authorized.", REPOSITORY_NOT_OWNER), 403 + return json_error("You are not authorized.", errors.REPOSITORY_NOT_OWNER), 403 if request.method == "GET": try: return json_success([a.to_json() for a in repository.authorizations]) except Exception as e: - return json_error("Unknown error:" + str(e), GENERIC_UFO), 400 + return json_error("Unknown error:" + str(e), errors.GENERIC_UFO), 400 if request.json is None: - return json_error("Missing json content.", GENERIC_NO_JSON), 400 + return json_error("Missing json content.", errors.GENERIC_NO_JSON), 400 if not request.json.get("email"): - return json_error("Missing user email.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing user email.", errors.GENERIC_MISSING_FIELDS), 400 target = User.query.filter_by(email=request.json.get('email')).first() if not target: - return json_error("User could not be located", USER_NOT_FOUND), 400 + return json_error("User could not be located", errors.USER_NOT_FOUND), 400 if target == user: - return json_error("Owner cannot be a spectator", GENERIC_ALREADY_EXISTS), 406 + return json_error("Owner cannot be a spectator", errors.GENERIC_ALREADY_EXISTS), 406 if request.method == "POST": authorization = Authorization(email=request.json.get('email'), rid=repository.id) ext.session.add(authorization) diff --git a/nest_backend/routes/repository/conditions/condition.py b/nest_backend/routes/repository/conditions/condition.py index 57a8e38..68fda3f 100644 --- a/nest_backend/routes/repository/conditions/condition.py +++ b/nest_backend/routes/repository/conditions/condition.py @@ -3,7 +3,7 @@ from nest_backend.database import * from flask_jwt_extended import jwt_required, get_jwt_identity from nest_backend.gestione import * from flask_cors import cross_origin -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -107,25 +107,25 @@ def page_condition(cid): condition = Condition.query.filter_by(id=cid).first() user = find_user(get_jwt_identity()) if not condition or condition.repository.is_deleted: - return json_error("Could not find the condition.", CONDITION_NOT_FOUND), 404 + return json_error("Could not find the condition.", errors.CONDITION_NOT_FOUND), 404 if condition.repository not in [a.repository for a in user.authorizations] + user.owner_of and not user.isAdmin: - return json_error("You lack the authorization to proceed, pal.", USER_NOT_AUTHORIZED), 403 + return json_error("You lack the authorization to proceed, pal.", errors.USER_NOT_AUTHORIZED), 403 if request.method == "GET": return json_success(condition.to_json()), 200 if condition.repository not in user.owner_of and not user.isAdmin: - return json_error("You lack the authorization to proceed, pal.", USER_NOT_AUTHORIZED), 403 + return json_error("You lack the authorization to proceed, pal.", errors.USER_NOT_AUTHORIZED), 403 if request.method == "PATCH": if request.json is None: - return json_error("Missing json content.", GENERIC_NO_JSON), 400 + return json_error("Missing json content.", errors.GENERIC_NO_JSON), 400 if (type_ := request.json.get("type")) is not None: try: type_ = ConditionType(type_) condition.type = type_ except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 except Exception as e: - return json_error("Unknown error:" + str(e), GENERIC_UFO), 400 + return json_error("Unknown error:" + str(e), errors.GENERIC_UFO), 400 if content := request.json.get("content"): condition.content = content diff --git a/nest_backend/routes/repository/conditions/repository_conditions.py b/nest_backend/routes/repository/conditions/repository_conditions.py index 6cca26e..773c0fc 100644 --- a/nest_backend/routes/repository/conditions/repository_conditions.py +++ b/nest_backend/routes/repository/conditions/repository_conditions.py @@ -5,7 +5,7 @@ from nest_backend.gestione import repository_auth, json_error, json_success, Con from nest_backend.database import ext from flask_cors import cross_origin from nest_backend.gestione import hashtag_validator -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -75,34 +75,34 @@ def page_repository_conditions(rid): repository = Repository.query.filter_by(id=rid, is_deleted=False).first() if not repository: - return json_error("Could not find repository", REPOSITORY_NOT_FOUND), 404 + return json_error("Could not find repository", errors.REPOSITORY_NOT_FOUND), 404 user = find_user(get_jwt_identity()) if request.method == "GET": try: return json_success([u.to_json() for u in repository.conditions]) except Exception as e: - return json_error("Unknown error:" + str(e), GENERIC_UFO), 400 + return json_error("Unknown error:" + str(e), errors.GENERIC_UFO), 400 if user.email != repository.owner_id: - return json_error("You are not authorized.", REPOSITORY_NOT_OWNER), 403 + return json_error("You are not authorized.", errors.REPOSITORY_NOT_OWNER), 403 if request.method == "POST": if request.json is None: - return json_error("Missing json content.", GENERIC_NO_JSON), 400 + return json_error("Missing json content.", errors.GENERIC_NO_JSON), 400 if (type_ := request.json.get("type")) is None: - return json_error("Missing `type` parameter.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing `type` parameter.", errors.GENERIC_MISSING_FIELDS), 400 try: type_ = ConditionType(type_) except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 except Exception as e: return json_error("Unknown error: " + str(e)), 400 if not (content := request.json.get("content")): - return json_error("Missing `content` parameter.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing `content` parameter.", errors.GENERIC_MISSING_FIELDS), 400 if type_ == ConditionType.hashtag: content = hashtag_validator(content) condition = Condition(content=content, type=type_, repository_id=rid) diff --git a/nest_backend/routes/repository/repositories.py b/nest_backend/routes/repository/repositories.py index 0da0ff6..d66af95 100644 --- a/nest_backend/routes/repository/repositories.py +++ b/nest_backend/routes/repository/repositories.py @@ -4,7 +4,7 @@ from flask_jwt_extended import jwt_required, get_jwt_identity from nest_backend.gestione import * import datetime from flask_cors import cross_origin -from nest_backend.errors import * +import nest_backend.errors as errors from nest_crawler.repo_search import search_repo_conditions import threading @@ -85,12 +85,12 @@ def page_repositories(): # Users will be tolerated if they change parameters they're not supposed to touch. We'll ignore them for now. if not request.json.get("name") or not request.json.get("conditions") or not str( request.json.get("evaluation_mode")): - return json_error("Missing arguments.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing arguments.", errors.GENERIC_MISSING_FIELDS), 400 name = request.json.get("name") try: evaluation_mode = ConditionMode(request.json['evaluation_mode']) except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 except Exception as e: return json_error("Unknown error: " + str(e)), 400 repository = Repository(name=name, owner_id=user.email, is_active=False, evaluation_mode=evaluation_mode) @@ -108,7 +108,7 @@ def page_repositories(): try: type_ = ConditionType(c['type']) except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 ext.session.add(Condition(type=type_, content=c['content'], repository_id=repository.id)) ext.session.commit() repository.is_active = True diff --git a/nest_backend/routes/repository/repository.py b/nest_backend/routes/repository/repository.py index 68c4d3e..a9a35e2 100644 --- a/nest_backend/routes/repository/repository.py +++ b/nest_backend/routes/repository/repository.py @@ -4,7 +4,7 @@ from flask_jwt_extended import jwt_required, get_jwt_identity from nest_backend.gestione import * from flask_cors import cross_origin import datetime -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -156,11 +156,11 @@ def page_repository(rid): user = find_user(get_jwt_identity()) repository = Repository.query.filter_by(id=rid, is_deleted=False).first() if not repository: - return json_error("Could not find repository.", REPOSITORY_NOT_FOUND), 404 + return json_error("Could not find repository.", errors.REPOSITORY_NOT_FOUND), 404 if request.method == "GET": return json_success(repository.to_json()), 200 if user.email != repository.owner_id: - return json_error("You are not the owner of this repository.", REPOSITORY_NOT_OWNER), 403 + return json_error("You are not the owner of this repository.", errors.REPOSITORY_NOT_OWNER), 403 elif request.method == "PATCH": if 'name' in request.json: repository.name = request.json['name'] @@ -173,7 +173,7 @@ def page_repository(rid): try: evaluation_mode = ConditionMode(request.json['evaluation_mode']) except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 repository.evaluation_mode = evaluation_mode ext.session.commit() return json_success(repository.to_json()), 204 @@ -183,16 +183,16 @@ def page_repository(rid): ext.session.commit() except Exception as e: ext.session.rollback() - return json_error("Cant delete repository because of dependencies.", REPOSITORY_DEPENDENCY_FAILURE), 500 + return json_error("Cant delete repository because of dependencies.", errors.REPOSITORY_DEPENDENCY_FAILURE), 500 return json_success("Success"), 204 elif request.method == "PUT": if not json_request_authorizer(request.json, repository): - return json_error("Missing one or more parameters in repository json.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing one or more parameters in repository json.", errors.GENERIC_MISSING_FIELDS), 400 # Users will be tolerated if they change parameters they're not supposed to touch. We'll ignore them for now. try: evaluation_mode = ConditionMode(request.json['evaluation_mode']) except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 repository.evaluation_mode = evaluation_mode repository.name = request.json['name'] repository.is_active = request.json['is_active'] @@ -210,14 +210,14 @@ def page_repository(rid): ext.session.delete(c) ext.session.commit() except Exception as e: - return json_error("Could not delete conditions.", GENERIC_UFO), 500 + return json_error("Could not delete conditions.", errors.GENERIC_UFO), 500 # Create brand new conditions for c in request.json['conditions']: if not c['id']: try: type_ = ConditionType(c['type']) except KeyError: - return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400 + return json_error("Unknown `type` specified.", errors.GENERIC_ENUM_INVALID), 400 content = c['content'] if type_ == ConditionType.hashtag: content = hashtag_validator(content) diff --git a/nest_backend/routes/repository/tweets/repository_tweets.py b/nest_backend/routes/repository/tweets/repository_tweets.py index ce8d427..7da1f81 100644 --- a/nest_backend/routes/repository/tweets/repository_tweets.py +++ b/nest_backend/routes/repository/tweets/repository_tweets.py @@ -5,7 +5,7 @@ from nest_backend.gestione import repository_auth, json_error, json_success, Con from nest_backend.database import ext from flask_cors import cross_origin from nest_backend.gestione import hashtag_validator -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -45,11 +45,11 @@ def page_repository_tweets(rid): repository = Repository.query.filter_by(id=rid, is_deleted=False).first() if not repository: - return json_error("Could not find repository", REPOSITORY_NOT_FOUND), 404 + return json_error("Could not find repository", errors.REPOSITORY_NOT_FOUND), 404 user = find_user(get_jwt_identity()) if user.email != repository.owner_id and user.email not in [a.email for a in repository.authorizations]: - return json_error("You are not authorized.", USER_NOT_AUTHORIZED), 403 + return json_error("You are not authorized.", errors.USER_NOT_AUTHORIZED), 403 if request.method == "GET": return json_success([t.tweet.to_json() for t in repository.tweets]) diff --git a/nest_backend/routes/users/login.py b/nest_backend/routes/users/login.py index 0178c44..e99f03d 100644 --- a/nest_backend/routes/users/login.py +++ b/nest_backend/routes/users/login.py @@ -4,7 +4,7 @@ from nest_backend.gestione import * from flask_jwt_extended import create_access_token from flask_cors import cross_origin from datetime import timedelta, datetime -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -43,4 +43,4 @@ def page_login(): access_token = create_access_token(identity=email, expires_delta=delta) user = find_user(email) return json_success({"access_token": access_token, 'user': user.to_json(), "expiration": expiration}), 201 - return json_error("Bad username or password.", USER_WRONG_CREDENTIALS), 401 + return json_error("Bad username or password.", errors.USER_WRONG_CREDENTIALS), 401 diff --git a/nest_backend/routes/users/user.py b/nest_backend/routes/users/user.py index 475ee44..63ceb1b 100644 --- a/nest_backend/routes/users/user.py +++ b/nest_backend/routes/users/user.py @@ -3,7 +3,7 @@ from nest_backend.database import * from flask_jwt_extended import jwt_required, get_jwt_identity from nest_backend.gestione import * from flask_cors import cross_origin -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -118,16 +118,16 @@ def page_user(email): user = find_user(get_jwt_identity()) target = find_user(email) if not target: - return json_error("Could not locate the user.", USER_NOT_FOUND), 404 + return json_error("Could not locate the user.", errors.USER_NOT_FOUND), 404 if request.method == "GET": if not email == user.email and not user.isAdmin: - return json_error("Thou art not authorized.", USER_NOT_AUTHORIZED), 403 + return json_error("Thou art not authorized.", errors.USER_NOT_AUTHORIZED), 403 return json_success(target.to_json()) elif request.method == "DELETE": if not user.isAdmin: - return json_error("User is not admin.", USER_NOT_ADMIN), 403 + return json_error("User is not admin.", errors.USER_NOT_ADMIN), 403 if user == target: - return json_error("The user cant delete himself. Its a sin.", USER_PREVENT_SEPPUKU), 406 + return json_error("The user cant delete himself. Its a sin.", errors.USER_PREVENT_SEPPUKU), 406 repos = target.owner_of for repository in repos: repository.owner_id = user.email @@ -140,11 +140,11 @@ def page_user(email): ext.session.commit() except Exception as e: ext.session.rollback() - return json_error("Could not delete the user.", USER_DELETION_ERROR), 500 + return json_error("Could not delete the user.", errors.USER_DELETION_ERROR), 500 return json_success(""), 204 # "The user has been deleted." elif request.method == "PATCH": if not email == user.email and not user.isAdmin: - return json_error("Thou art not authorized.", USER_NOT_AUTHORIZED), 403 + return json_error("Thou art not authorized.", errors.USER_NOT_AUTHORIZED), 403 target = find_user(email) if request.json.get("username"): target.username = request.json.get("username") diff --git a/nest_backend/routes/users/users.py b/nest_backend/routes/users/users.py index 3225876..19e546e 100644 --- a/nest_backend/routes/users/users.py +++ b/nest_backend/routes/users/users.py @@ -3,7 +3,7 @@ from nest_backend.database import * from flask_jwt_extended import jwt_required, get_jwt_identity from nest_backend.gestione import * from flask_cors import cross_origin -from nest_backend.errors import * +import nest_backend.errors as errors @cross_origin() @@ -69,11 +69,11 @@ def page_users(): return json_success([user.to_json() for user in users]), 200 if request.method == "POST": if not user.isAdmin: - return json_error("User is not admin. Thou art not authorized.", USER_NOT_ADMIN), 403 + return json_error("User is not admin. Thou art not authorized.", errors.USER_NOT_ADMIN), 403 if not request.json.get("email") or not request.json.get("password") or not request.json.get("username"): - return json_error("Missing required fields.", GENERIC_MISSING_FIELDS), 400 + return json_error("Missing required fields.", errors.GENERIC_MISSING_FIELDS), 400 if User.query.filter_by(email=request.json.get("email")).first(): - return json_error("User already exists.", GENERIC_ALREADY_EXISTS), 406 + return json_error("User already exists.", errors.GENERIC_ALREADY_EXISTS), 406 new_user = User(email=request.json.get("email"), password=gen_password(request.json.get("password")), username=request.json.get("username")) ext.session.add(new_user) diff --git a/nest_backend/test/test_0_doa.py b/nest_backend/test/test_0_doa.py index 46534f1..714e263 100644 --- a/nest_backend/test/test_0_doa.py +++ b/nest_backend/test/test_0_doa.py @@ -6,3 +6,8 @@ from flask.testing import Client def test_doa(flask_client: Client, admin_headers): response = flask_client.get("/doa", headers=admin_headers) assert b"If you see this, the server is fine." in response.data + + +def test_sq_told_me_to_do_this(flask_client: Client, user_headers): + response = flask_client.post("/doa", headers=user_headers) + assert b"Hello there." in response.data diff --git a/nest_backend/test/test_1_user.py b/nest_backend/test/test_1_user.py index 38cf6b2..3cc30c3 100644 --- a/nest_backend/test/test_1_user.py +++ b/nest_backend/test/test_1_user.py @@ -24,7 +24,7 @@ class TestUserGetAll: assert r.json["result"] == "success" def test_for_failure(self, flask_client: Client, user_headers): - r = flask_client.get(f'/api/v1/users/', headers=user_headers) + r = flask_client.patch(f'/api/v1/users/', headers=user_headers) assert r.json["result"] == "failure" diff --git a/nest_backend/test/test_2_repository.py b/nest_backend/test/test_2_repository.py index 910c6ae..79eef1a 100644 --- a/nest_backend/test/test_2_repository.py +++ b/nest_backend/test/test_2_repository.py @@ -130,6 +130,11 @@ class TestRepositoryGet: assert r.status_code == 404 assert r.json["result"] == "failure" + def test_wrong_request_type(self, flask_client: Client, admin_headers): + r = flask_client.put(f'/api/v1/repositories/99', headers=admin_headers) + assert r.status_code == 404 + assert r.json["result"] == "failure" + def test_user__not_logged(self, flask_client: Client, ): r = flask_client.get(f'/api/v1/repositories/1') assert r.status_code == 401 @@ -168,6 +173,10 @@ class TestRepositoryPatch: }) assert r.status_code == 204 + def test_error_500(self, flask_client: Client, user_headers): + r = flask_client.patch(f'/api/v99/repositories/1', headers=user_headers) + assert r.status_code == 500 + class TestRepositoryDelete: def test_wrong_owner(self, flask_client: Client, user_headers): @@ -198,8 +207,7 @@ class TestRepositoryPut: assert r.status_code == 401 def test_bad_request(self, flask_client: Client, user_headers): - r = flask_client.put(f'/api/v1/repositories/1', headers=user_headers, - json={ + r = flask_client.put(f'/api/v1/repositories/1', headers=user_headers, json={ "name": "string", "close": "string", "open": "string", @@ -213,8 +221,8 @@ class TestRepositoryPut: assert r.status_code == 404 assert r.json["result"] == "failure" - def test_for_success(self, flask_client: Client, admin_headers): - r = flask_client.put(f'/api/v1/repositories/1', headers=admin_headers, json={ + def test_for_success(self, flask_client: Client, user_headers): + r = flask_client.put(f'/api/v1/repositories/1', headers=user_headers, json={ "conditions": [ { "content": "string", @@ -236,3 +244,7 @@ class TestRepositoryPut: "start": "2021-05-14T12:12:29.827Z" }) assert r.status_code == 200 + + def test_error_500(self, flask_client: Client, user_headers): + r = flask_client.put(f'/api/v99/repositories/1', headers=user_headers) + assert r.status_code == 500 diff --git a/nest_backend/test/test_3_condition.py b/nest_backend/test/test_3_condition.py index fb621e1..e7dc5b7 100644 --- a/nest_backend/test/test_3_condition.py +++ b/nest_backend/test/test_3_condition.py @@ -12,8 +12,8 @@ class TestConditionGetAllOfARepository: assert r.status_code == 404 assert r.json["result"] == "failure" - def test__unauthorized_repository(self, flask_client: Client, admin_headers): - r = flask_client.get(f'/api/v1/repositories/1/conditions/', headers=admin_headers) + def test__unauthorized_user(self, flask_client: Client, user_headers): + r = flask_client.get(f'/api/v1/repositories/2/conditions/', headers=user_headers) assert r.status_code == 403 assert r.json["result"] == "failure" diff --git a/nest_backend/test/test_4_alert.py b/nest_backend/test/test_4_alert.py index 49a8877..6343d91 100644 --- a/nest_backend/test/test_4_alert.py +++ b/nest_backend/test/test_4_alert.py @@ -157,12 +157,7 @@ class TestAlertPost: assert r.json["result"] == "success" - - - # test del file alert - - -class TestOneAlertOfARepository: +class TestAlertGet: def test_alert_not_found(self, flask_client: Client, user_headers): r = flask_client.get(f'/api/v1/alert/99', headers=user_headers) assert r.status_code == 404 @@ -174,7 +169,8 @@ class TestOneAlertOfARepository: assert r.status_code == 200 assert r.json["result"] == "success" - # test PATCH + +class TestAlertPatch: def test_patch_alert_no_json(self, flask_client: Client, user_headers): r = flask_client.patch(f'/api/v1/alert/1', headers=user_headers) assert r.status_code == 400 @@ -197,13 +193,150 @@ class TestOneAlertOfARepository: assert r.status_code == 200 assert r.json["result"] == "success" - # test PUT + +class TestAlertPut: + def test_for_success(self, flask_client: Client, user_headers): + r = flask_client.put(f'/api/v1/alert/2', headers=user_headers, json={ + "conditions": [ + { + "content": "string", + "id": 0, + "type": 0 + } + ], + "evaluation_mode": 0, + "id": 0, + "limit": 0, + "name": "string", + "notifications": [ + { + "id": 0, + "ora": "2021-05-29T11:32:38.664Z", + "repository_id": 0 + } + ], + "repository_id": 0, + "window_size": 0 + }) + assert r.status_code == 200 + def test_put_alert_no_json(self, flask_client: Client, user_headers): - r = flask_client.patch(f'/api/v1/alert/2', headers=user_headers) + r = flask_client.put(f'/api/v1/alert/2', headers=user_headers) assert r.status_code == 400 assert r.json["result"] == "failure" - # test DELETE + def test_put_alert_wrong_evaluation_mode(self, flask_client: Client, user_headers): + r = flask_client.put(f'/api/v1/alert/2', headers=user_headers, + json={ + "conditions": [ + { + "content": "string", + "id": 0, + "type": 0 + } + ], + "evaluation_mode": 99, + "id": 0, + "limit": 0, + "name": "string", + "notifications": [ + { + "id": 0, + "ora": "2021-05-28T18:23:22.324Z", + "repository_id": 0 + } + ], + "repository_id": 0, + "window_size": 0 + }) + assert r.status_code == 400 + assert r.json["result"] == "failure" + + def test_put_alert_empty_conditions_type(self, flask_client: Client, user_headers): + r = flask_client.put(f'/api/v1/alert/2', headers=user_headers, + json={ + "conditions": [ + { + "content": "string", + "id": 0 + } + ], + "evaluation_mode": 0, + "id": 0, + "limit": 0, + "name": "string", + "notifications": [ + { + "id": 0, + "ora": "2021-05-28T18:23:22.324Z", + "repository_id": 0 + } + ], + "repository_id": 0, + "window_size": 0 + }) + assert r.status_code == 400 + assert r.json["result"] == "failure" + + def test_put_alert_wrong_conditions_type(self, flask_client: Client, user_headers): + r = flask_client.put(f'/api/v1/alert/2', headers=user_headers, + json={ + "conditions": [ + { + "content": "string", + "id": 0, + "type": 99 + } + ], + "evaluation_mode": 0, + "id": 0, + "limit": 0, + "name": "string", + "notifications": [ + { + "id": 0, + "ora": "2021-05-28T18:23:22.324Z", + "repository_id": 0 + } + ], + "repository_id": 0, + "window_size": 0 + }) + assert r.status_code == 400 + assert r.json["result"] == "failure" + + def test_put_alert_missing_conditions_content(self, flask_client: Client, user_headers): + r = flask_client.put(f'/api/v1/alert/2', headers=user_headers, + json={ + "conditions": [ + { + "id": 0, + "type": 99 + } + ], + "evaluation_mode": 0, + "id": 0, + "limit": 0, + "name": "string", + "notifications": [ + { + "id": 0, + "ora": "2021-05-28T18:23:22.324Z", + "repository_id": 0 + } + ], + "repository_id": 0, + "window_size": 0 + }) + assert r.status_code == 400 + assert r.json["result"] == "failure" + + +class TestAlertDelete: def test_delete_alert_for_success(self, flask_client: Client, user_headers): r = flask_client.delete(f'/api/v1/alert/1', headers=user_headers) assert r.status_code == 204 + + def test_error_500(self, flask_client: Client, user_headers): + r = flask_client.delete(f'/api/v99/alert/1', headers=user_headers) + assert r.status_code == 500 diff --git a/nest_backend/test/test_5_authorizations.py b/nest_backend/test/test_5_authorizations.py index b91ca7f..102ddca 100644 --- a/nest_backend/test/test_5_authorizations.py +++ b/nest_backend/test/test_5_authorizations.py @@ -74,9 +74,8 @@ class TestAuthorizationsPut: class TestAuthorizationsDelete: def test_for_success(self, flask_client: Client, user_headers): - r = flask_client.delete(f'/api/v1/repositories/1/authorizations/user_test@nest.com', headers=user_headers) + r = flask_client.delete(f'/api/v1/repositories/1/authorizations/admin@admin.com', headers=user_headers) assert r.status_code == 204 - assert r.json["result"] == "success" def test_user_not_logged(self, flask_client: Client): r = flask_client.delete(f'/api/v1/repositories/1/authorizations/user_test@nest.com') diff --git a/nest_backend/test/test_6_tweet.py b/nest_backend/test/test_6_tweet.py new file mode 100644 index 0000000..a8f822d --- /dev/null +++ b/nest_backend/test/test_6_tweet.py @@ -0,0 +1,25 @@ +from flask.testing import Client + +'''A file that contains tests classes and methods for all the requests concerning Tweets.''' +# TODO capire come passare i Tweet nell'URL + + +class TestTweetGet: + def test_for_success(self, flask_client: Client, user_headers): + r = flask_client.get(f'/api/v1/repositories/1/tweets/', headers=user_headers) + assert r.status_code == 200 + assert r.json["result"] == "success" + + def test_repository_not_found(self, flask_client: Client, user_headers): + r = flask_client.get(f'/api/v1/repositories/99/tweets/', headers=user_headers) + assert r.status_code == 404 + assert r.json["result"] == "failure" + + def test_user_wrong_owner(self, flask_client: Client, user_headers): + r = flask_client.get(f'/api/v1/repositories/2/tweets/', headers=user_headers) + assert r.status_code == 403 + assert r.json["result"] == "failure" + + def test_user_not_logged(self, flask_client: Client, ): + r = flask_client.get(f'/api/v1/repositories/2/tweets/') + assert r.status_code == 401 diff --git a/nest_crawler/__init__.py b/nest_crawler/__init__.py index 8d1c8b6..675c565 100644 --- a/nest_crawler/__init__.py +++ b/nest_crawler/__init__.py @@ -1 +1,4 @@ - +from .alert_trigger import * +from .associate_condition_tweet import * +from .authentication import * +from .repo_search import * diff --git a/nest_crawler/__main__.py b/nest_crawler/__main__.py index 9e00537..91a1c1e 100644 --- a/nest_crawler/__main__.py +++ b/nest_crawler/__main__.py @@ -1,7 +1,7 @@ from nest_backend.database import * -from nest_backend.app import app, extension_sqlalchemy -from nest_crawler.repo_search import search_repo_conditions -from alert_trigger import is_repo_alert_triggered +from nest_backend.app import app +from .repo_search import search_repo_conditions +from .alert_trigger import is_repo_alert_triggered ext.init_app(app=app) @@ -12,8 +12,7 @@ def search_all_repo(): search_repo_conditions(repo_id) is_repo_alert_triggered(repo_id) + if __name__ == "__main__": with app.app_context(): search_all_repo() - - diff --git a/nest_crawler/alert_trigger.py b/nest_crawler/alert_trigger.py index d22af0f..036aef8 100644 --- a/nest_crawler/alert_trigger.py +++ b/nest_crawler/alert_trigger.py @@ -1,9 +1,10 @@ from datetime import datetime, timedelta from nest_backend.database import * -from authentication import authenticate +from .authentication import authenticate import smtplib import tweepy as tw + def is_repo_alert_triggered(repository_id): repo = Repository.query.filter_by(id=repository_id).first() if repo is None: @@ -54,6 +55,7 @@ def send_notification_email(alert): except smtplib.SMTPException: print("Error: unable to send email") + def send_notification_tweet(alert): api = authenticate() conditions_string = '' @@ -66,3 +68,9 @@ def send_notification_tweet(alert): except tw.errors.Forbidden: print("Il tweet e' gia' stato pubblicato") + +__all__ = ( + "is_repo_alert_triggered", + "send_notification_email", + "send_notification_tweet", +) diff --git a/nest_crawler/associate_condition_tweet.py b/nest_crawler/associate_condition_tweet.py index f6bfce5..10383be 100644 --- a/nest_crawler/associate_condition_tweet.py +++ b/nest_crawler/associate_condition_tweet.py @@ -50,3 +50,9 @@ def is_coordinate_inside_bounding_box(latitude, longitude, radius, tweet_latitud dLongitude = dLatitude * cos(radians(latitude)) if (latitude - dLatitude < tweet_latitude < latitude+dLatitude) and (longitude-dLongitude < tweet_longitude < longitude+dLongitude): return True + + +__all__ = ( + "associate_condition_tweet", + "is_coordinate_inside_bounding_box", +) \ No newline at end of file diff --git a/nest_crawler/authentication.py b/nest_crawler/authentication.py index e4b68d8..b762cb3 100644 --- a/nest_crawler/authentication.py +++ b/nest_crawler/authentication.py @@ -12,4 +12,9 @@ def authenticate(): auth.set_access_token(a_t, a_t_s) api = tw.API(auth, wait_on_rate_limit=True) # client = tw.Client(b_t, c_k, c_s, a_t, a_t_s, wait_on_rate_limit=True); - return api \ No newline at end of file + return api + + +__all__ = ( + "authenticate", +) diff --git a/nest_crawler/repo_search.py b/nest_crawler/repo_search.py index e2ad9d9..35fa7a1 100644 --- a/nest_crawler/repo_search.py +++ b/nest_crawler/repo_search.py @@ -1,8 +1,8 @@ from nest_backend.database import * -import nest_crawler.authentication as authentication -from datetime import datetime, timedelta +from . import authentication +from datetime import datetime import tweepy as tw -from nest_crawler.associate_condition_tweet import associate_condition_tweet +from .associate_condition_tweet import associate_condition_tweet def search_repo_conditions(repository_id): @@ -148,3 +148,8 @@ def search_repo_conditions(repository_id): ext.session.add(composed) ext.session.commit() print(f"Done searching tweets from repo: {repo.name}") + + +__all__ = ( + "search_repo_conditions", +)
S
+ - -@@ -625,8 +677,12 @@ -
-
M
@@ -553,8 +595,12 @@-
-
Documentazione tecnica