Merge pull request 'Bug fixes and small structural changes' (#7) from dev into master

Reviewed-on: profitroll/HoloCheckerBot#7
This commit is contained in:
Profitroll 2023-01-06 17:01:20 +02:00
commit 234b73add0
19 changed files with 151 additions and 134 deletions

View File

@ -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```")

View File

@ -1,75 +1,16 @@
from datetime import datetime from datetime import datetime
from traceback import print_exc from traceback import format_exc
from app import app, isAnAdmin from app import app, isAnAdmin
from typing import Any, List, Literal, Union from typing import Any, List, Literal, Union
from pyrogram.types import User, ChatMember, ChatPrivileges, Chat, Message, Photo, Video, Document, Animation, Voice, ForceReply, ReplyKeyboardMarkup from pyrogram.types import User, ChatMember, ChatPrivileges, Chat, Message, Photo, Video, Document, Animation, Voice, ForceReply, ReplyKeyboardMarkup
from pyrogram.errors import bad_request_400 from pyrogram.errors import bad_request_400
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from classes.errors.geo import PlaceNotFoundError 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.database import col_tmp, col_users, col_applications, col_sponsorships, col_messages, col_spoilers
from modules.logging import logWrite 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):
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 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 HoloUser(): class HoloUser():
"""This object represents a user of HoloChecker bot. """This object represents a user of HoloChecker bot.
@ -215,11 +156,11 @@ class HoloUser():
if photo is not None: if photo is not None:
if isinstance(photo, Photo): if isinstance(photo, Photo):
photo = photo.file_id 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: elif video is not None:
if isinstance(video, Video): if isinstance(video, Video):
video = video.file_id 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: elif file is not None:
if isinstance(file, Document): if isinstance(file, Document):
file = file.file_id file = file.file_id
@ -227,7 +168,7 @@ class HoloUser():
elif animation is not None: elif animation is not None:
if isinstance(animation, Animation): if isinstance(animation, Animation):
animation = animation.file_id 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: elif voice is not None:
if isinstance(voice, Voice): if isinstance(voice, Voice):
voice = voice.file_id voice = voice.file_id
@ -240,11 +181,11 @@ class HoloUser():
if photo is not None: if photo is not None:
if isinstance(photo, Photo): if isinstance(photo, Photo):
photo = photo.file_id 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: elif video is not None:
if isinstance(video, Video): if isinstance(video, Video):
video = video.file_id 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: elif file is not None:
if isinstance(file, Document): if isinstance(file, Document):
file = file.file_id file = file.file_id
@ -252,11 +193,11 @@ class HoloUser():
elif animation is not None: elif animation is not None:
if isinstance(animation, Animation): if isinstance(animation, Animation):
animation = animation.file_id 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: elif voice is not None:
if isinstance(voice, Voice): if isinstance(voice, Voice):
voice = voice.file_id 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: else:
new_message = await app.send_message(self.id, text) new_message = await app.send_message(self.id, text)
@ -266,9 +207,9 @@ class HoloUser():
# Report to admin and to sender about message sending failure # Report to admin and to sender about message sending failure
except Exception as exp: 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: 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: except bad_request_400.PeerIdInvalid:
logWrite(f"Could not notify admin about failure when sending message! Admin has never interacted with bot!") 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)) await context.reply_text(locale("message_error", "message"), quote=should_quote(context))
@ -288,10 +229,9 @@ class HoloUser():
if not await isAnAdmin(self.id): if not await isAnAdmin(self.id):
await app.set_administrator_title(configGet("users", "groups"), self.id, label) await app.set_administrator_title(configGet("users", "groups"), self.id, label)
self.set("label", label) self.set("label", label)
except bad_request_400.UserCreator: except Exception as exp:
logWrite(f"Could not set {self.id}'s title to '{self.label}' because of bad_request_400.UserCreator") logWrite(f"Could not set {self.id}'s title to '{self.label}' due to {exp}")
except bad_request_400.ChatAdminRequired: raise LabelSettingError(exp, format_exc())
logWrite(f"Could not set {self.id}'s title to '{self.label}' because of bad_request_400.ChatAdminRequired")
async def label_reset(self, chat: Chat) -> None: async def label_reset(self, chat: Chat) -> None:
"""Reset label in destination group """Reset label in destination group
@ -391,7 +331,6 @@ class HoloUser():
return return
else: 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 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}}) 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)))) 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 +351,7 @@ class HoloUser():
except Exception as exp: 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)))) 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: 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: except bad_request_400.PeerIdInvalid:
logWrite(f"Could not notify admin about failure when sending message! Admin has never interacted with bot!") logWrite(f"Could not notify admin about failure when sending message! Admin has never interacted with bot!")
return return
@ -483,12 +422,9 @@ class HoloUser():
* msg (`Message`): Message that should receive replies * 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 not None:
if progress is None:
return
stage = progress["stage"] stage = progress["stage"]
@ -522,7 +458,7 @@ class HoloUser():
elif stage == 3: elif stage == 3:
if photo is not None: 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}}) 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)))) 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))))
@ -532,8 +468,8 @@ class HoloUser():
return return
progress["sponsorship"]["label"] = query progress["sponsorship"]["label"] = query
col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"sponsorship": progress["sponsorship"], "complete": True}}) col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"sponsorship": progress["sponsorship"], "complete": True}})
await msg.reply_photo( await msg.reply_cached_media(
photo=create_tmp(progress["sponsorship"]["proof"], kind="image"), progress["sponsorship"]["proof"],
caption=locale("sponsor_confirm", "message", locale=self.locale).format( caption=locale("sponsor_confirm", "message", locale=self.locale).format(
progress["sponsorship"]["streamer"], progress["sponsorship"]["streamer"],
progress["sponsorship"]["expires"].strftime("%d.%m.%Y"), progress["sponsorship"]["expires"].strftime("%d.%m.%Y"),

46
classes/templates.py Normal file
View File

@ -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": ""
}
}

View File

@ -41,7 +41,6 @@ from modules.handlers.contact import *
from modules.handlers.group_join import * from modules.handlers.group_join import *
from modules.handlers.voice import * from modules.handlers.voice import *
from modules.handlers.welcome import * from modules.handlers.welcome import *
from modules.handlers.sponsorship import *
from modules.handlers.everything import * from modules.handlers.everything import *
from modules.scheduled import * from modules.scheduled import *

View File

@ -108,10 +108,10 @@
"spoiler_empty": "Спойлер категорії \"{0}\" без опису", "spoiler_empty": "Спойлер категорії \"{0}\" без опису",
"spoiler_described": "Спойлер категорії \"{0}\": {1}", "spoiler_described": "Спойлер категорії \"{0}\": {1}",
"spoiler_description_enter": "Добре, введіть бажаний опис спойлера", "spoiler_description_enter": "Добре, введіть бажаний опис спойлера",
"spoiler_using_description": "Встановлено опис спойлера: {0}\n\nЗалишилось додати вміст самого спойлера. Бот приймає текстове повідомлення, фото, відео а також гіф зображення (1 шт.)", "spoiler_using_description": "Встановлено опис спойлера: {0}\n\nЗалишилось додати вміст самого спойлера. Бот приймає текстове повідомлення, фото, відео, файл а також гіф зображення (1 шт.)",
"spoiler_send_description": "Тепер треба надіслати коротенький опис спойлера, щоб люди розуміли що під ним варто очкувати. Надішли мінус (-) щоб пропустити цей крок.", "spoiler_send_description": "Тепер треба надіслати коротенький опис спойлера, щоб люди розуміли що під ним варто очкувати. Надішли мінус (-) щоб пропустити цей крок.",
"spoiler_ready": "Успіх! Спойлер створено. Користуйтесь кнопкою нижче щоб надіслати його.", "spoiler_ready": "Успіх! Спойлер створено. Користуйтесь кнопкою нижче щоб надіслати його.",
"spoiler_incorrect_content": "Бот не підтримує такий контент. Будь ласка, надішли текст, фото, відео або анімацію (гіф).", "spoiler_incorrect_content": "Бот не підтримує такий контент. Будь ласка, надішли текст, фото, відео, файл або анімацію (гіф).",
"spoiler_incorrect_category": "Вказана категорія не є дійсною. Будь ласка, користуйся клавіатурою бота (кнопка біля 📎) для вибору категорії.", "spoiler_incorrect_category": "Вказана категорія не є дійсною. Будь ласка, користуйся клавіатурою бота (кнопка біля 📎) для вибору категорії.",
"spoiler_in_progress": "❌ **Дія неможлива**\nПерш ніж починати нову дію, треба завершити створення спойлера або перервати його командою /cancel.", "spoiler_in_progress": "❌ **Дія неможлива**\nПерш ніж починати нову дію, треба завершити створення спойлера або перервати його командою /cancel.",
"yes": "Так", "yes": "Так",

View File

@ -3,6 +3,7 @@ from app import app
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ForceReply, CallbackQuery from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ForceReply, CallbackQuery
from pyrogram.client import Client from pyrogram.client import Client
from pyrogram import filters from pyrogram import filters
from classes.errors.holo_user import LabelSettingError
from classes.holo_user import HoloUser from classes.holo_user import HoloUser
from modules.utils import configGet, locale, logWrite, should_quote from modules.utils import configGet, locale, logWrite, should_quote
from modules.database import col_tmp, col_sponsorships from modules.database import col_tmp, col_sponsorships
@ -67,7 +68,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")]] edited_markup = [[InlineKeyboardButton(text=str(locale("accepted", "button")), callback_data="nothing")]]

View File

@ -5,7 +5,8 @@ from pyrogram.enums.parse_mode import ParseMode
from pyrogram.types import Message from pyrogram.types import Message
from pyrogram.errors import bad_request_400 from pyrogram.errors import bad_request_400
from pyrogram.client import Client 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 modules.utils import logWrite, locale, should_quote
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from modules.database import col_applications from modules.database import col_applications

View File

@ -5,7 +5,8 @@ from pyrogram.types import Message
from pyrogram.client import Client from pyrogram.client import Client
from pyrogram.errors import bad_request_400 from pyrogram.errors import bad_request_400
from pyrogram.enums.chat_action import ChatAction 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.utils import jsonLoad, should_quote, logWrite, locale, download_tmp, create_tmp, find_user
from modules import custom_filters from modules import custom_filters

View File

@ -2,8 +2,9 @@ from app import app
from pyrogram import filters from pyrogram import filters
from pyrogram.types import Message from pyrogram.types import Message
from pyrogram.client import Client from pyrogram.client import Client
from modules.utils import locale, should_quote, find_user from modules.utils import configGet, locale, should_quote, find_user
from classes.holo_user import HoloUser, LabelTooLongError from classes.errors.holo_user import LabelTooLongError, LabelSettingError
from classes.holo_user import HoloUser
from modules import custom_filters from modules import custom_filters
# Label command ================================================================================================================ # Label command ================================================================================================================
@ -32,6 +33,9 @@ async def cmd_label(app: Client, msg: Message):
except LabelTooLongError: except LabelTooLongError:
await msg.reply_text(locale("label_too_long", "message")) await msg.reply_text(locale("label_too_long", "message"))
return 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)) await msg.reply_text(f"Setting **{target.id}**'s label to **{label}**...", quote=should_quote(msg))
else: else:

View File

@ -2,8 +2,9 @@ from app import app
from pyrogram import filters from pyrogram import filters
from pyrogram.types import Message from pyrogram.types import Message
from pyrogram.client import Client from pyrogram.client import Client
from classes.errors.holo_user import UserInvalidError
from classes.holo_user import HoloUser from classes.holo_user import HoloUser
from modules.utils import logWrite, locale, should_quote from modules.utils import logWrite, locale, should_quote, find_user
from modules import custom_filters from modules import custom_filters
# Message command ============================================================================================================== # Message command ==============================================================================================================
@ -14,15 +15,15 @@ async def cmd_message(app: Client, msg: Message):
try: try:
destination = HoloUser(int(msg.command[1])) destination = HoloUser(int(msg.command[1]))
except ValueError: except (ValueError, UserInvalidError):
destination = HoloUser(msg.command[1]) destination = HoloUser(await find_user(app, query=msg.command[1]))
if ((msg.text is not None) and (len(msg.text.split()) > 2)): 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)): 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: 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: except IndexError:
await msg.reply_text(locale("message_invalid_syntax", "message", locale=msg.from_user), quote=should_quote(msg)) await msg.reply_text(locale("message_invalid_syntax", "message", locale=msg.from_user), quote=should_quote(msg))

View File

@ -2,7 +2,8 @@ from app import app
from pyrogram import filters from pyrogram import filters
from pyrogram.types import Message, ReplyKeyboardMarkup from pyrogram.types import Message, ReplyKeyboardMarkup
from pyrogram.client import Client 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.logging import logWrite
from modules.utils import locale from modules.utils import locale
from modules.database import col_spoilers from modules.database import col_spoilers
@ -30,6 +31,7 @@ async def cmd_spoiler(app: Client, msg: Message):
"photo": None, "photo": None,
"video": None, "video": None,
"animation": None, "animation": None,
"document": None,
"caption": None, "caption": None,
"text": None "text": None
} }

View File

@ -33,11 +33,13 @@ async def cmd_start(app: Client, msg: Message):
try: try:
spoiler = col_spoilers.find_one( {"_id": ObjectId(msg.command[1])} ) spoiler = col_spoilers.find_one( {"_id": ObjectId(msg.command[1])} )
if spoiler["photo"] is not None: 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: 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: 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: if spoiler["text"] is not None:
await msg.reply_text(spoiler["text"]) await msg.reply_text(spoiler["text"])
except InvalidId: except InvalidId:

View File

@ -1,6 +1,4 @@
from os import remove, sep
from typing import Literal from typing import Literal
from uuid import uuid1
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from datetime import datetime from datetime import datetime
from app import app from app import app
@ -115,13 +113,11 @@ async def confirm_yes(app: Client, msg: Message, kind: Literal["application", "s
if question == "expires": if question == "expires":
sponsorship_content.append(f"{locale(f'question_{question}', 'message', 'sponsor_titles')} {tmp_sponsorship['sponsorship'][question].strftime('%d.%m.%Y')}") sponsorship_content.append(f"{locale(f'question_{question}', 'message', 'sponsor_titles')} {tmp_sponsorship['sponsorship'][question].strftime('%d.%m.%Y')}")
elif question == "proof": elif question == "proof":
filename = uuid1() continue
with open(f"tmp{sep}{filename}.jpg", "wb") as f:
f.write(tmp_sponsorship['sponsorship']['proof'])
else: else:
sponsorship_content.append(f"{locale(f'question_{question}', 'message', 'sponsor_titles')} {tmp_sponsorship['sponsorship'][question]}") 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_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}") InlineKeyboardButton(text=str(locale("sponsor_yes", "button")), callback_data=f"sponsor_yes_{holo_user.id}")
@ -133,7 +129,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") logWrite(f"User {holo_user.id} sent his sponsorship application and it will now be reviewed")

View File

@ -2,7 +2,7 @@ from traceback import print_exc
from app import app, isAnAdmin from app import app, isAnAdmin
import asyncio import asyncio
from pyrogram import filters 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 pyrogram.client import Client
from classes.holo_user import HoloUser from classes.holo_user import HoloUser
from modules.utils import configGet, logWrite, locale, all_locales from modules.utils import configGet, logWrite, locale, all_locales
@ -43,6 +43,8 @@ async def any_stage(app: Client, msg: Message):
photo=msg.photo, photo=msg.photo,
video=msg.video, video=msg.video,
file=msg.document, file=msg.document,
animation=msg.animation,
voice=msg.voice,
adm_origin=await isAnAdmin(context_message.from_user.id), adm_origin=await isAnAdmin(context_message.from_user.id),
adm_context=await isAnAdmin(msg.from_user.id) adm_context=await isAnAdmin(msg.from_user.id)
) )
@ -55,7 +57,11 @@ async def any_stage(app: Client, msg: Message):
await holo_user.application_next(msg.text, msg=msg) await holo_user.application_next(msg.text, msg=msg)
if configGet("enabled", "features", "sponsorships") is True: 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": if holo_user.application_state()[0] != "fill" and holo_user.sponsorship_state()[0] != "fill":
@ -117,7 +123,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") logWrite(f"Adding animation with id {msg.animation.file_id} to {msg.from_user.id}'s spoiler")
ready = True 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: 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}} ) 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") logWrite(f"Adding text '{msg.text}' to {msg.from_user.id}'s spoiler")

View File

@ -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)

View File

@ -9,7 +9,8 @@ from pyrogram.client import Client
from pyrogram.enums.chat_type import ChatType from pyrogram.enums.chat_type import ChatType
from pyrogram.enums.chat_members_filter import ChatMembersFilter from pyrogram.enums.chat_members_filter import ChatMembersFilter
from dateutil.relativedelta import relativedelta 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.utils import configGet, locale
from modules.database import col_applications, col_spoilers from modules.database import col_applications, col_spoilers
from bson.objectid import ObjectId from bson.objectid import ObjectId

View File

@ -2,9 +2,9 @@ APScheduler==3.9.1.post1
fastapi==0.88.0 fastapi==0.88.0
psutil==5.9.4 psutil==5.9.4
pymongo==4.3.3 pymongo==4.3.3
Pyrogram==2.0.69 Pyrogram~=2.0.93
requests==2.28.1 requests==2.28.1
tgcrypto==1.2.5 tgcrypto==1.2.5
python_dateutil==2.8.2 python_dateutil==2.8.2
starlette==0.22.0 starlette==0.23.0
ujson==5.6.0 ujson==5.6.0

View File

@ -8,6 +8,7 @@
"photo", "photo",
"video", "video",
"animation", "animation",
"document",
"caption", "caption",
"text" "text"
], ],
@ -41,6 +42,10 @@
"bsonType": ["string", "null"], "bsonType": ["string", "null"],
"description": "Spoilered animation/GIF" "description": "Spoilered animation/GIF"
}, },
"document": {
"bsonType": ["string", "null"],
"description": "Spoilered document/file"
},
"caption": { "caption": {
"bsonType": ["string", "null"], "bsonType": ["string", "null"],
"description": "Spoilered caption for media" "description": "Spoilered caption for media"

View File

@ -33,7 +33,7 @@
"bsonType": "date" "bsonType": "date"
}, },
"sponsorship.proof": { "sponsorship.proof": {
"bsonType": "binData" "bsonType": "string"
}, },
"sponsorship.label": { "sponsorship.label": {
"bsonType": "string" "bsonType": "string"