Skip to content

Commit 1eaa087

Browse files
committed
Refactor bot_logic.py into handlers package
1 parent 0bf59a4 commit 1eaa087

13 files changed

Lines changed: 541 additions & 1210 deletions

File tree

bot_logic.py

Lines changed: 8 additions & 637 deletions
Large diffs are not rendered by default.

dcubabot.py

Lines changed: 0 additions & 519 deletions
This file was deleted.

handlers/__init__.py

Whitespace-only changes.

handlers/admin.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import logging
2+
import datetime
3+
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
4+
from telegram.ext import ContextTypes
5+
from telegram.constants import ParseMode
6+
from tg_ids import CODEPERS_CHATID, ROZEN_CHATID, DGARRO_CHATID
7+
from models import Noticia
8+
from handlers.db import get_session
9+
10+
logger = logging.getLogger("DCUBABOT")
11+
admin_ids = [ROZEN_CHATID, DGARRO_CHATID]
12+
13+
async def checodepers(update: Update, context: ContextTypes.DEFAULT_TYPE):
14+
if not context.args:
15+
ejemplo = """ Ejemplo de uso:
16+
/checodepers Hola, tengo un mensaje mucho muy importante que me gustaria que respondan
17+
"""
18+
await update.message.reply_text(ejemplo)
19+
return
20+
user = update.message.from_user
21+
try:
22+
if not user.username:
23+
raise Exception("not userneim")
24+
message = " ".join(context.args)
25+
await context.bot.send_message(
26+
chat_id=CODEPERS_CHATID, text=f"{user.first_name}(@{user.username}) : {message}")
27+
except Exception:
28+
try:
29+
await context.bot.forward_message(
30+
CODEPERS_CHATID, update.message.chat_id, update.message.message_id)
31+
logger.info(f"Malio sal {str(user)}")
32+
except Exception as e:
33+
await update.message.reply_text(
34+
"La verdad me re rompí, avisale a roz asi ve que onda")
35+
logger.error(e)
36+
return
37+
await update.message.reply_text("OK, se lo mando a les codepers.")
38+
39+
async def checodeppers(update: Update, context: ContextTypes.DEFAULT_TYPE):
40+
await checodepers(update, context)
41+
42+
async def sugerirNoticia(update: Update, context: ContextTypes.DEFAULT_TYPE):
43+
user = update.message.from_user
44+
name = user.first_name
45+
texto = " ".join(context.args)
46+
if not texto:
47+
await update.message.reply_text(
48+
text="Loc@, pusisiste algo mal, la idea es q pongas:\n "
49+
"/sugerirNoticia <texto>")
50+
return
51+
with get_session() as session:
52+
noticia = Noticia(text=texto)
53+
session.add(noticia)
54+
session.flush()
55+
noticia_id = noticia.id
56+
keyboard = [
57+
[
58+
InlineKeyboardButton("Aceptar", callback_data=f"Noticia|{noticia_id}|1"),
59+
InlineKeyboardButton("Rechazar", callback_data=f"Noticia|{noticia_id}|0")
60+
]
61+
]
62+
reply_markup = InlineKeyboardMarkup(keyboard)
63+
await context.bot.send_message(chat_id=ROZEN_CHATID, text=f"Noticia-{name}: {texto}",
64+
reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN)
65+
await update.message.reply_text(text="Ok, se lo pregunto a Rozen")
66+
67+
async def get_logs(update: Update, context: ContextTypes.DEFAULT_TYPE):
68+
user_id = update.effective_user.id
69+
if user_id not in admin_ids:
70+
return
71+
72+
try:
73+
from google.cloud import logging as gcp_logging
74+
import json
75+
import io
76+
77+
await update.message.reply_text("Buscando errores en Google Cloud Logging...")
78+
client = gcp_logging.Client()
79+
80+
filter_str = 'resource.type="cloud_run_revision" AND severity>=ERROR AND resource.labels.service_name="dcubabot"'
81+
entries = client.list_entries(filter_=filter_str, order_by=gcp_logging.DESCENDING, max_results=50)
82+
83+
log_msgs = []
84+
for entry in entries:
85+
log_data = {
86+
"timestamp": entry.timestamp.isoformat(),
87+
"severity": entry.severity,
88+
}
89+
90+
payload = entry.payload
91+
if isinstance(payload, dict):
92+
log_data["json_payload"] = payload
93+
elif payload is not None:
94+
log_data["text_payload"] = str(payload)
95+
else:
96+
log_data["resource"] = str(entry.resource)
97+
98+
log_msgs.append(log_data)
99+
100+
if not log_msgs:
101+
await update.message.reply_text("✅ No se encontraron errores recientes en GCP.")
102+
return
103+
104+
logs_json_str = json.dumps(log_msgs, indent=2, ensure_ascii=False)
105+
file_obj = io.BytesIO(logs_json_str.encode('utf-8'))
106+
file_obj.name = f"gcp_error_logs_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
107+
108+
await context.bot.send_document(
109+
chat_id=update.effective_chat.id,
110+
document=file_obj,
111+
caption="Acá tenés el archivo con los últimos errores registrados en GCP 🕵️‍♂️"
112+
)
113+
except Exception as e:
114+
await update.message.reply_text(f"Error al leer logs (¿falta permiso roles/logging.viewer en la Service Account?): {e}")

handlers/basic.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import sys
2+
from telegram import Update
3+
from telegram.ext import ContextTypes
4+
from models import Command
5+
from handlers.db import get_session
6+
7+
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
8+
await update.message.reply_text(
9+
"Hola, ¿qué tal? ¡Mandame /help si no sabés qué puedo hacer!")
10+
11+
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
12+
message_text = "Comandos disponibles:\n"
13+
with get_session() as session:
14+
commands = session.query(Command).filter_by(enabled=True).order_by(Command.name).all()
15+
for command in commands:
16+
if command.description:
17+
message_text += f"/{command.name} - {command.description}\n"
18+
else:
19+
message_text += f"/{command.name}\n"
20+
await update.message.reply_text(message_text)
21+
22+
async def estasvivo(update: Update, context: ContextTypes.DEFAULT_TYPE):
23+
await update.message.reply_text(f"Sí, estoy vivo y corriendo en Python {sys.version.split()[0]}")
24+
25+
async def colaborar(update: Update, context: ContextTypes.DEFAULT_TYPE):
26+
await update.message.reply_text(
27+
"Se puede colaborar con el DCUBA bot en https://github.com/comcomUBA/dcubabot")

handlers/callbacks.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from telegram import Update
2+
from telegram.ext import ContextTypes
3+
from telegram.constants import ParseMode
4+
from models import Listable, Noticia
5+
from handlers.db import get_session
6+
from tg_ids import NOTICIAS_CHATID
7+
8+
async def button(update: Update, context: ContextTypes.DEFAULT_TYPE):
9+
query = update.callback_query
10+
await query.answer()
11+
message = query.message
12+
buttonType, id_val, action = query.data.split("|")
13+
14+
with get_session() as session:
15+
if buttonType == "Listable":
16+
group = session.query(Listable).filter_by(id=int(id_val)).first()
17+
if group:
18+
if action == "1":
19+
group.validated = True
20+
action_text = "\n¡Aceptado!"
21+
else:
22+
session.delete(group)
23+
action_text = "\n¡Rechazado!"
24+
await query.edit_message_text(text=message.text + action_text)
25+
26+
elif buttonType == "Noticia":
27+
noticia = session.query(Noticia).filter_by(id=int(id_val)).first()
28+
if noticia:
29+
if action == "1":
30+
noticia.validated = True
31+
action_text = "\n¡Aceptado!"
32+
await context.bot.send_message(chat_id=NOTICIAS_CHATID,
33+
text=noticia.text, parse_mode=ParseMode.MARKDOWN)
34+
else:
35+
session.delete(noticia)
36+
action_text = "\n¡Rechazado!"
37+
await query.edit_message_text(text=message.text + action_text)

handlers/crons.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import pytz
2+
import datetime
3+
import random
4+
import logging
5+
from telegram.ext import ContextTypes
6+
import river
7+
import conciertos
8+
from tg_ids import DC_GROUP_CHATID, NOTICIAS_CHATID
9+
10+
logger = logging.getLogger("DCUBABOT")
11+
bsasTz = pytz.timezone("America/Argentina/Buenos_Aires")
12+
13+
def felizdia_text(today):
14+
meses = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio",
15+
"Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]
16+
dia = str(today.day)
17+
mes = int(today.month)
18+
19+
if mes == 3 and today.day == 8:
20+
return "Hoy es 8 de Marzo"
21+
else:
22+
mes = meses[mes - 1]
23+
return "Feliz " + dia + " de " + mes
24+
25+
async def felizdia(context: ContextTypes.DEFAULT_TYPE):
26+
if random.uniform(0, 7) > 1:
27+
return
28+
today = datetime.date.today()
29+
chat_id = DC_GROUP_CHATID
30+
await context.bot.send_message(chat_id=chat_id, text=felizdia_text(today))
31+
32+
async def actualizarPartidos(context: ContextTypes.DEFAULT_TYPE):
33+
hoy = datetime.datetime.now(bsasTz)
34+
mañana = hoy + datetime.timedelta(days=1)
35+
try:
36+
local, partido = river.es_local(mañana)
37+
if not local:
38+
return
39+
horario = "hora a confirmar" if partido.hora is None else partido.hora.strftime("a las %H:%M")
40+
msg = f"Mañana juega River, {horario}\n(contra {partido.equipo_visitante}, {partido.copa})"
41+
await context.bot.send_message(chat_id=NOTICIAS_CHATID, text=msg)
42+
except Exception as e:
43+
logger.error(f"Error checking River matches: {e}")
44+
45+
async def actualizarConciertos(context: ContextTypes.DEFAULT_TYPE):
46+
hoy = datetime.datetime.now(bsasTz)
47+
mañana = hoy + datetime.timedelta(days=1)
48+
try:
49+
hay, concierto = conciertos.hay_concierto(mañana)
50+
if not hay:
51+
return
52+
msg = f"Mañana hay un concierto en River\n{concierto.titulo}"
53+
await context.bot.send_message(chat_id=NOTICIAS_CHATID, text=msg)
54+
except Exception as e:
55+
logger.error(f"Error checking concerts: {e}")
56+
57+
async def actualizarRiver(context: ContextTypes.DEFAULT_TYPE):
58+
await actualizarPartidos(context)
59+
await actualizarConciertos(context)

handlers/db.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import models
2+
from contextlib import contextmanager
3+
4+
@contextmanager
5+
def get_session():
6+
"""Provide a transactional scope around a series of operations."""
7+
if models.Session is None:
8+
models.init_db()
9+
session = models.Session()
10+
try:
11+
yield session
12+
session.commit()
13+
except:
14+
session.rollback()
15+
raise
16+
finally:
17+
session.close()

0 commit comments

Comments
 (0)