Added sponsorship support

This commit is contained in:
Profitroll 2022-12-22 15:05:27 +01:00
parent ac5a0d112f
commit 95e9fdf460
8 changed files with 294 additions and 43 deletions

View File

@ -1,4 +1,6 @@
from datetime import datetime from datetime import datetime
from os import sep
from uuid import uuid1
from requests import get from requests import get
from traceback import print_exc from traceback import print_exc
from app import app, isAnAdmin from app import app, isAnAdmin
@ -35,6 +37,24 @@ class DefaultApplicationTemp(dict):
} }
} }
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): class UserNotFoundError(Exception):
"""HoloUser could not find user with such an ID in database""" """HoloUser could not find user with such an ID in database"""
def __init__(self, user, user_id): def __init__(self, user, user_id):
@ -103,18 +123,18 @@ class HoloUser():
if isinstance(user, User): if isinstance(user, User):
if (self.name != user.first_name) and hasattr(user, "first_name") and (user.first_name is not None): if (self.name != user.first_name) and hasattr(user, "first_name") and (user.first_name is not None):
self.set("tg_name", user.first_name) self.set("name", user.first_name, db_key="tg_name")
if (self.phone != user.phone_number) and hasattr(user, "phone_number") and (user.phone_number is not None): if (self.phone != user.phone_number) and hasattr(user, "phone") and (user.phone_number is not None):
self.set("tg_phone", user.phone_number) self.set("phone", user.phone_number, db_key="tg_phone")
if (self.locale != user.language_code) and hasattr(user, "language_code") and (user.language_code is not None): if (self.locale != user.language_code) and hasattr(user, "locale") and (user.language_code is not None):
self.set("tg_locale", user.language_code) self.set("locale", user.language_code, db_key="tg_locale")
if (self.username != user.username) and hasattr(user, "username") and (user.username is not None): if (self.username != user.username) and hasattr(user, "username") and (user.username is not None):
self.set("tg_username", user.username) self.set("username", user.username, db_key="tg_username")
def set(self, key: str, value: Any) -> None: def set(self, key: str, value: Any, db_key: Union[str, None] = None) -> None:
"""Set attribute data and save it into database """Set attribute data and save it into database
### Args: ### Args:
@ -124,7 +144,8 @@ class HoloUser():
if not hasattr(self, key): if not hasattr(self, key):
raise AttributeError() raise AttributeError()
setattr(self, key, value) setattr(self, key, value)
col_users.update_one(filter={"_id": self.db_id}, update={ "$set": { key: value } }, upsert=True) db_key = key if db_key is None else db_key
col_users.update_one(filter={"_id": self.db_id}, update={ "$set": { db_key: value } }, upsert=True)
logWrite(f"Set attribute {key} of user {self.id} to {value}") logWrite(f"Set attribute {key} of user {self.id} to {value}")
async def message(self, async def message(self,
@ -395,3 +416,96 @@ class HoloUser():
else: else:
return return
def sponsorship_state(self) -> tuple[Literal["none", "fill", "approved", "rejected"], bool]:
"""Check the current state of sponsorship in tmp collection
### Returns:
* `tuple[Literal["none", "fill", "approved", "rejected"], bool]`: First element is an enum of a state and the second one is whether sponsorship application is complete.
"""
tmp_sponsorship = col_tmp.find_one({"user": self.id, "type": "sponsorship"})
if tmp_sponsorship is None:
return "none", False
else:
return tmp_sponsorship["state"], tmp_sponsorship["complete"]
def sponsorship_valid(self) -> bool:
"""Check whether user has a valid sponsorship
### Returns:
* `bool`: `True` if yes and `False` if no
"""
return True if col_sponsorships.find_one({"user": self.id, "expires": {"$gt": datetime.now()}}) is not None else False
def sponsorship_restart(self) -> None:
"""Reset sponsorship of a user in tmp collection and replace it with an empty one
"""
if col_tmp.find_one({"user": self.id, "type": "sponsorship"}) is None:
col_tmp.insert_one(document=DefaultSponsorshipTemp(self.id).dict)
else:
col_tmp.delete_one({"user": self.id, "type": "sponsorship"})
col_tmp.insert_one(document=DefaultSponsorshipTemp(self.id).dict)
async def sponsorship_next(self, query: str, msg: Message, photo: Union[Photo, None] = None) -> None:
"""Move on filling sponsorship of user
### Args:
* query (`str`): Some kind of input
* 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"})
stage = progress["stage"]
if progress["state"] == "fill":
if stage == 1:
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))))
elif stage == 2:
try:
input_dt = datetime.strptime(query, "%d.%m.%Y")
except ValueError:
logWrite(f"User {msg.from_user.id} failed stage {stage} due to sending invalid date format")
await msg.reply_text(locale(f"sponsor2_invalid", "message", locale=self.locale), reply_markup=ForceReply(placeholder=str(locale(f"sponsor{stage}", "force_reply", locale=self.locale))))
return
if datetime.now() >= input_dt:
logWrite(f"User {msg.from_user.id} failed stage {stage} due to sending date in the past")
await msg.reply_text(locale("sponsor2_past", "message", locale=self.locale), reply_markup=ForceReply(placeholder=str(locale("sponsor2", "force_reply", locale=self.locale))))
return
else:
progress["sponsorship"]["expires"] = input_dt
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))))
elif stage == 3:
if photo is not None:
filename = uuid1()
await app.download_media(photo.file_id, f"tmp{sep}{filename}")
with open(f"tmp{sep}{filename}", "rb") as f:
photo_bytes = f.read()
progress["sponsorship"]["proof"] = photo_bytes
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))))
elif stage == 4:
progress["sponsorship"]["label"] = query
col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"sponsorship": progress["sponsorship"], "complete": True}})
await msg.reply_text("Sponsorship application is filled. Want to send it?", reply_markup=ReplyKeyboardMarkup(locale("confirm", "keyboard", locale=self.locale), resize_keyboard=True))
else:
return
logWrite(f"User {self.id} completed stage {stage} of sponsorship")
else:
return

View File

@ -24,12 +24,16 @@
"sponsor1": "На яку саме дівчину платна підписка?", "sponsor1": "На яку саме дівчину платна підписка?",
"sponsor2": "До якої дати (`ДД.ММ.РРРР`) підписка?", "sponsor2": "До якої дати (`ДД.ММ.РРРР`) підписка?",
"sponsor2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`", "sponsor2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`",
"sponsor2_past": "Вказана дата знаходиться в минулому. Будь ласка, вкажіть правильний термін дії підписки",
"sponsor3": "Будь ласка, надішли одне фото для підтвердження дійсності підписки", "sponsor3": "Будь ласка, надішли одне фото для підтвердження дійсності підписки",
"sponsor4": "Яку роль ти бажаєш отримати?",
"sponsorship_application_empty": "❌ **Дія неможлива**\nУ тебе немає заповненої та схваленої анкети. Заповни таку за допомогою /reapply та спробуй ще раз після її підтвердження.", "sponsorship_application_empty": "❌ **Дія неможлива**\nУ тебе немає заповненої та схваленої анкети. Заповни таку за допомогою /reapply та спробуй ще раз після її підтвердження.",
"confirm": "Супер, дякуємо!\n\nБудь ласка, перевір правильність даних:\n{0}\n\nВсе правильно?", "confirm": "Супер, дякуємо!\n\nБудь ласка, перевір правильність даних:\n{0}\n\nВсе правильно?",
"application_sent": "Дякуємо! Ми надіслали твою анкетку на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. До тих пір від тебе більше нічого не потребується. Гарного дня! :)", "application_sent": "Дякуємо! Ми надіслали твою анкетку на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. До тих пір від тебе більше нічого не потребується. Гарного дня! :)",
"application_got": "Отримано анкету від `{0}`\n\nІм'я тг: `{1}`, `{2}`\nЮзернейм: @{3}\n\n**Дані анкети:**\n{4}", "sponsorship_sent": "Дякуємо! Ми надіслали форму на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. Гарного дня! :)",
"reapply_got": "Отримано змінити анкети від `{0}`\n\nІм'я тг: `{1}`, `{2}`\nЮзернейм: @{3}\n\n**Дані анкети:**\n{4}", "application_got": "Отримано анкету від `{0}`\n\nІм'я тг: `{1}`\nЮзернейм: @{2}\n\n**Дані анкети:**\n{3}",
"reapply_got": "Отримано оновлення анкети від `{0}`\n\nІм'я тг: `{1}`\nЮзернейм: @{2}\n\n**Дані анкети:**\n{3}",
"sponsor_got": "Отримано форму на спонсорство від `{0}`\n\nІм'я тг: `{1}`\nЮзернейм: @{2}\n\n**Дані форми:**\n{3}",
"shutdown": "Вимкнення бота з підом `{0}`", "shutdown": "Вимкнення бота з підом `{0}`",
"startup": "Запуск бота з підом `{0}`", "startup": "Запуск бота з підом `{0}`",
"startup_downtime": "Запуск бота з підом `{0}` (лежав {1})", "startup_downtime": "Запуск бота з підом `{0}` (лежав {1})",
@ -43,6 +47,10 @@
"rejected_by": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`.", "rejected_by": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`.",
"rejected_by_agr": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`, заборонивши вступ до спільноти.\nПричина: агресивна/токсична анкета.", "rejected_by_agr": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`, заборонивши вступ до спільноти.\nПричина: агресивна/токсична анкета.",
"rejected_by_rus": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`, заборонивши вступ до спільноти.\nПричина: русня.", "rejected_by_rus": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`, заборонивши вступ до спільноти.\nПричина: русня.",
"sponsor_approved": "Вітаємо! Твою форму переглянули та підтвердили її правильність. Коли термін дії наданої підписки буде добігати кінця - ми нагадаємо, що треба оновити дані аби й надалі отримувати плюшки в боті. Гарного дня!",
"sponsor_rejected": "Ой лишенько! Твою форму переглянули, однак не підтвердили її. Можливо, щось не так з датами, або ж бажана роль не може бути надана.\n\nТи можеш спробувати повторно заповнити форму командою /sponsorship",
"sponsor_approved_by": "✅ **Підписку схвалено**\nАдмін **{0}** переглянув та схвалив форму `{1}`.",
"sponsor_rejected_by": "❌ **Підписку відхилено**\nАдмін **{0}** переглянув та відхилив форму `{1}`.",
"contact": "Анкета `{0}`\n\n**Дані анкети:**\n{1}\n\n{2}", "contact": "Анкета `{0}`\n\n**Дані анкети:**\n{1}\n\n{2}",
"application_status_accepted": "Прийнята `{0}` від {1}", "application_status_accepted": "Прийнята `{0}` від {1}",
"application_status_rejected": "Відхилена `{0}` від {1}", "application_status_rejected": "Відхилена `{0}` від {1}",
@ -77,6 +85,8 @@
"no_user_application": "Не знайдено користувачів за запитом **{0}**", "no_user_application": "Не знайдено користувачів за запитом **{0}**",
"user_invalid": "Надісланий користувач не має завершеної анкети.", "user_invalid": "Надісланий користувач не має завершеної анкети.",
"joined_false_link": "Користувач **{0}** (`{1}`) приєднався до групи не за своїм посиланням", "joined_false_link": "Користувач **{0}** (`{1}`) приєднався до групи не за своїм посиланням",
"sponsorships_expires": "⚠️ **Нагадування**\nНадана платна підписка припинить діяти **за {0} д**. Будь ласка, оновіть дані про неї командою /sponsorship інакше роль буде втрачено!",
"sponsorships_expired": "⚠️ **Нагадування**\nТермін дії вказаної підписки сплив. Для повторного отримання ролі користуйся командою /sponsorship.",
"voice_message": [ "voice_message": [
"why are u gae", "why are u gae",
"руки відірвало? пиши як людина", "руки відірвало? пиши як людина",
@ -93,6 +103,11 @@
"question8": "Дивлюсь стріми:", "question8": "Дивлюсь стріми:",
"question9": "Подобаються пісні:", "question9": "Подобаються пісні:",
"question10": "Про себе:" "question10": "Про себе:"
},
"sponsor_titles": {
"question_streamer": "Стрімер:",
"question_expires": "Підписка до:",
"question_label": "Хоче роль:"
} }
}, },
"keyboard": { "keyboard": {
@ -131,13 +146,16 @@
"question10": "Трошки про себе", "question10": "Трошки про себе",
"sponsor1": "Ім'я дівчини", "sponsor1": "Ім'я дівчини",
"sponsor2": "Дата до якої підписка", "sponsor2": "Дата до якої підписка",
"sponsor3": "Фото-підтвердження" "sponsor3": "Фото-підтвердження",
"sponsor4": "Бажана роль"
}, },
"button": { "button": {
"sub_yes": "✅ Прийняти", "sub_yes": "✅ Прийняти",
"sub_no": "❌ Відхилити", "sub_no": "❌ Відхилити",
"sub_aggressive": "🤡 Відхилити (Токс)", "sub_aggressive": "🤡 Відхилити (Токс)",
"sub_russian": "🇷🇺 Відхилити (Русак)", "sub_russian": "🇷🇺 Відхилити (Русак)",
"sponsor_yes": "✅ Прийняти",
"sponsor_no": "❌ Відхилити",
"accepted": "✅ Прийнято", "accepted": "✅ Прийнято",
"declined": "❌ Відхилено", "declined": "❌ Відхилено",
"join": "Приєднатись", "join": "Приєднатись",

View File

@ -77,7 +77,7 @@ async def callback_query_reapply_reject(app, clb):
async def callback_query_reapply_old(app, clb): async def callback_query_reapply_old(app, clb):
fullclb = clb.data.split("_") fullclb = clb.data.split("_")
message = await app.get_messages(clb.from_user.id, int(fullclb[2])) message = await app.get_messages(clb.from_user.id, int(fullclb[2]))
await confirm_yes(app, message) await confirm_yes(app, message, kind="application")
await clb.message.edit(clb.message.text, reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(locale("done", "button", locale=clb.from_user), "nothing")]])) await clb.message.edit(clb.message.text, reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(locale("done", "button", locale=clb.from_user), "nothing")]]))
# Start a new application when user reapplies after leaving the chat # Start a new application when user reapplies after leaving the chat

View File

@ -1,10 +1,10 @@
from datetime import datetime from datetime import datetime
from app import app from app import app
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ForceReply
from pyrogram import filters from pyrogram import filters
from classes.holo_user import HoloUser from classes.holo_user import HoloUser
from modules.utils import configGet, locale, logWrite from modules.utils import configGet, locale, logWrite
from modules.database import col_tmp,col_sponsorships from modules.database import col_tmp, col_sponsorships
# Callbacks sponsorship ======================================================================================================== # Callbacks sponsorship ========================================================================================================
@app.on_callback_query(filters.regex("sponsor_apply_[\s\S]*")) @app.on_callback_query(filters.regex("sponsor_apply_[\s\S]*"))
@ -15,24 +15,51 @@ async def callback_query_sponsor_apply(app, clb):
logWrite(f"User {holo_user.id} applied for sponsorship") logWrite(f"User {holo_user.id} applied for sponsorship")
col_tmp.insert_one( holo_user.sponsorship_restart()
{
"user": holo_user.id,
"type": "sponsorship",
"complete": False,
"sent": False,
"state": "fill",
"stage": 1,
"sponsorship": {
"streamer": None,
"expires": datetime.fromtimestamp(0),
"proof": None,
"label": ""
}
}
)
edited_markup = [[InlineKeyboardButton(text=str(locale("sponsor_started", "button")), callback_data="nothing")]] edited_markup = [[InlineKeyboardButton(text=str(locale("sponsor_started", "button")), callback_data="nothing")]]
await clb.message.edit(text=locale("sponsorship_apply", "message"), reply_markup=InlineKeyboardMarkup(edited_markup)) await clb.message.edit(text=locale("sponsorship_apply", "message"), reply_markup=InlineKeyboardMarkup(edited_markup))
await app.send_message(holo_user.id, locale(f"sponsor1", "message", locale=holo_user.locale), reply_markup=ForceReply(placeholder=str(locale(f"sponsor1", "force_reply", locale=holo_user.locale))))
await clb.answer(text=locale("sponsor_started", "callback").format(holo_user.id), show_alert=False) await clb.answer(text=locale("sponsor_started", "callback").format(holo_user.id), show_alert=False)
@app.on_callback_query(filters.regex("sponsor_yes_[\s\S]*"))
async def callback_query_sponsor_yes(app, clb):
fullclb = clb.data.split("_")
holo_user = HoloUser(int(fullclb[2]))
await app.send_message(configGet("admin_group"), locale("sponsor_approved_by", "message").format(clb.from_user.first_name, holo_user.id), disable_notification=True)
await app.send_message(holo_user.id, locale("sponsor_approved", "message", locale=holo_user))
logWrite(f"User {holo_user.id} got approved by {clb.from_user.id}")
if col_sponsorships.find_one({"user": holo_user.id}) is not None:
col_sponsorships.update_one({"date": {"$eq": datetime.now()}, "admin": {"$eq": clb.from_user.id}, "sponsorship": {"$eq": col_tmp.find_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "sponsorship"}})["sponsorship"]}})
else:
col_sponsorships.insert_one({"user": holo_user.id, "date": datetime.now(), "admin": clb.from_user.id, "sponsorship": col_tmp.find_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "sponsorship"}})["sponsorship"]})
col_tmp.update_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"state": "approved", "sent": False}})
await holo_user.set_label(configGet("destination_group"), col_tmp.find_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "sponsorship"}})["sponsorship"]["label"])
edited_markup = [[InlineKeyboardButton(text=str(locale("accepted", "button")), callback_data="nothing")]]
await app.edit_message_caption(clb.message.chat.id, clb.message.id, caption=clb.message.caption, reply_markup=InlineKeyboardMarkup(edited_markup))
await clb.answer(text=f"✅ Confirmed {fullclb[2]}", show_alert=False)
@app.on_callback_query(filters.regex("sponsor_no_[\s\S]*"))
async def callback_query_sponsor_no(app, clb):
fullclb = clb.data.split("_")
holo_user = HoloUser(int(fullclb[2]))
await app.send_message(configGet("admin_group"), locale("sponsor_rejected_by", "message").format(clb.from_user.first_name, holo_user.id), disable_notification=True)
await app.send_message(holo_user.id, locale("sponsor_rejected", "message", locale=holo_user))
logWrite(f"User {holo_user.id} got rejected by {clb.from_user.id}")
col_tmp.update_one({"user": {"$eq": holo_user.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"state": "rejected", "sent": False}})
edited_markup = [[InlineKeyboardButton(text=str(locale("declined", "button")), callback_data="nothing")]]
await app.edit_message_caption(clb.message.chat.id, clb.message.id, caption=clb.message.caption, reply_markup=InlineKeyboardMarkup(edited_markup))
await clb.answer(text=f"❌ Rejected {fullclb[2]}", show_alert=False)

View File

@ -1,8 +1,11 @@
from os import remove, sep
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
from pyrogram import filters from pyrogram import filters
from pyrogram.types import ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton from pyrogram.types import ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton, ForceReply
from pyrogram.enums.parse_mode import ParseMode from pyrogram.enums.parse_mode import ParseMode
from classes.holo_user import HoloUser from classes.holo_user import HoloUser
from modules.utils import all_locales, configGet, locale, logWrite from modules.utils import all_locales, configGet, locale, logWrite
@ -14,13 +17,11 @@ confirmation_1 = []
for pattern in all_locales("confirm", "keyboard"): for pattern in all_locales("confirm", "keyboard"):
confirmation_1.append(pattern[0][0]) confirmation_1.append(pattern[0][0])
@app.on_message(~ filters.scheduled & filters.private & filters.command(confirmation_1, prefixes=[""])) @app.on_message(~ filters.scheduled & filters.private & filters.command(confirmation_1, prefixes=[""]))
async def confirm_yes(app, msg): async def confirm_yes(app, msg, kind: Literal["application", "sponsorship"] = "unknown"):
holo_user = HoloUser(msg.from_user) holo_user = HoloUser(msg.from_user)
if (holo_user.application_state()[0] == "fill") and (holo_user.application_state()[1] is True): if (kind == "application") or ((holo_user.application_state()[0] == "fill") and (holo_user.application_state()[1] is True)):
await msg.reply_text(locale("application_sent", "message"), reply_markup=ReplyKeyboardRemove())
tmp_application = col_tmp.find_one({"user": holo_user.id, "type": "application"}) tmp_application = col_tmp.find_one({"user": holo_user.id, "type": "application"})
@ -28,6 +29,11 @@ async def confirm_yes(app, msg):
logWrite(f"Application of {holo_user.id} is nowhere to be found.") logWrite(f"Application of {holo_user.id} is nowhere to be found.")
return return
if tmp_application["sent"] is True:
return
await msg.reply_text(locale("application_sent", "message"), reply_markup=ReplyKeyboardRemove())
application_content = [] application_content = []
i = 1 i = 1
@ -47,7 +53,7 @@ async def confirm_yes(app, msg):
i += 1 i += 1
if tmp_application["reapply"]: if tmp_application["reapply"]:
await app.send_message(chat_id=configGet("admin_group"), text=(locale("reapply_got", "message")).format(str(holo_user.id), msg.from_user.first_name, msg.from_user.last_name, msg.from_user.username, "\n".join(application_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( await app.send_message(chat_id=configGet("admin_group"), 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}") InlineKeyboardButton(text=str(locale("reapply_yes", "button")), callback_data=f"reapply_yes_{holo_user.id}")
@ -59,7 +65,7 @@ async def confirm_yes(app, msg):
) )
) )
else: else:
await app.send_message(chat_id=configGet("admin_group"), text=(locale("application_got", "message")).format(str(holo_user.id), msg.from_user.first_name, msg.from_user.last_name, msg.from_user.username, "\n".join(application_content)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( await app.send_message(chat_id=configGet("admin_group"), 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}") InlineKeyboardButton(text=str(locale("sub_yes", "button")), callback_data=f"sub_yes_{holo_user.id}")
@ -81,19 +87,74 @@ async def confirm_yes(app, msg):
col_tmp.update_one({"user": holo_user.id, "type": "application"}, {"$set": {"sent": True}}) col_tmp.update_one({"user": holo_user.id, "type": "application"}, {"$set": {"sent": True}})
return
# configSet(["sent"], True, file=str(holo_user.id)) # configSet(["sent"], True, file=str(holo_user.id))
# configSet(["confirmed"], True, file=str(holo_user.id)) # configSet(["confirmed"], True, file=str(holo_user.id))
if (kind == "sponsorship") or ((holo_user.sponsorship_state()[0] == "fill") and (holo_user.sponsorship_state()[1] is True)):
tmp_sponsorship = col_tmp.find_one({"user": holo_user.id, "type": "sponsorship"})
if tmp_sponsorship is None:
logWrite(f"Sponsorship of {holo_user.id} is nowhere to be found.")
return
if tmp_sponsorship["sent"] is True:
return
await msg.reply_text(locale("sponsorship_sent", "message"), reply_markup=ReplyKeyboardRemove())
sponsorship_content = []
for question in tmp_sponsorship['sponsorship']:
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'])
else:
sponsorship_content.append(f"{locale(f'question_{question}', 'message', 'sponsor_titles')} {tmp_sponsorship['sponsorship'][question]}")
await app.send_photo(chat_id=configGet("admin_group"), 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(
[
[
InlineKeyboardButton(text=str(locale("sponsor_yes", "button")), callback_data=f"sponsor_yes_{holo_user.id}")
],
[
InlineKeyboardButton(text=str(locale("sponsor_no", "button")), callback_data=f"sponsor_no_{holo_user.id}")
]
]
)
)
remove(f"tmp{sep}{filename}.jpg")
logWrite(f"User {holo_user.id} sent his sponsorship application and it will now be reviewed")
col_tmp.update_one({"user": holo_user.id, "type": "sponsorship"}, {"$set": {"sent": True}})
return
confirmation_2 = [] confirmation_2 = []
for pattern in all_locales("confirm", "keyboard"): for pattern in all_locales("confirm", "keyboard"):
confirmation_2.append(pattern[1][0]) confirmation_2.append(pattern[1][0])
@app.on_message(~ filters.scheduled & filters.private & filters.command(confirmation_2, prefixes=[""])) @app.on_message(~ filters.scheduled & filters.private & filters.command(confirmation_2, prefixes=[""]))
async def confirm_no(app, msg): async def confirm_no(app, msg, kind: Literal["application", "sponsorship"] = "unknown"):
holo_user = HoloUser(msg.from_user) holo_user = HoloUser(msg.from_user)
if (holo_user.application_state()[0] == "fill") and (holo_user.application_state()[1] is True): if (kind == "application") or ((holo_user.application_state()[0] == "fill") and (holo_user.application_state()[1] is True)):
holo_user.application_restart() holo_user.application_restart()
await welcome_pass(app, msg, once_again=True) await welcome_pass(app, msg, once_again=True)
logWrite(f"User {msg.from_user.id} restarted the application due to typo in it") logWrite(f"User {msg.from_user.id} restarted the application due to typo in it")
return
if (kind == "sponsorship") or ((holo_user.sponsorship_state()[0] == "fill") and (holo_user.sponsorship_state()[1] is True)):
holo_user.sponsorship_restart()
await app.send_message(holo_user.id, locale(f"sponsor1", "message", locale=holo_user.locale), reply_markup=ForceReply(placeholder=str(locale(f"sponsor1", "force_reply", locale=holo_user.locale))))
logWrite(f"User {msg.from_user.id} restarted the sponsorship application due to typo in it")
return
# ============================================================================================================================== # ==============================================================================================================================

View File

@ -52,6 +52,7 @@ async def any_stage(app, msg):
if msg.text is not None: if msg.text is not None:
await holo_user.application_next(msg.text, msg=msg) await holo_user.application_next(msg.text, msg=msg)
await holo_user.sponsorship_next(msg.text, msg=msg)
# user_stage = configGet("stage", file=str(msg.from_user.id)) # user_stage = configGet("stage", file=str(msg.from_user.id))

View File

@ -1,6 +1,13 @@
from app import app from app import app
from pyrogram import filters from pyrogram import filters
from classes.holo_user import HoloUser
@app.on_message(~ filters.scheduled & filters.photo & filters.private) @app.on_message(~ filters.scheduled & filters.photo & filters.private)
async def sponsor_proof(app, msg): async def sponsor_proof(app, msg):
pass
if msg.via_bot is None:
holo_user = HoloUser(msg.from_user)
await holo_user.sponsorship_next(msg.text, msg=msg, photo=msg.photo)

View File

@ -5,9 +5,10 @@ from app import app
from pyrogram.types import BotCommand, BotCommandScopeChat from pyrogram.types import BotCommand, BotCommandScopeChat
from pyrogram.errors import bad_request_400 from pyrogram.errors import bad_request_400
from pyrogram.enums.chat_members_filter import ChatMembersFilter from pyrogram.enums.chat_members_filter import ChatMembersFilter
from classes.holo_user import HoloUser
from modules.utils import configGet, locale, logWrite from modules.utils import configGet, locale, logWrite
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from modules.database import col_applications from modules.database import col_applications, col_sponsorships
scheduler = AsyncIOScheduler() scheduler = AsyncIOScheduler()
@ -47,6 +48,28 @@ if configGet("enabled", "scheduler", "birthdays"):
if configGet("enabled", "scheduler", "sponsorships"): if configGet("enabled", "scheduler", "sponsorships"):
@scheduler.scheduled_job(trigger="cron", hour=configGet("time", "scheduler", "sponsorships")) @scheduler.scheduled_job(trigger="cron", hour=configGet("time", "scheduler", "sponsorships"))
async def check_sponsors(): async def check_sponsors():
for entry in col_sponsorships.find({"sponsorship.expires": {"$lt": datetime.now()+timedelta(days=2)}}):
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
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}'")
continue
for entry in col_sponsorships.find({"sponsorship.expires": {"$lt": datetime.now()}}):
try:
holo_user = HoloUser(entry["user"])
await app.send_message( entry["user"], locale("sponsorships_expired", "message") ) # type: ignore
await holo_user.reset_label(configGet("destination_group"))
try:
tg_user = await app.get_users(entry["user"])
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 expired due to '{exp}'")
except Exception as exp:
logWrite(f"Could not reset label of user {entry['user']} due to '{exp}'")
continue
logWrite("Sponsorships check performed") logWrite("Sponsorships check performed")