diff --git a/Course_1/Telegram_Bot/Buttons/Add_Maintenance/source.py b/Course_1/Telegram_Bot/Buttons/Add_Maintenance/source.py new file mode 100644 index 0000000..e5179ec --- /dev/null +++ b/Course_1/Telegram_Bot/Buttons/Add_Maintenance/source.py @@ -0,0 +1,113 @@ +from ..__modules__ import * + + +async def add_homework_state(call: types.CallbackQuery): + start_date = datetime.now() + await SelfState.Add_state.set() + await bot.edit_message_text( + chat_id=call.message.chat.id, + message_id=call.message.message_id, + text=f"*Выберите предмет*", + parse_mode="markdown", + reply_markup=create_subjects_keyboard(get_group_schedule(get_user_group(call.message), start=start_date)) + ) + + +async def add_homework(message: types.Message, state: FSMContext): + try: + async with state.proxy() as data: + date = data['date'] + subject = data['subject'] + data['state'] = False + except KeyError: + await message.answer(text='Ну ладно 🥺', parse_mode='markdown') + await state.finish() + return Ellipsis + + if HDB.is_exists(subject_name=subject, date=date, group=get_user_group(message)): + await message.reply(text='*Мы уже записывали задание на этот день и на этот предмет :)*', parse_mode='markdown') + await state.finish() + return Ellipsis + + text = message.text + Debugger.info(message.from_user.username, 'добавил', text if text is not None else message.caption) + user_group = get_user_group(message) + exercise = text + if message.document is not None and message.document.file_id is not None: + await SelfState.Parse_state.set() + HDB.attach_file(date=date, filename=message.document.file_id, group=user_group) + exercise = message.caption if message.caption is not None else exercise + elif message.photo and message.photo[0] is not None: + await SelfState.Parse_state.set() + HDB.attach_file(date=date, filename=message.photo[0].file_id, group=user_group) + exercise = message.caption if message.caption is not None else exercise + else: + await state.finish() + if exercise is not None: + await message.answer( + text='*{}*'.format( + HDB.add_homework( + subject_name=subject, + date=date, + text=exercise, + username=message.from_user.username, + group=user_group)), parse_mode='markdown') + try: + await bot.delete_message(message.chat.id, message_id=message.message_id - 1) + except MessageToDeleteNotFound: + Debugger.error('Какое-то сообщение не удаляется(') + + +async def parse_attachments(message: types.Message, state: FSMContext): + async with state.proxy() as data: + date = data['date'] + HDB.attach_file(date=date, filename=message.document.file_id, group=get_user_group(message)) + + +async def adding_add_homework_subject(query: types.CallbackQuery, state: FSMContext): + try: + async with state.proxy() as data: + data['subject'] = query.conf + date_count = data['date_count'] + data["state"] = True + + schedule = get_group_schedule(group=get_user_group(query.message), start=week_definition(date_count, debug=True)) + transliterated_schedule = list(map( + lambda x: translit(x, language_code='ru', reversed=True), schedule)) + subject = None + for pos, let in enumerate(transliterated_schedule): + if query.data in let: + subject = schedule[pos] + if subject is None: + async with state.proxy() as data: + subject = data['subject'] + + async with state.proxy() as data: + data['subject'] = subject + start_date, end_date = week_definition(date_count) + await bot.edit_message_text( + chat_id=query.message.chat.id, + message_id=query.message.message_id, + text=f'*На какой день задание?\n📅 {start_date} - {end_date} 📅*', + reply_markup=Inline_Date_ADD, + parse_mode='markdown') + except KeyError as e: + Debugger.error(e) + + +async def add_homework_date(query: types.CallbackQuery, state: FSMContext): + async with state.proxy() as data: + current_state = data['state'] + date_count = data['date_count'] + if current_state: + day = query.data.split("_")[2] + start_date = week_definition(date_count, debug=True) + await bot.edit_message_text( + text='*Введите домашнее задание*', + chat_id=query.message.chat.id, + message_id=query.message.message_id, + parse_mode='markdown' + ) + async with state.proxy() as data: + data['date'] = (start_date + timedelta(days=days[day])).strftime('%d.%m.%Y') + await SelfState.Add_state.set() diff --git a/Course_1/Telegram_Bot/Buttons/Delete_Maintenance/source.py b/Course_1/Telegram_Bot/Buttons/Delete_Maintenance/source.py new file mode 100644 index 0000000..2fc5cb0 --- /dev/null +++ b/Course_1/Telegram_Bot/Buttons/Delete_Maintenance/source.py @@ -0,0 +1,66 @@ +from Buttons.__modules__ import * + + +async def delete_homework_date(query: types.CallbackQuery, state: FSMContext): + day = query.data.split("_")[2] + async with state.proxy() as data: + date_count = data['date_count'] + start_date = week_definition(date_count, debug=True) + data['date'] = (start_date + timedelta(days=days[day])).strftime('%d.%m.%Y') + date = data["date"] + start_date, end_date = week_definition(date_count, debug=True), week_definition(date_count)[1] + start_date = start_date.strftime('%d.%m.%Y') + homework = HDB.is_available_homework_by_date(date=date, group=get_user_group(query.message), data=True) + homework = list(map(lambda x: x[0], homework)) + await bot.edit_message_text( + text='*Выберите предмет*' if homework else '*Тут ничего нет :(\nДавай выберем другой день лучше?*', + chat_id=query.message.chat.id, + message_id=query.message.message_id, + parse_mode='markdown', + reply_markup=create_subjects_keyboard(homework) if homework else None + ) + await asyncio.sleep(0.5) + if not homework: + await bot.send_message( + chat_id=query.message.chat.id, + text=f"*На какой день задание?\n📅 {start_date} - {end_date} 📅*", + reply_markup=Inline_Date_ADD, + parse_mode="markdown" + ) + + +async def delete_homework(query: types.CallbackQuery, state: FSMContext): + message = query.message + async with state.proxy() as data: + date = data['date'] + date_count = data['date_count'] + schedule = get_group_schedule(group=get_user_group(query.message), start=week_definition(date_count, debug=True)) + transliterated_schedule = list(map( + lambda x: translit(x, language_code='ru', reversed=True), schedule)) + subject = None + for pos, let in enumerate(transliterated_schedule): + if query.data in let: + subject = schedule[pos] + break + group = get_user_group(message) + Debugger.info(message.from_user.username, 'удалил', ' '.join([subject, date, group])) + HDB.delete_homework(subject_name=subject, date=date, group=group) + await bot.delete_message(chat_id=message.chat.id, message_id=message.message_id) + await message.answer( + text=f'*Запись успешно удалена!*', parse_mode='markdown') + await state.finish() + + +async def delete_homework_state(query: types.CallbackQuery, state: FSMContext): + async with state.proxy() as data: + data['state'] = True + date_count = data['date_count'] + start_date, end_date = week_definition(date_count) + await bot.edit_message_text( + chat_id=query.message.chat.id, + message_id=query.message.message_id, + text=f"*На какой день задание?\n📅 {start_date} - {end_date} 📅*", + reply_markup=Inline_Date_ADD, + parse_mode="markdown" + ) + await SelfState.Delete_state.set() diff --git a/Course_1/Telegram_Bot/Buttons/Edit_Maintenance/source.py b/Course_1/Telegram_Bot/Buttons/Edit_Maintenance/source.py new file mode 100644 index 0000000..c4a641c --- /dev/null +++ b/Course_1/Telegram_Bot/Buttons/Edit_Maintenance/source.py @@ -0,0 +1,91 @@ +from Buttons.__modules__ import * + + +async def editor_homework_date(query: types.CallbackQuery, state: FSMContext): + async with state.proxy() as data: + current_state = data['state'] + date_count = data['date_count'] + if current_state: + day = query.data.split("_")[2] + + start_date, end_date = week_definition(date_count, debug=True), week_definition(date_count)[1] + async with state.proxy() as data: + data['date'] = (start_date + timedelta(days=days[day])).strftime('%d.%m.%Y') + date = data["date"] + start_date = start_date.strftime('%d.%m.%Y') + homework = HDB.is_available_homework_by_date(date=date, group=get_user_group(query.message), data=True) + homework = list(map(lambda x: x[0], homework)) + await bot.edit_message_text( + text='*Выберите предмет*' if homework else '*Тут ничего нет :(\nДавай выберем другой день лучше?*', + chat_id=query.message.chat.id, + message_id=query.message.message_id, + parse_mode='markdown', + reply_markup=create_subjects_keyboard(homework) if homework else None + ) + await asyncio.sleep(0.5) + if not homework: + await bot.send_message( + chat_id=query.message.chat.id, + text=f"*На какой день задание?\n📅 {start_date} - {end_date} 📅*", + reply_markup=Inline_Date_ADD, + parse_mode="markdown" + ) + + +async def edit_homework(message: types.Message, state: FSMContext): + text = message.text + async with state.proxy() as data: + date = data['date'] + subject = data['subject'] + Debugger.info(message.from_user.username, 'отредактировал', text) + HDB.delete_homework(subject_name=subject, date=date, group=get_user_group(message)) + text = HDB.add_homework( + subject_name=subject, + username=message.from_user.username, + text=text, date=date, + group=get_user_group(message), + edit=True) + await message.answer( + text=f'*{text}*', parse_mode='markdown') + await state.finish() + + +async def edit_init(call: types.CallbackQuery, state: FSMContext): + async with state.proxy() as data: + data['state'] = True + date_count = data['date_count'] + start_date, end_date = week_definition(date_count) + await bot.edit_message_text( + chat_id=call.message.chat.id, + message_id=call.message.message_id, + text=f"*На какой день задание?\n📅 {start_date} - {end_date} 📅*", + reply_markup=Inline_Date_ADD, + parse_mode="markdown" + ) + await SelfState.Edit_state.set() + + +async def editor_add_homework_subject(query: types.CallbackQuery, state: FSMContext): + try: + async with state.proxy() as data: + data['subject'] = query.conf + date_count = data['date_count'] + data["state"] = True + + schedule = get_group_schedule(group=get_user_group(query.message), start=week_definition(date_count, debug=True)) + transliterated_schedule = list(map( + lambda x: translit(x, language_code='ru', reversed=True), schedule)) + subject = None + for pos, let in enumerate(transliterated_schedule): + if query.data in let: + subject = schedule[pos] + break + async with state.proxy() as data: + data['subject'] = subject + await bot.edit_message_text( + chat_id=query.message.chat.id, + message_id=query.message.message_id, + text=f'*Введите новое задание*', + parse_mode='markdown') + except KeyError as e: + Debugger.error(e) diff --git a/Course_1/Telegram_Bot/Utils/Buttons.py b/Course_1/Telegram_Bot/Buttons/Exactly_Buttons/Buttons.py similarity index 85% rename from Course_1/Telegram_Bot/Utils/Buttons.py rename to Course_1/Telegram_Bot/Buttons/Exactly_Buttons/Buttons.py index c95a7ea..0bda7c3 100644 --- a/Course_1/Telegram_Bot/Utils/Buttons.py +++ b/Course_1/Telegram_Bot/Buttons/Exactly_Buttons/Buttons.py @@ -2,17 +2,23 @@ from transliterate import translit +def __compose_str(string): + if len(string) <= 10: + return string + return string[len(string) // 2:] + + def create_subjects_keyboard(schedule: list or set): buttons_list = [] for item in schedule: item: str buttons_list.append([InlineKeyboardButton(text=item, callback_data=translit( - item[len(item) // 2:], language_code='ru', reversed=True))]) + __compose_str(item), language_code='ru', reversed=True))]) keyboard_inline_buttons = InlineKeyboardMarkup(inline_keyboard=buttons_list) return keyboard_inline_buttons -answer_start = ReplyKeyboardMarkup(resize_keyboard=True).add("Получить задание!").add('Управление заданиями') +answer_start = ReplyKeyboardMarkup(resize_keyboard=True).add("Получить задание!").add('Управление заданиями').add('Полезные материалы') Inline_Date = InlineKeyboardMarkup(inline_keyboard=True, row_width=3) Inline_Date_Week = InlineKeyboardButton(text='Вся неделя 🥶', callback_data='Inline_Date_Week') Inline_Date_Bm = InlineKeyboardButton(text='Понедельник 💀', callback_data='Inline_Date_Bm') @@ -28,12 +34,15 @@ def create_subjects_keyboard(schedule: list or set): Inline_Edit = InlineKeyboardButton(text='Редактировать ДЗ', callback_data='Inline_Edit') Inline_Add = InlineKeyboardButton(text='Добавить ДЗ', callback_data='Inline_Add') Inline_Delete = InlineKeyboardButton(text='Удалить ДЗ', callback_data='Inline_Delete') -Inline_Manage.add(Inline_Add).add(Inline_Edit).add(Inline_Delete) +Inline_Materials = InlineKeyboardButton(text='Добавить материалы', callback_data='Inline_Materials') +Inline_Manage.add(Inline_Add).add(Inline_Edit).add(Inline_Delete).add(Inline_Materials) Inline_Date_ADD = InlineKeyboardMarkup() + Inline_Date_ADD.add(Inline_Date_Up).add(Inline_Date_Bm).add(Inline_Date_Bt).add(Inline_Date_Bwd)\ .add(Inline_Date_Bth).add(Inline_Date_Bf)\ .add(Inline_Date_Sn).add(Inline_Date_Down) + Inline_Date.add(Inline_Date_Up).add(Inline_Date_Week).add(Inline_Date_Bm).add(Inline_Date_Bt).add(Inline_Date_Bwd)\ .add(Inline_Date_Bth).add(Inline_Date_Bf)\ .add(Inline_Date_Sn).add(Inline_Date_Down) diff --git a/Course_1/Telegram_Bot/Buttons/Maintenance.py b/Course_1/Telegram_Bot/Buttons/Maintenance.py new file mode 100644 index 0000000..c20e849 --- /dev/null +++ b/Course_1/Telegram_Bot/Buttons/Maintenance.py @@ -0,0 +1,64 @@ +from Buttons.Add_Maintenance.source import * +from Buttons.Delete_Maintenance.source import * +from Buttons.Edit_Maintenance.source import * +from Buttons.Reply_Maintenance.source import * + + +async def callback_down(call: types.CallbackQuery, state: FSMContext): + try: + async with state.proxy() as data: + data['date_count'] += 1 + date_count = data['date_count'] + button_state = data["state"] + await bot.edit_message_text( + chat_id=call.message.chat.id, + message_id=call.message.message_id, + text=f"*{'Выбираем день недели' if not button_state else 'На какой день задание?'}\n📅 {week_definition(date_count)[0]} - {week_definition(date_count)[1]} 📅*", + parse_mode="markdown", + reply_markup=Inline_Date_ADD if button_state else Inline_Date) + + except KeyError: + pass + + +async def callback_up(call: types.CallbackQuery, state: FSMContext): + try: + async with state.proxy() as data: + data['date_count'] -= 1 + date_count = data['date_count'] + button_state = data["state"] + await bot.edit_message_text( + chat_id=call.message.chat.id, + message_id=call.message.message_id, + text=f"*{'Выбираем день недели' if not button_state else 'На какой день задание?'}\n📅 {week_definition(date_count)[0]} - {week_definition(date_count)[1]} 📅*", + parse_mode="markdown", + reply_markup=Inline_Date_ADD if button_state else Inline_Date) + except KeyError: + pass + + +async def process_rule_command(message: types.Message, state: FSMContext): + await state.finish() + async with state.proxy() as data: + data['date_count'] = 0 + Debugger.info(message.from_user.username, 'управляет заданиями') + if message.from_user.username in green_list(): + await message.answer( + text='*Что будем делать?*', + parse_mode='markdown', + reply_markup=Inline_Manage + ) + + else: + await message.answer( + text='*Вы не можете управлять заданиями, для получения возможности → @Nps_rf или @monotank*', + parse_mode='markdown') + + +async def group_state_command(message: types.Message, state: FSMContext): + await state.finish() + await message.answer("Нажми на кнопку, чтобы получить домашнее задание.", reply_markup=answer_start) + chat_id = message.chat.id + user_group = message.text.upper() + HDB.add_user(chat_id=chat_id, user_group=user_group, username=message.from_user.username) + diff --git a/Course_1/Telegram_Bot/Buttons/Reply_Maintenance/source.py b/Course_1/Telegram_Bot/Buttons/Reply_Maintenance/source.py new file mode 100644 index 0000000..e1af9e8 --- /dev/null +++ b/Course_1/Telegram_Bot/Buttons/Reply_Maintenance/source.py @@ -0,0 +1,118 @@ +# noinspection INSPECTION_NAME + +from Buttons.__modules__ import * + + +async def all_week_homework(call: types.CallbackQuery, state: FSMContext): + try: + async with state.proxy() as data: + date_count = data['date_count'] + start_date = week_definition(date_count, debug=True) + for day in range(6): + current_day = (start_date + timedelta(days=day)).strftime('%d.%m.%Y') + available_homework = HDB.is_available_homework_by_date( + date=current_day, + group=get_user_group(call.message), + data=True) + __text = '' + + for num, subject in enumerate(available_homework): + __text += \ + f'{str(num + 1)}) ' + subject[0] + ': ' + subject[1] + '\n' + if not __text: + __text = '*Никто не заполнил домашнее задания на этот день* 😭' + else: + __text = '`' + __text + '`' + message = f'*📅 {days_of_week[day + 1]} {current_day}*\n{__text}' + await call.message.answer( + text=message, + parse_mode='markdown') + if HDB.is_file_attached(group=get_user_group(call.message), date=current_day): + attachments = HDB.get_attachments(group=get_user_group(call.message), date=current_day) + for pos, document in enumerate(attachments): + await bot.send_document( + chat_id=call.message.chat.id, + document=document[0], + caption=None, + parse_mode='markdown') + try: + await bot.delete_message(chat_id=call.message.chat.id, message_id=call.message.message_id) + except MessageToDeleteNotFound: + Debugger.error('Какое-то сообщение не удаляется(') + except KeyError: + await process_start_command(call.message) + + +async def homework_reply(query: types.CallbackQuery, state: FSMContext): + day = query.data.split("_")[2] + try: + async with state.proxy() as data: + date_count = data['date_count'] + start_date = week_definition(date_count, debug=True) + date_to_db = [ + (start_date + timedelta(days=days[day])).strftime('%d.%m.%y'), + (start_date + timedelta(days=days[day])).strftime('%d.%m.%Y')] + + if HDB.is_available_homework_by_date( + date=date_to_db[0], + group=get_user_group(query.message)) or HDB.is_available_homework_by_date( + date=date_to_db[1], + group=get_user_group(query.message)): + + date_to_db = date_to_db[0] if HDB.is_available_homework_by_date( + date=date_to_db[0], + group=get_user_group(query.message)) else date_to_db[1] + + available_homework = HDB.is_available_homework_by_date( + date=date_to_db, + data=True, + group=get_user_group(query.message)) + __text = str() + for num, subject in enumerate(available_homework): + __text += f'{str(num + 1)}) ' + subject[0] + ': ' + subject[1] + '\n' + text = f'*📅 {days_of_week[days[day] + 1]} {date_to_db}*\n`{__text}`' + await query.message.answer( + text=text, + parse_mode='markdown' + ) + if HDB.is_file_attached(date=date_to_db, group=get_user_group(query.message)): + attachments = HDB.get_attachments(group=get_user_group(query.message), date=date_to_db) + for pos, document in enumerate(attachments): + await bot.send_document( + chat_id=query.message.chat.id, + document=document[0], + caption=None, + parse_mode='markdown') + try: + await bot.delete_message(chat_id=query.message.chat.id, message_id=query.message.message_id) + except MessageToDeleteNotFound: + Debugger.error('Какое-то сообщение не удаляется(') + else: + await query.message.answer( + text='*Никто не заполнил домашнее задания на этот день* 😭', parse_mode='markdown' + ) + + except KeyError: + await process_start_command(query.message) + + +async def processing_of_receiving_hw(message: types.Message, state: FSMContext): + Debugger.info(message.from_user.username, 'получает задание') + await state.finish() + async with state.proxy() as data: + data['date_count'] = 0 + data["state"] = False + await message.answer( + f"*Выбираем день недели\n📅 {week_definition(0)[0]} - {week_definition(0)[1]} 📅*", + parse_mode="markdown", reply_markup=Inline_Date) + + +async def process_get_materials(message: types.Message, state: FSMContext): + await state.finish() + attachments = HDB.get_attachments_materials(group=get_user_group(message)) + for pos, document in enumerate(attachments): + await bot.send_document( + chat_id=message.chat.id, + document=document[0], + caption=None, + parse_mode='markdown') \ No newline at end of file diff --git a/Course_1/Telegram_Bot/Buttons/__modules__.py b/Course_1/Telegram_Bot/Buttons/__modules__.py new file mode 100644 index 0000000..c1da367 --- /dev/null +++ b/Course_1/Telegram_Bot/Buttons/__modules__.py @@ -0,0 +1,14 @@ +import asyncio +from datetime import timedelta, datetime + +from aiogram import types +from aiogram.dispatcher import FSMContext +from aiogram.utils.exceptions import MessageToDeleteNotFound + +from Buttons.Exactly_Buttons.Buttons import * +from Utils.Miscellaneous import bot, HDB, get_user_group, days_of_week, days, SelfState, \ + get_group_schedule, green_list +from Utils.date import week_definition +from bot import process_start_command +from Utils.debug import Debugger + diff --git a/Course_1/Telegram_Bot/db.py b/Course_1/Telegram_Bot/Database.py similarity index 100% rename from Course_1/Telegram_Bot/db.py rename to Course_1/Telegram_Bot/Database.py diff --git a/Course_1/Telegram_Bot/Dockerfile b/Course_1/Telegram_Bot/Dockerfile index 3f712fe..a486174 100644 --- a/Course_1/Telegram_Bot/Dockerfile +++ b/Course_1/Telegram_Bot/Dockerfile @@ -5,6 +5,6 @@ WORKDIR /src/app/ COPY . /src/app/ -RUN pip install --no-cache-dir -r requirements.txt +RUN pip install --user --no-cache-dir -r requirements.txt -CMD ["python", "bot.py"] +CMD ["python", "bot.py", "-i", "-s"] diff --git a/Course_1/Telegram_Bot/README.md b/Course_1/Telegram_Bot/README.md index dcfa7eb..ae5bdf6 100644 --- a/Course_1/Telegram_Bot/README.md +++ b/Course_1/Telegram_Bot/README.md @@ -75,8 +75,8 @@ 1) ~~**Сделать удаление домашних заданий**~~ 1) **Сделать управление вложениями** 2) ~~**Написать админку**~~ -3) **Сделать сборник полезных материалов группы** - 1) **Например учебник по английскому языку который скидывали ещё в начале года** +3) ~~**Сделать сборник полезных материалов группы**~~ + 1) ~~**Например учебник по английскому языку который скидывали ещё в начале года**~~ diff --git a/Course_1/Telegram_Bot/Tests/tests.py b/Course_1/Telegram_Bot/Tests/tests.py index 2559f32..c120292 100644 --- a/Course_1/Telegram_Bot/Tests/tests.py +++ b/Course_1/Telegram_Bot/Tests/tests.py @@ -1,6 +1,6 @@ import unittest import os -from Course_1.Telegram_Bot.db import * +from Course_1.Telegram_Bot.Database import * class DatabaseTests(unittest.TestCase): diff --git a/Course_1/Telegram_Bot/Utils/Maintenance.py b/Course_1/Telegram_Bot/Utils/Miscellaneous.py similarity index 90% rename from Course_1/Telegram_Bot/Utils/Maintenance.py rename to Course_1/Telegram_Bot/Utils/Miscellaneous.py index 8c761b1..f8fe431 100644 --- a/Course_1/Telegram_Bot/Utils/Maintenance.py +++ b/Course_1/Telegram_Bot/Utils/Miscellaneous.py @@ -1,10 +1,15 @@ +import sys + from aiogram import Bot, Dispatcher, types from aiogram.contrib.fsm_storage.memory import MemoryStorage from aiogram.dispatcher.filters.state import StatesGroup, State from Utils.Schedule import * from config import TOKEN -from db import Database +from Database import Database + + +sys.path.append("..") class SelfState(StatesGroup): @@ -14,6 +19,7 @@ class SelfState(StatesGroup): Delete_state = State() Parse_state = State() Materials_state = State() + Materials_parse_state = State() storage = MemoryStorage() @@ -31,12 +37,12 @@ class SelfState(StatesGroup): } days = { - 'Bm' : 0, - 'Bt' : 1, - 'Bwd' : 2, - 'Bth' : 3, - 'Bf' : 4, - 'BSn' : 5 + 'Bm': 0, + 'Bt': 1, + 'Bwd': 2, + 'Bth': 3, + 'Bf': 4, + 'BSn': 5 } diff --git a/Course_1/Telegram_Bot/Utils/debug.py b/Course_1/Telegram_Bot/Utils/debug.py new file mode 100644 index 0000000..04087fd --- /dev/null +++ b/Course_1/Telegram_Bot/Utils/debug.py @@ -0,0 +1,21 @@ +class Debugger: + debug = True + + @classmethod + def info(cls, user, action, data=None) -> str or None: + """Вывод в консоль информации о действиях пользователя""" + if not cls.debug: + return ... + if data is None: + data = '' + else: + data = f'\n--> {data}' + out = f'{user} {action}{data}' + print(out) + + @classmethod + def error(cls, data) -> str or None: + if not cls.debug: + return ... + print(data) + diff --git a/Course_1/Telegram_Bot/bot.py b/Course_1/Telegram_Bot/bot.py index 093bcca..6ec5349 100644 --- a/Course_1/Telegram_Bot/bot.py +++ b/Course_1/Telegram_Bot/bot.py @@ -1,18 +1,11 @@ ############################################ -import datetime # -import transliterate as tr # -import aiogram.utils.exceptions # +from Utils.Miscellaneous import * +from registration import * ############################################ -from Utils.Maintenance import * # -from Buttons.Maintenance import * # -from Buttons import Buttons # -############################################ -from datetime import timedelta # -from datetime import datetime # -from aiogram import types # -from aiogram.utils import executor # -from Utils.date import week_definition # -from aiogram.dispatcher import FSMContext # +from Utils.debug import Debugger +from aiogram import types +from aiogram.utils import executor +from aiogram.dispatcher import FSMContext ############################################ @@ -22,19 +15,20 @@ async def process_start_command(message: types.Message): await SelfState.Group_state.set() -@dp.message_handler(state=SelfState.Parse_state, content_types=types.ContentType.DOCUMENT) +@dp.message_handler(state=SelfState.Materials_parse_state, content_types=types.ContentType.DOCUMENT) async def parse_attachments(message: types.Message, state: FSMContext): - async with state.proxy() as data: - date = data['date'] - HDB.attach_file(date=date, filename=message.document.file_id, group=get_user_group(message)) + HDB.attach_file_materials(file_id=message.document.file_id, file_name=message.document.file_name, group=get_user_group(message)) @dp.message_handler(content_types=types.ContentType.DOCUMENT, state=SelfState.Materials_state) async def process_add_material_command(message: types.Message, state: FSMContext): await state.finish() - await SelfState.Parse_state.set() + await SelfState.Materials_parse_state.set() if HDB.is_file_attached_materials(group=get_user_group(message), file_name=message.document.file_name): - HDB.attach_file_materials(file_id=message.document.file_id, group=get_user_group(message), file_name=message.document.file_name) + HDB.attach_file_materials( + file_id=message.document.file_id, + group=get_user_group(message), + file_name=message.document.file_name) await message.answer("материалы добавлены") else: await message.answer("этот файл уже добавлен!") @@ -47,7 +41,7 @@ async def process_answer_by_document(message: types.Message, state: FSMContext): @dp.callback_query_handler(text='Inline_Materials') -async def materials_state(call: types.CallbackQuery, _state: FSMContext): +async def materials_state(call: types.CallbackQuery, state: FSMContext): await bot.send_message( chat_id=call.message.chat.id, text="Прикрепите материалы", @@ -56,320 +50,19 @@ async def materials_state(call: types.CallbackQuery, _state: FSMContext): await SelfState.Materials_state.set() -@dp.message_handler(lambda message: message.text == 'Полезные материалы', state="*") -async def process_get_materials(message: types.Message, state: FSMContext): - await state.finish() - attachments = HDB.get_attachments_materials(group=get_user_group(message)) - for pos, document in enumerate(attachments): - await bot.send_document( - chat_id=message.chat.id, - document=document[0], - caption=None, - parse_mode='markdown') - - -@dp.callback_query_handler(lambda query: 'Inline' not in query.data, state=SelfState.Add_state) -async def add_homework_subject(query: types.CallbackQuery, state: FSMContext): - try: - async with state.proxy() as data: - data['subject'] = query.conf - date_count = data['date_count'] - data["state"] = True - - schedule = get_group_schedule(group=get_user_group(query.message), start=week_definition(date_count, debug=True)) - transliterated_schedule = list(map( - lambda x: tr.translit(x, language_code='ru', reversed=True), schedule)) - subject = None - for pos, let in enumerate(transliterated_schedule): - if query.data in let: - subject = schedule[pos] - if subject is None: - async with state.proxy() as data: - subject = data['subject'] - - async with state.proxy() as data: - data['subject'] = subject - start_date, end_date = week_definition(date_count) - await bot.edit_message_text( - chat_id=query.message.chat.id, - message_id=query.message.message_id, - text=f'*На какой день задание?\n📅 {start_date} - {end_date} 📅*', - reply_markup=Buttons.Inline_Date_ADD, - parse_mode='markdown') - except KeyError as e: - print(e) - - -@dp.message_handler(lambda message: message.text == 'Получить задание!', state="*") -async def process_date(message: types.Message, state: FSMContext): - print(message.from_user.username, 'получает задание') - await state.finish() - async with state.proxy() as data: - data['date_count'] = 0 - data["state"] = False - await message.answer( - f"*Выбираем день недели\n📅 {week_definition(0)[0]} - {week_definition(0)[1]} 📅*", - parse_mode="markdown", reply_markup=Buttons.Inline_Date) - - -@dp.callback_query_handler(lambda query: 'Inline' not in query.data, state=SelfState.Edit_state) -async def add_homework_subject(query: types.CallbackQuery, state: FSMContext): - try: - async with state.proxy() as data: - data['subject'] = query.conf - date_count = data['date_count'] - data["state"] = True - - schedule = get_group_schedule(group=get_user_group(query.message), start=week_definition(date_count, debug=True)) - transliterated_schedule = list(map( - lambda x: tr.translit(x, language_code='ru', reversed=True), schedule)) - subject = None - for pos, let in enumerate(transliterated_schedule): - if query.data in let: - subject = schedule[pos] - break - async with state.proxy() as data: - data['subject'] = subject - await bot.edit_message_text( - chat_id=query.message.chat.id, - message_id=query.message.message_id, - text=f'*Введите новое задание*', - parse_mode='markdown') - except KeyError as e: - print(e) - - -@dp.callback_query_handler(text='Inline_Delete') -async def delete_homework_state(query: types.CallbackQuery, state: FSMContext): - async with state.proxy() as data: - data['state'] = True - date_count = data['date_count'] - print(data['date_count']) - start_date, end_date = week_definition(date_count) - await bot.edit_message_text( - chat_id=query.message.chat.id, - message_id=query.message.message_id, - text=f"*На какой день задание?\n📅 {start_date} - {end_date} 📅*", - reply_markup=Buttons.Inline_Date_ADD, - parse_mode="markdown" - ) - await SelfState.Delete_state.set() - - -@dp.callback_query_handler(lambda query: 'Inline' not in query.data, state=SelfState.Delete_state) -async def delete_homework(query: types.CallbackQuery, state: FSMContext): - message = query.message - async with state.proxy() as data: - date = data['date'] - date_count = data['date_count'] - schedule = get_group_schedule(group=get_user_group(query.message), start=week_definition(date_count, debug=True)) - transliterated_schedule = list(map( - lambda x: tr.translit(x, language_code='ru', reversed=True), schedule)) - subject = None - for pos, let in enumerate(transliterated_schedule): - if query.data in let: - subject = schedule[pos] - break - group = get_user_group(message) - print(message.from_user.username, 'удалил:\n', subject, date, group) - HDB.delete_homework(subject_name=subject, date=date, group=group) - await bot.delete_message(chat_id=message.chat.id, message_id=message.message_id) - await message.answer( - text=f'*Запись успешно удалена!*', parse_mode='markdown') - await state.finish() - - -@dp.callback_query_handler(lambda query: query.data.split('_')[2][0] == 'B', state=SelfState.Delete_state) -async def delete_homework_date(query: types.CallbackQuery, state: FSMContext): - day = query.data.split("_")[2] - async with state.proxy() as data: - date_count = data['date_count'] - start_date = week_definition(date_count, debug=True) - data['date'] = (start_date + timedelta(days=days[day])).strftime('%d.%m.%Y') - date = data["date"] - start_date, end_date = week_definition(date_count, debug=True), week_definition(date_count)[1] - start_date = start_date.strftime('%d.%m.%Y') - homework = HDB.is_available_homework_by_date(date=date, group=get_user_group(query.message), data=True) - homework = list(map(lambda x: x[0], homework)) - await bot.edit_message_text( - text='*Выберите предмет*' if homework else '*Тут ничего нет :(\nДавай выберем другой день лучше?*', - chat_id=query.message.chat.id, - message_id=query.message.message_id, - parse_mode='markdown', - reply_markup=Buttons.create_subjects_keyboard(homework) if homework else None - ) - await asyncio.sleep(0.5) - if not homework: - await bot.send_message( - chat_id=query.message.chat.id, - text=f"*На какой день задание?\n📅 {start_date} - {end_date} 📅*", - reply_markup=Buttons.Inline_Date_ADD, - parse_mode="markdown" - ) - - -@dp.message_handler(state=SelfState.Group_state) -async def group_state_command(message: types.Message, state: FSMContext): - await state.finish() - await message.answer("Нажми на кнопку, чтобы получить домашнее задание.", reply_markup=Buttons.answer_start) - chat_id = message.chat.id - user_group = message.text.upper() - HDB.add_user(chat_id=chat_id, user_group=user_group, username=message.from_user.username) - - -@dp.message_handler(lambda message: message.text == 'Управление заданиями', state="*") -async def process_add_command(message: types.Message, state: FSMContext): - await state.finish() - async with state.proxy() as data: - data['date_count'] = 0 - print(message.from_user.username, 'управляет заданиями') - if message.from_user.username in green_list(): - await message.answer( - text='*Что будем делать?*', - parse_mode='markdown', - reply_markup=Buttons.Inline_Manage - ) - - else: - await message.answer( - text='*Вы не можете управлять заданиями, для получения возможности → @Nps_rf или @monotank*', - parse_mode='markdown') - - -@dp.callback_query_handler(text='Inline_Add') -async def add_homework_state(call: types.CallbackQuery): - start_date = datetime.now() - await SelfState.Add_state.set() - await bot.edit_message_text( - chat_id=call.message.chat.id, - message_id=call.message.message_id, - text=f"*Выберите предмет*", - parse_mode="markdown", - reply_markup=Buttons.create_subjects_keyboard(get_group_schedule(get_user_group(call.message), start=start_date)) - ) - - -@dp.message_handler(state=SelfState.Parse_state, content_types=types.ContentType.DOCUMENT) -async def parse_attachments(message: types.Message, state: FSMContext): - async with state.proxy() as data: - date = data['date'] - HDB.attach_file(date=date, filename=message.document.file_id, group=get_user_group(message)) - - -@dp.message_handler( - state=SelfState.Add_state, - content_types=[types.ContentType.TEXT, types.ContentType.DOCUMENT, types.ContentType.PHOTO] -) -async def add_homework(message: types.Message, state: FSMContext): - try: - async with state.proxy() as data: - date = data['date'] - subject = data['subject'] - data['state'] = False - except KeyError: - await message.answer(text='Ну ладно 🥺', parse_mode='markdown') - await state.finish() - return Ellipsis - - if HDB.is_exists(subject_name=subject, date=date, group=get_user_group(message)): - await message.reply(text='*Мы уже записывали задание на этот день и на это предмет :)*', parse_mode='markdown') - await state.finish() - return Ellipsis - - text = message.text - print(message.from_user.username, 'добавил:\n', text if text is not None else message.caption) - user_group = get_user_group(message) - exercise = text - if message.document is not None and message.document.file_id is not None: - await SelfState.Parse_state.set() - HDB.attach_file(date=date, filename=message.document.file_id, group=user_group) - exercise = message.caption if message.caption is not None else exercise - elif message.photo and message.photo[0] is not None: - await SelfState.Parse_state.set() - HDB.attach_file(date=date, filename=message.photo[0].file_id, group=user_group) - exercise = message.caption if message.caption is not None else exercise - else: - await state.finish() - if exercise is not None: - await message.answer( - text='*{}*'.format( - HDB.add_homework( - subject_name=subject, - date=date, - text=exercise, - username=message.from_user.username, - group=user_group)), parse_mode='markdown') - try: - await bot.delete_message(message.chat.id, message_id=message.message_id - 1) - except aiogram.utils.exceptions.MessageToDeleteNotFound: - print('Какое-то сообщение не удаляется(') - - -@dp.callback_query_handler(text='Inline_Edit') -async def edit_init(call: types.CallbackQuery, state: FSMContext): - async with state.proxy() as data: - data['state'] = True - date_count = data['date_count'] - start_date, end_date = week_definition(date_count) - await bot.edit_message_text( - chat_id=call.message.chat.id, - message_id=call.message.message_id, - text=f"*На какой день задание?\n📅 {start_date} - {end_date} 📅*", - reply_markup=Buttons.Inline_Date_ADD, - parse_mode="markdown" - ) - await SelfState.Edit_state.set() - - -@dp.message_handler(state=SelfState.Edit_state) -async def edit_homework(message: types.Message, state: FSMContext): - text = message.text - async with state.proxy() as data: - date = data['date'] - subject = data['subject'] - print(message.from_user.username, 'отредактировал:\n', text) - HDB.delete_homework(subject_name=subject, date=date, group=get_user_group(message)) - text = HDB.add_homework( - subject_name=subject, - username=message.from_user.username, - text=text, date=date, - group=get_user_group(message), - edit=True) - await message.answer( - text=f'*{text}*', parse_mode='markdown') - await state.finish() - - -@dp.callback_query_handler(lambda query: query.data.split('_')[2][0] == 'B', state=SelfState.Add_state) -async def add_homework_date(query: types.CallbackQuery, state: FSMContext): - async with state.proxy() as data: - current_state = data['state'] - date_count = data['date_count'] - if current_state: - day = query.data.split("_")[2] - start_date = week_definition(date_count, debug=True) - await bot.edit_message_text( - text='*Введите домашнее задание*', - chat_id=query.message.chat.id, - message_id=query.message.message_id, - parse_mode='markdown' - ) - async with state.proxy() as data: - data['date'] = (start_date + timedelta(days=days[day])).strftime('%d.%m.%Y') - await SelfState.Add_state.set() - - -def register_cq_handlers(dsp: Dispatcher): - dsp.register_callback_query_handler(callback=callback_up, text='Inline_Date_Up', state='*') - dsp.register_callback_query_handler(callback=callback_down, text='Inline_Date_Up', state='*') - dsp.register_callback_query_handler(callback=all_week_homework, text='Inline_Date_Week', state='*') - dsp.register_callback_query_handler(homework_reply, lambda query: query.data.split('_')[2][0] == 'B') - dsp.register_callback_query_handler( - edit_homework_date, - lambda query: query.data.split('_')[2][0] == 'B', - state=SelfState.Edit_state) +def __sys_arguments(*args, **_kwargs): + for argument in args[1:]: + if argument == '-i' or argument == '--init': + HDB.init() + continue + if argument == '-s' or argument == '--silent': + Debugger.debug = False + continue + else: + exit(f'Unknown argument --> "{argument}"') if __name__ == '__main__': - register_cq_handlers(dp) + __sys_arguments(*sys.argv) + overall_handlers_registration(dp) executor.start_polling(dp, skip_updates=True) diff --git a/Course_1/Telegram_Bot/registration.py b/Course_1/Telegram_Bot/registration.py new file mode 100644 index 0000000..9411564 --- /dev/null +++ b/Course_1/Telegram_Bot/registration.py @@ -0,0 +1,73 @@ +from aiogram import Dispatcher +from Buttons.Maintenance import * + + +def register_cq_handlers(dp: Dispatcher): + dp.register_callback_query_handler(callback=callback_up, text='Inline_Date_Up', state='*') + dp.register_callback_query_handler(callback=callback_down, text='Inline_Date_Down', state='*') + dp.register_callback_query_handler(callback=all_week_homework, text='Inline_Date_Week', state='*') + dp.register_callback_query_handler( + homework_reply, + lambda query: query.data.split('_')[2][0] == 'B' if len(query.data.split('_')) > 2 else False) + dp.register_callback_query_handler( + editor_homework_date, + lambda query: query.data.split('_')[2][0] == 'B' if len(query.data.split('_')) > 2 else False, + state=SelfState.Edit_state) + dp.register_callback_query_handler( + add_homework_date, + lambda query: query.data.split('_')[2][0] == 'B' if len(query.data.split('_')) > 2 else False, + state=SelfState.Add_state + ) + dp.register_callback_query_handler(edit_init, text='Inline_Edit') + dp.register_callback_query_handler(add_homework_state, text='Inline_Add') + dp.register_callback_query_handler( + delete_homework_date, + lambda query: query.data.split('_')[2][0] == 'B' if len(query.data.split('_')) > 2 else False, + state=SelfState.Delete_state) + dp.register_callback_query_handler( + delete_homework, + lambda query: 'Inline' not in query.data, + state=SelfState.Delete_state) + dp.register_callback_query_handler(delete_homework_state, text='Inline_Delete') + dp.register_callback_query_handler( + editor_add_homework_subject, + lambda query: 'Inline' not in query.data, + state=SelfState.Edit_state) + dp.register_callback_query_handler( + adding_add_homework_subject, + lambda query: 'Inline' not in query.data, + state=SelfState.Add_state) + + +def register_msg_handlers(dp: Dispatcher): + dp.register_message_handler( + processing_of_receiving_hw, + lambda message: message.text == 'Получить задание!', + state="*") + dp.register_message_handler(edit_homework, state=SelfState.Edit_state) + dp.register_message_handler( + add_homework, + state=SelfState.Add_state, + content_types=[types.ContentType.TEXT, types.ContentType.DOCUMENT, types.ContentType.PHOTO]) + dp.register_message_handler( + parse_attachments, + state=SelfState.Parse_state, + content_types=types.ContentType.DOCUMENT) + dp.register_message_handler( + process_rule_command, + lambda message: message.text == 'Управление заданиями', + state="*") + dp.register_message_handler( + group_state_command, + state=SelfState.Group_state + ) + + dp.register_message_handler( + process_get_materials, + lambda message: message.text == 'Полезные материалы', + state="*") + + +def overall_handlers_registration(dp: Dispatcher): + register_cq_handlers(dp) + register_msg_handlers(dp)