ruz-bot/helpers/answer.py
Administrator f0440e3000 many fixes
2023-04-03 00:36:41 +03:00

408 lines
19 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from telebot.types import Message
from daemons.bot import bot
from daemons.fetch import fetch_schedule_for_user
from helpers import get_next_daily_notify_time
from helpers.keyboards import main_keyboard, notify_keyboard, yes_no_keyboard, again_keyboard, groups_keyboard, \
no_daily_notify, student_or_teacher_keyboard, campus_keyboard, daily_notify_type, notify_type, first_lesson_notify
from helpers.models import UserSchema, User
from helpers.mongo import mongo
from helpers.ruz import ruz
class BaseAnswer:
def process(self, message: Message):
user = mongo.users_collection.find_one({"chat_id": message.chat.id})
if user is None:
user = User(chat_id=message.chat.id)
mongo.users_collection.insert_one(UserSchema().dump(user))
else:
user = UserSchema().load(user)
attr = getattr(self, "handle_state_" + user.state, None)
if attr is None:
raise NotImplementedError(f"handled state {user.state} but not implemented!")
attr(message, user)
def set_state(self, user: User, state: str):
user.state = state
mongo.users_collection.update_one({"chat_id": user.chat_id}, {"$set": {"state": state}})
class Answer(BaseAnswer):
def handle_state_new(self, message: Message, user: User):
bot.send_message(
message.chat.id,
"Привет! Я буду помогать тебе выживать в вышке!\nИз какого ты кампуса?",
reply_markup=campus_keyboard()
)
self.set_state(user, "wait_for_campus")
def handle_state_wait_for_campus(self, message: Message, user: User):
if message.text not in ["Москва", "Санкт-Петербург", "Нижний Новгород", "Пермь"]:
bot.send_message(
user.chat_id,
"Ты прислал мне что-то непонятное, используй кнопки. Из какого ты кампуса?",
reply_markup=campus_keyboard()
)
return
bot.send_message(
user.chat_id,
"Принято! Ты преподаватель или студент?",
reply_markup=student_or_teacher_keyboard()
)
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"campus": message.text, "state": "wait_for_student_or_teacher"}}
)
def handle_state_wait_for_student_or_teacher(self, message: Message, user: User):
if message.text == "Студент 👨‍🎓":
bot.send_message(user.chat_id, "Принято! Теперь отправь мне свое ФИО.", reply_markup=again_keyboard())
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"is_teacher": False, "state": "wait_for_name"}}
)
self.set_state(user, "wait_for_name")
elif message.text == "Преподаватель 👨‍🏫":
bot.send_message(user.chat_id, "Принято! Теперь отправь мне свое ФИО.", reply_markup=again_keyboard())
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"is_teacher": True, "state": "wait_for_name"}}
)
self.set_state(user, "wait_for_name")
elif message.text == "Начать заново 🔄":
bot.send_message(
message.chat.id,
"Привет! Я буду помогать тебе выживать в вышке!\nИз какого ты кампуса?",
reply_markup=campus_keyboard()
)
self.set_state(user, "wait_for_campus")
return
else:
bot.send_message(user.chat_id, "Ты отправил мне что-то неправильное, используй кнопки. Ты преподаватель или студент?", reply_markup=student_or_teacher_keyboard())
def handle_state_wait_for_name(self, message: Message, user: User):
if message.text == "Начать заново 🔄":
bot.send_message(
message.chat.id,
"Привет! Я буду помогать тебе выживать в вышке!\nИз какого ты кампуса?",
reply_markup=campus_keyboard()
)
self.set_state(user, "wait_for_campus")
return
user.name = message.text
data = ruz.find_person(user)
if data is None:
bot.send_message(
user.chat_id,
"В РУЗе какая-то поломка, попробуй еще раз позже."
)
return
if len(data) == 0:
bot.send_message(user.chat_id, "К сожалению, в РУЗе не нашлось такого человека, попробуй еще раз.")
return
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"name": user.name}})
if user.is_teacher:
bot.send_message(
user.chat_id,
"Отлично! Теперь выбери из списка свой департамент.",
reply_markup=groups_keyboard(data)
)
else:
bot.send_message(
user.chat_id,
"Отлично! Теперь выбери из списка свою группу.",
reply_markup=groups_keyboard(data)
)
self.set_state(user, "wait_for_group")
def handle_state_wait_for_group(self, message: Message, user: User):
if message.text == "Начать заново 🔄":
bot.send_message(
message.chat.id,
"Привет! Я буду помогать тебе выживать в вышке!\nИз какого ты кампуса?",
reply_markup=campus_keyboard()
)
self.set_state(user, "wait_for_campus")
return
group = message.text
data = ruz.find_person(user)
if data is None:
bot.send_message(
user.chat_id,
"В РУЗе какая-то поломка, попробуй еще раз позже."
)
return
for element in data:
if element['description'] == group:
user.hse_id = int(element['id'])
user.group = group
user.name = element['label']
break
if user.group is None:
bot.send_message(user.chat_id, "Ты ввел что-то неправильно, попробуй еще раз сначала. Из какого ты кампуса?", reply_markup=campus_keyboard())
self.set_state(user, "wait_for_campus")
return
mongo.users_collection.update_one({"chat_id": user.chat_id}, {"$set": {
"hse_id": user.hse_id,
"group": group,
"name": user.name
}})
bot.send_message(
user.chat_id,
"Я нашел тебя в базе РУЗ. Я буду подсказывать тебе расписание, а также уведомлять о предстоящих парах.",
)
success = fetch_schedule_for_user(user)
if success:
lessons = mongo.get_today_lessons(user)
if len(lessons) == 0:
bot.send_message(
user.chat_id,
"Сегодня у тебя нет пар, отдыхай",
reply_markup=main_keyboard()
)
else:
bot.send_message(
user.chat_id,
"Твои пары сегодня:\n" + ruz.schedule_builder(lessons),
reply_markup=main_keyboard()
)
self.set_state(user, "ready")
def handle_state_ready(self, message: Message, user: User):
if message.text == "Пары сегодня":
lessons = mongo.get_today_lessons(user)
if len(lessons) == 0:
text = "Сегодня у тебя нет пар, отдыхай."
else:
text = ruz.schedule_builder(lessons)
elif message.text == "Пары завтра":
lessons = mongo.get_tomorrow_lessons(user)
if len(lessons) == 0:
text = "Завтра у тебя нет пар, отдыхай."
else:
text = ruz.schedule_builder(lessons)
elif message.text == "Расписание на неделю":
lessons = mongo.get_week_lessons(user)
if len(lessons) == 0:
text = "На этой неделе у тебя нет пар, отдыхай."
else:
text = ruz.schedule_builder(lessons)
elif message.text == "Напоминания о парах":
bot.send_message(
user.chat_id,
"Я умею напоминать о каждой паре и о первой паре. Что хочешь настроить?",
reply_markup=notify_type()
)
self.set_state(user, "notify_type")
return
elif message.text == "Ежедневные уведомления":
bot.send_message(
user.chat_id,
"Я могу присылать тебе расписание на текущий день или на следующий. Как ты хочешь чтобы я тебя уведомлял?",
reply_markup=daily_notify_type()
)
self.set_state(user, "wait_for_daily_notify_type")
return
elif message.text == "Сброс настроек":
bot.send_message(user.chat_id, "Ты уверен что хочешь сбросить все настройки и больше не получать уведомления?", reply_markup=yes_no_keyboard())
self.set_state(user, "reset")
return
else:
text = "Я не понимаю такой команды, используй кнопки."
bot.send_message(
user.chat_id,
text,
reply_markup=main_keyboard()
)
def handle_state_notify_type(self, message: Message, user: User):
text = message.text
if text == "О каждой паре":
bot.send_message(
user.chat_id,
"Выбери за сколько минут мне нужно напомнить тебе о предстоящей паре",
reply_markup=notify_keyboard()
)
self.set_state(user, "wait_for_notify")
elif text == "О первой паре":
bot.send_message(
user.chat_id,
"Выбери за сколько минут мне нужно напоминать тебе о первой паре",
reply_markup=first_lesson_notify()
)
self.set_state(user, "wait_for_first_notify")
elif text == "Назад":
self.set_state(user, "ready")
bot.send_message(
user.chat_id,
text,
reply_markup=main_keyboard()
)
else:
bot.send_message(user.chat_id, "Используй кнопки!", reply_markup=notify_type())
def handle_state_wait_for_first_notify(self, message: Message, user: User):
text = message.text
if text == "30 минут":
time_notify = 30
elif text == "1 час":
time_notify = 60
elif text == "4 часа":
time_notify = 4 * 60
elif text == "12 часов":
time_notify = 12 * 60
elif text == "Не уведомлять":
time_notify = None
else:
bot.send_message(user.chat_id, "Используй кнопки!", reply_markup=first_lesson_notify())
return
mongo.users_collection.update_one({"chat_id": user.chat_id}, {"$set": {"first_lesson_notify": time_notify}})
self.set_state(user, "ready")
bot.send_message(user.chat_id, "Запомнил!", reply_markup=main_keyboard())
def handle_state_wait_for_daily_notify_type(self, message: Message, user: User):
text = message.text
if text == "Текущий день":
bot.send_message(
user.chat_id,
"Каждый день (кроме воскресенья) я буду присылать тебе расписание на текущий день. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 09:30",
reply_markup=no_daily_notify()
)
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"daily_notify_today": True, "state": "wait_for_daily_notify"}}
)
elif text == "Следующий день":
bot.send_message(
user.chat_id,
"Каждый день (кроме субботы) я буду присылать тебе расписание на следующий день. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 20:30",
reply_markup=no_daily_notify()
)
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"daily_notify_today": False, "state": "wait_for_daily_notify"}}
)
elif text == "Не уведомлять":
bot.send_message(
user.chat_id,
"Принято! Я не буду уведомлять тебя.",
reply_markup=main_keyboard()
)
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"next_daily_notify_time": None, "daily_notify_time": None, "state": "ready"}}
)
elif text == "Назад":
bot.send_message(
user.chat_id,
"Возвращаюсь!",
reply_markup=main_keyboard()
)
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"next_daily_notify_time": None, "daily_notify_time": None, "state": "ready"}}
)
else:
bot.send_message(
user.chat_id,
"Ты прислал мне что-то неправильное, используй кнопки. Как ты хочешь чтобы я тебя уведомлял?",
reply_markup=daily_notify_type()
)
def handle_state_wait_for_notify(self, message: Message, user: User):
text = message.text
if text == "Не уведомлять":
user.notify_minutes = None
elif text == "5 минут":
user.notify_minutes = 5
elif text == "10 минут":
user.notify_minutes = 10
elif text == "15 минут":
user.notify_minutes = 15
elif text == "20 минут":
user.notify_minutes = 20
else:
bot.send_message(
user.chat_id,
"Я не понимаю такой команды, используй кнопки.",
reply_markup=notify_keyboard()
)
return
mongo.users_collection.update_one({"chat_id": user.chat_id}, {"$set": {"notify_minutes": user.notify_minutes}})
if user.notify_minutes is not None:
text = f"Принято! Буду уведомлять тебя за {text}."
else:
text = f"Принято! Я не буду уведомлять тебя."
bot.send_message(user.chat_id, text, reply_markup=main_keyboard())
self.set_state(user, "ready")
def _validate_time(self, line: str) -> bool:
if len(line) != 5:
return False
if line.count(":") != 1:
return False
hours, minutes = line.split(":")
try:
hours = int(hours)
minutes = int(minutes)
except ValueError:
return False
if hours < 0 or hours > 23 or minutes < 0 or minutes > 59:
return False
return True
def handle_state_wait_for_daily_notify(self, message: Message, user: User):
text = message.text
if text == "Не уведомлять":
bot.send_message(
user.chat_id,
"Принято! Я не буду присылать тебе ежедневные уведомления.",
reply_markup=main_keyboard()
)
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {"daily_notify_time": None, "next_daily_notify_time": None, "state": "ready"}}
)
return
if not self._validate_time(text):
bot.send_message(
user.chat_id,
"Ты прислал мне что-то неправильное. Пришли мне в формате чч:мм время, в которое ты хочешь получать расписание. Например, 09:30",
reply_markup=no_daily_notify()
)
return
user.daily_notify_time = text
next_time = get_next_daily_notify_time(user)
bot.send_message(
user.chat_id,
f"Принято! Буду уведомлять тебя каждый день в {text}.",
reply_markup=main_keyboard()
)
mongo.users_collection.update_one(
{"chat_id": user.chat_id},
{"$set": {
"daily_notify_time": text,
"next_daily_notify_time": next_time,
"state": "ready"
}}
)
def handle_state_reset(self, message: Message, user: User):
if message.text == "Да":
mongo.users_collection.delete_one({"chat_id": user.chat_id})
bot.send_message(user.chat_id, "Настройки сброшены, ждем твоего возвращения", reply_markup=again_keyboard())
elif message.text == "Нет":
bot.send_message(user.chat_id, "Возращаюсь к прежнему режиму", reply_markup=main_keyboard())
self.set_state(user, "ready")
else:
bot.send_message(user.chat_id,
"Я не понимаю, используй кнопки",
reply_markup=yes_no_keyboard())
answer = Answer()