232 lines
8.6 KiB
Python
232 lines
8.6 KiB
Python
import json
|
||
import random
|
||
import telebot
|
||
import datetime
|
||
from zoneinfo import ZoneInfo
|
||
from telebot.types import ReplyKeyboardMarkup, InlineQueryResultArticle, InputTextMessageContent, Message, ReplyKeyboardRemove, WebAppInfo, KeyboardButton
|
||
import config
|
||
from telebot import apihelper
|
||
|
||
apihelper.proxy = {
|
||
'http': config.TELEGRAM_PROXY,
|
||
'https': config.TELEGRAM_PROXY
|
||
}
|
||
|
||
bot = telebot.TeleBot(config.TOKEN, parse_mode='html')
|
||
|
||
from . import logger, user
|
||
|
||
def send(target: Message | int | str, text: str, reply_markup = None, disable_web_page_preview: bool = True, **kwargs) -> Message: # type: ignore
|
||
try:
|
||
_ = target.from_user.id # type: ignore
|
||
try: return bot.reply_to(target, text, reply_markup = reply_markup, disable_web_page_preview = True, **kwargs) # type: ignore
|
||
except Exception as e: logger.error('Bot', f'{e}')
|
||
except:
|
||
try: return bot.send_message(target, text, reply_markup = reply_markup, disable_web_page_preview = True, **kwargs) # type: ignore
|
||
except Exception as e: logger.error('Bot', f'{e}')
|
||
|
||
class Inlines:
|
||
def __init__(self, id: str, cache: int = 60) -> None:
|
||
self.list = []
|
||
self.cache = cache
|
||
self.id = id
|
||
|
||
def add(self, title: str, description: str, output: str) -> None:
|
||
self.list.append(
|
||
InlineQueryResultArticle(
|
||
id = str(random.randint(999,99999)),
|
||
title = title,
|
||
input_message_content = InputTextMessageContent(
|
||
message_text = output,
|
||
parse_mode = 'html',
|
||
disable_web_page_preview = True
|
||
),
|
||
description = description
|
||
)
|
||
)
|
||
|
||
def send(self) -> bool:
|
||
return bot.answer_inline_query(
|
||
self.id,
|
||
self.list,
|
||
self.cache,
|
||
is_personal = True
|
||
)
|
||
|
||
|
||
class Strings:
|
||
back_to_home = 'На главную 🏠'
|
||
back_to_search = 'К поиску 🔎'
|
||
|
||
# home
|
||
map = 'Карта 🗺️'
|
||
schedule = 'Расписание 📅'
|
||
schedule_emoji = '📅'
|
||
schedule_another_days = 'Другие дни 📁'
|
||
search = 'Поиск 🔎'
|
||
settings = '⚙️'
|
||
support = 'Поддержка 💞'
|
||
notifications = 'Уведомления ⏰'
|
||
current_schedule_name_F = '{} 🔄'
|
||
groups = 'Группы'
|
||
rooms = 'Аудитории'
|
||
teachers = 'Преподаватели'
|
||
add_schedule = 'Добавить расписание 🔆'
|
||
delete_active_schedule_F = 'Удалить "{}" 🗑'
|
||
delete_other_schedules_F = 'Удалить все кроме "{}" 🗑'
|
||
|
||
# register
|
||
register_not_found_T = 'Моего {} нету ⚠'
|
||
|
||
# schedule
|
||
today = 'Сегодня 🔥'
|
||
tomorrow = 'Завтра 🍀'
|
||
weekdays: list[str] = ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ']
|
||
even = 'Четная 📅'
|
||
odd = 'Нечетная 📅'
|
||
delete = 'Удалить 🗑'
|
||
save = 'Сохранить 🔆'
|
||
|
||
@staticmethod
|
||
def format(string: str, *args, **kwargs) -> str: return string.format(*args, **kwargs)
|
||
|
||
class Markup_v2:
|
||
@staticmethod
|
||
def remove() -> ReplyKeyboardRemove:
|
||
return ReplyKeyboardRemove()
|
||
|
||
@staticmethod
|
||
def default(user: user.User) -> ReplyKeyboardMarkup:
|
||
markup = ReplyKeyboardMarkup(resize_keyboard=True)
|
||
markup.add(
|
||
KeyboardButton(
|
||
text=Strings.map,
|
||
web_app=WebAppInfo(f'{config.WEB_BASE_URL.rstrip("/")}/map/?v=14&mode=search')
|
||
),
|
||
Strings.schedule,
|
||
row_width=2
|
||
)
|
||
markup.add(Strings.search, Strings.current_schedule_name_F.format(user.group), row_width=2)
|
||
markup.add(Strings.settings, Strings.support, row_width=2)
|
||
return markup
|
||
|
||
@staticmethod
|
||
def schedule(is_added: bool, from_search: bool = False) -> ReplyKeyboardMarkup:
|
||
odd_even = datetime.datetime.now(ZoneInfo('Europe/Moscow')).isocalendar().week % 2 == 0
|
||
markup = ReplyKeyboardMarkup(resize_keyboard=True)
|
||
markup.add(Strings.back_to_home, row_width=1) if not from_search else markup.add(Strings.back_to_search,Strings.back_to_home, row_width=2)
|
||
markup.add(Strings.today, Strings.tomorrow, row_width=2)
|
||
markup.add(*Strings.weekdays, row_width=5)
|
||
markup.add(
|
||
f'{"" if odd_even else "→ "}{Strings.odd}',
|
||
f'{"→ " if odd_even else ""}{Strings.even}',
|
||
row_width=2,
|
||
)
|
||
markup.add(Strings.delete if is_added else Strings.save, row_width=1)
|
||
return markup
|
||
|
||
|
||
class Markup_v1:
|
||
@staticmethod
|
||
def remove() -> ReplyKeyboardRemove:
|
||
return ReplyKeyboardRemove()
|
||
|
||
|
||
@staticmethod
|
||
def default(user: user.User) -> ReplyKeyboardMarkup:
|
||
markup = ReplyKeyboardMarkup(resize_keyboard=True)
|
||
markup.add(
|
||
KeyboardButton(
|
||
text=Strings.map,
|
||
web_app=WebAppInfo(f'{config.WEB_BASE_URL.rstrip("/")}/map/?v=14&mode=search')
|
||
),
|
||
Strings.search,
|
||
row_width=2
|
||
)
|
||
markup.add(Strings.today, Strings.tomorrow, row_width=2)
|
||
markup.add(Strings.schedule_another_days, Strings.current_schedule_name_F.format(user.group), row_width=2)
|
||
markup.add(Strings.notifications, Strings.support, row_width=2)
|
||
return markup
|
||
|
||
@staticmethod
|
||
def search_types() -> ReplyKeyboardMarkup:
|
||
markup = ReplyKeyboardMarkup(resize_keyboard=True)
|
||
markup.add(Strings.back_to_home, row_width=1)
|
||
markup.add(Strings.groups, row_width=1)
|
||
markup.add(Strings.rooms, row_width=1)
|
||
markup.add(Strings.teachers, row_width=1)
|
||
return markup
|
||
|
||
@staticmethod
|
||
def search_results(results: list[str]) -> ReplyKeyboardMarkup:
|
||
markup = ReplyKeyboardMarkup(resize_keyboard=True)
|
||
markup.add(Strings.back_to_home, row_width=1)
|
||
for result in results[:10]:
|
||
markup.add(result, row_width=1)
|
||
return markup
|
||
|
||
@staticmethod
|
||
def schedule(
|
||
is_saved: bool, from_search: bool = False, include_today: bool = False
|
||
) -> ReplyKeyboardMarkup:
|
||
even_week = datetime.datetime.now(ZoneInfo('Europe/Moscow')).isocalendar().week % 2 == 0
|
||
markup = ReplyKeyboardMarkup(resize_keyboard=True)
|
||
markup.add(Strings.back_to_search if from_search else Strings.back_to_home, row_width=1)
|
||
if from_search:
|
||
markup.add(Strings.delete if is_saved else Strings.save, row_width=1)
|
||
if from_search or include_today:
|
||
markup.add(Strings.today, Strings.tomorrow, row_width=2)
|
||
markup.add(*Strings.weekdays, row_width=5)
|
||
markup.add(
|
||
f'{"" if even_week else "→ "}{Strings.odd}',
|
||
f'{"→ " if even_week else ""}{Strings.even}',
|
||
row_width=2,
|
||
)
|
||
if not from_search:
|
||
markup.add(Strings.delete if is_saved else Strings.save, row_width=1)
|
||
return markup
|
||
|
||
@staticmethod
|
||
def notifications() -> ReplyKeyboardMarkup:
|
||
markup = ReplyKeyboardMarkup(resize_keyboard=True)
|
||
markup.add(Strings.back_to_home, row_width=1)
|
||
markup.add('Перед парой ⌛', row_width=1)
|
||
markup.add('Вечером 🌆', row_width=1)
|
||
markup.add('Файлом на неделю 📅', row_width=1)
|
||
|
||
return markup
|
||
|
||
@staticmethod
|
||
def saved_schedules(u: user.User) -> ReplyKeyboardMarkup:
|
||
markup = ReplyKeyboardMarkup(resize_keyboard=True)
|
||
markup.add(Strings.back_to_home, row_width=1)
|
||
markup.add(*(target['name'] for target in u.saved_schedules), row_width=4)
|
||
markup.add(Strings.add_schedule, row_width=1)
|
||
if u.active_target:
|
||
markup.add(Strings.delete_active_schedule_F.format(u.group), row_width=1)
|
||
markup.add(Strings.delete_other_schedules_F.format(u.group), row_width=1)
|
||
return markup
|
||
|
||
saved_groups = saved_schedules
|
||
|
||
@staticmethod
|
||
def selectGroup(groups: list[str]) -> ReplyKeyboardMarkup:
|
||
markup = ReplyKeyboardMarkup(resize_keyboard=True)
|
||
for group in groups:
|
||
markup.add(group, row_width=1)
|
||
markup.add('Моей группы нету ⚠', row_width=1)
|
||
return markup
|
||
|
||
|
||
Markup = Markup_v1
|
||
|
||
def Receive(state: str, text: str | None = None, strict: bool = True):
|
||
return bot.message_handler(
|
||
content_types = ['text'],
|
||
func = lambda m: user.validate(m).state == state and (
|
||
(m.text in text if not strict else m.text == text) if text != None else True
|
||
)
|
||
)
|
||
|
||
def Default(text: str, strict: bool = True):
|
||
return Receive('default', text, strict)
|