Browse Source

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	Readme.md
Vildan 2 years ago
parent
commit
c1d894a4fa
8 changed files with 141 additions and 71 deletions
  1. 4 10
      Readme.md
  2. 5 1
      bot/keyboards.py
  3. 7 2
      handlers/admin/notifications.py
  4. 51 17
      handlers/start.py
  5. 62 27
      handlers/user/make_events.py
  6. 8 8
      handlers/user/show_events.py
  7. 2 0
      handlers/user/states.py
  8. 2 6
      main.py

+ 4 - 10
Readme.md

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

+ 5 - 1
bot/keyboards.py

@@ -88,7 +88,11 @@ def make_calendar():
     button_after_tomorrow = InlineKeyboardButton(text="Послезавтра", callback_data="after_tomorrow")
     button_after_tomorrow = InlineKeyboardButton(text="Послезавтра", callback_data="after_tomorrow")
 
 
     for i in range(1, days_in_month+1, 1):
     for i in range(1, days_in_month+1, 1):
-        date_i = InlineKeyboardButton(text=str(i), callback_data=f"date_2022-{str(month)}-{str(i)}")
+        if i < 10:
+            day = f"0{i}"
+        else:
+            day = i
+        date_i = InlineKeyboardButton(text=str(i), callback_data=f"date_2022-{str(month)}-{str(day)}")
         keyboard.insert(date_i)
         keyboard.insert(date_i)
     # keyboard.add(button_today, button_tomorrow, button_after_tomorrow)
     # keyboard.add(button_today, button_tomorrow, button_after_tomorrow)
     return keyboard
     return keyboard

+ 7 - 2
handlers/admin/notifications.py

@@ -2,6 +2,7 @@
 from bot.dispatcher import bot
 from bot.dispatcher import bot
 import bot.config as cnf
 import bot.config as cnf
 
 
+
 async def new_event():
 async def new_event():
     await bot.send_message(cnf.CHAT_ID, "Новая заявка мероприятия")
     await bot.send_message(cnf.CHAT_ID, "Новая заявка мероприятия")
 
 
@@ -11,7 +12,11 @@ async def new_user():
 
 
 
 
 async def new_bug(data):
 async def new_bug(data):
-    msg = f"❗Баг❗\n" \
-          f"Баг: {data['bug']}\n" \
+    msg = f"<b>Обратная связь</b>\n" \
+          f"Сообщение: {data['bug']}\n" \
           f"Отправитель: {data['from_user']}\n"
           f"Отправитель: {data['from_user']}\n"
     await bot.send_message(cnf.CHAT_ID, msg)
     await bot.send_message(cnf.CHAT_ID, msg)
+
+
+async def message_to_all(msg):
+    await bot.send_message(msg)

+ 51 - 17
handlers/start.py

@@ -1,11 +1,13 @@
+import asyncio
+
 from aiogram import types, Dispatcher
 from aiogram import types, Dispatcher
 from bot.keyboards import main_kb, register_kb,   check_register_kb
 from bot.keyboards import main_kb, register_kb,   check_register_kb
 from bot import database
 from bot import database
 from bot import sql
 from bot import sql
 from bot.dispatcher import bot
 from bot.dispatcher import bot
 from aiogram.dispatcher.storage import FSMContext
 from aiogram.dispatcher.storage import FSMContext
-from handlers.user.states import SendBugState
-from handlers.admin.notifications import new_bug
+from handlers.user.states import SendBugState, MessageToAll
+from handlers.admin.notifications import new_bug, message_to_all
 
 
 
 
 # @dp.message_handler(commands=['start'])
 # @dp.message_handler(commands=['start'])
@@ -15,21 +17,23 @@ async def start_cmd(message: types.Message):
     if not db.sql_fetchone(sql.check_id(message.from_user.id)):
     if not db.sql_fetchone(sql.check_id(message.from_user.id)):
         await message.answer(f"🤖Вас приветствует лакей ТТИТ🤖\n\n"
         await message.answer(f"🤖Вас приветствует лакей ТТИТ🤖\n\n"
                              "Для доступа к функциям нужно пройти простую регистрацию\n", reply_markup=register_kb)
                              "Для доступа к функциям нужно пройти простую регистрацию\n", reply_markup=register_kb)
-    elif db.sql_fetchone(sql.check_approved(message.from_user.id)) == 0:
+    elif db.sql_fetchone(sql.check_approved(message.from_user.id)) == "0":
         await message.answer(f"Ваша заявка находится на рассмотрении", reply_markup=check_register_kb)
         await message.answer(f"Ваша заявка находится на рассмотрении", reply_markup=check_register_kb)
     else:
     else:
-        await message.answer(f"🤖Вас приветствует лакей ТТИТ🤖\n"
-                             f"\n"
-                             f"Я помогу Вам запланировать мероприятие в 405 аудитории.\n\n"
-                             f"Меня еще разрабатыают по этому умею немного.\n\n"
-                             f"Вот мои функции:\n"
-                             f"Запланировать мероприятие\n"
-                             f"Мои события\n"
-                             f"Все события\n\n"
-                             f"Если есть пожелания или замечания\n"
-                             f"Можете обратиться к @FeldwebelWillman\n"
-                             f"Или воспользовтаься обратной связью /bug",
-                             reply_markup=main_kb)
+        msg = await message.answer(f"🤖Вас приветствует лакей ТТИТ🤖\n"
+                                   f"\n"
+                                   f"Я помогу Вам запланировать мероприятие в 405 аудитории.\n\n"
+                                   f"Меня еще разрабатыают по этому умею немного.\n\n"
+                                   f"Вот мои функции:\n"
+                                   f"Запланировать мероприятие\n"
+                                   f"Мои события\n"
+                                   f"Все события\n\n"
+                                   f"Если есть пожелания или замечания\n"
+                                   f"Можете обратиться к @FeldwebelWillman\n"
+                                   f"Или воспользовтаься обратной связью /feedback",
+                                   reply_markup=main_kb)
+        await asyncio.sleep(10)
+        await msg.delete()
 
 
 
 
 async def stop_cmd(message: types.Message):
 async def stop_cmd(message: types.Message):
@@ -40,8 +44,11 @@ async def stop_cmd(message: types.Message):
 
 
 
 
 async def send_report(message: types.Message):
 async def send_report(message: types.Message):
+    await message.delete()
     await SendBugState.send_bug.set()
     await SendBugState.send_bug.set()
-    await message.answer("Опишите проблему")
+    msg = await message.answer("Опишите проблему")
+    await asyncio.sleep(5)
+    await msg.delete()
 
 
 
 
 async def get_report(message: types.Message, state: FSMContext):
 async def get_report(message: types.Message, state: FSMContext):
@@ -52,8 +59,35 @@ async def get_report(message: types.Message, state: FSMContext):
     await new_bug(data)
     await new_bug(data)
     await message.delete()
     await message.delete()
 
 
+
+async def broadcast_cmd(message: types.Message):
+    await message.delete()
+    await MessageToAll.send_message.set()
+    msg = await message.answer("Введите сооьщение которое будет отправленно всем пользователям")
+    await asyncio.sleep(5)
+    await msg.delete()
+
+
+async def get_message(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 message_to_all(data)
+    await message.delete()
+
+
+async def delete_all_msg(message: types.Message):
+    await asyncio.sleep(5)
+    await message.delete()
+
+
 def main_register(dp: Dispatcher):
 def main_register(dp: Dispatcher):
     dp.register_message_handler(start_cmd, commands=['start', 'help'])
     dp.register_message_handler(start_cmd, commands=['start', 'help'])
     dp.register_message_handler(stop_cmd, commands=['stop'])
     dp.register_message_handler(stop_cmd, commands=['stop'])
-    dp.register_message_handler(send_report, commands=['bug'])
+    dp.register_message_handler(send_report, commands=['feedback'])
     dp.register_message_handler(get_report, state=SendBugState.send_bug)
     dp.register_message_handler(get_report, state=SendBugState.send_bug)
+    dp.register_message_handler(broadcast_cmd, commands=['broadcast'])
+    dp.register_message_handler(get_message, state=MessageToAll.send_message)
+    dp.register_message_handler(delete_all_msg)
+

+ 62 - 27
handlers/user/make_events.py

@@ -1,11 +1,14 @@
+import asyncio
+import aiogram
 from aiogram import types, Dispatcher
 from aiogram import types, Dispatcher
 from bot import database, sql
 from bot import database, sql
 from bot.keyboards import register_kb, make_calendar, events_kb, cancel_booking, main_kb
 from bot.keyboards import register_kb, make_calendar, events_kb, cancel_booking, main_kb
-from bot.functions import make_date, time_validator, normalize_time, to_quotes, check_overlap, beauty_booked_time
+from bot.functions import make_date, date_range, time_validator, normalize_time, to_quotes, check_overlap, beauty_booked_time
 from handlers.user.states import BookingState
 from handlers.user.states import BookingState
 from aiogram.dispatcher.storage import FSMContext
 from aiogram.dispatcher.storage import FSMContext
 from bot import messages
 from bot import messages
 from handlers.admin.notifications import new_event
 from handlers.admin.notifications import new_event
+import datetime
 
 
 
 
 async def make_event(message: types.message):
 async def make_event(message: types.message):
@@ -18,73 +21,105 @@ async def make_event(message: types.message):
         if message.text == "🎯 Запланировать мероприятие":
         if message.text == "🎯 Запланировать мероприятие":
             await message.delete()
             await message.delete()
             # TODO: Добавить переход на следующий месяц
             # TODO: Добавить переход на следующий месяц
-            await message.answer(messages.events_welcome(make_date()), reply_markup=make_calendar())
+            msg = await message.answer(messages.events_welcome(make_date()), reply_markup=make_calendar())
+            await asyncio.sleep(60)
+            await msg.delete()
 
 
 
 
 async def select_date(call: types.CallbackQuery, state: FSMContext):
 async def select_date(call: types.CallbackQuery, state: FSMContext):
     db = database.Database()
     db = database.Database()
     date = call.data.split("_")[1]
     date = call.data.split("_")[1]
     booked = db.sql_fetchall(sql.sql_booked_time(date))
     booked = db.sql_fetchall(sql.sql_booked_time(date))
-    await BookingState.start.set()
-    await state.update_data(date=to_quotes(date))
-    await state.update_data(owner=call.from_user.id)
-    if len(booked) == 0:
-        await call.message.edit_text(f"Вы выбрали дату: {date}\n"
-                                     f"На этот день мероприятий не заплпнированно", reply_markup=events_kb())
+    today = datetime.datetime.now()
+    if date >= datetime.datetime.strftime(today, '%Y-%m-%d'):
+        if len(booked) == 0:
+            await BookingState.start.set()
+            await state.update_data(date=to_quotes(date))
+            await state.update_data(owner=call.from_user.id)
+            msg = await call.message.edit_text(f"Вы выбрали дату: {date}\n"
+                                               f"На этот день мероприятий не запланированно", reply_markup=events_kb())
+            await asyncio.sleep(30)
+            await msg.delete()
+        else:
+            await BookingState.start.set()
+            await state.update_data(date=to_quotes(date))
+            await state.update_data(owner=call.from_user.id)
+            msg = await call.message.edit_text(f"Вы выбрали дату: {date}\n\n"
+                                               f"Занятое время\n\n"
+                                               f"{beauty_booked_time(sorted(booked, key=lambda t: t['e_start'], reverse=False))}",
+                                               reply_markup=events_kb())
+            await asyncio.sleep(60)
+            await msg.delete()
     else:
     else:
-        await call.message.edit_text(f"Вы выбрали дату: {date}\n\n"
-                                     f"Занятое время\n\n"
-                                     f"{beauty_booked_time(sorted(booked, key=lambda t: t['e_start'], reverse=False))}",
-                                     reply_markup=events_kb())
+        msg = await call.message.answer("Нельзя выбрать дату позже сегодняшней")
+        await asyncio.sleep(5)
+        await msg.delete()
 
 
 
 
 async def edit_date(call: types.CallbackQuery, state: FSMContext):
 async def edit_date(call: types.CallbackQuery, state: FSMContext):
-    await call.message.edit_text(f"выберите дату чтобы увидеть список мероприятий\n\n"
-                                 f"Так же календарь мероприятий можно посмотреть в "
-                                 f"<a href=moodle.tomtit-tomsk.ru>Moodle</a>\n\n"
-                                 f"Сегодняшняя дата <b>{make_date()}</b>", reply_markup=make_calendar())
+    msg = await call.message.edit_text(f"выберите дату чтобы увидеть список мероприятий\n\n"
+                                       f"Так же календарь мероприятий можно посмотреть в "
+                                       f"<a href=moodle.tomtit-tomsk.ru>Moodle</a>\n\n"
+                                       f"Сегодняшняя дата <b>{make_date()}</b>", reply_markup=make_calendar())
     await call.message.delete()
     await call.message.delete()
     await state.finish()
     await state.finish()
+    await asyncio.sleep(30)
+    await msg.delete()
 
 
 
 
 async def booking_date(call: types.CallbackQuery):
 async def booking_date(call: types.CallbackQuery):
-    await call.message.answer("Введите диапазон времени\n"
-                              "Возможные форматы\n\n"
-                              "13.00 15.30\n"
-                              "13.00-15.30\n"
-                              "13:00 15:30\n"
-                              "13.00-15.30\n", reply_markup=cancel_booking())
+    msg = await call.message.answer("Введите диапазон времени\n"
+                                    "Возможные форматы\n\n"
+                                    "13.00 15.30\n"
+                                    "13.00-15.30\n"
+                                    "13:00 15:30\n"
+                                    "13.00-15.30\n", reply_markup=cancel_booking())
     await BookingState.time.set()
     await BookingState.time.set()
+    await asyncio.sleep(20)
+    await msg.delete()
 
 
 
 
 async def get_time(message: types.Message, state: FSMContext):
 async def get_time(message: types.Message, state: FSMContext):
     # Парсим то что ввел пользователь
     # Парсим то что ввел пользователь
     time = normalize_time(message.text)
     time = normalize_time(message.text)
+    await message.delete()
     # Забираем текущую дату
     # Забираем текущую дату
     date = await state.get_data()
     date = await state.get_data()
     # Проверяем валидность времени
     # Проверяем валидность времени
     if time_validator(message.text):
     if time_validator(message.text):
         # Проверяем пересечения
         # Проверяем пересечения
         if not check_overlap(time[0], time[1], date['date']):
         if not check_overlap(time[0], time[1], date['date']):
-            await message.answer("Указанное время пеерсекается")
+            msg = await message.answer("Указанное время пеерсекается")
+            await asyncio.sleep(5)
+            await msg.delete()
         else:
         else:
             await state.update_data(t_start=time[0])
             await state.update_data(t_start=time[0])
             await state.update_data(t_end=time[1])
             await state.update_data(t_end=time[1])
             await BookingState.description.set()
             await BookingState.description.set()
-            await message.answer("Введите краткое описание мероприятия", reply_markup=cancel_booking())
+            msg = await message.answer("Введите краткое описание мероприятия", reply_markup=cancel_booking())
+            await asyncio.sleep(10)
+            await msg.delete()
     else:
     else:
-        await message.answer("Неверный формат времени")
+        msg = await message.answer("Неверный формат времени")
+        await asyncio.sleep(5)
+        await msg.delete()
 
 
 
 
 async def send_event(message: types.Message, state: FSMContext):
 async def send_event(message: types.Message, state: FSMContext):
     db = database.Database()
     db = database.Database()
     if len(message.text) > 100:
     if len(message.text) > 100:
-        await message.answer("Описание слишком длинное")
+        msg = await message.answer("Описание слишком длинное")
+        await asyncio.sleep(5)
+        await msg.delete()
+        await message.delete()
     else:
     else:
         await state.update_data(description=message.text)
         await state.update_data(description=message.text)
         await state.update_data(approved=0)
         await state.update_data(approved=0)
         data = await state.get_data()
         data = await state.get_data()
-        await message.answer("Заявка принята", reply_markup=main_kb)
+        await message.delete()
+        msg = await message.answer("Заявка принята", reply_markup=main_kb)
+        await asyncio.sleep(5)
+        await msg.delete()
         await state.finish()
         await state.finish()
         db.sql_query_send(sql.sql_send_event(data))
         db.sql_query_send(sql.sql_send_event(data))
         await new_event()
         await new_event()

+ 8 - 8
handlers/user/show_events.py

@@ -6,12 +6,12 @@ from bot import sql
 
 
 
 
 async def my_events(message: types.Message):
 async def my_events(message: types.Message):
+    await message.delete()
     db = database.Database()
     db = database.Database()
-    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":
+    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.delete()
         await message.answer("Команды станут доступны после регистрации", reply_markup=register_kb)
         await message.answer("Команды станут доступны после регистрации", reply_markup=register_kb)
-    # elif db.sql_fetchone(sql=sql.check_admin(message.from_user.id)) == "0":
-    #    await message.answer("В разработке")
     else:
     else:
         data = db.sql_fetchall(sql=sql.get_user_event(message.from_user.id))
         data = db.sql_fetchall(sql=sql.get_user_event(message.from_user.id))
         if len(data) == 0:
         if len(data) == 0:
@@ -21,29 +21,29 @@ async def my_events(message: types.Message):
 
 
 
 
 async def all_events(message: types.Message):
 async def all_events(message: types.Message):
+    await message.delete()
     db = database.Database()
     db = database.Database()
-    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":
+    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.delete()
         await message.answer("Команды станут доступны после регистрации", reply_markup=register_kb)
         await message.answer("Команды станут доступны после регистрации", reply_markup=register_kb)
-    # elif db.sql_fetchone(sql=sql.check_admin(message.from_user.id)) == "0":
-    #    await message.answer("В разработке")
     else:
     else:
         await message.answer("Выберете интересующий диапазон", reply_markup=events_range_kb())
         await message.answer("Выберете интересующий диапазон", reply_markup=events_range_kb())
 
 
+
 # TODO: Визуальное оформление событий
 # TODO: Визуальное оформление событий
 
 
 
 
 async def select_range(call: types.CallbackQuery):
 async def select_range(call: types.CallbackQuery):
     if call.data == "today":
     if call.data == "today":
         db = database.Database()
         db = database.Database()
-        time = "'"+str(date_range("today"))+"'"
+        time = "'" + str(date_range("today")) + "'"
         data = db.sql_fetchall(sql=sql.get_all_events(time))
         data = db.sql_fetchall(sql=sql.get_all_events(time))
         if len(data) == 0:
         if len(data) == 0:
             await call.message.answer("Сегодня мероприятий нет")
             await call.message.answer("Сегодня мероприятий нет")
         else:
         else:
             await call.message.answer(beauty_all_events(sorted(data, key=lambda d: d['e_date'])))
             await call.message.answer(beauty_all_events(sorted(data, key=lambda d: d['e_date'])))
 
 
-
     if call.data == "week":
     if call.data == "week":
         db = database.Database()
         db = database.Database()
         time = date_range("week").split(" ")
         time = date_range("week").split(" ")

+ 2 - 0
handlers/user/states.py

@@ -16,3 +16,5 @@ class SendBugState(StatesGroup):
     send_bug = State()
     send_bug = State()
 
 
 
 
+class MessageToAll(StatesGroup):
+    send_message = State()

+ 2 - 6
main.py

@@ -4,16 +4,12 @@ import handlers.admin.admin_menu
 import logging
 import logging
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
-    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)
+    logging.basicConfig(level=logging.DEBUG)
     handlers.user.registration.register_handlers(dp)
     handlers.user.registration.register_handlers(dp)
-    handlers.start.main_register(dp)
     handlers.user.make_events.events_register(dp)
     handlers.user.make_events.events_register(dp)
     handlers.user.show_events.register(dp)
     handlers.user.show_events.register(dp)
     handlers.admin.admin_menu.register_admin_menu(dp)
     handlers.admin.admin_menu.register_admin_menu(dp)
     handlers.admin.manage_users.admin_handlers(dp)
     handlers.admin.manage_users.admin_handlers(dp)
     handlers.admin.manage_events.register_handlers(dp)
     handlers.admin.manage_events.register_handlers(dp)
+    handlers.start.main_register(dp)
     executor.start_polling(dp, skip_updates=True)
     executor.start_polling(dp, skip_updates=True)