From 6158af655cd09182594bb1edef6dab74d1225add Mon Sep 17 00:00:00 2001 From: far-galaxy Date: Sat, 4 Feb 2023 18:07:19 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE:=20=D0=B1=D0=BB=D0=B8=D0=B6=D0=B0=D0=B9=D1=88?= =?UTF-8?q?=D0=B0=D1=8F=20=D0=BF=D0=B0=D1=80=D0=B0=20=D0=98=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE:=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D0=BE=D0=BC=D0=BA=D0=B0=20MySQL=20=D0=BF=D0=BE=D1=81?= =?UTF-8?q?=D0=BB=D0=B5=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D0=91=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot.py | 24 +++++++--- database/a_sql.py | 4 +- database/shedule.py | 102 +++++++++++++++++++++++++++++++++++++++++-- database/shedule.sql | 13 ++++-- locale/ru.ini | 5 ++- 5 files changed, 134 insertions(+), 14 deletions(-) diff --git a/bot.py b/bot.py index c4a5f96..e6c519d 100644 --- a/bot.py +++ b/bot.py @@ -82,7 +82,7 @@ class Bot: tgId = query.from_user.id if 'conf' in tag: - self.confirmGroup(query, tag) + self.confirmGroup(query, tag, l9Id) if update.message: query = update.message @@ -96,6 +96,16 @@ class Bot: elif tag == 'add': self.addGroup(l9Id, query) + elif query.text == 'Главное меню': + near = self.shedule.nearLesson(query.date, l9Id) + if near != None: + # TODO: прописать другие случаи + self.tg.sendMessage( + tgId, + f"{loc['shedule']['near']}:\n{near}", + reply_markup=Keyboard.menu(), + ) + elif query.text == 'Отмена': # TODO: прописать отмену при отсутствующих группах self.tg_db.changeTag(tgId, 'ready') @@ -177,14 +187,18 @@ class Bot: reply_markup=Keyboard.cancel(), ) - def confirmGroup(self, query: telegram.CallbackQuery, tag: str): + def confirmGroup( + self, query: telegram.CallbackQuery, tag: str, l9Id: str + ): """Процесс подтверждения группы и загрузка расписания""" tgId = query.from_user.id self.answer(query) if query.data == 'yes': self.edit(query, loc['group']['loading']) - self.shedule.loadShedule( - tag[5:], query.message.date, config['first_week'] + self.shedule.loadShedule(tag[5:], query.message.date) + self.shedule.db.insert( + 'groups_users', + {'l9Id': l9Id, 'groupId': tag[5:]}, ) self.edit(query, loc['group']['loaded'], Keyboard.menu()) self.tg_db.changeTag(tgId, 'ready') @@ -203,7 +217,7 @@ if __name__ == "__main__": config = loadJSON("config") l9lk = L9_DB(**config['sql']) tg_db = TG_DB(l9lk) - shedule = Shedule_DB(l9lk) + shedule = Shedule_DB(l9lk, config['first_week']) bot = Bot( config['tg']['token'], l9lk, tg_db, shedule, config['tg']['limit'] ) diff --git a/database/a_sql.py b/database/a_sql.py index c173c9a..20ba557 100644 --- a/database/a_sql.py +++ b/database/a_sql.py @@ -42,8 +42,8 @@ class Database: """ with open(f'database/{filename}.sql', encoding='utf-8') as f: - query = f.read() - return self.execute(query, commit).fetchall() + query = f.read().split('\n\n\n') + return [self.execute(i, commit) for i in query] def initDatabase(self, name: str): """Создать базу данных, если таковая отсутствует, diff --git a/database/shedule.py b/database/shedule.py index 924e3b6..79085c0 100644 --- a/database/shedule.py +++ b/database/shedule.py @@ -8,9 +8,10 @@ import datetime class Shedule_DB: """Класс взаимодействия с базой расписания""" - def __init__(self, l9lk: L9_DB): + def __init__(self, l9lk: L9_DB, first_week): self.l9lk = l9lk self.db = l9lk.db + self.first_week = first_week self.db.executeFile('shedule') def checkGroupExists(self, groupName: str, l9Id: str) -> str: @@ -62,8 +63,9 @@ class Shedule_DB: else: return 'Empty' - def loadShedule(self, groupId, date, first_week): - week = date.isocalendar()[1] - first_week + def loadShedule(self, groupId: str, date: datetime.datetime): + """Загрузка расписания""" + week = date.isocalendar()[1] - self.first_week self.db.execute( f'DELETE FROM `lessons` WHERE WEEK(`begin`, 1) = {date.isocalendar()[1]} AND groupId = {groupId};' @@ -81,3 +83,97 @@ class Shedule_DB: for l in lessons: self.l9lk.db.insert('lessons', l) + + def getGroups(self, l9Id: str): + groups = self.db.execute( + ( + f'SELECT g.groupId, groupName FROM ' + f'`groups_users` AS gu JOIN `groups` AS g ' + 'ON gu.groupId=g.groupId WHERE ' + f'l9Id = {l9Id}' + ) + ).fetchall() + + return groups if groups != [] else None + + def getLesson(self, lessonId): + icons = {'other': '📙', 'lect': '📗', 'lab': '📘', 'pract': '📕'} + + lesson = self.db.get('lessons', f'lessonId = {lessonId}') + + if lesson != []: + lesson = lesson[0] + + teacher = None + if lesson[12] != None: + teacher = self.db.get( + 'teachers', f'teacherId = {lesson[12]}' + ) + + if teacher != None and teacher != []: + info = teacher[0] + teacher = f"{info[1]} {info[2][0]}.{info[3][0]}." + + json_lesson = { + 'numInDay': lesson[5], + 'type': icons[lesson[7]], + 'name': lesson[8], + 'place': lesson[13], + 'teacher': teacher, + 'add_info': lesson[14], + 'begin': lesson[10], + 'end': lesson[11], + } + + return json_lesson + + else: + return {'empty'} + + def strLesson(self, lessonIds): + lesson = [self.getLesson(i) for i in lessonIds] + begin = lesson[0]['begin'] + end = lesson[0]['end'] + text = "\n📆 %02i:%02i - %02i:%02i" % ( + begin.hour, + begin.minute, + end.hour, + end.minute, + ) + + for l in lesson: + add_info = "" if l['add_info'] == None else "\n" + l['add_info'] + teacher = "" if l['teacher'] == None else "\n👤 " + l['teacher'] + place = "" if l['place'] == None else f"\n🧭 {l['place']}" + text += f"\n{l['type']} {l['name']}{place}{teacher}{add_info}\n" + return text + + def nearLesson(self, date: datetime.datetime, l9Id: str, retry=False): + str_time = date.isoformat(sep=' ') + groupIds = self.getGroups(l9Id) + + if groupIds != None: + second_gr = ( + f' OR groupId = {groupIds[1][0]}' + if len(groupIds) == 2 + else '' + ) + lessonId = self.db.get( + 'lessons', + f"(groupId = {groupIds[0][0]}{second_gr}) AND `end` > '{str_time}' " + 'ORDER BY `begin` LIMIT 2', + ['lessonId, begin'], + ) + + if lessonId != []: + if len(lessonId) == 2 and lessonId[0][1] == lessonId[1][1]: + return self.strLesson([lessonId[0][0], lessonId[1][0]]) + else: + return self.strLesson([lessonId[0][0]]) + + elif not retry: + for groupId in [i for i in groupIds if i[0] > 1000]: + self.loadShedule( + groupId[0], date + datetime.timedelta(days=7) + ) + return self.nearLesson(date, l9Id, retry=True) diff --git a/database/shedule.sql b/database/shedule.sql index 70afc7b..c424e61 100644 --- a/database/shedule.sql +++ b/database/shedule.sql @@ -43,7 +43,8 @@ CREATE TABLE IF NOT EXISTS `groups_users` ( CONSTRAINT `gr_gu` FOREIGN KEY (`groupId`) REFERENCES `groups` (`groupId`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `l9_gu` FOREIGN KEY (`l9Id`) REFERENCES `users` (`l9Id`) ON DELETE CASCADE ON UPDATE CASCADE ); - + + -- Преподаватели CREATE TABLE IF NOT EXISTS `teachers` ( `teacherId` bigint NOT NULL, @@ -57,6 +58,7 @@ CREATE TABLE IF NOT EXISTS `teachers` ( PRIMARY KEY (`teacherId`) ); + -- Занятия CREATE TABLE IF NOT EXISTS `lessons` ( `lessonId` bigint NOT NULL AUTO_INCREMENT, @@ -73,10 +75,15 @@ CREATE TABLE IF NOT EXISTS `lessons` ( -- '0' - занятие НЕ отменено -- '`l9Id`' - занятие отменено пользователем - `migrated` bigint DEFAULT '0', - -- Отметка, является ли занятие перенесённым + `migratedTo` bigint DEFAULT '0', + -- Отметка, является ли занятие перенесённым КУДА-ТО -- '0' - занятие НЕ перенесено -- '`lessonId`' - занятие перенесено на другое время + + `migratedFrom` bigint DEFAULT '0', + -- Отметка, является ли занятие перенесённым ОТКУДА-ТО + -- '0' - занятие НЕ перенесено + -- '`lessonId`' - занятие перенесено c другой пары `numInDay` int DEFAULT '1', -- Порядковый номер занятия в текущем дне diff --git a/locale/ru.ini b/locale/ru.ini index ec6ab8b..d5c286a 100644 --- a/locale/ru.ini +++ b/locale/ru.ini @@ -28,4 +28,7 @@ loading=Загружаю расписание... loaded=Расписание загружено! -nogroup=Возможно, ты написал не ту группу, попробуй снова \ No newline at end of file +nogroup=Возможно, ты написал не ту группу, попробуй снова + +[shedule] +near=Ближайшая пара \ No newline at end of file