gear-orders/telegram/commands.py

188 lines
5.6 KiB
Python
Raw Normal View History

2026-01-09 22:33:38 +00:00
import re
2025-11-16 16:34:52 +00:00
import logging
import peewee
2025-11-16 17:58:34 +00:00
import datetime
2025-11-16 16:34:52 +00:00
2026-01-09 22:33:38 +00:00
from db.queries import skip_day_put, skip_day_delete, skip_days_upcoming, user_add, user_get, domsubusers_add, domsubusers_delete
2026-03-19 17:38:17 +00:00
from db.models import OrdersPool
2026-01-09 22:33:38 +00:00
from .telegram import Telegram, TelegramCommand
from settings import FLASK_URL
2025-11-16 16:34:52 +00:00
logger = logging.getLogger(__name__)
2026-03-19 17:38:17 +00:00
CALLBACK_PREFIX_SKIP_DAY_ADD = "skip_day_add_"
2026-01-09 22:33:38 +00:00
class StartCommand(TelegramCommand):
command_text = '/start'
2026-03-07 01:12:28 +00:00
description = "Start a session with the bot"
2026-01-09 22:33:38 +00:00
async def exec_inner(self, text, update, *args, **kwargs):
username = update['message']['chat']['username']
chat_id = update['message']['chat']['id']
user_add(username, chat_id)
2026-03-07 16:44:09 +00:00
yield f"Welcome to Gear Orders bot.\n\nEdit your orders at {FLASK_URL}\n\nAdd a dom with `/dom_add <username>` or ask a sub to add you."
2026-01-09 22:33:38 +00:00
class DomAddCommand(TelegramCommand):
2026-03-07 01:12:28 +00:00
command_text = "/dom_add"
2026-01-09 22:33:38 +00:00
command_regex = re.compile(r"^\/dom_add( (?P<username>@?\w+))$")
2026-03-07 01:12:28 +00:00
description = "Add a dom to your profile"
2026-01-09 22:33:38 +00:00
async def exec_inner(self, text, update, session, *args, **kwargs):
dom_username = text.split(' ')[1]
if dom_username.startswith('@'):
dom_username = dom_username[1:]
sub_username = update['message']['chat']['username']
sub = user_get(sub_username)
try:
dom = user_get(dom_username)
except:
yield "I'm sorry that user isn't registered with me."
return
try:
domsubusers_add(sub, dom)
except peewee.IntegrityError:
yield f"@{dom_username} is already on your list of doms"
return
yield f"Successfully added {dom_username} to your list of doms"
t = Telegram(session)
await t.message_send(dom.telegram_chat_id, f"@{sub_username} has added you as a dom. You may edit their orders at {FLASK_URL}")
2026-01-09 22:33:38 +00:00
class DomRemoveCommand(TelegramCommand):
2026-03-07 01:12:28 +00:00
command_text = "/dom_remove"
2026-01-09 22:33:38 +00:00
command_regex = re.compile(r"^\/dom_remove( (?P<username>@?\w+))$")
2026-03-07 01:12:28 +00:00
description = "Remove a dom from your profile"
2026-01-09 22:33:38 +00:00
async def exec_inner(self, text, update, session, *args, **kwargs):
dom_username = text.split(' ')[1]
if dom_username.startswith('@'):
dom_username = dom_username[1:]
sub_username = update['message']['chat']['username']
sub = user_get(sub_username)
try:
dom = user_get(dom_username)
except:
yield "I'm sorry that user isn't registered with me."
return
try:
domsubusers_delete(sub, dom)
except peewee.DoesNotExist:
yield "I'm sorry that user is not on your list of doms"
return
yield f"Successfully removed {dom_username} from your list of doms"
t = Telegram(session)
2026-03-06 02:16:31 +00:00
await t.message_send(dom.telegram_chat_id, f"@{sub_username} has removed you as a dom.")
2026-01-09 22:33:38 +00:00
2025-11-16 16:34:52 +00:00
class SkipDayAddCommand(TelegramCommand):
command_text = "/skip_day"
2026-03-07 01:12:28 +00:00
description = "Add a skip day"
2025-11-16 16:34:52 +00:00
async def exec_inner(self, text, update, session, forResponse=None, reply=None):
try:
yield "Please enter a skip day"
2026-03-19 17:38:17 +00:00
skip_day_str = await forResponse()
try:
skip_day = datetime.date.fromisoformat(skip_day_str)
except:
yield "The date you entered was not valid"
return
2025-11-16 16:34:52 +00:00
2026-03-06 02:16:31 +00:00
user = user_get(update['message']['chat']['username'])
2026-03-19 17:38:17 +00:00
inline_keyboard = [{
'text': 'All',
'callback_data': f"{CALLBACK_PREFIX_SKIP_DAY_ADD}_all"
}] + [
{
'text': pool.name,
'callback_data': f"{CALLBACK_PREFIX_SKIP_DAY_ADD}_{pool.id}"
} for pool in user.orders_pools
]
yield "Please choose an order pool", {
"inline_keyboard": [inline_keyboard]
}
pool_str = await forResponse()
if not pool_str.startswith("skip_day_add_"):
yield "There was a problem with your command"
return
2025-11-16 17:58:34 +00:00
2026-03-19 17:38:17 +00:00
try:
order_pool_id = int(pool_str[len(CALLBACK_PREFIX_SKIP_DAY_ADD)+1:])
order_pool = user.orders_pools.where(OrdersPool.id == order_pool_id).get()
except:
order_pool = None
skip_day_put(user, skip_day, order_pool)
if order_pool is not None:
yield f"Skip day {skip_day_str} for pool {order_pool.name} has been added"
else:
yield f"Skip day {skip_day_str} has been added"
2025-11-16 17:58:34 +00:00
except ValueError:
yield "That date was not valid"
2025-11-16 16:34:52 +00:00
except peewee.IntegrityError:
yield "That day has already been added"
2025-11-16 17:58:34 +00:00
class SkipDayDeleteCommand(TelegramCommand):
command_text = "/skip_day_delete"
2026-03-07 01:12:28 +00:00
description = "Delete a skip day"
2025-11-16 17:58:34 +00:00
async def exec_inner(self, text, update, session, forResponse=None, reply=None):
try:
yield "Please enter a skip day to delete"
response = await forResponse()
2026-03-06 02:16:31 +00:00
user = user_get(update['message']['chat']['username'])
2025-11-16 17:58:34 +00:00
skip_day = datetime.date.fromisoformat(response)
2026-03-06 02:16:31 +00:00
rows = skip_day_delete(user, skip_day)
2025-11-16 17:58:34 +00:00
if rows > 0:
yield f"Skip day {skip_day} has been deleted"
else:
yield f"Skip day {skip_day} does not exist"
except ValueError:
yield "That date was not valid"
class SkipDaysCommand(TelegramCommand):
command_text = "/skip_days"
2026-03-07 01:12:28 +00:00
description = "List upcoming skip days"
2025-11-16 17:58:34 +00:00
async def exec_inner(self, text, update, session, forResponse=None, reply=None):
2026-03-06 02:16:31 +00:00
user = user_get(update['message']['chat']['username'])
dates = skip_days_upcoming(user)
2026-03-19 17:38:17 +00:00
response = "Upcoming skip days -\n"
for date in dates:
if date.pool is None:
response += date.date.isoformat() + "\n"
else:
response += f"{date.date.isoformat()} - {date.pool.name}\n"
yield response
2025-11-16 17:58:34 +00:00
2025-11-16 16:34:52 +00:00
commands = [
2026-01-09 22:33:38 +00:00
StartCommand(),
DomAddCommand(),
DomRemoveCommand(),
2025-11-16 17:58:34 +00:00
SkipDayAddCommand(),
SkipDayDeleteCommand(),
SkipDaysCommand()
2025-11-16 16:34:52 +00:00
]