Browse Source

Merge remote-tracking branch 'origin/master'

Vildan 2 năm trước cách đây
mục cha
commit
0f06c9bd45

+ 5 - 17
Readme.md

@@ -4,23 +4,11 @@
 - Telegram бот для отправки на бронирование, одобрение и отлклонение заявок
 - Календарь Moodle
 - База данных мероприятий и пользователей
-- микросервис сборки мероприятия после одобрения
-- микросервис отправки мероприятия в календарь
-
 
 ## TODO list
-- [x] База данных
-- [ ] Календарь в Moodle 
-- [x] Телеграм бот
-- [x] Разграничение доступа для администраторов и пользователей
-- [x] Клавиатура для пользователей
-- [x] Клавиатура для заявок регистрации
-- [x] Клавиатура для регистрации
-- [ ] Клавиатура для управления мероприятиями
-- [x] Клавиатура для управления пользователями
-- [ ] Меню для бота
 - [ ] Выгрузка мероприятий в Moodle
-- [ ] Проверка на занятость кабинета
-- [ ] Оповещение о предстоящих мероприятиях в чате коллектива
-- [ ] Просмотр всех событий в боте
-
+- [ ] Добавить функционал для кнопок "Отклонить"
+- [ ] Исправить орфографические ошибки
+- [ ] Запретить бронирования даты позже "сегодняшней"
+- [ ] Запретить указывать время начала позже времени конца 
+- [ ] Дополнить Wiki

+ 1 - 0
bot/config.py

@@ -11,3 +11,4 @@ DB_HOST = os.getenv('DB_HOST')
 DB_NAME = os.getenv('DB_NAME')
 DB_USER = os.getenv('DB_USER')
 DB_PASS = os.getenv('DB_PASS')
+CHAT_ID = os.getenv('CHAT_ID')

+ 8 - 6
bot/database.py

@@ -4,12 +4,14 @@ from bot import config as conf
 
 class Database:
     def __init__(self):
-        self.connection = mysql.connector.connect(host=conf.DB_HOST,
-                                                  user=conf.DB_USER,
-                                                  password=conf.DB_PASS,
-                                                  database=conf.DB_NAME)
-        self.cursor = self.connection.cursor(dictionary=True)
-
+        try:
+            self.connection = mysql.connector.connect(host=conf.DB_HOST,
+                                                      user=conf.DB_USER,
+                                                      password=conf.DB_PASS,
+                                                      database=conf.DB_NAME)
+            self.cursor = self.connection.cursor(dictionary=True)
+        except mysql.connector.Error as err:
+            print("Something went wrong: {}".format(err))
     def cursor(self):
         return self.cursor
 

+ 1 - 0
handlers/admin/__init__.py

@@ -1,3 +1,4 @@
 import handlers.admin.admin_menu
 import handlers.admin.manage_users
 import handlers.admin.manage_events
+import handlers.admin.notifications

+ 16 - 0
handlers/admin/notifications.py

@@ -1 +1,17 @@
 # TODO: Рассылка для администраторов
+from bot.dispatcher import bot
+import bot.config as cnf
+
+async def new_event():
+    await bot.send_message(cnf.CHAT_ID, "Новая заявка мероприятия")
+
+
+async def new_user():
+    await bot.send_message(cnf.CHAT_ID, "Новая заявка на регистрацию")
+
+
+async def new_bug(data):
+    msg = f"❗Баг❗\n" \
+          f"Баг: {data['bug']}\n" \
+          f"Отправитель: {data['from_user']}\n"
+    await bot.send_message(cnf.CHAT_ID, msg)

+ 23 - 6
handlers/start.py

@@ -1,10 +1,11 @@
-import asyncio
-
-import aiogram
 from aiogram import types, Dispatcher
 from bot.keyboards import main_kb, register_kb,   check_register_kb
 from bot import database
 from bot import sql
+from bot.dispatcher import bot
+from aiogram.dispatcher.storage import FSMContext
+from handlers.user.states import SendBugState
+from handlers.admin.notifications import new_bug
 
 
 # @dp.message_handler(commands=['start'])
@@ -14,8 +15,8 @@ async def start_cmd(message: types.Message):
     if not db.sql_fetchone(sql.check_id(message.from_user.id)):
         await message.answer(f"🤖Вас приветствует лакей ТТИТ🤖\n\n"
                              "Для доступа к функциям нужно пройти простую регистрацию\n", reply_markup=register_kb)
-    elif not db.sql_fetchone(sql.check_approved(message.from_user.id)):
-        await message.answer(f"Ваша заявка находится на рассмотрернии", reply_markup=check_register_kb)
+    elif db.sql_fetchone(sql.check_approved(message.from_user.id)) == 0:
+        await message.answer(f"Ваша заявка находится на рассмотрении", reply_markup=check_register_kb)
     else:
         await message.answer(f"🤖Вас приветствует лакей ТТИТ🤖\n"
                              f"\n"
@@ -26,7 +27,8 @@ async def start_cmd(message: types.Message):
                              f"Мои события\n"
                              f"Все события\n\n"
                              f"Если есть пожелания или замечания\n"
-                             f"Можете обратиться к @FeldwebelWillman",
+                             f"Можете обратиться к @FeldwebelWillman\n"
+                             f"Или воспользовтаься обратной связью /bug",
                              reply_markup=main_kb)
 
 
@@ -37,6 +39,21 @@ async def stop_cmd(message: types.Message):
         await message.answer("Я слушаюсь только создателя")
 
 
+async def send_report(message: types.Message):
+    await SendBugState.send_bug.set()
+    await message.answer("Опишите проблему")
+
+
+async def get_report(message: types.Message, state: FSMContext):
+    await state.update_data(bug=message.text)
+    await state.update_data(from_user=message.from_user.username)
+    data = await state.get_data()
+    await state.finish()
+    await new_bug(data)
+    await message.delete()
+
 def main_register(dp: Dispatcher):
     dp.register_message_handler(start_cmd, commands=['start', 'help'])
     dp.register_message_handler(stop_cmd, commands=['stop'])
+    dp.register_message_handler(send_report, commands=['bug'])
+    dp.register_message_handler(get_report, state=SendBugState.send_bug)

+ 2 - 6
handlers/user/make_events.py

@@ -5,11 +5,7 @@ from bot.functions import make_date, time_validator, normalize_time, to_quotes,
 from handlers.user.states import BookingState
 from aiogram.dispatcher.storage import FSMContext
 from bot import messages
-
-
-# TODO: Убрать вывод данных состояния
-# Добавить визуализацию занятого времени
-# Переписать реактирование сообщений
+from handlers.admin.notifications import new_event
 
 
 async def make_event(message: types.message):
@@ -90,8 +86,8 @@ async def send_event(message: types.Message, state: FSMContext):
         data = await state.get_data()
         await message.answer("Заявка принята", reply_markup=main_kb)
         await state.finish()
-        print(data)
         db.sql_query_send(sql.sql_send_event(data))
+        await new_event()
 
 
 def events_register(dp: Dispatcher):

+ 10 - 7
handlers/user/registration.py

@@ -4,20 +4,20 @@ from bot.functions import validate_fio, validate_phone, reject_latin, reject_cmd
 from aiogram.dispatcher.storage import FSMContext
 from bot.keyboards import reset_register_kb, register_kb, main_kb, check_register_kb
 from bot import database, sql
-
+from handlers.admin.notifications import new_user
 
 async def registration(message: types.Message):
     db = database.Database()
     await message.delete()
     if db.sql_fetchone(f'select tg_id from user_table where tg_id = {message.from_user.id} and approved = 0'):
-        await message.answer("Ваша заявка рассматривается", reply_markup=check_register_kb)
+        await message.answer("Ваша заявка находится на рассмотрернии", reply_markup=check_register_kb)
     elif db.sql_fetchone(f'select tg_id from user_table where tg_id = {message.from_user.id} and approved = 1'):
         msg = await message.answer("Вы зарегистрированны", reply_markup=main_kb)
         await msg.delete()
     else:
-        await message.answer(f"Дkя регистрации необходимо указать\n"
-                             f"Номер телефона\n"
-                             f"Фамилия Имя Отчество")
+        await message.answer(f"Дkя регистрации необходимо будет указать\n"
+                             f"Номер телефона и "
+                             f"Фамилию Имя Отчество")
 
         await message.answer(f"Введите номер телефона\n"
                              f"Возможные форматы:\n\n"
@@ -33,9 +33,11 @@ async def check_reg_status(message: types.Message):
     db = database.Database()
     await message.delete()
     if db.sql_fetchone(f'select tg_id from user_table where tg_id = {message.from_user.id} and approved = 0'):
-        await message.answer("Ваша заявка рассматривается", reply_markup=check_register_kb)
+        await message.answer("Ваша заявка находится на рассмотрернии", reply_markup=check_register_kb)
     elif db.sql_fetchone(f'select tg_id from user_table where tg_id = {message.from_user.id} and approved = 1'):
         await message.answer("Вы зарегистрированны", reply_markup=main_kb)
+    else:
+        await message.answer("Вы не зарегистрированны", reply_markup=register_kb)
 
 
 async def get_number(message: types.Message, state: FSMContext):
@@ -66,8 +68,9 @@ async def get_fio(message: types.Message, state: FSMContext):
         await message.answer(f"Спасибо за регистрацию\n"
                              f"Вы сможете воспользоваться функциями после одобрения\n", reply_markup=check_register_kb)
 
-        db.sql_query_send(sql.sql_send_register(reg_data))
+        db.sql_query_send(sql.sql_send(reg_data))
         await state.finish()
+        await new_user()
 
 
 async def reset_register(message: types.Message, state: FSMContext):

+ 5 - 4
handlers/user/show_events.py

@@ -10,8 +10,8 @@ async def my_events(message: types.Message):
     if db.sql_fetchone(sql=sql.check_approved(message.from_user.id)) == "0" or db.sql_fetchone(sql=sql.check_id(message.from_user.id)) == "0":
         await message.delete()
         await message.answer("Команды станут доступны после регистрации", reply_markup=register_kb)
-    elif db.sql_fetchone(sql=sql.check_admin(message.from_user.id)) == "0":
-        await message.answer("В разработке")
+    # elif db.sql_fetchone(sql=sql.check_admin(message.from_user.id)) == "0":
+    #    await message.answer("В разработке")
     else:
         data = db.sql_fetchall(sql=sql.get_user_event(message.from_user.id))
         if len(data) == 0:
@@ -25,8 +25,8 @@ async def all_events(message: types.Message):
     if db.sql_fetchone(sql=sql.check_approved(message.from_user.id)) == "0" or db.sql_fetchone(sql=sql.check_id(message.from_user.id)) == "0":
         await message.delete()
         await message.answer("Команды станут доступны после регистрации", reply_markup=register_kb)
-    elif db.sql_fetchone(sql=sql.check_admin(message.from_user.id)) == "0":
-        await message.answer("В разработке")
+    # elif db.sql_fetchone(sql=sql.check_admin(message.from_user.id)) == "0":
+    #    await message.answer("В разработке")
     else:
         await message.answer("Выберете интересующий диапазон", reply_markup=events_range_kb())
 
@@ -43,6 +43,7 @@ async def select_range(call: types.CallbackQuery):
         else:
             await call.message.answer(beauty_all_events(sorted(data, key=lambda d: d['e_date'])))
 
+
     if call.data == "week":
         db = database.Database()
         time = date_range("week").split(" ")

+ 4 - 0
handlers/user/states.py

@@ -12,3 +12,7 @@ class BookingState(StatesGroup):
     description = State()
 
 
+class SendBugState(StatesGroup):
+    send_bug = State()
+
+

+ 5 - 1
main.py

@@ -4,7 +4,11 @@ import handlers.admin.admin_menu
 import logging
 
 if __name__ == '__main__':
-    logging.basicConfig(level=logging.INFO)
+    logging.basicConfig(handlers=[logging.FileHandler(filename="./log_records.txt",
+                                                      encoding='utf-8', mode='a+')],
+                        format="%(asctime)s %(name)s:%(levelname)s:%(message)s",
+                        datefmt="%F %A %T",
+                        level=logging.DEBUG)
     handlers.user.registration.register_handlers(dp)
     handlers.start.main_register(dp)
     handlers.user.make_events.events_register(dp)

+ 0 - 2
requirements.txt

@@ -1,6 +1,4 @@
 intervaltree
-mysql
-dotenv
 aiogram==2.22.2
 aiohttp==3.8.3
 aiosignal==1.2.0