First commit.

History is present
This commit is contained in:
cocco_git 2017-11-04 22:33:28 +01:00
commit cabebe4395
23 changed files with 1047 additions and 0 deletions

1
README.md Normal file
View file

@ -0,0 +1 @@

16
dbs/pinopisolo.db Normal file
View file

@ -0,0 +1,16 @@
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234065}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234070}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234632}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234658}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234672}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234711}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234747}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234854}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234865}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234890}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509234992}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509235079}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509235175}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509235215}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509235242}
{"actions": ["search_and_retweet"], "buddy": ["InfoAntifa", "LibreriAntigone", "romaoccupata", "Assospartaco", "BANDA_BASSOTTI", "rivamesta", "zeropregi", "progettoDegage", "contropiano", "DinamoPress", "ilmanifesto", "Radiondarossa", "repubblica", "notav_info", "Infoaut", "sap_clandestina", "zerocalcare", "FPrenestino", "AnpiRoma", "RFeminista_", "RomaAntifa", "AntifaOstia", "romattiva", "MilitantBlog", "RATM", "matteosalvinimi\u00a0", "gruppohobbit\u00a0", "CircoloFuturista", "MSR_cat\u00a0", "Occidentale", "OrdineNuovo", "romatoday\u00a0", "PBT_Torino", "Nigel_Farage", "UKIP", "SimoneCasaPound\u00a0", "MarcelloRuffo", "IannoneCpi", "ilgiornale\u00a0", "ChiaraScalzi85\u00a0", "BloccoStudentesco\u00a0", "prog_sociale", "ForzaNuova\u00a0", "AlbaDoratait\u00a0", "distefanoTW\u00a0", "CasaPoundItalia\u00a0", "giorgiameloni", "FratellidItalia"], "hash": ["fascismo", "antifascismo", "razzismo", "italia", "italiano", "italiaglitaliani", "stopinvasione", "puliziaetnica", "mussolini", "quandoceralui", "hitler", "farequadrato", "apologia", "nazismo", "antinazismo", "fakenews", "complotto", "noeuro", "scontri", "centrisociali", "occupazione", "lavoro", "sinistra", "manifestazione", "blackbloc", "vandalismo", "fanatismo", "destra", "parlamento", "violenza", "polizia", "esercito", "rom", "campirom", "roma", "guerra", "sciopero", "precari", "casa", "mafia", "camorra", "ndrangheta", "sindacato", "clandestino", "immigrato", "immigrati", "barconi", "negri", "cassazione", "pd", "leganord", "fdi", "an", "grillo", "m5s", "donne", "violenzasulledonne", "bambini", "famiglia", "dio", "patria", "difesa", "nazione", "paese", "madeinitaly", "salvini", "populismo", "casapound", "lepen", "schifo", "feccia", "odio", "amore", "forzanuova", "forteprenestino", "nietsche", "ezrapound", "democrazia", "politica", "votare", "elezioni", "parlamento"], "time": 1509235254}

3
requirements.txt Normal file
View file

@ -0,0 +1,3 @@
tweepy
pymongo
logging

37
setup.py Normal file
View file

@ -0,0 +1,37 @@
import os
from setuptools import setup
def read(fname):
with open(os.path.join(os.path.dirname(__file__), fname)) as buf:
return buf.read()
conf = dict(
name='valeriovive',
version='0.1',
description='Twitter Filter Bubble Experiment',
long_description=read('README.md'),
author='cocconat',
author_email='g3-3k@paranoici.org',
url='https://github.com/g3-3k/valeriovive',
license='AGPL',
packages=['valeriovive'],
install_requires=[
'tweepy',
'pymongo',
'mutagen',
'logging',
],
zip_safe=False,
classifiers=[
"License :: OSI Approved :: GNU Affero General Public License v3",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 2",
])
if __name__ == '__main__':
setup(**conf)

Binary file not shown.

6
valeriovive/__init__.py Normal file
View file

@ -0,0 +1,6 @@
from .experiment import Experiment
from .nano import Nano
from .twitter_agent import TwitterAgent
from .scheduler import Scheduler, dict_from_json
from .daemon import Daemon

52
valeriovive/__main__.py Normal file
View file

@ -0,0 +1,52 @@
import logging
from experiment import ExperimentDaemon, Experiment, ExperimentDebug, ExperimentShell
import sys,argparse, os
def getparser():
parser = argparse.ArgumentParser(description='run TIBER instance')
parser.add_argument('-c','--conf',dest='conf_file', type=str, default=None,
help='configuration_file for the experiment')
parser.add_argument('--start', dest='start', action='store_true', default=False,
help='start valeriovive ')
parser.add_argument('--restart', dest='restart', action='store_true',default=False,
help='restart valeriovive ')
parser.add_argument('--stop', dest='stop', action='store_true',default=False,
help='stop valeriovive ')
parser.add_argument('--oneshot', dest='oneshot', action='store_true',default=False,
help='do one shot twitter action ')
parser.add_argument('--debug', dest='debug', action='store_true',default=False,
help='get object in ipython console')
parser.add_argument('--remove-friends', dest='remove_friends', action='store_true',default=False,
help='remove all following accounts')
parser.add_argument('--shell', dest='shell', action='store_true',default=False,
help='open a shell')
return parser.parse_args()
if __name__ == "__main__":
logging_path=os.path.join(os.getcwd(),'valeriovive/logging.ini')
logging.config.fileConfig(logging_path)
args = getparser()
if args.debug or args.oneshot:
exp=ExperimentDebug(args)
elif args.shell:
print("entering shell!")
exp=ExperimentShell()
elif args.start:
exp=ExperimentDaemon("/tmp/valeriovive.pid", args)
exp.start()
sys.exit(0)
elif args.restart:
exp=ExperimentDaemon("/tmp/valeriovive.pid", args)
exp.restart()
sys.exit(0)
elif args.stop:
exp=ExperimentDaemon("/tmp/valeriovive.pid", args)
exp.stop()
sys.exit(0)
else:
print ("usage: %s start|stop|restart" % sys.argv[0])
sys.exit(2)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

138
valeriovive/daemon.py Normal file
View file

@ -0,0 +1,138 @@
#!/usr/bin/env python
# This class contains the class for the Linux system daemon.
import sys, os, time, atexit
from signal import SIGTERM
import logging
class Daemon:
"""
A generic daemon class.
Usage: subclass the Daemon class and override the run() method
"""
def __init__(self, pidfile, args, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr
self.pidfile = pidfile
self.args = args
self.log = logging.getLogger("daemon")
def daemonize(self):
"""
do the UNIX double-fork magic, see Stevens' "Advanced
Programming in the UNIX Environment" for details (ISBN 0201563177)
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
"""
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError as e:
self.log.error("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# decouple from parent environment
ex_path=os.getcwd()
os.chdir("/")
os.setsid()
os.umask(0)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError as e:
self.log.error("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# # redirect standard file descriptors
# sys.stdout.flush()
# sys.stderr.flush()
# si = file(self.stdin, 'r')
# so = file(self.stdout, 'a+')
# se = file(self.stderr, 'a+', 0)
# os.dup2(si.fileno(), sys.stdin.fileno())
# os.dup2(so.fileno(), sys.stdout.fileno())
# os.dup2(se.fileno(), sys.stderr.fileno())
# write pidfile
atexit.register(self.delpid)
pid = str(os.getpid())
open(self.pidfile,'w+').write("%s\n" % pid)
os.chdir(ex_path)
def delpid(self):
os.remove(self.pidfile)
def start(self):
"""
Start the daemon
"""
self.log.debug("daemon started")
# Check for a pidfile to see if the daemon already runs
try:
pf = open(self.pidfile,'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if pid:
message = "pidfile %s already exist. Daemon already running?\n"
sys.stderr.write(message % self.pidfile)
sys.exit(1)
# Start the daemon
self.daemonize()
self.run()
def stop(self):
"""
Stop the daemon
"""
self.log.debug("daemon stopped ")
# Get the pid from the pidfile
try:
pf = open(self.pidfile,'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if not pid:
message = "pidfile %s does not exist. Daemon not running?\n"
sys.stderr.write(message % self.pidfile)
return # not an error in a restart
# Try killing the daemon process
try:
while 1:
os.kill(pid, SIGTERM)
time.sleep(0.1)
except OSError as err:
err = str(err)
if err.find("No such process") > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print (str(err))
sys.exit(1)
def restart(self):
"""
Restart the daemon
"""
self.stop()
self.start()
def run(self):
"""
You should override this method when you subclass Daemon. It will be called after the process has been
daemonized by start() or restart().
"""

31
valeriovive/database.py Normal file
View file

@ -0,0 +1,31 @@
import json
class DB(object):
'''
db.add({timestamp: time.time(),
agent: 'tizio',
action: 'search',
target: 'tasse'
})
db.add({timestamp: time.time(),
agent: 'tizio',
action: 'wall',
seen: [
{user: 'zerogreggi', msg: 'ho le pecore'},
{user: 'caio', msg: 'ci faccio il formaggio'},
]
})
searches = [s for s in db.all() if s['action'] == 'wall']
'''
def __init__(self, fname):
self.fname = fname
def add(self, doc):
with open(self.fname, 'a') as buf:
buf.write(json.dumps(doc))
buf.write('\n')
def all(self):
with open(self.fname) as buf:
for line in buf:
yield json.loads(line)

134
valeriovive/experiment.py Normal file
View file

@ -0,0 +1,134 @@
import sys
import logging
from valeriovive.nano import Nano
from valeriovive.scheduler import Scheduler,dict_from_json
import logging.config
import sys, time, os
from valeriovive.daemon import Daemon
#!/usr/bin/env python
class ExperimentDaemon(Daemon):
def run(self):
experiment=Experiment(self.args)
experiment.start_experiment()
def ExperimentShell():
Experiment.run_shell()
def ExperimentDebug(args):
experiment=Experiment(args)
experiment.oneshot()
class Experiment(Scheduler):
"""
Experiment classs
controls the evolution of the experiment with the Scheduler
Each parameter can be set through this class
As many config file as many bots will be created, the bot are stored
in the 'bots' attribute.
"""
def __init__(self,*args, **kwargs):
self.log = logging.getLogger("root")
Scheduler.__init__(self, self.events_manager)
self.bots=[]
if "conf" in kwargs:
self.prepare_experiment(kwargs["conf"])
if "remove_friends" in kwargs:
self.remove_friends=True
self.log.debug("Experiment configured with {}".format(self.conf_file ))
@classmethod
def create_experiment(cls, **kwargs):
return Experiment(kwargs)
"""
Prepare experiment with conf_file params
"""
def prepare_experiment(self, conf_file=None):
##set the conf file or use the default
if isinstance(conf_file, str):
self.conf = dict_from_json(conf_file)
self.conf_file = os.path.join(os.getcwd(),conf_file)
else:
self.log.error("if you re not setting conf file, you are wrong")
self.conf_file = os.path.join(os.getcwd(),'valeriovive/nani.json')
self.conf = dict_from_json(self.conf_file)
self.log.debug("conf file is {}".format(self.conf_file))
##pass the conf file to each agent
for agent in self.conf['agents']:
nano = Nano(agent, self.conf_file)
self.bots.append(nano)
@staticmethod
def run_shell():
settings={}
while True:
s = input()
if s == "start":
exp = Experiment.create_experiment(settings)
elif s == "set conf":
print("digit the path to conf file")
conf_path = input()
try:
settings["conf"]=conf_path
except:
print("set configuration failed")
elif s == "remove friends":
settings["remove_friends"]=True
elif s == "exit" or s == "quit" or s == "q":
# break
def start_experiment(self, duration=0):
'''
Start the experiment.
Argument:
duration -- expressed in seconds
if duration not set, it will continue indefinitely
'''
self.log.debug("Experiment routine starting")
self.routine_manager(self.conf_file)
def oneshot(self):
"""
Play one only experience for the bot"
"""
self.log.debug("Experiment one shot")
for nano in self.bots:
if self.remove_friends:
nano.remove_friends()
else:
nano.set_behaviour()
nano.online_experience()
@property
def common_hours(self):
return self.conf['common']['hours']
def events_manager(self):
"""
Do the relevant action for the experiment:
1) For each nano, at scheduled time, start online experience
"""
for nano in self.bots:
nano.set_behaviour()
##retrieve action hours
try:
nano.events = Scheduler.events_from_hours(nano.get_hours())
except:
nano.events = Scheduler.events_from_hours(self.common_hours)
##schedule actions
for event_time in nano.events:
self.schedule_event(event_time, nano.online_experience)
logging.debug("nano {} scheduled at {}".format(nano.name, str(event_time)))

39
valeriovive/logging.ini Normal file
View file

@ -0,0 +1,39 @@
[loggers]
keys=root
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_scheduler]
level=DEBUG
handlers=consoleHandler
[logger_daemon]
level=DEBUG
handlers=consoleHandler
[logger_twitter_agent]
level=DEBUG
handlers=consoleHandler
[logger_nano]
level=DEBUG
handlers=consoleHandler
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

31
valeriovive/nani.json Normal file
View file

@ -0,0 +1,31 @@
{"agents":["sbinzolo"],
"individual_behaviour":false,
"sbinzolo":{
"name":"sbinzolo",
"dbpath": "sbinzolo.db",
"twitter":{
"consumer_key":"wG4qh5Uu9WAJiJAtYHEOUoTPd",
"consumer_set":"lR9mCtErxJ1rWwNaR9RtvpmSsKs301qxvwCt0658CUjAkydMXx",
"access_token":"863857515276230657-UajuyvISnw8537s8lXUBLI8h2zudpYR",
"secret_token":"UMBh1YFokq85Sl48FTFl0V4fJa7vBhwViyta8KOpe5lCq"
},
"actions":["search_and_retweet","search_and_follow","retweet_my_friends"],
"buddies":["Leila","Armando","FortePrenestino"],
"hashtags":["fasciappesi","cazziemazzi","giuliascopa"],
"hours":[0, 10, 17, 23]
},
"common":{
"actions":["search_and_retweet","search_and_follow","retweet_my_friends"],
"buddies":["Leila","Armando","FortePrenestino"],
"hashtags":["fasciappesi","cazziemazzi","giuliascopa"],
"hours":[0, 10, 17, 23],
"end_date":"2020-04-03",
"scheduler_interval":"midnight",
"buddies" : [
"InfoAntifa","LibreriAntigone","romaoccupata","Assospartaco","BANDA_BASSOTTI","rivamesta","zeropregi","progettoDegage","contropiano","DinamoPress","ilmanifesto","Radiondarossa","repubblica","notav_info","Infoaut","sap_clandestina","zerocalcare","FPrenestino","AnpiRoma","RFeminista_","RomaAntifa",
"AntifaOstia","romattiva","MilitantBlog","RATM","matteosalvinimi ","gruppohobbit ","CircoloFuturista","MSR_cat ","Occidentale","OrdineNuovo","romatoday ","PBT_Torino ","Nigel_Farage ","UKIP”,”SimoneCasaPound ","MarcelloRuffo ","IannoneCpi ","ilgiornale ","ChiaraScalzi85 ","BloccoStudentesco ","prog_sociale","ForzaNuova ","AlbaDoratait ","distefanoTW ","CasaPoundItalia ","giorgiameloni","FratellidItalia"],
"hashtags" : ["fascismo","antifascismo","razzismo","italia","italiano","italiaglitaliani","stopinvasione","puliziaetnica","mussolini","quandoceralui","hitler","farequadrato","apologia","nazismo","antinazismo","fakenews","complotto","noeuro","scontri","centrisociali","occupazione","lavoro","sinistra","manifestazione","blackbloc","vandalismo","fanatismo","destra","parlamento","violenza","polizia","esercito","rom","campirom","roma","guerra","sciopero","precari","casa","mafia","camorra","ndrangheta","sindacato","clandestino","immigrato","immigrati","barconi","negri","cassazione","pd","leganord","fdi","an","grillo","m5s","donne","violenzasulledonne","bambini","famiglia","dio","patria","difesa","nazione","paese","madeinitaly","salvini","populismo","casapound","lepen","schifo","feccia","odio","amore","forzanuova","forteprenestino","nietsche","ezrapound","democrazia","politica","votare","elezioni","parlamento"]
}
}

134
valeriovive/nano.py Normal file
View file

@ -0,0 +1,134 @@
from valeriovive.twitter_agent import TwitterAgent
import random
import json
import logging
import time
from valeriovive.scheduler import dict_from_json
class Nano:
'''
Create Nano Object
Nano is the active element of the experiment,it does stuff
Nano remains during all the experiment.
Nano is actually the bot and will be initialited with conf.file path. That cannot change.
Nano has no perception of time.
Attributes
==========
CONF:
common_conf dict See README
own_conf dict See README
__twitter_agent TwitterAgent(Tweepy)
Behaviour:
actions set of __twitter agent methods
buddy_list list(strigs)
hash_list
events list(hours(int[0-23]))
Methods
===========
'''
def __init__(self, name, conf_file):
self.name=name
self.conf_file=conf_file
self.twitter_agent = TwitterAgent(name,dict_from_json(self.conf_file)[self.name]["twitter"])
self.actions =[]
###
self.buddy_list = []
self.hash_list = []
self.actions_list =[]
self.events=None
### loggers
self.logger = logging.getLogger(name)
self.logger.info('created Nano {} obj, and file {}'.format(self.name,conf_file))
@property
def conf(self):
return dict_from_json(self.conf_file)[self.name]
# def twitter_conf(conf_file):
# try:
# return dict_from_json(conf_file)[self.name]["twitter"]
# except KeyError:
# raise ValueError("missing twitter conf in the configuration file")
"""
Set behaviour
Dict needs to contain buddies , hashtags , actions
"""
def set_behaviour(self):
if self.buddy_list == dict_from_json(self.conf_file)["individual_behaviour"]:
self.buddy_list = dict_from_json(self.conf_file)[self.name]['buddies']
self.hash_list = dict_from_json(self.conf_file)[self.name]['hashtags']
self.actions_list = dict_from_json(self.conf_file)[self.name]['actions']
else:
self.buddy_list = dict_from_json(self.conf_file)["common"]['buddies']
self.hash_list = dict_from_json(self.conf_file)["common"]['hashtags']
self.actions_list = dict_from_json(self.conf_file)["common"]['actions']
self.logger.debug("buddies: {} \n, hashtags: {} \n, actions: {}\n".format(self.buddy_list,self.hash_list,self.actions_list))
self.get_actions()
def get_hours(self):
return dict_from_json(self.conf_file[self.name]['hours'])
def get_actions(self):
"""
Retrieve functions from config and add to actions_list
"""
self.actions=[]
if "search_and_follow" in self.actions_list:
self.actions.append(self.twitter_agent.search_and_follow)
if "search_and_retweet" in self.actions_list:
self.actions.append(self.twitter_agent.search_and_retweet)
if "get_user_timeline" in self.actions_list:
self.actions.append(self.twitter_agent.get_user_timeline)
if "destroy_all_friends" in self.actions_list:
self.actions.append(self.twitter_agent.destroy_all_friends)
# if "retweet_my_friends" in self.actions:
# self.actions.append(self.__twitter_agent.retweet_my_friends)
"""
Start Online Session
log with tweepy and do stuff as in behaviour
"""
def online_experience(self):
random.shuffle(self.actions)
self.twitter_agent.connect()
if not self.twitter_agent.connected:
self.logger.error("cannot connect to Twitter!")
return
# self.twitter_agent.get_user_timeline()
for action in self.actions:
self.logger.debug("next action is {}".format(action.__name__))
try:
action(self.buddy_list, self.hash_list)
except :
self.logger.exception("Action {} failed".format(action.__name__))
if 'dbpath' in self.conf:
with open(self.conf['dbpath'], 'a') as buf:
record = {}
record['actions'] = [a.__name__ for a in self.actions]
record['buddy']= self.buddy_list
record['hash'] = self.hash_list
record['time'] = int(time.time())
buf.write(json.dumps(record))
buf.write("\n")
def remove_friends(self):
self.twitter_agent.connect()
try:
self.twitter_agent.destroy_all_friends()
except :
self.logger.error("cannot connect to Twitter!")

0
valeriovive/nanoBot.sh Normal file
View file

77
valeriovive/scheduler.py Normal file
View file

@ -0,0 +1,77 @@
import json, sched, datetime, time
import logging
import threading
import random
def dict_from_json(json_file):
with open(json_file) as json_data:
dict_ = json.load(json_data)
return dict_
class Scheduler:
def __init__(self, events_manager):
self.log = logging.getLogger(__name__)
self.log.info(" starting {} ".format(__name__))
self.events = []
self.hours = []
self.events_manager = events_manager
"""
Converts hours in dates.
Every day convert the hour in the exact date yyyy-mm-dd hh-mm
"""
@staticmethod
def events_from_hours(hours):
if not isinstance(hours, list):
hours = list(hours)
events = [datetime.datetime.today().replace(hour=hour,
minute=random.choice(range(60)))
for hour in hours]
return events
def routine_manager(self, conf_file):
"""
Routine manager
Always running untill --stop
conf_file is a path to json file.
The configuration file is read continously
"""
try:
logging.info("routine manager start at {}".format(str(datetime.datetime.now())))
conf = dict_from_json(conf_file)['common']
except:
self.log.error(conf_file+ " is the wrong configuration file")
while True and datetime.datetime.now() < datetime.datetime.strptime(conf["end_date"],"%Y-%m-%d"):
self.events_manager()
self.log.debug("routine manager loop at {}".format(str(datetime.datetime.now())))
conf = dict_from_json(conf_file)['common']
try:
if conf["scheduler_interval"] == "midnight":
interval_seconds = (datetime.datetime.today().replace(hour=23, minute=59) - datetime.datetime.now()).total_seconds()
self.log.info("Next routine_manager loop at {}".format(datetime.datetime.today().replace(hour=23, minute=59)))
if isinstance(conf["scheduler_interval"], int):
interval_seconds = datetime.timedelta(hours=conf["scheduler_interval"])
except KeyError:
self.log.error("Scheduler properties not found in {}", conf_file)
time.sleep(interval_seconds)
@staticmethod
def schedule_event(event_time, action, **kwargs):
"""
Schedule event with threading
Params:
==========
event_time datetime format
action function
**kwargs function arguments
"""
delta = (event_time - datetime.datetime.now()).total_seconds()
if delta > 0:
logging.debug("time interval to next action is {}".format(delta))
T = threading.Timer(int(delta), action, **kwargs)
T.start()
else:
logging.debug("event {} scheduled in the past!".format(str(event_time)))

View file

@ -0,0 +1,348 @@
import tweepy
from tweepy import OAuthHandler
import tweepy.streaming
from tweepy import StreamListener
from pymongo import MongoClient
import logging
import random
from copy import copy
class MyStreamListener(tweepy.StreamListener):
def on_status(self, status):
print(status.text)
def on_error(self, status_code):
if status_code == 420:
#returning False in on_data disconnects the stream
return False
class TwitterAgent():
"""
Twitter_agent class, initiated with keys, is a Tweepy based Object
TwitterAgent get init with a dictionary
Attributes
name String name of the agent
cfg Dict conf
api Tweepy Object
userdb Pymando db
twettsdb Pymando db
"""
def __init__(self,name,cfg):
##cfg is a json with
#consumer_key
#consumer_set
#access_token
#secret_token
self.name=name
self.userdb=None
self.tweetsdb=None
self.cfg =cfg
self.api =None
self.db_instance()
self.ERROR=[]
self.listener = None
self.streamer = None
### loggers
self.logger = logging.getLogger(name+": TwitterAgent")
self.logger.info('created Twitter Agent{} obj'.format(self.name))
"""
Authenticate
"""
@staticmethod
def authenticate(cfg):
auth=OAuthHandler(cfg["consumer_key"],cfg["consumer_set"])
auth.set_access_token(cfg["access_token"],cfg["secret_token"])
return tweepy.API(auth), auth
def connect(self):
self.api , auth= self.authenticate(self.cfg)
self.streamer = tweepy.Stream(auth, listener=MyStreamListener())
@property
def connected(self):
try:
return self.api.me()
except:
self.logger.error(ValueError)
"""
Instanciate Pymong db [a dictionary type]
tweetsdb will cotain the whole tweet
userdb will contain tweets's authors and relative followers
"""
def db_instance(self):
try:
client=MongoClient('localhost', 27017)
db=client.get_database('dict')
self.db=db[self.name]
#error list it's for those user resulting missing to followers retrieve
except:
raise ValueError("Error during mongodb initialization")
"""
Add Friends to authenticated user profile
Parameters:
buddy_list list(strings) Users list for next session
hash_list list(strings) Hash list for next session
"""
def add_friends(self, buddy_list, hash_list):
self.logger.debug("add_friends")
if not isinstance(buddy_list,list):
buddy_list=list(buddy_list)
for buddy in buddy_list:
try:
self.api.create_friendship(user_id=buddy)
except:
logging.warning("{} didn't find this buddy: {} \n".format(self.name,buddy))
"""
Search the hash_list and retweet some status
Parameters:
buddy_list list(strings) Users list for next session
hash_list list(strings) Hash list for next session
"""
def search_and_retweet(self, buddy_list, hash_list):
self.logger.debug("search_and_retweet")
if not isinstance(hash_list,list):
hash_list=list(hash_list)
for tag in hash_list:
if random.random() > 0.7:
hash_cursor = tweepy.Cursor(self.api.search, q="#"+tag).items()
for tweet in hash_cursor:
if tweet.retweeted: continue
if random.random() > 0.7:
print(tweet.id, tweet.user, tweet.retweeted)
self.api.retweet(tweet.id)
return 0
# cursor=tweepy.Cursor("c", id=user, count=5000).pages()
"""
Search the hash_list and follow some users
Parameters:
buddy_list list(strings) Users list for next session
hash_list list(strings) Hash list for next session
"""
def search_and_follow(self, buddy_list, hash_list):
self.logger.debug("search_and_follow")
if not isinstance(hash_list,list):
hash_list=list(hash_list)
my_hash_list = copy(hash_list)
random.shuffle(my_hash_list)
my_hash_list = my_hash_list[:int(0.3*len(my_hash_list))]
for tag in my_hash_list:
self.logger.debug("searching for hashtag "+tag)
hash_cursor = tweepy.Cursor(self.api.search, q="#"+tag).items(5)
for num, tweet in enumerate(hash_cursor):
if random.random() > 0.8:
self.logger.debug("searching for tweet "+tweet.text)
self.api.create_friendship(tweet.author.id)
return 0
"""
Search the buddy_list and retweet some users
Parameters:
buddy_list list(strings) Users list for next session
hash_list list(strings) Hash list for next session
"""
def retweet_my_friends(self, buddy_list, hash_list):
self.logger.debug("retweet_my_friends")
if not isinstance(buddy_list, list):
buddy_list=list(buddy_list)
random.shuffle(buddy_list)
for buddy in buddy_list:
try:
tweets = self.api.user_timeline(screen_name=buddy)
#self.stream.filter(buddy, _with='followings', async = True)
except:
logging.warning("user {} timeline not accesible \n".format(buddy))
for tweet in tweets:
if random.random()>0.8:
self.api.retweet(tweet.id)
return 0
def destroy_all_friends(self):
self.logger.debug("destroy_all_friends")
for friend in self.api.friends_ids(self.api.me().id):
self.api.destroy_friendship(friend)
#This function obtain tweet for the indicated query,
#it will save into db untill the element get the willed value-count.
#in order to start from last saved tweet after a possible break,
#it uses the external parameters lastid, wich is obtained from db itself in runtime
"""
Save the user user timeline
"""
def get_user_timeline(self):
self.logger.debug("get_timeline")
try:
timeline = self.api.home_timeline(count=200)
except:
self.logger.error("User timeline return error")
for tweet in timeline:
self.logger.debug("Tweet from {}, : {}".format(tweet.author.name,tweet.text))
self.db.insert({"status":{
"author_name":tweet.author.name,
"text": tweet.text,
"status":tweet._json}
})
self.logger.debug("item inserted in the db")
return 0
# def save_tweets(self,db,query,api=None,count=5000,lastid=0):
# api=self.api
# try:
# while db.count() <count:
# cursor=api[0].search(q=query,since_id=lastid)
# for tweet in cursor:
# #some information will be saved, this isn't complete but exahustive
# db.insert({"status":{"author_name":tweet.author.name,\
# "author_id":tweet.author.id,\
# "author_json":tweet.author._json,\
# "status_json":tweet._json}\
# })
# lastid=tweet.id
# return lastid
# except:
# return lastid
#this function returns all elements already "scrapied", that is which followers already are in userdb.
#this is to restart program since any lose too.
# def scrapied (self,userdb=None):
# userdb=self.userdb
# for i in userdb.find():
# yield int(i['user'].keys()[0])
# #a simple rotate function very usefull for api index scrolling
# def rotate(self,l):
# return l[1:] + l[:1]
# #it parses tweetsdb and return all authors, obviously the db is parsed only at first instance,
# #then everything is saved to user_list, and authors popped from there.
# #
# def get_users(self, tweetsdb, last_user=0, user_list=False):
# tweetsdb=self.tweetsdb
# if user_list:
# #pop an item from list and return it
# user_list.pop(0)
# return user_list
# else:
# users=[int(str(user['status']['author_id']).strip()) for user in tweetsdb.find()]
# user_list=sorted(set(users),reverse=True)[last_user:]
# #don't reapeat user
# for user in scrapied(userdb):
# try:
# user_list.remove(user)
# except:
# continue
# return user_list
# #most difficult to write down!
# #this function return followers for each author, adopting some tricks to keep memory of cursor
# #and same time get a new api when apiratelimit is exceeded
# # def get_followers(self,user,api=none):
# # api=self.api
# # followers=[]
# # count=1
# # cursor=tweepy.cursor(api[0].followers_ids, id=user, count=5000).pages()
# # while true:
# # try:
# # for page in cursor:
# # followers.extend(page)
# # print "page", count, "of user", user
# # sys.stdout.flush()
# # count +=1
# # return followers
# # except tweepy.ratelimiterror:
# #new api in case is at zero page retrieved
# # if cursor.next_cursor==-1:
# # self.rotate(self.api)
# # self.get_followers(user)
# # else:
# # print "let's take a break, it will restart from last page; api_index is", api[0],"current cursor", cursor.next_cursor
# # sys.stdout.flush()
# # for i in range(15):
# # print 15-i, "minutes to wait"
# # time.sleep(60)
# # continue
# # except:
# # print "Unexpected!!! on user", user
# # self.ERROR.append(user)
# # break
# #this function is a kind of main, retrieve users and scrapies followers for each one, then pop user and reapeat.
# def followers(self,api=None,userdb=None,tweetsdb=None):
# api=self.api
# tweetsdb=self.tweetsdb
# userdb=self.userdb
# user_list=get_users(tweetsdb)
# while user_list:
# if api[0].rate_limit_status()['resources']['followers']['/followers/ids']['remaining'] <1:
# api=self.rotate(api)
# print ("api_index has incremented")
# user=user_list[0]
# followers =self.get_followers(user,api=api)
# userdb.insert({"user":{str(user):followers}})
# user_list=get_users(tweetsdb,user_list=user_list)
# # In[26]:
# #lastid=int(tweetsdb.find()[len([tweetsdb.find()])-1]['status']['status_json']['id_str'])
# # In[33]:
# #len(list(scrapied(userdb)))
# # In[35]:
# #len(get_users(tweetsdb))
# # In[ ]:
# '''
# lastid=int(tweetsdb.find()[len([tweetsdb.find()])-1]['status']['status_json']['id_str'])
# count=10000
# #keep it running until count
# while tweetsdb.count() < count:
# api_index=0
# lastid=get_tweets(db=tweetsdb,api=api,query="Daesh",count=count,lastid=lastid,api_index=api_index)
# rotate(api)
# print tweetsdb.count()
# time.sleep(60*15)
# if len(get_users(tweetsdb)):
# followers(api=api,userdb=userdb,tweetsdb=tweetsdb)
# '''
# # In[9]:
# # In[8]:
# # In[34]:
# # In[84]: