From 1a438fc32ea285573a97bc06f592662fb8345a8c Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Fri, 6 Jan 2023 21:27:32 +0100 Subject: [PATCH 01/23] Fixed api method --- modules/handlers/confirmation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/handlers/confirmation.py b/modules/handlers/confirmation.py index c854e29..ee0115a 100644 --- a/modules/handlers/confirmation.py +++ b/modules/handlers/confirmation.py @@ -117,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_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( + await app.send_cached_media(configGet("admin", "groups"), 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}") -- 2.39.2 From a4bbb837d73904f42aa4bc76bb4d4db8ef3c636e Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Fri, 6 Jan 2023 21:27:47 +0100 Subject: [PATCH 02/23] Added delay for label setting --- classes/holo_user.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/classes/holo_user.py b/classes/holo_user.py index fb1cc35..6613618 100644 --- a/classes/holo_user.py +++ b/classes/holo_user.py @@ -1,4 +1,5 @@ from datetime import datetime +from asyncio import sleep from traceback import format_exc from app import app, isAnAdmin from typing import Any, List, Literal, Union @@ -227,6 +228,7 @@ class HoloUser(): try: await app.promote_chat_member(configGet("users", "groups"), self.id, privileges=ChatPrivileges(can_pin_messages=True, can_manage_video_chats=True)) if not await isAnAdmin(self.id): + await sleep(0.5) await app.set_administrator_title(configGet("users", "groups"), self.id, label) self.set("label", label) except Exception as exp: -- 2.39.2 From 21bf460b28b22cc7bee0bd666c54d20b7f7a60b9 Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Sat, 7 Jan 2023 00:38:35 +0100 Subject: [PATCH 03/23] Fixes + improved logging --- classes/holo_user.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/classes/holo_user.py b/classes/holo_user.py index 6613618..bce31e9 100644 --- a/classes/holo_user.py +++ b/classes/holo_user.py @@ -124,11 +124,11 @@ class HoloUser(): # Check if any text available and log message sending if text is not None: - logWrite(f"{context.from_user.id} sent message '{text}' to {self.id}") + logWrite(f"{context.from_user.id} sent message '{text}' to {self.id} (source message: {context.id})") elif caption is not None: - logWrite(f"{context.from_user.id} sent message '{caption}' to {self.id}") + logWrite(f"{context.from_user.id} sent message '{caption}' to {self.id} (source message: {context.id})") else: - logWrite(f"{context.from_user.id} sent message to {self.id}") + logWrite(f"{context.from_user.id} sent message to {self.id} (source message: {context.id})") # Add notices for admin or user if text is not None: @@ -165,7 +165,7 @@ class HoloUser(): elif file is not None: if isinstance(file, Document): file = file.file_id - new_message = await origin.reply_document(file, caption=caption, quote=True) + new_message = await origin.reply_cached_media(file, caption=caption, quote=True) elif animation is not None: if isinstance(animation, Animation): animation = animation.file_id @@ -190,7 +190,7 @@ class HoloUser(): elif file is not None: if isinstance(file, Document): file = file.file_id - new_message = await app.send_document(self.id, file, caption=caption) + new_message = await app.send_cached_media(self.id, file, caption=caption) elif animation is not None: if isinstance(animation, Animation): animation = animation.file_id -- 2.39.2 From bcaf80e2e158b90ae193997a5a17ea357789e066 Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Sat, 7 Jan 2023 00:38:53 +0100 Subject: [PATCH 04/23] Fixed reply_document() issue --- modules/commands/start.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/commands/start.py b/modules/commands/start.py index ac7e6df..55d42ab 100644 --- a/modules/commands/start.py +++ b/modules/commands/start.py @@ -33,13 +33,13 @@ 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_document(spoiler["photo"], caption=spoiler["caption"]) + await msg.reply_cached_media(spoiler["photo"], caption=spoiler["caption"]) if spoiler["video"] is not None: await msg.reply_cached_media(spoiler["video"], caption=spoiler["caption"]) if spoiler["animation"] is not None: 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"]) + await msg.reply_cached_media(spoiler["document"], caption=spoiler["caption"]) if spoiler["text"] is not None: await msg.reply_text(spoiler["text"]) except InvalidId: -- 2.39.2 From 0bf5ae70ebc99354013883abe3962e59154e3218 Mon Sep 17 00:00:00 2001 From: Profitroll <47523801+profitrollgame@users.noreply.github.com> Date: Sat, 7 Jan 2023 10:20:58 +0100 Subject: [PATCH 05/23] Improved inline query usage filters --- modules/inline.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/modules/inline.py b/modules/inline.py index d50ec8d..3f5f50a 100644 --- a/modules/inline.py +++ b/modules/inline.py @@ -11,7 +11,7 @@ from pyrogram.enums.chat_members_filter import ChatMembersFilter from dateutil.relativedelta import relativedelta from classes.errors.holo_user import UserNotFoundError, UserInvalidError from classes.holo_user import HoloUser -from modules.utils import configGet, locale +from modules.utils import configGet, jsonLoad, locale from modules.database import col_applications, col_spoilers from bson.objectid import ObjectId from bson.errors import InvalidId @@ -64,19 +64,27 @@ async def inline_answer(client: Client, inline_query: InlineQuery): ) return + results_forbidden = [ + InlineQueryResultArticle( + title=locale("title", "inline", "forbidden", locale=inline_query.from_user), + input_message_content=InputTextMessageContent( + locale("message_content", "inline", "forbidden", locale=inline_query.from_user) + ), + description=locale("description", "inline", "forbidden", locale=inline_query.from_user) + ) + ] + try: holo_user = HoloUser(inline_query.from_user) except (UserNotFoundError, UserInvalidError): await inline_query.answer( - results=[ - InlineQueryResultArticle( - title=locale("title", "inline", "forbidden", locale=inline_query.from_user), - input_message_content=InputTextMessageContent( - locale("message_content", "inline", "forbidden", locale=inline_query.from_user) - ), - description=locale("description", "inline", "forbidden", locale=inline_query.from_user) - ) - ] + results=results_forbidden + ) + return + + if path.exists(path.join(configGet("cache", "locations"), "group_members")) and (inline_query.from_user.id not in jsonLoad(path.join(configGet("cache", "locations"), "group_members"))): + await inline_query.answer( + results=results_forbidden ) return -- 2.39.2 From 496240c48bd09c042ac7aed944b91630f86b8d1a Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 11:39:24 +0100 Subject: [PATCH 06/23] Fixed id attribute in sponsorships scheduler --- modules/scheduled.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/scheduled.py b/modules/scheduled.py index 47116da..5498199 100644 --- a/modules/scheduled.py +++ b/modules/scheduled.py @@ -76,7 +76,7 @@ if configGet("enabled", "features", "sponsorships") is True: try: tg_user = await app.get_users(entry["user"]) until_expiry = relativedelta(datetime.now(), entry["sponsorship"]["expires"]).days - await app.send_message( tg_user, locale("sponsorships_expires", "message").format(until_expiry) ) # type: ignore + await app.send_message( tg_user.id, locale("sponsorships_expires", "message").format(until_expiry) ) # type: ignore logWrite(f"Notified user that sponsorship expires in {until_expiry} days") except Exception as exp: logWrite(f"Could not find user {entry['user']} notify about sponsorship expiry due to '{exp}'") -- 2.39.2 From e2d28f442c42dd8e91c15d99e43197400ecf9e68 Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 12:10:07 +0100 Subject: [PATCH 07/23] Changed inline caching time --- modules/inline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/inline.py b/modules/inline.py index 3f5f50a..33613a4 100644 --- a/modules/inline.py +++ b/modules/inline.py @@ -169,5 +169,5 @@ async def inline_answer(client: Client, inline_query: InlineQuery): await inline_query.answer( results=results, - cache_time=10 - ) + cache_time=150 + ) \ No newline at end of file -- 2.39.2 From d090b18655e6580988f8b45f383bccca6232a170 Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 12:11:29 +0100 Subject: [PATCH 08/23] Added additional caching message on debug --- modules/scheduled.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/scheduled.py b/modules/scheduled.py index 5498199..a9b199f 100644 --- a/modules/scheduled.py +++ b/modules/scheduled.py @@ -22,8 +22,10 @@ if configGet("enabled", "scheduler", "cache_members"): list_of_users = [] async for member in app.get_chat_members(configGet("users", "groups")): list_of_users.append(member.user.id) - makedirs("cache", exist_ok=True) + makedirs(configGet("cache", "locations"), exist_ok=True) jsonSave(list_of_users, path.join(configGet("cache", "locations"), "group_members")) + if configGet("debug") is True: + logWrite("User group caching performed") if configGet("enabled", "scheduler", "cache_admins"): @scheduler.scheduled_job(trigger="interval", seconds=configGet("interval", "scheduler", "cache_admins")) @@ -31,8 +33,10 @@ if configGet("enabled", "scheduler", "cache_admins"): list_of_users = [] async for member in app.get_chat_members(configGet("admin", "groups")): list_of_users.append(member.user.id) - makedirs("cache", exist_ok=True) + makedirs(configGet("cache", "locations"), exist_ok=True) jsonSave(list_of_users, path.join(configGet("cache", "locations"), "admins")) + if configGet("debug") is True: + logWrite("Admin group caching performed") # Cache the avatars of group members if configGet("enabled", "scheduler", "cache_avatars"): -- 2.39.2 From 3e166a3fcaa0ef0993ae95d75a690b6015298c30 Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 12:21:21 +0100 Subject: [PATCH 09/23] Fixed inline query caching --- modules/inline.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/modules/inline.py b/modules/inline.py index 33613a4..a5c9d28 100644 --- a/modules/inline.py +++ b/modules/inline.py @@ -11,6 +11,7 @@ from pyrogram.enums.chat_members_filter import ChatMembersFilter from dateutil.relativedelta import relativedelta from classes.errors.holo_user import UserNotFoundError, UserInvalidError from classes.holo_user import HoloUser +from modules.logging import logWrite from modules.utils import configGet, jsonLoad, locale from modules.database import col_applications, col_spoilers from bson.objectid import ObjectId @@ -77,16 +78,21 @@ async def inline_answer(client: Client, inline_query: InlineQuery): try: holo_user = HoloUser(inline_query.from_user) except (UserNotFoundError, UserInvalidError): + if configGet("debug") is True: + logWrite(f"Could not find application of {inline_query.from_user.id}, ignoring inline query") await inline_query.answer( results=results_forbidden ) return if path.exists(path.join(configGet("cache", "locations"), "group_members")) and (inline_query.from_user.id not in jsonLoad(path.join(configGet("cache", "locations"), "group_members"))): - await inline_query.answer( - results=results_forbidden - ) - return + if path.exists(path.join(configGet("cache", "locations"), "admins")) and (inline_query.from_user.id not in jsonLoad(path.join(configGet("cache", "locations"), "admins"))): + if configGet("debug") is True: + logWrite(f"{inline_query.from_user.id} is not an admin and not in members group, ignoring inline query") + await inline_query.answer( + results=results_forbidden + ) + return if holo_user.application_approved() or (await isAnAdmin(holo_user.id) is True): @@ -169,5 +175,6 @@ async def inline_answer(client: Client, inline_query: InlineQuery): await inline_query.answer( results=results, - cache_time=150 + cache_time=10, + is_personal=True ) \ No newline at end of file -- 2.39.2 From da3dd3a2fe60b088ce88d6b81102c8c12740e7ce Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 12:39:39 +0100 Subject: [PATCH 10/23] Changed debug logging logic --- modules/commands/reapply.py | 23 +++++++++++++++-------- modules/commands/resetcommands.py | 23 ++++++++--------------- modules/inline.py | 6 ++---- modules/scheduled.py | 11 ++++------- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/modules/commands/reapply.py b/modules/commands/reapply.py index c817c77..aec1829 100644 --- a/modules/commands/reapply.py +++ b/modules/commands/reapply.py @@ -34,14 +34,21 @@ async def cmd_reapply(app: Client, msg: Message): await welcome_pass(app, msg, once_again=True) else: - await msg.reply_text(locale("reapply_left_chat", "message", locale=holo_user), reply_markup=InlineKeyboardMarkup([ - [ - InlineKeyboardButton(locale("reapply_old_one", "button", locale=holo_user), f"reapply_old_{msg.id}") - ], - [ - InlineKeyboardButton(locale("reapply_new_one", "button", locale=holo_user), f"reapply_new_{msg.id}") - ] - ])) + + if holo_user.sponsorship_state()[1] is True: + + await msg.reply_text(locale("reapply_left_chat", "message", locale=holo_user), reply_markup=InlineKeyboardMarkup([ + [ + InlineKeyboardButton(locale("reapply_old_one", "button", locale=holo_user), f"reapply_old_{msg.id}") + ], + [ + InlineKeyboardButton(locale("reapply_new_one", "button", locale=holo_user), f"reapply_new_{msg.id}") + ] + ])) + + else: + holo_user.application_restart(reapply=True) + await welcome_pass(app, msg, once_again=True) else: diff --git a/modules/commands/resetcommands.py b/modules/commands/resetcommands.py index 5f5ef15..e9f2c5a 100644 --- a/modules/commands/resetcommands.py +++ b/modules/commands/resetcommands.py @@ -24,42 +24,35 @@ async def cmd_resetcommands(app: Client, msg: Message): if entry.endswith(".json"): valid_locales.append(".".join(entry.split(".")[:-1])) - if configGet("debug") is True: - logWrite(f'Resetting commands in groups {configGet("admin", "groups")} and {configGet("users", "groups")}') + logWrite(f'Resetting commands in groups {configGet("admin", "groups")} and {configGet("users", "groups")}', debug=True) await app.delete_bot_commands(scope=BotCommandScopeChat(chat_id=configGet("admin", "groups"))) await app.delete_bot_commands(scope=BotCommandScopeChat(chat_id=configGet("users", "groups"))) for admin in configGet("admins"): try: - if configGet("debug") is True: - logWrite(f'Resetting commands for admin {admin}') + logWrite(f'Resetting commands for admin {admin}', debug=True) await app.delete_bot_commands(scope=BotCommandScopeChat(chat_id=admin)) except bad_request_400.PeerIdInvalid: pass try: - if configGet("debug") is True: - logWrite(f'Resetting commands for owner {configGet("owner")}') + logWrite(f'Resetting commands for owner {configGet("owner")}', debug=True) for lc in valid_locales: - if configGet("debug") is True: - logWrite(f'Resetting commands for owner {configGet("owner")} [{lc}]') + logWrite(f'Resetting commands for owner {configGet("owner")} [{lc}]', debug=True) await app.delete_bot_commands(scope=BotCommandScopeChat(chat_id=configGet("owner")), language_code=lc) await app.delete_bot_commands(scope=BotCommandScopeChat(chat_id=configGet("owner"))) except bad_request_400.PeerIdInvalid: pass for lc in valid_locales: - if configGet("debug") is True: - logWrite(f'Resetting commands for locale {lc}') + logWrite(f'Resetting commands for locale {lc}', debug=True) await app.delete_bot_commands(scope=BotCommandScopeDefault(), language_code=lc) - if configGet("debug") is True: - logWrite(f'Resetting default commands') + logWrite(f'Resetting default commands', debug=True) await app.delete_bot_commands() await msg.reply_text("OK", quote=should_quote(msg)) - if configGet("debug") is True: - logWrite(str(await app.get_bot_commands())) - logWrite(str(await app.get_bot_commands(scope=BotCommandScopeChat(chat_id=configGet("owner"))))) + logWrite(str(await app.get_bot_commands()), debug=True) + logWrite(str(await app.get_bot_commands(scope=BotCommandScopeChat(chat_id=configGet("owner")))), debug=True) # ============================================================================================================================== \ No newline at end of file diff --git a/modules/inline.py b/modules/inline.py index a5c9d28..ce25f7b 100644 --- a/modules/inline.py +++ b/modules/inline.py @@ -78,8 +78,7 @@ async def inline_answer(client: Client, inline_query: InlineQuery): try: holo_user = HoloUser(inline_query.from_user) except (UserNotFoundError, UserInvalidError): - if configGet("debug") is True: - logWrite(f"Could not find application of {inline_query.from_user.id}, ignoring inline query") + logWrite(f"Could not find application of {inline_query.from_user.id}, ignoring inline query", debug=True) await inline_query.answer( results=results_forbidden ) @@ -87,8 +86,7 @@ async def inline_answer(client: Client, inline_query: InlineQuery): if path.exists(path.join(configGet("cache", "locations"), "group_members")) and (inline_query.from_user.id not in jsonLoad(path.join(configGet("cache", "locations"), "group_members"))): if path.exists(path.join(configGet("cache", "locations"), "admins")) and (inline_query.from_user.id not in jsonLoad(path.join(configGet("cache", "locations"), "admins"))): - if configGet("debug") is True: - logWrite(f"{inline_query.from_user.id} is not an admin and not in members group, ignoring inline query") + logWrite(f"{inline_query.from_user.id} is not an admin and not in members group, ignoring inline query", debug=True) await inline_query.answer( results=results_forbidden ) diff --git a/modules/scheduled.py b/modules/scheduled.py index a9b199f..bd0d0d0 100644 --- a/modules/scheduled.py +++ b/modules/scheduled.py @@ -24,8 +24,7 @@ if configGet("enabled", "scheduler", "cache_members"): list_of_users.append(member.user.id) makedirs(configGet("cache", "locations"), exist_ok=True) jsonSave(list_of_users, path.join(configGet("cache", "locations"), "group_members")) - if configGet("debug") is True: - logWrite("User group caching performed") + logWrite("User group caching performed", debug=True) if configGet("enabled", "scheduler", "cache_admins"): @scheduler.scheduled_job(trigger="interval", seconds=configGet("interval", "scheduler", "cache_admins")) @@ -35,8 +34,7 @@ if configGet("enabled", "scheduler", "cache_admins"): list_of_users.append(member.user.id) makedirs(configGet("cache", "locations"), exist_ok=True) jsonSave(list_of_users, path.join(configGet("cache", "locations"), "admins")) - if configGet("debug") is True: - logWrite("Admin group caching performed") + logWrite("Admin group caching performed", debug=True) # Cache the avatars of group members if configGet("enabled", "scheduler", "cache_avatars"): @@ -159,8 +157,7 @@ async def commands_register(): enabled = True if enabled is False: - if configGet("debug") is True: - logWrite(f"Not registering {command} at all") + logWrite(f"Not registering {command} at all", debug=True) continue for permission in config_commands[command]["permissions"]: @@ -223,4 +220,4 @@ async def commands_register(): if configGet("debug") is True: print(commands, flush=True) - logWrite(f"Complete commands registration:\n{dumps(commands_raw, indent=4, ensure_ascii=False, encode_html_chars=False)}") \ No newline at end of file + logWrite(f"Complete commands registration:\n{dumps(commands_raw, indent=4, ensure_ascii=False, encode_html_chars=False)}", debug=True) \ No newline at end of file -- 2.39.2 From eced1b798450716d0212346f6507b7984360e15e Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 12:54:00 +0100 Subject: [PATCH 11/23] Added one more check --- modules/custom_filters.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/custom_filters.py b/modules/custom_filters.py index 808965f..4fa39fe 100644 --- a/modules/custom_filters.py +++ b/modules/custom_filters.py @@ -15,7 +15,11 @@ async def member_func(_, __, msg: Message): return True if (msg.from_user.id in jsonLoad(path.join(configGet("cache", "locations"), "group_members"))) else False async def allowed_func(_, __, msg: Message): - return True if (col_applications.find_one({"user": msg.from_user.id}) is not None) else False + output = False + output = True if (col_applications.find_one({"user": msg.from_user.id}) is not None) else False + if path.exists(path.join(configGet("cache", "locations"), "group_members")) and (msg.from_user.id not in jsonLoad(path.join(configGet("cache", "locations"), "group_members"))): + output = False + return output async def enabled_general_func(_, __, msg: Message): return configGet("enabled", "features", "general") -- 2.39.2 From 64b0562bc412c45e78466f386805e8b888983e42 Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 13:08:02 +0100 Subject: [PATCH 12/23] Added "group_users_admins" command scope --- config_example.json | 3 +-- modules/scheduled.py | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/config_example.json b/config_example.json index 5080175..5d06ffc 100644 --- a/config_example.json +++ b/config_example.json @@ -114,7 +114,6 @@ "permissions": [ "users", "admins", - "group_users", "group_admins" ], "modules": [ @@ -123,7 +122,7 @@ }, "warn": { "permissions": [ - "group_users" + "group_users_admins" ], "modules": [ "warnings" diff --git a/modules/scheduled.py b/modules/scheduled.py index bd0d0d0..13a7322 100644 --- a/modules/scheduled.py +++ b/modules/scheduled.py @@ -6,7 +6,7 @@ from apscheduler.schedulers.asyncio import AsyncIOScheduler from datetime import datetime, timedelta from ujson import dumps from app import app -from pyrogram.types import BotCommand, BotCommandScopeChat +from pyrogram.types import BotCommand, BotCommandScopeChat, BotCommandScopeChatAdministrators from pyrogram.errors import bad_request_400 from pyrogram.enums.chat_members_filter import ChatMembersFilter from classes.holo_user import HoloUser @@ -110,6 +110,7 @@ async def commands_register(): "owner": [], "group_users": [], "group_admins": [], + "group_users_admins": [], "locales": {} } @@ -119,6 +120,7 @@ async def commands_register(): "owner": [], "group_users": [], "group_admins": [], + "group_users_admins": [], "locales": {} } @@ -133,7 +135,8 @@ async def commands_register(): "admins": [], "owner": [], "group_users": [], - "group_admins": [] + "group_admins": [], + "group_users_admins": [] } if configGet("debug") is True: commands_raw["locales"][".".join(entry.split(".")[:-1])] = { @@ -141,7 +144,8 @@ async def commands_register(): "admins": [], "owner": [], "group_users": [], - "group_admins": [] + "group_admins": [], + "group_users_admins": [] } config_modules = configGet("features") @@ -217,6 +221,13 @@ async def commands_register(): except bad_request_400.ChannelInvalid: logWrite(f"Could not register commands for destination group. Bot is likely not in the group.") + # Registering destination group admin commands + try: + await app.set_bot_commands(commands["group_users_admins"], scope=BotCommandScopeChatAdministrators(chat_id=configGet("users", "groups"))) + logWrite("Registered destination group admin commands") + except bad_request_400.ChannelInvalid: + logWrite(f"Could not register admin commands for destination group. Bot is likely not in the group.") + if configGet("debug") is True: print(commands, flush=True) -- 2.39.2 From 717d6364973334474d7cbe4d6d23bb86c2e2c978 Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 13:19:17 +0100 Subject: [PATCH 13/23] Added one more check --- modules/commands/reapply.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/commands/reapply.py b/modules/commands/reapply.py index aec1829..1912eb6 100644 --- a/modules/commands/reapply.py +++ b/modules/commands/reapply.py @@ -3,6 +3,7 @@ from pyrogram import filters from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, Message from pyrogram.client import Client from classes.holo_user import HoloUser +from modules.logging import logWrite from modules.utils import configGet, locale, should_quote from modules.handlers.welcome import welcome_pass from modules.database import col_tmp @@ -35,7 +36,7 @@ async def cmd_reapply(app: Client, msg: Message): else: - if holo_user.sponsorship_state()[1] is True: + if holo_user.application_state()[1] is True and holo_user.application_state()[0] != "fill": await msg.reply_text(locale("reapply_left_chat", "message", locale=holo_user), reply_markup=InlineKeyboardMarkup([ [ @@ -47,6 +48,7 @@ async def cmd_reapply(app: Client, msg: Message): ])) else: + holo_user.application_restart(reapply=True) await welcome_pass(app, msg, once_again=True) -- 2.39.2 From bdc775dcbda67c9b514217f5a7bca74078147a18 Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 14:34:33 +0100 Subject: [PATCH 14/23] Made groups caching log only visible on debug --- modules/scheduled.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/scheduled.py b/modules/scheduled.py index 13a7322..5b6a038 100644 --- a/modules/scheduled.py +++ b/modules/scheduled.py @@ -24,7 +24,8 @@ if configGet("enabled", "scheduler", "cache_members"): list_of_users.append(member.user.id) makedirs(configGet("cache", "locations"), exist_ok=True) jsonSave(list_of_users, path.join(configGet("cache", "locations"), "group_members")) - logWrite("User group caching performed", debug=True) + if configGet("debug") is True: + logWrite("User group caching performed", debug=True) if configGet("enabled", "scheduler", "cache_admins"): @scheduler.scheduled_job(trigger="interval", seconds=configGet("interval", "scheduler", "cache_admins")) @@ -34,7 +35,8 @@ if configGet("enabled", "scheduler", "cache_admins"): list_of_users.append(member.user.id) makedirs(configGet("cache", "locations"), exist_ok=True) jsonSave(list_of_users, path.join(configGet("cache", "locations"), "admins")) - logWrite("Admin group caching performed", debug=True) + if configGet("debug") is True: + logWrite("Admin group caching performed", debug=True) # Cache the avatars of group members if configGet("enabled", "scheduler", "cache_avatars"): -- 2.39.2 From 30dfe4ff04bdc3ec31b1af829ce6ba1007353f07 Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 14:43:19 +0100 Subject: [PATCH 15/23] Moved initial caching a bit --- modules/scheduled.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/scheduled.py b/modules/scheduled.py index 5b6a038..f30f312 100644 --- a/modules/scheduled.py +++ b/modules/scheduled.py @@ -40,7 +40,7 @@ if configGet("enabled", "scheduler", "cache_admins"): # Cache the avatars of group members if configGet("enabled", "scheduler", "cache_avatars"): - @scheduler.scheduled_job(trigger="date", run_date=datetime.now()+timedelta(seconds=10)) + @scheduler.scheduled_job(trigger="date", run_date=datetime.now()+timedelta(seconds=15)) @scheduler.scheduled_job(trigger="interval", hours=configGet("interval", "scheduler", "cache_avatars")) async def cache_avatars(): list_of_users = [] @@ -103,7 +103,7 @@ if configGet("enabled", "features", "sponsorships") is True: # Register all bot commands -@scheduler.scheduled_job(trigger="date", run_date=datetime.now()+timedelta(seconds=3)) +@scheduler.scheduled_job(trigger="date", run_date=datetime.now()+timedelta(seconds=10)) async def commands_register(): commands = { -- 2.39.2 From 478fb174c522972b32d31a8e1e03d13b2ea57619 Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 14:44:21 +0100 Subject: [PATCH 16/23] Updated requirements --- requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 263ef71..4e0ff57 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ APScheduler==3.9.1.post1 -fastapi==0.88.0 +fastapi~=0.88.0 psutil==5.9.4 pymongo==4.3.3 -Pyrogram~=2.0.93 +Pyrogram~=2.0.95 requests==2.28.1 tgcrypto==1.2.5 python_dateutil==2.8.2 -starlette==0.23.0 -ujson==5.6.0 \ No newline at end of file +starlette~=0.23.1 +ujson~=5.7.0 \ No newline at end of file -- 2.39.2 From f5e3cd5a501b9960967b9e7e777118acfbd275bb Mon Sep 17 00:00:00 2001 From: profitroll Date: Mon, 9 Jan 2023 14:50:33 +0100 Subject: [PATCH 17/23] Fixed requirements --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4e0ff57..7b778a1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,5 +6,5 @@ Pyrogram~=2.0.95 requests==2.28.1 tgcrypto==1.2.5 python_dateutil==2.8.2 -starlette~=0.23.1 +starlette~=0.22.0 ujson~=5.7.0 \ No newline at end of file -- 2.39.2 From f83751c07d0dd62f3dca2b61b80ade06c895dce5 Mon Sep 17 00:00:00 2001 From: profitroll Date: Tue, 10 Jan 2023 12:07:27 +0100 Subject: [PATCH 18/23] Updated rules about spoilers --- locale/uk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/uk.json b/locale/uk.json index b449d67..1fc89d2 100644 --- a/locale/uk.json +++ b/locale/uk.json @@ -262,7 +262,7 @@ "description": "Надіслати цей спойлер до чату" } }, - "rules_msg": "📢Правила можуть доповнюватись та змінюватись, залежно від потреби. У такому разі, порушення, які були вчинені до введення (змінення) правила, порушеннями вважатися не будуть. Про всі зміни в правилах, ви будете проінформовані за допомогою закріплених повідомлень. Але вони не будуть закріплені на постійній основі, тому, час від часу, перевіряйте актуальність правил у боті.\n\n🔔Якщо ви бачите, як хтось із учасників порушив правила, тегніть одного із адмінів, у відповідь на повідомлення, яке, на вашу думку, є порушенням. У дописі до тегу, вкажіть, по якому пункту ви побачили порушення. Або перешліть повідомлення до будь кого із адміністраторів у особисті повідомлення, та коротко опишіть ситуацію.\nСписок адміністраторів: @Chirkopol @Za_NerZula @Denialvapr\nЗ питань функціонування бота звертайтесь до @Profitroll2281337\n\n❗️Будь-який заборонений контент, може бути відправлений до чату за допомогою бота - https://t.me/spoilerobot з повним описом контенту, що міститься під спойлером. За неправильний або некоректний опис, може бути видане попередження.\n\n‼️Видалені або змінені повідомлення, все ще є повідомленнями від вашого імені, які могли побачити учасники чату, і які можуть бути відстежені через адмінську панель.\n\n🔨 За порушення - ви отримаєте попередження. За наявності 3-х попереджень - мут на добу. За повторні порушення, ви одразу отримаєте покарання, без додаткових попереджень.", + "rules_msg": "📢Правила можуть доповнюватись та змінюватись, залежно від потреби. У такому разі, порушення, які були вчинені до введення (змінення) правила, порушеннями вважатися не будуть. Про всі зміни в правилах, ви будете проінформовані за допомогою закріплених повідомлень. Але вони не будуть закріплені на постійній основі, тому, час від часу, перевіряйте актуальність правил у боті.\n\n🔔Якщо ви бачите, як хтось із учасників порушив правила, тегніть одного із адмінів, у відповідь на повідомлення, яке, на вашу думку, є порушенням. У дописі до тегу, вкажіть, по якому пункту ви побачили порушення. Або перешліть повідомлення до будь кого із адміністраторів у особисті повідомлення, та коротко опишіть ситуацію.\nСписок адміністраторів: @Chirkopol @Za_NerZula @Denialvapr\nЗ питань функціонування бота звертайтесь до @Profitroll2281337\n\n❗️Будь-який заборонений контент, може бути відправлений допомогою команди /spoiler у бота - з повним описом контенту, що міститься під спойлером. За неправильний або некоректний опис, може бути видане попередження.\n\n‼️Видалені або змінені повідомлення, все ще є повідомленнями від вашого імені, які могли побачити учасники чату, і які можуть бути відстежені через адмінську панель.\n\n🔨 За порушення - ви отримаєте попередження. За наявності 3-х попереджень - мут на добу. За повторні порушення, ви одразу отримаєте покарання, без додаткових попереджень.", "rules": [ "1️⃣) \"HoloKyiv Chat\" та \"HoloUA (Hololive Ukraine) Chat\" створені виключно для українців (13+). В них можуть знаходитись тільки люди які: \n- Народились в Україні, та проживають, на данний момент, у ній.\n- Народились за межами України, але проживають у ній.\n- Народились в Україні але, на даний момент, не проживають у ній.\n\"HoloUA (Hololive Ukraine) Chat\" відкритий для усіх українців. Щоб потрапити до нього, заповніть, будь ласка, анкету, та дочекайтесь, поки її схвалять адміни.\nУ \"HoloKyiv Chat\" можна потрапити тільки особисто, якщо ви проживаєте у Київі, або є близьким другом одного із учасників чату. Із приводу додавання до чату пишіть @Chirkopol у приватні повідомлення.\n🔨 Якщо у процесі спілкування виявиться, що ви не українець, вас буде видалено із чату, до моменту, поки ви їм не станете. Без образ. Ми створюємо виключно українське ком'юніті.", "2️⃣) Заборонено поширення NSFW-контенту з прямим або частково прихованим порнографічним змістом. На контенті \"еротичного характеру\" повинні бути закриті \"сумнівні\" ділянки тіл. \nЗаборонено поширення шок-контенту з великою наявністю крові та/або фізичних пошкоджень.", -- 2.39.2 From b67b1daf7c614fac95b8e6ff46de9c82cba2cfd2 Mon Sep 17 00:00:00 2001 From: profitroll Date: Tue, 10 Jan 2023 12:07:40 +0100 Subject: [PATCH 19/23] Fixed logical hole in cancel command --- modules/commands/cancel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/commands/cancel.py b/modules/commands/cancel.py index a0d755c..4c86903 100644 --- a/modules/commands/cancel.py +++ b/modules/commands/cancel.py @@ -9,7 +9,7 @@ from modules import custom_filters # Cancel command =============================================================================================================== @app.on_message((custom_filters.enabled_applications | custom_filters.enabled_sponsorships) & ~filters.scheduled & filters.command("cancel", prefixes=["/"])) async def command_cancel(app: Client, msg: Message): - col_tmp.delete_many( {"user": msg.from_user.id} ) + col_tmp.delete_many( {"user": msg.from_user.id, "sent": False} ) col_spoilers.delete_many( {"user": msg.from_user.id, "completed": False} ) await msg.reply_text(locale("cancel", "message", locale=msg.from_user), quote=should_quote(msg), reply_markup=ReplyKeyboardRemove()) logWrite(f"Cancelling all ongoing tmp operations for {msg.from_user.id}") -- 2.39.2 From 00a408ac6cf5bd4786e8a6675aa72ad2377b4e9c Mon Sep 17 00:00:00 2001 From: profitroll Date: Tue, 10 Jan 2023 12:11:29 +0100 Subject: [PATCH 20/23] Added audio support for spoilers --- modules/commands/spoiler.py | 1 + modules/commands/start.py | 2 ++ modules/handlers/everything.py | 11 ++++++++--- validation/spoilers.json | 5 +++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/modules/commands/spoiler.py b/modules/commands/spoiler.py index 3f0e5e7..48b203e 100644 --- a/modules/commands/spoiler.py +++ b/modules/commands/spoiler.py @@ -30,6 +30,7 @@ async def cmd_spoiler(app: Client, msg: Message): "description": None, "photo": None, "video": None, + "audio": None, "animation": None, "document": None, "caption": None, diff --git a/modules/commands/start.py b/modules/commands/start.py index 55d42ab..85b8e0c 100644 --- a/modules/commands/start.py +++ b/modules/commands/start.py @@ -36,6 +36,8 @@ async def cmd_start(app: Client, msg: Message): await msg.reply_cached_media(spoiler["photo"], caption=spoiler["caption"]) if spoiler["video"] is not None: await msg.reply_cached_media(spoiler["video"], caption=spoiler["caption"]) + if spoiler["audio"] is not None: + await msg.reply_cached_media(spoiler["audio"], caption=spoiler["caption"]) if spoiler["animation"] is not None: await msg.reply_cached_media(spoiler["animation"], caption=spoiler["caption"]) if spoiler["document"] is not None: diff --git a/modules/handlers/everything.py b/modules/handlers/everything.py index 6270e8e..78d3fc3 100644 --- a/modules/handlers/everything.py +++ b/modules/handlers/everything.py @@ -89,7 +89,7 @@ async def any_stage(app: Client, msg: Message): await msg.reply_text(locale("spoiler_send_description", "message", locale=msg.from_user), reply_markup=ForceReply(placeholder=locale("spoiler_description", "force_reply", locale=msg.from_user))) return - if spoiler["description"] is None and (spoiler["photo"] is None and spoiler["video"] is None and spoiler["animation"] is None and spoiler["text"] is None): + if spoiler["description"] is None and (spoiler["photo"] is None and spoiler["video"] is None and spoiler["audio"] is None and spoiler["animation"] is None and spoiler["text"] is None): # for lc in all_locales("spoiler_description", "keyboard"): # if msg.text == lc[-1][0]: @@ -115,7 +115,12 @@ async def any_stage(app: Client, msg: Message): if msg.video is not None: col_spoilers.find_one_and_update( {"user": msg.from_user.id, "completed": False}, {"$set": {"video": msg.video.file_id, "caption": msg.caption, "completed": True}} ) - logWrite(f"Adding video with id {msg.video.file_id} to {msg.from_user.id}'s spoiler") + logWrite(f"Adding audio with id {msg.video.file_id} to {msg.from_user.id}'s spoiler") + ready = True + + if msg.audio is not None: + col_spoilers.find_one_and_update( {"user": msg.from_user.id, "completed": False}, {"$set": {"audio": msg.audio.file_id, "caption": msg.caption, "completed": True}} ) + logWrite(f"Adding video with id {msg.audio.file_id} to {msg.from_user.id}'s spoiler") ready = True if msg.animation is not None: @@ -128,7 +133,7 @@ async def any_stage(app: Client, msg: Message): 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 spoiler["photo"] is None and spoiler["video"] is None and spoiler["audio"] 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 c54cc48..a8a1cfe 100644 --- a/validation/spoilers.json +++ b/validation/spoilers.json @@ -7,6 +7,7 @@ "description", "photo", "video", + "audio", "animation", "document", "caption", @@ -38,6 +39,10 @@ "bsonType": ["string", "null"], "description": "Spoilered video" }, + "audio": { + "bsonType": ["string", "null"], + "description": "Spoilered audio" + }, "animation": { "bsonType": ["string", "null"], "description": "Spoilered animation/GIF" -- 2.39.2 From dabfa2ecef8540e6a9b0da85f861e30db42d15e2 Mon Sep 17 00:00:00 2001 From: profitroll Date: Tue, 10 Jan 2023 13:41:08 +0100 Subject: [PATCH 21/23] Added ftfy and length limit --- classes/holo_user.py | 25 +++++++++++++++++++++++++ locale/uk.json | 4 ++++ modules/handlers/everything.py | 6 ++++++ requirements.txt | 5 +++-- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/classes/holo_user.py b/classes/holo_user.py index bce31e9..cef36cf 100644 --- a/classes/holo_user.py +++ b/classes/holo_user.py @@ -1,5 +1,6 @@ from datetime import datetime from asyncio import sleep +from ftfy import fix_text from traceback import format_exc from app import app, isAnAdmin from typing import Any, List, Literal, Union @@ -122,6 +123,11 @@ class HoloUser(): * adm_context (`bool`, *optional*): Whether context sender is an admin. Defaults to False. """ + if text is not None: + text = fix_text(text) + elif caption is not None: + caption = fix_text(caption) + # Check if any text available and log message sending if text is not None: logWrite(f"{context.from_user.id} sent message '{text}' to {self.id} (source message: {context.id})") @@ -313,6 +319,9 @@ class HoloUser(): if progress["state"] == "fill" and progress["sent"] is False: + if msg.text is not None: + msg.text = fix_text(msg.text) + if stage == 2: try: @@ -359,6 +368,9 @@ class HoloUser(): return elif stage == 10: + if len(query) > 1024: + await msg.reply_text(locale("question10_too_long", "message", locale=self.locale), reply_markup=ForceReply(placeholder=str(locale(f"question{stage}", "force_reply", locale=self.locale)))) + return progress["application"][str(stage)] = query col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "application"}}, {"$set": {"application": progress["application"], "complete": True}}) application_content = [] @@ -378,6 +390,9 @@ class HoloUser(): await msg.reply_text(locale("confirm", "message", locale=self.locale).format("\n".join(application_content)), reply_markup=ReplyKeyboardMarkup(locale("confirm", "keyboard", locale=self.locale), resize_keyboard=True)) else: + if len(query) > 256: + await msg.reply_text(locale("question_too_long", "message", locale=self.locale), reply_markup=ForceReply(placeholder=str(locale(f"question{stage}", "force_reply", locale=self.locale)))) + return progress["application"][str(stage)] = query 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)))) @@ -430,10 +445,20 @@ class HoloUser(): stage = progress["stage"] + if msg.text is not None: + msg.text = fix_text(msg.text) + elif msg.caption is not None: + msg.caption = fix_text(msg.caption) + if progress["state"] == "fill" and progress["sent"] is False: if stage == 1: + if len(query) > 240: + logWrite(f"User {msg.from_user.id} failed stage {stage} due to sending invalid date format") + await msg.reply_text(locale(f"sponsor1_invalid", "message", locale=self.locale), reply_markup=ForceReply(placeholder=str(locale(f"sponsor{stage}", "force_reply", locale=self.locale)))) + return + progress["sponsorship"]["streamer"] = query 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)))) diff --git a/locale/uk.json b/locale/uk.json index 1fc89d2..bf71dec 100644 --- a/locale/uk.json +++ b/locale/uk.json @@ -13,6 +13,7 @@ "question8": "Чи дивишся ти стріми дівчат Хололайву?", "question9": "Чиї пісні з Хололайву тобі подобаються найбільше?", "question10": "Ну і нарешті, розкажи трохи про себе. Про хобі, чим тобі подобається займатись. Одним повідомленням, будь ласка.", + "question_too_long": "Текст занадто довгий. Будь ласка, умісти відповідь у 256 символів.", "question2_underage": "Вибач, але треба досягти віку {0} років, щоб приєднатись до нас. Такі обмеження існують для того, щоб всім у спільноті було цікаво одне з одним.", "question2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`", "question2_joke": "Шутнік, ми так і поняли. Але будь ласка, введи реальне значення.", @@ -20,9 +21,11 @@ "question3_found": "Використовую наступний результат:\n• {0} ({1})", "question3_error": "⚠️ **Сталась помилка**\nНе вдалось отримати географічну мітку. Розробника повідомлено про цю помилку. Будь ласка, спробуйте ще раз.", "question3_traceback": "⚠️ **Сталась помилка**\nПомилка отримання геокодингу для `{0}`\nПомилка: `{1}`\n\nTraceback:\n```\n{2}\n```", + "question10_too_long": "Текст занадто довгий. Будь ласка, умісти відповідь у 1024 символи.", "sponsorship_apply": "ℹ️ Оформіть платну підписку на когось з Холо, заповніть форму та отримайте особливу роль в якості винагороди!", "sponsorship_applying": "ℹ️ Розпочато заповнення форми на отримання бонусів за платну підписку на холодівчат.", "sponsor1": "На яку саме дівчину платна підписка?", + "sponsor1_invalid": "Будь ласка, введіть ім'я не довше за 240 символів", "sponsor2": "До якої дати (`ДД.ММ.РРРР`) підписка?", "sponsor2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`", "sponsor2_past": "Вказана дата знаходиться в минулому. Будь ласка, вкажіть правильний термін дії підписки", @@ -108,6 +111,7 @@ "spoiler_empty": "Спойлер категорії \"{0}\" без опису", "spoiler_described": "Спойлер категорії \"{0}\": {1}", "spoiler_description_enter": "Добре, введіть бажаний опис спойлера", + "spoiler_description_too_long": "Текст занадто довгий. Будь ласка, умісти опис у 1024 символи.", "spoiler_using_description": "Встановлено опис спойлера: {0}\n\nЗалишилось додати вміст самого спойлера. Бот приймає текстове повідомлення, фото, відео, файл а також гіф зображення (1 шт.)", "spoiler_send_description": "Тепер треба надіслати коротенький опис спойлера, щоб люди розуміли що під ним варто очкувати. Надішли мінус (-) щоб пропустити цей крок.", "spoiler_ready": "Успіх! Спойлер створено. Користуйтесь кнопкою нижче щоб надіслати його.", diff --git a/modules/handlers/everything.py b/modules/handlers/everything.py index 78d3fc3..eaf83cb 100644 --- a/modules/handlers/everything.py +++ b/modules/handlers/everything.py @@ -1,6 +1,7 @@ from traceback import print_exc from app import app, isAnAdmin import asyncio +from ftfy import fix_text from pyrogram import filters from pyrogram.types import Message, ForceReply, InlineKeyboardMarkup, InlineKeyboardButton from pyrogram.client import Client @@ -95,8 +96,13 @@ async def any_stage(app: Client, msg: Message): # if msg.text == lc[-1][0]: # await msg.reply_text(locale("spoiler_description_enter", "message", locale=msg.from_user), reply_markup=ForceReply(placeholder=locale("spoiler_description", "force_reply", locale=msg.from_user))) # return + if msg.text != "-": + msg.text = fix_text(msg.text) + if len(msg.text) > 1024: + await msg.reply_text(locale("spoiler_description_too_long", "message", locale=msg.from_user), reply_markup=ForceReply(placeholder=locale("spoiler_description", "force_reply", locale=msg.from_user))) + return col_spoilers.find_one_and_update( {"user": msg.from_user.id, "completed": False}, {"$set": {"description": msg.text}} ) else: col_spoilers.find_one_and_update( {"user": msg.from_user.id, "completed": False}, {"$set": {"description": ""}} ) diff --git a/requirements.txt b/requirements.txt index 7b778a1..8e2a18e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,9 +2,10 @@ APScheduler==3.9.1.post1 fastapi~=0.88.0 psutil==5.9.4 pymongo==4.3.3 -Pyrogram~=2.0.95 +Pyrogram~=2.0.96 requests==2.28.1 tgcrypto==1.2.5 python_dateutil==2.8.2 starlette~=0.22.0 -ujson~=5.7.0 \ No newline at end of file +ujson~=5.7.0 +ftfy~=6.1.1 \ No newline at end of file -- 2.39.2 From 92386ac8ce6614cd1813fdfaa49315cafc74863f Mon Sep 17 00:00:00 2001 From: profitroll Date: Wed, 11 Jan 2023 12:28:58 +0100 Subject: [PATCH 22/23] Fixed some logic holes --- classes/holo_user.py | 5 ++--- modules/callbacks/reapply.py | 11 +++++++++-- modules/handlers/confirmation.py | 16 ++++++++++++---- modules/handlers/welcome.py | 5 +++-- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/classes/holo_user.py b/classes/holo_user.py index cef36cf..d06acca 100644 --- a/classes/holo_user.py +++ b/classes/holo_user.py @@ -281,10 +281,9 @@ class HoloUser(): """Reset application of a user in tmp collection and replace it with an empty one """ if col_tmp.find_one({"user": self.id, "type": "application"}) is None: - col_tmp.insert_one(document=DefaultApplicationTemp(self.id).dict) - else: - col_tmp.delete_one({"user": self.id, "type": "application"}) col_tmp.insert_one(document=DefaultApplicationTemp(self.id, reapply=reapply).dict) + else: + col_tmp.find_one_and_replace({"user": self.id, "type": "application"}, DefaultApplicationTemp(self.id, reapply=reapply).dict) async def application_next(self, query: str, msg: Message) -> None: """Move on filling application of user diff --git a/modules/callbacks/reapply.py b/modules/callbacks/reapply.py index 3f6a523..ded851d 100644 --- a/modules/callbacks/reapply.py +++ b/modules/callbacks/reapply.py @@ -21,8 +21,15 @@ async def callback_reapply_query_accept(app: Client, clb: CallbackQuery): await app.send_message(holo_user.id, locale("approved_joined", "message", locale=holo_user)) - col_applications.delete_one({"user": holo_user.id}) - col_applications.insert_one({"user": holo_user.id, "date": datetime.now(), "admin": clb.from_user.id, "application": col_tmp.find_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "application"}})["application"]}) + applications = col_applications.find({"user": holo_user.id}) + + if len(list(applications)) > 1: + col_applications.delete_many({"user": holo_user.id}) + col_applications.insert_one({"user": holo_user.id, "date": datetime.now(), "admin": clb.from_user.id, "application": col_tmp.find_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "application"}})["application"]}) + elif applications == 1: + col_applications.find_one_and_replace({"user": holo_user.id}, {"user": holo_user.id, "date": datetime.now(), "admin": clb.from_user.id, "application": col_tmp.find_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "application"}})["application"]}) + else: + col_applications.insert_one({"user": holo_user.id, "date": datetime.now(), "admin": clb.from_user.id, "application": col_tmp.find_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "application"}})["application"]}) col_tmp.update_one({"user": holo_user.id, "type": "application"}, {"$set": {"state": "approved", "sent": False}}) edited_markup = [[InlineKeyboardButton(text=str(locale("accepted", "button")), callback_data="nothing")]] diff --git a/modules/handlers/confirmation.py b/modules/handlers/confirmation.py index ee0115a..364a276 100644 --- a/modules/handlers/confirmation.py +++ b/modules/handlers/confirmation.py @@ -9,7 +9,7 @@ from pyrogram.enums.parse_mode import ParseMode from classes.holo_user import HoloUser from modules.utils import all_locales, configGet, locale, logWrite from modules.handlers.welcome import welcome_pass -from modules.database import col_tmp +from modules.database import col_tmp, col_applications from modules import custom_filters # Confirmation ================================================================================================================= @@ -54,8 +54,12 @@ async def confirm_yes(app: Client, msg: Message, kind: Literal["application", "s i += 1 - if tmp_application["reapply"]: - await app.send_message(chat_id=configGet("admin", "groups"), text=(locale("reapply_got", "message")).format(str(holo_user.id), msg.from_user.first_name, msg.from_user.username, "\n".join(application_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( + if tmp_application["reapply"] is True and col_applications.find_one({"user": holo_user.id}) is not None: + await app.send_message( + chat_id=configGet("admin", "groups"), + text=(locale("reapply_got", "message")).format(str(holo_user.id),msg.from_user.first_name, msg.from_user.username, "\n".join(application_content)), + parse_mode=ParseMode.MARKDOWN, + reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton(text=str(locale("reapply_yes", "button")), callback_data=f"reapply_yes_{holo_user.id}") @@ -67,7 +71,11 @@ async def confirm_yes(app: Client, msg: Message, kind: Literal["application", "s ) ) else: - await app.send_message(chat_id=configGet("admin", "groups"), text=(locale("application_got", "message")).format(str(holo_user.id), msg.from_user.first_name, msg.from_user.username, "\n".join(application_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( + await app.send_message( + chat_id=configGet("admin", "groups"), + text=(locale("application_got", "message")).format(str(holo_user.id), msg.from_user.first_name, msg.from_user.username, "\n".join(application_content)), + parse_mode=ParseMode.MARKDOWN, + reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton(text=str(locale("sub_yes", "button")), callback_data=f"sub_yes_{holo_user.id}") diff --git a/modules/handlers/welcome.py b/modules/handlers/welcome.py index 45c2ca7..9194174 100644 --- a/modules/handlers/welcome.py +++ b/modules/handlers/welcome.py @@ -13,7 +13,7 @@ for pattern in all_locales("welcome", "keyboard"): for pattern in all_locales("return", "keyboard"): welcome_1.append(pattern[0][0]) @app.on_message(custom_filters.enabled_applications & ~filters.scheduled & filters.private & filters.command(welcome_1, prefixes=[""])) -async def welcome_pass(app: Client, msg: Message, once_again: bool = True) -> None: +async def welcome_pass(app: Client, msg: Message, once_again: bool = False) -> None: """Set user's stage to 1 and start a fresh application ### Args: @@ -27,7 +27,8 @@ async def welcome_pass(app: Client, msg: Message, once_again: bool = True) -> No holo_user = HoloUser(msg.from_user) - holo_user.application_restart() + if once_again is False: + holo_user.application_restart() logWrite(f"User {msg.from_user.id} confirmed starting the application") await msg.reply_text(locale("question1", "message", locale=msg.from_user), reply_markup=ForceReply(placeholder=locale("question1", "force_reply", locale=msg.from_user))) -- 2.39.2 From ecbf7d8b7836928ab104de62f8e0a77d5704e472 Mon Sep 17 00:00:00 2001 From: profitroll Date: Wed, 11 Jan 2023 12:53:20 +0100 Subject: [PATCH 23/23] Updated ignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index daa0805..796d839 100644 --- a/.gitignore +++ b/.gitignore @@ -161,4 +161,6 @@ data TASK.md inline_bot.py .vscode -migrate.py \ No newline at end of file +migrate.py +validation/* +!validation/*.json \ No newline at end of file -- 2.39.2