-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2a06161
Showing
8 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# API de OpenWeatherMap | ||
from pyowm import OWM | ||
import os | ||
|
||
def getClima(ciudad): | ||
|
||
API_KEY = os.getenv('API_KEY') | ||
|
||
# Se proporciona la clave de la API | ||
# Se cera un objeto de tipo OWM | ||
owm = OWM(API_KEY) | ||
|
||
# Se crea un objeto de tipo WeatherManager | ||
wm = owm.weather_manager() | ||
|
||
# Se busca el clima de una ciudad | ||
obs = wm.weather_at_place(ciudad) | ||
|
||
# Se obtiene informacion del clima de la ciudad | ||
clima = obs.weather | ||
localidad = obs.location | ||
|
||
temperatura = clima.temperature('celsius')['temp'] | ||
humedad = clima.humidity | ||
viento = clima.wind() | ||
nubes = clima.status | ||
|
||
clima = ( | ||
f"Localidad: {localidad.name} \nTemperatura: {temperatura} °C\nHumedad: {humedad}%\nViento: {viento['speed']} km/h\nNubes: {nubes}") | ||
|
||
return clima |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import tweepy | ||
import logging | ||
from config import crearAPI | ||
import time | ||
import API.weatherAPI as weatherAPI | ||
|
||
logging.basicConfig(level=logging.INFO) | ||
|
||
logger = logging.getLogger() | ||
|
||
# since_id especifica resultados con una ID mayor que la id especificada (más reciente) | ||
|
||
def verificarMenciones(api, palabrasClaves, idDesde): | ||
|
||
logger.info("Recuperando menciones...") | ||
|
||
idDesdeNuevo = idDesde | ||
|
||
# Cursor maneja la paginacion de resultados | ||
for tweet in tweepy.Cursor(api.mentions_timeline, since_id=idDesde).items(): | ||
|
||
idDesdeNuevo = max(tweet.id, idDesdeNuevo) | ||
|
||
me = api.me() | ||
|
||
if any(palabraClave in tweet.text.lower() for palabraClave in palabrasClaves) and tweet.user.id != me.id: | ||
|
||
logger.info(f"Respondiendo al usuario {tweet.user.screen_name}") | ||
|
||
if not tweet.user.following: | ||
|
||
logger.info(f"Siguiendo al usuario {tweet.user.screen_name}") | ||
|
||
tweet.user.follow() | ||
|
||
if not tweet.favorited: | ||
|
||
logger.info("Dando me gusta al tweet...") | ||
|
||
tweet.favorite() | ||
|
||
usuario = tweet.user.screen_name | ||
|
||
ciudad = 'Mendoza, AR' | ||
|
||
clima = weatherAPI.getClima(ciudad) | ||
|
||
hora = time.strftime("%H:%M:%S") | ||
|
||
clima += f"\nHora: {hora}" | ||
|
||
# Se responde al tweet que nos mencionaron | ||
try: | ||
api.update_status(f"@{usuario} {clima}", | ||
in_reply_to_status_id=tweet.id) | ||
except Exception as e: | ||
logger.info( | ||
"No se pudo responder, el tweet está duplicado.", exc_info=True) | ||
|
||
return idDesdeNuevo | ||
|
||
|
||
def main(): | ||
api = crearAPI() | ||
idDesde = 1 | ||
|
||
while True: | ||
|
||
idDesde = verificarMenciones( | ||
api, ["getclima"], idDesde) | ||
|
||
logger.info("Esperando para volver a verificar en 1 minuto...") | ||
|
||
time.sleep(60) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import tweepy | ||
# Logging se utiliza para informar errores y mensajes que nos ayudan en caso de un problema | ||
import logging | ||
# os interactua con el sistema operativo, en este caso las variables de entorno | ||
import os | ||
|
||
# Archivo de configuracion | ||
# Autenticarse en la API de Twitter | ||
# Crear y devolver el objeto api de tipo API | ||
|
||
# Al leer las credenciales de las variables de entorno se evita | ||
# codificarlas/mostrarlas en el codigo fuente, lo que lo hace más seguro | ||
|
||
logger = logging.getLogger() | ||
|
||
# Se leen las credenciales de autenticacion de las variables de entorno | ||
# y crea el objeto API Tweepy | ||
|
||
def crearAPI(): | ||
|
||
consumerKey = os.getenv('CONSUMER_KEY') | ||
consumerSecret = os.getenv('CONSUMER_SECRET') | ||
accessToken = os.getenv('ACCESS_TOKEN') | ||
accessTokenSecret = os.getenv('ACCESS_TOKEN_SECRET') | ||
|
||
aut=tweepy.OAuthHandler(consumerKey, consumerSecret) | ||
aut.set_access_token(accessToken, accessTokenSecret) | ||
|
||
# Se crea el objeto api de tipo API | ||
# Tweepy espera e imprime un mensaje cuando se excede el límite de velocidad | ||
api=tweepy.API(aut, wait_on_rate_limit = True, | ||
wait_on_rate_limit_notify = True) | ||
|
||
# Se verifica si las credenciales son válidas | ||
try: | ||
api.verify_credentials() | ||
except Exception as e: | ||
logger.error("Error al verificar las credenciales.", exc_info = True) | ||
raise e | ||
|
||
logger.info("API creada correctamente.") | ||
|
||
return api |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import tweepy | ||
import logging | ||
from config import crearAPI | ||
import json | ||
|
||
logging.basicConfig(level=logging.INFO) | ||
|
||
logger = logging.getLogger() | ||
|
||
# Clase que hereda de StreamListener | ||
# StreamListener es un oyente de flujo que imprime el texto de estado | ||
|
||
class FavRetweetListener(tweepy.StreamListener): | ||
|
||
def __init__(self, api): | ||
self.api = api | ||
# api.me() devuelve la informacion del usuario autenticado (yo) | ||
self.me = api.me() | ||
|
||
# Recibe un tweet y lo marca como me gusta y retweet | ||
def on_status(self, tweet): | ||
|
||
logger.info( | ||
f"Procesando tweet con id {tweet.id} de {tweet.user.screen_name}") | ||
|
||
# Si el tweet es una respuesta a otro tweet o si yo soy el autor del tweet (user.id) | ||
if tweet.in_reply_to_status_id is not None or tweet.user.id == self.me.id: | ||
return | ||
|
||
# si el tweet no se le ha dado me gusta | ||
if not tweet.favorited: | ||
|
||
try: | ||
|
||
logger.info("Dando me gusta al tweet...") | ||
tweet.favorite() | ||
|
||
except Exception as e: | ||
logger.error("Error en el me gusta.", exc_info=True) | ||
|
||
# Si el tweet no ha sido retweteado | ||
if not tweet.retweeted: | ||
try: | ||
|
||
logger.info("Retweeteando...") | ||
tweet.retweet() | ||
|
||
except Exception as e: | ||
logger.error("Error en el retweet.", exc_info=True) | ||
|
||
# Si ocurre algun error | ||
def on_error(self, status): | ||
logger.error(status) | ||
|
||
|
||
# Recibe las palabras claves para filtrar tweets | ||
|
||
def main(palabrasClaves): | ||
# Se crea el objeto API y un objeto de tipo FavRetweetListener | ||
api = crearAPI() | ||
tweetsListener = FavRetweetListener(api) | ||
|
||
# Se crea un objeto de transmision de tipo Stream de la API de transmision de Twitter | ||
# tweepy.Stream establece una sesion de transmision | ||
# y enruta los mensajes (tweets) a la instancia de StreamListener | ||
stream = tweepy.Stream(auth=api.auth, listener=tweetsListener) | ||
|
||
logger.info("Escuchando tweets...") | ||
|
||
# Se usa filter para transmitir todos los tweets que contengan dichas palabras | ||
stream.filter(track=palabrasClaves) | ||
|
||
|
||
if __name__ == "__main__": | ||
main(["getClima"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Este bot obtiene la lista de seguidores cada minuto | ||
# para seguir a cada usuario que aún no está siguiendo | ||
import tweepy | ||
import logging | ||
# se importa el metodo del archivo config | ||
from config import crearAPI | ||
import time | ||
|
||
logging.basicConfig(level=logging.INFO) | ||
logger = logging.getLogger() | ||
|
||
def seguirSeguidores(api): | ||
|
||
logger.info("Recuperando seguidores...") | ||
|
||
# Se obtienen y recorren los seguiidores de la lista de seguidores | ||
for seguidor in tweepy.Cursor(api.followers).items(): | ||
# Si no se está siguiendo a un seguidor | ||
if not seguidor.following: | ||
hora = time.strftime("%H:%M:%S") | ||
logger.info(f"Siguiendo a {seguidor.name} a las {hora}") | ||
# Se sigue al seguidor | ||
seguidor.follow() | ||
|
||
|
||
def main(): | ||
# Se obtiene el objeto api creado en config | ||
api = crearAPI() | ||
|
||
# Se repite infinitamente | ||
while True: | ||
seguirSeguidores(api) | ||
logger.info("Esperando para volver a verificar...") | ||
# Se llama una vez por minuto | ||
# ya que hay un limite de peticiones | ||
time.sleep(60) | ||
|
||
|
||
# Se ejecuta el main | ||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import tweepy | ||
import time | ||
import logging | ||
from config import crearAPI | ||
import API.weatherAPI as weatherAPI | ||
|
||
logging.basicConfig(level=logging.INFO) | ||
logger = logging.getLogger() | ||
|
||
|
||
def publicarTweet(api, clima): | ||
|
||
try: | ||
logger.info("Creando tweet...") | ||
api.update_status(clima) | ||
|
||
except Exception as e: | ||
logger.error("Error al crear el tweet.", exc_info=True) | ||
|
||
|
||
def main(): | ||
|
||
api = crearAPI() | ||
|
||
while True: | ||
|
||
ciudad = 'Mendoza, AR' | ||
clima = weatherAPI.getClima(ciudad) | ||
hora = time.strftime("%H:%M:%S") | ||
|
||
clima += f"\nHora: {hora}" | ||
|
||
publicarTweet(api, clima) | ||
|
||
logger.info("Esperando para volver a publicar...") | ||
time.sleep(60) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |