make_event.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import asyncio
  2. import calendar
  3. from datetime import date, datetime
  4. from aiogram import types, Dispatcher
  5. from aiogram.dispatcher.storage import FSMContext
  6. from bot import database, sql
  7. from bot.functions import make_date, time_validator, normalize_time, to_quotes, check_overlap, beauty_booked_time
  8. from bot.keyboards import make_calendar, events_kb, cancel_booking, main_kb
  9. from bot.notifications import new_event
  10. from bot.states import BookingState
  11. async def make_event(call: types.CallbackQuery):
  12. today = date.today()
  13. month = today.month
  14. days_in_month = calendar.monthrange(today.year, month)[1]
  15. db = database.Database()
  16. text = (f"выберите дату чтобы увидеть список мероприятий\n\n"
  17. f"Так же календарь мероприятий можно посмотреть в "
  18. f"<a href=moodle.tomtit-tomsk.ru>Moodle</a>\n\n"
  19. f"Сегодняшняя дата <b>{make_date()}</b>")
  20. await call.message.edit_text(text, reply_markup=make_calendar(month,
  21. days_in_month,
  22. f"month_prev:{month}",
  23. f"month_next:{month}"))
  24. async def select_date(call: types.CallbackQuery, state: FSMContext):
  25. db = database.Database()
  26. username = db.sql_fetchone(f"select name from user_table where tg_id = {call.from_user.id}")
  27. await state.update_data(username=username)
  28. date = call.data.split("_")[1]
  29. booked = db.sql_fetchall(sql.sql_booked_time(date))
  30. today = datetime.strftime(datetime.today(), '%Y-%m-%d')
  31. t_day = today.split("-")[2]
  32. t_month = today.split("-")[1]
  33. if int(date.split("-")[1]) == int(t_month):
  34. if int(date.split("-")[2]) >= int(t_day):
  35. if len(booked) == 0:
  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"
  40. f"На этот день мероприятий не запланированно", reply_markup=events_kb())
  41. else:
  42. await BookingState.start.set()
  43. await state.update_data(date=to_quotes(date))
  44. await state.update_data(owner=call.from_user.id)
  45. await call.message.edit_text(f"Вы выбрали дату: {date}\n\n"
  46. f"Занятое время\n\n"
  47. f"{beauty_booked_time(sorted(booked, key=lambda t: t['e_start'], reverse=False))}",
  48. reply_markup=events_kb())
  49. else:
  50. msg = await call.message.answer("Нельзя выбрать дату позже сегодняшней")
  51. await asyncio.sleep(5)
  52. await msg.delete()
  53. elif int(date.split("-")[1]) > int(t_month):
  54. if len(booked) == 0:
  55. await BookingState.start.set()
  56. await state.update_data(date=to_quotes(date))
  57. await state.update_data(owner=call.from_user.id)
  58. await call.message.edit_text(f"Вы выбрали дату: {date}\n"
  59. f"На этот день мероприятий не запланированно", reply_markup=events_kb())
  60. else:
  61. await BookingState.start.set()
  62. await state.update_data(date=to_quotes(date))
  63. await state.update_data(owner=call.from_user.id)
  64. await call.message.edit_text(f"Вы выбрали дату: {date}\n\n"
  65. f"Занятое время\n\n"
  66. f"{beauty_booked_time(sorted(booked, key=lambda t: t['e_start'], reverse=False))}",
  67. reply_markup=events_kb())
  68. else:
  69. msg = await call.message.answer("Нельзя выбрать дату позже сегодняшней")
  70. await asyncio.sleep(5)
  71. await msg.delete()
  72. async def edit_date(call: types.CallbackQuery, state: FSMContext):
  73. await call.message.edit_text(f"🤖Вас приветствует бот 405 кабинета🤖\n"
  74. f"Я помогу Вам запланировать мероприятие.\n\n"
  75. f"Вот что можно сделать:\n"
  76. f"<b>Запланировать мероприятие</b>\n"
  77. f"Планирование мероприятия\n\n"
  78. f"<b>Мои события</b>\n"
  79. f"События запланированные Вами\n\n"
  80. f"<b>Все события</b>\n"
  81. f"События всех пользователей\n"
  82. f"с выборкой по интервалам\n\n"
  83. f"Если есть пожелания или замечания\n"
  84. f"Можете обратиться к @FeldwebelWillman\n"
  85. f"Или воспользовтаься обратной связью /feedback",
  86. reply_markup=main_kb())
  87. await state.finish()
  88. async def booking_date(call: types.CallbackQuery):
  89. await call.message.edit_text("Введите диапазон времени\n"
  90. "Возможные форматы\n\n"
  91. "13.00 15.30\n"
  92. "8.00-9.00\n"
  93. "10:30 14:00\n"
  94. "11.50-12.30\n", reply_markup=cancel_booking())
  95. await BookingState.time.set()
  96. async def get_time(message: types.Message, state: FSMContext):
  97. # Парсим то что ввел пользователь
  98. time = normalize_time(message.text)
  99. await message.delete()
  100. date = await state.get_data()
  101. # Проверяем валидность времени
  102. if time_validator(message.text):
  103. # Проверяем что старт не позже конца
  104. if time[0] > time[1]:
  105. await message.answer("Начало не может быть раньше конца")
  106. elif not check_overlap(time[0], time[1], date['date']):
  107. await message.answer("Указанное время пеерсекается")
  108. else:
  109. await state.update_data(t_start=time[0])
  110. await state.update_data(t_end=time[1])
  111. await BookingState.description.set()
  112. await message.answer("Введите краткое описание мероприятия", reply_markup=cancel_booking())
  113. else:
  114. await message.answer("Неверный формат времени")
  115. async def send_event(message: types.Message, state: FSMContext):
  116. db = database.Database()
  117. if len(message.text) > 100:
  118. await message.answer("Описание слишком длинное")
  119. else:
  120. await state.update_data(description=message.text)
  121. await state.update_data(approved=0)
  122. data = await state.get_data()
  123. db.sql_query_send(sql.sql_send_event(data))
  124. await message.delete()
  125. await message.answer("Заявка принята\n"
  126. "Уведомлять администраторов не требуется\n"
  127. "они получат оповощение автоматически\n"
  128. "Для новой заявки используйте /start")
  129. event_id = db.sql_fetchone('select max(id) from events_table')
  130. await state.update_data(id=event_id)
  131. data = await state.get_data()
  132. await state.finish()
  133. await new_event(data)
  134. def register(dp: Dispatcher):
  135. dp.register_callback_query_handler(make_event, text='plain')
  136. dp.register_callback_query_handler(select_date, text_startswith='date_')
  137. dp.register_callback_query_handler(edit_date, text='cancel_booking')
  138. dp.register_callback_query_handler(booking_date, text='booking', state=BookingState.start)
  139. dp.register_callback_query_handler(edit_date, text=['change', 'cancel_booking'], state=[BookingState.start,
  140. BookingState.time,
  141. BookingState.description])
  142. dp.register_message_handler(get_time, state=BookingState.time)
  143. dp.register_message_handler(send_event, state=BookingState.description)