diff --git a/.gitignore b/.gitignore
index 379ee55..598a033 100644
--- a/.gitignore
+++ b/.gitignore
@@ -159,4 +159,4 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
-noticias.json
\ No newline at end of file
+*.json
\ No newline at end of file
diff --git a/connectors/fiuba_web.py b/connectors/fiuba_web.py
index 1c12e89..7810b67 100644
--- a/connectors/fiuba_web.py
+++ b/connectors/fiuba_web.py
@@ -2,12 +2,13 @@
from entities.noticia import Noticia
+
class FiubaWeb(ABC):
-
+
@abstractclassmethod
def obtener_noticias(self, n: int = 1) -> list:
pass
@abstractclassmethod
def obtener_noticias_nuevas(self, ultima_noticia: Noticia) -> list:
- pass
\ No newline at end of file
+ pass
diff --git a/connectors/silk.py b/connectors/silk.py
index 4753f7f..aff53f2 100644
--- a/connectors/silk.py
+++ b/connectors/silk.py
@@ -16,6 +16,7 @@
INICIO_TITULO = 8
MAX_NOTICIAS = 16
+
class Silk(FiubaWeb):
def __init__(self):
self.logger = logging.getLogger(__class__.__name__)
@@ -31,7 +32,7 @@ def obtener_noticias(self, n_noticias: int = 1) -> list:
noticias.append(self.obtener_noticia(uri))
return noticias
-
+
def obtener_noticia(self, uri: str) -> Noticia:
url = DOMINIO + uri
self.logger.info("Obteniendo noticia de {url}".format(url=url))
@@ -50,7 +51,7 @@ def obtener_noticia(self, uri: str) -> Noticia:
titulo = soup.title.get_text()[INICIO_TITULO:]
return Noticia(titulo, descripcion, fecha, url)
-
+
def obtener_noticias_nuevas(self, ultima_noticia: Noticia) -> list:
uris_noticias = self.__obtener_uri_noticias()
@@ -58,20 +59,20 @@ def obtener_noticias_nuevas(self, ultima_noticia: Noticia) -> list:
for uri in uris_noticias[:MAX_NOTICIAS]:
noticia = self.obtener_noticia(uri)
-
+
if noticia.fecha > ultima_noticia.fecha:
noticias_nuevas.append(noticia)
else:
break
return noticias_nuevas
-
+
def __obtener_uri_noticias(self) -> list:
page = requests.get(LINK_NOTICIAS)
soup = BeautifulSoup(page.content, 'html.parser')
return list(map(lambda x: x.get('href'), soup.select(".noticia > a")))
-
+
def __validar_cantidad(self, n_noticias: int) -> None:
if n_noticias <= 0:
raise CantidadNoticiasNegativaException(n_noticias)
diff --git a/controllers/jjjameson.py b/controllers/jjjameson.py
index 07dc66e..a2a9849 100644
--- a/controllers/jjjameson.py
+++ b/controllers/jjjameson.py
@@ -5,20 +5,28 @@
from connectors.fiuba_web import FiubaWeb
from view.imprenta import Imprenta
from repositories.noticias_repository import NoticiasRepository
+from repositories.estado_repository import EstadoRepository
from error_handler import logging
from exceptions.cantidad_noticias_exception import CantidadNoticiasNoEsNumeroException
ID_CANAL_NOTICIAS = os.getenv('ID_CANAL_NOTICIAS')
-INTERVALO_MENSAJES_AUTOMATICOS = 3*60*60 # En segundos
+INTERVALO_MENSAJES_AUTOMATICOS = 3*60*60 # En segundos
+
class JJJameson:
- def __init__(self, fiuba_web: FiubaWeb, repo: NoticiasRepository, imprenta: Imprenta):
+ def __init__(self, fiuba_web: FiubaWeb, noticias_repo: NoticiasRepository, estado_repo: EstadoRepository, imprenta: Imprenta, job_queue, bot):
self.fiuba_web = fiuba_web
- self.repo = repo
+ self.repo = noticias_repo
+ self.estado_repo = estado_repo
self.imprenta = imprenta
- self.noticias_automaticas = False
- self.job = None
+ self.noticias_automaticas = self.estado_repo.noticias_automaticas()
+
+ if self.noticias_automaticas:
+ self.__activar_noticias_automaticas(job_queue, bot.get_chat(ID_CANAL_NOTICIAS))
+ else:
+ self.job = None
+
self.logger = logging.getLogger(__class__.__name__)
def conseguir_noticias(self, update: Update, context: CallbackContext):
@@ -39,29 +47,33 @@ def conseguir_noticias(self, update: Update, context: CallbackContext):
self.logger.warn("Cantidad de noticias no es número {arg}".format(arg=context.args[0]))
raise CantidadNoticiasNoEsNumeroException(arg=context.args[0])
+ def __activar_noticias_automaticas(self, job_queue, chat):
+ self.job = job_queue.run_repeating(self.conseguir_noticias_automatico, INTERVALO_MENSAJES_AUTOMATICOS, context=chat)
+
def activar_noticias_automaticas(self, update: Update, context: CallbackContext):
- if self.noticias_automaticas == False:
- self.job = context.job_queue.run_repeating(self.conseguir_noticias_automatico, INTERVALO_MENSAJES_AUTOMATICOS, context=context.bot.get_chat(ID_CANAL_NOTICIAS))
+ if not self.noticias_automaticas:
+ self.__activar_noticias_automaticas(context.job_queue, context.bot.get_chat(ID_CANAL_NOTICIAS))
self.noticias_automaticas = True
- self.logger.info("Se activaron las noticias automaticas.")
+ self.estado_repo.guardar(self.noticias_automaticas)
+ self.logger.info("Se activaron las noticias automáticas.")
update.effective_chat.send_message("Se activaron las noticias automáticas.")
else:
- update.effective_chat.send_message("Las noticias automáticas ya estan activadas.")
-
+ update.effective_chat.send_message("Las noticias automáticas ya están activadas.")
def desactivar_noticias_automaticas(self, update: Update, _: CallbackContext):
- if self.noticias_automaticas == True:
+ if self.noticias_automaticas:
self.job.schedule_removal()
self.noticias_automaticas = False
+ self.estado_repo.guardar(self.noticias_automaticas)
self.logger.info("Se desactivaron las noticias automáticas.")
update.effective_chat.send_message("Se desactivaron las noticias automáticas.")
else:
- update.effective_chat.send_message("Las noticias automáticas no estan activadas.")
+ update.effective_chat.send_message("Las noticias automáticas no están activadas.")
def conseguir_noticias_automatico(self, context: CallbackContext):
ultima_noticia_guardada = self.repo.ultima_noticia()
self.logger.info("Fecha de última noticia {titulo} es {fecha}.".format(titulo=ultima_noticia_guardada.titulo, fecha=ultima_noticia_guardada.fecha))
-
+
nuevas_noticias = self.fiuba_web.obtener_noticias_nuevas(ultima_noticia_guardada)
if len(nuevas_noticias) > 0:
@@ -70,3 +82,6 @@ def conseguir_noticias_automatico(self, context: CallbackContext):
self.imprenta.enviar_noticias(context.job.context, nuevas_noticias, 30)
else:
self.logger.info("No hay noticias nuevas.")
+
+ def estado(self, update: Update, _: CallbackContext):
+ update.effective_chat.send_message("Noticias automáticas: {noticias_automaticas}".format(noticias_automaticas=self.noticias_automaticas))
diff --git a/exceptions/cantidad_noticias_exception.py b/exceptions/cantidad_noticias_exception.py
index 89f69cf..9314360 100644
--- a/exceptions/cantidad_noticias_exception.py
+++ b/exceptions/cantidad_noticias_exception.py
@@ -3,16 +3,19 @@ def __init__(self, message) -> None:
self.message = message
super().__init__(self.message)
+
class CantidadNoticiasNoEsNumeroException(CantidadNoticiasException):
- def __init__(self, arg = "") -> None:
+ def __init__(self, arg="") -> None:
self.message = "No creo que '{arg}' sea un número.".format(arg=arg)
super().__init__(self.message)
-
+
+
class CantidadNoticiasNegativaException(CantidadNoticiasException):
def __init__(self, arg) -> None:
self.message = "¿Cómo puedo conseguir {arg} noticias?".format(arg=arg)
super().__init__(self.message)
+
class CantidadNoticiasMaximaException(CantidadNoticiasException):
def __init__(self, arg) -> None:
self.message = "¿Quieres que consiga {arg} noticias? Aumentame el sueldo.".format(arg=arg)
diff --git a/main.py b/main.py
index d29dffb..c25adf6 100644
--- a/main.py
+++ b/main.py
@@ -4,6 +4,7 @@
from connectors.silk import Silk
from view.threats_and_menaces import ThreatsAndMenaces
from repositories.noticias_repository import NoticiasRepository
+from repositories.estado_repository import EstadoRepository
from error_handler import error_handler, logging
from telegram.ext import Updater, Filters, CommandHandler
from dotenv import load_dotenv
@@ -13,6 +14,7 @@
logger = logging.getLogger('main')
+
def main():
updater = Updater(token=os.getenv('BOT_TOKEN'), use_context=True)
@@ -20,21 +22,22 @@ def main():
logger.info("Iniciando {full_name} (@{username}).".format(full_name=bot.full_name, username=bot.username))
- jameson = JJJameson(Silk(), NoticiasRepository(), ThreatsAndMenaces())
+ jameson = JJJameson(Silk(), NoticiasRepository(), EstadoRepository(), ThreatsAndMenaces(), updater.job_queue, updater.bot)
filtro = Filters.chat(chat_id=int(os.getenv('ID_GRUPO_NOTICIAS')))
updater.dispatcher.add_handler(CommandHandler('noticias', jameson.conseguir_noticias, filtro))
updater.dispatcher.add_handler(CommandHandler('empezar', jameson.activar_noticias_automaticas, filtro))
updater.dispatcher.add_handler(CommandHandler('terminar', jameson.desactivar_noticias_automaticas, filtro))
+ updater.dispatcher.add_handler(CommandHandler('estado', jameson.estado, filtro))
updater.dispatcher.add_error_handler(error_handler)
try:
updater.start_polling()
logger.info("Iniciado, esperando por comandos...")
-
+
updater.idle()
except Exception as e:
logger.error(e.__cause__)
-main()
\ No newline at end of file
+main()
diff --git a/repositories/estado_repository.py b/repositories/estado_repository.py
new file mode 100644
index 0000000..38f2512
--- /dev/null
+++ b/repositories/estado_repository.py
@@ -0,0 +1,30 @@
+import os
+import json
+
+ESTADO_DEFAULT_JSON = {
+ "noticias_automaticas": False
+}
+
+
+class EstadoRepository:
+ def __init__(self, path: str = "estado.json"):
+ if not os.path.exists(path):
+ with open(path, "w", encoding='utf-8') as f:
+ json.dump(ESTADO_DEFAULT_JSON, f, indent=4)
+
+ self.path = path
+
+ def noticias_automaticas(self) -> bool:
+ estado = {}
+ with open(self.path, 'r', encoding='utf-8') as f:
+ estado = json.load(f)
+
+ return estado.get("noticias_automaticas", False)
+
+ def guardar(self, noticias_automaticas) -> None:
+ estado = {
+ "noticias_automaticas": noticias_automaticas
+ }
+
+ with open(self.path, "w", encoding='utf-8') as f:
+ json.dump(estado, f, indent=4)
diff --git a/repositories/noticias_repository.py b/repositories/noticias_repository.py
index 2bfea41..e9ce458 100644
--- a/repositories/noticias_repository.py
+++ b/repositories/noticias_repository.py
@@ -5,9 +5,10 @@
from entities.noticia import Noticia
from error_handler import logging
+
class NoticiasRepository:
def __init__(self, path: str = "noticias.json"):
- if os.path.exists(path) == False:
+ if not os.path.exists(path):
f = open(path, "w")
f.close()
self.path = path
@@ -18,7 +19,7 @@ def ultima_noticia(self) -> Noticia:
with open(self.path, 'r', encoding='utf-8') as f:
ultima_noticia_json = json.load(f)
-
+
return self.__json_to_object(ultima_noticia_json)
def guardar(self, noticia: Noticia) -> Noticia:
@@ -28,7 +29,7 @@ def guardar(self, noticia: Noticia) -> Noticia:
json.dump(noticia_json, f, indent=4)
self.logger.info("Guardada {noticia}.".format(noticia=noticia_json))
-
+
return noticia
def __object_to_json(self, noticia: Noticia) -> dict:
@@ -40,7 +41,7 @@ def __object_to_json(self, noticia: Noticia) -> dict:
}
return noticia_json
-
+
def __json_to_object(self, noticia_json: dict) -> Noticia:
fecha = datetime.strptime(noticia_json['fecha'], "%Y-%m-%d %H:%M")
- return Noticia(noticia_json['titulo'], noticia_json['descripcion'], fecha, noticia_json['url'])
\ No newline at end of file
+ return Noticia(noticia_json['titulo'], noticia_json['descripcion'], fecha, noticia_json['url'])
diff --git a/view/threats_and_menaces.py b/view/threats_and_menaces.py
index 07da354..38c4e13 100644
--- a/view/threats_and_menaces.py
+++ b/view/threats_and_menaces.py
@@ -8,6 +8,7 @@
MAS_INFORMACION = emojize(":information: Más información")
FORMATO_MENSAJE = "{titulo}\n\n{descripcion}\n\n{texto_url}\n"
+
class ThreatsAndMenaces(Imprenta):
def __init__(self):
self.logger = logging.getLogger(__class__.__name__)