فهرست منبع

Испарвлен нормализатор времени. мелкие исправления

vmshay 2 سال پیش
والد
کامیت
3215aa8314
5فایلهای تغییر یافته به همراه59 افزوده شده و 113 حذف شده
  1. 20 30
      bot/functions.py
  2. 2 2
      bot/keyboards.py
  3. 9 55
      draft.py
  4. 0 4
      handlers/admin/manage_users.py
  5. 28 22
      handlers/user/make_events.py

+ 20 - 30
bot/functions.py

@@ -2,7 +2,8 @@ import phonenumbers
 import re
 import datetime
 from datetime import date, timedelta
-from bot.database import Database
+from bot import database
+import intervaltree
 
 
 def validate_phone(number):
@@ -114,38 +115,27 @@ def time_validator(data):
         return False
 
 
-def split_time(data):
+def normalize_time(data):
     if len(data.split(" ")) == 2:
-        return data.replace(".", ":").split(" ")
+        if len(data.split(" ")[0]) == 4:
+            data = "0" + data
+            return data.replace(".", ":").split(" ")
+        else:
+            return data.replace(".", ":").split(" ")
     elif len(data.split("-")) == 2:
-        return data.replace(".", ":").split("-")
+        if len(data.split("-")[0]) == 4:
+            data = "0" + data
+            return data.replace(".", ":").split("-")
+        else:
+            return data.replace(".", ":").split("-")
     else:
         return False
 
 
-def get_time_range(start,finish):
-    db = Database()
-    sql1 = f"SELECT Id,e_end,e_start from events_table where e_date = '2022-10-10'"
-    results = db.sql_fetchall(sql1)
-    # print(results)
-    for res in results:
-        if res['e_start'] < start and res['e_end'] > finish:
-            print(f"Внутри {res['Id']}")
-            break
-        elif res['e_start'] > start and res['e_end'] < finish:
-            print(f"Перекрывает {res['Id']}")
-            break
-        elif start < res['e_end']:
-            print(f"С конца {res['Id']}")
-            print(finish)
-            print(res['e_start'])
-        elif finish > res['e_start']:
-            print(f"С начала {res['Id']}")
-            print(finish)
-            print(res['e_start'])
-
-# print(split_time("1.00-15.30"))
-get_time_range('12:00','13:30')
-#
-#
-# 14:00	16:30
+def check_overlap(start, end, date):
+    it = intervaltree.IntervalTree()
+    db = database.Database()
+    times = db.sql_fetchall(f"select e_start,e_end from events_table where e_date = {date}")
+    for time in times:
+        it.addi(time['e_start'], time['e_end'])
+    return not it.overlaps(start, end)

+ 2 - 2
bot/keyboards.py

@@ -43,8 +43,8 @@ def user_manage_kb(b_accept, b_deny, b_next, b_prev, b_count):
     keyboard = InlineKeyboardMarkup()
     accept_button = InlineKeyboardButton(text="Одобрить", callback_data=b_accept)
     deny_button = InlineKeyboardButton(text="Отклонить", callback_data=b_deny)
-    count_button = InlineKeyboardButton(text=b_count, callback_data="NULL")  # f"{index}/{len(data)}"
-    next_button = InlineKeyboardButton(text="Далее", callback_data=b_next)   # f"next:0"
+    count_button = InlineKeyboardButton(text=b_count, callback_data="NULL")
+    next_button = InlineKeyboardButton(text="Далее", callback_data=b_next)
     prev_button = InlineKeyboardButton(text="Назад", callback_data=b_prev)
 
     keyboard.add(accept_button, deny_button)

+ 9 - 55
draft.py

@@ -1,58 +1,12 @@
-# async def user_manage(message: types.Message):
-#     if not sql_check_user(f"select tg_id from user_table where tg_id ={message.from_user.id}") or \
-#             not sql_simple_check(f"select approved from user_table where tg_id={message.from_user.id}", "approved"):
-#         await message.delete()
-#         await message.answer("Команды станут доступны после регистрации", reply_markup=register_kb)
-#     elif not sql_simple_check(f'select admin from user_table where tg_id = {message.from_user.id}', "admin"):
-#         await message.answer("Доступ только для администраторов", reply_markup=main_kb)
-#     else:
-#         await message.answer(f"Управление пользователями\n\n"
-#                              f"Здесь вы можете управлять заявками на регистрацию\n\n")
-#         if not sql_check_user(f"select name,phone from user_table where approved = '0'"):
-#             await message.answer("Нет заявок на регистрацию")
-#         else:
-#             data = sql_parse_users(f"select id,name,phone from user_table where approved = '0'")
-#             await message.answer(f"Заявки на регистрацию")
-#            await message.answer(" ".join(sql_parse_users(f"select id,name,phone"
-#                                                          f"from user_table"
-#                                                          f"where approved = '0'")))
-#             await message.answer(''.join(data[:1]), reply_markup=kb_user_manage())
-
-
-# @dp.callback_query_handler()
-# async def select_date(call: types.CallbackQuery):
-#     await bot.answer_callback_query(call.id)
-#     await bot.send_message(call.message.chat.id, "Вы выбрали " + call.data)
-
-        # events = db.sql_parse_all_events(f"select events_table.description, user_table.name, events_table.dat from events_table inner join user_table on events_table.owner = user_table.tg_id")
-
-
-#        await message.answer("Список всех событий")
-#        for event in events:
-#           await message.answer(beauty_all_events(event))
-# {'date': '2022-10-9', 'owner': 338836490, 't_start': '13.00', 't_end': '15.30', 'description': 'sdlf;sdlf', 'approved': 0}
-#
-# def sql_fetchone(self, sql: str):
-#     self.execute(sql)
-#     response = self.fetchone()
-#     if response is None:
-#         return False
-#     else:
-#         for v in response.values():
-#             return v
-#
-#
-# def sql_parse_users(self, sql: str):
-#     self.execute(sql)
-#     result_set = self.fetchall()
-#     users_list = []
-#     if len(result_set) == 0:
-#         return False
-#     elif len(result_set) > 0:
-#         for row in result_set:
-#             users_data = {"ID": row['id'], "ФИО": row['name'], "Номер телефона": row['phone']}
-#             users_list.append(users_data)
-#         return users_list
+import intervaltree
 
+it = intervaltree.IntervalTree()
+it.addi('08:00', '11:00')
+it.addi('16:40', '17:50')
+it.addi('14:00', '16:30')
 
+print(f"Одно значение: {it.overlaps('10:01', '14:00')}")
+print(f"Перекрытие интервала: {it.overlaps('07:00', '12:00')}")
+print(f"Внутри интервала: {it.overlaps('15:00', '15:30')}")
+print(f"Пересекает: {it.overlaps('12:00', '13:00')}")
 

+ 0 - 4
handlers/admin/manage_users.py

@@ -45,7 +45,6 @@ async def prev_user_page(call: types.CallbackQuery):
     db = database.Database()
     data = db.sql_parse_users("select id,name,phone from user_table where approved = '0'")
     index = int(call.data.split(":")[1])-1
-    # print(f"prev_index{index}")
     if not data:
         await call.message.answer('Заявки на регистрацию отсутствуют')
     elif index < 0:
@@ -63,10 +62,7 @@ async def prev_user_page(call: types.CallbackQuery):
 async def accept_user(call: types.CallbackQuery):
     db = database.Database()
     data = db.sql_parse_users("select id,name,phone from user_table where approved = '0'")
-    # data = db.sql_parse_users("select id,name,phone from user_table where approved = '0'")
     index = int(call.message.reply_markup.inline_keyboard[1][1].text.split("/")[0])-1
-    # print(index)
-
 
     if len(data) == 1:
         user_id = data[index]['ID']

+ 28 - 22
handlers/user/make_events.py

@@ -1,7 +1,7 @@
 from aiogram import types, Dispatcher
 from bot import database, sql
 from bot.keyboards import register_kb, make_calendar, events_kb, cancel_booking, main_kb
-from bot.functions import make_date, time_validator, split_time, to_quotes
+from bot.functions import make_date, time_validator, normalize_time, to_quotes, check_overlap
 from handlers.user.states import BookingState
 from aiogram.dispatcher.storage import FSMContext
 
@@ -24,21 +24,20 @@ async def make_event(message: types.message):
 
 async def select_date(call: types.CallbackQuery, state: FSMContext):
     db = database.Database()
-    print(call.data)
     date = call.data.split("_")[1]
-
-    booked = db.sql_fetchall(f"select events_table.e_start, events_table.e_end from events_table WHERE e_date = {to_quotes(date)}")
+    booked = db.sql_fetchall(
+        f"select events_table.e_start, events_table.e_end from events_table WHERE e_date = {to_quotes(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("На этот день мероприятий не заплпнированно", reply_markup=events_kb())
+        await call.message.edit_text(f"Вы выбрали дату: {date}\n"
+                                     f"На этот день мероприятий не заплпнированно", reply_markup=events_kb())
     else:
         await call.message.edit_text(sorted(booked, key=lambda t: t['e_start'], reverse=True), reply_markup=events_kb())
 
 
 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"
@@ -53,20 +52,24 @@ async def booking_date(call: types.CallbackQuery):
                                  "13.00-15.30\n"
                                  "13:00 15:30\n"
                                  "13.00-15.30\n", reply_markup=cancel_booking())
-    # TODO: Проверка на занятость
     await BookingState.time.set()
 
 
 async def get_date(message: types.Message, state: FSMContext):
+    # Парсим то что ввел пользователь
+    time = normalize_time(message.text)
+    # Забираем текущую дату
+    date = await state.get_data()
+    # Проверяем валидность времени
     if time_validator(message.text):
-        db = database.Database()
-        time = split_time(message.text)
-        await state.update_data(t_start=time[0])
-        await state.update_data(t_end=time[1])
-        sql_data = db.sql_fetchall(sql.sql_time_range(time))
-        print(len(sql_data))
-        await message.answer("Введите краткое описание мероприятия", reply_markup=cancel_booking())
-        await BookingState.description.set()
+        # Проверяем пересечения
+        if not check_overlap(time[0], time[1], date['date']):
+            await message.answer("Указанное время пеерсекается")
+        else:
+            await state.update_data(t_start=time[0])
+            await state.update_data(t_end=time[1])
+            await BookingState.description.set()
+            await message.answer("Введите краткое описание мероприятия", reply_markup=cancel_booking())
     else:
         await message.answer("Неверный формат времени")
 
@@ -75,13 +78,16 @@ async def get_date(message: types.Message, state: FSMContext):
 
 async def send_event(message: types.Message, state: FSMContext):
     db = database.Database()
-    await state.update_data(description=message.text)
-    await state.update_data(approved=0)
-    data = await state.get_data()
-    await message.answer("Заявка принята", reply_markup=main_kb)
-    await state.finish()
-    await message.answer(data)
-    db.sql_query_send(sql.sql_send_event(data))
+    if len(message.text) > 100:
+        await message.answer("Описание слишком длинное")
+    else:
+        await state.update_data(description=message.text)
+        await state.update_data(approved=0)
+        data = await state.get_data()
+        await message.answer("Заявка принята", reply_markup=main_kb)
+        await state.finish()
+        await message.answer(data)
+        db.sql_query_send(sql.sql_send_event(data))
 
 
 def events_register(dp: Dispatcher):