From 373f2332a0d3f25c079b524a2b3253799d97c351 Mon Sep 17 00:00:00 2001 From: profitroll Date: Thu, 5 Jan 2023 15:51:25 +0100 Subject: [PATCH 01/10] Updated requirements --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 1b571e9..263ef71 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,9 +2,9 @@ APScheduler==3.9.1.post1 fastapi==0.88.0 psutil==5.9.4 pymongo==4.3.3 -Pyrogram==2.0.69 +Pyrogram~=2.0.93 requests==2.28.1 tgcrypto==1.2.5 python_dateutil==2.8.2 -starlette==0.22.0 +starlette==0.23.0 ujson==5.6.0 \ No newline at end of file From ee288a1983853965718694eff00814e7eafbe0e9 Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Thu, 5 Jan 2023 20:45:35 +0100 Subject: [PATCH 02/10] Photo ID used instead of files for sponsorships --- classes/holo_user.py | 33 ++++++++++++++++---------------- modules/handlers/confirmation.py | 8 +++----- validation/sponsorships.json | 2 +- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/classes/holo_user.py b/classes/holo_user.py index 7b19a5f..fdc577e 100644 --- a/classes/holo_user.py +++ b/classes/holo_user.py @@ -1,5 +1,5 @@ from datetime import datetime -from traceback import print_exc +from traceback import format_exc from app import app, isAnAdmin from typing import Any, List, Literal, Union from pyrogram.types import User, ChatMember, ChatPrivileges, Chat, Message, Photo, Video, Document, Animation, Voice, ForceReply, ReplyKeyboardMarkup @@ -8,7 +8,7 @@ from dateutil.relativedelta import relativedelta from classes.errors.geo import PlaceNotFoundError from modules.database import col_tmp, col_users, col_applications, col_sponsorships, col_messages, col_spoilers from modules.logging import logWrite -from modules.utils import configGet, create_tmp, download_tmp, find_location, locale, should_quote +from modules.utils import configGet, find_location, locale, should_quote class DefaultApplicationTemp(dict): def __init__(self, user: int, reapply: bool = False): @@ -71,6 +71,10 @@ class LabelTooLongError(Exception): self.label = label super().__init__(f"Could not set label to '{label}' because it is {len(label)} characters long (16 is maximum)") +class LabelSettingError(Exception): + def __init__(self, exp: Exception, trace: str) -> None: + super().__init__(f"❌ **Could not set label**\n\nException: `{exp}`\n\n**Traceback:**\n```\n{trace}\n```") + class HoloUser(): """This object represents a user of HoloChecker bot. It is primarily used to interact with a database in a more python-friendly way, @@ -266,9 +270,9 @@ class HoloUser(): # Report to admin and to sender about message sending failure except Exception as exp: - logWrite(f"Exception {exp} happened as {context.from_user.id} tried to send message to {self.id}. Traceback:\n{print_exc()}") + logWrite(f"Exception {exp} happened as {context.from_user.id} tried to send message to {self.id}. Traceback:\n{format_exc()}") try: - await app.send_message(configGet("owner"), locale("message_traceback", "message").format(context.from_user.id, self.id, exp, print_exc())) + await app.send_message(configGet("owner"), locale("message_traceback", "message").format(context.from_user.id, self.id, exp, format_exc())) except bad_request_400.PeerIdInvalid: logWrite(f"Could not notify admin about failure when sending message! Admin has never interacted with bot!") await context.reply_text(locale("message_error", "message"), quote=should_quote(context)) @@ -288,10 +292,9 @@ class HoloUser(): if not await isAnAdmin(self.id): await app.set_administrator_title(configGet("users", "groups"), self.id, label) self.set("label", label) - except bad_request_400.UserCreator: - logWrite(f"Could not set {self.id}'s title to '{self.label}' because of bad_request_400.UserCreator") - except bad_request_400.ChatAdminRequired: - logWrite(f"Could not set {self.id}'s title to '{self.label}' because of bad_request_400.ChatAdminRequired") + except Exception as exp: + logWrite(f"Could not set {self.id}'s title to '{self.label}' due to {exp}") + raise LabelSettingError(exp, format_exc()) async def label_reset(self, chat: Chat) -> None: """Reset label in destination group @@ -391,7 +394,6 @@ class HoloUser(): return else: - print(f'Look: {((datetime.now() - input_dt).days)} > {(datetime.now() - datetime.now().replace(year=datetime.now().year - configGet("age_allowed"))).days}') progress["application"][str(stage)] = input_dt col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "application"}}, {"$set": {"application": progress["application"], "stage": progress["stage"]+1}}) await msg.reply_text(locale(f"question{stage+1}", "message", locale=self.locale), reply_markup=ForceReply(placeholder=str(locale(f"question{stage+1}", "force_reply", locale=self.locale)))) @@ -412,7 +414,7 @@ class HoloUser(): except Exception as exp: await msg.reply_text(locale("question3_error", "message", locale=self.locale), reply_markup=ForceReply(placeholder=str(locale(f"question{stage}", "force_reply", locale=self.locale)))) try: - await app.send_message(configGet("owner"), locale("question3_traceback", "message", locale=self.locale).format(query, exp, print_exc())) + await app.send_message(configGet("owner"), locale("question3_traceback", "message", locale=self.locale).format(query, exp, format_exc())) except bad_request_400.PeerIdInvalid: logWrite(f"Could not notify admin about failure when sending message! Admin has never interacted with bot!") return @@ -483,12 +485,9 @@ class HoloUser(): * msg (`Message`): Message that should receive replies """ - if col_tmp.find_one({"user": self.id, "type": "sponsorship"}) is not None: + progress = col_tmp.find_one({"user": self.id, "type": "sponsorship"}) - progress = col_tmp.find_one({"user": self.id, "type": "sponsorship"}) - - if progress is None: - return + if progress is not None: stage = progress["stage"] @@ -522,7 +521,7 @@ class HoloUser(): elif stage == 3: if photo is not None: - progress["sponsorship"]["proof"] = await download_tmp(app, photo.file_id) + progress["sponsorship"]["proof"] = photo.file_id col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"sponsorship": progress["sponsorship"], "stage": progress["stage"]+1}}) await msg.reply_text(locale(f"sponsor{stage+1}", "message", locale=self.locale), reply_markup=ForceReply(placeholder=str(locale(f"sponsor{stage+1}", "force_reply", locale=self.locale)))) @@ -533,7 +532,7 @@ class HoloUser(): progress["sponsorship"]["label"] = query col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"sponsorship": progress["sponsorship"], "complete": True}}) await msg.reply_photo( - photo=create_tmp(progress["sponsorship"]["proof"], kind="image"), + photo=progress["sponsorship"]["proof"], caption=locale("sponsor_confirm", "message", locale=self.locale).format( progress["sponsorship"]["streamer"], progress["sponsorship"]["expires"].strftime("%d.%m.%Y"), diff --git a/modules/handlers/confirmation.py b/modules/handlers/confirmation.py index cda9537..48d071b 100644 --- a/modules/handlers/confirmation.py +++ b/modules/handlers/confirmation.py @@ -115,13 +115,11 @@ async def confirm_yes(app: Client, msg: Message, kind: Literal["application", "s if question == "expires": sponsorship_content.append(f"{locale(f'question_{question}', 'message', 'sponsor_titles')} {tmp_sponsorship['sponsorship'][question].strftime('%d.%m.%Y')}") elif question == "proof": - filename = uuid1() - with open(f"tmp{sep}{filename}.jpg", "wb") as f: - f.write(tmp_sponsorship['sponsorship']['proof']) + continue else: sponsorship_content.append(f"{locale(f'question_{question}', 'message', 'sponsor_titles')} {tmp_sponsorship['sponsorship'][question]}") - await app.send_photo(chat_id=configGet("admin", "groups"), photo=f"tmp{sep}{filename}.jpg", caption=(locale("sponsor_got", "message")).format(str(holo_user.id), msg.from_user.first_name, msg.from_user.username, "\n".join(sponsorship_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( + await app.send_photo(chat_id=configGet("admin", "groups"), photo=tmp_sponsorship["sponsorship"]["proof"], caption=(locale("sponsor_got", "message")).format(str(holo_user.id), msg.from_user.first_name, msg.from_user.username, "\n".join(sponsorship_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton(text=str(locale("sponsor_yes", "button")), callback_data=f"sponsor_yes_{holo_user.id}") @@ -133,7 +131,7 @@ async def confirm_yes(app: Client, msg: Message, kind: Literal["application", "s ) ) - remove(f"tmp{sep}{filename}.jpg") + # remove(f"tmp{sep}{filename}.jpg") logWrite(f"User {holo_user.id} sent his sponsorship application and it will now be reviewed") diff --git a/validation/sponsorships.json b/validation/sponsorships.json index 3610e48..7ba5f38 100644 --- a/validation/sponsorships.json +++ b/validation/sponsorships.json @@ -33,7 +33,7 @@ "bsonType": "date" }, "sponsorship.proof": { - "bsonType": "binData" + "bsonType": "string" }, "sponsorship.label": { "bsonType": "string" From 57518399a1dbe0e737eebfe3a896f10cee5fc4a4 Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Thu, 5 Jan 2023 20:46:04 +0100 Subject: [PATCH 03/10] Sponsorship handler removed --- holochecker.py | 1 - modules/handlers/sponsorship.py | 16 ---------------- 2 files changed, 17 deletions(-) delete mode 100644 modules/handlers/sponsorship.py diff --git a/holochecker.py b/holochecker.py index e7b9859..da72662 100644 --- a/holochecker.py +++ b/holochecker.py @@ -41,7 +41,6 @@ from modules.handlers.contact import * from modules.handlers.group_join import * from modules.handlers.voice import * from modules.handlers.welcome import * -from modules.handlers.sponsorship import * from modules.handlers.everything import * from modules.scheduled import * diff --git a/modules/handlers/sponsorship.py b/modules/handlers/sponsorship.py deleted file mode 100644 index 4021cf0..0000000 --- a/modules/handlers/sponsorship.py +++ /dev/null @@ -1,16 +0,0 @@ -from app import app -from pyrogram import filters -from pyrogram.types import Message -from pyrogram.client import Client -from classes.holo_user import HoloUser -from modules import custom_filters - -@app.on_message(custom_filters.enabled_sponsorships & custom_filters.filling_sponsorship & ~filters.scheduled & filters.private) -async def sponsor_proof(app: Client, msg: Message): - - if msg.via_bot is None: - - holo_user = HoloUser(msg.from_user) - - if msg.photo is not None: - await holo_user.sponsorship_next(msg.text, msg=msg, photo=msg.photo) \ No newline at end of file From 59dafc004da7c8d9d7606eee4133b4218fc6fb8d Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Thu, 5 Jan 2023 20:46:47 +0100 Subject: [PATCH 04/10] LabelSettingError added --- modules/callbacks/sponsorship.py | 7 +++++-- modules/commands/label.py | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/callbacks/sponsorship.py b/modules/callbacks/sponsorship.py index 429aa2b..30d5ea1 100644 --- a/modules/callbacks/sponsorship.py +++ b/modules/callbacks/sponsorship.py @@ -3,7 +3,7 @@ from app import app from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ForceReply, CallbackQuery from pyrogram.client import Client from pyrogram import filters -from classes.holo_user import HoloUser +from classes.holo_user import HoloUser, LabelSettingError from modules.utils import configGet, locale, logWrite, should_quote from modules.database import col_tmp, col_sponsorships @@ -67,7 +67,10 @@ async def callback_query_sponsor_yes(app: Client, clb: CallbackQuery): } ) - await holo_user.label_set(configGet("users", "groups"), col_tmp.find_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "sponsorship"}})["sponsorship"]["label"]) + try: + await holo_user.label_set(configGet("users", "groups"), col_tmp.find_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "sponsorship"}})["sponsorship"]["label"]) + except LabelSettingError as exp: + await app.send_message(configGet("admin", "groups"), exp.__str__(), disable_notification=True) edited_markup = [[InlineKeyboardButton(text=str(locale("accepted", "button")), callback_data="nothing")]] diff --git a/modules/commands/label.py b/modules/commands/label.py index e0e711e..f669489 100644 --- a/modules/commands/label.py +++ b/modules/commands/label.py @@ -2,8 +2,8 @@ from app import app from pyrogram import filters from pyrogram.types import Message from pyrogram.client import Client -from modules.utils import locale, should_quote, find_user -from classes.holo_user import HoloUser, LabelTooLongError +from modules.utils import configGet, locale, should_quote, find_user +from classes.holo_user import HoloUser, LabelTooLongError, LabelSettingError from modules import custom_filters # Label command ================================================================================================================ @@ -32,6 +32,9 @@ async def cmd_label(app: Client, msg: Message): except LabelTooLongError: await msg.reply_text(locale("label_too_long", "message")) return + except LabelSettingError as exp: + await app.send_message(configGet("admin", "groups"), exp.__str__(), disable_notification=True) + return await msg.reply_text(f"Setting **{target.id}**'s label to **{label}**...", quote=should_quote(msg)) else: From b6d45545fc0843fbe6a01b2153fd201ff918b9bb Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Thu, 5 Jan 2023 20:47:02 +0100 Subject: [PATCH 05/10] User search improved --- modules/commands/message.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/commands/message.py b/modules/commands/message.py index 94af6d8..de21225 100644 --- a/modules/commands/message.py +++ b/modules/commands/message.py @@ -2,8 +2,8 @@ from app import app from pyrogram import filters from pyrogram.types import Message from pyrogram.client import Client -from classes.holo_user import HoloUser -from modules.utils import logWrite, locale, should_quote +from classes.holo_user import HoloUser, UserInvalidError +from modules.utils import logWrite, locale, should_quote, find_user from modules import custom_filters # Message command ============================================================================================================== @@ -14,8 +14,8 @@ async def cmd_message(app: Client, msg: Message): try: destination = HoloUser(int(msg.command[1])) - except ValueError: - destination = HoloUser(msg.command[1]) + except (ValueError, UserInvalidError): + destination = HoloUser(await find_user(app, query=msg.command[1])) if ((msg.text is not None) and (len(msg.text.split()) > 2)): await destination.message(context=msg, text=" ".join(msg.text.split()[2:]), caption=msg.caption, photo=msg.photo, video=msg.video, file=msg.document, adm_context=True) From 67f1ce535f95efca31629f178b2543a6ea939dec Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Thu, 5 Jan 2023 20:47:30 +0100 Subject: [PATCH 06/10] Small fixes --- modules/handlers/everything.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/handlers/everything.py b/modules/handlers/everything.py index 5639271..135d91b 100644 --- a/modules/handlers/everything.py +++ b/modules/handlers/everything.py @@ -2,7 +2,7 @@ from traceback import print_exc from app import app, isAnAdmin import asyncio from pyrogram import filters -from pyrogram.types import Message, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply, InlineKeyboardMarkup, InlineKeyboardButton +from pyrogram.types import Message, ForceReply, InlineKeyboardMarkup, InlineKeyboardButton from pyrogram.client import Client from classes.holo_user import HoloUser from modules.utils import configGet, logWrite, locale, all_locales @@ -55,7 +55,11 @@ async def any_stage(app: Client, msg: Message): await holo_user.application_next(msg.text, msg=msg) if configGet("enabled", "features", "sponsorships") is True: - await holo_user.sponsorship_next(msg.text, msg=msg) + + await holo_user.sponsorship_next(msg.text, msg) + + if msg.photo is not None: + await holo_user.sponsorship_next(msg.text, msg=msg, photo=msg.photo) if holo_user.application_state()[0] != "fill" and holo_user.sponsorship_state()[0] != "fill": From 1195df894c0fb70ae8ea50355d37c9499e8e0cfd Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Thu, 5 Jan 2023 21:15:34 +0100 Subject: [PATCH 07/10] Added documents support for spoilers --- locale/uk.json | 4 ++-- modules/commands/spoiler.py | 1 + modules/commands/start.py | 2 ++ modules/handlers/everything.py | 7 ++++++- validation/spoilers.json | 5 +++++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/locale/uk.json b/locale/uk.json index 5f4b8b6..b449d67 100644 --- a/locale/uk.json +++ b/locale/uk.json @@ -108,10 +108,10 @@ "spoiler_empty": "Спойлер категорії \"{0}\" без опису", "spoiler_described": "Спойлер категорії \"{0}\": {1}", "spoiler_description_enter": "Добре, введіть бажаний опис спойлера", - "spoiler_using_description": "Встановлено опис спойлера: {0}\n\nЗалишилось додати вміст самого спойлера. Бот приймає текстове повідомлення, фото, відео а також гіф зображення (1 шт.)", + "spoiler_using_description": "Встановлено опис спойлера: {0}\n\nЗалишилось додати вміст самого спойлера. Бот приймає текстове повідомлення, фото, відео, файл а також гіф зображення (1 шт.)", "spoiler_send_description": "Тепер треба надіслати коротенький опис спойлера, щоб люди розуміли що під ним варто очкувати. Надішли мінус (-) щоб пропустити цей крок.", "spoiler_ready": "Успіх! Спойлер створено. Користуйтесь кнопкою нижче щоб надіслати його.", - "spoiler_incorrect_content": "Бот не підтримує такий контент. Будь ласка, надішли текст, фото, відео або анімацію (гіф).", + "spoiler_incorrect_content": "Бот не підтримує такий контент. Будь ласка, надішли текст, фото, відео, файл або анімацію (гіф).", "spoiler_incorrect_category": "Вказана категорія не є дійсною. Будь ласка, користуйся клавіатурою бота (кнопка біля 📎) для вибору категорії.", "spoiler_in_progress": "❌ **Дія неможлива**\nПерш ніж починати нову дію, треба завершити створення спойлера або перервати його командою /cancel.", "yes": "Так", diff --git a/modules/commands/spoiler.py b/modules/commands/spoiler.py index cecac06..691d8f5 100644 --- a/modules/commands/spoiler.py +++ b/modules/commands/spoiler.py @@ -30,6 +30,7 @@ async def cmd_spoiler(app: Client, msg: Message): "photo": None, "video": None, "animation": None, + "document": None, "caption": None, "text": None } diff --git a/modules/commands/start.py b/modules/commands/start.py index 109a743..84beb63 100644 --- a/modules/commands/start.py +++ b/modules/commands/start.py @@ -38,6 +38,8 @@ async def cmd_start(app: Client, msg: Message): await msg.reply_video(spoiler["video"], caption=spoiler["caption"]) if spoiler["animation"] is not None: await msg.reply_animation(spoiler["animation"], caption=spoiler["caption"]) + if spoiler["document"] is not None: + await msg.reply_document(spoiler["document"], caption=spoiler["caption"]) if spoiler["text"] is not None: await msg.reply_text(spoiler["text"]) except InvalidId: diff --git a/modules/handlers/everything.py b/modules/handlers/everything.py index 135d91b..2f8a30e 100644 --- a/modules/handlers/everything.py +++ b/modules/handlers/everything.py @@ -121,7 +121,12 @@ async def any_stage(app: Client, msg: Message): logWrite(f"Adding animation with id {msg.animation.file_id} to {msg.from_user.id}'s spoiler") ready = True - if spoiler["photo"] is None and spoiler["video"] is None and spoiler["animation"] is None and spoiler["text"] is None: + if msg.document is not None: + col_spoilers.find_one_and_update( {"user": msg.from_user.id, "completed": False}, {"$set": {"document": msg.document.file_id, "caption": msg.caption, "completed": True}} ) + logWrite(f"Adding document with id {msg.document.file_id} to {msg.from_user.id}'s spoiler") + ready = True + + if spoiler["photo"] is None and spoiler["video"] is None and spoiler["animation"] is None and spoiler["document"] is None and spoiler["text"] is None: if msg.text is not None: col_spoilers.find_one_and_update( {"user": msg.from_user.id, "completed": False}, {"$set": {"text": msg.text, "completed": True}} ) logWrite(f"Adding text '{msg.text}' to {msg.from_user.id}'s spoiler") diff --git a/validation/spoilers.json b/validation/spoilers.json index 8c6733d..c54cc48 100644 --- a/validation/spoilers.json +++ b/validation/spoilers.json @@ -8,6 +8,7 @@ "photo", "video", "animation", + "document", "caption", "text" ], @@ -41,6 +42,10 @@ "bsonType": ["string", "null"], "description": "Spoilered animation/GIF" }, + "document": { + "bsonType": ["string", "null"], + "description": "Spoilered document/file" + }, "caption": { "bsonType": ["string", "null"], "description": "Spoilered caption for media" From 374effd5d75798b40bdcfbedf7ab3a04be877713 Mon Sep 17 00:00:00 2001 From: profitroll Date: Fri, 6 Jan 2023 13:21:16 +0100 Subject: [PATCH 08/10] Fixed bugs of /message and now using cached media --- classes/holo_user.py | 18 +++++++++--------- modules/commands/message.py | 6 +++--- modules/commands/start.py | 6 +++--- modules/handlers/confirmation.py | 4 +--- modules/handlers/everything.py | 2 ++ 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/classes/holo_user.py b/classes/holo_user.py index fdc577e..8c9adc1 100644 --- a/classes/holo_user.py +++ b/classes/holo_user.py @@ -219,11 +219,11 @@ class HoloUser(): if photo is not None: if isinstance(photo, Photo): photo = photo.file_id - new_message = await origin.reply_photo(photo, caption=caption, quote=True) + new_message = await origin.reply_cached_media(photo, caption=caption, quote=True) elif video is not None: if isinstance(video, Video): video = video.file_id - new_message = await origin.reply_video(video, caption=caption, quote=True) + new_message = await origin.reply_cached_media(video, caption=caption, quote=True) elif file is not None: if isinstance(file, Document): file = file.file_id @@ -231,7 +231,7 @@ class HoloUser(): elif animation is not None: if isinstance(animation, Animation): animation = animation.file_id - new_message = await origin.reply_animation(animation, caption=caption, quote=True) + new_message = await origin.reply_cached_media(animation, caption=caption, quote=True) elif voice is not None: if isinstance(voice, Voice): voice = voice.file_id @@ -244,11 +244,11 @@ class HoloUser(): if photo is not None: if isinstance(photo, Photo): photo = photo.file_id - new_message = await app.send_photo(self.id, photo, caption=caption) + new_message = await app.send_cached_media(self.id, photo, caption=caption) elif video is not None: if isinstance(video, Video): video = video.file_id - new_message = await app.send_video(self.id, video, caption=caption) + new_message = await app.send_cached_media(self.id, video, caption=caption) elif file is not None: if isinstance(file, Document): file = file.file_id @@ -256,11 +256,11 @@ class HoloUser(): elif animation is not None: if isinstance(animation, Animation): animation = animation.file_id - new_message = await app.send_animation(self.id, animation, caption=caption) + new_message = await app.send_cached_media(self.id, animation, caption=caption) elif voice is not None: if isinstance(voice, Voice): voice = voice.file_id - new_message = await app.send_voice(self.id, voice, caption=caption) + new_message = await app.send_cached_media(self.id, voice, caption=caption) else: new_message = await app.send_message(self.id, text) @@ -531,8 +531,8 @@ class HoloUser(): return progress["sponsorship"]["label"] = query col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"sponsorship": progress["sponsorship"], "complete": True}}) - await msg.reply_photo( - photo=progress["sponsorship"]["proof"], + await msg.reply_cached_media( + progress["sponsorship"]["proof"], caption=locale("sponsor_confirm", "message", locale=self.locale).format( progress["sponsorship"]["streamer"], progress["sponsorship"]["expires"].strftime("%d.%m.%Y"), diff --git a/modules/commands/message.py b/modules/commands/message.py index de21225..a2a8205 100644 --- a/modules/commands/message.py +++ b/modules/commands/message.py @@ -18,11 +18,11 @@ async def cmd_message(app: Client, msg: Message): destination = HoloUser(await find_user(app, query=msg.command[1])) if ((msg.text is not None) and (len(msg.text.split()) > 2)): - await destination.message(context=msg, text=" ".join(msg.text.split()[2:]), caption=msg.caption, photo=msg.photo, video=msg.video, file=msg.document, adm_context=True) + await destination.message(context=msg, text=" ".join(msg.text.split()[2:]), caption=msg.caption, photo=msg.photo, video=msg.video, file=msg.document, voice=msg.voice, animation=msg.animation, adm_context=True) elif ((msg.caption is not None) and (len(msg.caption.split()) > 2)): - await destination.message(context=msg, text=msg.text, caption=" ".join(msg.caption.split()[2:]), photo=msg.photo, video=msg.video, file=msg.document, adm_context=True) + await destination.message(context=msg, text=msg.text, caption=" ".join(msg.caption.split()[2:]), photo=msg.photo, video=msg.video, file=msg.document, voice=msg.voice, animation=msg.animation, adm_context=True) else: - await destination.message(context=msg, text=None, caption=None, photo=msg.photo, video=msg.video, file=msg.document, adm_context=True) + await destination.message(context=msg, text=None, caption=None, photo=msg.photo, video=msg.video, file=msg.document, voice=msg.voice, animation=msg.animation, adm_context=True) except IndexError: await msg.reply_text(locale("message_invalid_syntax", "message", locale=msg.from_user), quote=should_quote(msg)) diff --git a/modules/commands/start.py b/modules/commands/start.py index 84beb63..ac7e6df 100644 --- a/modules/commands/start.py +++ b/modules/commands/start.py @@ -33,11 +33,11 @@ async def cmd_start(app: Client, msg: Message): try: spoiler = col_spoilers.find_one( {"_id": ObjectId(msg.command[1])} ) if spoiler["photo"] is not None: - await msg.reply_photo(spoiler["photo"], caption=spoiler["caption"]) + await msg.reply_document(spoiler["photo"], caption=spoiler["caption"]) if spoiler["video"] is not None: - await msg.reply_video(spoiler["video"], caption=spoiler["caption"]) + await msg.reply_cached_media(spoiler["video"], caption=spoiler["caption"]) if spoiler["animation"] is not None: - await msg.reply_animation(spoiler["animation"], caption=spoiler["caption"]) + await msg.reply_cached_media(spoiler["animation"], caption=spoiler["caption"]) if spoiler["document"] is not None: await msg.reply_document(spoiler["document"], caption=spoiler["caption"]) if spoiler["text"] is not None: diff --git a/modules/handlers/confirmation.py b/modules/handlers/confirmation.py index 48d071b..c854e29 100644 --- a/modules/handlers/confirmation.py +++ b/modules/handlers/confirmation.py @@ -1,6 +1,4 @@ -from os import remove, sep from typing import Literal -from uuid import uuid1 from dateutil.relativedelta import relativedelta from datetime import datetime from app import app @@ -119,7 +117,7 @@ async def confirm_yes(app: Client, msg: Message, kind: Literal["application", "s else: sponsorship_content.append(f"{locale(f'question_{question}', 'message', 'sponsor_titles')} {tmp_sponsorship['sponsorship'][question]}") - await app.send_photo(chat_id=configGet("admin", "groups"), photo=tmp_sponsorship["sponsorship"]["proof"], caption=(locale("sponsor_got", "message")).format(str(holo_user.id), msg.from_user.first_name, msg.from_user.username, "\n".join(sponsorship_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( + await app.send_cached_media(chat_id=configGet("admin", "groups"), photo=tmp_sponsorship["sponsorship"]["proof"], caption=(locale("sponsor_got", "message")).format(str(holo_user.id), msg.from_user.first_name, msg.from_user.username, "\n".join(sponsorship_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton(text=str(locale("sponsor_yes", "button")), callback_data=f"sponsor_yes_{holo_user.id}") diff --git a/modules/handlers/everything.py b/modules/handlers/everything.py index 2f8a30e..6270e8e 100644 --- a/modules/handlers/everything.py +++ b/modules/handlers/everything.py @@ -43,6 +43,8 @@ async def any_stage(app: Client, msg: Message): photo=msg.photo, video=msg.video, file=msg.document, + animation=msg.animation, + voice=msg.voice, adm_origin=await isAnAdmin(context_message.from_user.id), adm_context=await isAnAdmin(msg.from_user.id) ) From 78a37ca186ed2fe2d46aa02babf3a8d84b113887 Mon Sep 17 00:00:00 2001 From: profitroll Date: Fri, 6 Jan 2023 15:49:51 +0100 Subject: [PATCH 09/10] Placed exceptions to errors module --- classes/errors/holo_user.py | 24 ++++++++++++++++++++++++ classes/holo_user.py | 23 +---------------------- modules/callbacks/sponsorship.py | 3 ++- modules/commands/application.py | 3 ++- modules/commands/identify.py | 3 ++- modules/commands/label.py | 3 ++- modules/commands/message.py | 3 ++- modules/commands/spoiler.py | 3 ++- modules/inline.py | 3 ++- 9 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 classes/errors/holo_user.py diff --git a/classes/errors/holo_user.py b/classes/errors/holo_user.py new file mode 100644 index 0000000..a4fbb6b --- /dev/null +++ b/classes/errors/holo_user.py @@ -0,0 +1,24 @@ +"""Exceptions that are meant to be used by HoloUser class +and other modules that handle those exceptions""" + +class UserNotFoundError(Exception): + """HoloUser could not find user with such an ID in database""" + def __init__(self, user, user_id): + self.user = user + self.user_id = user_id + super().__init__(f"User of type {type(self.user)} with id {self.user_id} was not found") + +class UserInvalidError(Exception): + """Provided to HoloUser object is not supported""" + def __init__(self, user): + self.user = user + super().__init__(f"Could not find HoloUser by using {type(self.user)} as an input type") + +class LabelTooLongError(Exception): + def __init__(self, label: str) -> None: + self.label = label + super().__init__(f"Could not set label to '{label}' because it is {len(label)} characters long (16 is maximum)") + +class LabelSettingError(Exception): + def __init__(self, exp: Exception, trace: str) -> None: + super().__init__(f"❌ **Could not set label**\n\nException: `{exp}`\n\n**Traceback:**\n```\n{trace}\n```") \ No newline at end of file diff --git a/classes/holo_user.py b/classes/holo_user.py index 8c9adc1..80e87bf 100644 --- a/classes/holo_user.py +++ b/classes/holo_user.py @@ -6,6 +6,7 @@ from pyrogram.types import User, ChatMember, ChatPrivileges, Chat, Message, Phot from pyrogram.errors import bad_request_400 from dateutil.relativedelta import relativedelta from classes.errors.geo import PlaceNotFoundError +from classes.errors.holo_user import UserInvalidError, UserNotFoundError, LabelTooLongError, LabelSettingError from modules.database import col_tmp, col_users, col_applications, col_sponsorships, col_messages, col_spoilers from modules.logging import logWrite from modules.utils import configGet, find_location, locale, should_quote @@ -53,28 +54,6 @@ class DefaultSponsorshipTemp(dict): } } -class UserNotFoundError(Exception): - """HoloUser could not find user with such an ID in database""" - def __init__(self, user, user_id): - self.user = user - self.user_id = user_id - super().__init__(f"User of type {type(self.user)} with id {self.user_id} was not found") - -class UserInvalidError(Exception): - """Provided to HoloUser object is not supported""" - def __init__(self, user): - self.user = user - super().__init__(f"Could not find HoloUser by using {type(self.user)} as an input type") - -class LabelTooLongError(Exception): - def __init__(self, label: str) -> None: - self.label = label - super().__init__(f"Could not set label to '{label}' because it is {len(label)} characters long (16 is maximum)") - -class LabelSettingError(Exception): - def __init__(self, exp: Exception, trace: str) -> None: - super().__init__(f"❌ **Could not set label**\n\nException: `{exp}`\n\n**Traceback:**\n```\n{trace}\n```") - class HoloUser(): """This object represents a user of HoloChecker bot. It is primarily used to interact with a database in a more python-friendly way, diff --git a/modules/callbacks/sponsorship.py b/modules/callbacks/sponsorship.py index 30d5ea1..918135f 100644 --- a/modules/callbacks/sponsorship.py +++ b/modules/callbacks/sponsorship.py @@ -3,7 +3,8 @@ from app import app from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ForceReply, CallbackQuery from pyrogram.client import Client from pyrogram import filters -from classes.holo_user import HoloUser, LabelSettingError +from classes.errors.holo_user import LabelSettingError +from classes.holo_user import HoloUser from modules.utils import configGet, locale, logWrite, should_quote from modules.database import col_tmp, col_sponsorships diff --git a/modules/commands/application.py b/modules/commands/application.py index b1d429a..069c03e 100644 --- a/modules/commands/application.py +++ b/modules/commands/application.py @@ -5,7 +5,8 @@ from pyrogram.enums.parse_mode import ParseMode from pyrogram.types import Message from pyrogram.errors import bad_request_400 from pyrogram.client import Client -from classes.holo_user import HoloUser, UserNotFoundError +from classes.errors.holo_user import UserNotFoundError +from classes.holo_user import HoloUser from modules.utils import logWrite, locale, should_quote from dateutil.relativedelta import relativedelta from modules.database import col_applications diff --git a/modules/commands/identify.py b/modules/commands/identify.py index 953fd42..ad76a0b 100644 --- a/modules/commands/identify.py +++ b/modules/commands/identify.py @@ -5,7 +5,8 @@ from pyrogram.types import Message from pyrogram.client import Client from pyrogram.errors import bad_request_400 from pyrogram.enums.chat_action import ChatAction -from classes.holo_user import HoloUser, UserNotFoundError, UserInvalidError +from classes.errors.holo_user import UserNotFoundError, UserInvalidError +from classes.holo_user import HoloUser from modules.utils import jsonLoad, should_quote, logWrite, locale, download_tmp, create_tmp, find_user from modules import custom_filters diff --git a/modules/commands/label.py b/modules/commands/label.py index f669489..70821b8 100644 --- a/modules/commands/label.py +++ b/modules/commands/label.py @@ -3,7 +3,8 @@ from pyrogram import filters from pyrogram.types import Message from pyrogram.client import Client from modules.utils import configGet, locale, should_quote, find_user -from classes.holo_user import HoloUser, LabelTooLongError, LabelSettingError +from classes.errors.holo_user import LabelTooLongError, LabelSettingError +from classes.holo_user import HoloUser from modules import custom_filters # Label command ================================================================================================================ diff --git a/modules/commands/message.py b/modules/commands/message.py index a2a8205..50c6b0a 100644 --- a/modules/commands/message.py +++ b/modules/commands/message.py @@ -2,7 +2,8 @@ from app import app from pyrogram import filters from pyrogram.types import Message from pyrogram.client import Client -from classes.holo_user import HoloUser, UserInvalidError +from classes.errors.holo_user import UserInvalidError +from classes.holo_user import HoloUser from modules.utils import logWrite, locale, should_quote, find_user from modules import custom_filters diff --git a/modules/commands/spoiler.py b/modules/commands/spoiler.py index 691d8f5..3f0e5e7 100644 --- a/modules/commands/spoiler.py +++ b/modules/commands/spoiler.py @@ -2,7 +2,8 @@ from app import app from pyrogram import filters from pyrogram.types import Message, ReplyKeyboardMarkup from pyrogram.client import Client -from classes.holo_user import HoloUser, UserInvalidError, UserNotFoundError +from classes.errors.holo_user import UserNotFoundError, UserInvalidError +from classes.holo_user import HoloUser from modules.logging import logWrite from modules.utils import locale from modules.database import col_spoilers diff --git a/modules/inline.py b/modules/inline.py index dec4344..d50ec8d 100644 --- a/modules/inline.py +++ b/modules/inline.py @@ -9,7 +9,8 @@ from pyrogram.client import Client from pyrogram.enums.chat_type import ChatType from pyrogram.enums.chat_members_filter import ChatMembersFilter from dateutil.relativedelta import relativedelta -from classes.holo_user import HoloUser, UserInvalidError, UserNotFoundError +from classes.errors.holo_user import UserNotFoundError, UserInvalidError +from classes.holo_user import HoloUser from modules.utils import configGet, locale from modules.database import col_applications, col_spoilers from bson.objectid import ObjectId From 742b529c33d0c385674e412bff8972002ba09c51 Mon Sep 17 00:00:00 2001 From: profitroll Date: Fri, 6 Jan 2023 15:59:09 +0100 Subject: [PATCH 10/10] Moved templates classes into another module --- classes/holo_user.py | 44 +----------------------------------------- classes/templates.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 43 deletions(-) create mode 100644 classes/templates.py diff --git a/classes/holo_user.py b/classes/holo_user.py index 80e87bf..fb1cc35 100644 --- a/classes/holo_user.py +++ b/classes/holo_user.py @@ -7,53 +7,11 @@ from pyrogram.errors import bad_request_400 from dateutil.relativedelta import relativedelta from classes.errors.geo import PlaceNotFoundError from classes.errors.holo_user import UserInvalidError, UserNotFoundError, LabelTooLongError, LabelSettingError +from classes.templates import DefaultApplicationTemp, DefaultSponsorshipTemp from modules.database import col_tmp, col_users, col_applications, col_sponsorships, col_messages, col_spoilers from modules.logging import logWrite from modules.utils import configGet, find_location, locale, should_quote -class DefaultApplicationTemp(dict): - def __init__(self, user: int, reapply: bool = False): - super().__init__({}) - self.dict = { - "user": user, - "type": "application", - "complete": False, - "sent": False, - "state": "fill", - "reapply": reapply, - "stage": 1, - "application": { - "1": None, - "2": None, - "3": None, - "4": None, - "5": None, - "6": None, - "7": None, - "8": None, - "9": None, - "10": None - } - } - -class DefaultSponsorshipTemp(dict): - def __init__(self, user: int): - super().__init__({}) - self.dict = { - "user": user, - "type": "sponsorship", - "complete": False, - "sent": False, - "state": "fill", - "stage": 1, - "sponsorship": { - "streamer": None, - "expires": datetime.fromtimestamp(0), - "proof": None, - "label": "" - } - } - class HoloUser(): """This object represents a user of HoloChecker bot. It is primarily used to interact with a database in a more python-friendly way, diff --git a/classes/templates.py b/classes/templates.py new file mode 100644 index 0000000..08a848b --- /dev/null +++ b/classes/templates.py @@ -0,0 +1,46 @@ +"""Templates for temporary application/sponsorship records""" + +from datetime import datetime + +class DefaultApplicationTemp(dict): + def __init__(self, user: int, reapply: bool = False): + super().__init__({}) + self.dict = { + "user": user, + "type": "application", + "complete": False, + "sent": False, + "state": "fill", + "reapply": reapply, + "stage": 1, + "application": { + "1": None, + "2": None, + "3": None, + "4": None, + "5": None, + "6": None, + "7": None, + "8": None, + "9": None, + "10": None + } + } + +class DefaultSponsorshipTemp(dict): + def __init__(self, user: int): + super().__init__({}) + self.dict = { + "user": user, + "type": "sponsorship", + "complete": False, + "sent": False, + "state": "fill", + "stage": 1, + "sponsorship": { + "streamer": None, + "expires": datetime.fromtimestamp(0), + "proof": None, + "label": "" + } + } \ No newline at end of file