10 Commits

Author SHA1 Message Date
95be1e72d3 Merge pull request 'Bug fixes and improvements' (#8) from dev into master
Reviewed-on: profitroll/HoloCheckerBot#8
2023-01-11 17:22:34 +02:00
ecbf7d8b78 Updated ignore 2023-01-11 12:53:20 +01:00
92386ac8ce Fixed some logic holes 2023-01-11 12:28:58 +01:00
dabfa2ecef Added ftfy and length limit 2023-01-10 13:41:08 +01:00
234b73add0 Merge pull request 'Bug fixes and small structural changes' (#7) from dev into master
Reviewed-on: profitroll/HoloCheckerBot#7
2023-01-06 17:01:20 +02:00
f4fb85f7a4 Merge pull request 'Removed legacy, fixed some bugs, improved spoilers' (#6) from dev into master
Reviewed-on: profitroll/HoloCheckerBot#6
2023-01-05 16:49:35 +02:00
4fba305b05 Merge pull request 'Small fix for spoiler with an empty description' (#5) from dev into master
Reviewed-on: profitroll/HoloCheckerBot#5
2023-01-05 13:54:19 +02:00
68c7cc0ada Merge pull request 'Spoilers, major command system improvements' (#4) from dev into master
Reviewed-on: profitroll/HoloCheckerBot#4
2023-01-05 13:45:14 +02:00
79304816b0 Merge pull request '/cancel, /identify, sponsorships improvements and fixes' (#3) from dev into master
Reviewed-on: profitroll/HoloCheckerBot#3
2023-01-03 16:45:20 +02:00
2cfa5a8f8d Merge pull request '/nearby, subscriptions check, geocoding' (#2) from dev into master
Reviewed-on: profitroll/HoloCheckerBot#2
2023-01-02 12:16:38 +02:00
8 changed files with 67 additions and 14 deletions

2
.gitignore vendored
View File

@@ -162,3 +162,5 @@ TASK.md
inline_bot.py inline_bot.py
.vscode .vscode
migrate.py migrate.py
validation/*
!validation/*.json

View File

@@ -1,5 +1,6 @@
from datetime import datetime from datetime import datetime
from asyncio import sleep from asyncio import sleep
from ftfy import fix_text
from traceback import format_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
@@ -122,6 +123,11 @@ class HoloUser():
* adm_context (`bool`, *optional*): Whether context sender is an admin. Defaults to False. * 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 # Check if any text available and log message sending
if text is not None: if text is not None:
logWrite(f"{context.from_user.id} sent message '{text}' to {self.id} (source message: {context.id})") logWrite(f"{context.from_user.id} sent message '{text}' to {self.id} (source message: {context.id})")
@@ -275,10 +281,9 @@ class HoloUser():
"""Reset application of a user in tmp collection and replace it with an empty one """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: 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) 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: async def application_next(self, query: str, msg: Message) -> None:
"""Move on filling application of user """Move on filling application of user
@@ -313,6 +318,9 @@ class HoloUser():
if progress["state"] == "fill" and progress["sent"] is False: if progress["state"] == "fill" and progress["sent"] is False:
if msg.text is not None:
msg.text = fix_text(msg.text)
if stage == 2: if stage == 2:
try: try:
@@ -359,6 +367,9 @@ class HoloUser():
return return
elif stage == 10: 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 progress["application"][str(stage)] = query
col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "application"}}, {"$set": {"application": progress["application"], "complete": True}}) col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "application"}}, {"$set": {"application": progress["application"], "complete": True}})
application_content = [] application_content = []
@@ -378,6 +389,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)) 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: 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 progress["application"][str(stage)] = query
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))))
@@ -430,10 +444,20 @@ class HoloUser():
stage = progress["stage"] 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 progress["state"] == "fill" and progress["sent"] is False:
if stage == 1: 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 progress["sponsorship"]["streamer"] = query
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))))

View File

@@ -13,6 +13,7 @@
"question8": "Чи дивишся ти стріми дівчат Хололайву?", "question8": "Чи дивишся ти стріми дівчат Хололайву?",
"question9": "Чиї пісні з Хололайву тобі подобаються найбільше?", "question9": "Чиї пісні з Хололайву тобі подобаються найбільше?",
"question10": "Ну і нарешті, розкажи трохи про себе. Про хобі, чим тобі подобається займатись. Одним повідомленням, будь ласка.", "question10": "Ну і нарешті, розкажи трохи про себе. Про хобі, чим тобі подобається займатись. Одним повідомленням, будь ласка.",
"question_too_long": "Текст занадто довгий. Будь ласка, умісти відповідь у 256 символів.",
"question2_underage": "Вибач, але треба досягти віку {0} років, щоб приєднатись до нас. Такі обмеження існують для того, щоб всім у спільноті було цікаво одне з одним.", "question2_underage": "Вибач, але треба досягти віку {0} років, щоб приєднатись до нас. Такі обмеження існують для того, щоб всім у спільноті було цікаво одне з одним.",
"question2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`", "question2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`",
"question2_joke": "Шутнік, ми так і поняли. Але будь ласка, введи реальне значення.", "question2_joke": "Шутнік, ми так і поняли. Але будь ласка, введи реальне значення.",
@@ -20,9 +21,11 @@
"question3_found": "Використовую наступний результат:\n• {0} ({1})", "question3_found": "Використовую наступний результат:\n• {0} ({1})",
"question3_error": "⚠️ **Сталась помилка**\nНе вдалось отримати географічну мітку. Розробника повідомлено про цю помилку. Будь ласка, спробуйте ще раз.", "question3_error": "⚠️ **Сталась помилка**\nНе вдалось отримати географічну мітку. Розробника повідомлено про цю помилку. Будь ласка, спробуйте ще раз.",
"question3_traceback": "⚠️ **Сталась помилка**\nПомилка отримання геокодингу для `{0}`\nПомилка: `{1}`\n\nTraceback:\n```\n{2}\n```", "question3_traceback": "⚠️ **Сталась помилка**\nПомилка отримання геокодингу для `{0}`\nПомилка: `{1}`\n\nTraceback:\n```\n{2}\n```",
"question10_too_long": "Текст занадто довгий. Будь ласка, умісти відповідь у 1024 символи.",
"sponsorship_apply": " Оформіть платну підписку на когось з Холо, заповніть форму та отримайте особливу роль в якості винагороди!", "sponsorship_apply": " Оформіть платну підписку на когось з Холо, заповніть форму та отримайте особливу роль в якості винагороди!",
"sponsorship_applying": " Розпочато заповнення форми на отримання бонусів за платну підписку на холодівчат.", "sponsorship_applying": " Розпочато заповнення форми на отримання бонусів за платну підписку на холодівчат.",
"sponsor1": "На яку саме дівчину платна підписка?", "sponsor1": "На яку саме дівчину платна підписка?",
"sponsor1_invalid": "Будь ласка, введіть ім'я не довше за 240 символів",
"sponsor2": "До якої дати (`ДД.ММ.РРРР`) підписка?", "sponsor2": "До якої дати (`ДД.ММ.РРРР`) підписка?",
"sponsor2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`", "sponsor2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`",
"sponsor2_past": "Вказана дата знаходиться в минулому. Будь ласка, вкажіть правильний термін дії підписки", "sponsor2_past": "Вказана дата знаходиться в минулому. Будь ласка, вкажіть правильний термін дії підписки",
@@ -108,6 +111,7 @@
"spoiler_empty": "Спойлер категорії \"{0}\" без опису", "spoiler_empty": "Спойлер категорії \"{0}\" без опису",
"spoiler_described": "Спойлер категорії \"{0}\": {1}", "spoiler_described": "Спойлер категорії \"{0}\": {1}",
"spoiler_description_enter": "Добре, введіть бажаний опис спойлера", "spoiler_description_enter": "Добре, введіть бажаний опис спойлера",
"spoiler_description_too_long": "Текст занадто довгий. Будь ласка, умісти опис у 1024 символи.",
"spoiler_using_description": "Встановлено опис спойлера: {0}\n\nЗалишилось додати вміст самого спойлера. Бот приймає текстове повідомлення, фото, відео, файл а також гіф зображення (1 шт.)", "spoiler_using_description": "Встановлено опис спойлера: {0}\n\nЗалишилось додати вміст самого спойлера. Бот приймає текстове повідомлення, фото, відео, файл а також гіф зображення (1 шт.)",
"spoiler_send_description": "Тепер треба надіслати коротенький опис спойлера, щоб люди розуміли що під ним варто очкувати. Надішли мінус (-) щоб пропустити цей крок.", "spoiler_send_description": "Тепер треба надіслати коротенький опис спойлера, щоб люди розуміли що під ним варто очкувати. Надішли мінус (-) щоб пропустити цей крок.",
"spoiler_ready": "Успіх! Спойлер створено. Користуйтесь кнопкою нижче щоб надіслати його.", "spoiler_ready": "Успіх! Спойлер створено. Користуйтесь кнопкою нижче щоб надіслати його.",

View File

@@ -21,7 +21,14 @@ async def callback_reapply_query_accept(app: Client, clb: CallbackQuery):
await app.send_message(holo_user.id, locale("approved_joined", "message", locale=holo_user)) await app.send_message(holo_user.id, locale("approved_joined", "message", locale=holo_user))
col_applications.delete_one({"user": holo_user.id}) 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_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}}) col_tmp.update_one({"user": holo_user.id, "type": "application"}, {"$set": {"state": "approved", "sent": False}})

View File

@@ -9,7 +9,7 @@ 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
from modules.handlers.welcome import welcome_pass 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 from modules import custom_filters
# Confirmation ================================================================================================================= # Confirmation =================================================================================================================
@@ -54,8 +54,12 @@ async def confirm_yes(app: Client, msg: Message, kind: Literal["application", "s
i += 1 i += 1
if tmp_application["reapply"]: 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( 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}") 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: 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}") InlineKeyboardButton(text=str(locale("sub_yes", "button")), callback_data=f"sub_yes_{holo_user.id}")

View File

@@ -1,6 +1,7 @@
from traceback import print_exc from traceback import print_exc
from app import app, isAnAdmin from app import app, isAnAdmin
import asyncio import asyncio
from ftfy import fix_text
from pyrogram import filters from pyrogram import filters
from pyrogram.types import Message, ForceReply, InlineKeyboardMarkup, InlineKeyboardButton from pyrogram.types import Message, ForceReply, InlineKeyboardMarkup, InlineKeyboardButton
from pyrogram.client import Client from pyrogram.client import Client
@@ -96,7 +97,12 @@ async def any_stage(app: Client, msg: Message):
# 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))) # 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 # return
if msg.text != "-": 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}} ) col_spoilers.find_one_and_update( {"user": msg.from_user.id, "completed": False}, {"$set": {"description": msg.text}} )
else: else:
col_spoilers.find_one_and_update( {"user": msg.from_user.id, "completed": False}, {"$set": {"description": ""}} ) col_spoilers.find_one_and_update( {"user": msg.from_user.id, "completed": False}, {"$set": {"description": ""}} )

View File

@@ -13,7 +13,7 @@ for pattern in all_locales("welcome", "keyboard"):
for pattern in all_locales("return", "keyboard"): for pattern in all_locales("return", "keyboard"):
welcome_1.append(pattern[0][0]) welcome_1.append(pattern[0][0])
@app.on_message(custom_filters.enabled_applications & ~filters.scheduled & filters.private & filters.command(welcome_1, prefixes=[""])) @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 """Set user's stage to 1 and start a fresh application
### Args: ### Args:
@@ -27,6 +27,7 @@ async def welcome_pass(app: Client, msg: Message, once_again: bool = True) -> No
holo_user = HoloUser(msg.from_user) holo_user = HoloUser(msg.from_user)
if once_again is False:
holo_user.application_restart() holo_user.application_restart()
logWrite(f"User {msg.from_user.id} confirmed starting the application") logWrite(f"User {msg.from_user.id} confirmed starting the application")

View File

@@ -2,9 +2,10 @@ 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.95 Pyrogram~=2.0.96
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.22.0
ujson~=5.7.0 ujson~=5.7.0
ftfy~=6.1.1