First commit.
History is present
This commit is contained in:
commit
cabebe4395
23 changed files with 1047 additions and 0 deletions
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
|||
|
16
dbs/pinopisolo.db
Normal file
16
dbs/pinopisolo.db
Normal 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
3
requirements.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
tweepy
|
||||
pymongo
|
||||
logging
|
37
setup.py
Normal file
37
setup.py
Normal 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)
|
BIN
valeriovive/.twitter_agent.py.swp
Normal file
BIN
valeriovive/.twitter_agent.py.swp
Normal file
Binary file not shown.
6
valeriovive/__init__.py
Normal file
6
valeriovive/__init__.py
Normal 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
52
valeriovive/__main__.py
Normal 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)
|
||||
|
||||
|
||||
|
BIN
valeriovive/__pycache__/__init__.cpython-36.pyc
Normal file
BIN
valeriovive/__pycache__/__init__.cpython-36.pyc
Normal file
Binary file not shown.
BIN
valeriovive/__pycache__/__main__.cpython-36.pyc
Normal file
BIN
valeriovive/__pycache__/__main__.cpython-36.pyc
Normal file
Binary file not shown.
BIN
valeriovive/__pycache__/daemon.cpython-36.pyc
Normal file
BIN
valeriovive/__pycache__/daemon.cpython-36.pyc
Normal file
Binary file not shown.
BIN
valeriovive/__pycache__/experiment.cpython-36.pyc
Normal file
BIN
valeriovive/__pycache__/experiment.cpython-36.pyc
Normal file
Binary file not shown.
BIN
valeriovive/__pycache__/nano.cpython-36.pyc
Normal file
BIN
valeriovive/__pycache__/nano.cpython-36.pyc
Normal file
Binary file not shown.
BIN
valeriovive/__pycache__/scheduler.cpython-36.pyc
Normal file
BIN
valeriovive/__pycache__/scheduler.cpython-36.pyc
Normal file
Binary file not shown.
BIN
valeriovive/__pycache__/twitter_agent.cpython-36.pyc
Normal file
BIN
valeriovive/__pycache__/twitter_agent.cpython-36.pyc
Normal file
Binary file not shown.
138
valeriovive/daemon.py
Normal file
138
valeriovive/daemon.py
Normal 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
31
valeriovive/database.py
Normal 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
134
valeriovive/experiment.py
Normal 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
39
valeriovive/logging.ini
Normal 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
31
valeriovive/nani.json
Normal 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
134
valeriovive/nano.py
Normal 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
0
valeriovive/nanoBot.sh
Normal file
77
valeriovive/scheduler.py
Normal file
77
valeriovive/scheduler.py
Normal 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)))
|
||||
|
||||
|
348
valeriovive/twitter_agent.py
Normal file
348
valeriovive/twitter_agent.py
Normal 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]:
|
Loading…
Reference in a new issue