make_events.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import asyncio
  2. import aiogram
  3. from aiogram import types, Dispatcher
  4. from bot import database, sql
  5. from bot.keyboards import register_kb, make_calendar, events_kb, cancel_booking, main_kb
  6. from bot.functions import make_date, date_range, time_validator, normalize_time, to_quotes, check_overlap, beauty_booked_time
  7. from handlers.user.states import BookingState
  8. from aiogram.dispatcher.storage import FSMContext
  9. from bot import messages
  10. from handlers.admin.notifications import new_event
  11. import datetime
  12. async def make_event(message: types.message):
  13. db = database.Database()
  14. if not db.sql_fetchone(f"select tg_id from user_table where tg_id ={message.from_user.id}") or \
  15. not db.sql_fetchone(f"select approved from user_table where tg_id={message.from_user.id}"):
  16. await message.delete()
  17. await message.answer(messages.non_register, reply_markup=register_kb)
  18. else:
  19. if message.text == "🎯 Запланировать мероприятие":
  20. await message.delete()
  21. # TODO: Добавить переход на следующий месяц
  22. await message.answer(messages.events_welcome(make_date()), reply_markup=make_calendar())
  23. async def select_date(call: types.CallbackQuery, state: FSMContext):
  24. db = database.Database()
  25. date = call.data.split("_")[1]
  26. booked = db.sql_fetchall(sql.sql_booked_time(date))
  27. today = datetime.datetime.now()
  28. if date >= datetime.datetime.strftime(today, '%Y-%m-%d'):
  29. if len(booked) == 0:
  30. await BookingState.start.set()
  31. await state.update_data(date=to_quotes(date))
  32. await state.update_data(owner=call.from_user.id)
  33. await call.message.edit_text(f"Вы выбрали дату: {date}\n"
  34. f"На этот день мероприятий не заплпнированно", reply_markup=events_kb())
  35. else:
  36. await BookingState.start.set()
  37. await state.update_data(date=to_quotes(date))
  38. await state.update_data(owner=call.from_user.id)
  39. await call.message.edit_text(f"Вы выбрали дату: {date}\n\n"
  40. f"Занятое время\n\n"
  41. f"{beauty_booked_time(sorted(booked, key=lambda t: t['e_start'], reverse=False))}",
  42. reply_markup=events_kb())
  43. else:
  44. msg = await call.message.answer("Нельзя выбрать дату позже сегодняшней")
  45. await asyncio.sleep(4)
  46. await msg.delete()
  47. async def edit_date(call: types.CallbackQuery, state: FSMContext):
  48. await call.message.edit_text(f"выберите дату чтобы увидеть список мероприятий\n\n"
  49. f"Так же календарь мероприятий можно посмотреть в "
  50. f"<a href=moodle.tomtit-tomsk.ru>Moodle</a>\n\n"
  51. f"Сегодняшняя дата <b>{make_date()}</b>", reply_markup=make_calendar())
  52. await call.message.delete()
  53. await state.finish()
  54. async def booking_date(call: types.CallbackQuery):
  55. await call.message.answer("Введите диапазон времени\n"
  56. "Возможные форматы\n\n"
  57. "13.00 15.30\n"
  58. "13.00-15.30\n"
  59. "13:00 15:30\n"
  60. "13.00-15.30\n", reply_markup=cancel_booking())
  61. await BookingState.time.set()
  62. async def get_time(message: types.Message, state: FSMContext):
  63. # Парсим то что ввел пользователь
  64. time = normalize_time(message.text)
  65. # Забираем текущую дату
  66. date = await state.get_data()
  67. # Проверяем валидность времени
  68. if time_validator(message.text):
  69. # Проверяем пересечения
  70. if not check_overlap(time[0], time[1], date['date']):
  71. await message.answer("Указанное время пеерсекается")
  72. else:
  73. await state.update_data(t_start=time[0])
  74. await state.update_data(t_end=time[1])
  75. await BookingState.description.set()
  76. await message.answer("Введите краткое описание мероприятия", reply_markup=cancel_booking())
  77. else:
  78. await message.answer("Неверный формат времени")
  79. async def send_event(message: types.Message, state: FSMContext):
  80. db = database.Database()
  81. if len(message.text) > 100:
  82. await message.answer("Описание слишком длинное")
  83. else:
  84. await state.update_data(description=message.text)
  85. await state.update_data(approved=0)
  86. data = await state.get_data()
  87. await message.answer("Заявка принята", reply_markup=main_kb)
  88. await state.finish()
  89. db.sql_query_send(sql.sql_send_event(data))
  90. await new_event()
  91. def events_register(dp: Dispatcher):
  92. dp.register_message_handler(make_event, text="🎯 Запланировать мероприятие")
  93. dp.register_callback_query_handler(select_date, text_startswith='date_')
  94. dp.register_callback_query_handler(edit_date, text=['change', 'cancel_booking'], state=[BookingState.start,
  95. BookingState.time,
  96. BookingState.description])
  97. dp.register_callback_query_handler(booking_date, text='booking', state=BookingState.start)
  98. dp.register_message_handler(get_time, state=BookingState.time)
  99. dp.register_message_handler(send_event, state=BookingState.description)