Compare commits

..

No commits in common. "3b22cb01302ff8f020f84c546615b89bc41a9207" and "091c0abace762fe62947b1f368a89ae08971d103" have entirely different histories.

9 changed files with 75 additions and 113 deletions

View File

@ -1,11 +1,9 @@
from app import app, isAnAdmin
from typing import Any, List, Union
from pyrogram.types import User, ChatMember, ChatPrivileges, Chat, Message
from app import isAnAdmin
from typing import List, Union
from pyrogram.types import User, ChatMember, ChatPrivileges, Chat
from pyrogram.client import Client
from pyrogram.errors import bad_request_400
from modules.database import col_users, col_context, col_warnings, col_applications, col_sponsorships, col_messages
from modules.logging import logWrite
from modules.utils import configGet, locale, should_quote
from modules.database import col_users, col_context, col_warnings, col_applications, col_sponsorships
from modules.utils import configGet
class UserNotFoundError(Exception):
"""HoloUser could not find user with such an ID in database"""
@ -22,7 +20,7 @@ class UserInvalidError(Exception):
class HoloUser():
def __init__(self, user: Union[List[User], User, ChatMember, int, str]) -> None:
def __init__(self, user: Union[List[User], User, ChatMember, int]) -> None:
# Determine input object class and extract id
if isinstance(user, list) and len(user) != 0:
@ -33,13 +31,6 @@ class HoloUser():
self.id = user.user.id
elif isinstance(user, int):
self.id = user
elif isinstance(user, str):
try:
self.id = (app.get_users(user)).id # this line requires testing though
except bad_request_400.UsernameNotOccupied:
raise UserInvalidError(user)
except bad_request_400.PeerIdInvalid:
raise UserInvalidError(user)
else:
raise UserInvalidError(user)
@ -51,33 +42,9 @@ class HoloUser():
self.db_id = holo_user["_id"]
self.link = holo_user["link"]
self.label = holo_user["label"]
self.name = holo_user["tg_name"]
self.phone = holo_user["tg_phone"]
self.locale = holo_user["tg_locale"]
self.username = holo_user["tg_username"]
def set(self, key: str, value: Any) -> None:
"""Set attribute data and save it into database
### Args:
* `key` (`str`): Attribute to be changed
* `value` (`Any`): Value to set
"""
if not hasattr(self, key):
raise AttributeError()
setattr(self, key, value)
col_users.update_one(filter={"_id": self.db_id}, update={ "$set": { key: value } }, upsert=True)
logWrite(f"Set attribute {key} of user {self.id} to {value}")
async def message(self, origin: Message, text: Union[str, None] = None, photo: Union[str, None] = None, video: Union[str, None] = None, file: Union[str, None] = None):
new_message = await app.send_message(self.id, text+locale("message_reply_notice", "message"))
await origin.reply_text(locale("message_sent", "message"), quote=should_quote(origin))
logWrite(f"Admin {origin.from_user.id} sent message '{' '.join(origin.command[2:])}' to {self.id}")
col_messages.insert_one({"origin": {"chat": origin.chat.id, "id": origin.id}, "destination": {"chat": new_message.chat.id, "id": new_message.id}})
async def set_label(self, chat: Chat, label: str):
async def set_label(self, app: Client, chat: Chat, label: str):
"""Set label in destination group
### Args:
@ -85,19 +52,17 @@ class HoloUser():
* label (`str`): Label you want to set
"""
self.label = label
self.set("label", label)
await app.promote_chat_member(configGet("destination_group"), self.id)
if (not await isAnAdmin(self.id)) and (chat.id == configGet("admin_group")):
await app.set_administrator_title(configGet("destination_group"), self.id, label)
async def reset_label(self, chat: Chat):
async def reset_label(self, app: Client, chat: Chat):
"""Reset label in destination group
### Args:
* app (`Client`): Pyrogram client
"""
self.label = ""
self.set("label", "")
await app.set_administrator_title(configGet("destination_group"), self.id, "")
if (not await isAnAdmin(self.id)) and (chat.id == configGet("admin_group")):
await app.promote_chat_member(configGet("destination_group"), self.id, privileges=ChatPrivileges(

View File

@ -10,7 +10,7 @@ async def cmd_label(app, msg):
if msg.chat.id == configGet("admin_group") or await isAnAdmin(msg.from_user.id):
if len(msg.command) < 3:
await msg.reply_text("Invalid syntax:\n`/label USER LABEL`")
await msg.reply_text("Invalid syntax:\n`/label USER NICKNAME`")
return
target = await find_user(app, msg.command[1])
@ -19,15 +19,15 @@ async def cmd_label(app, msg):
target = HoloUser(target)
label = " ".join(msg.command[2:])
nickname = " ".join(msg.command[2:])
if label.lower() == "reset":
await target.reset_label(msg.chat)
if nickname.lower() == "reset":
await target.reset_label(app, msg.chat)
await msg.reply_text(f"Resetting **{target.id}**'s label...", quote=should_quote(msg))
else:
await target.set_label(msg.chat, label)
await msg.reply_text(f"Setting **{target.id}**'s label to **{label}**...", quote=should_quote(msg))
await target.set_label(app, msg.chat, nickname)
await msg.reply_text(f"Setting **{target.id}**'s label to **{nickname}**...", quote=should_quote(msg))
else:
await msg.reply_text(f"User not found")

View File

@ -2,9 +2,7 @@ from os import sep
from app import app, isAnAdmin
from pyrogram import filters
from pyrogram.errors import bad_request_400
from classes.holo_user import HoloUser
from modules.utils import jsonLoad, jsonSave, logWrite, locale, configGet, should_quote
from modules.database import col_messages
# Message command ==============================================================================================================
@app.on_message(~ filters.scheduled & filters.command(["message"], prefixes=["/"]))
@ -13,25 +11,36 @@ async def cmd_message(app, msg):
if msg.chat.id == configGet("admin_group") or await isAnAdmin(msg.from_user.id):
try:
try:
destination = HoloUser(int(msg.command[1]))
destination = await app.get_users(int(msg.command[1]))
if destination == [] or destination == None:
raise TypeError
except TypeError:
try:
destination = await app.get_users(msg.command[1])
except bad_request_400.UsernameNotOccupied:
await msg.reply_text(locale("message_no_user", "message"), quote=should_quote(msg))
logWrite(f"Admin {msg.from_user.id} tried to send message '{' '.join(msg.command[2:])}' to '{msg.command[1]}' but 'UsernameNotOccupied'")
return
except ValueError:
destination = HoloUser(msg.command[1])
try:
destination = await app.get_users(msg.command[1])
except bad_request_400.UsernameNotOccupied:
await msg.reply_text(locale("message_no_user", "message"), quote=should_quote(msg))
logWrite(f"Admin {msg.from_user.id} tried to send message '{' '.join(msg.command[2:])}' to '{msg.command[1]}' but 'UsernameNotOccupied'")
return
void = msg.command[2]
message = " ".join(msg.command[2:])
await destination.message(msg, msg.command[2:])
# try:
# new_message = await app.send_message(destination.id, message+locale("message_reply_notice", "message"))
# await msg.reply_text(locale("message_sent", "message"), quote=should_quote(msg))
# logWrite(f"Admin {msg.from_user.id} sent message '{' '.join(msg.command[2:])}' to {destination.id}")
# col_messages.insert_one({"origin": {"chat": msg.chat.id, "id": msg.id}, "destination": {"chat": new_message.chat.id, "id": new_message.id}})
# except bad_request_400.PeerIdInvalid:
# await msg.reply_text(locale("message_no_user", "message"), quote=should_quote(msg))
# logWrite(f"Admin {msg.from_user.id} tried to send message '{' '.join(msg.command[2:])}' to {destination.id} but 'PeerIdInvalid'")
try:
new_message = await app.send_message(destination.id, message+locale("message_reply_notice", "message"))
await msg.reply_text(locale("message_sent", "message"), quote=should_quote(msg))
logWrite(f"Admin {msg.from_user.id} sent message '{' '.join(msg.command[2:])}' to {destination.id}")
messages = jsonLoad(f"{configGet('data', 'locations')}{sep}messages.json")
messages.append({"origin": {"chat": msg.chat.id, "id": msg.id}, "destination": {"chat": new_message.chat.id, "id": new_message.id}})
jsonSave(messages, f"{configGet('data', 'locations')}{sep}messages.json")
except bad_request_400.PeerIdInvalid:
await msg.reply_text(locale("message_no_user", "message"), quote=should_quote(msg))
logWrite(f"Admin {msg.from_user.id} tried to send message '{' '.join(msg.command[2:])}' to {destination.id} but 'PeerIdInvalid'")
except IndexError:
await msg.reply_text(locale("message_invalid_syntax", "message"), quote=should_quote(msg))
logWrite(f"Admin {msg.from_user.id} tried to send message but 'IndexError'")

View File

@ -1,9 +1,7 @@
from app import app, isAnAdmin
from os import getpid
from sys import exit
from pyrogram import filters
from modules.utils import configGet, logWrite, should_quote
from modules.scheduled import scheduler
from modules.utils import configGet, logWrite, killProc, should_quote
pid = getpid()
@ -14,6 +12,5 @@ async def cmd_kill(app, msg):
if msg.chat.id == configGet("admin_group") or await isAnAdmin(msg.from_user.id):
logWrite(f"Shutting down bot with pid {pid}")
await msg.reply_text(f"Вимкнення бота з підом `{pid}`", quote=should_quote(msg))
scheduler.shutdown()
exit()
killProc(pid)
# ==============================================================================================================================

View File

@ -2,27 +2,24 @@ from app import app
from os import sep
from pyrogram import filters
from pyrogram.types import ReplyKeyboardMarkup
from modules.utils import locale, logWrite
from modules.database import col_users
from modules.utils import jsonLoad, jsonSave, configGet, configSet, locale, logWrite
# Start command ================================================================================================================
@app.on_message(~ filters.scheduled & filters.private & filters.command(["start"], prefixes=["/"]))
async def cmd_start(app, msg):
user = col_users.find_one({"user": msg.from_user.id})
try:
user_stage = configGet("stage", file=str(msg.from_user.id))
if user_stage != 0:
return
except FileNotFoundError:
jsonSave(jsonLoad(f"{configGet('data', 'locations')}{sep}user_default.json"), f"{configGet('data', 'locations')}{sep}users{sep}{msg.from_user.id}.json")
user_stage = configGet("stage", file=str(msg.from_user.id))
configSet(["telegram_id"], str(msg.from_user.username), file=str(msg.from_user.id))
configSet(["telegram_name"], f"{msg.from_user.first_name} {msg.from_user.last_name}", file=str(msg.from_user.id))
configSet(["telegram_phone"], str(msg.from_user.phone_number), file=str(msg.from_user.id))
configSet(["telegram_locale"], str(msg.from_user.language_code), file=str(msg.from_user.id))
if user is None:
col_users.insert_one({
"user": msg.from_user.id,
"link": None,
"label": "",
"tg_name": msg.from_user.first_name,
"tg_phone": msg.from_user.phone_number,
"tg_locale": msg.from_user.language_code,
"tg_username": msg.from_user.username
})
logWrite(f"User {msg.from_user.id} started bot interaction")
await msg.reply_text(locale("start", "message"), reply_markup=ReplyKeyboardMarkup(locale("welcome", "keyboard"), resize_keyboard=True))
logWrite(f"User {msg.from_user.id} started bot interaction")
await msg.reply_text(locale("start", "message"), reply_markup=ReplyKeyboardMarkup(locale("welcome", "keyboard"), resize_keyboard=True))
# ==============================================================================================================================

View File

@ -5,19 +5,19 @@ import asyncio
from pyrogram import filters
from pyrogram.types import ForceReply, ReplyKeyboardMarkup, Message
from modules.utils import configGet, configSet, jsonLoad, jsonSave, locale, logWrite, should_quote
from modules.database import col_messages
async def message_involved(msg: Message) -> bool:
message = col_messages.find_one({"destination.id": msg.reply_to_message.id, "destination.chat": msg.reply_to_message.chat.id})
if message is not None:
return True
async def message_involved(msg: Message):
messages = jsonLoad(f"{configGet('data', 'locations')}{sep}messages.json")
for message in messages:
if (message["destination"]["id"] == msg.reply_to_message.id) and (message["destination"]["chat"] == msg.reply_to_message.chat.id):
return True
return False
async def message_context(msg: Message) -> tuple:
message = col_messages.find_one({"destination.id": msg.reply_to_message.id, "destination.chat": msg.reply_to_message.chat.id})
if message is not None:
return message["origin"]["chat"], message["origin"]["id"]
return 0, 0
async def message_context(msg: Message):
messages = jsonLoad(f"{configGet('data', 'locations')}{sep}messages.json")
for message in messages:
if (message["destination"]["id"] == msg.reply_to_message.id) and (message["destination"]["chat"] == msg.reply_to_message.chat.id):
return message["origin"]["chat"], message["origin"]["id"]
# Any other input ==============================================================================================================
@app.on_message(~ filters.scheduled & filters.private)
@ -32,7 +32,9 @@ async def any_stage(app, msg):
else:
new_message = await (await app.get_messages(context[0], context[1])).reply_text(locale("message_from", "message").format(msg.from_user.first_name, msg.from_user.id)+msg.text+locale("message_reply_notice", "message"), quote=True)
await msg.reply_text(locale("message_sent", "message"), quote=should_quote(msg))
col_messages.insert_one({"origin": {"chat": msg.chat.id, "id": msg.id}, "destination": {"chat": new_message.chat.id, "id": new_message.id}})
messages = jsonLoad(f"{configGet('data', 'locations')}{sep}messages.json")
messages.append({"origin": {"chat": msg.chat.id, "id": msg.id}, "destination": {"chat": new_message.chat.id, "id": new_message.id}})
jsonSave(messages, f"{configGet('data', 'locations')}{sep}messages.json")
return
user_stage = configGet("stage", file=str(msg.from_user.id))

View File

@ -1,7 +1,6 @@
from app import app
from pyrogram import filters
from pyrogram.types import ForceReply, ReplyKeyboardMarkup
from classes.holo_user import HoloUser
from modules.utils import configGet, configSet, locale, logWrite
# Welcome check ================================================================================================================
@ -15,8 +14,6 @@ async def welcome_pass(app, msg, once_again: bool = True) -> None:
* once_again (bool, optional): Set to False if it's the first time as user applies. Defaults to True.
"""
holo_user = HoloUser(msg.from_user)
if not once_again:
await msg.reply_text(locale("privacy_notice", "message"))

View File

@ -1,4 +1,4 @@
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.schedulers.background import BackgroundScheduler
from datetime import datetime
from os import fsdecode, listdir, sep
from app import app
@ -6,7 +6,7 @@ from modules.utils import configGet, jsonLoad, locale, logWrite
from dateutil.relativedelta import relativedelta
from modules.database import col_applications
scheduler = AsyncIOScheduler()
scheduler = BackgroundScheduler()
# for user_file in listdir(f"{configGet('data', 'locations')}{sep}users{sep}"):
# filename = fsdecode(f"{configGet('data', 'locations')}{sep}users{sep}{user_file}")

View File

@ -3,7 +3,6 @@
"required": [
"user",
"link",
"label",
"tg_name",
"tg_phone",
"tg_locale",
@ -15,27 +14,23 @@
"description": "Telegram ID of user"
},
"link": {
"bsonType": ["string", "null"],
"description": "Invite link to destination group"
},
"label": {
"bsonType": "string",
"description": "Label given by admins"
"description": "Invite link to destination group"
},
"tg_name": {
"bsonType": "string",
"description": "Telegram first name"
},
"tg_phone": {
"bsonType": ["string", "null"],
"bsonType": "string",
"description": "Telegram phone number"
},
"tg_locale": {
"bsonType": ["string", "null"],
"bsonType": "string",
"description": "Telegram locale"
},
"tg_username": {
"bsonType": ["string", "null"],
"bsonType": "string",
"description": "Telegram username"
}
}