/cancel, /identify, sponsorships improvements and fixes #3
@ -104,9 +104,9 @@ After all of that you're good to go! Happy using :)
|
|||||||
|
|
||||||
## To-Do
|
## To-Do
|
||||||
|
|
||||||
* [ ] Check sponsorship on Holo girls
|
* [x] Check sponsorship on Holo girls
|
||||||
* [ ] Stats and infographic
|
* [ ] Stats and infographic
|
||||||
* [ ] /nearby command
|
* [x] /nearby command
|
||||||
* [ ] Check group members without completed application
|
* [ ] Check group members without completed application
|
||||||
* [x] Complete messenger between user and admins
|
* [x] Complete messenger between user and admins
|
||||||
* [x] Get application by id and user_id
|
* [x] Get application by id and user_id
|
7
app.py
7
app.py
@ -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"))
|
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):
|
async def isAnAdmin(admin_id):
|
||||||
|
|
||||||
|
# Check if user is mentioned in config
|
||||||
if (admin_id == configGet("owner")) or (admin_id in configGet("admins")):
|
if (admin_id == configGet("owner")) or (admin_id in configGet("admins")):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# Check if user is probably in cache
|
||||||
if path.exists(f"cache{sep}admins") is True:
|
if path.exists(f"cache{sep}admins") is True:
|
||||||
try:
|
try:
|
||||||
return True if admin_id in jsonLoad(f"cache{sep}admins") else False
|
return True if admin_id in jsonLoad(f"cache{sep}admins") else False
|
||||||
except (FileNotFoundError, JSONDecodeError):
|
except (FileNotFoundError, JSONDecodeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Check if user is in admin group
|
||||||
try:
|
try:
|
||||||
async for member in app.get_chat_members(configGet("admin_group")):
|
async for member in app.get_chat_members(configGet("admin_group")):
|
||||||
if member.user.id == admin_id:
|
if member.user.id == admin_id:
|
||||||
@ -22,4 +28,5 @@ async def isAnAdmin(admin_id):
|
|||||||
except bad_request_400.ChannelInvalid:
|
except bad_request_400.ChannelInvalid:
|
||||||
logWrite(f"Could not get users in admin group to answer isAnAdmin(). Bot is likely not in the group.")
|
logWrite(f"Could not get users in admin group to answer isAnAdmin(). Bot is likely not in the group.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return False
|
return False
|
@ -1,7 +1,4 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from os import sep
|
|
||||||
from uuid import uuid1
|
|
||||||
from requests import get
|
|
||||||
from traceback import print_exc
|
from traceback import print_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
|
||||||
@ -9,9 +6,9 @@ from pyrogram.types import User, ChatMember, ChatPrivileges, Chat, Message, Phot
|
|||||||
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 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.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):
|
class DefaultApplicationTemp(dict):
|
||||||
def __init__(self, user: int, reapply: bool = False):
|
def __init__(self, user: int, reapply: bool = False):
|
||||||
@ -286,10 +283,15 @@ class HoloUser():
|
|||||||
if len(label) > 16:
|
if len(label) > 16:
|
||||||
raise LabelTooLongError(label)
|
raise LabelTooLongError(label)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.set("label", label)
|
try:
|
||||||
await app.promote_chat_member(configGet("destination_group"), self.id, privileges=ChatPrivileges(can_pin_messages=True, can_manage_video_chats=True))
|
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):
|
if not await isAnAdmin(self.id):
|
||||||
await app.set_administrator_title(configGet("destination_group"), self.id, label)
|
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:
|
async def label_reset(self, chat: Chat) -> None:
|
||||||
"""Reset label in destination group
|
"""Reset label in destination group
|
||||||
@ -344,11 +346,14 @@ 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": "application"}) is None:
|
# if col_tmp.find_one({"user": self.id, "type": "application"}) is None:
|
||||||
|
|
||||||
col_tmp.insert_one(
|
if self.sponsorship_state()[0] == "fill":
|
||||||
document=DefaultApplicationTemp(self.id).dict
|
return
|
||||||
)
|
|
||||||
|
# col_tmp.insert_one(
|
||||||
|
# document=DefaultApplicationTemp(self.id).dict
|
||||||
|
# )
|
||||||
|
|
||||||
progress = col_tmp.find_one({"user": self.id, "type": "application"})
|
progress = col_tmp.find_one({"user": self.id, "type": "application"})
|
||||||
|
|
||||||
@ -357,9 +362,9 @@ class HoloUser():
|
|||||||
|
|
||||||
stage = progress["stage"]
|
stage = progress["stage"]
|
||||||
|
|
||||||
if self.sponsorship_state()[0] == "fill":
|
# if self.sponsorship_state()[0] == "fill":
|
||||||
await msg.reply_text(locale("finish_sponsorship", "message"), quote=should_quote(msg))
|
# await msg.reply_text(locale("finish_sponsorship", "message"), quote=should_quote(msg))
|
||||||
return
|
# return
|
||||||
|
|
||||||
if progress["state"] == "fill" and progress["sent"] is False:
|
if progress["state"] == "fill" and progress["sent"] is False:
|
||||||
|
|
||||||
@ -514,21 +519,24 @@ class HoloUser():
|
|||||||
elif stage == 3:
|
elif stage == 3:
|
||||||
|
|
||||||
if photo is not None:
|
if photo is not None:
|
||||||
filename = uuid1()
|
progress["sponsorship"]["proof"] = await download_tmp(app, photo.file_id)
|
||||||
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}})
|
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))))
|
||||||
|
|
||||||
elif stage == 4:
|
elif stage == 4:
|
||||||
if len(query) > 16:
|
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
|
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_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:
|
else:
|
||||||
return
|
return
|
||||||
|
@ -13,6 +13,7 @@ makedirs(f'{configGet("cache", "locations")}{sep}avatars', exist_ok=True)
|
|||||||
from modules.commands.application import *
|
from modules.commands.application import *
|
||||||
from modules.commands.applications import *
|
from modules.commands.applications import *
|
||||||
from modules.commands.cancel import *
|
from modules.commands.cancel import *
|
||||||
|
from modules.commands.identify import *
|
||||||
from modules.commands.label import *
|
from modules.commands.label import *
|
||||||
from modules.commands.message import *
|
from modules.commands.message import *
|
||||||
from modules.commands.nearby import *
|
from modules.commands.nearby import *
|
||||||
|
@ -26,13 +26,13 @@
|
|||||||
"sponsor2": "До якої дати (`ДД.ММ.РРРР`) підписка?",
|
"sponsor2": "До якої дати (`ДД.ММ.РРРР`) підписка?",
|
||||||
"sponsor2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`",
|
"sponsor2_invalid": "Будь ласка, введи дату формату `ДД.ММ.РРРР`",
|
||||||
"sponsor2_past": "Вказана дата знаходиться в минулому. Будь ласка, вкажіть правильний термін дії підписки",
|
"sponsor2_past": "Вказана дата знаходиться в минулому. Будь ласка, вкажіть правильний термін дії підписки",
|
||||||
"sponsor3": "Будь ласка, надішли одне фото для підтвердження дійсності підписки",
|
"sponsor3": "Будь ласка, надішли одне фото для підтвердження дійсності підписки\n\nℹ️ **Підказка**\nПрочитай як правильно скрінити легітимне підтвердження підписки: https://telegra.ph/Pіdpiska-na-holo-dіvchinu-01-02",
|
||||||
"sponsor4": "Яку роль ти бажаєш отримати?",
|
"sponsor4": "Яку роль ти бажаєш отримати?\n\nℹ️ **Підказка**\nНазва ролі повинна бути якось пов'язана зі вказаною дівчиною, не повинна порушувати правила спільноти а також має бути не довше за 16 символів (обмеження Telegram).",
|
||||||
"sponsorship_application_empty": "❌ **Дія неможлива**\nУ тебе немає заповненої та схваленої анкети. Заповни таку за допомогою /reapply та спробуй ще раз після її підтвердження.",
|
"sponsorship_application_empty": "❌ **Дія неможлива**\nУ тебе немає заповненої та схваленої анкети. Заповни таку за допомогою /reapply та спробуй ще раз після її підтвердження.",
|
||||||
"confirm": "Супер, дякуємо!\n\nБудь ласка, перевір правильність даних:\n{0}\n\nВсе правильно?",
|
"confirm": "Супер, дякуємо!\n\nБудь ласка, перевір правильність даних:\n{0}\n\nВсе правильно?",
|
||||||
"sponsor_confirm": "Здається, це все. Перевір чи все правильно та жмакни кнопку на клавіатурі щоб продовжити.",
|
"sponsor_confirm": "**Дані форми:**\nСтрімер: {0}\nПідписка до: {1}\nХочу роль: {2}\n\nПеревір чи все правильно та жмакни кнопку на клавіатурі щоб продовжити.",
|
||||||
"application_sent": "Дякуємо! Ми надіслали твою анкетку на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. До тих пір від тебе більше нічого не потребується. Гарного дня! :)",
|
"application_sent": "Дякуємо! Ми надіслали твою анкетку на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. До тих пір від тебе більше нічого не потребується :)",
|
||||||
"sponsorship_sent": "Дякуємо! Ми надіслали форму на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення. Гарного дня! :)",
|
"sponsorship_sent": "Дякуємо! Ми надіслали форму на перевірку. Ти отримаєш повідомлення як тільки її перевірять та приймуть рішення :)",
|
||||||
"application_got": "Отримано анкету від `{0}`\n\nІм'я тг: `{1}`\nЮзернейм: @{2}\n\n**Дані анкети:**\n{3}",
|
"application_got": "Отримано анкету від `{0}`\n\nІм'я тг: `{1}`\nЮзернейм: @{2}\n\n**Дані анкети:**\n{3}",
|
||||||
"reapply_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}",
|
"sponsor_got": "Отримано форму на спонсорство від `{0}`\n\nІм'я тг: `{1}`\nЮзернейм: @{2}\n\n**Дані форми:**\n{3}",
|
||||||
@ -49,7 +49,7 @@
|
|||||||
"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_approved": "Вітаємо! Твою форму переглянули та підтвердили її правильність. Коли термін дії наданої підписки буде добігати кінця - ми нагадаємо, що треба оновити дані аби й надалі отримувати плюшки в чаті. Також можна повторно заповнити форму, якщо хочеться змінити бажане ім'я ролі або подовжити термін дії підписки завчасно, за допомогою команди /sponsorship. Гарного дня!",
|
||||||
"sponsor_rejected": "Ой лишенько! Твою форму переглянули, однак не підтвердили її. Можливо, щось не так з датами, або ж бажана роль не може бути надана.\n\nТи можеш спробувати повторно заповнити форму командою /sponsorship",
|
"sponsor_rejected": "Ой лишенько! Твою форму переглянули, однак не підтвердили її. Можливо, щось не так з датами, або ж бажана роль не може бути надана.\n\nТи можеш спробувати повторно заповнити форму командою /sponsorship",
|
||||||
"sponsor_approved_by": "✅ **Підписку схвалено**\nАдмін **{0}** переглянув та схвалив форму `{1}`.",
|
"sponsor_approved_by": "✅ **Підписку схвалено**\nАдмін **{0}** переглянув та схвалив форму `{1}`.",
|
||||||
"sponsor_rejected_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_error": "⚠️ **Сталась помилка**\n\nПомилка: `{0}`\n\nTraceback:\n```\n{1}\n```",
|
||||||
"nearby_result": "Результати пошуку:\n\n{0}",
|
"nearby_result": "Результати пошуку:\n\n{0}",
|
||||||
"nearby_empty": "Здається, нікого поблизу немає.",
|
"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": [
|
"voice_message": [
|
||||||
"why are u gae",
|
"why are u gae",
|
||||||
"руки відірвало? пиши як людина",
|
"руки відірвало? пиши як людина",
|
||||||
@ -233,6 +239,7 @@
|
|||||||
"rules_additional": "Додаткові правила, які несуть рекомендаційний характер, та не мають явних покарань за порушення:\n1️⃣) У чаті немає заборони на російську мову. Ми поважаємо кожного українця і не бажаємо розпалювати мовні конфлікти.\n2️⃣) У чаті немає заборони на російський контент. Але, майте на увазі, що учасники, здебільшого, не будуть зацікавлені у тому, щоб обговорювати його і він може бути проігнорованим.\n3️⃣) Не зловживайте матами. Намагайтесь спілкуватись чистою мовою.\n4️⃣) Поважайте авторські права контентмейкерів. Якщо ви знаходите арт, анімацію, музику тощо, на офіційних ресурсах (pixiv, twitter, deviantart тощо), відправляйте на нього посилання.\nЯкщо хтось із учасників відправив арт із не офіційного ресурсу і ви бажаєте дізнатись його автора, відправте у відповідь повідомлення із текстом `/search` на повідомлення із артом.",
|
"rules_additional": "Додаткові правила, які несуть рекомендаційний характер, та не мають явних покарань за порушення:\n1️⃣) У чаті немає заборони на російську мову. Ми поважаємо кожного українця і не бажаємо розпалювати мовні конфлікти.\n2️⃣) У чаті немає заборони на російський контент. Але, майте на увазі, що учасники, здебільшого, не будуть зацікавлені у тому, щоб обговорювати його і він може бути проігнорованим.\n3️⃣) Не зловживайте матами. Намагайтесь спілкуватись чистою мовою.\n4️⃣) Поважайте авторські права контентмейкерів. Якщо ви знаходите арт, анімацію, музику тощо, на офіційних ресурсах (pixiv, twitter, deviantart тощо), відправляйте на нього посилання.\nЯкщо хтось із учасників відправив арт із не офіційного ресурсу і ви бажаєте дізнатись його автора, відправте у відповідь повідомлення із текстом `/search` на повідомлення із артом.",
|
||||||
"commands": {
|
"commands": {
|
||||||
"rules": "Правила спільноти",
|
"rules": "Правила спільноти",
|
||||||
|
"cancel": "Відмінити актуальну дію",
|
||||||
"nearby": "Показати користувачів поблизу",
|
"nearby": "Показати користувачів поблизу",
|
||||||
"reapply": "Повторно заповнити анкету",
|
"reapply": "Повторно заповнити анкету",
|
||||||
"sponsorship": "Отримати роль за спонсорство"
|
"sponsorship": "Отримати роль за спонсорство"
|
||||||
@ -241,6 +248,7 @@
|
|||||||
"reboot": "Перезапустити бота",
|
"reboot": "Перезапустити бота",
|
||||||
"label": "Встановити нікнейм користувачу",
|
"label": "Встановити нікнейм користувачу",
|
||||||
"message": "Надіслати користувачу повідомлення",
|
"message": "Надіслати користувачу повідомлення",
|
||||||
|
"identify": "Дізнатись дані про користувача за айді",
|
||||||
"warnings": "Переглянути попередження користувача",
|
"warnings": "Переглянути попередження користувача",
|
||||||
"application": "Переглянути анкету користувача",
|
"application": "Переглянути анкету користувача",
|
||||||
"applications": "Отримати всі анкети як JSON"
|
"applications": "Отримати всі анкети як JSON"
|
||||||
@ -250,6 +258,7 @@
|
|||||||
"label": "Встановити нікнейм користувачу",
|
"label": "Встановити нікнейм користувачу",
|
||||||
"nearby": "Показати користувачів поблизу",
|
"nearby": "Показати користувачів поблизу",
|
||||||
"message": "Надіслати користувачу повідомлення",
|
"message": "Надіслати користувачу повідомлення",
|
||||||
|
"identify": "Дізнатись дані про користувача за айді",
|
||||||
"warnings": "Переглянути попередження користувача",
|
"warnings": "Переглянути попередження користувача",
|
||||||
"application": "Переглянути анкету користувача",
|
"application": "Переглянути анкету користувача",
|
||||||
"applications": "Отримати всі анкети як JSON"
|
"applications": "Отримати всі анкети як JSON"
|
||||||
|
@ -4,7 +4,7 @@ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ReplyKeyb
|
|||||||
from pyrogram.client import Client
|
from pyrogram.client import Client
|
||||||
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, should_quote
|
from modules.utils import configGet, locale, logWrite
|
||||||
from modules.handlers.confirmation import confirm_yes
|
from modules.handlers.confirmation import confirm_yes
|
||||||
from modules.handlers.welcome import welcome_pass
|
from modules.handlers.welcome import welcome_pass
|
||||||
from modules.database import col_tmp, col_applications
|
from modules.database import col_tmp, col_applications
|
||||||
|
@ -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(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))
|
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:
|
if col_sponsorships.find_one({"user": holo_user.id}) is not None:
|
||||||
col_sponsorships.update_one({"user": holo_user.id},
|
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(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))
|
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"},
|
col_tmp.update_one({"user": holo_user.id, "type": "sponsorship"},
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@ async def cmd_application(app: Client, msg: Message):
|
|||||||
except (ValueError, UserNotFoundError):
|
except (ValueError, UserNotFoundError):
|
||||||
try:
|
try:
|
||||||
holo_user = HoloUser((await app.get_users(msg.command[1])).id)
|
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))
|
await msg.reply_text(locale("no_user_application", "message", locale=msg.from_user).format(msg.command[1]), quote=should_quote(msg))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -2,8 +2,11 @@ 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 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=["/"]))
|
@app.on_message(~ filters.scheduled & filters.command("cancel", prefixes=["/"]))
|
||||||
async def command_cancel(app: Client, msg: Message):
|
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}")
|
63
modules/commands/identify.py
Normal file
63
modules/commands/identify.py
Normal 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}")
|
@ -6,7 +6,7 @@ from modules.utils import locale, should_quote, find_user
|
|||||||
from classes.holo_user import HoloUser, LabelTooLongError
|
from classes.holo_user import HoloUser, LabelTooLongError
|
||||||
from modules import custom_filters
|
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):
|
async def cmd_label(app: Client, msg: Message):
|
||||||
|
|
||||||
if len(msg.command) < 3:
|
if len(msg.command) < 3:
|
||||||
|
@ -45,9 +45,9 @@ async def cmd_nearby(app: Client, msg: Message):
|
|||||||
user = col_users.find_one( {"user": entry["user"]} )
|
user = col_users.find_one( {"user": entry["user"]} )
|
||||||
if user is not None:
|
if user is not None:
|
||||||
if user["tg_username"] not in [None, "None", ""]: # Check if user has any name
|
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:
|
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")
|
logWrite(f"{holo_user.id} tried to find someone nearby {location[1]} {location[0]} in the radius of {configGet('search_radius')} kilometers")
|
||||||
|
|
||||||
|
@ -13,18 +13,25 @@ async def cmd_reapply(app: Client, msg: Message):
|
|||||||
|
|
||||||
holo_user = HoloUser(msg.from_user)
|
holo_user = HoloUser(msg.from_user)
|
||||||
|
|
||||||
if holo_user.application_state()[0] in ["approved", "rejected"]:
|
# Check if user has approved/rejected tmp application
|
||||||
if (holo_user.application_state()[1] is True) and (not col_tmp.find_one({"user": holo_user.id, "type": "application"})["sent"]):
|
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
|
left_chat = True
|
||||||
|
|
||||||
async for member in app.get_chat_members(configGet("destination_group")):
|
async for member in app.get_chat_members(configGet("destination_group")):
|
||||||
if member.user.id == msg.from_user.id:
|
if member.user.id == msg.from_user.id:
|
||||||
left_chat = False
|
left_chat = False
|
||||||
|
|
||||||
if not left_chat:
|
if not left_chat:
|
||||||
if holo_user.sponsorship_state()[0] == "fill":
|
if holo_user.sponsorship_state()[0] == "fill":
|
||||||
await msg.reply_text(locale("finish_sponsorship", "message"), quote=should_quote(msg))
|
await msg.reply_text(locale("finish_sponsorship", "message"), quote=should_quote(msg))
|
||||||
return
|
return
|
||||||
holo_user.application_restart(reapply=True)
|
holo_user.application_restart(reapply=True)
|
||||||
await welcome_pass(app, msg, once_again=True)
|
await welcome_pass(app, msg, once_again=True)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
await msg.reply_text(locale("reapply_left_chat", "message", locale=holo_user), reply_markup=InlineKeyboardMarkup([
|
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}")
|
InlineKeyboardButton(locale("reapply_new_one", "button", locale=holo_user), f"reapply_new_{msg.id}")
|
||||||
]
|
]
|
||||||
]))
|
]))
|
||||||
|
|
||||||
else:
|
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([
|
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}")
|
InlineKeyboardButton(locale("applying_stop", "button", locale=holo_user), f"reapply_stop_{msg.id}")
|
||||||
]
|
]
|
||||||
]))
|
]))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if (holo_user.application_state()[0] == "fill") and (col_tmp.find_one({"user": holo_user.id, "type": "application"})["sent"] is True):
|
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))
|
await msg.reply_text(locale("reapply_forbidden", "message", locale=holo_user))
|
||||||
|
|
||||||
else:
|
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([
|
await msg.reply_text(locale("reapply_in_progress", "message", locale=holo_user).format(locale("confirm", "keyboard", locale=holo_user)[1][0]), reply_markup=InlineKeyboardMarkup([
|
||||||
[
|
[
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
"""Custom message filters made to improve commands
|
||||||
|
usage in context of Holo Users."""
|
||||||
|
|
||||||
from app import isAnAdmin
|
from app import isAnAdmin
|
||||||
from modules.database import col_applications
|
from modules.database import col_applications
|
||||||
from pyrogram import filters
|
from pyrogram import filters
|
||||||
|
from pyrogram.types import Message
|
||||||
|
|
||||||
async def admin_func(_, __, msg):
|
async def admin_func(_, __, msg: Message):
|
||||||
return await isAnAdmin(msg)
|
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
|
return True if (col_applications.find_one({"user": msg.from_user.id}) is not None) else False
|
||||||
|
|
||||||
admin = filters.create(admin_func)
|
admin = filters.create(admin_func)
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
"""Module that provides all database columns and
|
||||||
|
creates geospatial index for col_applications"""
|
||||||
|
|
||||||
from pymongo import MongoClient, GEOSPHERE
|
from pymongo import MongoClient, GEOSPHERE
|
||||||
from ujson import loads
|
from ujson import loads
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ from app import app
|
|||||||
from pyrogram import filters
|
from pyrogram import filters
|
||||||
from pyrogram.types import ForceReply, ReplyKeyboardMarkup, Message
|
from pyrogram.types import ForceReply, ReplyKeyboardMarkup, Message
|
||||||
from pyrogram.client import Client
|
from pyrogram.client import Client
|
||||||
|
from classes.holo_user import HoloUser
|
||||||
from modules.utils import all_locales, locale, logWrite
|
from modules.utils import all_locales, locale, logWrite
|
||||||
|
|
||||||
# Welcome check ================================================================================================================
|
# Welcome check ================================================================================================================
|
||||||
@ -11,7 +12,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(~ filters.scheduled & filters.private & filters.command(welcome_1, prefixes=[""]))
|
@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
|
"""Set user's stage to 1 and start a fresh application
|
||||||
|
|
||||||
### Args:
|
### Args:
|
||||||
@ -22,6 +23,10 @@ async def welcome_pass(app, msg, once_again: bool = True) -> None:
|
|||||||
|
|
||||||
if not once_again:
|
if not once_again:
|
||||||
await msg.reply_text(locale("privacy_notice", "message"))
|
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")
|
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)))
|
await msg.reply_text(locale("question1", "message", locale=msg.from_user), reply_markup=ForceReply(placeholder=locale("question1", "force_reply", locale=msg.from_user)))
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
"""Module responsible for providing answers to
|
||||||
|
all inline queries that bot receives"""
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from os import path, sep
|
from os import path, sep
|
||||||
from app import app, isAnAdmin
|
from app import app, isAnAdmin
|
||||||
|
@ -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 os import listdir, makedirs, path, sep
|
||||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from typing import Any, Union
|
from typing import Any, Literal, Union
|
||||||
|
from uuid import uuid1
|
||||||
from requests import get
|
from requests import get
|
||||||
from pyrogram.enums.chat_type import ChatType
|
from pyrogram.enums.chat_type import ChatType
|
||||||
from pyrogram.types import User
|
from pyrogram.types import User
|
||||||
@ -8,7 +9,7 @@ from ujson import JSONDecodeError as JSONDecodeError
|
|||||||
from ujson import loads, dumps
|
from ujson import loads, dumps
|
||||||
|
|
||||||
from sys import exit
|
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 os import name as osname
|
||||||
from traceback import print_exc
|
from traceback import print_exc
|
||||||
from classes.errors.geo import PlaceNotFoundError
|
from classes.errors.geo import PlaceNotFoundError
|
||||||
@ -191,6 +192,43 @@ def find_location(query: str) -> dict:
|
|||||||
except (ValueError, KeyError, IndexError):
|
except (ValueError, KeyError, IndexError):
|
||||||
raise PlaceNotFoundError(query)
|
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:
|
try:
|
||||||
from psutil import Process
|
from psutil import Process
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
|
@ -1,6 +1,87 @@
|
|||||||
{
|
{
|
||||||
"$jsonSchema": {
|
"$jsonSchema": {
|
||||||
"required": [],
|
"required": [
|
||||||
"properties": {}
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,43 @@
|
|||||||
{
|
{
|
||||||
"$jsonSchema": {
|
"$jsonSchema": {
|
||||||
"required": [],
|
"required": [
|
||||||
"properties": {}
|
"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
6
validation/tmp.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"$jsonSchema": {
|
||||||
|
"required": [],
|
||||||
|
"properties": {}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user