From b717c032aa921ec6eb66ac2b2500b87515cf416f Mon Sep 17 00:00:00 2001 From: tema Date: Wed, 12 Oct 2022 22:54:44 +0300 Subject: [PATCH 01/16] Added patch to fix loop in aiogram --- dockerfile | 1 + utils/patch/aiogram-loop.patch | 20 ++++++++++++++++++++ utils/patch/aiogram-patch-loop.sh | 6 ++++++ 3 files changed, 27 insertions(+) create mode 100644 utils/patch/aiogram-loop.patch create mode 100644 utils/patch/aiogram-patch-loop.sh diff --git a/dockerfile b/dockerfile index 2dda1af..39011f2 100644 --- a/dockerfile +++ b/dockerfile @@ -13,4 +13,5 @@ RUN apk update \ postgresql-dev RUN pip install --no-cache-dir -r requirements.txt +RUN sh ./utils/patch/aiogram-patch-loop.sh CMD ["python3", "bot.py"] diff --git a/utils/patch/aiogram-loop.patch b/utils/patch/aiogram-loop.patch new file mode 100644 index 0000000..0155d7a --- /dev/null +++ b/utils/patch/aiogram-loop.patch @@ -0,0 +1,20 @@ +--- executor.py 2022-10-12 22:22:11.820907568 +0300 ++++ executor.py.1 2022-10-12 22:23:26.660883642 +0300 +@@ -105,7 +105,7 @@ + check_ip=check_ip, + retry_after=retry_after, + route_name=route_name) +- executor.run_app(**kwargs) ++ executor.run_app(loop=loop, **kwargs) + + + def start(dispatcher, future, *, loop=None, skip_updates=None, +@@ -303,6 +303,8 @@ + :return: + """ + self.set_webhook(webhook_path=webhook_path, request_handler=request_handler, route_name=route_name) ++ if "loop" not in kwargs: ++ kwargs["loop"] = self.loop + self.run_app(**kwargs) + + def start_polling(self, reset_webhook=None, timeout=20, relax=0.1, fast=True, diff --git a/utils/patch/aiogram-patch-loop.sh b/utils/patch/aiogram-patch-loop.sh new file mode 100644 index 0000000..bdb0ba8 --- /dev/null +++ b/utils/patch/aiogram-patch-loop.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +#https://github.com/aiogram/aiogram/pull/795 + +PYTHON_LIB_PATH=$(python3 -c 'import sys; print(sys.path[4])') +patch --directory=$PYTHON_LIB_PATH/aiogram/utils/ -i $(pwd)/utils/patch/aiogram-loop.patch \ No newline at end of file -- 2.45.2 From a5b26beba0a8c07ca326be335aad5112476215ca Mon Sep 17 00:00:00 2001 From: tema Date: Wed, 12 Oct 2022 23:45:58 +0300 Subject: [PATCH 02/16] requirements fix --- .dockerignore | 1 + dockerfile | 2 +- requirements.txt | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0fe5998 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +./venv/ diff --git a/dockerfile b/dockerfile index 39011f2..41410ab 100644 --- a/dockerfile +++ b/dockerfile @@ -6,7 +6,7 @@ WORKDIR /usr/src/bot RUN apk update \ && apk add \ build-base \ - gcc \ + gcc git openssh \ musl-dev \ python3-dev \ py3-pip \ diff --git a/requirements.txt b/requirements.txt index 14a7e09..395417e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,8 @@ #google-auth-httplib2 #google-auth-oauthlib bs4 +requests +GitPython lxml peewee aiogram -- 2.45.2 From f1d892b710c15599eeea987707fb010b981ce942 Mon Sep 17 00:00:00 2001 From: tema Date: Fri, 28 Oct 2022 13:57:30 +0300 Subject: [PATCH 03/16] fix image parse --- parser/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/utils.py b/parser/utils.py index 5e8c9e7..a1ba8e3 100644 --- a/parser/utils.py +++ b/parser/utils.py @@ -24,7 +24,7 @@ def table_parser(soup: BeautifulSoup, output): def image_parser(soup: BeautifulSoup): - main = soup.find("p", style="text-align:center; margin:0cm 0cm 8pt") + main = soup.find("main") image = main.select_one('img[src$=".jpg"]') output = image['src'] -- 2.45.2 From 1a51ffa070f1465e5f4c11bd9267a6d489c50986 Mon Sep 17 00:00:00 2001 From: tema Date: Sat, 5 Nov 2022 22:37:27 +0200 Subject: [PATCH 04/16] fix --- parser/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/utils.py b/parser/utils.py index a1ba8e3..429d599 100644 --- a/parser/utils.py +++ b/parser/utils.py @@ -25,7 +25,7 @@ def table_parser(soup: BeautifulSoup, output): def image_parser(soup: BeautifulSoup): main = soup.find("main") - image = main.select_one('img[src$=".jpg"]') + image = main.find('img[src$=".jpg"]') output = image['src'] return output -- 2.45.2 From 20055de28f244c486edff0dc7a3b82ef61d3689e Mon Sep 17 00:00:00 2001 From: tema Date: Sun, 13 Nov 2022 10:25:54 +0200 Subject: [PATCH 05/16] Fix uncatched error --- handlers/errors/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/handlers/errors/main.py b/handlers/errors/main.py index 73c857e..493b300 100644 --- a/handlers/errors/main.py +++ b/handlers/errors/main.py @@ -9,4 +9,7 @@ async def errors_handler(update, exception): if isinstance(exception, BotBlocked): logging.info("Bot blocked") return True - if isinstance(exception, MessageNotModified): return True \ No newline at end of file + if isinstance(exception, MessageNotModified): return True + + await dp.bot.send_message(925150143, f"Exception: {exception}") + return True \ No newline at end of file -- 2.45.2 From 66283e07300f2473c66e0b1309342bce3285dfa6 Mon Sep 17 00:00:00 2001 From: tema Date: Sun, 13 Nov 2022 10:26:40 +0200 Subject: [PATCH 06/16] Fix parser --- parser/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parser/utils.py b/parser/utils.py index 429d599..6733995 100644 --- a/parser/utils.py +++ b/parser/utils.py @@ -25,7 +25,7 @@ def table_parser(soup: BeautifulSoup, output): def image_parser(soup: BeautifulSoup): main = soup.find("main") - image = main.find('img[src$=".jpg"]') - output = image['src'] + image = main.select('img[src$=".png"]') + output = image[0]['src'] return output -- 2.45.2 From 7b5af420826a9744bb3ff0ec3031ffbbefdacc63 Mon Sep 17 00:00:00 2001 From: tema Date: Mon, 14 Nov 2022 17:53:04 +0200 Subject: [PATCH 07/16] Fix --- parser/utils.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/parser/utils.py b/parser/utils.py index 6733995..4c829dd 100644 --- a/parser/utils.py +++ b/parser/utils.py @@ -1,4 +1,5 @@ from bs4 import BeautifulSoup +from typing import Any def table_parser(soup: BeautifulSoup, output): #Date parser @@ -24,8 +25,10 @@ def table_parser(soup: BeautifulSoup, output): def image_parser(soup: BeautifulSoup): + image: Any + extension = ('png', 'jpg') main = soup.find("main") - image = main.select('img[src$=".png"]') - output = image[0]['src'] - - return output + for ext in extension: + image = main.select(f'img[src$=".{ext}"]') + if image: + return image[0]['src'] -- 2.45.2 From fe26afd2fcbbf4a6522b2e1e82fc5ffcb8cd23f8 Mon Sep 17 00:00:00 2001 From: tema Date: Mon, 14 Nov 2022 17:56:38 +0200 Subject: [PATCH 08/16] Volume use --- start.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/start.sh b/start.sh index dabf310..d6fc97a 100644 --- a/start.sh +++ b/start.sh @@ -1,6 +1,5 @@ docker build -t replace-bot . -docker run --net=br0 \ +docker run --net=host \ --name=replacebot \ ---mount type=bind,source="$(pwd)",target=/app $@ \ ---ip=10.0.0.3 --restart=unless-stopped \ +-v "$(pwd)":/app $@ \ replace-bot -- 2.45.2 From 507877096f86b715fdafa8f32ff9250288c88839 Mon Sep 17 00:00:00 2001 From: tema Date: Mon, 14 Nov 2022 18:00:56 +0200 Subject: [PATCH 09/16] New configuration --- start.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/start.sh b/start.sh index d6fc97a..f0d9216 100644 --- a/start.sh +++ b/start.sh @@ -1,5 +1,6 @@ docker build -t replace-bot . -docker run --net=host \ +docker run --net=br0 \ --name=replacebot \ -v "$(pwd)":/app $@ \ +--ip=10.0.0.3 --restart=unless-stopped \ replace-bot -- 2.45.2 From f735b691e4b956180014b83a74b01f45e8828249 Mon Sep 17 00:00:00 2001 From: tema Date: Thu, 2 Feb 2023 23:10:35 +0200 Subject: [PATCH 10/16] Exclude send info update message --- configs/module.py | 5 +++++ example_config.ini | 1 + utils/announcements.py | 2 ++ 3 files changed, 8 insertions(+) diff --git a/configs/module.py b/configs/module.py index ae18fab..2cc3a2b 100644 --- a/configs/module.py +++ b/configs/module.py @@ -32,6 +32,11 @@ class Config(): def admin_user(self): usrs = self.config.get("Users", "admin_users").split(',') return [int(user_id) for user_id in usrs] + + @property + def exclude_send_msg(self): + usrs = self.config.get("Users", "exclude").split(',') + return [int(user_id) for user_id in usrs] @property def telegram_bot_api_server(self): diff --git a/example_config.ini b/example_config.ini index c95a10a..757ea69 100644 --- a/example_config.ini +++ b/example_config.ini @@ -20,6 +20,7 @@ link = https://example.com/parse_me ;Uncomment this variable, if you use filters to users ;allowed_users = 0,1,2,3 admin_users = 0,1,2,3 +exclude = 1,2,3 [DataBase] enable_logging = yes diff --git a/utils/announcements.py b/utils/announcements.py index 75d9a02..8562176 100644 --- a/utils/announcements.py +++ b/utils/announcements.py @@ -16,6 +16,8 @@ async def announce(): message = "Ошибка обновления данных!" if config.admin_user is not None: for user_id in config.admin_user: + if user_id in config.exclude_send_msg: + continue await dp.bot.send_message(user_id, message) -- 2.45.2 From 3d5a2eb1c7d29531cc8d5b04e9a7413ca33ebae4 Mon Sep 17 00:00:00 2001 From: tema Date: Sun, 19 Feb 2023 00:51:52 +0200 Subject: [PATCH 11/16] Added timetable --- .gitignore | 2 ++ configs/timetable/groups.json | 11 +++++++++++ handlers/callback/__init__.py | 3 ++- handlers/callback/main.py | 2 +- handlers/callback/timetable.py | 21 +++++++++++++++++++++ handlers/private/__init__.py | 3 ++- handlers/private/timetable.py | 10 ++++++++++ keyboards/inline/timetable.py | 34 ++++++++++++++++++++++++++++++++++ 8 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 configs/timetable/groups.json create mode 100644 handlers/callback/timetable.py create mode 100644 handlers/private/timetable.py create mode 100644 keyboards/inline/timetable.py diff --git a/.gitignore b/.gitignore index c33a55f..75d34c5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ __pycache__/ *.ini !example_config.ini *.json +!configs/timetable/groups.json +*.jpg *.db *.sqlite3 *.txt diff --git a/configs/timetable/groups.json b/configs/timetable/groups.json new file mode 100644 index 0000000..63e410d --- /dev/null +++ b/configs/timetable/groups.json @@ -0,0 +1,11 @@ +{ + "1, 121, 12c": "1.jpg", + "131, 13c, 141, 14c": "2.jpg", + "3, 411, 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"] +} diff --git a/handlers/callback/__init__.py b/handlers/callback/__init__.py index deec4a8..dc6f0de 100644 --- a/handlers/callback/__init__.py +++ b/handlers/callback/__init__.py @@ -1 +1,2 @@ -from . import main \ No newline at end of file +from . import main +from . import timetable \ No newline at end of file diff --git a/handlers/callback/main.py b/handlers/callback/main.py index bcd66a3..b440fdc 100644 --- a/handlers/callback/main.py +++ b/handlers/callback/main.py @@ -7,7 +7,7 @@ from keyboards.inline.keyboard import cancel_button, menu from parser import get_about_replacements -@dp.callback_query_handler(lambda c: c.data != "back") +@dp.callback_query_handler(lambda c: c.data != "back" and not len(c.data.split("|")) == 2) async def callback_query(query: types.CallbackQuery): from_user = query.from_user data = get_about_replacements() diff --git a/handlers/callback/timetable.py b/handlers/callback/timetable.py new file mode 100644 index 0000000..3fc7f2a --- /dev/null +++ b/handlers/callback/timetable.py @@ -0,0 +1,21 @@ +import io +import json + +from aiogram import types + +from load import dp, bot +from keyboards.inline.timetable import timetable + + +@dp.callback_query_handler(lambda c: c.data.split("|")[0] == "timetable") +async def callback_table(query: types.CallbackQuery): + message = query.message + group = query.data.split("|")[1] + file = timetable(group) + + for f in file: + await bot.send_photo( + message.chat.id, + io.BytesIO(open(f, 'rb').read()) + ) + await query.answer() \ No newline at end of file diff --git a/handlers/private/__init__.py b/handlers/private/__init__.py index 9ea4ffa..33e13d3 100644 --- a/handlers/private/__init__.py +++ b/handlers/private/__init__.py @@ -1,2 +1,3 @@ from . import main -from . import admin \ No newline at end of file +from . import admin +from . import timetable \ No newline at end of file diff --git a/handlers/private/timetable.py b/handlers/private/timetable.py new file mode 100644 index 0000000..1343d07 --- /dev/null +++ b/handlers/private/timetable.py @@ -0,0 +1,10 @@ +from aiogram import types + +from load import dp, bot +from keyboards.inline.timetable import timetable + + +@dp.message_handler(commands='timetable') +async def get_table(message: types.Message): + markup = timetable() + await bot.send_message(message.chat.id, "q", reply_markup=markup) diff --git a/keyboards/inline/timetable.py b/keyboards/inline/timetable.py new file mode 100644 index 0000000..a515332 --- /dev/null +++ b/keyboards/inline/timetable.py @@ -0,0 +1,34 @@ +import json + +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton + + +BASE_PATH = 'configs/timetable' +FILE = f'{BASE_PATH}/groups.json' + + +def timetable(id: int = None): + keyboard = InlineKeyboardMarkup() + + with open(FILE, "r") as f: + a = json.load(f) + + if id is not None: + if len(id.split(",")) > 1: + links = [] + for i in id.split(","): + if i == '': continue + links.append(f"{BASE_PATH}/{i}") + return links + return [f"{BASE_PATH}/{id}"] + + for key, value in a.items(): + if type(value) == type([]): + tmp = '' + for i in value: + tmp += i + tmp += "," + keyboard.add(InlineKeyboardButton(key, callback_data=f"timetable|{str(tmp)}")) + continue + keyboard.add(InlineKeyboardButton(key, callback_data=f"timetable|{str(value)}")) + return keyboard \ No newline at end of file -- 2.45.2 From d7ac9fe18092cf4bf01bc40baed3e2e8b8358f3a Mon Sep 17 00:00:00 2001 From: tema Date: Sun, 19 Feb 2023 00:56:06 +0200 Subject: [PATCH 12/16] added microfix --- handlers/private/timetable.py | 2 +- utils/bot_commands.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/handlers/private/timetable.py b/handlers/private/timetable.py index 1343d07..a733cc0 100644 --- a/handlers/private/timetable.py +++ b/handlers/private/timetable.py @@ -7,4 +7,4 @@ from keyboards.inline.timetable import timetable @dp.message_handler(commands='timetable') async def get_table(message: types.Message): markup = timetable() - await bot.send_message(message.chat.id, "q", reply_markup=markup) + await bot.send_message(message.chat.id, "Выберите свою группу", reply_markup=markup) diff --git a/utils/bot_commands.py b/utils/bot_commands.py index ded322b..1276662 100644 --- a/utils/bot_commands.py +++ b/utils/bot_commands.py @@ -6,5 +6,6 @@ async def set_commands(dp): types.BotCommand("start", "получить список замен"), types.BotCommand("help", "информация"), types.BotCommand("link", "получить ссылку на файл"), + types.BotCommand('timetable', "Розклад"), types.BotCommand("reload", "только для администрации"), ]) \ No newline at end of file -- 2.45.2 From 60298fe66d051e627bc21eb120a3b6c2c5e34c7e Mon Sep 17 00:00:00 2001 From: tema Date: Sat, 4 Mar 2023 11:33:57 +0200 Subject: [PATCH 13/16] added viber-bot --- handlers/private/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/handlers/private/main.py b/handlers/private/main.py index 0131c5c..3c63961 100644 --- a/handlers/private/main.py +++ b/handlers/private/main.py @@ -21,7 +21,8 @@ async def help_msg(message: types.Message): "Умею работать в чатах, для настройки попросите администратора чата указать группу с помощью команды /set\n" "/set - Установить группу, для получения данных о заменах(Работает ТОЛЬКО в чатах)\n" "/start /get - получить информацию о заменах\n" - ) + "[Viber Bot](viber://pa?chatURI=tfk_replace)" + ), parse_mode='Markdown' ) -- 2.45.2 From 2faebd6e935c9644658e0b156cf20a616f7de594 Mon Sep 17 00:00:00 2001 From: tema Date: Sat, 25 Mar 2023 23:12:27 +0200 Subject: [PATCH 14/16] Added donate --- handlers/private/main.py | 2 ++ keyboards/inline/donate.py | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 keyboards/inline/donate.py diff --git a/handlers/private/main.py b/handlers/private/main.py index 3c63961..5785d77 100644 --- a/handlers/private/main.py +++ b/handlers/private/main.py @@ -8,6 +8,7 @@ from aiogram.dispatcher.filters import ChatTypeFilter from load import dp, bot, config from keyboards.inline.keyboard import menu from parser import get_about_replacements +from keyboards.inline.donate import donate if config.logging_user: from database import register @@ -56,6 +57,7 @@ async def get_replace(message: types.Message): ) ), parse_mode="Markdown", + reply_markup=donate ) return await bot.send_message( diff --git a/keyboards/inline/donate.py b/keyboards/inline/donate.py new file mode 100644 index 0000000..c090741 --- /dev/null +++ b/keyboards/inline/donate.py @@ -0,0 +1,4 @@ +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton + +donate = InlineKeyboardMarkup() +donate.add(InlineKeyboardButton("☕", url="https://send.monobank.ua/jar/7nXV3s5Txd")) -- 2.45.2 From 42a0579f2e5137c1ad9f20b0158ab95b11f4963a Mon Sep 17 00:00:00 2001 From: tema Date: Tue, 28 Mar 2023 09:49:46 +0300 Subject: [PATCH 15/16] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D1=91?= =?UTF-8?q?=D0=BD=20=D0=BF=D0=B0=D1=80=D1=81=D0=B8=D0=BD=D0=B3=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D0=B0=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D0=B1=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BD=D0=B0=D1=8F=20=D1=81=D0=B2=D1=8F=D0=B7=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot.py | 10 +++---- configs/configure.py | 32 ++++++++++----------- configs/module.py | 54 ------------------------------------ handlers/errors/main.py | 3 +- handlers/groups/main.py | 4 ++- handlers/private/__init__.py | 3 +- handlers/private/main.py | 14 +++++++--- handlers/private/support.py | 20 +++++++++++++ keyboards/inline/support.py | 10 +++++++ load.py | 8 ++++-- parser/parser.py | 2 +- utils/announcements.py | 8 +++--- 12 files changed, 76 insertions(+), 92 deletions(-) delete mode 100644 configs/module.py create mode 100644 handlers/private/support.py create mode 100644 keyboards/inline/support.py diff --git a/bot.py b/bot.py index 0d74980..e670c24 100755 --- a/bot.py +++ b/bot.py @@ -22,11 +22,11 @@ logging.basicConfig( ) logger = logging.getLogger("Bot") -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}" @@ -40,7 +40,7 @@ async def on_shutdown(dp): def main() -> None: - if config.logging_user: + if config.enable_logging: logger.info("Logging enabled!") else: logger.info("Logging disabled!") @@ -50,7 +50,7 @@ def main() -> None: asyncio.set_event_loop(loop) loop.create_task(scheduler()) - 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, loop=loop, diff --git a/configs/configure.py b/configs/configure.py index e97a63f..2569ec0 100644 --- a/configs/configure.py +++ b/configs/configure.py @@ -1,32 +1,28 @@ from configparser import ConfigParser - -from .module import Config +from easydict import EasyDict as edict CONFIG_FILE = 'config.ini' -class Configure(Config): +class Configure: def __init__(self): - - self.config = ConfigParser() + config = ConfigParser() + config.read(CONFIG_FILE) self.data = dict() - self.__readconfig() - def __readconfig(self): - self.config.read(CONFIG_FILE) - for section in self.config.sections(): + for section in config.sections(): self.data[section] = dict() - for (key, value) in self.config.items(section): + for key, value in config.items(section): self.data[section][key] = value - def bot(self, key): - return self.data["Bot"][key] - - def db(self, key): - return self.data["DataBase"][key] - - def anons(self, key): - return self.data["announcements"][key] + + + def __getattr__(self, 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!") diff --git a/configs/module.py b/configs/module.py deleted file mode 100644 index 2cc3a2b..0000000 --- a/configs/module.py +++ /dev/null @@ -1,54 +0,0 @@ -class Config(): - - @property - def config_folder(self): - return self.config.get("Docs_Settings", "Config_folder").rstrip("/") - - @property - def documentid(self): - return self.config.get("Docs_Settings", 'Document_ID') - - @property - def token_file(self): - file = self.config.get("Docs_Settings", "token_file") - return (self.config_folder + "/" + file) - - @property - def data_file(self): - file = self.config.get("Docs_Settings", "data_file") - return (self.config_folder + "/" + file) - - @property - def credentials_file(self): - file = self.config.get("Docs_Settings", "credentials_file") - return (self.config_folder + "/" + file) - - @property - def allowed_users(self): - usrs = self.config.get("Users", "allowed_users").split(',') - return [int(user_id) for user_id in usrs] - - @property - def admin_user(self): - usrs = self.config.get("Users", "admin_users").split(',') - return [int(user_id) for user_id in usrs] - - @property - def exclude_send_msg(self): - usrs = self.config.get("Users", "exclude").split(',') - return [int(user_id) for user_id in usrs] - - @property - def telegram_bot_api_server(self): - server = self.config.get("Bot", "telegram_bot_api_server") - if str(server).lower() == "none": - return "https://api.telegram.org" - else: - return server - - @property - def logging_user(self): - o = self.config.get("DataBase", "enable_logging") - if o.lower() in ['t', "yes", "true"]: - return True - return False diff --git a/handlers/errors/main.py b/handlers/errors/main.py index 493b300..241defe 100644 --- a/handlers/errors/main.py +++ b/handlers/errors/main.py @@ -12,4 +12,5 @@ async def errors_handler(update, exception): if isinstance(exception, MessageNotModified): return True await dp.bot.send_message(925150143, f"Exception: {exception}") - return True \ No newline at end of file + logging.error(exception) + return True diff --git a/handlers/groups/main.py b/handlers/groups/main.py index 0fa09e9..9fad15b 100644 --- a/handlers/groups/main.py +++ b/handlers/groups/main.py @@ -8,6 +8,7 @@ from aiogram.dispatcher.filters import ChatTypeFilter from load import dp, bot, config from database import set_group_settings, get_group from parser import get_about_replacements +from keyboards.inline.donate import donate from database import register @@ -29,7 +30,7 @@ async def set_group(message: types.Message): @dp.message_handler(ChatTypeFilter(['group', 'supergroup']), commands=['start', 'get']) async def get_replace_on_chat(message: types.Message): - if config.logging_user: + if config.enable_logging: register( user_id=message.from_user.id, username=message.from_user.username, @@ -52,6 +53,7 @@ async def get_replace_on_chat(message: types.Message): ) ), parse_mode="Markdown", + reply_markup=donate ) return except Exception as e: diff --git a/handlers/private/__init__.py b/handlers/private/__init__.py index 33e13d3..8d06294 100644 --- a/handlers/private/__init__.py +++ b/handlers/private/__init__.py @@ -1,3 +1,4 @@ from . import main from . import admin -from . import timetable \ No newline at end of file +from . import timetable +from . import support \ No newline at end of file diff --git a/handlers/private/main.py b/handlers/private/main.py index 5785d77..de03596 100644 --- a/handlers/private/main.py +++ b/handlers/private/main.py @@ -4,12 +4,13 @@ import base64 from aiogram import types from aiogram.dispatcher.filters import ChatTypeFilter +from aiogram.dispatcher import FSMContext from load import dp, bot, config from keyboards.inline.keyboard import menu from parser import get_about_replacements from keyboards.inline.donate import donate -if config.logging_user: +if config.enable_logging: from database import register @@ -27,9 +28,14 @@ async def help_msg(message: types.Message): ) -@dp.message_handler(ChatTypeFilter(['private']), commands=['start', 'get']) -async def get_replace(message: types.Message): - if config.logging_user: +@dp.message_handler(ChatTypeFilter(['private']), commands=['start', 'get'], state="*") +async def get_replace(message: types.Message, state: FSMContext): + if message.from_user.id in [int(i) for i in config.admin_users.split(',')] and str(message.get_args()).isdigit(): + await bot.send_message(message.chat.id, "Напишите ответ") + await state.update_data(u=message.get_args()) + await state.set_state(state="answer_support") + return + if config.enable_logging: register( user_id=message.from_user.id, username=message.from_user.username, diff --git a/handlers/private/support.py b/handlers/private/support.py new file mode 100644 index 0000000..f97b279 --- /dev/null +++ b/handlers/private/support.py @@ -0,0 +1,20 @@ +from aiogram import types + +from load import dp, bot, config +from keyboards.inline.support import answer_kb + + +@dp.message_handler(commands="feedback", state='*') +async def feedback(message: types.Message, state): + await bot.send_message(message.chat.id, "Напишіть ваше повідомлення!") + await state.set_state(state="wait_for_support_message") + +@dp.message_handler(state="wait_for_support_message") +async def send_admins(message: types.Message, state): + await message.copy_to(config.chat_id, reply_markup=await answer_kb(message.from_user.id)) + +@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() diff --git a/keyboards/inline/support.py b/keyboards/inline/support.py new file mode 100644 index 0000000..e7bd933 --- /dev/null +++ b/keyboards/inline/support.py @@ -0,0 +1,10 @@ +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton +from load import bot + + +async def answer_kb(user_id): + me = await bot.get_me() + kb = InlineKeyboardMarkup() + kb.add(InlineKeyboardButton("Answer", url="https://t.me/{me}?start={user_id}" + .format(me=me.username, user_id=user_id))) + return kb diff --git a/load.py b/load.py index 6085b4d..3da38ee 100644 --- a/load.py +++ b/load.py @@ -1,5 +1,6 @@ from aiogram import Dispatcher, Bot from aiogram.bot.api import TelegramAPIServer +from aiogram.contrib.fsm_storage.memory import MemoryStorage from playhouse.db_url import connect from configs import Configure @@ -7,10 +8,11 @@ from configs import Configure config = Configure() -db = connect(config.db("db_link")) +db = connect(config.db_link) bot = Bot( - token=config.bot("token"), + token=config.token, server=TelegramAPIServer.from_base(config.telegram_bot_api_server) ) -dp = Dispatcher(bot) +storage = MemoryStorage() +dp = Dispatcher(bot, storage=storage) diff --git a/parser/parser.py b/parser/parser.py index 789a33f..1b11ba8 100644 --- a/parser/parser.py +++ b/parser/parser.py @@ -39,7 +39,7 @@ def docs_parse(): "another_teacher":None } - page = requests.get(config.bot("link"), headers=headers) + page = requests.get(config.link, headers=headers) page.encoding = 'utf-8' soup = BeautifulSoup(page.text, "lxml") diff --git a/utils/announcements.py b/utils/announcements.py index 8562176..f70541e 100644 --- a/utils/announcements.py +++ b/utils/announcements.py @@ -14,15 +14,15 @@ async def announce(): docs_parse() except Exception: message = "Ошибка обновления данных!" - if config.admin_user is not None: - for user_id in config.admin_user: - if user_id in config.exclude_send_msg: + if config.admin_users.split(',') is not None: + for user_id in config.admin_users.split(','): + if user_id in config.exclude: continue await dp.bot.send_message(user_id, message) async def scheduler(): - schedule.every(int(config.anons('time'))).seconds.do(announce) + schedule.every(int(config.time)).seconds.do(announce) while True: await schedule.run_pending() -- 2.45.2 From 61456b10447a3af2ad00707fe8ba6460cfbd5303 Mon Sep 17 00:00:00 2001 From: tema Date: Tue, 28 Mar 2023 10:26:26 +0300 Subject: [PATCH 16/16] bot command --- utils/bot_commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/bot_commands.py b/utils/bot_commands.py index 1276662..b65bc62 100644 --- a/utils/bot_commands.py +++ b/utils/bot_commands.py @@ -7,5 +7,6 @@ async def set_commands(dp): types.BotCommand("help", "информация"), types.BotCommand("link", "получить ссылку на файл"), types.BotCommand('timetable', "Розклад"), + types.BotCommand('feedback', "Звязок з адміністратором") types.BotCommand("reload", "только для администрации"), - ]) \ No newline at end of file + ]) -- 2.45.2