/cancel, /identify, sponsorships improvements and fixes #3

Merged
profitroll merged 19 commits from dev into master 2023-01-03 16:45:20 +02:00
22 changed files with 335 additions and 52 deletions

View File

@ -104,9 +104,9 @@ After all of that you're good to go! Happy using :)
## To-Do
* [ ] Check sponsorship on Holo girls
* [x] Check sponsorship on Holo girls
* [ ] Stats and infographic
* [ ] /nearby command
* [x] /nearby command
* [ ] Check group members without completed application
* [x] Complete messenger between user and admins
* [x] Get application by id and user_id

7
app.py
View File

@ -8,13 +8,19 @@ from pyrogram.errors import bad_request_400
app = Client("holochecker", bot_token=configGet("bot_token", "bot"), api_id=configGet("api_id", "bot"), api_hash=configGet("api_hash", "bot"))
async def isAnAdmin(admin_id):
# Check if user is mentioned in config
if (admin_id == configGet("owner")) or (admin_id in configGet("admins")):
return True
# Check if user is probably in cache
if path.exists(f"cache{sep}admins") is True:
try:
return True if admin_id in jsonLoad(f"cache{sep}admins") else False
except (FileNotFoundError, JSONDecodeError):
pass
# Check if user is in admin group
try:
async for member in app.get_chat_members(configGet("admin_group")):
if member.user.id == admin_id:
@ -22,4 +28,5 @@ async def isAnAdmin(admin_id):
except bad_request_400.ChannelInvalid:
logWrite(f"Could not get users in admin group to answer isAnAdmin(). Bot is likely not in the group.")
return False
return False

View File

@ -1,7 +1,4 @@
from datetime import datetime
from os import sep
from uuid import uuid1
from requests import get
from traceback import print_exc
from app import app, isAnAdmin
from typing import Any, List, Literal, Union
@ -9,9 +6,9 @@ from pyrogram.types import User, ChatMember, ChatPrivileges, Chat, Message, Phot
from pyrogram.errors import bad_request_400
from dateutil.relativedelta import relativedelta
from classes.errors.geo import PlaceNotFoundError
from modules.database import col_tmp, col_users, col_context, col_warnings, col_applications, col_sponsorships, col_messages
from modules.database import col_tmp, col_users, col_applications, col_sponsorships, col_messages
from modules.logging import logWrite
from modules.utils import configGet, find_location, locale, should_quote
from modules.utils import configGet, create_tmp, download_tmp, find_location, locale, should_quote
class DefaultApplicationTemp(dict):
def __init__(self, user: int, reapply: bool = False):
@ -286,10 +283,15 @@ class HoloUser():
if len(label) > 16:
raise LabelTooLongError(label)
self.label = label
self.set("label", label)
await app.promote_chat_member(configGet("destination_group"), self.id, privileges=ChatPrivileges(can_pin_messages=True, can_manage_video_chats=True))
if not await isAnAdmin(self.id):
await app.set_administrator_title(configGet("destination_group"), self.id, label)
try:
await app.promote_chat_member(configGet("destination_group"), self.id, privileges=ChatPrivileges(can_pin_messages=True, can_manage_video_chats=True))
if not await isAnAdmin(self.id):
await app.set_administrator_title(configGet("destination_group"), self.id, label)
self.set("label", label)
except bad_request_400.UserCreator:
logWrite(f"Could not set {self.id}'s title to '{self.label}' because of bad_request_400.UserCreator")
except bad_request_400.ChatAdminRequired:
logWrite(f"Could not set {self.id}'s title to '{self.label}' because of bad_request_400.ChatAdminRequired")
async def label_reset(self, chat: Chat) -> None:
"""Reset label in destination group
@ -344,11 +346,14 @@ class HoloUser():
* msg (`Message`): Message that should receive replies
"""
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
)
if self.sponsorship_state()[0] == "fill":
return
# col_tmp.insert_one(
# document=DefaultApplicationTemp(self.id).dict
# )
progress = col_tmp.find_one({"user": self.id, "type": "application"})
@ -357,9 +362,9 @@ class HoloUser():
stage = progress["stage"]
if self.sponsorship_state()[0] == "fill":
await msg.reply_text(locale("finish_sponsorship", "message"), quote=should_quote(msg))
return
# if self.sponsorship_state()[0] == "fill":
# await msg.reply_text(locale("finish_sponsorship", "message"), quote=should_quote(msg))
# return
if progress["state"] == "fill" and progress["sent"] is False:
@ -514,21 +519,24 @@ class HoloUser():
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
progress["sponsorship"]["proof"] = await download_tmp(app, photo.file_id)
col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"sponsorship": progress["sponsorship"], "stage": progress["stage"]+1}})
await msg.reply_text(locale(f"sponsor{stage+1}", "message", locale=self.locale), reply_markup=ForceReply(placeholder=str(locale(f"sponsor{stage+1}", "force_reply", locale=self.locale))))
elif stage == 4:
if len(query) > 16:
await msg.reply_text(locale("label_too_long", "message"))
await msg.reply_text(locale("label_too_long", "message"), reply_markup=ForceReply(placeholder=str(locale("sponsor4", "force_reply", locale=self.locale))))
return
progress["sponsorship"]["label"] = query
col_tmp.update_one({"user": {"$eq": self.id}, "type": {"$eq": "sponsorship"}}, {"$set": {"sponsorship": progress["sponsorship"], "complete": True}})
await msg.reply_text(locale("sponsor_confirm", "message", locale=self.locale), reply_markup=ReplyKeyboardMarkup(locale("confirm", "keyboard", locale=self.locale), resize_keyboard=True))
await msg.reply_photo(
photo=create_tmp(progress["sponsorship"]["proof"], kind="image"),
caption=locale("sponsor_confirm", "message", locale=self.locale).format(
progress["sponsorship"]["streamer"],
progress["sponsorship"]["expires"].strftime("%d.%m.%Y"),
progress["sponsorship"]["label"]
),
reply_markup=ReplyKeyboardMarkup(locale("confirm", "keyboard", locale=self.locale), resize_keyboard=True))
else:
return

View File

@ -13,6 +13,7 @@ makedirs(f'{configGet("cache", "locations")}{sep}avatars', exist_ok=True)
from modules.commands.application import *
from modules.commands.applications import *
from modules.commands.cancel import *
from modules.commands.identify import *
from modules.commands.label import *
from modules.commands.message import *
from modules.commands.nearby import *

View File

@ -26,13 +26,13 @@
"sponsor2": "До якої дати (`ДД.ММ.РРРР`) підписка?",
"sponsor2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`",
"sponsor2_past": "Вказана дата знаходиться в минулому. Будь ласка, вкажіть правильний термін дії підписки",
"sponsor3": "Будь ласка, надішли одне фото для підтвердження дійсності підписки",
"sponsor4": "Яку роль ти бажаєш отримати?",
"sponsor3": "Будь ласка, надішли одне фото для підтвердження дійсності підписки\n\n **Підказка**\nПрочитай як правильно скрінити легітимне підтвердження підписки: https://telegra.ph/Pіdpiska-na-holo-dіvchinu-01-02",
"sponsor4": "Яку роль ти бажаєш отримати?\n\n **Підказка**\nНазва ролі повинна бути якось пов'язана зі вказаною дівчиною, не повинна порушувати правила спільноти а також має бути не довше за 16 символів (обмеження Telegram).",
"sponsorship_application_empty": "❌ **Дія неможлива**\nУ тебе немає заповненої та схваленої анкети. Заповни таку за допомогою /reapply та спробуй ще раз після її підтвердження.",
"confirm": "Супер, дякуємо!\n\nБудь ласка, перевір правильність даних:\n{0}\n\nВсе правильно?",
"sponsor_confirm": "Здається, це все. Перевір чи все правильно та жмакни кнопку на клавіатурі щоб продовжити.",
"application_sent": "Дякуємо! Ми надіслали твою анкетку на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. До тих пір від тебе більше нічого не потребується. Гарного дня! :)",
"sponsorship_sent": "Дякуємо! Ми надіслали форму на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. Гарного дня! :)",
"sponsor_confirm": "**Дані форми:**\nСтрімер: {0}\nПідписка до: {1}\nХочу роль: {2}\n\nПеревір чи все правильно та жмакни кнопку на клавіатурі щоб продовжити.",
"application_sent": "Дякуємо! Ми надіслали твою анкетку на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. До тих пір від тебе більше нічого не потребується :)",
"sponsorship_sent": "Дякуємо! Ми надіслали форму на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення :)",
"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}",
@ -49,7 +49,7 @@
"rejected_by": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`.",
"rejected_by_agr": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`, заборонивши вступ до спільноти.\nПричина: агресивна/токсична анкета.",
"rejected_by_rus": "❌ **Анкету відхилено**\nАдмін **{0}** переглянув та відхилив анкету `{1}`, заборонивши вступ до спільноти.\nПричина: русня.",
"sponsor_approved": "Вітаємо! Твою форму переглянули та підтвердили її правильність. Коли термін дії наданої підписки буде добігати кінця - ми нагадаємо, що треба оновити дані аби й надалі отримувати плюшки в боті. Гарного дня!",
"sponsor_approved": "Вітаємо! Твою форму переглянули та підтвердили її правильність. Коли термін дії наданої підписки буде добігати кінця - ми нагадаємо, що треба оновити дані аби й надалі отримувати плюшки в чаті. Також можна повторно заповнити форму, якщо хочеться змінити бажане ім'я ролі або подовжити термін дії підписки завчасно, за допомогою команди /sponsorship. Гарного дня!",
"sponsor_rejected": "Ой лишенько! Твою форму переглянули, однак не підтвердили її. Можливо, щось не так з датами, або ж бажана роль не може бути надана.\n\nТи можеш спробувати повторно заповнити форму командою /sponsorship",
"sponsor_approved_by": "✅ **Підписку схвалено**\nАдмін **{0}** переглянув та схвалив форму `{1}`.",
"sponsor_rejected_by": "❌ **Підписку відхилено**\nАдмін **{0}** переглянув та відхилив форму `{1}`.",
@ -96,6 +96,12 @@
"nearby_error": "⚠️ **Сталась помилка**\n\nПомилка: `{0}`\n\nTraceback:\n```\n{1}\n```",
"nearby_result": "Результати пошуку:\n\n{0}",
"nearby_empty": "Здається, нікого поблизу немає.",
"cancel": "Всі поточні операції скасовано.",
"identify_invalid_syntax": "Неправильний синтаксис!\nТреба: `/identify ID/NAME/USERNAME`",
"identify_not_found": "Не знайдено користувачів за запитом **{0}**",
"identify_success": "Користувач `{0}`\n\nІм'я: {1}\nЮзернейм: {2}\nЄ в чаті: {3}\nЄ адміном: {4}\nРоль: {5}\nНаявна анкета: {6}\nНаявне спонсорство: {7}",
"yes": "Так",
"no": "Ні",
"voice_message": [
"why are u gae",
"руки відірвало? пиши як людина",
@ -233,6 +239,7 @@
"rules_additional": "Додаткові правила, які несуть рекомендаційний характер, та не мають явних покарань за порушення:\n1⃣) У чаті немає заборони на російську мову. Ми поважаємо кожного українця і не бажаємо розпалювати мовні конфлікти.\n2⃣) У чаті немає заборони на російський контент. Але, майте на увазі, що учасники, здебільшого, не будуть зацікавлені у тому, щоб обговорювати його і він може бути проігнорованим.\n3⃣) Не зловживайте матами. Намагайтесь спілкуватись чистою мовою.\n4⃣) Поважайте авторські права контентмейкерів. Якщо ви знаходите арт, анімацію, музику тощо, на офіційних ресурсах (pixiv, twitter, deviantart тощо), відправляйте на нього посилання.\nЯкщо хтось із учасників відправив арт із не офіційного ресурсу і ви бажаєте дізнатись його автора, відправте у відповідь повідомлення із текстом `/search` на повідомлення із артом.",
"commands": {
"rules": "Правила спільноти",
"cancel": "Відмінити актуальну дію",
"nearby": "Показати користувачів поблизу",
"reapply": "Повторно заповнити анкету",
"sponsorship": "Отримати роль за спонсорство"
@ -241,6 +248,7 @@
"reboot": "Перезапустити бота",
"label": "Встановити нікнейм користувачу",
"message": "Надіслати користувачу повідомлення",
"identify": "Дізнатись дані про користувача за айді",
"warnings": "Переглянути попередження користувача",
"application": "Переглянути анкету користувача",
"applications": "Отримати всі анкети як JSON"
@ -250,6 +258,7 @@
"label": "Встановити нікнейм користувачу",
"nearby": "Показати користувачів поблизу",
"message": "Надіслати користувачу повідомлення",
"identify": "Дізнатись дані про користувача за айді",
"warnings": "Переглянути попередження користувача",
"application": "Переглянути анкету користувача",
"applications": "Отримати всі анкети як JSON"

View File

@ -4,7 +4,7 @@ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ReplyKeyb
from pyrogram.client import Client
from pyrogram import filters
from classes.holo_user import HoloUser
from modules.utils import configGet, locale, logWrite, should_quote
from modules.utils import configGet, locale, logWrite
from modules.handlers.confirmation import confirm_yes
from modules.handlers.welcome import welcome_pass
from modules.database import col_tmp, col_applications

View File

@ -36,7 +36,7 @@ async def callback_query_sponsor_yes(app: Client, clb: CallbackQuery):
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}")
logWrite(f"User {holo_user.id} got sponsorship approved by {clb.from_user.id}")
if col_sponsorships.find_one({"user": holo_user.id}) is not None:
col_sponsorships.update_one({"user": holo_user.id},
@ -82,7 +82,7 @@ async def callback_query_sponsor_no(app: Client, clb: CallbackQuery):
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}")
logWrite(f"User {holo_user.id} got sponsorship rejected by {clb.from_user.id}")
col_tmp.update_one({"user": holo_user.id, "type": "sponsorship"},
{

View File

@ -22,7 +22,7 @@ async def cmd_application(app: Client, msg: Message):
except (ValueError, UserNotFoundError):
try:
holo_user = HoloUser((await app.get_users(msg.command[1])).id)
except (bad_request_400.UsernameInvalid, bad_request_400.PeerIdInvalid):
except (bad_request_400.UsernameInvalid, bad_request_400.PeerIdInvalid, bad_request_400.UsernameNotOccupied):
await msg.reply_text(locale("no_user_application", "message", locale=msg.from_user).format(msg.command[1]), quote=should_quote(msg))
return

View File

@ -2,8 +2,11 @@ from app import app
from pyrogram import filters
from pyrogram.types import Message
from pyrogram.client import Client
from modules.utils import should_quote
from modules.utils import should_quote, logWrite, locale
from modules.database import col_tmp
@app.on_message(~ filters.scheduled & filters.command("cancel", prefixes=["/"]))
async def command_cancel(app: Client, msg: Message):
await msg.reply_text("Command exists.", quote=should_quote(msg))
col_tmp.delete_many( {"user": msg.from_user.id} )
await msg.reply_text(locale("cancel", "message", locale=msg.from_user), quote=should_quote(msg))
logWrite(f"Cancelling all ongoing tmp operations for {msg.from_user.id}")

View File

@ -0,0 +1,63 @@
from os import path
from app import app, isAnAdmin
from pyrogram import filters
from pyrogram.types import Message
from pyrogram.client import Client
from pyrogram.errors import bad_request_400
from pyrogram.enums.chat_action import ChatAction
from classes.holo_user import HoloUser, UserNotFoundError, UserInvalidError
from modules.utils import jsonLoad, should_quote, logWrite, locale, download_tmp, create_tmp
from modules import custom_filters
@app.on_message(~ filters.scheduled & filters.command("identify", prefixes=["/"]) & custom_filters.admin)
async def command_identify(app: Client, msg: Message):
if len(msg.command) != 2:
await msg.reply_text(locale("identify_invalid_syntax", "message", locale=msg.from_user))
return
try:
try:
holo_user = HoloUser(int(msg.command[1]))
except ValueError:
holo_user = HoloUser(await app.get_users(msg.command[1]))
except (UserInvalidError, UserNotFoundError, bad_request_400.UsernameInvalid, bad_request_400.PeerIdInvalid, bad_request_400.UsernameNotOccupied):
await msg.reply_text(locale("identify_not_found", "message", locale=msg.from_user).format(msg.command[1]))
return
role = holo_user.label
has_application = locale("yes", "message", locale=msg.from_user) if holo_user.application_approved() is True else locale("no", "message", locale=msg.from_user)
has_sponsorship = locale("yes", "message", locale=msg.from_user) if holo_user.sponsorship_valid() is True else locale("no", "message", locale=msg.from_user)
username = holo_user.username if holo_user.username is not None else "N/A"
in_chat = locale("yes", "message", locale=msg.from_user) if (holo_user.id in jsonLoad(path.join("cache", "group_members"))) else locale("no", "message", locale=msg.from_user)
is_admin = locale("yes", "message", locale=msg.from_user) if (await isAnAdmin(holo_user.id)) else locale("no", "message", locale=msg.from_user)
output = locale("identify_success", "message", locale=msg.from_user).format(
holo_user.id,
holo_user.name,
username,
in_chat,
is_admin,
role,
has_application,
has_sponsorship
)
user = await app.get_users(holo_user.id)
if user.photo is not None:
await app.send_chat_action(msg.chat.id, action=ChatAction.UPLOAD_PHOTO)
await msg.reply_photo(
create_tmp(await download_tmp(app, user.photo.big_file_id), kind="image"),
quote=should_quote(msg),
caption=output
)
else:
await app.send_chat_action(msg.chat.id, action=ChatAction.TYPING)
await msg.reply_text(
output,
quote=should_quote(msg)
)
logWrite(f"User {msg.from_user.id} identified user {holo_user.id}")

View File

@ -6,7 +6,7 @@ from modules.utils import locale, should_quote, find_user
from classes.holo_user import HoloUser, LabelTooLongError
from modules import custom_filters
@app.on_message(~ filters.scheduled & filters.private & filters.command(["label"], prefixes=["/"]) & custom_filters.admin)
@app.on_message(~ filters.scheduled & filters.command(["label"], prefixes=["/"]) & custom_filters.admin)
async def cmd_label(app: Client, msg: Message):
if len(msg.command) < 3:

View File

@ -45,9 +45,9 @@ async def cmd_nearby(app: Client, msg: Message):
user = col_users.find_one( {"user": entry["user"]} )
if user is not None:
if user["tg_username"] not in [None, "None", ""]: # Check if user has any name
output.append(f'{user["tg_name"]} (@{user["tg_username"]}):\n {entry["application"]["3"]["name"]}, {entry["application"]["3"]["adminName1"]}')
output.append(f'**{user["tg_name"]}** (@{user["tg_username"]}):\n - {entry["application"]["3"]["name"]}, {entry["application"]["3"]["adminName1"]}')
else:
output.append(f'{user["tg_name"]}:\n {entry["application"]["3"]["name"]}, {entry["application"]["3"]["adminName1"]}')
output.append(f'**{user["tg_name"]}**:\n - {entry["application"]["3"]["name"]}, {entry["application"]["3"]["adminName1"]}')
logWrite(f"{holo_user.id} tried to find someone nearby {location[1]} {location[0]} in the radius of {configGet('search_radius')} kilometers")

View File

@ -13,18 +13,25 @@ async def cmd_reapply(app: Client, msg: Message):
holo_user = HoloUser(msg.from_user)
if holo_user.application_state()[0] in ["approved", "rejected"]:
if (holo_user.application_state()[1] is True) and (not col_tmp.find_one({"user": holo_user.id, "type": "application"})["sent"]):
# Check if user has approved/rejected tmp application
if (holo_user.application_state()[0] in ["approved", "rejected"]) or (holo_user.application_state()[0] == "none"):
# Check if user's tmp application is already completed or even sent
if ((holo_user.application_state()[1] is True) and (not col_tmp.find_one({"user": holo_user.id, "type": "application"})["sent"])) or (holo_user.application_state()[0] == "none"):
left_chat = True
async for member in app.get_chat_members(configGet("destination_group")):
if member.user.id == msg.from_user.id:
left_chat = False
if not left_chat:
if holo_user.sponsorship_state()[0] == "fill":
await msg.reply_text(locale("finish_sponsorship", "message"), quote=should_quote(msg))
return
holo_user.application_restart(reapply=True)
await welcome_pass(app, msg, once_again=True)
else:
await msg.reply_text(locale("reapply_left_chat", "message", locale=holo_user), reply_markup=InlineKeyboardMarkup([
[
@ -34,15 +41,20 @@ async def cmd_reapply(app: Client, msg: Message):
InlineKeyboardButton(locale("reapply_new_one", "button", locale=holo_user), f"reapply_new_{msg.id}")
]
]))
else:
await msg.reply_text(locale("reapply_in_progress", "message", locale=holo_user).format(locale("confirm", "keyboard", locale=holo_user)[1][0]), reply_markup=InlineKeyboardMarkup([
[
InlineKeyboardButton(locale("applying_stop", "button", locale=holo_user), f"reapply_stop_{msg.id}")
]
]))
else:
if (holo_user.application_state()[0] == "fill") and (col_tmp.find_one({"user": holo_user.id, "type": "application"})["sent"] is True):
await msg.reply_text(locale("reapply_forbidden", "message", locale=holo_user))
else:
await msg.reply_text(locale("reapply_in_progress", "message", locale=holo_user).format(locale("confirm", "keyboard", locale=holo_user)[1][0]), reply_markup=InlineKeyboardMarkup([
[

View File

@ -1,11 +1,15 @@
"""Custom message filters made to improve commands
usage in context of Holo Users."""
from app import isAnAdmin
from modules.database import col_applications
from pyrogram import filters
from pyrogram.types import Message
async def admin_func(_, __, msg):
return await isAnAdmin(msg)
async def admin_func(_, __, msg: Message):
return await isAnAdmin(msg.from_user.id)
async def allowed_func(_, __, msg):
async def allowed_func(_, __, msg: Message):
return True if (col_applications.find_one({"user": msg.from_user.id}) is not None) else False
admin = filters.create(admin_func)

View File

@ -1,3 +1,6 @@
"""Module that provides all database columns and
creates geospatial index for col_applications"""
from pymongo import MongoClient, GEOSPHERE
from ujson import loads

View File

@ -2,6 +2,7 @@ from app import app
from pyrogram import filters
from pyrogram.types import ForceReply, ReplyKeyboardMarkup, Message
from pyrogram.client import Client
from classes.holo_user import HoloUser
from modules.utils import all_locales, locale, logWrite
# Welcome check ================================================================================================================
@ -11,7 +12,7 @@ for pattern in all_locales("welcome", "keyboard"):
for pattern in all_locales("return", "keyboard"):
welcome_1.append(pattern[0][0])
@app.on_message(~ filters.scheduled & filters.private & filters.command(welcome_1, prefixes=[""]))
async def welcome_pass(app, msg, once_again: bool = True) -> None:
async def welcome_pass(app: Client, msg: Message, once_again: bool = True) -> None:
"""Set user's stage to 1 and start a fresh application
### Args:
@ -22,6 +23,10 @@ async def welcome_pass(app, msg, once_again: bool = True) -> None:
if not once_again:
await msg.reply_text(locale("privacy_notice", "message"))
holo_user = HoloUser(msg.from_user)
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)))

View File

@ -1,3 +1,6 @@
"""Module responsible for providing answers to
all inline queries that bot receives"""
from datetime import datetime
from os import path, sep
from app import app, isAnAdmin

View File

@ -1,3 +1,6 @@
"""Automatically register commands and execute
some scheduled tasks is the main idea of this module"""
from os import listdir, makedirs, path, sep
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from datetime import datetime, timedelta

View File

@ -1,4 +1,5 @@
from typing import Any, Union
from typing import Any, Literal, Union
from uuid import uuid1
from requests import get
from pyrogram.enums.chat_type import ChatType
from pyrogram.types import User
@ -8,7 +9,7 @@ from ujson import JSONDecodeError as JSONDecodeError
from ujson import loads, dumps
from sys import exit
from os import kill, listdir, sep
from os import kill, listdir, makedirs, path, sep
from os import name as osname
from traceback import print_exc
from classes.errors.geo import PlaceNotFoundError
@ -191,6 +192,43 @@ def find_location(query: str) -> dict:
except (ValueError, KeyError, IndexError):
raise PlaceNotFoundError(query)
def create_tmp(bytedata: Union[bytes, bytearray], kind: Union[Literal["image", "video"], None] = None) -> str:
"""Create temporary file to help uploading it
### Args:
* bytedata (`Union[bytes, bytearray]`): Some bytes to be written
* kind (`Union[Literal["image", "video"], None]`): Kind of upload. Will add `.jpg` or `.mp4` if needed
### Returns:
* `str`: Path to temporary file
"""
filename = str(uuid1())
if kind == "image":
filename += ".jpg"
elif kind == "video":
filename += ".mp4"
makedirs("tmp", exist_ok=True)
with open(path.join("tmp", filename), "wb") as file:
file.write(bytedata)
return path.join("tmp", filename)
async def download_tmp(app: Client, file_id: str) -> bytes:
"""Download file by its ID and return its bytes
### Args:
* app (`Client`): App that will download the file
* file_id (`str`): File's unique id
### Returns:
* `bytes`: Bytes of downloaded file
"""
filename = str(uuid1())
makedirs("tmp", exist_ok=True)
await app.download_media(file_id, path.join("tmp", filename))
with open(path.join("tmp", filename), "rb") as f:
bytedata = f.read()
return bytedata
try:
from psutil import Process
except ModuleNotFoundError:

View File

@ -1,6 +1,87 @@
{
"$jsonSchema": {
"required": [],
"properties": {}
"required": [
"user",
"date",
"admin",
"application",
"application.1",
"application.2",
"application.3",
"application.3.name",
"application.3.adminName1",
"application.3.countryCode",
"application.3.countryName",
"application.3.location",
"application.4",
"application.5",
"application.6",
"application.7",
"application.8",
"application.9",
"application.10"
],
"properties": {
"user": {
"bsonType": ["int", "long"],
"description": "Telegram ID of user"
},
"date": {
"bsonType": "date",
"description": "Date when application was accepted"
},
"admin": {
"bsonType": ["int", "long"],
"description": "Telegram ID of admin that accepted the application"
},
"application": {
"bsonType": "object"
},
"application.1": {
"bsonType": "string"
},
"application.2": {
"bsonType": "date"
},
"application.3": {
"bsonType": "object"
},
"application.3.name": {
"bsonType": "string"
},
"application.3.adminName1": {
"bsonType": "string"
},
"application.3.countryCode": {
"bsonType": "string"
},
"application.3.countryName": {
"bsonType": "string"
},
"application.3.location": {
"bsonType": "array"
},
"application.4": {
"bsonType": "string"
},
"application.5": {
"bsonType": "string"
},
"application.6": {
"bsonType": "string"
},
"application.7": {
"bsonType": "string"
},
"application.8": {
"bsonType": "string"
},
"application.9": {
"bsonType": "string"
},
"application.10": {
"bsonType": "string"
}
}
}
}

View File

@ -1,6 +1,43 @@
{
"$jsonSchema": {
"required": [],
"properties": {}
"required": [
"user",
"date",
"admin",
"sponsorship",
"sponsorship.streamer",
"sponsorship.expires",
"sponsorship.proof",
"sponsorship.label"
],
"properties": {
"user": {
"bsonType": ["int", "long"],
"description": "Telegram ID of user"
},
"date": {
"bsonType": "date",
"description": "Date when sponsorship was accepted"
},
"admin": {
"bsonType": ["int", "long"],
"description": "Telegram ID of admin that accepted the sponsorship"
},
"sponsorship": {
"bsonType": "object"
},
"sponsorship.streamer": {
"bsonType": "string"
},
"sponsorship.expires": {
"bsonType": "date"
},
"sponsorship.proof": {
"bsonType": "binData"
},
"sponsorship.label": {
"bsonType": "string"
}
}
}
}

6
validation/tmp.json Normal file
View File

@ -0,0 +1,6 @@
{
"$jsonSchema": {
"required": [],
"properties": {}
}
}