diff --git a/1.jsob b/1.jsob new file mode 100644 index 0000000..f2c7c1d --- /dev/null +++ b/1.jsob @@ -0,0 +1 @@ +{"title": "\u0417\u0430\u043c\u0456\u043d\u0438 \u0434\u043e \u0440\u043e\u0437\u043a\u043b\u0430\u0434\u0443", "body": {"content": [{"endIndex": 1, "sectionBreak": {"sectionStyle": {"columnSeparatorStyle": "NONE", "contentDirection": "LEFT_TO_RIGHT", "sectionType": "CONTINUOUS"}}}, {"startIndex": 1, "endIndex": 20, "paragraph": {"elements": [{"startIndex": 1, "endIndex": 20, "textRun": {"content": "\u0417\u0430\u043c\u0456\u043d\u0438 \u0434\u043e \u0440\u043e\u0437\u043a\u043b\u0430\u0434\u0443\n", "textStyle": {"bold": true, "backgroundColor": {"color": {"rgbColor": {"red": 1, "green": 1, "blue": 1}}}, "fontSize": {"magnitude": 20, "unit": "PT"}, "weightedFontFamily": {"fontFamily": "Times New Roman", "weight": 400}}}}], "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "alignment": "CENTER", "lineSpacing": 100, "direction": "LEFT_TO_RIGHT", "spaceAbove": {"magnitude": 12, "unit": "PT"}, "indentFirstLine": {"unit": "PT"}, "indentStart": {"unit": "PT"}}}}, {"startIndex": 20, "endIndex": 22, "paragraph": {"elements": [{"startIndex": 20, "endIndex": 21, "inlineObjectElement": {"inlineObjectId": "kix.x5vm3f73wn5o", "textStyle": {"bold": true, "backgroundColor": {"color": {"rgbColor": {"red": 1, "green": 1, "blue": 1}}}, "fontSize": {"magnitude": 20, "unit": "PT"}, "weightedFontFamily": {"fontFamily": "Times New Roman", "weight": 400}}}}, {"startIndex": 21, "endIndex": 22, "textRun": {"content": "\n", "textStyle": {"bold": true, "backgroundColor": {"color": {"rgbColor": {"red": 1, "green": 1, "blue": 1}}}, "fontSize": {"magnitude": 20, "unit": "PT"}, "weightedFontFamily": {"fontFamily": "Times New Roman", "weight": 400}}}}], "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "alignment": "CENTER", "lineSpacing": 100, "direction": "LEFT_TO_RIGHT", "spaceAbove": {"magnitude": 12, "unit": "PT"}, "indentFirstLine": {"unit": "PT"}, "indentStart": {"unit": "PT"}}}}]}, "headers": {"kix.6vee0g5srhfm": {"headerId": "kix.6vee0g5srhfm", "content": [{"endIndex": 1, "paragraph": {"elements": [{"endIndex": 1, "textRun": {"content": "\n", "textStyle": {"fontSize": {"magnitude": 12, "unit": "PT"}}}}], "paragraphStyle": {"headingId": "h.u6ln6uwnxj1m", "namedStyleType": "TITLE", "alignment": "CENTER", "lineSpacing": 100, "direction": "LEFT_TO_RIGHT", "spaceAbove": {"magnitude": 12, "unit": "PT"}, "indentFirstLine": {"magnitude": 14.173228346456689, "unit": "PT"}, "indentStart": {"magnitude": 85.03937007874016, "unit": "PT"}}}}]}, "kix.i6h67293cr5": {"headerId": "kix.i6h67293cr5", "content": [{"endIndex": 1, "paragraph": {"elements": [{"endIndex": 1, "textRun": {"content": "\n", "textStyle": {}}}], "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "pageBreakBefore": false}}}]}}, "footers": {"kix.vzzvlgoavtbc": {"footerId": "kix.vzzvlgoavtbc", "content": [{"endIndex": 1, "paragraph": {"elements": [{"endIndex": 1, "textRun": {"content": "\n", "textStyle": {}}}], "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "pageBreakBefore": false}}}]}}, "documentStyle": {"background": {"color": {}}, "defaultHeaderId": "kix.6vee0g5srhfm", "firstPageHeaderId": "kix.i6h67293cr5", "firstPageFooterId": "kix.vzzvlgoavtbc", "pageNumberStart": 1, "marginTop": {"magnitude": 72, "unit": "PT"}, "marginBottom": {"magnitude": 72, "unit": "PT"}, "marginRight": {"magnitude": 36, "unit": "PT"}, "marginLeft": {"magnitude": 63.75, "unit": "PT"}, "pageSize": {"height": {"magnitude": 841.8897637795277, "unit": "PT"}, "width": {"magnitude": 595.2755905511812, "unit": "PT"}}, "marginHeader": {"magnitude": 36, "unit": "PT"}, "marginFooter": {"magnitude": 36, "unit": "PT"}}, "namedStyles": {"styles": [{"namedStyleType": "NORMAL_TEXT", "textStyle": {"bold": false, "italic": false, "underline": false, "strikethrough": false, "smallCaps": false, "backgroundColor": {}, "foregroundColor": {"color": {"rgbColor": {}}}, "fontSize": {"magnitude": 11, "unit": "PT"}, "weightedFontFamily": {"fontFamily": "Arial", "weight": 400}, "baselineOffset": "NONE"}, "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "alignment": "START", "lineSpacing": 115, "direction": "LEFT_TO_RIGHT", "spacingMode": "NEVER_COLLAPSE", "spaceAbove": {"unit": "PT"}, "spaceBelow": {"unit": "PT"}, "borderBetween": {"color": {}, "width": {"unit": "PT"}, "padding": {"unit": "PT"}, "dashStyle": "SOLID"}, "borderTop": {"color": {}, "width": {"unit": "PT"}, "padding": {"unit": "PT"}, "dashStyle": "SOLID"}, "borderBottom": {"color": {}, "width": {"unit": "PT"}, "padding": {"unit": "PT"}, "dashStyle": "SOLID"}, "borderLeft": {"color": {}, "width": {"unit": "PT"}, "padding": {"unit": "PT"}, "dashStyle": "SOLID"}, "borderRight": {"color": {}, "width": {"unit": "PT"}, "padding": {"unit": "PT"}, "dashStyle": "SOLID"}, "indentFirstLine": {"unit": "PT"}, "indentStart": {"unit": "PT"}, "indentEnd": {"unit": "PT"}, "keepLinesTogether": false, "keepWithNext": false, "avoidWidowAndOrphan": true, "shading": {"backgroundColor": {}}, "pageBreakBefore": false}}, {"namedStyleType": "HEADING_1", "textStyle": {"fontSize": {"magnitude": 20, "unit": "PT"}}, "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "spaceAbove": {"magnitude": 20, "unit": "PT"}, "spaceBelow": {"magnitude": 6, "unit": "PT"}, "keepLinesTogether": true, "keepWithNext": true, "pageBreakBefore": false}}, {"namedStyleType": "HEADING_2", "textStyle": {"bold": false, "fontSize": {"magnitude": 16, "unit": "PT"}}, "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "spaceAbove": {"magnitude": 18, "unit": "PT"}, "spaceBelow": {"magnitude": 6, "unit": "PT"}, "keepLinesTogether": true, "keepWithNext": true, "pageBreakBefore": false}}, {"namedStyleType": "HEADING_3", "textStyle": {"bold": false, "foregroundColor": {"color": {"rgbColor": {"red": 0.2627451, "green": 0.2627451, "blue": 0.2627451}}}, "fontSize": {"magnitude": 14, "unit": "PT"}}, "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "spaceAbove": {"magnitude": 16, "unit": "PT"}, "spaceBelow": {"magnitude": 4, "unit": "PT"}, "keepLinesTogether": true, "keepWithNext": true, "pageBreakBefore": false}}, {"namedStyleType": "HEADING_4", "textStyle": {"foregroundColor": {"color": {"rgbColor": {"red": 0.4, "green": 0.4, "blue": 0.4}}}, "fontSize": {"magnitude": 12, "unit": "PT"}}, "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "spaceAbove": {"magnitude": 14, "unit": "PT"}, "spaceBelow": {"magnitude": 4, "unit": "PT"}, "keepLinesTogether": true, "keepWithNext": true, "pageBreakBefore": false}}, {"namedStyleType": "HEADING_5", "textStyle": {"foregroundColor": {"color": {"rgbColor": {"red": 0.4, "green": 0.4, "blue": 0.4}}}, "fontSize": {"magnitude": 11, "unit": "PT"}}, "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "spaceAbove": {"magnitude": 12, "unit": "PT"}, "spaceBelow": {"magnitude": 4, "unit": "PT"}, "keepLinesTogether": true, "keepWithNext": true, "pageBreakBefore": false}}, {"namedStyleType": "HEADING_6", "textStyle": {"italic": true, "foregroundColor": {"color": {"rgbColor": {"red": 0.4, "green": 0.4, "blue": 0.4}}}, "fontSize": {"magnitude": 11, "unit": "PT"}}, "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "spaceAbove": {"magnitude": 12, "unit": "PT"}, "spaceBelow": {"magnitude": 4, "unit": "PT"}, "keepLinesTogether": true, "keepWithNext": true, "pageBreakBefore": false}}, {"namedStyleType": "TITLE", "textStyle": {"fontSize": {"magnitude": 26, "unit": "PT"}}, "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "spaceAbove": {"unit": "PT"}, "spaceBelow": {"magnitude": 3, "unit": "PT"}, "keepLinesTogether": true, "keepWithNext": true, "pageBreakBefore": false}}, {"namedStyleType": "SUBTITLE", "textStyle": {"italic": false, "foregroundColor": {"color": {"rgbColor": {"red": 0.4, "green": 0.4, "blue": 0.4}}}, "fontSize": {"magnitude": 15, "unit": "PT"}, "weightedFontFamily": {"fontFamily": "Arial", "weight": 400}}, "paragraphStyle": {"namedStyleType": "NORMAL_TEXT", "direction": "LEFT_TO_RIGHT", "spaceAbove": {"unit": "PT"}, "spaceBelow": {"magnitude": 16, "unit": "PT"}, "keepLinesTogether": true, "keepWithNext": true, "pageBreakBefore": false}}]}, "lists": {"kix.d3btfm56ji6u": {"listProperties": {"nestingLevels": [{"bulletAlignment": "START", "glyphSymbol": "\u25cf", "glyphFormat": "%0", "indentFirstLine": {"magnitude": 18, "unit": "PT"}, "indentStart": {"magnitude": 36, "unit": "PT"}, "textStyle": {"underline": false}, "startNumber": 1}, {"bulletAlignment": "START", "glyphSymbol": "\u25cb", "glyphFormat": "%1", "indentFirstLine": {"magnitude": 54, "unit": "PT"}, "indentStart": {"magnitude": 72, "unit": "PT"}, "textStyle": {"underline": false}, "startNumber": 1}, {"bulletAlignment": "START", "glyphSymbol": "\u25a0", "glyphFormat": "%2", "indentFirstLine": {"magnitude": 90, "unit": "PT"}, "indentStart": {"magnitude": 108, "unit": "PT"}, "textStyle": {"underline": false}, "startNumber": 1}, {"bulletAlignment": "START", "glyphSymbol": "\u25cf", "glyphFormat": "%3", "indentFirstLine": {"magnitude": 126, "unit": "PT"}, "indentStart": {"magnitude": 144, "unit": "PT"}, "textStyle": {"underline": false}, "startNumber": 1}, {"bulletAlignment": "START", "glyphSymbol": "\u25cb", "glyphFormat": "%4", "indentFirstLine": {"magnitude": 162, "unit": "PT"}, "indentStart": {"magnitude": 180, "unit": "PT"}, "textStyle": {"underline": false}, "startNumber": 1}, {"bulletAlignment": "START", "glyphSymbol": "\u25a0", "glyphFormat": "%5", "indentFirstLine": {"magnitude": 198, "unit": "PT"}, "indentStart": {"magnitude": 216, "unit": "PT"}, "textStyle": {"underline": false}, "startNumber": 1}, {"bulletAlignment": "START", "glyphSymbol": "\u25cf", "glyphFormat": "%6", "indentFirstLine": {"magnitude": 234, "unit": "PT"}, "indentStart": {"magnitude": 252, "unit": "PT"}, "textStyle": {"underline": false}, "startNumber": 1}, {"bulletAlignment": "START", "glyphSymbol": "\u25cb", "glyphFormat": "%7", "indentFirstLine": {"magnitude": 270, "unit": "PT"}, "indentStart": {"magnitude": 288, "unit": "PT"}, "textStyle": {"underline": false}, "startNumber": 1}, {"bulletAlignment": "START", "glyphSymbol": "\u25a0", "glyphFormat": "%8", "indentFirstLine": {"magnitude": 306, "unit": "PT"}, "indentStart": {"magnitude": 324, "unit": "PT"}, "textStyle": {"underline": false}, "startNumber": 1}]}}}, "suggestionsViewMode": "PREVIEW_WITHOUT_SUGGESTIONS", "inlineObjects": {"kix.x5vm3f73wn5o": {"objectId": "kix.x5vm3f73wn5o", "inlineObjectProperties": {"embeddedObject": {"imageProperties": {"contentUri": "https://lh4.googleusercontent.com/V6dX_A92qmmRYdkfOLKTNymjMuY6icJ6vDTmRL8n6HDf5cAgQ7TrDsrYsiBgffyE7Tx8n-tvvkJOq8rFr_Su7tmhhscsFiuL0GWykpAMJjIunDDowK_wc6K8oUBcXfagfEmsnNJtk80dM3xTc_kL2RL2xb2w2txW", "cropProperties": {}}, "embeddedObjectBorder": {"color": {"color": {"rgbColor": {}}}, "width": {"unit": "PT"}, "dashStyle": "SOLID", "propertyState": "NOT_RENDERED"}, "size": {"height": {"magnitude": 452, "unit": "PT"}, "width": {"magnitude": 495.52559055118115, "unit": "PT"}}, "marginTop": {"magnitude": 9, "unit": "PT"}, "marginBottom": {"magnitude": 9, "unit": "PT"}, "marginRight": {"magnitude": 9, "unit": "PT"}, "marginLeft": {"magnitude": 9, "unit": "PT"}}}}}, "documentId": "18FYetZmms7sNCVvjZfLKgJT-RG5xo9NviKXfwdYHIFM"} diff --git a/1.p b/1.p new file mode 100644 index 0000000..1bc77f4 --- /dev/null +++ b/1.p @@ -0,0 +1,117 @@ +diff --git a/engineering_works.py b/engineering_works.py +index a122c3c..ebd6cea 100644 +--- a/engineering_works.py ++++ b/engineering_works.py +@@ -13,11 +13,11 @@ logging.basicConfig( + + + +-WEBAPP_HOST = config.bot("ip") +-WEBAPP_PORT = config.bot("port") ++WEBAPP_HOST = config.ip ++WEBAPP_PORT = config.port + + WEBHOOK_HOST = f'http://{WEBAPP_HOST}:{WEBAPP_PORT}' +-WEBHOOK_PATH = f'/bot{config.bot("token")}/' ++WEBHOOK_PATH = f'/bot{config.token}/' + WEBHOOK_URL = f"{WEBHOOK_HOST}{WEBHOOK_PATH}" + + engeneerings_works = ( +@@ -29,7 +29,7 @@ parse_error = ( + "Бот приостановлен на неопределенный срок!\n" + "Что случилось?\n" + "Администрация коледжа изменила формат файла с google docs на docx(Microsoft Office)\n" +- "Замены вы можете посмотреть тут: https://docs.google.com/document/d/{}".format(config.documentid) ++ "Замены вы можете посмотреть тут: https://docs.google.com/document/d/{}".format("") + ) + + new_year = ( +@@ -48,7 +48,11 @@ september_1 = ("Всіх з 1 вересням, всього найкращог + "Бот буде запущений чуть пізніше, " + "коли заміни будуть публіковаться текстом") + +-send_msg = the_end ++upd_1 = ("Невеликі зміни в боті.\n" ++ "1. Добавлени донати, тепер ви можете підтримати автора бота\n" ++ "2. Добалено звязок з адміністратором") ++ ++send_msg = upd_1 + + async def on_startup(dp): + await bot.set_webhook(url=WEBHOOK_URL) +@@ -81,7 +85,7 @@ async def start(message: types.Message): + ) + + if __name__ == "__main__": +- if config.bot("use_webhook").lower() in ['t', 'true', '1', 'yes', 'y']: ++ if config.use_webhook.lower() in ['t', 'true', '1', 'yes', 'y']: + executor.start_webhook( + dispatcher=dp, + webhook_path=WEBHOOK_PATH, +diff --git a/filters/main.py b/filters/main.py +index 849e6de..7539de0 100644 +--- a/filters/main.py ++++ b/filters/main.py +@@ -28,7 +28,7 @@ class BotAdmin(BoundFilter): + self.admin = admin + + async def check(self, message: types.Message): +- if message.from_user.id in config.admin_user: ++ if message.from_user.id in [int(i) for i in config.admin_users.split(",")]: + return True + else: + await message.answer("Хорошая попытка, но ты не администратор!") +diff --git a/handlers/private/main.py b/handlers/private/main.py +index de03596..370218a 100644 +--- a/handlers/private/main.py ++++ b/handlers/private/main.py +@@ -45,7 +45,7 @@ async def get_replace(message: types.Message, state: FSMContext): + + link = ( + 'Проверьте замены тут' +- .format(config.bot("link")) ++ .format(config.link) + ) + logging.info("User: {user_id} - {username}".format( + user_id=str(message.from_user.id), +@@ -94,7 +94,7 @@ async def get_replace(message: types.Message, state: FSMContext): + async def get_link(message: types.Message): + msg = ( + 'Проверьте замены тут' +- .format(config.bot("link")) ++ .format(config.link) + ) + await bot.send_message( + message.chat.id, +diff --git a/utils/announcements.py b/utils/announcements.py +index f70541e..4e264de 100644 +--- a/utils/announcements.py ++++ b/utils/announcements.py +@@ -1,3 +1,4 @@ ++ + import datetime + import asyncio + import aioschedule as schedule +@@ -15,8 +16,8 @@ async def announce(): + except Exception: + message = "Ошибка обновления данных!" + if config.admin_users.split(',') is not None: +- for user_id in config.admin_users.split(','): +- if user_id in config.exclude: ++ for user_id in [int(i) for i in config.admin_users.split(',')]: ++ if user_id in [int(i) for i in config.exclude.split(",")]: + continue + await dp.bot.send_message(user_id, message) + +diff --git a/utils/bot_commands.py b/utils/bot_commands.py +index b65bc62..3de6ed1 100644 +--- a/utils/bot_commands.py ++++ b/utils/bot_commands.py +@@ -7,6 +7,6 @@ async def set_commands(dp): + types.BotCommand("help", "информация"), + types.BotCommand("link", "получить ссылку на файл"), + types.BotCommand('timetable', "Розклад"), +- types.BotCommand('feedback', "Звязок з адміністратором") ++ types.BotCommand('feedback', "Звязок з адміністратором"), + types.BotCommand("reload", "только для администрации"), + ]) diff --git a/backup/google_parser/requirements.txt b/backup/google_parser/requirements.txt index e6d4123..d689e7c 100644 --- a/backup/google_parser/requirements.txt +++ b/backup/google_parser/requirements.txt @@ -5,5 +5,5 @@ peewee aiogram cryptography pymysqldb -psycopg2 +#psycopg2 aioschedule diff --git a/configs/configure.py b/configs/configure.py index 2569ec0..37f296c 100644 --- a/configs/configure.py +++ b/configs/configure.py @@ -18,11 +18,17 @@ class Configure: for key, value in config.items(section): self.data[section][key] = value - - + config_folder = config.get("Docs_Settings", "Config_folder").rstrip("/") + self.data["documentid"] = config.get("Docs_Settings", 'Document_ID') + self.data["data_file"] = config_folder + "/" + config.get("Docs_Settings", "data_file") + self.data["credentials_file"] = config_folder + "/" + config.get("Docs_Settings", "credentials_file") + self.data["token_file"] = self.config_folder + "/" + self.data['Docs_Settings']['token_file'] + def __getattr__(self, name): + if name in ["documentid", "data_file", "credentials_file", "token_file"]: + return self.data[name] for key in self.data.keys(): if name not in self.data[key]: continue return self.data[key][name] - raise NameError("Config options not found!") +# raise NameError("Config options not found!") diff --git a/configs/timetable/groups.json b/configs/timetable/groups.json index 63e410d..7cf36f0 100644 --- a/configs/timetable/groups.json +++ b/configs/timetable/groups.json @@ -1,11 +1,12 @@ { "1, 121, 12c": "1.jpg", "131, 13c, 141, 14c": "2.jpg", - "3, 411, 42c, 431": "3.jpg", + "3, 421, 42c, 431": "3.jpg", "43c": "4.jpg", "4, 521, 52c, 531": "5.jpg", - "53c, 541, 54c": "6.jpg", - "2, 221, 22c, 231": "7.jpg", - "23c, 241, 24c": "8.jpg", - "411, 421, 431": ["9.jpg","10.jpg"] + "53c": "6.jpg", + "541, 54c": "7.jpg", + "2, 221, 22c, 231": "8.jpg", + "23c, 241, 24c": "9.jpg", + "411, 421, 431": ["10.jpg","11.jpg"] } diff --git a/engineering_works.py b/engineering_works.py index a122c3c..6daa520 100644 --- a/engineering_works.py +++ b/engineering_works.py @@ -13,11 +13,11 @@ logging.basicConfig( -WEBAPP_HOST = config.bot("ip") -WEBAPP_PORT = config.bot("port") +WEBAPP_HOST = config.ip +WEBAPP_PORT = config.port WEBHOOK_HOST = f'http://{WEBAPP_HOST}:{WEBAPP_PORT}' -WEBHOOK_PATH = f'/bot{config.bot("token")}/' +WEBHOOK_PATH = f'/bot{config.token}/' WEBHOOK_URL = f"{WEBHOOK_HOST}{WEBHOOK_PATH}" engeneerings_works = ( @@ -29,7 +29,7 @@ parse_error = ( "Бот приостановлен на неопределенный срок!\n" "Что случилось?\n" "Администрация коледжа изменила формат файла с google docs на docx(Microsoft Office)\n" - "Замены вы можете посмотреть тут: https://docs.google.com/document/d/{}".format(config.documentid) +# "Замены вы можете посмотреть тут: https://docs.google.com/document/d/{}".format(config.documentid) ) new_year = ( @@ -45,10 +45,20 @@ the_end =( ) september_1 = ("Всіх з 1 вересням, всього найкращого!\n" -"Бот буде запущений чуть пізніше, " -"коли заміни будуть публіковаться текстом") +"Бот працює в нормальному режимі!\n" +"Приятного використання!") send_msg = the_end +idea = ( +"Бажаєте предложити ідеї для функціонала бота, або для новошо боту?\n" +"У вас є така можливість, відправляйте свої ідеї в /feedback") +msg = idea + +donate_add = ("На період канікул бот був вимкнутий\n" + "Ви можете зробити донат\n" + f"Оплптити онлайн: {config.payment_link}\n" + f"Переказ на карту: {config.card_number}\n") +msg = september_1 async def on_startup(dp): await bot.set_webhook(url=WEBHOOK_URL) @@ -63,7 +73,7 @@ async def asd(message): if user_id != 1083440854: print(user_id) try: - await bot.send_message(chat_id=user_id, text=send_msg) + await bot.send_message(chat_id=user_id, text=msg) except: pass @@ -77,11 +87,11 @@ async def start(message: types.Message): ) await bot.send_message( message.chat.id, - engeneerings_works + msg ) if __name__ == "__main__": - if config.bot("use_webhook").lower() in ['t', 'true', '1', 'yes', 'y']: + if config.use_webhook.lower() in ['t', 'true', '1', 'yes', 'y']: executor.start_webhook( dispatcher=dp, webhook_path=WEBHOOK_PATH, diff --git a/handlers/groups/main.py b/handlers/groups/main.py index 9fad15b..bb820fc 100644 --- a/handlers/groups/main.py +++ b/handlers/groups/main.py @@ -14,7 +14,7 @@ from database import register @dp.message_handler(ChatTypeFilter(['group', 'supergroup']), commands=['set']) async def set_group(message: types.Message): - if (message.from_user.id not in [admin.user.id for admin in await bot.get_chat_administrators(message.chat.id)]) and (message.from_user.id not in config.admin_user): + if (message.from_user.id not in [admin.user.id for admin in await bot.get_chat_administrators(message.chat.id)]) and (str(message.from_user.id) not in config.admin_users.split(",")): await message.answer("Вы не являетесь администратором чата!") return args = message.text.split() diff --git a/handlers/private/support.py b/handlers/private/support.py index 34a42d7..751ba11 100644 --- a/handlers/private/support.py +++ b/handlers/private/support.py @@ -14,10 +14,11 @@ async def feedback(message: types.Message, state): async def send_admins(message: types.Message, state): await message.copy_to(config.chat_id, reply_markup=await answer_kb(message.from_user.id)) await message.answer("Дякую!") + await state.finish() @dp.message_handler(state="answer_support") async def send_answer(message: types.Message, state): data = await state.get_data() - await message.copy_to(data["u"]) await state.finish() + await message.copy_to(data["u"]) diff --git a/parser/parser.py b/parser/parser.py index 1b11ba8..6db8588 100644 --- a/parser/parser.py +++ b/parser/parser.py @@ -1,65 +1,121 @@ -import base64 +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import os import json -import datetime -from datetime import datetime as dt -import requests -from bs4 import BeautifulSoup +from googleapiclient.discovery import build +from google_auth_oauthlib.flow import InstalledAppFlow +from google.auth.transport.requests import Request +from google.oauth2.credentials import Credentials -try: - from load import config -except ImportError: config = None -try: - from .utils import * -except ImportError: - from utils import * +from load import config +from .utils import Helper + +# If modifying these scopes, delete the file token.json. +SCOPES = ['https://www.googleapis.com/auth/documents.readonly'] + +__all__ = ['docs_parse', 'get_about_replacements'] -headers = { - 'user-agent':( - "Mozilla/5.0 (Windows NT 10.0; WOW64) " - "AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/62.0.3202.9 Safari/537.36" - ) -} - - -def date_parser_helper(days:int, parse:str="%d.%m.20%y"): - return dt.strftime( - dt.now() + - datetime.timedelta(days=days), - parse +def docs_parse() -> None: + creds = None + # The file token.json stores the user's access and refresh tokens, and is + # created automatically when the authorization flow completes for the first + # time. + if os.path.exists(config.token_file): + creds = Credentials.from_authorized_user_file( + config.token_file, + SCOPES ) + # If there are no (valid) credentials available, let the user log in. + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + flow = InstalledAppFlow.from_client_secrets_file( + config.credentials_file, SCOPES) + creds = flow.run_local_server(port=0) + # Save the credentials for the next run + with open(config.token_file, 'w') as token: + token.write(creds.to_json()) + service = build('docs', 'v1', credentials=creds) -def docs_parse(): - - output = { - "data":{}, - "another_teacher":None - } - - page = requests.get(config.link, headers=headers) - page.encoding = 'utf-8' - - soup = BeautifulSoup(page.text, "lxml") - - # Это в идеале нужно переписать... - url = image_parser(soup) - with requests.get(url=url, allow_redirects=True, stream=True) as r: - output['image'] = True - output['date'] = 'невозможно получить!' - output['data']['all'] = base64.b64encode(r.content).decode('utf-8') - + # Retrieve the documents contents from the Docs service. + document = service.documents().get(documentId=config.documentid).execute() + if os.path.exists(config.data_file): + os.remove(config.data_file) with open(config.data_file, 'w') as f: - json.dump(output, f, ensure_ascii=False) + json.dump(document, f, ensure_ascii=False) f.close() -def get_about_replacements() -> dict: +def read_parse_data(): with open(config.data_file, 'r') as f: data = json.loads(f.read()) f.close() return data -docs_parse() \ No newline at end of file + + +def get_about_replacements() -> dict: + helper = Helper() + document = read_parse_data() + info = [] + element = helper.get_table_element() + + try: + count = document['body']["content"][element]["table"]["rows"] + except (IndexError, KeyError): + image, image_bytes = helper.find_image(document) + print(image) + if not image: + element = helper.find_with_table(document) + if element: + count = document['body']["content"][element]["table"]["rows"] + else: + info = helper.find_with_text(document) + + if not image: + date = helper.get_date(document) + + another_teacher = helper.teacher(document) + else: + date, another_teacher = False, None + + if element and (not image): + for c in range(0, count): + more_replaces = (document['body'] + ["content"][element]["table"] + ["tableRows"][c]["tableCells"][1] + ["content"] + ) + replaces = '' + for i in range(0, len(more_replaces)): + replaces += (document['body']["content"][element]["table"] + ["tableRows"][c]["tableCells"][1] + ["content"][i]["paragraph"]["elements"][0] + ["textRun"]["content"].rstrip("\n")) + + info.append( + ( + document['body']["content"][element]["table"] + ["tableRows"][c]["tableCells"][0] + ["content"][0]["paragraph"]["elements"][0] + ["textRun"]["content"].rstrip("\n"), + replaces + ) + ) + + if image: + return { + "image": image, + 'date': date if type(date) != type(False) else "Error" , + 'data': {"all": image_bytes}, + 'another_teacher': another_teacher, + } + return { + 'date': date if type(date) != type(False) else "Error" , + 'data': dict(info), + 'another_teacher': another_teacher, + } diff --git a/parser/utils.py b/parser/utils.py index 4c829dd..0c7721f 100644 --- a/parser/utils.py +++ b/parser/utils.py @@ -1,34 +1,210 @@ -from bs4 import BeautifulSoup -from typing import Any +import os +import datetime +from datetime import datetime as dt -def table_parser(soup: BeautifulSoup, output): - #Date parser - date = (soup.find("main").findAll('span', style="color:black"))[1] - output["date"] = date.text.replace(u'\xa0', u'') +import requests + +from load import config - #Replaces parser - replaces = soup.findAll('tr') - for data in replaces: - - text = ( - data.find("td", valign="top") - .find("span", style="color:black") - .text.replace(u'\xa0', u'') +def date_parser_helper(days:int, parse:str="%d.%m.20%y"): + return dt.strftime( + dt.now() + + datetime.timedelta(days=days), + parse ) - group = ( - data.find("span", style="color:black") - .text.replace(" ", "").replace(u'\xa0', u'')) - output["data"][group] = text - - return output +''' +self.months = { + 1: "січень", + 2: "лютий", + 3: "березень", + 4: "квітень", + 5: "травень", + 6: "червень", + 7: "липень", + 8: "серпень", + 9: "вересень", + 10: "жовтень", + 11: "листопад", + 12: "грудень" +} +''' -def image_parser(soup: BeautifulSoup): - image: Any - extension = ('png', 'jpg') - main = soup.find("main") - for ext in extension: - image = main.select(f'img[src$=".{ext}"]') - if image: - return image[0]['src'] +headers = { + 'user-agent':( + "Mozilla/5.0 (Windows NT 10.0; WOW64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/62.0.3202.9 Safari/537.36" + ) +} + +class Helper(): + + def __init__(self): + self.date_now = date_parser_helper(0) + self.date_next = date_parser_helper(1) + self.weekend_pass = date_parser_helper(2) + self.two_day_pass = date_parser_helper(3) + + self.black_list = [ + 'черговий викладач', + self.date_now, + self.date_next, + self.weekend_pass, + self.two_day_pass + ] + + @staticmethod + def find_with_table(document): + c_element = 2 + while True: + try: + document['body']["content"][c_element]["table"]["rows"] + break + except KeyError: + c_element += 1 + if c_element > 15: + return False + except IndexError: + return False + + with open("{}/table_element.txt".format(config.config_folder), 'w') as f: + f.write(str(c_element)) + f.close() + return c_element + + def find_with_text(self, document): + format_charset = '-' + alternative_format_charset = "\t" + element = 4 + data = [] + text = '' + + while element < 15: + doc = ( + document['body']["content"][element] + ["paragraph"]["elements"][0]["textRun"]["content"] + ).rstrip("\n").replace("–", "-", 1) + if ( + ( + ("-" in doc) + #and + #("\t" not in doc) + ) + and + ([p not in doc.lower() for p in self.black_list][0]) + ): + try: + group, text = doc.split(format_charset) + except ValueError: + if element > 6: + break + else: + try: + group, text = doc.split(alternative_format_charset) + except ValueError: + if element > 6: + break + if text != '': + data.append( + (group.strip(" "), text.lstrip(" ").replace("\t", "")) + ) + element += 1 + return data + + def get_date(self, document): + date_element = 1 + while date_element < 16: + try: + date = ( + document['body']["content"][date_element] + ["paragraph"]["elements"][0]["textRun"]["content"] + .rstrip(" \n")) + except: + date_element += 1 + if ( + ( + ( + self.date_now in date.lower() + .lstrip("заміни").lstrip("на").replace(" ", "") + ) + or + ( + self.date_next in date.lower() + .lstrip("заміни").lstrip("на").replace(" ", "") + ) + or + ( + self.weekend_pass in date.lower() + .lstrip("заміни").lstrip("на").replace(" ", "") + ) + or + ( + self.two_day_pass in date.lower() + .lstrip("заміни").lstrip("на").replace(" ", "") + ) + ) + or + ( + "заміни на" in date.lower() + ) + ): + return date + else: + date_element += 1 + + return False + + @staticmethod + def get_table_element(): + if os.path.exists(f"{config.config_folder}/table_element.txt"): + element = int( + open( + f"{config.config_folder}/table_element.txt", + 'r' + ) + .read() + ) + else: + element = 6 + return element + + @staticmethod + def teacher(document): + element = 1 + while element < 6: + if "paragraph" in document['body']["content"][element]: + length_element = (len(document['body']["content"][element] + ["paragraph"]["elements"])) + + doc = ( + document['body']["content"][element]["paragraph"]["elements"] + [0]["textRun"]["content"].rstrip("\n") + ) + if 'черговий викладач' in doc.lower().replace("–", ""): + return doc + + elif length_element > 1: + for p in range(length_element): + doc = ( + document['body']["content"][element] + ["paragraph"]["elements"] + [p]["textRun"]["content"].rstrip("\n") + ) + if 'черговий викладач' in doc.lower().replace("–", ""): + return doc + + element += 1 + + + + @classmethod + def find_image(cls, document): + for i in document['body']["content"]: + if ("paragraph" in i) and ("elements" in i["paragraph"]): + if "inlineObjectElement" in i["paragraph"]["elements"][0]: + import base64 + return True, base64.b64encode(open("photo.png", 'rb').read()).decode('utf-8') + return False, None + diff --git a/photo.png b/photo.png new file mode 100644 index 0000000..030dbb3 Binary files /dev/null and b/photo.png differ diff --git a/setup_google_docs_api.py b/setup_google_docs_api.py new file mode 100644 index 0000000..5a90893 --- /dev/null +++ b/setup_google_docs_api.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +''' +Don`t move this file! +''' + +if __name__ == '__main__': + from parser import docs_parse + docs_parse() diff --git a/website-parser/__init__.py b/website-parser/__init__.py new file mode 100644 index 0000000..3188cf5 --- /dev/null +++ b/website-parser/__init__.py @@ -0,0 +1,2 @@ +from .parser import get_about_replacements, docs_parse +__all__ = ['get_about_replacements', 'docs_parse'] diff --git a/website-parser/parser.py b/website-parser/parser.py new file mode 100644 index 0000000..19d4141 --- /dev/null +++ b/website-parser/parser.py @@ -0,0 +1,68 @@ +import base64 +import json +import datetime +from datetime import datetime as dt + +import requests +from bs4 import BeautifulSoup + +try: + from load import config +except ImportError: config = None +try: + from .utils import * +except ImportError: + from utils import * + + +headers = { + 'user-agent':( + "Mozilla/5.0 (Windows NT 10.0; WOW64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/62.0.3202.9 Safari/537.36" + ) +} + + +def date_parser_helper(days:int, parse:str="%d.%m.20%y"): + return dt.strftime( + dt.now() + + datetime.timedelta(days=days), + parse + ) + + +def docs_parse(): + + output = { + "data":{}, + "another_teacher":None + } + + page = requests.get(config.link, headers=headers) + page.encoding = 'utf-8' + + soup = BeautifulSoup(page.text, "lxml") + + # Это в идеале нужно переписать... + url = image_parser(soup) + with requests.get(url=url, allow_redirects=True, stream=True) as r: + output['image'] = True + output['date'] = 'невозможно получить!' + output['data']['all'] = base64.b64encode(r.content).decode('utf-8') + + + with open(config.data_file, 'w') as f: + json.dump(output, f, ensure_ascii=False) + f.close() + + +def get_about_replacements() -> dict: + with open(config.data_file, 'r') as f: + data = json.loads(f.read()) + f.close() + return data + + +if __name__ == "__main__": + docs_parse() diff --git a/website-parser/utils.py b/website-parser/utils.py new file mode 100644 index 0000000..4c829dd --- /dev/null +++ b/website-parser/utils.py @@ -0,0 +1,34 @@ +from bs4 import BeautifulSoup +from typing import Any + +def table_parser(soup: BeautifulSoup, output): + #Date parser + date = (soup.find("main").findAll('span', style="color:black"))[1] + output["date"] = date.text.replace(u'\xa0', u'') + + + #Replaces parser + replaces = soup.findAll('tr') + for data in replaces: + + text = ( + data.find("td", valign="top") + .find("span", style="color:black") + .text.replace(u'\xa0', u'') + ) + group = ( + data.find("span", style="color:black") + .text.replace(" ", "").replace(u'\xa0', u'')) + output["data"][group] = text + + return output + + +def image_parser(soup: BeautifulSoup): + image: Any + extension = ('png', 'jpg') + main = soup.find("main") + for ext in extension: + image = main.select(f'img[src$=".{ext}"]') + if image: + return image[0]['src']