make_events.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. msg = await message.answer(messages.events_welcome(make_date()), reply_markup=make_calendar())
  23. await asyncio.sleep(60)
  24. await msg.delete()
  25. async def select_date(call: types.CallbackQuery, state: FSMContext):
  26. db = database.Database()
  27. date = call.data.split("_")[1]
  28. booked = db.sql_fetchall(sql.sql_booked_time(date))
  29. today = datetime.datetime.now()
  30. if date >= datetime.datetime.strftime(today, '%Y-%m-%d'):
  31. if len(booked) == 0:
  32. await BookingState.start.set()
  33. await state.update_data(date=to_quotes(date))
  34. await state.update_data(owner=call.from_user.id)
  35. msg = await call.message.edit_text(f"Вы выбрали дату: {date}\n"
  36. f"На этот день мероприятий не запланированно", reply_markup=events_kb())
  37. await asyncio.sleep(30)
  38. await msg.delete()
  39. else:
  40. await BookingState.start.set()
  41. await state.update_data(date=to_quotes(date))
  42. await state.update_data(owner=call.from_user.id)
  43. msg = await call.message.edit_text(f"Вы выбрали дату: {date}\n\n"
  44. f"Занятое время\n\n"
  45. f"{beauty_booked_time(sorted(booked, key=lambda t: t['e_start'], reverse=False))}",
  46. reply_markup=events_kb())
  47. await asyncio.sleep(60)
  48. await msg.delete()
  49. else:
  50. msg = await call.message.answer("Нельзя выбрать дату позже сегодняшней")
  51. await asyncio.sleep(5)
  52. await msg.delete()
  53. async def edit_date(call: types.CallbackQuery, state: FSMContext):
  54. msg = await call.message.edit_text(f"выберите дату чтобы увидеть список мероприятий\n\n"
  55. f"Так же календарь мероприятий можно посмотреть в "
  56. f"<a href=moodle.tomtit-tomsk.ru>Moodle</a>\n\n"
  57. f"Сегодняшняя дата <b>{make_date()}</b>", reply_markup=make_calendar())
  58. await call.message.delete()
  59. await state.finish()
  60. await asyncio.sleep(30)
  61. await msg.delete()
  62. async def booking_date(call: types.CallbackQuery):
  63. msg = await call.message.answer("Введите диапазон времени\n"
  64. "Возможные форматы\n\n"
  65. "13.00 15.30\n"
  66. "13.00-15.30\n"
  67. "13:00 15:30\n"
  68. "13.00-15.30\n", reply_markup=cancel_booking())
  69. await BookingState.time.set()
  70. await asyncio.sleep(20)
  71. await msg.delete()
  72. async def get_time(message: types.Message, state: FSMContext):
  73. # Парсим то что ввел пользователь
  74. time = normalize_time(message.text)
  75. await message.delete()
  76. # Забираем текущую дату
  77. date = await state.get_data()
  78. # Проверяем валидность времени
  79. if time_validator(message.text):
  80. # Проверяем пересечения
  81. if not check_overlap(time[0], time[1], date['date']):
  82. msg = await message.answer("Указанное время пеерсекается")
  83. await asyncio.sleep(5)
  84. await msg.delete()
  85. else:
  86. await state.update_data(t_start=time[0])
  87. await state.update_data(t_end=time[1])
  88. await BookingState.description.set()
  89. msg = await message.answer("Введите краткое описание мероприятия", reply_markup=cancel_booking())
  90. await asyncio.sleep(10)
  91. await msg.delete()
  92. else:
  93. msg = await message.answer("Неверный формат времени")
  94. await asyncio.sleep(5)
  95. await msg.delete()
  96. async def send_event(message: types.Message, state: FSMContext):
  97. db = database.Database()
  98. if len(message.text) > 100:
  99. msg = await message.answer("Описание слишком длинное")
  100. await asyncio.sleep(5)
  101. await msg.delete()
  102. await message.delete()
  103. else:
  104. await state.update_data(description=message.text)
  105. await state.update_data(approved=0)
  106. data = await state.get_data()
  107. await message.delete()
  108. msg = await message.answer("Заявка принята", reply_markup=main_kb)
  109. await asyncio.sleep(5)
  110. await msg.delete()
  111. await state.finish()
  112. db.sql_query_send(sql.sql_send_event(data))
  113. await new_event()
  114. def events_register(dp: Dispatcher):
  115. dp.register_message_handler(make_event, text="🎯 Запланировать мероприятие")
  116. dp.register_callback_query_handler(select_date, text_startswith='date_')
  117. dp.register_callback_query_handler(edit_date, text=['change', 'cancel_booking'], state=[BookingState.start,
  118. BookingState.time,
  119. BookingState.description])
  120. dp.register_callback_query_handler(booking_date, text='booking', state=BookingState.start)
  121. dp.register_message_handler(get_time, state=BookingState.time)
  122. dp.register_message_handler(send_event, state=BookingState.description)