From be0c2b079c797a3555c15e3db4d5411c33f2924f Mon Sep 17 00:00:00 2001 From: Itz-fork Date: Sun, 31 Dec 2023 15:14:02 +0530 Subject: [PATCH] perf: reduce database calls and use C wrapper for calculations --- megadl/helpers/database.py | 84 +++++++++++++++----------------------- megadl/helpers/pyros.py | 37 ++--------------- megadl/lib/megatools.py | 12 ++---- megadl/modules/admin.py | 14 +++---- megadl/modules/generals.py | 12 +++--- megadl/modules/mega_up.py | 2 +- requirements.txt | 3 +- 7 files changed, 57 insertions(+), 107 deletions(-) diff --git a/megadl/helpers/database.py b/megadl/helpers/database.py index 8309a19b..2315b5be 100644 --- a/megadl/helpers/database.py +++ b/megadl/helpers/database.py @@ -14,42 +14,38 @@ def __init__(self) -> None: # <<<<<<<<<< Active user functions >>>>>>>>>> # async def add(self, user_id: int): - added = await self.is_there(user_id) - if not added: - await self.mongoc.insert_async( - self.coll_users, - { - "_id": user_id, - "email": "", - "password": "", - "status": {"banned": False, "reason": ""}, - "total_downloads": 0, - "total_uploads": 0, - }, - ) + await self.mongoc.update_async( + self.coll_users, + {"_id": user_id}, + { + "_id": user_id, + "email": "", + "password": "", + "status": {"banned": False, "reason": ""}, + "total_downloads": 0, + "total_uploads": 0, + }, + upsert=True, + ) async def plus_fl_count( self, user_id: int, downloads: int | None = None, uploads: int | None = None ): - dl_up = await self.is_there(user_id) if downloads: await self.mongoc.update_async( self.coll_users, {"_id": user_id}, - {"total_downloads": dl_up["total_downloads"] + downloads}, + {"$inc": {"total_downloads": downloads}}, ) elif uploads: await self.mongoc.update_async( self.coll_users, {"_id": user_id}, - {"total_uploads": dl_up["total_uploads"] + uploads}, + {"$inc": {"total_uploads": uploads}}, ) async def delete(self, user_id: int): - uid = {"_id": user_id} - added = await self.is_there(self.coll_users, user_id) - if added: - await self.mongoc.delete_async(self.coll_users, uid) + await self.mongoc.delete_async(self.coll_users, {"_id": user_id}) async def is_there(self, user_id: int, use_acc: bool = False): """ @@ -74,45 +70,31 @@ async def is_there(self, user_id: int, use_acc: bool = False): # <<<<<<<<<< Banned user functions >>>>>>>>>> # async def ban_user(self, user_id: int, reason: str): - uid = {"_id": user_id} - to_ban = await self.mongoc.find_async(self.coll_users, uid) - if to_ban: - await self.mongoc.update_async( - self.coll_users, - {"_id": user_id}, - {"status": {"banned": True, "reason": reason}}, - ) + await self.mongoc.update_async( + self.coll_users, + {"_id": user_id}, + {"status": {"banned": True, "reason": reason}}, + ) async def unban_user(self, user_id: int): - uid = {"_id": user_id} - to_ban = await self.mongoc.find_async(self.coll_users, uid) - if to_ban: - await self.mongoc.update_async( - self.coll_users, - {"_id": user_id}, - {"status": {"banned": False, "reason": "Got unbanned"}}, - ) + await self.mongoc.update_async( + self.coll_users, + {"_id": user_id}, + {"status": {"banned": False, "reason": "Got unbanned"}}, + ) # <<<<<<<<<< Mega functions >>>>>>>>>> # async def mega_login(self, user_id: int, email: str, password: str): - uid = {"_id": user_id} - logged = await self.mongoc.find_async(self.coll_users, uid) - if logged: - await self.mongoc.update_async( - self.coll_users, uid, {"email": email, "password": password} - ) - # this should never happen but better safe than sorry - else: - await self.mongoc.insert_async( - self.coll_users, {"_id": user_id, "email": email, "password": password} - ) + await self.mongoc.update_async( + self.coll_users, + {"_id": user_id}, + {"email": email, "password": password}, + upsert=True, + ) async def mega_logout(self, user_id: int): - uid = {"_id": user_id} - logged = await self.mongoc.find_async(self.coll_users, uid) - if logged: - await self.mongoc.delete_async(self.coll_users, uid) + await self.mongoc.delete_async(self.coll_users, {"_id": user_id}) async def how_many(self): return (user["user_id"] async for user in self.coll_users.find({})) diff --git a/megadl/helpers/pyros.py b/megadl/helpers/pyros.py index d7d30989..042ccb8b 100644 --- a/megadl/helpers/pyros.py +++ b/megadl/helpers/pyros.py @@ -5,6 +5,7 @@ from time import time from math import floor +from humans import human_time, human_bytes # Porogress bar for pyrogram @@ -19,8 +20,8 @@ async def track_progress(current, total, client, ides, start, **kwargs): time_to_completion = round((total - current) / speed) * 1000 estimated_total_time = elapsed_time + time_to_completion - elapsed_time = TimeFormatter(milliseconds=elapsed_time) - estimated_total_time = TimeFormatter(milliseconds=estimated_total_time) + elapsed_time = human_time(elapsed_time) + estimated_total_time = human_time(estimated_total_time) progress = "[{0}{1}] \n**Process**: {2}%\n".format( "█" * floor(percentage / 5), @@ -28,40 +29,10 @@ async def track_progress(current, total, client, ides, start, **kwargs): round(percentage, 2), ) - tmp = f"{progress}{humanbytes(current)} of {humanbytes(total)}\n**Speed:** {humanbytes(speed)}/s\n**ETA:** {estimated_total_time if estimated_total_time != '' else '0 s'}\n" + tmp = f"{progress}{human_bytes(current)} of {human_bytes(total)}\n**Speed:** {human_bytes(speed)}/s\n**ETA:** {estimated_total_time if estimated_total_time != '' else '0 s'}\n" try: await client.edit_message_text( ides[0], ides[1], f"{tmp}\n\n**Powered by @NexaBotsUpdates**", **kwargs ) except: pass - - -def TimeFormatter(milliseconds: int) -> str: - seconds, milliseconds = divmod(int(milliseconds), 1000) - minutes, seconds = divmod(seconds, 60) - hours, minutes = divmod(minutes, 60) - days, hours = divmod(hours, 24) - - if minutes > 0: - return f"{minutes}m" - elif seconds > 0: - return f"{seconds}s" - elif hours > 0: - return f"{hours}h" - elif days > 0: - return f"{days}d" - else: - return f"{milliseconds}ms" - - -def humanbytes(size): - if not size: - return "" - power = 2**10 - n = 0 - pwrN = {0: " ", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"} - while size > power: - size /= power - n += 1 - return str(round(size, 2)) + " " + pwrN[n] + "B" diff --git a/megadl/lib/megatools.py b/megadl/lib/megatools.py index 7894c01b..648377d7 100644 --- a/megadl/lib/megatools.py +++ b/megadl/lib/megatools.py @@ -8,8 +8,8 @@ import json import asyncio +from humans import human_bytes from aiohttp import ClientSession -from megadl.helpers.pyros import humanbytes from megadl.helpers.files import listfiles from megadl.helpers.sysfncs import run_partial, run_on_shell from megadl.helpers.crypt import ( @@ -199,7 +199,7 @@ async def get_info(url: str) -> list[str]: data = (await resp.json())[0] key = base64_to_a32(file_key) tk = (key[0] ^ key[4], key[1] ^ key[5], key[2] ^ key[6], key[3] ^ key[7]) - fsize = humanbytes(data["s"]) + fsize = human_bytes(data["s"]) fname = decrypt_attr(base64_url_decode(data["at"]), tk)["n"] return [fsize, fname] @@ -264,16 +264,12 @@ async def prepare_string(nodes, shared_key, depth=0): ) attrs = decrypt_attr(base64_url_decode(node["a"]), k) file_name = attrs["n"] - to_return += ( - " " * depth - + "|- " - + f"{file_name} ({humanbytes(file_size)})\n" - ) + to_return += f"{' ' * depth}├─ {file_name} ({human_bytes(file_size)})\n" elif node["t"] == 1: # folder k = key attrs = decrypt_attr(base64_url_decode(node["a"]), k) file_name = attrs["n"] - to_return += " " * depth + "|- " + f"{file_name}\n" + to_return += f"{' ' * depth}├─ {file_name}\n" await prepare_string( await get_sub_dir_nodes(root_folder, file_id), shared_key, diff --git a/megadl/modules/admin.py b/megadl/modules/admin.py index 2aa7c80f..90737d2c 100644 --- a/megadl/modules/admin.py +++ b/megadl/modules/admin.py @@ -34,7 +34,7 @@ async def admin_user_info(client: CypherClient, msg: Message): up_count = _user["total_uploads"] ban_status = ( - f"`Banned`\n ↳ `{ban_rsn}`" + f"`Banned`\n ⤷ `{ban_rsn}`" if is_ban else "Admin" if buid in client.auth_users @@ -43,10 +43,10 @@ async def admin_user_info(client: CypherClient, msg: Message): await msg.reply( f""" **User Info** - ↳ **ID:** `{buid}` - ↳ **Status:** {ban_status} - ↳ **Total downloads:** `{dl_count}` - ↳ **Total uploads:** `{up_count}` + ⤷ **ID:** `{buid}` + ⤷ **Status:** {ban_status} + ⤷ **Total downloads:** `{dl_count}` + ⤷ **Total uploads:** `{up_count}` **Detect abuse?** @@ -74,7 +74,7 @@ async def admin_ban_user(client: CypherClient, msg: Message): return await msg.reply("Why do you want to ban an admin 😶‍🌫️?") await client.database.ban_user(buid, reason) - await msg.reply(f"Banned user `{buid}`") + await msg.reply(f"Banned user `{buid}` ✅") @CypherClient.on_message(filters.command("unban")) @@ -91,4 +91,4 @@ async def admin_unban_user(client: CypherClient, msg: Message): return await msg.reply("Provide a user id to unban \n\nEx: `/unban 12345`") await client.database.unban_user(buid) - await msg.reply(f"Unbanned user `{buid}`") + await msg.reply(f"Unbanned user `{buid}` ✅") diff --git a/megadl/modules/generals.py b/megadl/modules/generals.py index f8100ada..a9e66a8f 100644 --- a/megadl/modules/generals.py +++ b/megadl/modules/generals.py @@ -32,15 +32,15 @@ async def start_msg(_: CypherClient, msg: Message): async def help_msg(_: CypherClient, msg: Message): await msg.reply_text( f""" -**How do I login?** - Send /login command and enter your details when I ask you. Don't worry we encrypt your data before sending it anywhere 🤗 +**✘ How do I login?** + ⤷ Send /login command and enter your details when I ask you. Don't worry we encrypt your data before sending it anywhere 🤗 -**How to download from mega link?** - It's very easy. Just send the link you want to download and I'll download it for you 😉. +**✘ How to download from mega link?** + ⤷ It's very easy. Just send the link you want to download and I'll download it for you 😉. For private content you need to login first then send path to the file or folder you want to download starting with `/Root/`. -**How to upload files to Mega.nz?** - Just send me the files and I'll ask you whether you want to upload it or not. Same goes for direct download links 😎 +**✘ How to upload files to Mega.nz?** + ⤷ Just send me the files and I'll ask you whether you want to upload it or not. Same goes for direct download links 😎 **Made with ❤️ by @NexaBotsUpdates** diff --git a/megadl/modules/mega_up.py b/megadl/modules/mega_up.py index d7b7bc47..d61cee90 100644 --- a/megadl/modules/mega_up.py +++ b/megadl/modules/mega_up.py @@ -33,7 +33,7 @@ async def up_to(_: CypherClient, msg: Message): _mid = msg.id await msg.reply( - "Select what you want to do 🤗", + "**Select what you want to do 🤗**", reply_markup=InlineKeyboardMarkup( [ [InlineKeyboardButton("Upload 🗃", callback_data=f"up_tgdl-{_mid}")], diff --git a/requirements.txt b/requirements.txt index ccb9eef5..a9d5b9d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,5 @@ pymongo dnspython cryptography pycryptodome -psutil \ No newline at end of file +psutil +humans-formatter \ No newline at end of file