diff --git a/README.md b/README.md index bb189da1e3a2..53a406581915 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ programming in Python. ## qBittorrent - External access to webui, so you can remove files or edit settings. Then you can sync settings in database with sync button in bsetting - - Select files from a Torrent before and during download using mltb file selector (Requires Base URL) (task option) + - Select files from a Torrent before and during download using ZEE file selector (Requires Base URL) (task option) - Seed torrents to a specific ratio and time (task option) - Edit Global Options while the bot is running from bot settings (global option) @@ -37,7 +37,7 @@ programming in Python. ## Sabnzbd - External access to web interface, so you can remove files or edit settings. Then you can sync settings in database with sync button in bsetting - - Remove files from job before and during download using mltb file selector (Requires Base URL) (task option) + - Remove files from job before and during download using ZEE file selector (Requires Base URL) (task option) - Edit Global Options while the bot is running from bot settings (global option) - Servers menu to edit/add/remove usenet servers @@ -70,6 +70,7 @@ programming in Python. - Download restricted messages (document or link) by tg private/public/super links (task option) - Choose transfer by bot or user session in case you have a premium plan (global, user option and task option) - Mix upload between user and bot session with respect to file size (global, user option and task option) + - Upload with custom layout multiple thubnmail (global, user option and task option) ## Google Drive @@ -144,6 +145,7 @@ programming in Python. - Extract splits with or without password - Zip file/folder with or without password + - Decompress zst files - Using 7-zip tool to extract with or without password all supported types: > ZIP, RAR, TAR, 7z, ISO, WIM, CAB, GZIP, BZIP2, APM, ARJ, CHM, CPIO, CramFS, DEB, DMG, FAT, HFS, LZH, LZMA, LZMA2,MBR, @@ -175,6 +177,7 @@ programming in Python. - Bulk download from telegram txt file or text message contains links seperated by new line (task option) - Join splitted files that have splitted before by split(linux pkg) (task option) - Sample video Generator (task option) + - Screenshots Generator (task option) - Ability to cancel upload/clone/archive/extract/split/queue (task option) - Cancel all buttons for choosing specific tasks status to cancel (global option) - Convert videos and audios to specific format with filter (task option) @@ -371,20 +374,20 @@ programming in Python. - `USER_TRANSMISSION`: Upload/Download by user session. Only in superChat. Default is `False`. `Bool` - `MIXED_LEECH`: Upload by user and bot session with respect to file size. Only in superChat. Default is `False`. `Bool` - `USER_LEECH_DESTINATION`: ID or USERNAME or PM(private message) to where files would be uploaded. `Int`|`Str`. Add `-100` before channel/superGroup id. - - `NAME_SUBSTITUTE`: Add word/letter/sentense/pattern to remove or replace with other words with sensitive case or without.**Notes**: + - `NAME_SUBSTITUTE`: Add word/letter/character/sentense/pattern to remove or replace with other words with sensitive case or without. **Notes**: 1. Seed will get disbaled while using this option - 2. Before any character you must add \, those are the characters: `\^$.|?*+()[]{}-` - * Example-1: `text : code : s | mirror : leech | tea : : s | clone` - - text will get replaced by code with sensitive case - - mirror will get replaced by leech - - tea will get removed with sensitive case - - clone will get removed - * Example-2: `\(text\) | \[test\] : test | \\text\\ : text : s` - - `(text)` will get removed - - `[test]` will get replaced by test - - `\text\` will get replaced by text with sensitive case + 2. Before any character you must add `\BACKSLASH`, those are the characters: `\^$.|?*+()[]{}-` + * Example: script/code/s | mirror/leech | tea/ /s | clone | cpu/ | \[ZEE\]/ZEE | \\text\\/text/s + - script will get replaced by code with sensitive case + - mirror will get replaced by leech + - tea will get replaced by space with sensitive case + - clone will get removed + - cpu will get replaced by space + - [ZEE] will get replaced by ZEE + - \text\ will get replaced by text with sensitive case - `METADATA_TXT`: Edit metadata of the video. `Str` - `META_ATTACHMENT`: Add attachment to the metadata. `Str` + - `THUMBNAIL_LAYOUT`: Thumbnail layout (widthxheight, 2x2, 3x3, 2x4, 4x4, ...) of how many photo arranged for the thumbnail.`Str` **12. Super Group Features** diff --git a/bot/__init__.py b/bot/__init__.py index ebb66518fb54..5007dab19e99 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -1,29 +1,31 @@ -from collections import OrderedDict from apscheduler.schedulers.asyncio import AsyncIOScheduler +from asyncio import ( + Lock, + get_running_loop, + new_event_loop, + set_event_loop +) from aria2p import ( API as ariaAPI, Client as ariaClient ) -from asyncio import ( - Lock, - get_event_loop -) -from concurrent.futures import ThreadPoolExecutor +from collections import OrderedDict from dotenv import ( load_dotenv, dotenv_values ) from logging import ( + INFO, + ERROR, getLogger, FileHandler, StreamHandler, - INFO, basicConfig, error as log_error, info as log_info, warning as log_warning, - ERROR, ) +from nekozee import Client as TgClient from os import ( remove, path as ospath, @@ -31,11 +33,9 @@ ) from pymongo.mongo_client import MongoClient from pymongo.server_api import ServerApi -from nekozee import ( - Client as tgClient -) -from qbittorrentapi import Client as qbClient -from sabnzbdapi import sabnzbdClient +from qbittorrentapi import Client as QbClient +from sabnzbdapi import SabnzbdClient +from shutil import rmtree from socket import setdefaulttimeout from subprocess import ( Popen, @@ -60,10 +60,11 @@ getLogger("pymongo").setLevel(ERROR) getLogger("nekozee").setLevel(ERROR) -botStartTime = time() -bot_loop = get_event_loop() -THREADPOOL = ThreadPoolExecutor(max_workers=99999) -bot_loop.set_default_executor(THREADPOOL) +bot_start_time = time() + +bot_loop = new_event_loop() +set_event_loop(bot_loop) + basicConfig( format="%(levelname)s | From %(name)s -> %(module)s line no: %(lineno)d | %(message)s", @@ -81,20 +82,20 @@ override=True ) -Intervals = { +intervals = { "status": {}, "qb": "", "jd": "", "nzb": "", "stopAll": False } -QbTorrents = {} +qb_torrents = {} jd_downloads = {} nzb_jobs = {} -DRIVES_NAMES = [] -DRIVES_IDS = [] -INDEX_URLS = [] -GLOBAL_EXTENSION_FILTER = [ +drives_names = [] +drives_ids = [] +index_urls = [] +global_extension_filter = [ "aria2", "!qB" ] @@ -124,6 +125,7 @@ jd_lock = Lock() cpu_eater_lock = Lock() subprocess_lock = Lock() +same_directory_lock = Lock() status_dict = {} task_dict = {} rss_dict = {} @@ -140,7 +142,7 @@ log_error("BOT_TOKEN variable is missing! Exiting now") exit(1) -bot_id = BOT_TOKEN.split( +BOT_ID = BOT_TOKEN.split( ":", 1 )[0] @@ -160,10 +162,10 @@ ) db = conn.zee current_config = dict(dotenv_values("config.env")) - old_config = db.settings.deployConfig.find_one({"_id": bot_id}) + old_config = db.settings.deployConfig.find_one({"_id": BOT_ID}) if old_config is None: db.settings.deployConfig.replace_one( - {"_id": bot_id}, + {"_id": BOT_ID}, current_config, upsert=True ) @@ -174,15 +176,15 @@ and old_config != current_config ): db.settings.deployConfig.replace_one( - {"_id": bot_id}, + {"_id": BOT_ID}, current_config, upsert=True ) - elif config_dict := db.settings.config.find_one({"_id": bot_id}): + elif config_dict := db.settings.config.find_one({"_id": BOT_ID}): del config_dict["_id"] for key, value in config_dict.items(): environ[key] = str(value) - if pf_dict := db.settings.files.find_one({"_id": bot_id}): + if pf_dict := db.settings.files.find_one({"_id": BOT_ID}): del pf_dict["_id"] for key, value in pf_dict.items(): if value: @@ -195,27 +197,13 @@ "wb+" ) as f: f.write(value) - if file_ == "cfg.zip": - run([ - "rm", - "-rf", - "/JDownloader/cfg" - ]) - run([ - "7z", - "x", - "-bso0", - "cfg.zip", - "-o/JDownloader" - ]) - remove("cfg.zip") - if a2c_options := db.settings.aria2c.find_one({"_id": bot_id}): + if a2c_options := db.settings.aria2c.find_one({"_id": BOT_ID}): del a2c_options["_id"] aria2_options = a2c_options - if qbit_opt := db.settings.qbittorrent.find_one({"_id": bot_id}): + if qbit_opt := db.settings.qbittorrent.find_one({"_id": BOT_ID}): del qbit_opt["_id"] qbit_options = qbit_opt - if nzb_opt := db.settings.nzb.find_one({"_id": bot_id}): + if nzb_opt := db.settings.nzb.find_one({"_id": BOT_ID}): if ospath.exists("sabnzbd/SABnzbd.ini.bak"): remove("sabnzbd/SABnzbd.ini.bak") del nzb_opt["_id"] @@ -228,7 +216,7 @@ "BOT_TOKEN", "" ) - bot_id = BOT_TOKEN.split( + BOT_ID = BOT_TOKEN.split( ":", 1 )[0] @@ -241,6 +229,20 @@ else: config_dict = {} +if ospath.exists("cfg.zip"): + if ospath.exists("/JDownloader/cfg"): + rmtree( + "/JDownloader/cfg", + ignore_errors=True + ) + run([ + "7z", + "x", + "cfg.zip", + "-o/JDownloader" + ]) + remove("cfg.zip") + if not ospath.exists(".netrc"): with open( ".netrc", @@ -286,7 +288,7 @@ ) if len(USER_SESSION_STRING) != 0: try: - user = tgClient( + user = TgClient( "zeeu", TELEGRAM_API, TELEGRAM_HASH, @@ -376,7 +378,7 @@ fx = EXTENSION_FILTER.split() for x in fx: x = x.lstrip(".") - GLOBAL_EXTENSION_FILTER.append(x.strip().lower()) + global_extension_filter.append(x.strip().lower()) JD_EMAIL = environ.get( "JD_EMAIL", @@ -1065,6 +1067,9 @@ MEGA_PASSWORD = "" +THUMBNAIL_LAYOUT = environ.get("THUMBNAIL_LAYOUT", "") +THUMBNAIL_LAYOUT = "" if len(THUMBNAIL_LAYOUT) == 0 else THUMBNAIL_LAYOUT + config_dict = { "AS_DOCUMENT": AS_DOCUMENT, "AUTHORIZED_CHATS": AUTHORIZED_CHATS, @@ -1145,6 +1150,7 @@ "TELEGRAM_API": TELEGRAM_API, "TELEGRAM_HASH": TELEGRAM_HASH, "TORRENT_LIMIT": TORRENT_LIMIT, + "THUMBNAIL_LAYOUT": THUMBNAIL_LAYOUT, "TORRENT_TIMEOUT": TORRENT_TIMEOUT, "TOKEN_TIMEOUT": TOKEN_TIMEOUT, "USER_TRANSMISSION": USER_TRANSMISSION, @@ -1162,9 +1168,9 @@ config_dict = OrderedDict(sorted(config_dict.items())) if GDRIVE_ID: - DRIVES_NAMES.append("Main") - DRIVES_IDS.append(GDRIVE_ID) - INDEX_URLS.append(INDEX_URL) + drives_names.append("Main") + drives_ids.append(GDRIVE_ID) + index_urls.append(INDEX_URL) KEY = ("@Z_Mirror") @@ -1176,12 +1182,12 @@ lines = f.readlines() for line in lines: temp = line.strip().split() - DRIVES_IDS.append(temp[1]) - DRIVES_NAMES.append(temp[0].replace("_", " ")) + drives_ids.append(temp[1]) + drives_names.append(temp[0].replace("_", " ")) if len(temp) > 2: - INDEX_URLS.append(temp[2]) + index_urls.append(temp[2]) else: - INDEX_URLS.append("") + index_urls.append("") if ospath.exists("buttons.txt"): with open( @@ -1221,11 +1227,7 @@ if ospath.exists("accounts.zip"): if ospath.exists("accounts"): - run([ - "rm", - "-rf", - "accounts" - ]) + rmtree("accounts") run([ "7z", "x", @@ -1246,7 +1248,7 @@ config_dict["USE_SERVICE_ACCOUNTS"] = False -qbittorrent_client = qbClient( +qbittorrent_client = QbClient( host="localhost", port=8090, VERIFY_WEBUI_CERTIFICATE=False, @@ -1260,7 +1262,7 @@ BASE += ("G8k7bAblAEkiZDyAAjM6a") -sabnzbd_client = sabnzbdClient( +sabnzbd_client = SabnzbdClient( host="http://localhost", api_key="zee", port="8070", @@ -1283,7 +1285,7 @@ "server-stat-of", ] -bot = tgClient( +bot = TgClient( "zeeb", TELEGRAM_API, TELEGRAM_HASH, diff --git a/bot/__main__.py b/bot/__main__.py index cbdc0e5bbcc6..0ba07039ac24 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -4,32 +4,31 @@ remove ) from asyncio import ( - gather, - create_subprocess_exec + create_subprocess_exec, + gather ) -from os import execl as osexecl from nekozee.filters import command from nekozee.handlers import MessageHandler -from signal import signal, SIGINT +from os import execl as osexecl +from signal import SIGINT, signal from sys import executable from time import time from bot import ( - bot, LOGGER, - Intervals, - DATABASE_URL, - INCOMPLETE_TASK_NOTIFIER, - scheduler, + bot, + config_dict, + intervals, sabnzbd_client, - STOP_DUPLICATE_TASKS, + scheduler, ) from .helper.ext_utils.bot_utils import ( + create_help_buttons, + new_task, set_commands, - sync_to_async, - create_help_buttons + sync_to_async ) -from .helper.ext_utils.db_handler import DbManager +from .helper.ext_utils.db_handler import database from .helper.ext_utils.files_utils import ( clean_all, exit_clean_up @@ -42,9 +41,9 @@ from .helper.telegram_helper.filters import CustomFilters from .helper.telegram_helper.message_utils import ( auto_delete_message, - sendMessage, - editMessage, - sendFile + send_message, + edit_message, + send_file ) from .modules import ( anonymous, @@ -62,30 +61,29 @@ leech_del, mirror_leech, rmdb, - rss, shell, status, - torrent_search, users_settings, ytdlp, ) +@new_task async def restart(_, message): - Intervals["stopAll"] = True - restart_message = await sendMessage( + intervals["stopAll"] = True + restart_message = await send_message( message, "Restarting..." ) if scheduler.running: scheduler.shutdown(wait=False) - if qb := Intervals["qb"]: + if qb := intervals["qb"]: qb.cancel() - if jd := Intervals["jd"]: + if jd := intervals["jd"]: jd.cancel() - if nzb := Intervals["nzb"]: + if nzb := intervals["nzb"]: nzb.cancel() - if st := Intervals["status"]: + if st := intervals["status"]: for intvl in list(st.values()): intvl.cancel() await sync_to_async(clean_all) @@ -125,21 +123,23 @@ async def restart(_, message): ) +@new_task async def ping(_, message): start_time = int(round(time() * 1000)) - reply = await sendMessage( + reply = await send_message( message, "Starting Ping" ) end_time = int(round(time() * 1000)) - await editMessage( + await edit_message( reply, f"{end_time - start_time} ms" ) +@new_task async def log(_, message): - await sendFile( + await send_file( message, "Zee_Logs.txt" ) @@ -202,9 +202,9 @@ async def log(_, message): /{BotCommands.RssCommand}: RSS Menu. """ - +@new_task async def bot_help(_, message): - hmsg = await sendMessage( + hmsg = await send_message( message, help_string ) @@ -253,8 +253,8 @@ async def send_incomplete_task_message(cid, msg): except Exception as e: LOGGER.error(e) - if INCOMPLETE_TASK_NOTIFIER and DATABASE_URL: - if notifier_dict := await DbManager().get_incomplete_tasks(): + if config_dict["INCOMPLETE_TASK_NOTIFIER"] and config_dict["DATABASE_URL"]: + if notifier_dict := await database.get_incomplete_tasks(): for cid, data in notifier_dict.items(): msg = ( "Restarted Successfully!" @@ -279,8 +279,8 @@ async def send_incomplete_task_message(cid, msg): cid, msg ) - if STOP_DUPLICATE_TASKS: - await DbManager().clear_download_links() + if config_dict["STOP_DUPLICATE_TASKS"]: + await database.clear_download_links() if await aiopath.isfile(".restartmsg"): try: @@ -295,12 +295,12 @@ async def send_incomplete_task_message(cid, msg): async def main(): - if DATABASE_URL: - await DbManager().db_load() - jdownloader.initiate() # type: ignore + if config_dict["DATABASE_URL"]: + await database.db_load() await gather( + jdownloader.initiate(), sync_to_async(clean_all), - torrent_search.initiate_search_tools(), + bot_settings.initiate_search_tools(), restart_notification(), telegraph.create_account(), rclone_serve_booter(), diff --git a/bot/helper/common.py b/bot/helper/common.py index 9599e2e1893a..94a5fe039fe0 100644 --- a/bot/helper/common.py +++ b/bot/helper/common.py @@ -33,19 +33,19 @@ LOGGER, task_dict_lock, task_dict, - GLOBAL_EXTENSION_FILTER, + global_extension_filter, cpu_eater_lock, subprocess_lock, - Intervals, + intervals, ) -from bot.helper.ext_utils.bot_utils import ( +from .ext_utils.bot_utils import ( new_task, sync_to_async, - getSizeBytes + get_size_bytes ) -from bot.helper.ext_utils.bulk_links import extractBulkLinks -from bot.helper.ext_utils.exceptions import NotSupportedExtractionArchive -from bot.helper.ext_utils.files_utils import ( +from .ext_utils.bulk_links import extract_bulk_links +from .ext_utils.exceptions import NotSupportedExtractionArchive +from .ext_utils.files_utils import ( get_base_name, is_first_archive_split, is_archive, @@ -53,54 +53,54 @@ get_path_size, clean_target, ) -from bot.helper.ext_utils.links_utils import ( +from .ext_utils.links_utils import ( is_gdrive_id, is_rclone_path, is_gdrive_link, is_telegram_link, ) -from bot.helper.ext_utils.media_utils import ( +from .ext_utils.media_utils import ( add_attachment, - createThumb, - createSampleVideo, + create_thumb, + create_sample_video, edit_video_metadata, take_ss, ) -from bot.helper.ext_utils.media_utils import ( +from .ext_utils.media_utils import ( split_file, get_document_type, convert_video, convert_audio, ) -from bot.helper.task_utils.gdrive_utils.list import gdriveList -from bot.helper.task_utils.rclone_utils.list import RcloneList -from bot.helper.task_utils.status_utils.extract_status import ExtractStatus -from bot.helper.task_utils.status_utils.sample_video_status import ( +from .task_utils.gdrive_utils.list import GoogleDriveList +from .task_utils.rclone_utils.list import RcloneList +from .task_utils.status_utils.extract_status import ExtractStatus +from .task_utils.status_utils.sample_video_status import ( SampleVideoStatus, ) -from bot.helper.task_utils.status_utils.media_convert_status import ( +from .task_utils.status_utils.media_convert_status import ( MediaConvertStatus, ) -from bot.helper.task_utils.status_utils.meta_status import MetaStatus -from bot.helper.task_utils.status_utils.split_status import SplitStatus -from bot.helper.task_utils.status_utils.zip_status import ZipStatus -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.message_utils import ( +from .task_utils.status_utils.meta_status import MetaStatus +from .task_utils.status_utils.split_status import SplitStatus +from .task_utils.status_utils.zip_status import ZipStatus +from .telegram_helper.bot_commands import BotCommands +from .telegram_helper.message_utils import ( anno_checker, auto_delete_message, delete_links, - deleteMessage, - editMessage, - isAdmin, - isBot_canDm, + delete_message, + edit_message, + is_admin, + is_bot_can_dm, request_limiter, send_to_chat, - sendMessage, - sendLogMessage, - sendStatusMessage, + send_message, + send_log_message, + send_status_message, get_tg_link_message, ) -from bot.helper.z_utils import ( +from .z_utils import ( none_admin_utils, stop_duplicate_tasks ) @@ -110,35 +110,36 @@ class TaskConfig: def __init__(self): self.mid = self.message.id # type: ignore self.user = None - self.userId = None - self.userDict = {} + self.user_id = None + self.user_dict = {} self.dir = f"{DOWNLOAD_DIR}{self.mid}" self.link = "" - self.upDest = "" - self.rcFlags = "" + self.up_dest = "" + self.rc_flags = "" self.tag = "" self.name = "" - self.newDir = "" - self.nameSub = "" + self.new_dir = "" + self.name_sub = "" self.mode = "" self.time = "" - self.chatId = "" - self.metaData = None - self.metaAttachment = None - self.getChat = None - self.splitSize = 0 - self.maxSplitSize = 0 + self.chat_id = "" + self.thumbnail_layout = "" + self.metadata = None + self.m_attachment = None + self.get_chat = None + self.split_size = 0 + self.max_split_size = 0 self.multi = 0 self.size = 0 - self.isLeech = False - self.isQbit = False - self.isNzb = False - self.isJd = False - self.isClone = False - self.isYtDlp = False - self.equalSplits = False - self.userTransmission = False - self.mixedLeech = False + self.is_leech = False + self.is_qbit = False + self.is_nzb = False + self.is_jd = False + self.is_clone = False + self.is_ytdlp = False + self.equal_splits = False + self.user_transmission = False + self.mixed_leech = False self.extract = False self.compress = False self.select = False @@ -146,69 +147,70 @@ def __init__(self): self.compress = False self.extract = False self.join = False - self.privateLink = False - self.stopDuplicate = False - self.sampleVideo = False - self.convertAudio = False - self.convertVideo = False - self.screenShots = False - self.asDoc = False - self.isCancelled = False - self.forceRun = False - self.forceDownload = False - self.forceUpload = False - self.isTorrent = False + self.private_link = False + self.stop_duplicate = False + self.sample_video = False + self.convert_audio = False + self.convert_video = False + self.screen_shots = False + self.is_cancelled = False + self.force_run = False + self.force_download = False + self.force_upload = False + self.is_torrent = False self.is_playlist = False + self.as_med = False + self.as_doc = False self.suproc = None self.thumb = None - self.dmMessage = None - self.logMessage = None + self.dm_message = None + self.log_message = None self.raw_url = None - self.extensionFilter = [] - self.isSuperChat = self.message.chat.type.name in [ # type: ignore + self.extension_filter = [] + self.is_super_chat = self.message.chat.type.name in [ # type: ignore "SUPERGROUP", "CHANNEL" ] - async def getId(self): + async def get_id(self): self.user = self.message.from_user # type: ignore if not self.message.from_user: # type: ignore self.user = self.message.from_user = await anno_checker( # type: ignore self.message, # type: ignore self.pmsg # type: ignore ) - self.userId = self.user.id - self.userDict = user_data.get( - self.userId, + self.user_id = self.user.id + self.user_dict = user_data.get( + self.user_id, {} ) - self.chatId = self.message.chat.id # type: ignore - self.getChat = await self.client.get_chat(self.chatId) # type: ignore + self.chat_id = self.message.chat.id # type: ignore + self.get_chat = await self.client.get_chat(self.chat_id) # type: ignore - async def setMode(self): + async def set_mode(self): mode = ( "Telegram" - if self.isLeech + if self.is_leech else "RcDrive" if ( - self.upDest == "rc" or - self.upDest == "rcl" or - self.upDest == "rcu" or - is_rclone_path(str(self.upDest)) == True + self.up_dest == "rc" or + self.up_dest == "rcl" or + self.up_dest == "rcu" or + is_rclone_path(str(self.up_dest)) == True ) else "GDrive" if ( - self.isClone or - self.upDest == "gd" or - self.upDest == "gdl" or - self.upDest == "gdu" or - is_gdrive_id(str(self.upDest)) == True + self.is_clone or + self.up_dest == "gd" or + self.up_dest == "gdl" or + self.up_dest == "gdu" or + is_gdrive_id(str(self.up_dest)) == True ) else - f"{self.upDest}" + f"{self.up_dest}" ) if self.compress: @@ -218,9 +220,9 @@ async def setMode(self): self.mode = mode - def getTokenPath(self, dest): + def get_token_path(self, dest): if dest.startswith("mtp:"): - return f"tokens/{self.userId}.pickle" + return f"tokens/{self.user_id}.pickle" elif ( dest.startswith("sa:") or config_dict["USE_SERVICE_ACCOUNTS"] @@ -230,21 +232,21 @@ def getTokenPath(self, dest): else: return "token.pickle" - def getConfigPath(self, dest): + def get_config_path(self, dest): return ( - f"rclone/{self.userId}.conf" + f"rclone/{self.user_id}.conf" if dest.startswith("mrcc:") else "rclone.conf" ) - async def isTokenExists(self, path, status): + async def is_token_exists(self, path, status): if is_rclone_path(path): - config_path = self.getConfigPath(path) + config_path = self.get_config_path(path) if ( config_path != "rclone.conf" and status == "up" ): - self.privateLink = True + self.private_link = True if not await aiopath.exists(config_path): raise ValueError(f"Rclone Config: {config_path} not Exists!") @@ -254,22 +256,22 @@ async def isTokenExists(self, path, status): or status == "up" and is_gdrive_id(path) ): - token_path = self.getTokenPath(path) + token_path = self.get_token_path(path) if ( token_path.startswith("tokens/") and status == "up" ): - self.privateLink = True + self.private_link = True if not await aiopath.exists(token_path): raise ValueError(f"NO TOKEN! {token_path} not Exists!") - async def permissionCheck(self): + async def permission_check(self): error_msg = [] error_button = None - if not await isAdmin(self.message): # type: ignore + if not await is_admin(self.message): # type: ignore if await request_limiter(self.message): # type: ignore await delete_links(self.message) # type: ignore return @@ -281,7 +283,7 @@ async def permissionCheck(self): ) if self.raw_url == "duplicate_tasks": - await deleteMessage(self.pmsg) # type: ignore + await delete_message(self.pmsg) # type: ignore await delete_links(self.message) # type: ignore return @@ -290,7 +292,7 @@ async def permissionCheck(self): error_button ) = await none_admin_utils( self.message, # type: ignore - self.isLeech + self.is_leech ) if none_admin_msg: @@ -301,29 +303,29 @@ async def permissionCheck(self): and self.message.chat.type == self.message.chat.type.SUPERGROUP # type: ignore ): if ( - self.isLeech + self.is_leech and IS_PREMIUM_USER and not config_dict["DUMP_CHAT_ID"] ): error_msg.append("DM_MODE and User Session need DUMP_CHAT_ID") ( - self.dmMessage, + self.dm_message, error_button - ) = await isBot_canDm( + ) = await is_bot_can_dm( self.message, # type: ignore dmMode, error_button ) if ( - self.dmMessage is not None - and self.dmMessage != "BotStarted" + self.dm_message is not None + and self.dm_message != "BotStarted" ): - error_msg.append(self.dmMessage) + error_msg.append(self.dm_message) else: - self.dmMessage = None + self.dm_message = None if error_msg: final_msg = f"Hey, {self.tag},\n" @@ -344,13 +346,13 @@ async def permissionCheck(self): await delete_links(self.message) # type: ignore try: - mmsg = await editMessage( + mmsg = await edit_message( self.pmsg, # type: ignore final_msg, error_button ) except: - mmsg = await sendMessage( + mmsg = await send_message( self.message, # type: ignore final_msg, error_button @@ -363,240 +365,240 @@ async def permissionCheck(self): return return True - async def beforeStart(self): + async def before_start(self): if ( config_dict["DISABLE_SEED"] and self.seed - and not await isAdmin(self.message) # type: ignore + and not await is_admin(self.message) # type: ignore ): raise ValueError("Seed is Disabled!") - self.nameSub = ( - self.nameSub - or self.userDict.get( + self.name_sub = ( + self.name_sub + or self.user_dict.get( "name_sub", False ) or ( config_dict["NAME_SUBSTITUTE"] - if "name_sub" not in self.userDict + if "name_sub" not in self.user_dict else "" ) ) - if self.nameSub: - self.nameSub = [ - x.split(" : ") + if self.name_sub: + self.name_sub = [ + x.split("/") for x - in self.nameSub.split(" | ") # type: ignore + in self.name_sub.split(" | ") # type: ignore ] self.seed = False - self.extensionFilter = self.userDict.get("excluded_extensions") or ( - GLOBAL_EXTENSION_FILTER - if "excluded_extensions" not in self.userDict + self.extension_filter = self.user_dict.get("excluded_extensions") or ( + global_extension_filter + if "excluded_extensions" not in self.user_dict else [ "aria2", "!qB" ] ) - self.metaData = self.metaData or self.userDict.get("metatxt") or ( + self.metadata = self.metadata or self.user_dict.get("metatxt") or ( config_dict["METADATA_TXT"] - if "metatxt" not in self.userDict + if "metatxt" not in self.user_dict else False ) - self.metaAttachment = self.metaAttachment or self.userDict.get("attachmenturl") or ( + self.m_attachment = self.m_attachment or self.user_dict.get("attachmenturl") or ( config_dict["META_ATTACHMENT"] - if "attachmenturl" not in self.userDict + if "attachmenturl" not in self.user_dict else False ) if self.link not in [ "rcl", "gdl" ]: - if ( - is_rclone_path(self.link) or - is_gdrive_link(self.link) + if (not self.is_jd + and is_rclone_path(self.link) + or is_gdrive_link(self.link) ): - await self.isTokenExists( + await self.is_token_exists( self.link, "dl" ) elif self.link == "rcl": if ( - not self.isYtDlp - and not self.isJd + not self.is_ytdlp + and not self.is_jd ): self.link = await RcloneList(self).get_rclone_path("rcd") if not is_rclone_path(self.link): raise ValueError(self.link) elif self.link == "gdl": if ( - not self.isYtDlp - and not self.isJd + not self.is_ytdlp + and not self.is_jd ): - self.link = await gdriveList(self).get_target_id("gdd") + self.link = await GoogleDriveList(self).get_target_id("gdd") if not is_gdrive_id(self.link): raise ValueError(self.link) - self.userTransmission = IS_PREMIUM_USER and ( - self.userDict.get("user_transmission") + self.user_transmission = IS_PREMIUM_USER and ( + self.user_dict.get("user_transmission") or config_dict["USER_TRANSMISSION"] - and "user_transmission" not in self.userDict + and "user_transmission" not in self.user_dict ) if ( - "upload_paths" in self.userDict - and self.upDest - and self.upDest - in self.userDict["upload_paths"] + "upload_paths" in self.user_dict + and self.up_dest + and self.up_dest + in self.user_dict["upload_paths"] ): - self.upDest = self.userDict["upload_paths"][self.upDest] + self.up_dest = self.user_dict["upload_paths"][self.up_dest] - if not self.isLeech: - self.stopDuplicate = ( - self.userDict.get("stop_duplicate") + if not self.is_leech: + self.stop_duplicate = ( + self.user_dict.get("stop_duplicate") or "stop_duplicate" - not in self.userDict + not in self.user_dict and config_dict["STOP_DUPLICATE"] ) default_upload = ( - self.userDict.get( + self.user_dict.get( "default_upload", "" ) or config_dict["DEFAULT_UPLOAD"] ) if ( - not self.upDest + not self.up_dest and default_upload == "rc" - ) or self.upDest == "rc": - self.upDest = ( - self.userDict.get("rclone_path") + ) or self.up_dest == "rc": + self.up_dest = ( + self.user_dict.get("rclone_path") or config_dict["RCLONE_PATH"] ) elif ( - not self.upDest + not self.up_dest and default_upload == "gd" - ) or self.upDest == "gd": - self.upDest = ( - self.userDict.get("gdrive_id") + ) or self.up_dest == "gd": + self.up_dest = ( + self.user_dict.get("gdrive_id") or config_dict["GDRIVE_ID"] ) - if not self.upDest: + if not self.up_dest: raise ValueError("No Upload Destination!") if ( - not is_gdrive_id(str(self.upDest)) - and not is_rclone_path(str(self.upDest)) + not is_gdrive_id(str(self.up_dest)) + and not is_rclone_path(str(self.up_dest)) ): raise ValueError("Wrong Upload Destination!") if ( - self.upDest + self.up_dest not in [ "rcl", "gdl" ] ): - await self.isTokenExists( - self.upDest, + await self.is_token_exists( + self.up_dest, "up" ) - if self.upDest == "rcl": - if self.isClone: + if self.up_dest == "rcl": + if self.is_clone: if not is_rclone_path(self.link): raise ValueError( "You can't clone from different types of tools" ) - config_path = self.getConfigPath(self.link) + config_path = self.get_config_path(self.link) else: config_path = None - self.upDest = await RcloneList(self).get_rclone_path( + self.up_dest = await RcloneList(self).get_rclone_path( "rcu", config_path ) - if not is_rclone_path(self.upDest): - raise ValueError(self.upDest) - elif self.upDest == "gdl": - if self.isClone: + if not is_rclone_path(self.up_dest): + raise ValueError(self.up_dest) + elif self.up_dest == "gdl": + if self.is_clone: if not is_gdrive_link(self.link): raise ValueError( "You can't clone from different types of tools" ) - token_path = self.getTokenPath(self.link) + token_path = self.get_token_path(self.link) else: token_path = None - self.upDest = await gdriveList(self).get_target_id( + self.up_dest = await GoogleDriveList(self).get_target_id( "gdu", token_path ) - if not is_gdrive_id(self.upDest): - raise ValueError(self.upDest) - elif self.isClone: + if not is_gdrive_id(self.up_dest): + raise ValueError(self.up_dest) + elif self.is_clone: if ( is_gdrive_link(self.link) - and self.getTokenPath(self.link) - != self.getTokenPath(self.upDest) + and self.get_token_path(self.link) + != self.get_token_path(self.up_dest) ): raise ValueError("You must use the same token to clone!") elif ( is_rclone_path(self.link) - and self.getConfigPath(self.link) - != self.getConfigPath(self.upDest) + and self.get_config_path(self.link) + != self.get_config_path(self.up_dest) ): raise ValueError("You must use the same config to clone!") else: if self.message.chat.type != self.message.chat.type.SUPERGROUP: # type: ignore raise ValueError("Leech is not allowed in private!\nUse me in a supergroup!") - self.upDest = ( - self.upDest - or self.userDict.get("leech_dest") + self.up_dest = ( + self.up_dest + or self.user_dict.get("leech_dest") or config_dict["USER_LEECH_DESTINATION"] ) - self.mixedLeech = IS_PREMIUM_USER and ( - self.userDict.get("mixed_leech") + self.mixed_leech = IS_PREMIUM_USER and ( + self.user_dict.get("mixed_leech") or config_dict["MIXED_LEECH"] and "mixed_leech" - not in self.userDict + not in self.user_dict ) - if self.upDest: + if self.up_dest: if not isinstance( - self.upDest, + self.up_dest, int ): - if self.upDest.startswith("b:"): - self.upDest = self.upDest.replace( + if self.up_dest.startswith("b:"): + self.up_dest = self.up_dest.replace( "b:", "", 1 ) - self.userTransmission = False - self.mixedLeech = False - elif self.upDest.startswith("u:"): - self.upDest = self.upDest.replace( + self.user_transmission = False + self.mixed_leech = False + elif self.up_dest.startswith("u:"): + self.up_dest = self.up_dest.replace( "u:", "", 1 ) - self.userTransmission = IS_PREMIUM_USER - self.mixedLeech = False - elif self.upDest.startswith("m:"): - self.userTransmission = IS_PREMIUM_USER - self.mixedLeech = self.userTransmission + self.user_transmission = IS_PREMIUM_USER + self.mixed_leech = False + elif self.up_dest.startswith("m:"): + self.user_transmission = IS_PREMIUM_USER + self.mixed_leech = self.user_transmission if ( - self.upDest.isdigit() - or self.upDest.startswith("-") + self.up_dest.isdigit() + or self.up_dest.startswith("-") ): - self.upDest = int(self.upDest) - elif self.upDest.lower() in [ + self.up_dest = int(self.up_dest) + elif self.up_dest.lower() in [ "pm", "dm" ]: - self.upDest = self.userId + self.up_dest = self.user_id udc = user.session.dc_id if user else 0 bdc = bot.session.dc_id # type: ignore - if udc != bdc and self.mixedLeech: - self.mixedLeech = False + if udc != bdc and self.mixed_leech: + self.mixed_leech = False - chat = await self.client.get_chat(self.upDest) # type: ignore + chat = await self.client.get_chat(self.up_dest) # type: ignore uploader_id = self.client.me.id # type: ignore if chat.type.name in [ @@ -615,7 +617,7 @@ async def beforeStart(self): else: try: await self.client.send_chat_action( # type: ignore - self.upDest, + self.up_dest, ChatAction.TYPING ) except: @@ -653,80 +655,95 @@ async def beforeStart(self): "Allow me 'post messages' permissions!" ) - if self.splitSize: - if self.splitSize.isdigit(): # type: ignore - self.splitSize = int(self.splitSize) + if self.split_size: + if self.split_size.isdigit(): # type: ignore + self.split_size = int(self.split_size) else: - self.splitSize = getSizeBytes(self.splitSize) - self.splitSize = ( - self.splitSize - or self.userDict.get("split_size") + self.split_size = get_size_bytes(self.split_size) + self.split_size = ( + self.split_size + or self.user_dict.get("split_size") or config_dict["LEECH_SPLIT_SIZE"] ) - self.equalSplits = ( - self.userDict.get("equal_splits") + self.equal_splits = ( + self.user_dict.get("equal_splits") or config_dict["EQUAL_SPLITS"] - and "equal_splits" not in self.userDict + and "equal_splits" not in self.user_dict ) - self.maxSplitSize = ( + self.max_split_size = ( MAX_SPLIT_SIZE - if self.userTransmission + if self.user_transmission else 2097152000 ) - self.splitSize = min( - self.splitSize, - self.maxSplitSize + self.split_size = min( + self.split_size, + self.max_split_size ) - self.asDoc = ( - self.userDict.get( - "as_doc", + if not self.as_doc: + self.as_doc = ( + not self.as_med + if self.as_med + else ( + self.user_dict.get("as_doc", False) + or config_dict["AS_DOCUMENT"] + and "as_doc" not in self.user_dict + ) + ) + + self.thumbnail_layout = ( + self.thumbnail_layout + or self.user_dict.get( + "thumb_layout", False ) - or config_dict["AS_DOCUMENT"] - and "as_doc" not in self.userDict + or ( + config_dict["THUMBNAIL_LAYOUT"] + if "thumb_layout" not in self.user_dict + else "" + ) ) if is_telegram_link(str(self.thumb)): thumb = await get_tg_link_message(self.thumb) msg = (f"{thumb}")[0] self.thumb = ( - await createThumb(msg) + await create_thumb(msg) if msg.photo # type: ignore or msg.document # type: ignore else "" ) - await self.setMode() - self.logMessage = await sendLogMessage( + await self.set_mode() + self.log_message = await send_log_message( self.message, # type: ignore self.link, self.tag ) await delete_links(self.message) # type: ignore - if self.dmMessage == "BotStarted": - chatId = self.message.from_user.id # type: ignore + if self.dm_message == "BotStarted": + chat_id = self.message.from_user.id # type: ignore if ( - self.isLeech and - self.upDest + self.is_leech and + self.up_dest ): - chatId = self.upDest + chat_id = self.up_dest if reply_to := self.message.reply_to_message: # type: ignore if not reply_to.text: - self.dmMessage = await reply_to.copy(chatId) + self.dm_message = await reply_to.copy(chat_id) else: - self.dmMessage = await send_to_chat( + self.dm_message = await send_to_chat( self.message._client, # type: ignore - chatId, + chat_id, self.message.reply_to_message.text # type: ignore ) else: - self.dmMessage = await send_to_chat( + self.dm_message = await send_to_chat( self.message._client, # type: ignore - chatId, + chat_id, self.message.text # type: ignore ) - async def getTag(self, text: list): + async def get_tag(self, text: list): if len(text) > 1 and text[1].startswith("Tag: "): user_info = text[1].split("Tag: ") if len(user_info) >= 3: @@ -738,9 +755,9 @@ async def getTag(self, text: list): id_ ) = text[1].split("Tag: ")[1].split() self.user = self.message.from_user = await self.client.get_users(id_) # type: ignore - self.userId = self.user.id - self.userDict = user_data.get( - self.userId, + self.user_id = self.user.id + self.user_dict = user_data.get( + self.user_id, {} ) try: @@ -763,9 +780,9 @@ async def run_multi(self, input_list, folder_name, obj): if ( config_dict["DISABLE_MULTI"] and self.multi > 1 - and not await isAdmin(self.message) # type: ignore + and not await is_admin(self.message) # type: ignore ): - smsg = await sendMessage( + smsg = await send_message( self.message, # type: ignore f"Multi Task is Disabled!\n\ncc: {self.tag}" ) @@ -776,25 +793,25 @@ async def run_multi(self, input_list, folder_name, obj): return await sleep(7) if ( - not self.multiTag + not self.multi_tag and self.multi > 1 ): - self.multiTag = token_urlsafe(3) - multi_tags.add(self.multiTag) + self.multi_tag = token_urlsafe(3) + multi_tags.add(self.multi_tag) elif self.multi <= 1: - if self.multiTag in multi_tags: - multi_tags.discard(self.multiTag) + if self.multi_tag in multi_tags: + multi_tags.discard(self.multi_tag) return if ( - self.multiTag - and self.multiTag + self.multi_tag + and self.multi_tag not in multi_tags ): - smsg = await sendMessage( + smsg = await send_message( self.message, # type: ignore f"{self.tag} Multi Task has been cancelled!" ) - await sendStatusMessage(self.message) # type: ignore + await send_status_message(self.message) # type: ignore await auto_delete_message( self.message, # type: ignore smsg @@ -805,8 +822,8 @@ async def run_multi(self, input_list, folder_name, obj): msg.append(f"{self.bulk[0]} -m {self.multi - 1} {self.options}") msgts = " ".join(msg) if self.multi > 2: - msgts += f"\nCancel Multi: /{BotCommands.CancelTaskCommand[1]} {self.multiTag}" - nextmsg = await sendMessage( + msgts += f"\nCancel Multi: /{BotCommands.CancelTaskCommand[1]} {self.multi_tag}" + nextmsg = await send_message( self.message, # type: ignore msgts ) @@ -824,8 +841,8 @@ async def run_multi(self, input_list, folder_name, obj): ) msgts = " ".join(msg) if self.multi > 2: - msgts += f"\nCancel Multi: /{BotCommands.CancelTaskCommand[1]} {self.multiTag}" - nextmsg = await sendMessage( + msgts += f"\nCancel Multi: /{BotCommands.CancelTaskCommand[1]} {self.multi_tag}" + nextmsg = await send_message( nextmsg, msgts ) @@ -834,32 +851,32 @@ async def run_multi(self, input_list, folder_name, obj): message_ids=nextmsg.id # type: ignore ) if folder_name: - self.sameDir["tasks"].add(nextmsg.id) # type: ignore + self.same_dir["tasks"].add(nextmsg.id) # type: ignore if self.message.from_user: # type: ignore nextmsg.from_user = self.user else: nextmsg.sender_chat = self.user - if Intervals["stopAll"]: + if intervals["stopAll"]: return await obj( self.client, # type: ignore nextmsg, - self.isQbit, - self.isLeech, - self.isJd, - self.isNzb, - self.sameDir, # type: ignore + self.is_qbit, + self.is_leech, + self.is_jd, + self.is_nzb, + self.same_dir, # type: ignore self.bulk, - self.multiTag, + self.multi_tag, self.options, - ).newEvent() + ).new_event() - async def initBulk(self, input_list, bulk_start, bulk_end, obj): + async def init_bulk(self, input_list, bulk_start, bulk_end, obj): if ( config_dict["DISABLE_BULK"] - and not await isAdmin(self.message) # type: ignore + and not await is_admin(self.message) # type: ignore ): - smsg = await sendMessage( + smsg = await send_message( self.message, # type: ignore f"Bulk Task is Disabled!\n\ncc: {self.tag}" ) @@ -869,7 +886,7 @@ async def initBulk(self, input_list, bulk_start, bulk_end, obj): ) return try: - self.bulk = await extractBulkLinks( + self.bulk = await extract_bulk_links( self.message, # type: ignore bulk_start, bulk_end @@ -884,7 +901,7 @@ async def initBulk(self, input_list, bulk_start, bulk_end, obj): del self.options[index + 1] self.options = " ".join(self.options) b_msg.append(f"{self.bulk[0]} -m {len(self.bulk)} {self.options}") - nextmsg = await sendMessage( + nextmsg = await send_message( self.message, # type: ignore " ".join(b_msg) ) @@ -899,17 +916,17 @@ async def initBulk(self, input_list, bulk_start, bulk_end, obj): await obj( self.client, # type: ignore nextmsg, - self.isQbit, - self.isLeech, - self.isJd, - self.isNzb, - self.sameDir, # type: ignore + self.is_qbit, + self.is_leech, + self.is_jd, + self.is_nzb, + self.same_dir, # type: ignore self.bulk, - self.multiTag, + self.multi_tag, self.options, - ).newEvent() + ).new_event() except: - smsg = await sendMessage( + smsg = await send_message( self.message, # type: ignore "Reply to text file or to telegram message that have links seperated by new line!", ) @@ -918,7 +935,58 @@ async def initBulk(self, input_list, bulk_start, bulk_end, obj): smsg ) - async def proceedExtract(self, dl_path, gid): + async def decompress_zst(self, dl_path, is_dir=False): + if is_dir: + for dirpath, _, files in await sync_to_async(walk, dl_path, topdown=False): + for file_ in files: + if file_.endswith(".zst"): + f_path = ospath.join(dirpath, file_) + out_path = get_base_name(f_path) + cmd = ["unzstd", f_path, "-o", out_path] + if self.is_cancelled: + return "" + async with subprocess_lock: + self.suproc = await create_subprocess_exec( + *cmd, stderr=PIPE + ) + _, stderr = await self.suproc.communicate() + if self.is_cancelled: + return "" + code = self.suproc.returncode + if code != 0: + try: + stderr = stderr.decode().strip() + except: + stderr = "Unable to decode the error!" + LOGGER.error( + f"{stderr}. Unable to extract zst file!. Path: {f_path}" + ) + elif not self.seed: + await remove(f_path) + return + elif dl_path.endswith(".zst"): + out_path = get_base_name(dl_path) + cmd = ["unzstd", dl_path, "-o", out_path] + if self.is_cancelled: + return "" + async with subprocess_lock: + self.suproc = await create_subprocess_exec(*cmd, stderr=PIPE) + _, stderr = await self.suproc.communicate() + if self.is_cancelled: + return "" + code = self.suproc.returncode + if code != 0: + try: + stderr = stderr.decode().strip() + except: + stderr = "Unable to decode the error!" + LOGGER.error(f"{stderr}. Unable to extract zst file!. Path: {dl_path}") + elif not self.seed: + await remove(dl_path) + return out_path + return dl_path + + async def proceed_extract(self, dl_path, gid): pswd = ( self.extract if isinstance( @@ -936,10 +1004,14 @@ async def proceedExtract(self, dl_path, gid): ) if await aiopath.isdir(dl_path): if self.seed: - self.newDir = f"{self.dir}10000" - up_path = f"{self.newDir}/{self.name}" + self.new_dir = f"{self.dir}10000" + up_path = f"{self.new_dir}/{self.name}" else: up_path = dl_path + await self.decompress_zst( + dl_path, + is_dir=True + ) for ( dirpath, _, @@ -954,6 +1026,7 @@ async def proceedExtract(self, dl_path, gid): is_first_archive_split(file_) or is_archive(file_) and not file_.endswith(".rar") + and not file_.endswith(".zst") ): f_path = ospath.join( dirpath, @@ -962,7 +1035,7 @@ async def proceedExtract(self, dl_path, gid): t_path = ( dirpath.replace( self.dir, - self.newDir + self.new_dir ) if self.seed else dirpath @@ -978,7 +1051,7 @@ async def proceedExtract(self, dl_path, gid): ] if not pswd: del cmd[2] - if self.isCancelled: + if self.is_cancelled: return "" async with subprocess_lock: self.suproc = await create_subprocess_exec( @@ -989,7 +1062,7 @@ async def proceedExtract(self, dl_path, gid): _, stderr ) = await self.suproc.communicate() - if self.isCancelled: + if self.is_cancelled: return "" code = self.suproc.returncode if code != 0: @@ -1017,15 +1090,16 @@ async def proceedExtract(self, dl_path, gid): try: await remove(del_path) except: - self.isCancelled = True + self.is_cancelled = True return up_path else: + dl_path = await self.decompress_zst(dl_path) up_path = get_base_name(dl_path) if self.seed: - self.newDir = f"{self.dir}10000" + self.new_dir = f"{self.dir}10000" up_path = up_path.replace( self.dir, - self.newDir + self.new_dir ) cmd = [ "7z", @@ -1038,7 +1112,7 @@ async def proceedExtract(self, dl_path, gid): ] if not pswd: del cmd[2] - if self.isCancelled: + if self.is_cancelled: return "" async with subprocess_lock: self.suproc = await create_subprocess_exec( @@ -1049,19 +1123,19 @@ async def proceedExtract(self, dl_path, gid): _, stderr ) = await self.suproc.communicate() - if self.isCancelled: + if self.is_cancelled: return "" code = self.suproc.returncode if code == -9: - self.isCancelled = True + self.is_cancelled = True return "" elif code == 0: LOGGER.info(f"Extracted Path: {up_path}") if not self.seed: try: - await remove(dl_path) + await remove(dl_path) # type: ignore except: - self.isCancelled = True + self.is_cancelled = True return up_path else: try: @@ -1071,16 +1145,16 @@ async def proceedExtract(self, dl_path, gid): LOGGER.error( f"{stderr}. Unable to extract archive! Uploading anyway. Path: {dl_path}" ) - self.newDir = "" + self.new_dir = "" return dl_path except NotSupportedExtractionArchive: LOGGER.info( f"Not any valid archive, uploading file as it is. Path: {dl_path}" ) - self.newDir = "" + self.new_dir = "" return dl_path - async def proceedCompress(self, dl_path, gid, o_files, ft_delete): + async def proceed_compress(self, dl_path, gid, o_files, ft_delete): pswd = ( self.compress if isinstance( @@ -1091,10 +1165,10 @@ async def proceedCompress(self, dl_path, gid, o_files, ft_delete): ) if ( self.seed - and not self.newDir + and not self.new_dir ): - self.newDir = f"{self.dir}10000" - up_path = f"{self.newDir}/{self.name}.7z" + self.new_dir = f"{self.dir}10000" + up_path = f"{self.new_dir}/{self.name}.7z" delete = False else: up_path = f"{dl_path}.7z" @@ -1102,11 +1176,11 @@ async def proceedCompress(self, dl_path, gid, o_files, ft_delete): async with task_dict_lock: task_dict[self.mid] = ZipStatus(self, gid) size = await get_path_size(dl_path) - if self.equalSplits: - parts = -(-size // self.splitSize) + if self.equal_splits: + parts = -(-size // self.split_size) split_size = (size // parts) + (size % parts) else: - split_size = self.splitSize + split_size = self.split_size cmd = [ "7z", f"-v{split_size}b", @@ -1120,13 +1194,13 @@ async def proceedCompress(self, dl_path, gid, o_files, ft_delete): cmd.extend( f"-xr!*.{ext}" for ext - in self.extensionFilter + in self.extension_filter ) if o_files: for f in o_files: - if self.newDir and self.newDir in f: + if self.new_dir and self.new_dir in f: fte = f.replace( - f"{self.newDir}/", + f"{self.new_dir}/", "" ) else: @@ -1135,7 +1209,7 @@ async def proceedCompress(self, dl_path, gid, o_files, ft_delete): "" ) cmd.append(f"-xr!{fte}") - if self.isLeech and int(size) > self.splitSize: + if self.is_leech and int(size) > self.split_size: if not pswd: del cmd[4] LOGGER.info(f"Zip: orig_path: {dl_path}, zip_path: {up_path}.0*") @@ -1144,7 +1218,7 @@ async def proceedCompress(self, dl_path, gid, o_files, ft_delete): if not pswd: del cmd[3] LOGGER.info(f"Zip: orig_path: {dl_path}, zip_path: {up_path}") - if self.isCancelled: + if self.is_cancelled: return "" async with subprocess_lock: self.suproc = await create_subprocess_exec( @@ -1155,11 +1229,11 @@ async def proceedCompress(self, dl_path, gid, o_files, ft_delete): _, stderr ) = await self.suproc.communicate() - if self.isCancelled: + if self.is_cancelled: return "" code = self.suproc.returncode if code == -9: - self.isCancelled = True + self.is_cancelled = True return "" elif code == 0: if not self.seed or delete: @@ -1173,9 +1247,9 @@ async def proceedCompress(self, dl_path, gid, o_files, ft_delete): ft_delete.clear() return up_path else: - await clean_target(self.newDir) + await clean_target(self.new_dir) if not delete: - self.newDir = "" + self.new_dir = "" try: stderr = stderr.decode().strip() except: @@ -1183,7 +1257,7 @@ async def proceedCompress(self, dl_path, gid, o_files, ft_delete): LOGGER.error(f"{stderr}. Unable to zip this path: {dl_path}") return dl_path - async def proceedSplit(self, up_dir, m_size, o_files, gid): + async def proceed_split(self, up_dir, m_size, o_files, gid): checked = False for ( dirpath, @@ -1202,7 +1276,7 @@ async def proceedSplit(self, up_dir, m_size, o_files, gid): if f_path in o_files: continue f_size = await aiopath.getsize(f_path) - if f_size > self.splitSize: + if f_size > self.split_size: if not checked: checked = True async with task_dict_lock: @@ -1213,16 +1287,16 @@ async def proceedSplit(self, up_dir, m_size, o_files, gid): f_size, dirpath, file_, - self.splitSize, + self.split_size, self ) - if self.isCancelled: + if self.is_cancelled: return if not res: - if f_size >= self.maxSplitSize: + if f_size >= self.max_split_size: if ( self.seed - and not self.newDir + and not self.new_dir ): m_size.append(f_size) o_files.append(f_path) @@ -1234,7 +1308,7 @@ async def proceedSplit(self, up_dir, m_size, o_files, gid): continue elif ( not self.seed - or self.newDir + or self.new_dir ): try: await remove(f_path) @@ -1244,11 +1318,11 @@ async def proceedSplit(self, up_dir, m_size, o_files, gid): m_size.append(f_size) o_files.append(f_path) - async def generateSampleVideo(self, dl_path, gid, unwanted_files, ft_delete): + async def generate_sample_video(self, dl_path, gid, unwanted_files, ft_delete): data = ( - self.sampleVideo.split(":") + self.sample_video.split(":") if isinstance( - self.sampleVideo, + self.sample_video, str ) else "" @@ -1280,7 +1354,7 @@ async def generateSampleVideo(self, dl_path, gid, unwanted_files, ft_delete): checked = True await cpu_eater_lock.acquire() LOGGER.info(f"Creating Sample video: {self.name}") - res = await createSampleVideo( + res = await create_sample_video( self, dl_path, sample_duration, @@ -1295,17 +1369,17 @@ async def generateSampleVideo(self, dl_path, gid, unwanted_files, ft_delete): )[1] if ( self.seed - and not self.newDir + and not self.new_dir ): if ( - self.isLeech + self.is_leech and not self.compress ): return self.dir - self.newDir = f"{self.dir}10000" + self.new_dir = f"{self.dir}10000" newfolder = newfolder.replace( self.dir, - self.newDir + self.new_dir ) await makedirs( newfolder, @@ -1359,10 +1433,10 @@ async def generateSampleVideo(self, dl_path, gid, unwanted_files, ft_delete): checked = True await cpu_eater_lock.acquire() LOGGER.info(f"Creating Sample videos: {self.name}") - if self.isCancelled: + if self.is_cancelled: cpu_eater_lock.release() return "" - res = await createSampleVideo( + res = await create_sample_video( self, f_path, sample_duration, @@ -1375,10 +1449,10 @@ async def generateSampleVideo(self, dl_path, gid, unwanted_files, ft_delete): return dl_path - async def convertMedia(self, dl_path, gid, o_files, m_size, ft_delete): + async def convert_media(self, dl_path, gid, o_files, m_size, ft_delete): fvext = [] - if self.convertVideo: - vdata = self.convertVideo.split() # type: ignore + if self.convert_video: + vdata = self.convert_video.split() # type: ignore vext = vdata[0] if len(vdata) > 2: if "+" in vdata[1].split(): @@ -1399,8 +1473,8 @@ async def convertMedia(self, dl_path, gid, o_files, m_size, ft_delete): vstatus = "" faext = [] - if self.convertAudio: - adata = self.convertAudio.split() # type: ignore + if self.convert_audio: + adata = self.convert_audio.split() # type: ignore aext = adata[0] if len(adata) > 2: if "+" in adata[1].split(): @@ -1422,7 +1496,7 @@ async def convertMedia(self, dl_path, gid, o_files, m_size, ft_delete): checked = False - async def proceedConvert(m_path): + async def proceed_convert(m_path): nonlocal checked ( is_video, @@ -1459,7 +1533,7 @@ async def proceedConvert(m_path): ) return ( "" - if self.isCancelled + if self.is_cancelled else res ) elif ( @@ -1493,25 +1567,25 @@ async def proceedConvert(m_path): ) return ( "" - if self.isCancelled + if self.is_cancelled else res ) else: return "" if await aiopath.isfile(dl_path): - output_file = await proceedConvert(dl_path) # type: ignore + output_file = await proceed_convert(dl_path) # type: ignore if checked: cpu_eater_lock.release() if output_file: if self.seed: - self.newDir = f"{self.dir}10000" + self.new_dir = f"{self.dir}10000" new_output_file = output_file.replace( self.dir, - self.newDir + self.new_dir ) await makedirs( - self.newDir, + self.new_dir, exist_ok=True ) await move( @@ -1536,16 +1610,16 @@ async def proceedConvert(m_path): topdown=False ): for file_ in files: - if self.isCancelled: + if self.is_cancelled: cpu_eater_lock.release() return "" f_path = ospath.join( dirpath, file_ ) - res = await proceedConvert(f_path) + res = await proceed_convert(f_path) if res: - if self.seed and not self.newDir: + if self.seed and not self.new_dir: o_files.append(f_path) fsize = await aiopath.getsize(f_path) m_size.append(fsize) @@ -1559,11 +1633,11 @@ async def proceedConvert(m_path): cpu_eater_lock.release() return dl_path - async def generateScreenshots(self, dl_path): + async def generate_screenshots(self, dl_path): ss_nb = ( - int(self.screenShots) + int(self.screen_shots) if isinstance( - self.screenShots, + self.screen_shots, str ) else 10 @@ -1583,10 +1657,10 @@ async def generateScreenshots(self, dl_path): )[1] if ( self.seed - and not self.newDir + and not self.new_dir ): if ( - self.isLeech + self.is_leech and not self.compress ): return self.dir @@ -1594,10 +1668,10 @@ async def generateScreenshots(self, dl_path): newfolder, exist_ok=True ) - self.newDir = f"{self.dir}10000" + self.new_dir = f"{self.dir}10000" newfolder = newfolder.replace( self.dir, - self.newDir + self.new_dir ) await gather( copy2( @@ -1657,15 +1731,20 @@ async def substitute(self, dl_path): "/", 1 ) - for l in self.nameSub: - pattern = l[0] - res = ( - l[1] - if len(l) > 1 and l[1] - else "" - ) - sen = len(l) > 2 and l[2] == "s" - new_name = sub( + for substitution in self.name_sub: + sen = False + pattern = substitution[0] + if len(substitution) > 1: + if len(substitution) > 2: + sen = substitution[2] == "s" + res = substitution[1] + elif len(substitution[1]) == 0: + res = " " + else: + res = substitution[1] + else: + res = "" + name = sub( rf"{pattern}", res, name, @@ -1675,7 +1754,7 @@ async def substitute(self, dl_path): ) new_path = ospath.join( up_dir, - new_name + name ) await move( dl_path, @@ -1697,15 +1776,20 @@ async def substitute(self, dl_path): dirpath, file_ ) - for l in self.nameSub: - pattern = l[0] - res = ( - l[1] - if len(l) > 1 and l[1] - else "" - ) - sen = len(l) > 2 and l[2] == "s" - new_name = sub( + for substitution in self.name_sub: + sen = False + pattern = substitution[0] + if len(substitution) > 1: + if len(substitution) > 2: + sen = substitution[2] == "s" + res = substitution[1] + elif len(substitution[1]) == 0: + res = " " + else: + res = substitution[1] + else: + res = "" + file_ = sub( rf"{pattern}", res, file_, @@ -1717,7 +1801,7 @@ async def substitute(self, dl_path): f_path, ospath.join( dirpath, - new_name + file_ ) ) return dl_path @@ -1728,7 +1812,7 @@ async def proceedMetadata(self, up_path, gid): self, gid ) - LOGGER.info(f"Editing Metadata: {self.metaData} into {up_path}") + LOGGER.info(f"Editing Metadata: {self.metadata} into {up_path}") await edit_video_metadata( self, up_path @@ -1741,7 +1825,7 @@ async def proceedAttachment(self, up_path, gid): self, gid ) - LOGGER.info(f"Adding Attachment: {self.metaAttachment} into {up_path}") + LOGGER.info(f"Adding Attachment: {self.m_attachment} into {up_path}") await add_attachment( self, up_path diff --git a/bot/helper/ext_utils/bot_utils.py b/bot/helper/ext_utils/bot_utils.py index 0ae1b65532ef..8b9bf6d8790f 100644 --- a/bot/helper/ext_utils/bot_utils.py +++ b/bot/helper/ext_utils/bot_utils.py @@ -5,10 +5,15 @@ sleep, ) from asyncio.subprocess import PIPE -from functools import partial, wraps +from concurrent.futures import ThreadPoolExecutor +from functools import ( + partial, + wraps +) +from os import cpu_count +from httpx import AsyncClient from nekozee.types import BotCommand -from httpx import AsyncClient from bot import ( user_data, @@ -16,19 +21,26 @@ bot_loop, extra_buttons ) -from bot.helper.ext_utils.help_messages import ( +from .help_messages import ( YT_HELP_DICT, MIRROR_HELP_DICT, CLONE_HELP_DICT, ) -from bot.helper.ext_utils.telegraph_helper import telegraph -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.bot_commands import BotCommands +from .telegraph_helper import telegraph +from ..telegram_helper.button_build import ButtonMaker +from ..telegram_helper.bot_commands import BotCommands COMMAND_USAGE = {} +max_workers = min( + 10000, + ( + cpu_count() + or 0 + ) + 4 +) +THREAD_POOL = ThreadPoolExecutor(max_workers=max_workers) - -class setInterval: +class SetInterval: def __init__(self, interval, action, *args, **kwargs): self.interval = interval self.action = action @@ -51,49 +63,37 @@ def cancel(self): self.task.cancel() -def create_help_buttons(): +def _build_command_usage(help_dict, command_key): buttons = ButtonMaker() - for name in list(MIRROR_HELP_DICT.keys())[1:]: - buttons.ibutton( + for name in list(help_dict.keys())[1:]: + buttons.data_button( name, - f"help mirror {name}" + f"help {command_key} {name}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "help close" ) - COMMAND_USAGE["mirror"] = [ - MIRROR_HELP_DICT["main"], + COMMAND_USAGE[command_key] = [ + help_dict["main"], buttons.build_menu(2) ] buttons.reset() - for name in list(YT_HELP_DICT.keys())[1:]: - buttons.ibutton( - name, - f"help yt {name}" - ) - buttons.ibutton( - "ᴄʟᴏꜱᴇ", - "help close" + + +def create_help_buttons(): + _build_command_usage( + MIRROR_HELP_DICT, + "mirror" ) - COMMAND_USAGE["yt"] = [ - YT_HELP_DICT["main"], - buttons.build_menu(2) - ] - buttons.reset() - for name in list(CLONE_HELP_DICT.keys())[1:]: - buttons.ibutton( - name, - f"help clone {name}" - ) - buttons.ibutton( - "ᴄʟᴏꜱᴇ", - "help close" + _build_command_usage( + YT_HELP_DICT, + "yt" + ) + _build_command_usage( + CLONE_HELP_DICT, + "clone" ) - COMMAND_USAGE["clone"] = [ - CLONE_HELP_DICT["main"], - buttons.build_menu(2) - ] def bt_selection_buttons(id_): @@ -112,24 +112,24 @@ def bt_selection_buttons(id_): buttons = ButtonMaker() BASE_URL = config_dict["BASE_URL"] if config_dict["WEB_PINCODE"]: - buttons.ubutton( + buttons.url_button( "ꜱᴇʟᴇᴄᴛ ꜰɪʟᴇꜱ", f"{BASE_URL}/app/files/{id_}" ) - buttons.ibutton( + buttons.data_button( "ᴘɪɴᴄᴏᴅᴇ", f"sel pin {gid} {pincode}" ) else: - buttons.ubutton( + buttons.url_button( "ꜱᴇʟᴇᴄᴛ ꜰɪʟᴇꜱ", f"{BASE_URL}/app/files/{id_}?pin_code={pincode}" ) - buttons.ibutton( + buttons.data_button( "ᴅᴏɴᴇ ꜱᴇʟᴇᴄᴛɪɴɢ", f"sel done {gid} {id_}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"sel cancel {gid}" ) @@ -142,7 +142,7 @@ def extra_btns(buttons): btn_name, btn_url ) in extra_buttons.items(): - buttons.ubutton( + buttons.url_button( btn_name, btn_url ) @@ -251,7 +251,7 @@ async def get_telegraph_list(telegraph_content): telegraph_content ) buttons = ButtonMaker() - buttons.ubutton( + buttons.url_button( "🔎 ᴠɪᴇᴡ\nʀᴇꜱᴜʟᴛꜱ", f"https://telegra.ph/{path[0]}" ) @@ -275,6 +275,8 @@ def arg_parser(items, arg_base): "-fu", "-sync", "-ml", + "-doc", + "-med" } t = len(items) i = 0 @@ -295,7 +297,9 @@ def arg_parser(items, arg_base): "-fd", "-fu", "-sync", - "-ml" + "-ml", + "-doc", + "-med" ] ): arg_base[part] = True @@ -328,7 +332,7 @@ def arg_parser(items, arg_base): arg_base["link"] = " ".join(link) -def getSizeBytes(size): +def get_size_bytes(size): size = size.lower() if size.endswith("mb"): size = size.split("mb")[0] @@ -407,21 +411,17 @@ async def cmd_exec(cmd, shell=False): def new_task(func): @wraps(func) - def wrapper( + async def wrapper( *args, **kwargs ): - bot_loop.create_task( + task = bot_loop.create_task( func( *args, **kwargs ) ) - - async def dummy(): - pass - - return dummy + return task return wrapper @@ -433,7 +433,7 @@ async def sync_to_async(func, *args, wait=True, **kwargs): **kwargs ) future = bot_loop.run_in_executor( - None, + THREAD_POOL, pfunc ) return ( @@ -458,7 +458,7 @@ def async_to_sync(func, *args, wait=True, **kwargs): ) -def new_thread(func): +def loop_thread(func): @wraps(func) def wrapper( *args, diff --git a/bot/helper/ext_utils/bulk_links.py b/bot/helper/ext_utils/bulk_links.py index 2711ade96930..5afd9ae36915 100644 --- a/bot/helper/ext_utils/bulk_links.py +++ b/bot/helper/ext_utils/bulk_links.py @@ -2,7 +2,7 @@ from aiofiles.os import remove -def filterLinks(links_list: list, bulk_start: int, bulk_end: int) -> list: +def filter_links(links_list: list, bulk_start: int, bulk_end: int) -> list: if bulk_start != 0 and bulk_end != 0: links_list = links_list[bulk_start:bulk_end] elif bulk_start != 0: @@ -12,7 +12,7 @@ def filterLinks(links_list: list, bulk_start: int, bulk_end: int) -> list: return links_list -def getLinksFromMessage(text: str) -> list: +def get_links_from_message(text: str) -> list: links_list = text.split("\n") return [ item.strip() for item in links_list @@ -20,7 +20,7 @@ def getLinksFromMessage(text: str) -> list: ] -async def getLinksFromFile(message) -> list: +async def get_links_from_file(message) -> list: links_list = [] text_file_dir = await message.download() async with aiopen( @@ -38,7 +38,7 @@ async def getLinksFromFile(message) -> list: return links_list -async def extractBulkLinks(message, bulk_start: str, bulk_end: str) -> list: +async def extract_bulk_links(message, bulk_start: str, bulk_end: str) -> list: bulk_start = int(bulk_start) # type: ignore bulk_end = int(bulk_end) # type: ignore links_list = [] @@ -47,11 +47,11 @@ async def extractBulkLinks(message, bulk_start: str, bulk_end: str) -> list: (file_ := reply_to.document) and (file_.mime_type == "text/plain") ): - links_list = await getLinksFromFile(reply_to) + links_list = await get_links_from_file(reply_to) elif text := reply_to.text: - links_list = getLinksFromMessage(text) + links_list = get_links_from_message(text) return ( - filterLinks( + filter_links( links_list, bulk_start, # type: ignore bulk_end # type: ignore diff --git a/bot/helper/ext_utils/db_handler.py b/bot/helper/ext_utils/db_handler.py index 8648831f9f93..5bfeb48424e7 100644 --- a/bot/helper/ext_utils/db_handler.py +++ b/bot/helper/ext_utils/db_handler.py @@ -10,11 +10,10 @@ from bot import ( bot_name, - DATABASE_URL, user_data, rss_dict, LOGGER, - bot_id, + BOT_ID, config_dict, aria2_options, qbit_options, @@ -23,29 +22,42 @@ class DbManager: def __init__(self): - self._err = False + self._return = False self._db = None self._conn = None - self._connect() - def _connect(self): + async def connect(self): try: - self._conn = AsyncIOMotorClient( - DATABASE_URL, - server_api=ServerApi("1") - ) - self._db = self._conn.zee + if config_dict["DATABASE_URL"]: + if self._conn is not None: + await self._conn.close() + self._conn = AsyncIOMotorClient( + config_dict["DATABASE_URL"], server_api=ServerApi("1") + ) + self._db = self._conn.zee + self._return = False + else: + self._return = True + except PyMongoError as e: LOGGER.error(f"Error in DB connection: {e}") - self._err = True + self._return = True + + async def disconnect(self): + if self._conn is not None: + await self._conn.close() + self._conn = None + self._return = True async def db_load(self): - if self._err: + if self._db is None: + await self.connect() + if self._return : return # Save bot settings try: await self._db.settings.config.replace_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, config_dict, upsert=True ) @@ -53,30 +65,30 @@ async def db_load(self): LOGGER.error(f"DataBase Collection Error: {e}") return # Save Aria2c options - if await self._db.settings.aria2c.find_one({"_id": bot_id}) is None: # type: ignore + if await self._db.settings.aria2c.find_one({"_id": BOT_ID}) is None: # type: ignore await self._db.settings.aria2c.update_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, {"$set": aria2_options}, upsert=True ) # Save qbittorrent options - if await self._db.settings.qbittorrent.find_one({"_id": bot_id}) is None: # type: ignore + if await self._db.settings.qbittorrent.find_one({"_id": BOT_ID}) is None: # type: ignore await self.save_qbit_settings() # Save nzb config - if await self._db.settings.nzb.find_one({"_id": bot_id}) is None: # type: ignore + if await self._db.settings.nzb.find_one({"_id": BOT_ID}) is None: # type: ignore async with aiopen( "sabnzbd/SABnzbd.ini", "rb+" ) as pf: nzb_conf = await pf.read() await self._db.settings.nzb.update_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, {"$set": {"SABnzbd__ini": nzb_conf}}, upsert=True ) # User Data - if await self._db.users[bot_id].find_one(): # type: ignore - rows = self._db.users[bot_id].find({}) # type: ignore + if await self._db.users[BOT_ID].find_one(): # type: ignore + rows = self._db.users[BOT_ID].find({}) # type: ignore # return a dict ==> {_id, is_sudo, is_auth, as_doc, thumb, yt_opt, media_group, equal_splits, split_size, rclone, rclone_path, token_pickle, gdrive_id, leech_dest, lperfix, lprefix, excluded_extensions, user_transmission, index_url, default_upload} async for row in rows: uid = row["_id"] @@ -113,62 +125,62 @@ async def db_load(self): row["token_pickle"] = token_path user_data[uid] = row # Rss Data - if await self._db.rss[bot_id].find_one(): # type: ignore + if await self._db.rss[BOT_ID].find_one(): # type: ignore # return a dict ==> {_id, title: {link, last_feed, last_name, inf, exf, command, paused} - rows = self._db.rss[bot_id].find({}) # type: ignore + rows = self._db.rss[BOT_ID].find({}) # type: ignore async for row in rows: user_id = row["_id"] del row["_id"] rss_dict[user_id] = row async def update_deploy_config(self): - if self._err: + if self._return : return current_config = dict(dotenv_values("config.env")) await self._db.settings.deployConfig.replace_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, current_config, upsert=True ) async def update_config(self, dict_): - if self._err: + if self._return : return await self._db.settings.config.update_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, {"$set": dict_}, upsert=True ) async def update_aria2(self, key, value): - if self._err: + if self._return : return await self._db.settings.aria2c.update_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, {"$set": {key: value}}, upsert=True ) async def update_qbittorrent(self, key, value): - if self._err: + if self._return : return await self._db.settings.qbittorrent.update_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, {"$set": {key: value}}, upsert=True ) async def save_qbit_settings(self): - if self._err: + if self._return : return await self._db.settings.qbittorrent.replace_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, qbit_options, upsert=True ) async def update_private_file(self, path): - if self._err: + if self._return : return if await aiopath.exists(path): async with aiopen(path, "rb+") as pf: @@ -177,7 +189,7 @@ async def update_private_file(self, path): pf_bin = "" path = path.replace(".", "__") await self._db.settings.files.update_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, {"$set": {path: pf_bin}}, upsert=True ) @@ -191,13 +203,13 @@ async def update_nzb_config(self): ) as pf: nzb_conf = await pf.read() await self._db.settings.nzb.replace_one( # type: ignore - {"_id": bot_id}, + {"_id": BOT_ID}, {"SABnzbd__ini": nzb_conf}, upsert=True ) async def update_user_data(self, user_id): - if self._err: + if self._return : return data = user_data.get( user_id, @@ -209,14 +221,14 @@ async def update_user_data(self, user_id): del data["rclone_config"] if data.get("token_pickle"): del data["token_pickle"] - await self._db.users[bot_id].replace_one( # type: ignore + await self._db.users[BOT_ID].replace_one( # type: ignore {"_id": user_id}, data, upsert=True ) async def update_user_doc(self, user_id, key, path=""): - if self._err: + if self._return : return if path: async with aiopen( @@ -226,40 +238,40 @@ async def update_user_doc(self, user_id, key, path=""): doc_bin = await doc.read() else: doc_bin = "" - await self._db.users[bot_id].update_one( # type: ignore + await self._db.users[BOT_ID].update_one( # type: ignore {"_id": user_id}, {"$set": {key: doc_bin}}, upsert=True ) async def rss_update_all(self): - if self._err: + if self._return : return for user_id in list(rss_dict.keys()): - await self._db.rss[bot_id].replace_one( # type: ignore + await self._db.rss[BOT_ID].replace_one( # type: ignore {"_id": user_id}, rss_dict[user_id], upsert=True ) async def rss_update(self, user_id): - if self._err: + if self._return : return - await self._db.rss[bot_id].replace_one( # type: ignore + await self._db.rss[BOT_ID].replace_one( # type: ignore {"_id": user_id}, rss_dict[user_id], upsert=True ) async def rss_delete(self, user_id): - if self._err: + if self._return : return - await self._db.rss[bot_id].delete_one({"_id": user_id}) # type: ignore + await self._db.rss[BOT_ID].delete_one({"_id": user_id}) # type: ignore async def add_incomplete_task(self, cid, link, tag): - if self._err: + if self._return : return - await self._db.tasks[bot_id].insert_one( # type: ignore + await self._db.tasks[BOT_ID].insert_one( # type: ignore { "_id": link, "cid": cid, @@ -268,17 +280,17 @@ async def add_incomplete_task(self, cid, link, tag): ) async def rm_complete_task(self, link): - if self._err: + if self._return : return - await self._db.tasks[bot_id].delete_one({"_id": link}) # type: ignore + await self._db.tasks[BOT_ID].delete_one({"_id": link}) # type: ignore async def get_incomplete_tasks(self): notifier_dict = {} - if self._err: + if self._return : return notifier_dict - if await self._db.tasks[bot_id].find_one(): # type: ignore + if await self._db.tasks[BOT_ID].find_one(): # type: ignore # return a dict ==> {_id, cid, tag} - rows = self._db.tasks[bot_id].find({}) # type: ignore + rows = self._db.tasks[BOT_ID].find({}) # type: ignore async for row in rows: if row["cid"] in list(notifier_dict.keys()): if row["tag"] in list(notifier_dict[row["cid"]]): @@ -287,16 +299,16 @@ async def get_incomplete_tasks(self): notifier_dict[row["cid"]][row["tag"]] = [row["_id"]] else: notifier_dict[row["cid"]] = {row["tag"]: [row["_id"]]} - await self._db.tasks[bot_id].drop() # type: ignore + await self._db.tasks[BOT_ID].drop() # type: ignore return notifier_dict # return a dict ==> {cid: {tag: [_id, _id, ...]}} async def trunc_table(self, name): - if self._err: + if self._return : return - await self._db[name][bot_id].drop() # type: ignore + await self._db[name][BOT_ID].drop() # type: ignore async def add_download_url(self, url: str, tag: str): - if self._err: + if self._return : return download = { "_id": url, @@ -310,25 +322,25 @@ async def add_download_url(self, url: str, tag: str): ) async def check_download(self, url: str): - if self._err: + if self._return : return exist = await self._db.download_links.find_one({"_id": url}) # type: ignore return exist async def clear_download_links(self, botName=None): - if self._err: + if self._return : return if not botName: botName = bot_name await self._db.download_links.delete_many({"botname": botName}) # type: ignore async def remove_download(self, url: str): - if self._err: + if self._return : return await self._db.download_links.delete_one({"_id": url}) # type: ignore async def update_user_tdata(self, user_id, token, time): - if self._err: + if self._return : return await self._db.access_token.update_one( # type: ignore {"_id": user_id}, @@ -337,7 +349,7 @@ async def update_user_tdata(self, user_id, token, time): ) async def update_user_token(self, user_id, token, inittime): - if self._err: + if self._return : return await self._db.access_token.update_one( # type: ignore {"_id": user_id}, @@ -346,7 +358,7 @@ async def update_user_token(self, user_id, token, inittime): ) async def get_token_expire_time(self, user_id): - if self._err: + if self._return : return None user_data = await self._db.access_token.find_one({"_id": user_id}) # type: ignore if user_data: @@ -354,7 +366,7 @@ async def get_token_expire_time(self, user_id): return None async def get_user_token(self, user_id): - if self._err: + if self._return : return None user_data = await self._db.access_token.find_one({"_id": user_id}) # type: ignore if user_data: @@ -362,7 +374,7 @@ async def get_user_token(self, user_id): return None async def get_token_init_time(self, user_id): - if self._err: + if self._return : return None user_data = await self._db.access_token.find_one({"_id": user_id}) # type: ignore if user_data: @@ -370,6 +382,9 @@ async def get_token_init_time(self, user_id): return None async def delete_all_access_tokens(self): - if self._err: + if self._return : return - await self._db.access_token.delete_many({}) # type: ignore \ No newline at end of file + await self._db.access_token.delete_many({}) # type: ignore + + +database = DbManager() diff --git a/bot/helper/ext_utils/files_utils.py b/bot/helper/ext_utils/files_utils.py index 0929615b5de9..abca3a4fdc6c 100644 --- a/bot/helper/ext_utils/files_utils.py +++ b/bot/helper/ext_utils/files_utils.py @@ -30,7 +30,7 @@ DOWNLOAD_DIR, qbittorrent_client ) -from bot.helper.ext_utils.bot_utils import ( +from .bot_utils import ( sync_to_async, cmd_exec ) @@ -74,6 +74,7 @@ ".udf", ".vhd", ".xar", + ".zst", ] FIRST_SPLIT_REGEX = r"(\.|_)part0*1\.rar$|(\.|_)7z\.0*1$|(\.|_)zip\.0*1$|^(?!.*(\.|_)part\d+\.rar$).*\.rar$" diff --git a/bot/helper/ext_utils/help_messages.py b/bot/helper/ext_utils/help_messages.py index 775e7e1736d1..b2c9eaebfef9 100644 --- a/bot/helper/ext_utils/help_messages.py +++ b/bot/helper/ext_utils/help_messages.py @@ -169,8 +169,8 @@ screenshot = """ Screenshots: -ss -Create up to 10 screenshots for one video or a folder of videos. -/cmd -ss (it will take the default values which are 10 photos). +Create screenshots for one video or folder of videos. +/cmd -ss (it will take the default values which is 10 photos). You can control this value. Example: /cmd -ss 6. """ @@ -202,7 +202,8 @@ yt_opt = """ Options: -opt -/cmd link -opt playliststart:^10|fragment_retries:^inf|matchtitle:S13|writesubtitles:true|live_from_start:true|postprocessor_args:{"ffmpeg": ["-threads", "4"]}|wait_for_video:(5, 100) +/cmd link -opt playliststart:^10|fragment_retries:^inf|matchtitle:S13|writesubtitles:true|live_from_start:true|postprocessor_args:{"ffmpeg": ["-threads", "4"]}|wait_for_video:(5, 100)|download_ranges:[{"start_time": 0, "end_time": 10}] + Note: Add `^` before integer or float, some values must be numeric and some string. Like playlist_items:10 works with string, so no need to add `^` before the number but playlistend works only with integer so you must add `^` before the number like example above. You can add tuple and dict also. Use double quotes inside dict. @@ -245,14 +246,21 @@ /cmd mrcc:rclonePath -up rcl or rc(if you have added rclone path from usetting) (to use user config) """ -name_sub = """ +name_sub = r""" Name Substitution: -ns -/cmd link -ns tea : coffee : s|ACC : : s|mP4 -This will affect all files. Format: wordToReplace : wordToReplaceWith : sensitiveCase -1. tea will get replaced by coffee with sensitive case because I have added `s` last of the option. -2. ACC will get removed because I have added nothing between to replace with sensitive case because I have added `s` last of the option. -3. mP4 will get removed because I have added nothing to replace with +b>Name Substitution: -ns +/cmd link -ns script/code/s | mirror/leech | tea/ /s | clone | cpu/ | \[ZEE\]/ZEE | \\text\\/text/s +This will affect on all files. Format: wordToReplace/wordToReplaceWith/sensitiveCase +Word Subtitions. You can add pattern instead of normal text. Timeout: 60 sec +NOTE: You must add \ before any character, those are the characters: \^$.|?*+()[]{}- +1. script will get replaced by code with sensitive case +2. mirror will get replaced by leech +4. tea will get replaced by space with sensitive case +5. clone will get removed +6. cpu will get replaced by space +7. [ZEE] will get replaced by ZEE +8. \text\ will get replaced by text with sensitive case """ mixed_leech = """ @@ -261,6 +269,19 @@ /cmd link -ml (leech by user and bot session with respect to size) """ +thumbnail_layout = """ +Thumbnail Layout: -tl + +/cmd link -tl 3x3 (widthxheight) 3 photos in row and 3 photos in column +""" + +leech_as = """ +Leech as: -doc -med + +/cmd link -doc (Leech as document) +/cmd link -med (Leech as media) +""" + YT_HELP_DICT = { "main": yt, "ʀᴇɴᴀᴍᴇ\nꜰɪʟᴇ": f"{new_name}\nNote: Don't add file extension", @@ -280,6 +301,8 @@ "ꜰᴏʀᴄᴇ\nꜱᴛᴀʀᴛ": force_start, "ɴᴀᴍᴇ\nꜱᴜʙꜱᴛɪᴛᴜᴛᴇ": name_sub, "ʜʏʙʀɪᴅ\nʟᴇᴇᴄʜ": mixed_leech, + "ᴛʜᴜᴍʙ\nʟᴀʏᴏᴜᴛ": thumbnail_layout, + "ʟᴇᴇᴄʜ\nᴛʏᴘᴇ": leech_as, } MIRROR_HELP_DICT = { @@ -307,6 +330,8 @@ "ᴜꜱᴇʀ\nᴅᴏᴡɴʟᴏᴀᴅ": user_download, "ɴᴀᴍᴇ\nꜱᴜʙꜱᴛɪᴛᴜᴛᴇ": name_sub, "ʜʏʙʀɪᴅ\nʟᴇᴇᴄʜ": mixed_leech, + "ᴛʜᴜᴍʙ\nʟᴀʏᴏᴜᴛ": thumbnail_layout, + "ʟᴇᴇᴄʜ\nᴛʏᴘᴇ": leech_as, } CLONE_HELP_DICT = { diff --git a/bot/helper/ext_utils/jdownloader_booter.py b/bot/helper/ext_utils/jdownloader_booter.py index 047dcc9c2f8c..11e9e38aba0f 100644 --- a/bot/helper/ext_utils/jdownloader_booter.py +++ b/bot/helper/ext_utils/jdownloader_booter.py @@ -16,11 +16,11 @@ jd_lock, bot_name ) -from bot.helper.ext_utils.bot_utils import ( +from .bot_utils import ( cmd_exec, new_task, ) -from myjd import Myjdapi +from myjd import MyJdApi from myjd.exception import ( MYJDException, MYJDAuthFailedException, @@ -30,7 +30,7 @@ ) -class JDownloader(Myjdapi): +class JDownloader(MyJdApi): def __init__(self): super().__init__() self._username = "" @@ -46,7 +46,7 @@ async def initiate(self): async with jd_lock: is_connected = await self.jdconnect() if is_connected: - self.boot() # type: ignore + await self.boot() await self.connectToDevice() @new_task @@ -103,7 +103,7 @@ async def boot(self): shell=True ) if code != -9: - self.boot() # type: ignore + await self.boot() async def jdconnect(self): if ( diff --git a/bot/helper/ext_utils/media_utils.py b/bot/helper/ext_utils/media_utils.py index 0261701f3178..b03a864bd3eb 100644 --- a/bot/helper/ext_utils/media_utils.py +++ b/bot/helper/ext_utils/media_utils.py @@ -1,5 +1,4 @@ -from pathlib import Path -from PIL import Image +from aioshutil import rmtree from aiofiles.os import ( remove, path as aiopath, @@ -12,17 +11,27 @@ ) from asyncio.subprocess import PIPE from os import ( - path as ospath, - cpu_count + cpu_count, + path as ospath +) +from pathlib import Path +from PIL import Image +from re import ( + escape, + search as re_search ) -from re import search as re_search from time import time -from aioshutil import rmtree -from bot import LOGGER, subprocess_lock -from bot.helper.ext_utils.bot_utils import cmd_exec -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.files_utils import ( +from bot import ( + LOGGER, + DOWNLOAD_DIR, + subprocess_lock +) +from .bot_utils import ( + cmd_exec, + sync_to_async +) +from .files_utils import ( ARCH_EXT, get_mime_type ) @@ -70,20 +79,20 @@ async def convert_video(listener, video_file, ext, retry=False): "copy", output ] - if listener.isCancelled: + if listener.is_cancelled: return False listener.suproc = await create_subprocess_exec( *cmd, stderr=PIPE ) _, stderr = await listener.suproc.communicate() - if listener.isCancelled: + if listener.is_cancelled: return False code = listener.suproc.returncode if code == 0: return output elif code == -9: - listener.isCancelled = True + listener.is_cancelled = True return False else: if not retry: @@ -117,7 +126,7 @@ async def convert_audio(listener, audio_file, ext): f"{cpu_count() // 2}", # type: ignore output, ] - if listener.isCancelled: + if listener.is_cancelled: return False listener.suproc = await create_subprocess_exec( *cmd, @@ -127,13 +136,13 @@ async def convert_audio(listener, audio_file, ext): _, stderr ) = await listener.suproc.communicate() - if listener.isCancelled: + if listener.is_cancelled: return False code = listener.suproc.returncode if code == 0: return output elif code == -9: - listener.isCancelled = True + listener.is_cancelled = True return False else: try: @@ -148,23 +157,32 @@ async def convert_audio(listener, audio_file, ext): return False -async def createThumb(msg, _id=""): +async def create_thumb(msg, _id=""): if not _id: _id = msg.id - path = "Thumbnails/" + path = f"{DOWNLOAD_DIR}Thumbnails" + else: + path = 'Thumbnails' await makedirs( path, exist_ok=True ) photo_dir = await msg.download() - des_dir = f"{path}{_id}.jpg" + output = ospath.join( + path, + f"{_id}.jpg" + ) await sync_to_async( - Image.open(photo_dir).convert("RGB").save, - des_dir, + Image.open( + photo_dir + ).convert( + "RGB" + ).save, + output, "JPEG" ) await remove(photo_dir) - return des_dir + return output global_streams = {} async def is_multi_streams(path): @@ -295,21 +313,6 @@ async def get_document_type(path): False, True ) - if mime_type.startswith("audio"): - return ( - False, - True, - False - ) - if ( - not mime_type.startswith("video") and - not mime_type.endswith("octet-stream") - ): - return ( - is_video, - is_audio, - is_image - ) try: result = await cmd_exec( [ @@ -327,6 +330,21 @@ async def get_document_type(path): is_video = True except Exception as e: LOGGER.error(f"Get Document Type: {e}. Mostly File not found! - File: {path}") + if mime_type.startswith("audio"): + return ( + False, + True, + False + ) + if ( + not mime_type.startswith("video") and + not mime_type.endswith("octet-stream") + ): + return ( + is_video, + is_audio, + is_image + ) if mime_type.startswith("video"): is_video = True return ( @@ -360,10 +378,6 @@ async def get_document_type(path): async def take_ss(video_file, ss_nb) -> bool: - ss_nb = min( - ss_nb, - 10 - ) duration = (await get_media_info(video_file))[0] if duration != 0: ( @@ -377,13 +391,13 @@ async def take_ss(video_file, ss_nb) -> bool: name, _ ) = ospath.splitext(name) - dirpath = f"{dirpath}/{name}_zeess/" + dirpath = f"{dirpath}/{name}_zeess" await makedirs(dirpath, exist_ok=True) interval = duration // (ss_nb + 1) cap_time = interval cmds = [] for i in range(ss_nb): - output = f"{dirpath}SS.{name}_{i:02}.png" + output = f"{dirpath}/SS.{name}_{i:02}.png" cmd = [ "ffmpeg", "-hide_banner", @@ -429,20 +443,19 @@ async def take_ss(video_file, ss_nb) -> bool: return dirpath # type: ignore else: LOGGER.error("take_ss: Can't get the duration of video") - await rmtree( - dirpath, # type: ignore - ignore_errors=True - ) return False -async def get_audio_thumb(audio_file): - des_dir = "Thumbnails/" +async def get_audio_thumbnail(audio_file): + output_dir = f"{DOWNLOAD_DIR}Thumbnails" await makedirs( - des_dir, + output_dir, exist_ok=True ) - des_dir = f"Thumbnails/{time()}.jpg" + output = ospath.join( + output_dir, + f"{time()}.jpg" + ) cmd = [ "ffmpeg", "-hide_banner", @@ -455,29 +468,29 @@ async def get_audio_thumb(audio_file): "copy", "-threads", f"{cpu_count() // 2}", # type: ignore - des_dir, + output, ] ( _, err, code ) = await cmd_exec(cmd) - if code != 0 or not await aiopath.exists(des_dir): + if code != 0 or not await aiopath.exists(output): LOGGER.error( f"Error while extracting thumbnail from audio. Name: {audio_file} stderr: {err}" ) return None - return des_dir + return output -async def create_thumbnail(video_file, duration): - des_dir = "Thumbnails" +async def get_video_thumbnail(video_file, duration): + output_dir = f"{DOWNLOAD_DIR}Thumbnails" await makedirs( - des_dir, + output_dir, exist_ok=True ) - des_dir = ospath.join( - des_dir, + output = ospath.join( + output_dir, f"{time()}.jpg" ) if duration is None: @@ -496,11 +509,13 @@ async def create_thumbnail(video_file, duration): video_file, "-vf", "thumbnail", + "-q:v", + "1", "-frames:v", "1", "-threads", f"{cpu_count() // 2}", # type: ignore - des_dir, + output, ] try: ( @@ -513,7 +528,7 @@ async def create_thumbnail(video_file, duration): ) if ( code != 0 - or not await aiopath.exists(des_dir) + or not await aiopath.exists(output) ): LOGGER.error( f"Error while extracting thumbnail from video. Name: {video_file} stderr: {err}" @@ -524,7 +539,74 @@ async def create_thumbnail(video_file, duration): f"Error while extracting thumbnail from video. Name: {video_file}. Error: Timeout some issues with ffmpeg with specific arch!" ) return None - return des_dir + return output + + +async def get_multiple_frames_thumbnail(video_file, layout, keep_screenshots): + ss_nb = layout.split("x") + ss_nb = int(ss_nb[0]) * int(ss_nb[1]) + dirpath = await take_ss( + video_file, + ss_nb + ) + if not dirpath: + return None + output_dir = f"{DOWNLOAD_DIR}Thumbnails" + await makedirs( + output_dir, + exist_ok=True + ) + output = ospath.join( + output_dir, + f"{time()}.jpg" + ) + cmd = [ + "ffmpeg", + "-hide_banner", + "-loglevel", + "error", + "-pattern_type", + "glob", + "-i", + f"{escape(dirpath)}/*.png", # type: ignore + "-vf", + f"tile={layout}, thumbnail", + "-q:v", + "1", + "-frames:v", + "1", + "-f", + "mjpeg", + "-threads", + f"{cpu_count() // 2}", # type: ignore + output, + ] + try: + ( + _, + err, + code + ) = await wait_for( + cmd_exec(cmd), + timeout=60 + ) + if code != 0 or not await aiopath.exists(output): + LOGGER.error( + f"Error while combining thumbnails for video. Name: {video_file} stderr: {err}" + ) + return None + except: + LOGGER.error( + f"Error while combining thumbnails from video. Name: {video_file}. Error: Timeout some issues with ffmpeg with specific arch!" + ) + return None + finally: + if not keep_screenshots: + await rmtree( + dirpath, + ignore_errors=True + ) + return output async def split_file( @@ -541,21 +623,21 @@ async def split_file( ): if ( listener.seed and not - listener.newDir + listener.new_dir ): dirpath = f"{dirpath}/splited_files_zee" await makedirs( dirpath, exist_ok=True ) - parts = -(-size // listener.splitSize) + parts = -(-size // listener.split_size) if ( - listener.equalSplits + listener.equal_splits and not inLoop ): split_size = (size // parts) + (size % parts) if ( - not listener.asDoc + not listener.as_doc and (await get_document_type(path))[0] ): if multi_streams: @@ -594,7 +676,7 @@ async def split_file( if not multi_streams: del cmd[10] del cmd[10] - if listener.isCancelled: + if listener.is_cancelled: return False async with subprocess_lock: listener.suproc = await create_subprocess_exec( @@ -605,11 +687,11 @@ async def split_file( _, stderr ) = await listener.suproc.communicate() - if listener.isCancelled: + if listener.is_cancelled: return False code = listener.suproc.returncode if code == -9: - listener.isCancelled = True + listener.is_cancelled = True return False elif code != 0: try: @@ -638,12 +720,12 @@ async def split_file( ) else: LOGGER.warning( - f"{stderr}. Unable to split this video, if it's size less than {listener.maxSplitSize} will be uploaded as it is. Path: {path}" + f"{stderr}. Unable to split this video, if it's size less than {listener.max_split_size} will be uploaded as it is. Path: {path}" ) return False out_size = await aiopath.getsize(out_path) - if out_size > listener.maxSplitSize: - dif = out_size - listener.maxSplitSize + if out_size > listener.max_split_size: + dif = out_size - listener.max_split_size split_size -= dif + 5000000 await remove(out_path) return await split_file( @@ -677,7 +759,7 @@ async def split_file( else: out_path = f"{dirpath}/{file_}." async with subprocess_lock: - if listener.isCancelled: + if listener.is_cancelled: return False listener.suproc = await create_subprocess_exec( "split", @@ -692,11 +774,11 @@ async def split_file( _, stderr ) = await listener.suproc.communicate() - if listener.isCancelled: + if listener.is_cancelled: return False code = listener.suproc.returncode if code == -9: - listener.isCancelled = True + listener.is_cancelled = True return False elif code != 0: try: @@ -707,7 +789,7 @@ async def split_file( return True -async def createSampleVideo(listener, video_file, sample_duration, part_duration): +async def create_sample_video(listener, video_file, sample_duration, part_duration): ( dir, name @@ -776,7 +858,7 @@ async def createSampleVideo(listener, video_file, sample_duration, part_duration output_file, ] - if listener.isCancelled: + if listener.is_cancelled: return False listener.suproc = await create_subprocess_exec( *cmd, @@ -786,11 +868,11 @@ async def createSampleVideo(listener, video_file, sample_duration, part_duration _, stderr ) = await listener.suproc.communicate() - if listener.isCancelled: + if listener.is_cancelled: return False code = listener.suproc.returncode if code == -9: - listener.isCancelled = True + listener.is_cancelled = True return False elif code == 0: return output_file @@ -815,7 +897,7 @@ async def createSampleVideo(listener, video_file, sample_duration, part_duration async def edit_video_metadata(listener, dir): - data = listener.metaData + data = listener.metadata dir_path = Path(dir) if dir_path.suffix.lower() not in SUPPORTED_VIDEO_EXTENSIONS: @@ -935,7 +1017,7 @@ async def edit_video_metadata(listener, dir): try: async with subprocess_lock: - if listener.isCancelled: + if listener.is_cancelled: if work_path.exists(): work_path.unlink() return @@ -952,7 +1034,7 @@ async def edit_video_metadata(listener, dir): if listener.suproc.returncode != 0: if work_path.exists(): work_path.unlink() - if listener.isCancelled: + if listener.is_cancelled: return err = stderr.decode().strip() LOGGER.error(f"Error modifying metadata for file: {file_name} | {err}") @@ -988,7 +1070,7 @@ async def add_attachment(listener, dir): "png": "image/png", } - data = listener.metaAttachment + data = listener.m_attachment dir_path = Path(dir) if dir_path.suffix.lower() not in SUPPORTED_VIDEO_EXTENSIONS: @@ -1020,7 +1102,7 @@ async def add_attachment(listener, dir): try: async with subprocess_lock: - if listener.isCancelled: + if listener.is_cancelled: if work_path.exists(): work_path.unlink() return @@ -1037,7 +1119,7 @@ async def add_attachment(listener, dir): if listener.suproc.returncode != 0: if work_path.exists(): work_path.unlink() - if listener.isCancelled: + if listener.is_cancelled: return LOGGER.error(f"Error adding photo attachment to file: {file_name}") return dir diff --git a/bot/helper/ext_utils/status_utils.py b/bot/helper/ext_utils/status_utils.py index 85b059a4ac80..0194da55617a 100644 --- a/bot/helper/ext_utils/status_utils.py +++ b/bot/helper/ext_utils/status_utils.py @@ -12,13 +12,13 @@ DOWNLOAD_DIR, task_dict, task_dict_lock, - botStartTime, + bot_start_time, config_dict, status_dict, ) -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.bot_commands import BotCommands +from .bot_utils import sync_to_async +from ..telegram_helper.button_build import ButtonMaker +from ..telegram_helper.bot_commands import BotCommands SIZE_UNITS = [ "B", @@ -66,7 +66,7 @@ class MirrorStatus: } -async def getTaskByGid(gid: str): +async def get_task_by_gid(gid: str): async with task_dict_lock: for tk in task_dict.values(): if hasattr( @@ -79,22 +79,22 @@ async def getTaskByGid(gid: str): return None -def getSpecificTasks(status, userId): +def get_specific_tasks(status, user_id): if status == "All": - if userId: + if user_id: return [ tk for tk in task_dict.values() - if tk.listener.userId == userId + if tk.listener.user_id == user_id ] else: return list(task_dict.values()) - elif userId: + elif user_id: return [ tk for tk in task_dict.values() - if tk.listener.userId == userId + if tk.listener.user_id == user_id and ( (st := tk.status()) and st == status @@ -113,27 +113,25 @@ def getSpecificTasks(status, userId): ] -async def getAllTasks(req_status: str, userId): +async def get_all_tasks(req_status: str, user_id): async with task_dict_lock: return await sync_to_async( - getSpecificTasks, + get_specific_tasks, req_status, - userId + user_id ) def get_readable_file_size(size_in_bytes): - if size_in_bytes is None: + if not size_in_bytes: return "0B" + index = 0 while size_in_bytes >= 1024 and index < len(SIZE_UNITS) - 1: - size_in_bytes /= 1024 # type: ignore + size_in_bytes /= 1024 index += 1 - return ( - f"{size_in_bytes:.2f}{SIZE_UNITS[index]}" - if index > 0 - else f"{size_in_bytes:.2f}B" - ) + + return f"{size_in_bytes:.2f}{SIZE_UNITS[index]}" def get_readable_time(seconds): @@ -209,7 +207,7 @@ async def get_readable_message( button = None tasks = await sync_to_async( - getSpecificTasks, + get_specific_tasks, status, sid if is_user @@ -245,7 +243,7 @@ async def get_readable_message( user_tag = task.listener.tag.replace("@", "").replace("_", " ") cancel_task = ( f"/{BotCommands.CancelTaskCommand[1]} {task.gid()}" - if not task.listener.getChat.has_protected_content + if not task.listener.get_chat.has_protected_content else f"/{BotCommands.CancelTaskCommand[1]}_{task.gid()}" ) @@ -283,7 +281,7 @@ async def get_readable_message( f"\nETA : {task.eta()}" f"\nPast : {elapsed}" f"\nUser : {user_tag}" - f"\nUserID : ||{task.listener.userId}||" + f"\nUserID : ||{task.listener.user_id}||" f"\nUpload : {task.listener.mode}" f"\nEngine : {task.engine}" ) @@ -319,7 +317,7 @@ async def get_readable_message( f"\nUpload : {task.listener.mode}" f"\nPast : {elapsed}" f"\nUser : {user_tag}" - f"\nUserID : ||{task.listener.userId}||" + f"\nUserID : ||{task.listener.user_id}||" f"\nEngine : {task.engine}" ) msg += f"\n⚠️ {cancel_task}\n\n" @@ -334,35 +332,35 @@ async def get_readable_message( msg = f"No Active {status} Tasks!\n\n" buttons = ButtonMaker() if is_user: - buttons.ibutton( + buttons.data_button( "ʀᴇғʀᴇsʜ", f"status {sid} ref", position="header" ) if not is_user: - buttons.ibutton( + buttons.data_button( "ᴛᴀsᴋs\nɪɴғᴏ", f"status {sid} ov", position="footer" ) - buttons.ibutton( + buttons.data_button( "sʏsᴛᴇᴍ\nɪɴғᴏ", f"status {sid} stats", position="footer" ) if len(tasks) > STATUS_LIMIT: msg += f"Tasks: {tasks_no} | Step: {page_step}\n" - buttons.ibutton( + buttons.data_button( "⫷", f"status {sid} pre", position="header" ) - buttons.ibutton( + buttons.data_button( f"ᴘᴀɢᴇs\n{page_no}/{pages}", f"status {sid} ref", position="header" ) - buttons.ibutton( + buttons.data_button( "⫸", f"status {sid} nex", position="header" @@ -377,7 +375,7 @@ async def get_readable_message( 10, 15 ]: - buttons.ibutton( + buttons.data_button( i, f"status {sid} ps {i}" ) @@ -390,7 +388,7 @@ async def get_readable_message( status_value ) in list(STATUSES.items())[:9]: if status_value != status: - buttons.ibutton( + buttons.data_button( label, f"status {sid} st {status_value}" ) @@ -400,7 +398,7 @@ async def get_readable_message( f"CPU: {cpu_percent()}% | " f"FREE: {get_readable_file_size(disk_usage(DOWNLOAD_DIR).free)}\n" f"RAM: {virtual_memory().percent}% | " - f"UPTM: {get_readable_time(time() - botStartTime)}" + f"UPTM: {get_readable_time(time() - bot_start_time)}" ) return ( msg, diff --git a/bot/helper/ext_utils/task_manager.py b/bot/helper/ext_utils/task_manager.py index e92aee0347ac..7a641dd0e57c 100644 --- a/bot/helper/ext_utils/task_manager.py +++ b/bot/helper/ext_utils/task_manager.py @@ -12,38 +12,38 @@ queue_dict_lock, LOGGER, ) -from bot.helper.ext_utils.bot_utils import ( +from .bot_utils import ( sync_to_async, get_telegraph_list, ) -from bot.helper.ext_utils.files_utils import ( +from .files_utils import ( check_storage_threshold, get_base_name ) -from bot.helper.ext_utils.links_utils import is_gdrive_id -from bot.helper.ext_utils.status_utils import ( - getSpecificTasks, +from .links_utils import is_gdrive_id +from .status_utils import ( + get_specific_tasks, get_readable_file_size ) -from bot.helper.task_utils.gdrive_utils.search import gdSearch -from bot.helper.telegram_helper.message_utils import isAdmin +from ..task_utils.gdrive_utils.search import GoogleDriveSearch +from ..telegram_helper.message_utils import is_admin async def stop_duplicate_check(listener): if ( isinstance( - listener.upDest, + listener.up_dest, int ) - or listener.isLeech + or listener.is_leech or listener.select - or not is_gdrive_id(listener.upDest) + or not is_gdrive_id(listener.up_dest) or ( - listener.upDest.startswith("mtp:") - and listener.stopDuplicate + listener.up_dest.startswith("mtp:") + and listener.stop_duplicate ) - or not listener.stopDuplicate - or listener.sameDir + or not listener.stop_duplicate + or listener.same_dir ): return ( False, @@ -66,13 +66,13 @@ async def stop_duplicate_check(listener): telegraph_content, contents_no ) = await sync_to_async( - gdSearch( - stopDup=True, - noMulti=listener.isClone + GoogleDriveSearch( + stop_dup=True, + no_multi=listener.is_clone ).drive_list, name, - listener.upDest, - listener.userId, + listener.up_dest, + listener.user_id, ) if telegraph_content: msg = f"File/Folder is already available in Drive.\nHere are {contents_no} list results:" @@ -102,13 +102,13 @@ async def check_running_tasks(listener, state="dl"): non_queued_dl.remove(listener.mid) if ( (all_limit or state_limit) - and not listener.forceRun + and not listener.force_run and not ( - listener.forceUpload + listener.force_upload and state == "up" ) and not ( - listener.forceDownload + listener.force_download and state == "dl" ) ): @@ -253,7 +253,7 @@ async def start_from_queued(): async def check_user_tasks(user_id, maxtask): all_tasks = await sync_to_async( - getSpecificTasks, + get_specific_tasks, "All", user_id ) @@ -262,7 +262,7 @@ async def check_user_tasks(user_id, maxtask): async def list_checker(listener): try: - if await isAdmin(listener.message): + if await is_admin(listener.message): return except Exception as e: LOGGER.error(f"Error while checking if the user is Admin: {e}") @@ -274,15 +274,15 @@ async def list_checker(listener): async def limit_checker( listener, - isTorrent=False, - isMega=False, - isDriveLink=False, - isRclone=False, - isJd=False, - isNzb=False, + is_torrent=False, + is_mega=False, + is_drive_link=False, + is_rclone=False, + is_jd=False, + is_nzb=False, ): try: - if await isAdmin(listener.message): + if await is_admin(listener.message): return except Exception as e: LOGGER.error(f"Error while checking if the user is Admin: {e}") @@ -298,7 +298,7 @@ def check_limit(limit, size, limit_type): limit_configs = [ ( - listener.isYtDlp, + listener.is_ytdlp, "YTDLP_LIMIT", "Yt-Dlp" ), @@ -309,37 +309,37 @@ def check_limit(limit, size, limit_type): "playlist_count" ), ( - listener.isClone, + listener.is_clone, "CLONE_LIMIT", "Clone" ), ( - isRclone, + is_rclone, "RCLONE_LIMIT", "Rclone" ), ( - isJd, + is_jd, "JD_LIMIT", "Jdownloader" ), ( - isMega, + is_mega, "MEGA_LIMIT", "Mega" ), ( - isDriveLink, + is_drive_link, "GDRIVE_LIMIT", "Google drive" ), ( - isNzb, + is_nzb, "NZB_LIMIT", "NZB" ), ( - isTorrent or listener.isTorrent, + is_torrent or listener.is_torrent, "TORRENT_LIMIT", "Torrent" ), @@ -374,7 +374,7 @@ def check_limit(limit, size, limit_type): if ( not limit_exceeded - and listener.isLeech + and listener.is_leech ): limit = config_dict.get("LEECH_LIMIT") if limit: @@ -387,7 +387,7 @@ def check_limit(limit, size, limit_type): if ( not limit_exceeded and config_dict.get("STORAGE_THRESHOLD") - and not listener.isClone + and not listener.is_clone ): arch = any([ listener.compress, diff --git a/bot/helper/ext_utils/telegraph_helper.py b/bot/helper/ext_utils/telegraph_helper.py index 4309d0e171fc..1c4acc9068e5 100644 --- a/bot/helper/ext_utils/telegraph_helper.py +++ b/bot/helper/ext_utils/telegraph_helper.py @@ -83,7 +83,7 @@ async def edit_telegraph(self, path, telegraph_content): nxt_page += 1 await self.edit_page( path=path[prev_page], - title="@Z_Mirror Torrent Search", + title="@Z_Mirror Search Engine", content=content, ) return diff --git a/bot/helper/ext_utils/token_manager.py b/bot/helper/ext_utils/token_manager.py index 9d4db6408f30..5f4efe878cd5 100644 --- a/bot/helper/ext_utils/token_manager.py +++ b/bot/helper/ext_utils/token_manager.py @@ -5,16 +5,19 @@ bot, bot_name, config_dict, - DATABASE_URL, user_data, ) -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.ext_utils.status_utils import get_readable_time -from bot.helper.ext_utils.shortener import short_url -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import sendMessage, sendLogMessage +from .bot_utils import new_task +from .db_handler import database +from .status_utils import get_readable_time +from .shortener import short_url +from ..telegram_helper.bot_commands import BotCommands +from ..telegram_helper.button_build import ButtonMaker +from ..telegram_helper.filters import CustomFilters +from ..telegram_helper.message_utils import ( + send_message, + send_log_message +) from nekozee.filters import command from nekozee.handlers import MessageHandler @@ -31,8 +34,8 @@ async def checking_access(user_id, button=None): {} ) data = user_data[user_id] - if DATABASE_URL: - data["time"] = await DbManager().get_token_expire_time(user_id) + if config_dict["DATABASE_URL"]: + data["time"] = await database.get_token_expire_time(user_id) expire = data.get("time") isExpired = ( expire is None @@ -51,8 +54,8 @@ async def checking_access(user_id, button=None): del data["time"] data["token"] = token data["inittime"] = inittime - if DATABASE_URL: - await DbManager().update_user_token( + if config_dict["DATABASE_URL"]: + await database.update_user_token( user_id, token, inittime @@ -60,7 +63,7 @@ async def checking_access(user_id, button=None): user_data[user_id].update(data) if button is None: button = ButtonMaker() - button.ubutton( + button.url_button( "ɢᴇɴᴇʀᴀᴛᴇ\nɴᴇᴡ ᴛᴏᴋᴇɴ", short_url(f"https://redirect.z-mirror.eu.org/{bot_name}/{token}") ) @@ -78,6 +81,7 @@ async def checking_access(user_id, button=None): ) +@new_task async def start(client, message): tag = message.from_user.mention if ( @@ -86,19 +90,19 @@ async def start(client, message): ): userid = message.from_user.id input_token = message.command[1] - if DATABASE_URL: - stored_token = await DbManager().get_user_token(userid) + if config_dict["DATABASE_URL"]: + stored_token = await database.get_user_token(userid) if stored_token is None: - return await sendMessage( + return await send_message( message, "This token is not associated with your account.\n\nPlease generate your own token." ) if input_token != stored_token: - return await sendMessage( + return await send_message( message, "Invalid token.\n\nPlease generate a new one." ) - inittime = await DbManager().get_token_init_time(userid) + inittime = await database.get_token_init_time(userid) duration = time() - inittime # type: ignore if ( config_dict["MINIMUM_DURATOIN"] @@ -106,17 +110,17 @@ async def start(client, message): duration < config_dict["MINIMUM_DURATOIN"] ) ): - await DbManager().update_user_tdata( + await database.update_user_tdata( userid, 0, 0 ) - await sendLogMessage( + await send_log_message( message, f"#BYPASS\n\nShortener bypass detected.", tag ) - return await sendMessage( + return await send_message( message, ( "Shortener bypass detected.\nPlease generate a new token.\n\n" @@ -124,11 +128,11 @@ async def start(client, message): "Don't use any Adblocker or VPN or Proxy\n" "or Incognito or DNS or Extensions\n" "or Any other Bypass methods.\n\nFor your safety and my " - "profit, use telegram's inbuilt browser or chrome without any extensions." + "profit, use google chrome browser without any extensions." ) ) if userid not in user_data: - return await sendMessage( + return await send_message( message, "This token is not yours!\n\nKindly generate your own." ) @@ -137,7 +141,7 @@ async def start(client, message): "token" not in data or data["token"] != input_token ): - return await sendMessage( + return await send_message( message, "Token already used!\n\nKindly generate a new one." ) @@ -149,12 +153,12 @@ async def start(client, message): ) ): del data["token"] - await sendLogMessage( + await send_log_message( message, f"#BYPASS\n\nShortener bypass detected.", tag ) - return await sendMessage( + return await send_message( message, ( "Shortener bypass detected.\nPlease generate a new token.\n\n" @@ -170,8 +174,8 @@ async def start(client, message): data["token"] = token data["time"] = ttime user_data[userid].update(data) - if DATABASE_URL: - await DbManager().update_user_tdata( + if config_dict["DATABASE_URL"]: + await database.update_user_tdata( userid, token, ttime @@ -182,7 +186,7 @@ async def start(client, message): "Your Limites:\n" f"➜ {config_dict["USER_MAX_TASKS"]} parallal tasks.\n" ) - return await sendMessage( + return await send_message( message, msg ) @@ -215,7 +219,7 @@ async def start(client, message): else: start_string = "Start me in DM, not in the group.\n" \ f"cc: {tag}" - await sendMessage( + await send_message( message, start_string ) diff --git a/bot/helper/listeners/aria2_listener.py b/bot/helper/listeners/aria2_listener.py index 317a4b5d1495..7067b3f77c28 100644 --- a/bot/helper/listeners/aria2_listener.py +++ b/bot/helper/listeners/aria2_listener.py @@ -6,40 +6,40 @@ from time import time from bot import ( + LOGGER, aria2, config_dict, - Intervals, - LOGGER, + intervals, task_dict_lock, task_dict, ) -from bot.helper.ext_utils.bot_utils import ( - new_thread, +from ..ext_utils.bot_utils import ( bt_selection_buttons, + loop_thread, sync_to_async, ) -from bot.helper.ext_utils.files_utils import clean_unwanted -from bot.helper.ext_utils.status_utils import ( +from ..ext_utils.files_utils import clean_unwanted +from ..ext_utils.status_utils import ( get_readable_file_size, - getTaskByGid + get_task_by_gid ) -from bot.helper.ext_utils.task_manager import ( +from ..ext_utils.task_manager import ( limit_checker, stop_duplicate_check, check_avg_speed ) -from bot.helper.task_utils.status_utils.aria2_status import Aria2Status -from bot.helper.telegram_helper.message_utils import ( +from ..task_utils.status_utils.aria2_status import Aria2Status +from ..telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendMessage, - deleteMessage, + delete_message, + send_message, update_status_message, ) -@new_thread -async def _onDownloadStarted(api, gid): +@loop_thread +async def _on_download_started(api, gid): download = await sync_to_async( api.get_download, gid @@ -49,18 +49,18 @@ async def _onDownloadStarted(api, gid): if download.is_metadata: LOGGER.info(f"onDownloadStarted: {gid} METADATA") await sleep(1) - if task := await getTaskByGid(gid): - task.listener.isTorrent = True + if task := await get_task_by_gid(gid): + task.listener.is_torrent = True if task.listener.select: metamsg = "Downloading Metadata, wait then you can select files. Use torrent file to avoid this wait." - meta = await sendMessage( + meta = await send_message( task.listener.message, metamsg ) while True: await sleep(0.5) if download.is_removed or download.followed_by_ids: - await deleteMessage(meta) + await delete_message(meta) break await sync_to_async(download.update) return @@ -68,7 +68,7 @@ async def _onDownloadStarted(api, gid): LOGGER.info(f"onAria2DownloadStarted: {download.name} - Gid: {gid}") await sleep(1) - if task := await getTaskByGid(gid): + if task := await get_task_by_gid(gid): download = await sync_to_async( api.get_download, gid @@ -76,10 +76,10 @@ async def _onDownloadStarted(api, gid): await sleep(2) await sync_to_async(download.update) task.listener.name = download.name - task.listener.isTorrent = download.is_torrent + task.listener.is_torrent = download.is_torrent msg, button = await stop_duplicate_check(task.listener) if msg: - await task.listener.onDownloadError( + await task.listener.on_download_error( msg, button ) @@ -111,7 +111,7 @@ async def _onDownloadStarted(api, gid): if not task.listener.select: if limit_exceeded := await limit_checker(task.listener): LOGGER.info(f"Aria2 Limit Exceeded: {task.listener.name} | {get_readable_file_size(task.listener.size)}") - amsg = await task.listener.onDownloadError(limit_exceeded) + amsg = await task.listener.on_download_error(limit_exceeded) await sync_to_async( api.remove, [download], @@ -140,7 +140,7 @@ async def _onDownloadStarted(api, gid): LOGGER.info( f"Task is slower than minimum download speed: {task.listener.name} | {get_readable_file_size(dl_speed)}ps" ) - smsg = await task.listener.onDownloadError(min_speed) + smsg = await task.listener.on_download_error(min_speed) await sync_to_async( api.remove, [download], @@ -154,8 +154,8 @@ async def _onDownloadStarted(api, gid): ) -@new_thread -async def _onDownloadComplete(api, gid): +@loop_thread +async def _on_download_complete(api, gid): try: download = await sync_to_async( api.get_download, @@ -168,8 +168,8 @@ async def _onDownloadComplete(api, gid): if download.followed_by_ids: new_gid = download.followed_by_ids[0] LOGGER.info(f"Gid changed from {gid} to {new_gid}") - if task := await getTaskByGid(new_gid): - task.listener.isTorrent = True + if task := await get_task_by_gid(new_gid): + task.listener.is_torrent = True if ( config_dict["BASE_URL"] and task.listener.select @@ -181,20 +181,20 @@ async def _onDownloadComplete(api, gid): ) SBUTTONS = bt_selection_buttons(new_gid) msg = "Your download paused. Choose files then press Done Selecting button to start downloading." - await sendMessage( + await send_message( task.listener.message, msg, SBUTTONS ) elif download.is_torrent: - if task := await getTaskByGid(gid): - task.listener.isTorrent = True + if task := await get_task_by_gid(gid): + task.listener.is_torrent = True if hasattr( task, "seeding" ) and task.seeding: - LOGGER.info(f"Cancelling Seed: {download.name} onDownloadComplete") - await task.listener.onUploadError( + LOGGER.info(f"Cancelling Seed: {download.name} on_download_complete") + await task.listener.on_upload_error( f"Seeding stopped with Ratio: {task.ratio()} and Time: {task.seeding_time()}" ) await sync_to_async( @@ -204,10 +204,10 @@ async def _onDownloadComplete(api, gid): files=True ) else: - LOGGER.info(f"onDownloadComplete: {download.name} - Gid: {gid}") - if task := await getTaskByGid(gid): - await task.listener.onDownloadComplete() - if Intervals["stopAll"]: + LOGGER.info(f"on_download_complete: {download.name} - Gid: {gid}") + if task := await get_task_by_gid(gid): + await task.listener.on_download_complete() + if intervals["stopAll"]: return await sync_to_async( api.remove, @@ -216,17 +216,17 @@ async def _onDownloadComplete(api, gid): files=True ) -@new_thread -async def _onBtDownloadComplete(api, gid): +@loop_thread +async def _on_bt_download_complete(api, gid): seed_start_time = time() await sleep(1) download = await sync_to_async( api.get_download, gid ) - LOGGER.info(f"onBtDownloadComplete: {download.name} - Gid: {gid}") - if task := await getTaskByGid(gid): - task.listener.isTorrent = True + LOGGER.info(f"on_bt_download_complete: {download.name} - Gid: {gid}") + if task := await get_task_by_gid(gid): + task.listener.is_torrent = True if task.listener.select: res = download.files for file_o in res: @@ -259,48 +259,52 @@ async def _onBtDownloadComplete(api, gid): ) except Exception as e: LOGGER.error(f"{e} GID: {gid}") - await task.listener.onDownloadComplete() - if Intervals["stopAll"]: + await task.listener.on_download_complete() + if intervals["stopAll"]: return await sync_to_async(download.update) - if task.listener.seed: - if download.is_complete: - if await getTaskByGid(gid): - LOGGER.info(f"Cancelling Seed: {download.name}") - await task.listener.onUploadError( - f"Seeding stopped with Ratio: {task.ratio()} and Time: {task.seeding_time()}" - ) + if ( + task.listener.seed + and download.is_complete + and await get_task_by_gid(gid) + ): + LOGGER.info(f"Cancelling Seed: {download.name}") + await task.listener.on_upload_error( + f"Seeding stopped with Ratio: {task.ratio()} and Time: {task.seeding_time()}" + ) + await sync_to_async( + api.remove, + [download], + force=True, + files=True + ) + elif ( + task.listener.seed + and download.is_complete + and not await get_task_by_gid(gid) + ): + pass + elif ( + task.listener.seed + and not task.listener.is_cancelled + ): + async with task_dict_lock: + if task.listener.mid not in task_dict: await sync_to_async( api.remove, [download], force=True, files=True ) - elif not task.listener.isCancelled: - async with task_dict_lock: - if task.listener.mid not in task_dict: - await sync_to_async( - api.remove, - [download], - force=True, - files=True - ) - return - task_dict[task.listener.mid] = Aria2Status( - task.listener, - gid, - True - ) - task_dict[task.listener.mid].start_time = seed_start_time - LOGGER.info(f"Seeding started: {download.name} - Gid: {gid}") - await update_status_message(task.listener.message.chat.id) - else: - await sync_to_async( - api.remove, - [download], - force=True, - files=True + return + task_dict[task.listener.mid] = Aria2Status( + task.listener, + gid, + True ) + task_dict[task.listener.mid].start_time = seed_start_time + LOGGER.info(f"Seeding started: {download.name} - Gid: {gid}") + await update_status_message(task.listener.message.chat.id) else: await sync_to_async( api.remove, @@ -310,16 +314,16 @@ async def _onBtDownloadComplete(api, gid): ) -@new_thread -async def _onDownloadStopped(api, gid): +@loop_thread +async def _on_download_stopped(api, gid): await sleep(4) - if task := await getTaskByGid(gid): - await task.listener.onDownloadError("Dead torrent!") + if task := await get_task_by_gid(gid): + await task.listener.on_download_error("Dead torrent!") -@new_thread -async def _onDownloadError(api, gid): - LOGGER.info(f"onDownloadError: {gid}") +@loop_thread +async def _on_download_error(api, gid): + LOGGER.info(f"on_download_error: {gid}") error = "None" try: download = await sync_to_async( @@ -332,17 +336,17 @@ async def _onDownloadError(api, gid): LOGGER.info(f"Download Error: {error}") except: pass - if task := await getTaskByGid(gid): - await task.listener.onDownloadError(error) + if task := await get_task_by_gid(gid): + await task.listener.on_download_error(error) def start_aria2_listener(): aria2.listen_to_notifications( threaded=False, - on_download_start=_onDownloadStarted, - on_download_error=_onDownloadError, - on_download_stop=_onDownloadStopped, - on_download_complete=_onDownloadComplete, - on_bt_download_complete=_onBtDownloadComplete, + on_download_start=_on_download_started, + on_download_error=_on_download_error, + on_download_stop=_on_download_stopped, + on_download_complete=_on_download_complete, + on_bt_download_complete=_on_bt_download_complete, timeout=60, ) diff --git a/bot/helper/listeners/direct_listener.py b/bot/helper/listeners/direct_listener.py index 197b9ed224dc..d60b3b70718c 100644 --- a/bot/helper/listeners/direct_listener.py +++ b/bot/helper/listeners/direct_listener.py @@ -4,7 +4,7 @@ LOGGER, aria2 ) -from bot.helper.ext_utils.bot_utils import ( +from ..ext_utils.bot_utils import ( async_to_sync, sync_to_async ) @@ -42,7 +42,7 @@ def speed(self): def download(self, contents): self.is_downloading = True for content in contents: - if self.listener.isCancelled: + if self.listener.is_cancelled: break if content["path"]: self._a2c_opt["dir"] = f"{self._path}/{content['path']}" @@ -62,7 +62,7 @@ def download(self, contents): continue self.download_task = self.download_task.live while True: - if self.listener.isCancelled: + if self.listener.is_cancelled: if self.download_task: self.download_task.remove( True, @@ -86,20 +86,20 @@ def download(self, contents): break sleep(1) self.download_task = None - if self.listener.isCancelled: + if self.listener.is_cancelled: return if self._failed == len(contents): async_to_sync( - self.listener.onDownloadError, + self.listener.on_download_error, "All files are failed to download!" ) return - async_to_sync(self.listener.onDownloadComplete) + async_to_sync(self.listener.on_download_complete) async def cancel_task(self): - self.listener.isCancelled = True + self.listener.is_cancelled = True LOGGER.info(f"Cancelling Download: {self.listener.name}") - await self.listener.onDownloadError("Download Cancelled by User!") + await self.listener.on_download_error("Download Cancelled by User!") if self.download_task: await sync_to_async( self.download_task.remove, diff --git a/bot/helper/listeners/jdownloader_listener.py b/bot/helper/listeners/jdownloader_listener.py index 68e997318b4a..0122d6fd2483 100644 --- a/bot/helper/listeners/jdownloader_listener.py +++ b/bot/helper/listeners/jdownloader_listener.py @@ -4,17 +4,17 @@ ) from bot import ( - Intervals, + LOGGER, jd_lock, jd_downloads, - LOGGER + intervals ) -from bot.helper.ext_utils.bot_utils import ( +from ..ext_utils.bot_utils import ( new_task, retry_function ) -from bot.helper.ext_utils.jdownloader_booter import jdownloader -from bot.helper.ext_utils.status_utils import getTaskByGid +from ..ext_utils.jdownloader_booter import jdownloader +from ..ext_utils.status_utils import get_task_by_gid @new_task @@ -24,7 +24,7 @@ async def update_download(gid, value): del value["ids"][0] new_gid = value["ids"][0] jd_downloads[new_gid] = value - if task := await getTaskByGid(f"{gid}"): + if task := await get_task_by_gid(f"{gid}"): task._gid = new_gid async with jd_lock: del jd_downloads[gid] @@ -34,21 +34,21 @@ async def update_download(gid, value): @new_task async def remove_download(gid): - if Intervals["stopAll"]: + if intervals["stopAll"]: return await retry_function( jdownloader.device.downloads.remove_links, # type: ignore package_ids=[gid], ) - if task := await getTaskByGid(f"{gid}"): - await task.listener.onDownloadError("Download removed manually!") + if task := await get_task_by_gid(f"{gid}"): + await task.listener.on_download_error("Download removed manually!") async with jd_lock: del jd_downloads[gid] @new_task -async def _onDownloadComplete(gid): - if task := await getTaskByGid(f"{gid}"): +async def _on_download_complete(gid): + if task := await get_task_by_gid(f"{gid}"): if task.listener.select: async with jd_lock: await retry_function( @@ -58,8 +58,8 @@ async def _onDownloadComplete(gid): "SELECTED", package_ids=jd_downloads[gid]["ids"], ) - await task.listener.onDownloadComplete() - if Intervals["stopAll"]: + await task.listener.on_download_complete() + if intervals["stopAll"]: return async with jd_lock: if gid in jd_downloads: @@ -76,7 +76,7 @@ async def _jd_listener(): await sleep(3) async with jd_lock: if len(jd_downloads) == 0: - Intervals["jd"] = "" + intervals["jd"] = "" break try: await wait_for( @@ -122,9 +122,9 @@ async def _jd_listener(): ): cdi = jd_downloads[k]["ids"] if len(cdi) > 1: - update_download(k, v) # type: ignore + await update_download(k, v) else: - remove_download(k) # type: ignore + await remove_download(k) else: for ( index, @@ -146,10 +146,10 @@ async def _jd_listener(): ) if is_finished: jd_downloads[gid]["status"] = "done" - _onDownloadComplete(gid) # type: ignore + await _on_download_complete(gid) # type: ignore -async def onDownloadStart(): +async def on_download_start(): async with jd_lock: - if not Intervals["jd"]: - Intervals["jd"] = _jd_listener() + if not intervals["jd"]: + intervals["jd"] = await _jd_listener() diff --git a/bot/helper/listeners/mega_listener.py b/bot/helper/listeners/mega_listener.py index f86f67bbe9f9..30146549cd77 100644 --- a/bot/helper/listeners/mega_listener.py +++ b/bot/helper/listeners/mega_listener.py @@ -1,23 +1,29 @@ from threading import Event + from mega import ( MegaApi, - MegaListener, MegaError, + MegaListener, MegaRequest, MegaTransfer ) -from bot.helper.ext_utils.bot_utils import ( + +from bot import LOGGER +from ..ext_utils.bot_utils import ( async_to_sync, sync_to_async ) -from bot import LOGGER class AsyncExecutor: def __init__(self): self.continue_event = Event() - def do(self, function, args): + def do( + self, + function, + args + ): self.continue_event.clear() function(*args) self.continue_event.wait() @@ -127,7 +133,7 @@ def onRequestTemporaryError( if not self.is_cancelled: self.is_cancelled = True async_to_sync( - self.listener.onDownloadError, + self.listener.on_download_error, f"RequestTempError: {error.toString()}" ) self.error = error.toString() @@ -164,7 +170,7 @@ def onTransferFinish( transfer.getFileName() == self._name ) ): - async_to_sync(self.listener.onDownloadComplete) + async_to_sync(self.listener.on_download_complete) self.continue_event.set() except Exception as e: LOGGER.error(e) @@ -188,4 +194,4 @@ def onTransferTemporaryError( async def cancel_task(self): self.is_cancelled = True - await self.listener.onDownloadError("Download Canceled by user") + await self.listener.on_download_error("Download Canceled by user") diff --git a/bot/helper/listeners/nzb_listener.py b/bot/helper/listeners/nzb_listener.py index c1e179a52585..947332637aa0 100644 --- a/bot/helper/listeners/nzb_listener.py +++ b/bot/helper/listeners/nzb_listener.py @@ -4,24 +4,23 @@ ) from bot import ( - Intervals, - sabnzbd_client, + LOGGER, + intervals, nzb_jobs, nzb_listener_lock, + sabnzbd_client, task_dict_lock, - LOGGER, - bot_loop, ) -from bot.helper.ext_utils.bot_utils import new_task -from bot.helper.ext_utils.status_utils import ( - getTaskByGid, +from ..ext_utils.bot_utils import new_task +from ..ext_utils.status_utils import ( + get_task_by_gid, speed_string_to_bytes ) -from bot.helper.ext_utils.task_manager import ( +from ..ext_utils.task_manager import ( limit_checker, stop_duplicate_check ) -from bot.helper.telegram_helper.message_utils import auto_delete_message +from ..telegram_helper.message_utils import auto_delete_message async def _remove_job(nzo_id, mid): @@ -46,12 +45,12 @@ async def _remove_job(nzo_id, mid): @new_task -async def _onDownloadError(err, nzo_id, button=None): - task = await getTaskByGid(nzo_id) +async def _on_download_error(err, nzo_id, button=None): + task = await get_task_by_gid(nzo_id) await task.update() # type: ignore LOGGER.info(f"Cancelling Download: {task.name()}") # type: ignore await gather( - task.listener.onDownloadError( # type: ignore + task.listener.on_download_error( # type: ignore err, button ), @@ -72,14 +71,14 @@ async def _onDownloadError(err, nzo_id, button=None): @new_task async def _change_status(nzo_id, status): - task = await getTaskByGid(nzo_id) + task = await get_task_by_gid(nzo_id) async with task_dict_lock: task.cstatus = status # type: ignore @new_task async def _stop_duplicate(nzo_id): - task = await getTaskByGid(nzo_id) + task = await get_task_by_gid(nzo_id) await task.update() # type: ignore task.listener.name = task.name() # type: ignore ( @@ -87,7 +86,7 @@ async def _stop_duplicate(nzo_id): button ) = await stop_duplicate_check(task.listener) # type: ignore if msg: - _onDownloadError( + _on_download_error( msg, nzo_id, button @@ -96,17 +95,17 @@ async def _stop_duplicate(nzo_id): @new_task async def _size_checker(nzo_id): - task = await getTaskByGid(nzo_id) + task = await get_task_by_gid(nzo_id) await task.update() # type: ignore task.listener.size = speed_string_to_bytes(task.size()) # type: ignore if limit_exceeded := await limit_checker( task.listener, # type: ignore - isNzb=True + is_nzb=True ): LOGGER.info( f"NZB Limit Exceeded: {task.name()} | {task.size()}" # type: ignore ) - nmsg = _onDownloadError( + nmsg = _on_download_error( limit_exceeded, nzo_id ) @@ -117,10 +116,10 @@ async def _size_checker(nzo_id): @new_task -async def _onDownloadComplete(nzo_id): - task = await getTaskByGid(nzo_id) - await task.listener.onDownloadComplete() # type: ignore - if Intervals["stopAll"]: +async def _on_download_complete(nzo_id): + task = await get_task_by_gid(nzo_id) + await task.listener.on_download_complete() # type: ignore + if intervals["stopAll"]: return await _remove_job( nzo_id, @@ -128,14 +127,15 @@ async def _onDownloadComplete(nzo_id): ) +@new_task async def _nzb_listener(): - while not Intervals["stopAll"]: + while not intervals["stopAll"]: async with nzb_listener_lock: try: jobs = (await sabnzbd_client.get_history())["history"]["slots"] downloads = (await sabnzbd_client.get_downloads())["queue"]["slots"] if len(nzb_jobs) == 0: - Intervals["nzb"] = "" + intervals["nzb"] = "" break for job in jobs: nzo_id = job["nzo_id"] @@ -144,10 +144,10 @@ async def _nzb_listener(): if job["status"] == "Completed": if not nzb_jobs[nzo_id]["uploaded"]: nzb_jobs[nzo_id]["uploaded"] = True - _onDownloadComplete(nzo_id) # type: ignore + await _on_download_complete(nzo_id) # type: ignore nzb_jobs[nzo_id]["status"] = "Completed" elif job["status"] == "Failed": - _onDownloadError( + await _on_download_error( job["fail_message"], nzo_id ) # type: ignore @@ -160,7 +160,7 @@ async def _nzb_listener(): "Extracting", ]: if job["status"] != nzb_jobs[nzo_id]["status"]: - _change_status( + await _change_status( nzo_id, job["status"] ) # type: ignore @@ -174,19 +174,19 @@ async def _nzb_listener(): and not dl["filename"].startswith("Trying") ): nzb_jobs[nzo_id]["stop_dup_check"] = True - _stop_duplicate(nzo_id) # type: ignore - _size_checker(nzo_id) # type: ignore + await _stop_duplicate(nzo_id) # type: ignore + await _size_checker(nzo_id) # type: ignore except Exception as e: LOGGER.error(str(e)) await sleep(3) -async def onDownloadStart(nzo_id): +async def on_download_start(nzo_id): async with nzb_listener_lock: nzb_jobs[nzo_id] = { "uploaded": False, "stop_dup_check": False, "status": "Downloading", } - if not Intervals["nzb"]: - Intervals["nzb"] = bot_loop.create_task(_nzb_listener()) + if not intervals["nzb"]: + intervals["nzb"] = await _nzb_listener() diff --git a/bot/helper/listeners/qbit_listener.py b/bot/helper/listeners/qbit_listener.py index 0cbe41c3fd6c..7a5c7fcc2212 100644 --- a/bot/helper/listeners/qbit_listener.py +++ b/bot/helper/listeners/qbit_listener.py @@ -6,33 +6,32 @@ from time import time from bot import ( - task_dict, - task_dict_lock, - Intervals, - qbittorrent_client, + LOGGER, config_dict, - QbTorrents, + intervals, qb_listener_lock, - LOGGER, - bot_loop, + qbittorrent_client, + qb_torrents, + task_dict, + task_dict_lock ) -from bot.helper.ext_utils.bot_utils import ( +from ..ext_utils.bot_utils import ( new_task, sync_to_async ) -from bot.helper.ext_utils.files_utils import clean_unwanted -from bot.helper.ext_utils.status_utils import ( +from ..ext_utils.files_utils import clean_unwanted +from ..ext_utils.status_utils import ( get_readable_file_size, get_readable_time, - getTaskByGid + get_task_by_gid ) -from bot.helper.ext_utils.task_manager import ( +from ..ext_utils.task_manager import ( check_avg_speed, limit_checker, stop_duplicate_check ) -from bot.helper.task_utils.status_utils.qbit_status import QbittorrentStatus -from bot.helper.telegram_helper.message_utils import ( +from ..task_utils.status_utils.qbit_status import QbittorrentStatus +from ..telegram_helper.message_utils import ( auto_delete_message, delete_links, update_status_message @@ -46,8 +45,8 @@ async def _remove_torrent(hash_, tag): delete_files=True ) async with qb_listener_lock: - if tag in QbTorrents: - del QbTorrents[tag] + if tag in qb_torrents: + del qb_torrents[tag] await sync_to_async( qbittorrent_client.torrents_delete_tags, tags=tag @@ -55,11 +54,11 @@ async def _remove_torrent(hash_, tag): @new_task -async def _onDownloadError(err, tor, button=None): +async def _on_download_error(err, tor, button=None): LOGGER.info(f"Cancelling Download: {tor.name}") ext_hash = tor.hash - if task := await getTaskByGid(ext_hash[:12]): - await task.listener.onDownloadError( + if task := await get_task_by_gid(ext_hash[:12]): + await task.listener.on_download_error( err, button ) @@ -75,12 +74,12 @@ async def _onDownloadError(err, tor, button=None): @new_task -async def _onSeedFinish(tor): +async def _on_seed_finish(tor): ext_hash = tor.hash LOGGER.info(f"Cancelling Seed: {tor.name}") - if task := await getTaskByGid(ext_hash[:12]): + if task := await get_task_by_gid(ext_hash[:12]): msg = f"Seeding stopped with Ratio: {round(tor.ratio, 3)} and Time: {get_readable_time(tor.seeding_time)}" - await task.listener.onUploadError(msg) + await task.listener.on_upload_error(msg) await _remove_torrent( ext_hash, tor.tags @@ -89,8 +88,8 @@ async def _onSeedFinish(tor): @new_task async def _stop_duplicate(tor): - if task := await getTaskByGid(tor.hash[:12]): - if task.listener.stopDuplicate: # type: ignore + if task := await get_task_by_gid(tor.hash[:12]): + if task.listener.stop_duplicate: # type: ignore task.listener.name = tor.content_path.rsplit( # type: ignore "/", 1 @@ -103,7 +102,7 @@ async def _stop_duplicate(tor): button ) = await stop_duplicate_check(task.listener) # type: ignore if msg: - _onDownloadError( + await _on_download_error( msg, tor, button @@ -112,16 +111,16 @@ async def _stop_duplicate(tor): @new_task async def _size_checked(tor): - if task := await getTaskByGid(tor.hash[:12]): + if task := await get_task_by_gid(tor.hash[:12]): task.listener.size = tor.size # type: ignore if limit_exceeded := await limit_checker( task.listener, # type: ignore - isTorrent=True + is_torrent=True ): LOGGER.info( f"qBit Limit Exceeded: {task.listener.name} | {get_readable_file_size(task.listener.size)}" # type: ignore ) - qmsg = _onDownloadError( + qmsg = await _on_download_error( limit_exceeded, tor ) @@ -134,7 +133,7 @@ async def _size_checked(tor): @new_task async def _avg_speed_check(tor): - if task := await getTaskByGid(tor.hash[:12]): + if task := await get_task_by_gid(tor.hash[:12]): if config_dict["AVG_SPEED"]: start_time = time() total_speed = 0 @@ -158,7 +157,7 @@ async def _avg_speed_check(tor): LOGGER.info( f"Task is slower than minimum download speed: {task.listener.name} | {get_readable_file_size(dl_speed)}ps" ) - qmsg = _onDownloadError( + qmsg = await _on_download_error( min_speed, tor ) @@ -170,10 +169,10 @@ async def _avg_speed_check(tor): @new_task -async def _onDownloadComplete(tor): +async def _on_download_complete(tor): ext_hash = tor.hash tag = tor.tags - if task := await getTaskByGid(tor.hash[:12]): + if task := await get_task_by_gid(tor.hash[:12]): if not task.listener.seed: # type: ignore await sync_to_async( qbittorrent_client.torrents_pause, @@ -198,12 +197,12 @@ async def _onDownloadComplete(tor): await remove(f"{path}/{f.name}") except: pass - await task.listener.onDownloadComplete() # type: ignore - if Intervals["stopAll"]: + await task.listener.on_download_complete() # type: ignore + if intervals["stopAll"]: return if ( task.listener.seed and not # type: ignore - task.listener.isCancelled # type: ignore + task.listener.is_cancelled # type: ignore ): async with task_dict_lock: if task.listener.mid in task_dict: # type: ignore @@ -222,7 +221,7 @@ async def _onDownloadComplete(tor): return if ( task.listener.seed and not - task.listener.isCancelled + task.listener.is_cancelled ): async with task_dict_lock: if task.listener.mid in task_dict: @@ -240,8 +239,8 @@ async def _onDownloadComplete(tor): ) return async with qb_listener_lock: - if tag in QbTorrents: - QbTorrents[tag]["seeding"] = True + if tag in qb_torrents: + qb_torrents[tag]["seeding"] = True else: return await update_status_message(task.listener.message.chat.id) @@ -258,27 +257,28 @@ async def _onDownloadComplete(tor): ) +@new_task async def _qb_listener(): while True: async with qb_listener_lock: try: torrents = await sync_to_async(qbittorrent_client.torrents_info) if len(torrents) == 0: - Intervals["qb"] = "" + intervals["qb"] = "" break for tor_info in torrents: tag = tor_info.tags - if tag not in QbTorrents: + if tag not in qb_torrents: continue state = tor_info.state if state == "metaDL": TORRENT_TIMEOUT = config_dict["TORRENT_TIMEOUT"] - QbTorrents[tag]["stalled_time"] = time() + qb_torrents[tag]["stalled_time"] = time() if ( TORRENT_TIMEOUT and time() - tor_info.added_on >= TORRENT_TIMEOUT ): - _onDownloadError( + await _on_download_error( "Dead Torrent!", tor_info ) # type: ignore @@ -288,16 +288,16 @@ async def _qb_listener(): torrent_hashes=tor_info.hash, ) elif state == "downloading": - QbTorrents[tag]["stalled_time"] = time() - if not QbTorrents[tag]["stop_dup_check"]: - QbTorrents[tag]["stop_dup_check"] = True - _stop_duplicate(tor_info) # type: ignore - _size_checked(tor_info) # type: ignore - _avg_speed_check(tor_info) # type: ignore + qb_torrents[tag]["stalled_time"] = time() + if not qb_torrents[tag]["stop_dup_check"]: + qb_torrents[tag]["stop_dup_check"] = True + await _stop_duplicate(tor_info) # type: ignore + await _size_checked(tor_info) # type: ignore + await _avg_speed_check(tor_info) # type: ignore elif state == "stalledDL": TORRENT_TIMEOUT = config_dict["TORRENT_TIMEOUT"] if ( - not QbTorrents[tag]["rechecked"] + not qb_torrents[tag]["rechecked"] and 0.99989999999999999 < tor_info.progress < 1 ): msg = f"Force recheck - Name: {tor_info.name} Hash: " @@ -308,13 +308,13 @@ async def _qb_listener(): qbittorrent_client.torrents_recheck, torrent_hashes=tor_info.hash, ) - QbTorrents[tag]["rechecked"] = True + qb_torrents[tag]["rechecked"] = True elif ( TORRENT_TIMEOUT - and time() - QbTorrents[tag]["stalled_time"] + and time() - qb_torrents[tag]["stalled_time"] >= TORRENT_TIMEOUT ): - _onDownloadError( + await _on_download_error( "Dead Torrent!", tor_info ) # type: ignore @@ -329,13 +329,13 @@ async def _qb_listener(): torrent_hashes=tor_info.hash, ) elif state == "error": - _onDownloadError( + await _on_download_error( "No enough space for this torrent on device", tor_info # type: ignore ) elif ( tor_info.completion_on != 0 - and not QbTorrents[tag]["uploaded"] + and not qb_torrents[tag]["uploaded"] and state not in [ "checkingUP", @@ -343,33 +343,33 @@ async def _qb_listener(): "checkingResumeData" ] ): - QbTorrents[tag]["uploaded"] = True - _onDownloadComplete(tor_info) # type: ignore + qb_torrents[tag]["uploaded"] = True + await _on_download_complete(tor_info) # type: ignore elif ( state in [ "pausedUP", "pausedDL" - ] and QbTorrents[tag]["seeding"] + ] and qb_torrents[tag]["seeding"] ): - QbTorrents[tag]["seeding"] = False - _onSeedFinish(tor_info) # type: ignore + qb_torrents[tag]["seeding"] = False + await _on_seed_finish(tor_info) # type: ignore await sleep(0.5) except Exception as e: LOGGER.error(str(e)) await sleep(3) -async def onDownloadStart(tag): +async def on_download_start(tag): try: async with qb_listener_lock: - QbTorrents[tag] = { + qb_torrents[tag] = { "stalled_time": time(), "stop_dup_check": False, "rechecked": False, "uploaded": False, "seeding": False, } - if not Intervals["qb"]: - Intervals["qb"] = bot_loop.create_task(_qb_listener()) + if not intervals["qb"]: + intervals["qb"] = await _qb_listener() except Exception as e: LOGGER.error(str(e)) diff --git a/bot/helper/listeners/task_listener.py b/bot/helper/listeners/task_listener.py index 64c41758e912..aa8b95fb79b9 100644 --- a/bot/helper/listeners/task_listener.py +++ b/bot/helper/listeners/task_listener.py @@ -6,62 +6,61 @@ ) from aioshutil import move from asyncio import ( - sleep, - gather + gather, + sleep ) from html import escape from requests import utils as rutils from time import time from bot import ( - Intervals, - aria2, - DOWNLOAD_DIR, - task_dict, - task_dict_lock, LOGGER, - DATABASE_URL, + aria2, config_dict, - non_queued_up, + intervals, non_queued_dl, - queued_up, + non_queued_up, queued_dl, + queued_up, queue_dict_lock, + same_directory_lock, + task_dict, + task_dict_lock ) -from bot.helper.common import TaskConfig -from bot.helper.ext_utils.bot_utils import ( +from ..common import TaskConfig +from ..ext_utils.bot_utils import ( extra_btns, sync_to_async ) -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.ext_utils.files_utils import ( - get_path_size, +from ..ext_utils.db_handler import database +from ..ext_utils.files_utils import ( clean_download, clean_target, - join_files, + get_path_size, + join_files ) -from bot.helper.ext_utils.links_utils import is_gdrive_id -from bot.helper.ext_utils.status_utils import ( +from ..ext_utils.links_utils import is_gdrive_id +from ..ext_utils.status_utils import ( get_readable_file_size, get_readable_time ) -from bot.helper.ext_utils.task_manager import ( - start_from_queued, - check_running_tasks +from ..ext_utils.task_manager import ( + check_running_tasks, + start_from_queued ) -from bot.helper.task_utils.gdrive_utils.upload import gdUpload -from bot.helper.task_utils.rclone_utils.transfer import RcloneTransferHelper -from bot.helper.task_utils.status_utils.gdrive_status import GdriveStatus -from bot.helper.task_utils.status_utils.queue_status import QueueStatus -from bot.helper.task_utils.status_utils.rclone_status import RcloneStatus -from bot.helper.task_utils.status_utils.telegram_status import TelegramStatus -from bot.helper.task_utils.telegram_uploader import TgUploader -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.message_utils import ( +from ..task_utils.gdrive_utils.upload import GoogleDriveUpload +from ..task_utils.rclone_utils.transfer import RcloneTransferHelper +from ..task_utils.status_utils.gdrive_status import GoogleDriveStatus +from ..task_utils.status_utils.queue_status import QueueStatus +from ..task_utils.status_utils.rclone_status import RcloneStatus +from ..task_utils.status_utils.telegram_status import TelegramStatus +from ..task_utils.telegram_uploader import TelegramUploader +from ..telegram_helper.button_build import ButtonMaker +from ..telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendMessage, delete_status, + send_message, update_status_message, ) @@ -73,10 +72,10 @@ def __init__(self): async def clean(self): try: - if st := Intervals["status"]: + if st := intervals["status"]: for intvl in list(st.values()): intvl.cancel() - Intervals["status"].clear() + intervals["status"].clear() await gather( sync_to_async(aria2.purge), delete_status() @@ -84,70 +83,75 @@ async def clean(self): except: pass - def removeFromSameDir(self): + def remove_from_same_dir(self): if ( - self.sameDir # type: ignore + self.same_dir # type: ignore and self.mid - in self.sameDir["tasks"] # type: ignore + in self.same_dir["tasks"] # type: ignore ): - self.sameDir["tasks"].remove(self.mid) # type: ignore - self.sameDir["total"] -= 1 # type: ignore + self.same_dir["tasks"].remove(self.mid) # type: ignore + self.same_dir["total"] -= 1 # type: ignore - async def onDownloadStart(self): + async def on_download_start(self): if ( - DATABASE_URL + config_dict["DATABASE_URL"] and config_dict["STOP_DUPLICATE_TASKS"] and self.raw_url ): - await DbManager().add_download_url( + await database.add_download_url( self.raw_url, self.tag ) if ( - self.isSuperChat + self.is_super_chat and config_dict["INCOMPLETE_TASK_NOTIFIER"] - and DATABASE_URL + and config_dict["DATABASE_URL"] ): - await DbManager().add_incomplete_task( + await database.add_incomplete_task( self.message.chat.id, # type: ignore self.message.link, # type: ignore self.tag ) - async def onDownloadComplete(self): + async def on_download_complete(self): multi_links = False if ( - DATABASE_URL + config_dict["DATABASE_URL"] and config_dict["STOP_DUPLICATE_TASKS"] and self.raw_url ): - await DbManager().remove_download(self.raw_url) + await database.remove_download(self.raw_url) if ( - self.sameDir # type: ignore + self.same_dir # type: ignore and self.mid - in self.sameDir["tasks"] # type: ignore + in self.same_dir["tasks"] # type: ignore ): - while not ( - self.sameDir["total"] in [1, 0] # type: ignore - or self.sameDir["total"] > 1 # type: ignore - and len(self.sameDir["tasks"]) > 1 # type: ignore - ): - await sleep(0.5) - + async with same_directory_lock: + while True: + async with task_dict_lock: + if self.mid not in self.same_dir["tasks"]: # type: ignore + return + if ( + self.mid in self.same_dir["tasks"] and ( # type: ignore + self.same_dir["total"] == 1 # type: ignore + or len(self.same_dir["tasks"]) > 1 # type: ignore + ) + ): + break + await sleep(1) + await sleep(2) # wait for qbitorrent or any other package to rearrange files and folders like removing !qB async with task_dict_lock: if ( - self.sameDir # type: ignore - and self.sameDir["total"] > 1 # type: ignore + self.same_dir # type: ignore + and self.same_dir["total"] > 1 # type: ignore and self.mid - in self.sameDir["tasks"] # type: ignore + in self.same_dir["tasks"] # type: ignore ): - self.sameDir["tasks"].remove(self.mid) # type: ignore - self.sameDir["total"] -= 1 # type: ignore - folder_name = self.sameDir["name"] # type: ignore + self.same_dir["tasks"].remove(self.mid) # type: ignore + self.same_dir["total"] -= 1 # type: ignore + folder_name = self.same_dir["name"] # type: ignore spath = f"{self.dir}{folder_name}" - des_path = ( - f"{DOWNLOAD_DIR}{list(self.sameDir["tasks"])[0]}{folder_name}" # type: ignore - ) + des_path = f"{config_dict["DOWNLOAD_DIR"]}{list(self.same_dir["tasks"])[0]}{folder_name}" # type: ignore await makedirs( des_path, exist_ok=True @@ -170,14 +174,20 @@ async def onDownloadComplete(self): f"{des_path}/{item}" ) multi_links = True + elif ( + self.same_dir # type: ignore + and self.mid + not in self.same_dir["tasks"] # type: ignore + ): + return download = task_dict[self.mid] self.name = download.name() gid = download.gid() LOGGER.info(f"Download completed: {self.name}") if not ( - self.isTorrent or - self.isQbit + self.is_torrent or + self.is_qbit ): self.seed = False @@ -186,9 +196,12 @@ async def onDownloadComplete(self): files_to_delete = [] if multi_links: - await self.onUploadError("Downloaded! Waiting for other tasks...") + await self.on_upload_error(f"{self.name} Downloaded!\n\nWaiting for other tasks to finish...") return + if self.same_dir: # type: ignore + self.name = self.same_dir["name"].split("/")[-1] # type: ignore + if not await aiopath.exists(f"{self.dir}/{self.name}"): try: files = await listdir(self.dir) @@ -196,7 +209,7 @@ async def onDownloadComplete(self): if self.name == "yt-dlp-thumb": self.name = files[0] except Exception as e: - await self.onUploadError(str(e)) + await self.on_upload_error(str(e)) return up_path = f"{self.dir}/{self.name}" @@ -210,12 +223,12 @@ async def onDownloadComplete(self): if self.join and await aiopath.isdir(up_path): await join_files(up_path) - if self.extract and not self.isNzb: - up_path = await self.proceedExtract( + if self.extract and not self.is_nzb: + up_path = await self.proceed_extract( up_path, gid ) - if self.isCancelled: + if self.is_cancelled: return ( up_dir, @@ -226,15 +239,15 @@ async def onDownloadComplete(self): ) self.size = await get_path_size(up_dir) - if self.nameSub: + if self.name_sub: up_path = await self.substitute(up_path) - if self.isCancelled: + if self.is_cancelled: return self.name = up_path.rsplit("/", 1)[1] - if self.screenShots: - up_path = await self.generateScreenshots(up_path) - if self.isCancelled: + if self.screen_shots: + up_path = await self.generate_screenshots(up_path) + if self.is_cancelled: return ( up_dir, @@ -245,15 +258,15 @@ async def onDownloadComplete(self): ) self.size = await get_path_size(up_dir) - if self.convertAudio or self.convertVideo: - up_path = await self.convertMedia( + if self.convert_audio or self.convert_video: + up_path = await self.convert_media( up_path, gid, unwanted_files, unwanted_files_size, files_to_delete ) - if self.isCancelled: + if self.is_cancelled: return ( up_dir, @@ -264,14 +277,14 @@ async def onDownloadComplete(self): ) self.size = await get_path_size(up_dir) - if self.sampleVideo: - up_path = await self.generateSampleVideo( + if self.sample_video: + up_path = await self.generate_sample_video( up_path, gid, unwanted_files, files_to_delete ) - if self.isCancelled: + if self.is_cancelled: return ( up_dir, @@ -283,13 +296,13 @@ async def onDownloadComplete(self): self.size = await get_path_size(up_dir) if self.compress: - up_path = await self.proceedCompress( + up_path = await self.proceed_compress( up_path, gid, unwanted_files, files_to_delete ) - if self.isCancelled: + if self.is_cancelled: return ( @@ -301,30 +314,30 @@ async def onDownloadComplete(self): ) self.size = await get_path_size(up_dir) - if self.metaData: + if self.metadata: await self.proceedMetadata( up_path, gid ) - if self.isCancelled: + if self.is_cancelled: return - if self.metaAttachment: + if self.m_attachment: await self.proceedAttachment( up_path, gid ) - if self.isCancelled: + if self.is_cancelled: return - if self.isLeech and not self.compress: - await self.proceedSplit( + if self.is_leech and not self.compress: + await self.proceed_split( up_dir, unwanted_files_size, unwanted_files, gid ) - if self.isCancelled: + if self.is_cancelled: return ( @@ -344,7 +357,7 @@ async def onDownloadComplete(self): "Up" ) await event.wait() # type: ignore - if self.isCancelled: + if self.is_cancelled: return async with queue_dict_lock: non_queued_up.add(self.mid) @@ -354,9 +367,9 @@ async def onDownloadComplete(self): for s in unwanted_files_size: self.size -= s - if self.isLeech: + if self.is_leech: LOGGER.info(f"Leech Name: {self.name}") - tg = TgUploader( + tg = TelegramUploader( self, up_dir ) @@ -374,14 +387,14 @@ async def onDownloadComplete(self): files_to_delete ), ) - elif is_gdrive_id(self.upDest): # type: ignore + elif is_gdrive_id(self.up_dest): # type: ignore LOGGER.info(f"Gdrive Upload Name: {self.name}") - drive = gdUpload( + drive = GoogleDriveUpload( self, up_path ) async with task_dict_lock: - task_dict[self.mid] = GdriveStatus( + task_dict[self.mid] = GoogleDriveStatus( self, drive, gid, @@ -424,17 +437,17 @@ async def onUploadComplete( dir_id="" ): if ( - DATABASE_URL + config_dict["DATABASE_URL"] and config_dict["STOP_DUPLICATE_TASKS"] and self.raw_url ): - await DbManager().remove_download(self.raw_url) + await database.remove_download(self.raw_url) if ( - self.isSuperChat + self.is_super_chat and config_dict["INCOMPLETE_TASK_NOTIFIER"] - and DATABASE_URL + and config_dict["DATABASE_URL"] ): - await DbManager().rm_complete_task(self.message.link) # type: ignore + await database.rm_complete_task(self.message.link) # type: ignore LOGGER.info(f"Task Done: {self.name}") lmsg = ( f"{escape(self.name)}" @@ -452,20 +465,20 @@ async def onUploadComplete( else f"\n\nPath : {rclonePath}" ) msg_ = "\n\nLink has been sent in your DM." - if self.isLeech: + if self.is_leech: msg += f"\nFiles : {folders}\n" if mime_type != 0: msg += f"Error : {mime_type}\n" msg_ = "\nFiles has been sent in your DM." - if not self.dmMessage: + if not self.dm_message: if not files: - await sendMessage( + await send_message( self.message, # type: ignore lmsg + msg ) - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, lmsg + msg ) else: @@ -479,49 +492,49 @@ async def onUploadComplete( ): fmsg += f"{index}. {self.name}\n" if len(fmsg.encode() + msg.encode()) > 4000: - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, lmsg + msg + fmsg ) - await sendMessage( + await send_message( self.message, # type: ignore lmsg + msg + fmsg ) await sleep(1) fmsg = "\n" if fmsg != "\n": - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, lmsg + msg + fmsg ) - await sendMessage( + await send_message( self.message, # type: ignore lmsg + msg + fmsg ) else: if not files: - await sendMessage( + await send_message( self.message, # type: ignore gmsg + msg + msg_ ) - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, lmsg + msg ) elif ( - self.dmMessage + self.dm_message and not config_dict["DUMP_CHAT_ID"] ): - await sendMessage( + await send_message( self.message, # type: ignore gmsg + msg + msg_ ) - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, lmsg + msg ) else: @@ -535,20 +548,20 @@ async def onUploadComplete( ): fmsg += f"{index}. {self.name}\n" if len(fmsg.encode() + msg.encode()) > 4000: - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, lmsg + msg + fmsg ) await sleep(1) fmsg = "\n" if fmsg != "\n": - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, lmsg + msg + fmsg ) - await sendMessage( + await send_message( self.message, # type: ignore gmsg + msg + msg_ ) @@ -568,13 +581,13 @@ async def onUploadComplete( link.startswith("https://drive.google.com/") and not config_dict["DISABLE_DRIVE_LINK"] ): - buttons.ubutton( + buttons.url_button( "ᴅʀɪᴠᴇ\nʟɪɴᴋ", link, "header" ) elif not link.startswith("https://drive.google.com/"): - buttons.ubutton( + buttons.url_button( "ᴄʟᴏᴜᴅ\nʟɪɴᴋ", link, "header" @@ -593,14 +606,14 @@ async def onUploadComplete( share_url = f"{RCLONE_SERVE_URL}/{remote}/{url_path}" if mime_type == "Folder": share_url += "/" - buttons.ubutton( + buttons.url_button( "ʀᴄʟᴏɴᴇ\nʟɪɴᴋ", share_url ) elif not rclonePath: INDEX_URL = "" - if self.privateLink: - INDEX_URL = self.userDict.get( + if self.private_link: + INDEX_URL = self.user_dict.get( "index_url", "" ) or "" @@ -609,12 +622,12 @@ async def onUploadComplete( if INDEX_URL: share_url = f"{INDEX_URL}findpath?id={dir_id}" if mime_type == "Folder": - buttons.ubutton( + buttons.url_button( "ᴅɪʀᴇᴄᴛ\nꜰɪʟᴇ ʟɪɴᴋ", share_url ) else: - buttons.ubutton( + buttons.url_button( "ᴅɪʀᴇᴄᴛ\nꜰᴏʟᴅᴇʀ ʟɪɴᴋ", share_url ) @@ -626,65 +639,65 @@ async def onUploadComplete( ) ): share_urls = f"{INDEX_URL}findpath?id={dir_id}&view=true" - buttons.ubutton( + buttons.url_button( "ᴠɪᴇᴡ\nʟɪɴᴋ", share_urls ) buttons = extra_btns(buttons) - if self.dmMessage: - await sendMessage( - self.dmMessage, + if self.dm_message: + await send_message( + self.dm_message, lmsg + msg + _msg, buttons.build_menu(2) ) - await sendMessage( + await send_message( self.message, # type: ignore gmsg + msg + msg_ ) else: - await sendMessage( + await send_message( self.message, # type: ignore lmsg + msg + _msg, buttons.build_menu(2) ) - if self.logMessage: + if self.log_message: if ( link.startswith("https://drive.google.com/") and config_dict["DISABLE_DRIVE_LINK"] ): - buttons.ubutton( + buttons.url_button( "ᴅʀɪᴠᴇ\nʟɪɴᴋ", link, "header" ) - await sendMessage( - self.logMessage, + await send_message( + self.log_message, lmsg + msg + _msg, buttons.build_menu(2) ) else: - if self.dmMessage: - await sendMessage( + if self.dm_message: + await send_message( self.message, # type: ignore gmsg + msg + msg_ ) - await sendMessage( - self.dmMessage, + await send_message( + self.dm_message, lmsg + msg + _msg ) else: - await sendMessage( + await send_message( self.message, # type: ignore lmsg + msg + _msg + msg_ ) - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, lmsg + msg + _msg ) if self.seed: - if self.newDir: - await clean_target(self.newDir) + if self.new_dir: + await clean_target(self.new_dir) async with queue_dict_lock: if ( self.mid @@ -709,17 +722,17 @@ async def onUploadComplete( await start_from_queued() - async def onDownloadError(self, error, button=None): + async def on_download_error(self, error, button=None): async with task_dict_lock: if self.mid in task_dict: del task_dict[self.mid] count = len(task_dict) - self.removeFromSameDir() + self.remove_from_same_dir() msg = f"Sorry {self.tag}!\nYour download has been stopped." msg += f"\n\nReason : {escape(str(error))}" msg += f"\nPast : {get_readable_time(time() - self.time)}" msg += f"\nMode : {self.mode}" - tlmsg = await sendMessage( + tlmsg = await send_message( self.message, # type: ignore msg, button @@ -728,15 +741,15 @@ async def onDownloadError(self, error, button=None): self.message, # type: ignore tlmsg ) - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, msg, button ) - if self.dmMessage: - await sendMessage( - self.dmMessage, + if self.dm_message: + await send_message( + self.dm_message, msg, button ) @@ -746,18 +759,18 @@ async def onDownloadError(self, error, button=None): await update_status_message(self.message.chat.id) # type: ignore if ( - DATABASE_URL + config_dict["DATABASE_URL"] and config_dict["STOP_DUPLICATE_TASKS"] and self.raw_url ): - await DbManager().remove_download(self.raw_url) + await database.remove_download(self.raw_url) if ( - self.isSuperChat + self.is_super_chat and config_dict["INCOMPLETE_TASK_NOTIFIER"] - and DATABASE_URL + and config_dict["DATABASE_URL"] ): - await DbManager().rm_complete_task(self.message.link) # type: ignore + await database.rm_complete_task(self.message.link) # type: ignore async with queue_dict_lock: if self.mid in queued_dl: @@ -775,15 +788,15 @@ async def onDownloadError(self, error, button=None): await delete_links(self.message) # type: ignore await sleep(3) await clean_download(self.dir) - if self.newDir: - await clean_download(self.newDir) + if self.new_dir: + await clean_download(self.new_dir) if ( self.thumb and await aiopath.exists(self.thumb) ): await remove(self.thumb) - async def onUploadError(self, error): + async def on_upload_error(self, error): async with task_dict_lock: if self.mid in task_dict: del task_dict[self.mid] @@ -792,7 +805,7 @@ async def onUploadError(self, error): msg += f"\n\nReason : {escape(str(error))}" msg += f"\nPast : {get_readable_time(time() - self.time)}" msg += f"\nMode : {self.mode}" - tlmsg = await sendMessage( + tlmsg = await send_message( self.message, # type: ignore msg ) @@ -800,14 +813,14 @@ async def onUploadError(self, error): self.message, # type: ignore tlmsg ) - if self.logMessage: - await sendMessage( - self.logMessage, + if self.log_message: + await send_message( + self.log_message, msg ) - if self.dmMessage: - await sendMessage( - self.dmMessage, + if self.dm_message: + await send_message( + self.dm_message, msg, ) if count == 0: @@ -816,18 +829,18 @@ async def onUploadError(self, error): await update_status_message(self.message.chat.id) # type: ignore if ( - DATABASE_URL + config_dict["DATABASE_URL"] and config_dict["STOP_DUPLICATE_TASKS"] and self.raw_url ): - await DbManager().remove_download(self.raw_url) + await database.remove_download(self.raw_url) if ( - self.isSuperChat + self.is_super_chat and config_dict["INCOMPLETE_TASK_NOTIFIER"] - and DATABASE_URL + and config_dict["DATABASE_URL"] ): - await DbManager().rm_complete_task(self.message.link) # type: ignore + await database.rm_complete_task(self.message.link) # type: ignore async with queue_dict_lock: if self.mid in queued_dl: @@ -845,8 +858,8 @@ async def onUploadError(self, error): await delete_links(self.message) # type: ignore await sleep(3) await clean_download(self.dir) - if self.newDir: - await clean_download(self.newDir) + if self.new_dir: + await clean_download(self.new_dir) if ( self.thumb and await aiopath.exists(self.thumb) diff --git a/bot/helper/listeners/ytdlp_listener.py b/bot/helper/listeners/ytdlp_listener.py index 4cba82f5d488..7e57a3d43192 100644 --- a/bot/helper/listeners/ytdlp_listener.py +++ b/bot/helper/listeners/ytdlp_listener.py @@ -1,21 +1,22 @@ -from time import time -from functools import partial from asyncio import ( Event, wait_for, ) +from functools import partial +from time import time -from bot.helper.ext_utils.status_utils import ( +from ..ext_utils.bot_utils import new_task +from ..ext_utils.status_utils import ( get_readable_file_size, get_readable_time ) -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.message_utils import ( +from ..telegram_helper.button_build import ButtonMaker +from ..telegram_helper.message_utils import ( auto_delete_message, delete_links, - deleteMessage, - editMessage, - sendMessage + delete_message, + edit_message, + send_message ) from nekozee.handlers import CallbackQueryHandler @@ -28,6 +29,7 @@ from yt_dlp import YoutubeDL +@new_task async def select_format(_, query, obj): data = query.data.split() message = query.message @@ -48,12 +50,12 @@ async def select_format(_, query, obj): elif data[1] == "back": await obj.back_to_main() elif data[1] == "cancel": - cmsg = await editMessage( + cmsg = await edit_message( message, "Yt-Dlp task has been cancelled." ) obj.qual = None - obj.listener.isCancelled = True + obj.listener.is_cancelled = True obj.event.set() else: if data[1] == "sub": @@ -63,7 +65,7 @@ async def select_format(_, query, obj): else: obj.qual = data[1] obj.event.set() - if obj.listener.isCancelled: + if obj.listener.is_cancelled: await auto_delete_message( message, cmsg @@ -96,7 +98,7 @@ async def _event_handler(self): pfunc, filters=regex("^ytq") & - user(self.listener.userId) + user(self.listener.user_id) ), group=-1, ) @@ -106,12 +108,12 @@ async def _event_handler(self): timeout=self._timeout ) except: - await editMessage( + await edit_message( self._reply_to, "Timed Out. Task has been cancelled!" ) self.qual = None - self.listener.isCancelled = True + self.listener.is_cancelled = True await auto_delete_message( self.listener.message, self._reply_to @@ -119,7 +121,7 @@ async def _event_handler(self): self.event.set() finally: self.listener.client.remove_handler(*handler) - if self.listener.isCancelled: + if self.listener.is_cancelled: await delete_links(self.listener.message) async def get_quality(self, result): @@ -139,34 +141,34 @@ async def get_quality(self, result): video_format = f"bv*[height<=?{i}][ext=mp4]+ba[ext=m4a]/b[height<=?{i}]" b_data = f"{i}|mp4" self.formats[b_data] = video_format - buttons.ibutton( + buttons.data_button( f"{i}-ᴍᴘ4", f"ytq {b_data}" ) video_format = f"bv*[height<=?{i}][ext=webm]+ba/b[height<=?{i}]" b_data = f"{i}|webm" self.formats[b_data] = video_format - buttons.ibutton( + buttons.data_button( f"{i}-ᴡᴇʙᴍ", f"ytq {b_data}" ) - buttons.ibutton( + buttons.data_button( "ᴍᴘ3", "ytq mp3" ) - buttons.ibutton( + buttons.data_button( "ᴀᴜᴅɪᴏ\nꜰᴏʀᴍᴀᴛꜱ", "ytq audio" ) - buttons.ibutton( + buttons.data_button( "ʙᴇꜱᴛ\nᴠɪᴅᴇᴏꜱ", "ytq bv*+ba/b" ) - buttons.ibutton( + buttons.data_button( "ʙᴇꜱᴛ\nᴀᴜᴅɪᴏꜱ", "ytq ba/b" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", "ytq cancel", "footer" @@ -236,46 +238,46 @@ async def get_quality(self, result): v_list ) = next(iter(tbr_dict.items())) buttonName = f"{b_name} ({get_readable_file_size(v_list[0])})" - buttons.ibutton( + buttons.data_button( buttonName, f"ytq sub {b_name} {tbr}" ) else: - buttons.ibutton( + buttons.data_button( b_name, f"ytq dict {b_name}" ) - buttons.ibutton( + buttons.data_button( "ᴍᴘ3", "ytq mp3" ) - buttons.ibutton( + buttons.data_button( "ᴀᴜᴅɪᴏ\nꜰᴏʀᴍᴀᴛꜱ", "ytq audio" ) - buttons.ibutton( + buttons.data_button( "ʙᴇꜱᴛ\nᴠɪᴅᴇᴏ", "ytq bv*+ba/b" ) - buttons.ibutton( + buttons.data_button( "ʙᴇꜱᴛ\nᴀᴜᴅɪᴏ", "ytq ba/b" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", "ytq cancel", "footer" ) self._main_buttons = buttons.build_menu(2) msg = f"Choose Video Quality:\nTimeout: {get_readable_time(self._timeout - (time() - self._time))}\n\ncc: {self.tag}" - self._reply_to = await sendMessage( + self._reply_to = await send_message( self.listener.message, msg, self._main_buttons ) await self._event_handler() - if not self.listener.isCancelled: - await deleteMessage(self._reply_to) + if not self.listener.is_cancelled: + await delete_message(self._reply_to) return self.qual async def back_to_main(self): @@ -283,7 +285,7 @@ async def back_to_main(self): msg = f"Choose Playlist Videos Quality:\nTimeout: {get_readable_time(self._timeout - (time() - self._time))}\n\ncc: {self.tag}" else: msg = f"Choose Video Quality:\nTimeout: {get_readable_time(self._timeout - (time() - self._time))}\n\ncc: {self.tag}" - await editMessage( + await edit_message( self._reply_to, msg, self._main_buttons @@ -297,16 +299,16 @@ async def qual_subbuttons(self, b_name): d_data ) in tbr_dict.items(): button_name = f"{tbr}K ({get_readable_file_size(d_data[0])})" - buttons.ibutton( + buttons.data_button( button_name, f"ytq sub {b_name} {tbr}" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "ytq back", "footer" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", "ytq cancel", "footer" @@ -316,7 +318,7 @@ async def qual_subbuttons(self, b_name): f"Choose Bit rate for {b_name}:\n" f"Timeout: {get_readable_time(self._timeout - (time() - self._time))}\n\ncc: {self.tag}" ) - await editMessage( + await edit_message( self._reply_to, msg, subbuttons @@ -332,21 +334,21 @@ async def mp3_subbuttons(self): ] for q in audio_qualities: audio_format = f"ba/b-mp3-{q}" - buttons.ibutton( + buttons.data_button( f"{q}ᴋ-ᴍᴘ3", f"ytq {audio_format}" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "ytq back" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", "ytq cancel" ) subbuttons = buttons.build_menu(3) msg = f"Choose mp3 Audio{i} Bitrate:\nTimeout: {get_readable_time(self._timeout - (time() - self._time))}\n\ncc: {self.tag}" - await editMessage( + await edit_message( self._reply_to, msg, subbuttons @@ -365,23 +367,23 @@ async def audio_format(self): "wav" ]: audio_format = f"ba/b-{frmt}-" - buttons.ibutton( + buttons.data_button( frmt, f"ytq aq {audio_format}" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "ytq back", "footer" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", "ytq cancel", "footer" ) subbuttons = buttons.build_menu(3) msg = f"Choose Audio{i} Format:\nTimeout: {get_readable_time(self._timeout - (time() - self._time))}\n\ncc: {self.tag}" - await editMessage( + await edit_message( self._reply_to, msg, subbuttons @@ -396,15 +398,15 @@ async def audio_quality(self, format): buttons = ButtonMaker() for qual in range(11): audio_format = f"{format}{qual}" - buttons.ibutton( + buttons.data_button( qual, f"ytq {audio_format}" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "ytq aq back" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", "ytq aq cancel" ) @@ -413,7 +415,7 @@ async def audio_quality(self, format): f"Choose Audio{i} Qaulity:\n0 is best and 10 is worst\n" f"Timeout: {get_readable_time(self._timeout - (time() - self._time))}\n\ncc: {self.tag}" ) - await editMessage( + await edit_message( self._reply_to, msg, subbuttons diff --git a/bot/helper/task_utils/download_utils/aria2_download.py b/bot/helper/task_utils/download_utils/aria2_download.py index d22e8688177d..be3327ca50bf 100644 --- a/bot/helper/task_utils/download_utils/aria2_download.py +++ b/bot/helper/task_utils/download_utils/aria2_download.py @@ -14,15 +14,15 @@ non_queued_dl, queue_dict_lock, ) -from bot.helper.ext_utils.bot_utils import ( +from ...ext_utils.bot_utils import ( bt_selection_buttons, sync_to_async ) -from bot.helper.ext_utils.task_manager import check_running_tasks -from bot.helper.task_utils.status_utils.aria2_status import Aria2Status -from bot.helper.telegram_helper.message_utils import ( - sendStatusMessage, - sendMessage +from ...ext_utils.task_manager import check_running_tasks +from ...task_utils.status_utils.aria2_status import Aria2Status +from ...telegram_helper.message_utils import ( + send_status_message, + send_message ) @@ -64,14 +64,14 @@ async def add_aria2c_download(listener, dpath, header, ratio, seed_time): )[0] except Exception as e: LOGGER.info(f"Aria2c Download Error: {e}") - await listener.onDownloadError(f"{e}") + await listener.on_download_error(f"{e}") return if await aiopath.exists(listener.link): await remove(listener.link) if download.error_message: error = str(download.error_message).replace("<", " ").replace(">", " ") LOGGER.info(f"Aria2c Download Error: {error}") - await listener.onDownloadError(error) + await listener.on_download_error(error) return gid = download.gid @@ -85,11 +85,11 @@ async def add_aria2c_download(listener, dpath, header, ratio, seed_time): if add_to_queue: LOGGER.info(f"Added to Queue/Download: {name}. Gid: {gid}") if (not listener.select or not download.is_torrent) and listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) else: LOGGER.info(f"Aria2Download started: {name}. Gid: {gid}") - await listener.onDownloadStart() + await listener.on_download_start() if ( not add_to_queue @@ -99,7 +99,7 @@ async def add_aria2c_download(listener, dpath, header, ratio, seed_time): ) and listener.multi <= 1 ): - await sendStatusMessage(listener.message) + await send_status_message(listener.message) elif ( listener.select and download.is_torrent @@ -111,8 +111,8 @@ async def add_aria2c_download(listener, dpath, header, ratio, seed_time): gid ) SBUTTONS = bt_selection_buttons(gid) - msg = "Your download paused. Choose files then press Done Selecting button to start downloading." - await sendMessage( + msg = f"Your download paused. Choose files then press Done Selecting button to start downloading.\n\ncc: {listener.tag}" + await send_message( listener.message, msg, SBUTTONS @@ -120,7 +120,7 @@ async def add_aria2c_download(listener, dpath, header, ratio, seed_time): if add_to_queue: await event.wait() # type: ignore - if listener.isCancelled: + if listener.is_cancelled: return async with queue_dict_lock: non_queued_dl.add(listener.mid) diff --git a/bot/helper/task_utils/download_utils/direct_downloader.py b/bot/helper/task_utils/download_utils/direct_downloader.py index 3665c26319c3..c7b9b32204de 100644 --- a/bot/helper/task_utils/download_utils/direct_downloader.py +++ b/bot/helper/task_utils/download_utils/direct_downloader.py @@ -10,28 +10,28 @@ non_queued_dl, queue_dict_lock, ) -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.status_utils import get_readable_file_size -from bot.helper.ext_utils.task_manager import ( +from ...ext_utils.bot_utils import sync_to_async +from ...ext_utils.status_utils import get_readable_file_size +from ...ext_utils.task_manager import ( check_running_tasks, limit_checker, stop_duplicate_check ) -from bot.helper.listeners.direct_listener import DirectListener -from bot.helper.task_utils.status_utils.direct_status import DirectStatus -from bot.helper.task_utils.status_utils.queue_status import QueueStatus -from bot.helper.telegram_helper.message_utils import ( +from ...listeners.direct_listener import DirectListener +from ...task_utils.status_utils.direct_status import DirectStatus +from ...task_utils.status_utils.queue_status import QueueStatus +from ...telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendMessage, - sendStatusMessage + send_message, + send_status_message ) async def add_direct_download(listener, path): details = listener.link if not (contents := details.get("contents")): - await listener.onDownloadError("There is nothing to download!") + await listener.on_download_error("There is nothing to download!") return listener.size = details["total_size"] @@ -44,7 +44,7 @@ async def add_direct_download(listener, path): button ) = await stop_duplicate_check(listener) if msg: - await listener.onDownloadError( + await listener.on_download_error( msg, button ) @@ -52,7 +52,7 @@ async def add_direct_download(listener, path): await sleep(1) if limit_exceeded := await limit_checker(listener): LOGGER.info(f"Direct Limit Exceeded: {listener.name} | {get_readable_file_size(listener.size)}") - amsg = await sendMessage( + amsg = await send_message( listener.message, limit_exceeded ) @@ -73,11 +73,11 @@ async def add_direct_download(listener, path): gid, "dl" ) - await listener.onDownloadStart() + await listener.on_download_start() if listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) await event.wait() # type: ignore - if listener.isCancelled: + if listener.is_cancelled: return async with queue_dict_lock: non_queued_dl.add(listener.mid) @@ -110,9 +110,9 @@ async def add_direct_download(listener, path): LOGGER.info(f"Start Queued Download from Direct Download: {listener.name}") else: LOGGER.info(f"Download from Direct Download: {listener.name}") - await listener.onDownloadStart() + await listener.on_download_start() if listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) await sync_to_async( directListener.download, diff --git a/bot/helper/task_utils/download_utils/direct_link_generator.py b/bot/helper/task_utils/download_utils/direct_link_generator.py index ec19ed6c264b..1e65c7196fd8 100644 --- a/bot/helper/task_utils/download_utils/direct_link_generator.py +++ b/bot/helper/task_utils/download_utils/direct_link_generator.py @@ -26,10 +26,10 @@ from base64 import b64decode from bot import config_dict -from bot.helper.ext_utils.exceptions import DirectDownloadLinkException -from bot.helper.ext_utils.help_messages import PASSWORD_ERROR_MESSAGE -from bot.helper.ext_utils.links_utils import is_share_link -from bot.helper.ext_utils.status_utils import speed_string_to_bytes +from ...ext_utils.exceptions import DirectDownloadLinkException +from ...ext_utils.help_messages import PASSWORD_ERROR_MESSAGE +from ...ext_utils.links_utils import is_share_link +from ...ext_utils.status_utils import speed_string_to_bytes user_agent = ( diff --git a/bot/helper/task_utils/download_utils/gd_download.py b/bot/helper/task_utils/download_utils/gd_download.py index 03990a59fd8d..ba542b7c3e48 100644 --- a/bot/helper/task_utils/download_utils/gd_download.py +++ b/bot/helper/task_utils/download_utils/gd_download.py @@ -7,27 +7,27 @@ task_dict, task_dict_lock, ) -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.status_utils import get_readable_file_size -from bot.helper.ext_utils.task_manager import ( +from ...ext_utils.bot_utils import sync_to_async +from ...ext_utils.status_utils import get_readable_file_size +from ...ext_utils.task_manager import ( check_running_tasks, limit_checker, stop_duplicate_check ) -from bot.helper.task_utils.gdrive_utils.count import gdCount -from bot.helper.task_utils.gdrive_utils.download import gdDownload -from bot.helper.task_utils.status_utils.gdrive_status import GdriveStatus -from bot.helper.task_utils.status_utils.queue_status import QueueStatus -from bot.helper.telegram_helper.message_utils import ( +from ...task_utils.gdrive_utils.count import GoogleDriveCount +from ...task_utils.gdrive_utils.download import GoogleDriveDownload +from ...task_utils.status_utils.gdrive_status import GoogleDriveStatus +from ...task_utils.status_utils.queue_status import QueueStatus +from ...telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendMessage, - sendStatusMessage + send_message, + send_status_message ) async def add_gd_download(listener, path): - drive = gdCount() + drive = GoogleDriveCount() ( name, mime_type, @@ -37,10 +37,10 @@ async def add_gd_download(listener, path): ) = await sync_to_async( drive.count, listener.link, - listener.userId + listener.user_id ) if mime_type is None: - await listener.onDownloadError(name) + await listener.on_download_error(name) return listener.name = listener.name or name @@ -51,17 +51,17 @@ async def add_gd_download(listener, path): button ) = await stop_duplicate_check(listener) if msg: - await listener.onDownloadError( + await listener.on_download_error( msg, button ) return if limit_exceeded := await limit_checker( listener, - isDriveLink=True + is_drive_link=True ): LOGGER.info(f"GDrive Limit Exceeded: {listener.name} | {get_readable_file_size(listener.size)}") - gmsg = await sendMessage( + gmsg = await send_message( listener.message, limit_exceeded ) @@ -84,21 +84,21 @@ async def add_gd_download(listener, path): gid, "dl" ) - await listener.onDownloadStart() + await listener.on_download_start() if listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) await event.wait() # type: ignore - if listener.isCancelled: + if listener.is_cancelled: return async with queue_dict_lock: non_queued_dl.add(listener.mid) - drive = gdDownload( + drive = GoogleDriveDownload( listener, path ) async with task_dict_lock: - task_dict[listener.mid] = GdriveStatus( + task_dict[listener.mid] = GoogleDriveStatus( listener, drive, gid, @@ -109,8 +109,8 @@ async def add_gd_download(listener, path): LOGGER.info(f"Start Queued Download from GDrive: {listener.name}") else: LOGGER.info(f"Download from GDrive: {listener.name}") - await listener.onDownloadStart() + await listener.on_download_start() if listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) await sync_to_async(drive.download) diff --git a/bot/helper/task_utils/download_utils/jd_download.py b/bot/helper/task_utils/download_utils/jd_download.py index 641a2fd68091..e1e8a6341e62 100644 --- a/bot/helper/task_utils/download_utils/jd_download.py +++ b/bot/helper/task_utils/download_utils/jd_download.py @@ -15,49 +15,53 @@ from base64 import b64encode from bot import ( - task_dict, - task_dict_lock, LOGGER, + jd_downloads, + jd_lock, non_queued_dl, queue_dict_lock, - jd_lock, - jd_downloads, + task_dict, + task_dict_lock, +) +from ...ext_utils.bot_utils import ( + new_task, + retry_function ) -from bot.helper.ext_utils.bot_utils import retry_function -from bot.helper.ext_utils.jdownloader_booter import jdownloader -from bot.helper.ext_utils.task_manager import ( +from ...ext_utils.jdownloader_booter import jdownloader +from ...ext_utils.task_manager import ( check_running_tasks, limit_checker, stop_duplicate_check, ) -from bot.helper.listeners.jdownloader_listener import onDownloadStart -from bot.helper.task_utils.status_utils.jdownloader_status import ( +from ...listeners.jdownloader_listener import on_download_start +from ...task_utils.status_utils.jdownloader_status import ( JDownloaderStatus, ) -from bot.helper.task_utils.status_utils.queue_status import QueueStatus -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.message_utils import ( +from ...task_utils.status_utils.queue_status import QueueStatus +from ...telegram_helper.button_build import ButtonMaker +from ...telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendMessage, - sendStatusMessage, - editMessage, - deleteMessage, + send_message, + send_status_message, + edit_message, + delete_message, ) -async def configureDownload(_, query, obj): +@new_task +async def configure_download(_, query, obj): data = query.data.split() message = query.message await query.answer() if data[1] == "sdone": obj.event.set() elif data[1] == "cancel": - await editMessage( + await edit_message( message, "Task has been cancelled." ) - obj.listener.isCancelled = True + obj.listener.is_cancelled = True obj.event.set() @@ -70,14 +74,14 @@ def __init__(self, listener): async def _event_handler(self): pfunc = partial( - configureDownload, + configure_download, obj=self ) handler = self.listener.client.add_handler( CallbackQueryHandler( pfunc, filters=regex("^jdq") - & user(self.listener.userId) + & user(self.listener.user_id) ), group=-1, ) @@ -87,11 +91,11 @@ async def _event_handler(self): timeout=self._timeout ) except: - await editMessage( + await edit_message( self._reply_to, "Timed Out. Task has been cancelled!" ) - self.listener.isCancelled = True + self.listener.is_cancelled = True await auto_delete_message( self.listener.message, self._reply_to @@ -100,17 +104,17 @@ async def _event_handler(self): finally: self.listener.client.remove_handler(*handler) - async def waitForConfigurations(self): + async def wait_for_configurations(self): buttons = ButtonMaker() - buttons.ubutton( + buttons.url_button( "Select", "https://my.jdownloader.org" ) - buttons.ibutton( + buttons.data_button( "Done Selecting", "jdq sdone" ) - buttons.ibutton( + buttons.data_button( "Cancel", "jdq cancel" ) @@ -118,21 +122,21 @@ async def waitForConfigurations(self): msg = "Disable/Remove the unwanted files or change variants or " msg += f"edit files names from myJdownloader site for {self.listener.name} " msg += "but don't start it manually!\n\nAfter finish press Done Selecting!\nTimeout: 300s" - self._reply_to = await sendMessage( + self._reply_to = await send_message( self.listener.message, msg, button ) await self._event_handler() - if not self.listener.isCancelled: - await deleteMessage(self._reply_to) - return self.listener.isCancelled + if not self.listener.is_cancelled: + await delete_message(self._reply_to) + return self.listener.is_cancelled async def add_jd_download(listener, path): async with jd_lock: if jdownloader.device is None: - await listener.onDownloadError(jdownloader.error) + await listener.on_download_error(jdownloader.error) return try: @@ -143,12 +147,12 @@ async def add_jd_download(listener, path): except: is_connected = await jdownloader.jdconnect() if not is_connected: - await listener.onDownloadError(jdownloader.error) + await listener.on_download_error(jdownloader.error) return jdownloader.boot() # type: ignore isDeviceConnected = await jdownloader.connectToDevice() if not isDeviceConnected: - await listener.onDownloadError(jdownloader.error) + await listener.on_download_error(jdownloader.error) return if not jd_downloads: @@ -232,7 +236,7 @@ async def add_jd_download(listener, path): ) if not online_packages and corrupted_packages and error: - await listener.onDownloadError(error) + await listener.on_download_error(error) await retry_function( jdownloader.device.linkgrabber.remove_links, package_ids=corrupted_packages, @@ -299,7 +303,7 @@ async def add_jd_download(listener, path): if online_packages: if listener.join and len(online_packages) > 1: - listener.name = listener.sameDir["name"] + listener.name = listener.same_dir["name"] await retry_function( jdownloader.device.linkgrabber.move_to_new_package, listener.name, @@ -312,7 +316,7 @@ async def add_jd_download(listener, path): error = ( name or "Download Not Added! Maybe some issues in jdownloader or site!" ) - await listener.onDownloadError(error) + await listener.on_download_error(error) if corrupted_packages or online_packages: packages_to_remove = corrupted_packages + online_packages await retry_function( @@ -359,7 +363,7 @@ async def add_jd_download(listener, path): jdownloader.device.linkgrabber.remove_links, package_ids=online_packages ) - await listener.onDownloadError( + await listener.on_download_error( msg, button ) @@ -368,12 +372,12 @@ async def add_jd_download(listener, path): return if limit_exceeded := await limit_checker( listener, - isJd=True + is_jd=True ): LOGGER.info( f"JDownloader Limit Exceeded: {listener.name} | {listener.size}" ) - jdmsg = await listener.onDownloadError(limit_exceeded) + jdmsg = await listener.on_download_error(limit_exceeded) await delete_links(listener.message) await auto_delete_message( listener.message, @@ -383,13 +387,13 @@ async def add_jd_download(listener, path): if ( listener.select and - await JDownloaderHelper(listener).waitForConfigurations() + await JDownloaderHelper(listener).wait_for_configurations() ): await retry_function( jdownloader.device.linkgrabber.remove_links, package_ids=online_packages, ) - listener.removeFromSameDir() + listener.remove_from_same_dir() return add_to_queue, event = await check_running_tasks(listener) @@ -401,11 +405,11 @@ async def add_jd_download(listener, path): f"{gid}", "dl" ) - await listener.onDownloadStart() + await listener.on_download_start() if listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) await event.wait() # type: ignore - if listener.isCancelled: + if listener.is_cancelled: return async with queue_dict_lock: non_queued_dl.add(listener.mid) @@ -434,7 +438,7 @@ async def add_jd_download(listener, path): jd_downloads[gid]["ids"] = packages if not packages: - await listener.onDownloadError("This Download have been removed manually!") + await listener.on_download_error("This Download have been removed manually!") async with jd_lock: del jd_downloads[gid] return @@ -450,12 +454,12 @@ async def add_jd_download(listener, path): f"{gid}", ) - await onDownloadStart() + await on_download_start() if add_to_queue: LOGGER.info(f"Start Queued Download from JDownloader: {listener.name}") else: LOGGER.info(f"Download with JDownloader: {listener.name}") - await listener.onDownloadStart() + await listener.on_download_start() if listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) diff --git a/bot/helper/task_utils/download_utils/mega_download.py b/bot/helper/task_utils/download_utils/mega_download.py index 4ead15a12b96..a32daa0a0b33 100644 --- a/bot/helper/task_utils/download_utils/mega_download.py +++ b/bot/helper/task_utils/download_utils/mega_download.py @@ -11,23 +11,23 @@ non_queued_dl, queue_dict_lock ) -from bot.helper.ext_utils.links_utils import get_mega_link_type -from bot.helper.ext_utils.bot_utils import sync_to_async +from ...ext_utils.links_utils import get_mega_link_type +from ...ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.task_manager import ( +from ...ext_utils.task_manager import ( check_running_tasks, limit_checker, stop_duplicate_check ) -from bot.helper.task_utils.status_utils.mega_download_status import MegaDownloadStatus -from bot.helper.task_utils.status_utils.queue_status import QueueStatus -from bot.helper.telegram_helper.message_utils import ( +from ...task_utils.status_utils.mega_download_status import MegaDownloadStatus +from ...task_utils.status_utils.queue_status import QueueStatus +from ...telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendMessage, - sendStatusMessage + send_message, + send_status_message ) -from bot.helper.listeners.mega_listener import ( +from ...listeners.mega_listener import ( MegaAppListener, AsyncExecutor, mega_login, @@ -87,7 +87,7 @@ async def add_mega_download(listener, path): ) if mega_listener.error: - mmsg = await sendMessage( + mmsg = await send_message( listener.message, str(mega_listener.error) ) @@ -112,7 +112,7 @@ async def add_mega_download(listener, path): button ) = await stop_duplicate_check(listener) if msg: - mmsg = await sendMessage( + mmsg = await send_message( listener.message, msg, button @@ -136,9 +136,9 @@ async def add_mega_download(listener, path): listener.size = api.getSize(node) if limit_exceeded := await limit_checker( listener, - isMega=True + is_mega=True ): - mmsg = await sendMessage( + mmsg = await send_message( listener.message, limit_exceeded ) @@ -166,8 +166,8 @@ async def add_mega_download(listener, path): gid, "Dl" ) - await listener.onDownloadStart() - await sendStatusMessage(listener.message) + await listener.on_download_start() + await send_status_message(listener.message) await event.wait() # type: ignore async with task_dict_lock: if listener.mid not in task_dict: @@ -195,8 +195,8 @@ async def add_mega_download(listener, path): if from_queue: LOGGER.info(f"Start Queued Download from Mega: {listener.name}") else: - await listener.onDownloadStart() - await sendStatusMessage(listener.message) + await listener.on_download_start() + await send_status_message(listener.message) LOGGER.info(f"Download from Mega: {listener.name}") await makedirs( diff --git a/bot/helper/task_utils/download_utils/nzb_downloader.py b/bot/helper/task_utils/download_utils/nzb_downloader.py index 322a78dfd9b5..6b497a12e6db 100644 --- a/bot/helper/task_utils/download_utils/nzb_downloader.py +++ b/bot/helper/task_utils/download_utils/nzb_downloader.py @@ -18,18 +18,17 @@ LOGGER, config_dict, non_queued_dl, - queue_dict_lock, - DATABASE_URL, + queue_dict_lock ) -from bot.helper.ext_utils.bot_utils import bt_selection_buttons -from bot.helper.ext_utils.task_manager import check_running_tasks -from bot.helper.listeners.nzb_listener import onDownloadStart -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.task_utils.status_utils.nzb_status import SabnzbdStatus -from bot.helper.telegram_helper.message_utils import ( - sendMessage, - sendStatusMessage, - deleteMessage, +from ...ext_utils.bot_utils import bt_selection_buttons +from ...ext_utils.task_manager import check_running_tasks +from ...listeners.nzb_listener import on_download_start +from ...ext_utils.db_handler import database +from ...task_utils.status_utils.nzb_status import SabnzbdStatus +from ...telegram_helper.message_utils import ( + send_message, + send_status_message, + delete_message, ) @@ -45,9 +44,9 @@ async def add_servers(): if server["host"] not in servers_hosts: tasks.append(sabnzbd_client.add_server(server)) config_dict["USENET_SERVERS"].append(server) - if DATABASE_URL: + if config_dict["DATABASE_URL"]: tasks.append( - DbManager().update_config( + database.update_config( {"USENET_SERVERS": config_dict["USENET_SERVERS"]} ) ) @@ -82,7 +81,7 @@ async def add_nzb(listener, path): try: await add_servers() except Exception as e: - await listener.onDownloadError(str(e)) + await listener.on_download_error(str(e)) return try: await sabnzbd_client.create_category( @@ -113,7 +112,7 @@ async def add_nzb(listener, path): else 1, ) if not res["status"]: - await listener.onDownloadError( + await listener.on_download_error( "Not added! Mostly issue in the link", ) return @@ -128,7 +127,7 @@ async def add_nzb(listener, path): history = await sabnzbd_client.get_history(nzo_ids=job_id) if err := history["history"]["slots"][0]["fail_message"]: await gather( - listener.onDownloadError(err), + listener.on_download_error(err), sabnzbd_client.delete_history( job_id, delete_files=True @@ -145,14 +144,14 @@ async def add_nzb(listener, path): job_id, queued=add_to_queue ) - await onDownloadStart(job_id) + await on_download_start(job_id) if add_to_queue: LOGGER.info(f"Added to Queue/Download: {name} - Job_id: {job_id}") else: LOGGER.info(f"NzbDownload started: {name} - Job_id: {job_id}") - await listener.onDownloadStart() + await listener.on_download_start() if ( config_dict["BASE_URL"] @@ -163,7 +162,7 @@ async def add_nzb(listener, path): name.startswith("Trying") ): metamsg = "Fetching URL, wait then you can select files. Use nzb file to avoid this wait." - meta = await sendMessage( + meta = await send_message( listener.message, metamsg ) @@ -173,27 +172,27 @@ async def add_nzb(listener, path): if not nzb_info["queue"]["slots"][0]["filename"].startswith( "Trying" ): - await deleteMessage(meta) + await delete_message(meta) break else: - await deleteMessage(meta) + await delete_message(meta) return await sleep(1) if not add_to_queue: await sabnzbd_client.pause_job(job_id) SBUTTONS = bt_selection_buttons(job_id) msg = "Your download paused. Choose files then press Done Selecting button to start downloading." - await sendMessage( + await send_message( listener.message, msg, SBUTTONS ) elif listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) if add_to_queue: await event.wait() # type: ignore - if listener.isCancelled: + if listener.is_cancelled: return async with queue_dict_lock: non_queued_dl.add(listener.mid) @@ -205,7 +204,7 @@ async def add_nzb(listener, path): f"Start Queued Download from Sabnzbd: {name} - Job_id: {job_id}" ) except Exception as e: - await listener.onDownloadError(f"{e}") + await listener.on_download_error(f"{e}") finally: if nzbpath and await aiopath.exists(listener.link): await remove(listener.link) diff --git a/bot/helper/task_utils/download_utils/qbit_download.py b/bot/helper/task_utils/download_utils/qbit_download.py index ccd71d44c80c..4826ea98c12c 100644 --- a/bot/helper/task_utils/download_utils/qbit_download.py +++ b/bot/helper/task_utils/download_utils/qbit_download.py @@ -1,3 +1,4 @@ +from time import time from aiofiles.os import ( remove, path as aiopath @@ -5,47 +6,28 @@ from asyncio import sleep from bot import ( - task_dict, - task_dict_lock, - qbittorrent_client, LOGGER, config_dict, non_queued_dl, + qbittorrent_client, queue_dict_lock, + task_dict, + task_dict_lock, ) -from bot.helper.ext_utils.bot_utils import ( +from ...ext_utils.bot_utils import ( bt_selection_buttons, sync_to_async ) -from bot.helper.ext_utils.task_manager import check_running_tasks -from bot.helper.listeners.qbit_listener import onDownloadStart -from bot.helper.task_utils.status_utils.qbit_status import QbittorrentStatus -from bot.helper.telegram_helper.message_utils import ( - sendMessage, - deleteMessage, - sendStatusMessage, +from ...ext_utils.task_manager import check_running_tasks +from ...listeners.qbit_listener import on_download_start +from ...task_utils.status_utils.qbit_status import QbittorrentStatus +from ...telegram_helper.message_utils import ( + delete_message, + send_message, + send_status_message, ) -""" -Only v1 torrents -#from hashlib import sha1 -#from base64 import b16encode, b32decode -#from bencoding import bencode, bdecode -#from re import search as re_search -def _get_hash_magnet(mgt: str): - hash_ = re_search(r"(?<=xt=urn:btih:)[a-zA-Z0-9]+", mgt).group(0) - if len(hash_) == 32: - hash_ = b16encode(b32decode(hash_.upper())).decode() - return hash_ - -def _get_hash_file(fpath): - with open(fpath, "rb") as f: - decodedDict = bdecode(f.read()) - return sha1(bencode(decodedDict[b"info"])).hexdigest() -""" - - async def add_qb_torrent(listener, path, ratio, seed_time): try: url = listener.link @@ -66,14 +48,17 @@ async def add_qb_torrent(listener, path, ratio, seed_time): tags=f"{listener.mid}", ratio_limit=ratio, seeding_time_limit=seed_time, - headers={"user-agent": "Wget/1.12"}, + headers={"user-agent": "Wget/1.12"} ) + if op.lower() == "ok.": tor_info = await sync_to_async( qbittorrent_client.torrents_info, tag=f"{listener.mid}" ) + if len(tor_info) == 0: + start_time = time() while True: tor_info = await sync_to_async( qbittorrent_client.torrents_info, @@ -81,14 +66,20 @@ async def add_qb_torrent(listener, path, ratio, seed_time): ) if len(tor_info) > 0: break + if time() - start_time > 60: + LOGGER.error("Download not started! This Torrent already added or unsupported/invalid link/file.") + await listener.on_download_error( + "Download not started!\nThis Torrent already added or unsupported/invalid link/file." + ) + return await sleep(1) + tor_info = tor_info[0] listener.name = tor_info.name ext_hash = tor_info.hash else: - await listener.onDownloadError( - "This Torrent already added or unsupported/invalid link/file.", - ) + LOGGER.error("Download not started! This Torrent already added or unsupported/invalid link/file.") + await listener.on_download_error("Download not started!\nThis Torrent already added or unsupported/invalid link/file.") return async with task_dict_lock: @@ -96,14 +87,15 @@ async def add_qb_torrent(listener, path, ratio, seed_time): listener, queued=add_to_queue ) - await onDownloadStart(f"{listener.mid}") + + await on_download_start(f"{listener.mid}") if add_to_queue: LOGGER.info(f"Added to Queue/Download: {tor_info.name} - Hash: {ext_hash}") else: LOGGER.info(f"QbitDownload started: {tor_info.name} - Hash: {ext_hash}") - await listener.onDownloadStart() + await listener.on_download_start() if ( config_dict["BASE_URL"] @@ -111,7 +103,7 @@ async def add_qb_torrent(listener, path, ratio, seed_time): ): if listener.link.startswith("magnet:"): metamsg = "Downloading Metadata, wait then you can select files. Use torrent file to avoid this wait." - meta = await sendMessage( + meta = await send_message( listener.message, metamsg ) @@ -120,8 +112,9 @@ async def add_qb_torrent(listener, path, ratio, seed_time): qbittorrent_client.torrents_info, tag=f"{listener.mid}" ) + if len(tor_info) == 0: - await deleteMessage(meta) + await delete_message(meta) return try: tor_info = tor_info[0] @@ -130,10 +123,10 @@ async def add_qb_torrent(listener, path, ratio, seed_time): "checkingResumeData", "pausedDL", ]: - await deleteMessage(meta) + await delete_message(meta) break except: - await deleteMessage(meta) + await delete_message(meta) return ext_hash = tor_info.hash @@ -143,18 +136,19 @@ async def add_qb_torrent(listener, path, ratio, seed_time): torrent_hashes=ext_hash ) SBUTTONS = bt_selection_buttons(ext_hash) - msg = "Your download paused. Choose files then press Done Selecting button to start downloading." - await sendMessage( + msg = f"Your download paused. Choose files then press Done Selecting button to start downloading.\n\ncc: {listener.tag}" + await send_message( listener.message, msg, SBUTTONS ) + elif listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) if add_to_queue: await event.wait() # type: ignore - if listener.isCancelled: + if listener.is_cancelled: return async with queue_dict_lock: non_queued_dl.add(listener.mid) @@ -165,11 +159,10 @@ async def add_qb_torrent(listener, path, ratio, seed_time): qbittorrent_client.torrents_resume, torrent_hashes=ext_hash ) - LOGGER.info( - f"Start Queued Download from Qbittorrent: {tor_info.name} - Hash: {ext_hash}" - ) + LOGGER.info(f"Start Queued Download from Qbittorrent: {tor_info.name} - Hash: {ext_hash}") except Exception as e: - await listener.onDownloadError(f"{e}") + LOGGER.error(f"Qbittorrent download error: {e}") + await listener.on_download_error(f"{e}") finally: - if tpath and await aiopath.exists(listener.link): - await remove(listener.link) + if tpath and await aiopath.exists(tpath): + await remove(tpath) diff --git a/bot/helper/task_utils/download_utils/rclone_download.py b/bot/helper/task_utils/download_utils/rclone_download.py index 6df0c8dc2ed9..ed8e71fbefa5 100644 --- a/bot/helper/task_utils/download_utils/rclone_download.py +++ b/bot/helper/task_utils/download_utils/rclone_download.py @@ -9,21 +9,21 @@ non_queued_dl, LOGGER ) -from bot.helper.ext_utils.bot_utils import cmd_exec -from bot.helper.ext_utils.status_utils import get_readable_file_size -from bot.helper.ext_utils.task_manager import ( +from ...ext_utils.bot_utils import cmd_exec +from ...ext_utils.status_utils import get_readable_file_size +from ...ext_utils.task_manager import ( check_running_tasks, limit_checker, stop_duplicate_check ) -from bot.helper.task_utils.rclone_utils.transfer import RcloneTransferHelper -from bot.helper.task_utils.status_utils.queue_status import QueueStatus -from bot.helper.task_utils.status_utils.rclone_status import RcloneStatus -from bot.helper.telegram_helper.message_utils import ( +from ...task_utils.rclone_utils.transfer import RcloneTransferHelper +from ...task_utils.status_utils.queue_status import QueueStatus +from ...task_utils.status_utils.rclone_status import RcloneStatus +from ...telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendMessage, - sendStatusMessage + send_message, + send_status_message ) @@ -33,7 +33,7 @@ async def add_rclone_download(listener, path): "mrcc:", 1 )[1] - config_path = f"rclone/{listener.userId}.conf" + config_path = f"rclone/{listener.user_id}.conf" else: config_path = "rclone.conf" @@ -75,7 +75,7 @@ async def add_rclone_download(listener, path): or "Use /shell cat rlog.txt to see more information" ) msg = f"Error: While getting rclone stat/size. Path: {remote}:{listener.link}. Stderr: {err[:4000]}" - await listener.onDownloadError(msg) + await listener.on_download_error(msg) return try: rstat = loads(res1[0]) @@ -83,7 +83,7 @@ async def add_rclone_download(listener, path): except Exception as err: if not str(err): err = "Use /shell cat rlog.txt to see more information" - await listener.onDownloadError(f"RcloneDownload JsonLoad: {err}") + await listener.on_download_error(f"RcloneDownload JsonLoad: {err}") return if rstat["IsDir"]: if not listener.name: @@ -106,14 +106,14 @@ async def add_rclone_download(listener, path): button ) = await stop_duplicate_check(listener) if msg: - await listener.onDownloadError( + await listener.on_download_error( msg, button ) return - if limit_exceeded := await limit_checker(listener, isRclone=True): + if limit_exceeded := await limit_checker(listener, is_rclone=True): LOGGER.info(f"Rclone Limit Exceeded: {listener.name} | {get_readable_file_size(listener.size)}") - rmsg = await sendMessage( + rmsg = await send_message( listener.message, limit_exceeded ) @@ -136,11 +136,11 @@ async def add_rclone_download(listener, path): gid, "dl" ) - await listener.onDownloadStart() + await listener.on_download_start() if listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) await event.wait() # type: ignore - if listener.isCancelled: + if listener.is_cancelled: return async with queue_dict_lock: non_queued_dl.add(listener.mid) @@ -157,9 +157,9 @@ async def add_rclone_download(listener, path): if add_to_queue: LOGGER.info(f"Start Queued Download with rclone: {listener.link}") else: - await listener.onDownloadStart() + await listener.on_download_start() if listener.multi <= 1: - await sendStatusMessage(listener.message) + await send_status_message(listener.message) LOGGER.info(f"Download with rclone: {listener.link}") await RCTransfer.download( diff --git a/bot/helper/task_utils/download_utils/telegram_download.py b/bot/helper/task_utils/download_utils/telegram_download.py index dd304d35c757..71366bc42bb8 100644 --- a/bot/helper/task_utils/download_utils/telegram_download.py +++ b/bot/helper/task_utils/download_utils/telegram_download.py @@ -15,15 +15,15 @@ bot, user, ) -from bot.helper.ext_utils.task_manager import ( +from ...ext_utils.task_manager import ( check_running_tasks, stop_duplicate_check ) -from bot.helper.task_utils.status_utils.queue_status import QueueStatus -from bot.helper.task_utils.status_utils.telegram_status import TelegramStatus -from bot.helper.telegram_helper.message_utils import ( - sendMessage, - sendStatusMessage +from ...task_utils.status_utils.queue_status import QueueStatus +from ...task_utils.status_utils.telegram_status import TelegramStatus +from ...telegram_helper.message_utils import ( + send_message, + send_status_message ) global_lock = Lock() @@ -46,7 +46,7 @@ def speed(self): def processed_bytes(self): return self._processed_bytes - async def _onDownloadStart(self, file_id, from_queue): + async def _on_download_start(self, file_id, from_queue): async with global_lock: GLOBAL_GID.add(file_id) self._id = file_id @@ -58,31 +58,31 @@ async def _onDownloadStart(self, file_id, from_queue): "dl", ) if not from_queue: - await self._listener.onDownloadStart() + await self._listener.on_download_start() if self._listener.multi <= 1: - await sendStatusMessage(self._listener.message) + await send_status_message(self._listener.message) LOGGER.info(f"Download from Telegram: {self._listener.name}") else: LOGGER.info(f"Start Queued Download from Telegram: {self._listener.name}") - async def _onDownloadProgress(self, current, total): - if self._listener.isCancelled: + async def _on_download_progress(self, current, total): + if self._listener.is_cancelled: if self.session == "user": user.stop_transmission() # type: ignore else: bot.stop_transmission() # type: ignore self._processed_bytes = current - async def _onDownloadError(self, error): + async def _on_download_error(self, error): async with global_lock: try: GLOBAL_GID.remove(self._id) except: pass - await self._listener.onDownloadError(error) + await self._listener.on_download_error(error) - async def _onDownloadComplete(self): - await self._listener.onDownloadComplete() + async def _on_download_complete(self): + await self._listener.on_download_complete() async with global_lock: GLOBAL_GID.remove(self._id) @@ -90,10 +90,10 @@ async def _download(self, message, path): try: download = await message.download( file_name=path, - progress=self._onDownloadProgress + progress=self._on_download_progress ) - if self._listener.isCancelled: - await self._onDownloadError("Cancelled by user!") + if self._listener.is_cancelled: + await self._on_download_error("Cancelled by user!") return except FloodWait as f: @@ -101,19 +101,19 @@ async def _download(self, message, path): await sleep(f.value) # type: ignore except Exception as e: LOGGER.error(str(e)) - await self._onDownloadError(str(e)) + await self._on_download_error(str(e)) return if download is not None: - await self._onDownloadComplete() - elif not self._listener.isCancelled: - await self._onDownloadError("Internal error occurred") + await self._on_download_complete() + elif not self._listener.is_cancelled: + await self._on_download_error("Internal error occurred") async def add_download(self, message, path, session): if ( config_dict["DELETE_LINKS"] and not config_dict["LOG_CHAT_ID"] ): - return await sendMessage( + return await send_message( message, "You must add LOG_CHAT_ID or disable DELETE_LINKS to download files." ) @@ -123,12 +123,12 @@ async def add_download(self, message, path, session): "user", "bot" ] - and self._listener.userTransmission - and self._listener.isSuperChat + and self._listener.user_transmission + and self._listener.is_super_chat ): self.session = "user" if config_dict["LOG_CHAT_ID"]: - file_to_download = self._listener.logMessage + file_to_download = self._listener.log_message else: file_to_download = message message = await user.get_messages( # type: ignore @@ -174,7 +174,7 @@ async def add_download(self, message, path, session): button ) = await stop_duplicate_check(self._listener) if msg: - await self._listener.onDownloadError( + await self._listener.on_download_error( msg, button ) @@ -192,26 +192,26 @@ async def add_download(self, message, path, session): gid, "dl" ) - await self._listener.onDownloadStart() + await self._listener.on_download_start() if self._listener.multi <= 1: - await sendStatusMessage(self._listener.message) + await send_status_message(self._listener.message) await event.wait() # type: ignore - if self._listener.isCancelled: + if self._listener.is_cancelled: return async with queue_dict_lock: non_queued_dl.add(self._listener.mid) - await self._onDownloadStart(gid, add_to_queue) + await self._on_download_start(gid, add_to_queue) await self._download(message, path) else: - await self._onDownloadError("File already being downloaded!") + await self._on_download_error("File already being downloaded!") else: - await self._onDownloadError( + await self._on_download_error( "No document in the replied message! Use SuperGroup incase you are trying to download with User session!" ) async def cancel_task(self): - self._listener.isCancelled = True + self._listener.is_cancelled = True LOGGER.info( f"Cancelling download on user request: name: {self._listener.name} id: {self._id}" ) diff --git a/bot/helper/task_utils/download_utils/yt_dlp_download.py b/bot/helper/task_utils/download_utils/yt_dlp_download.py index febff277e03a..fec4a8da4e6b 100644 --- a/bot/helper/task_utils/download_utils/yt_dlp_download.py +++ b/bot/helper/task_utils/download_utils/yt_dlp_download.py @@ -5,11 +5,6 @@ ) from re import search as re_search from secrets import token_urlsafe -from bot.helper.ext_utils.status_utils import get_readable_file_size -from yt_dlp import ( - YoutubeDL, - DownloadError -) from bot import ( task_dict_lock, @@ -17,21 +12,26 @@ non_queued_dl, queue_dict_lock ) -from bot.helper.ext_utils.bot_utils import ( +from ...ext_utils.bot_utils import ( sync_to_async, async_to_sync ) -from bot.helper.ext_utils.task_manager import ( +from ...ext_utils.status_utils import get_readable_file_size +from yt_dlp import ( + YoutubeDL, + DownloadError +) +from ...ext_utils.task_manager import ( check_running_tasks, limit_checker, list_checker, stop_duplicate_check ) -from bot.helper.task_utils.status_utils.queue_status import QueueStatus -from bot.helper.telegram_helper.message_utils import ( +from ...task_utils.status_utils.queue_status import QueueStatus +from ...telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendStatusMessage + send_status_message ) from ..status_utils.yt_dlp_download_status import YtDlpDownloadStatus @@ -86,7 +86,7 @@ def __init__(self, listener): self.playlist_index = 0 self.playlist_count = 0 self.opts = { - "progress_hooks": [self._onDownloadProgress], + "progress_hooks": [self._on_download_progress], "logger": MyLogger( self, self._listener @@ -128,9 +128,9 @@ def progress(self): def eta(self): return self._eta - def _onDownloadProgress(self, d): + def _on_download_progress(self, d): self._downloading = True - if self._listener.isCancelled: + if self._listener.is_cancelled: raise ValueError("Cancelling...") if d["status"] == "finished": if self.is_playlist: @@ -161,7 +161,7 @@ def _onDownloadProgress(self, d): except: pass - async def _onDownloadStart(self, from_queue=False): + async def _on_download_start(self, from_queue=False): async with task_dict_lock: task_dict[self._listener.mid] = YtDlpDownloadStatus( self._listener, @@ -169,15 +169,15 @@ async def _onDownloadStart(self, from_queue=False): self._gid ) if not from_queue: - await self._listener.onDownloadStart() + await self._listener.on_download_start() if self._listener.multi <= 1: - await sendStatusMessage(self._listener.message) + await send_status_message(self._listener.message) - def _onDownloadError(self, error): - self._listener.isCancelled = True - async_to_sync(self._listener.onDownloadError, error) + def _on_download_error(self, error): + self._listener.is_cancelled = True + async_to_sync(self._listener.on_download_error, error) - def extractMetaData(self): + def _extract_meta_data(self): if self._listener.link.startswith(( "rtmp", "mms", @@ -194,7 +194,7 @@ def extractMetaData(self): if result is None: raise ValueError("Info result is None") except Exception as e: - return self._onDownloadError(str(e)) + return self._on_download_error(str(e)) if self.is_playlist: self.playlist_count = result.get( "playlist_count", @@ -244,22 +244,22 @@ def _download(self, path): try: ydl.download([self._listener.link]) except DownloadError as e: - if not self._listener.isCancelled: - self._onDownloadError(str(e)) + if not self._listener.is_cancelled: + self._on_download_error(str(e)) return if self.is_playlist and ( not ospath.exists(path) or len(listdir(path)) == 0 ): - self._onDownloadError( + self._on_download_error( "No video available to download from this playlist. Check logs for more details" ) return - if self._listener.isCancelled: + if self._listener.is_cancelled: raise ValueError - async_to_sync(self._listener.onDownloadComplete) + async_to_sync(self._listener.on_download_complete) except ValueError: - self._onDownloadError("Download Stopped by User!") + self._on_download_error("Download Stopped by User!") async def add_download(self, path, qual, playlist, options): if playlist: @@ -268,7 +268,7 @@ async def add_download(self, path, qual, playlist, options): self._gid = token_urlsafe(8) - await self._onDownloadStart() + await self._on_download_start() self.opts["postprocessors"] = [ { @@ -303,8 +303,8 @@ async def add_download(self, path, qual, playlist, options): self.opts["format"] = qual - await sync_to_async(self.extractMetaData) - if self._listener.isCancelled: + await sync_to_async(self._extract_meta_data) + if self._listener.is_cancelled: return ( @@ -355,7 +355,7 @@ async def add_download(self, path, qual, playlist, options): if qual.startswith("ba/b"): self._listener.name = f"{base_name}{self._ext}" - if self._listener.isLeech: + if self._listener.is_leech and not self._listener.thumbnail_layout: self.opts["postprocessors"].append( { "format": "jpg", @@ -377,11 +377,13 @@ async def add_download(self, path, qual, playlist, options): ]: self.opts["postprocessors"].append( { - "already_have_thumbnail": self._listener.isLeech, + "already_have_thumbnail": bool( + self._listener.is_leech and not self._listener.thumbnail_layout + ), "key": "EmbedThumbnail", } ) - elif not self._listener.isLeech: + elif not self._listener.is_leech: self.opts["writethumbnail"] = False ( @@ -389,7 +391,7 @@ async def add_download(self, path, qual, playlist, options): button ) = await stop_duplicate_check(self._listener) if msg: - await self._listener.onDownloadError( + await self._listener.on_download_error( msg, button ) @@ -400,7 +402,7 @@ async def add_download(self, path, qual, playlist, options): LOGGER.info( f"Yt-Dlp Limit Exceeded: {self._listener.name} | {get_readable_file_size(self._listener.size)} | {self.playlist_count}" ) - ymsg = await self._listener.onDownloadError(limit_exceeded) + ymsg = await self._listener.on_download_error(limit_exceeded) await delete_links(self._listener.message) await auto_delete_message( self._listener.message, @@ -411,7 +413,7 @@ async def add_download(self, path, qual, playlist, options): LOGGER.info( f"Yt-Dlp Limit Exceeded: {self._listener.name} | {get_readable_file_size(self._listener.size)} | {self.playlist_count}" ) - ymsg = await self._listener.onDownloadError(list_exceeded) + ymsg = await self._listener.on_download_error(list_exceeded) await delete_links(self._listener.message) await auto_delete_message( self._listener.message, @@ -432,12 +434,12 @@ async def add_download(self, path, qual, playlist, options): "dl" ) await event.wait() # type: ignore - if self._listener.isCancelled: + if self._listener.is_cancelled: return async with queue_dict_lock: non_queued_dl.add(self._listener.mid) LOGGER.info(f"Start Queued Download from YT_DLP: {self._listener.name}") - await self._onDownloadStart(True) + await self._on_download_start(True) if not add_to_queue: LOGGER.info(f"Download with YT_DLP: {self._listener.name}") @@ -445,10 +447,10 @@ async def add_download(self, path, qual, playlist, options): await sync_to_async(self._download, path) async def cancel_task(self): - self._listener.isCancelled = True + self._listener.is_cancelled = True LOGGER.info(f"Cancelling Download: {self._listener.name}") if not self._downloading: - await self._listener.onDownloadError("Download Cancelled by User!") + await self._listener.on_download_error("Download Cancelled by User!") def _set_options(self, options): options = options.split("|") @@ -498,5 +500,8 @@ def _set_options(self, options): self.opts[key].extend(tuple(value)) elif isinstance(value, dict): self.opts[key].append(value) + elif key == "download_ranges": + if isinstance(value, list): + self.opts[key] = lambda info, ytdl: value else: self.opts[key] = value diff --git a/bot/helper/task_utils/gdrive_utils/clone.py b/bot/helper/task_utils/gdrive_utils/clone.py index e6eeb42b93ac..1f4b0e4f24a9 100644 --- a/bot/helper/task_utils/gdrive_utils/clone.py +++ b/bot/helper/task_utils/gdrive_utils/clone.py @@ -10,13 +10,14 @@ ) from time import time -from bot.helper.ext_utils.bot_utils import async_to_sync -from bot.helper.task_utils.gdrive_utils.helper import GoogleDriveHelper +from ...ext_utils.bot_utils import async_to_sync +from ...task_utils.gdrive_utils.helper import GoogleDriveHelper LOGGER = getLogger(__name__) -class gdClone(GoogleDriveHelper): +class GoogleDriveClone(GoogleDriveHelper): + def __init__( self, listener @@ -29,28 +30,28 @@ def __init__( def user_setting(self): if ( - self.listener.upDest.startswith("mtp:") or + self.listener.up_dest.startswith("mtp:") or self.listener.link.startswith("mtp:") ): - self.token_path = f"tokens/{self.listener.userId}.pickle" - self.listener.upDest = self.listener.upDest.replace( + self.token_path = f"tokens/{self.listener.user_id}.pickle" + self.listener.up_dest = self.listener.up_dest.replace( "mtp:", "", 1 ) self.use_sa = False - elif self.listener.upDest.startswith("tp:"): - self.listener.upDest = self.listener.upDest.replace( + elif self.listener.up_dest.startswith("tp:"): + self.listener.up_dest = self.listener.up_dest.replace( "tp:", "", 1 ) self.use_sa = False elif ( - self.listener.upDest.startswith("sa:") or + self.listener.up_dest.startswith("sa:") or self.listener.link.startswith("sa:") ): - self.listener.upDest = self.listener.upDest.replace( + self.listener.up_dest = self.listener.up_dest.replace( "sa:", "", 1 @@ -59,7 +60,7 @@ def user_setting(self): def clone(self): try: - file_id = self.getIdFromUrl(self.listener.link) + file_id = self.get_id_from_url(self.listener.link) except ( KeyError, IndexError @@ -75,12 +76,12 @@ def clone(self): msg = "" LOGGER.info(f"File ID: {file_id}") try: - meta = self.getFileMetadata(file_id) + meta = self.get_file_metadata(file_id) mime_type = meta.get("mimeType") if mime_type == self.G_DRIVE_DIR_MIME_TYPE: dir_id = self.create_directory( meta.get("name"), - self.listener.upDest + self.listener.up_dest ) self._cloneFolder( meta.get("name"), @@ -88,7 +89,7 @@ def clone(self): dir_id ) durl = self.G_DRIVE_DIR_BASE_DOWNLOAD_URL.format(dir_id) - if self.listener.isCancelled: + if self.listener.is_cancelled: LOGGER.info("Deleting cloned data from Drive...") self.service.files().delete( fileId=dir_id, @@ -106,7 +107,7 @@ def clone(self): else: file = self._copyFile( meta.get("id"), - self.listener.upDest + self.listener.up_dest ) msg += f'Name: {file.get("name")}' # type: ignore durl = self.G_DRIVE_BASE_DOWNLOAD_URL.format(file.get("id")) # type: ignore @@ -121,7 +122,7 @@ def clone(self): mime_type, self.total_files, self.total_folders, - self.getIdFromUrl(durl), + self.get_id_from_url(durl), ) except Exception as err: if isinstance( @@ -152,7 +153,7 @@ def clone(self): else: msg = f"Error.\n{err}" async_to_sync( - self.listener.onUploadError, + self.listener.on_upload_error, msg ) return ( @@ -165,7 +166,7 @@ def clone(self): def _cloneFolder(self, folder_name, folder_id, dest_id): LOGGER.info(f"Syncing: {folder_name}") - files = self.getFilesByFolderId(folder_id) + files = self.get_files_by_folder_id(folder_id) if len(files) == 0: return dest_id for file in files: @@ -187,7 +188,7 @@ def _cloneFolder(self, folder_name, folder_id, dest_id): elif ( not file.get("name") .lower() - .endswith(tuple(self.listener.extensionFilter)) + .endswith(tuple(self.listener.extension_filter)) ): self.total_files += 1 self._copyFile( @@ -199,7 +200,7 @@ def _cloneFolder(self, folder_name, folder_id, dest_id): 0 )) self.total_time = int(time() - self._start_time) - if self.listener.isCancelled: + if self.listener.is_cancelled: break @retry( @@ -244,9 +245,9 @@ def _copyFile(self, file_id, dest_id): ) raise err else: - if self.listener.isCancelled: + if self.listener.is_cancelled: return - self.switchServiceAccount() + self.switch_service_account() return self._copyFile( file_id, dest_id diff --git a/bot/helper/task_utils/gdrive_utils/count.py b/bot/helper/task_utils/gdrive_utils/count.py index ffc2efb81451..93951fc923ec 100644 --- a/bot/helper/task_utils/gdrive_utils/count.py +++ b/bot/helper/task_utils/gdrive_utils/count.py @@ -1,19 +1,26 @@ from logging import getLogger from tenacity import RetryError -from bot.helper.task_utils.gdrive_utils.helper import GoogleDriveHelper +from ...task_utils.gdrive_utils.helper import GoogleDriveHelper LOGGER = getLogger(__name__) -class gdCount(GoogleDriveHelper): +class GoogleDriveCount(GoogleDriveHelper): + def __init__(self): super().__init__() def count(self, link, user_id): try: - file_id = self.getIdFromUrl(link, user_id) - except (KeyError, IndexError): + file_id = self.get_id_from_url( + link, + user_id + ) + except ( + KeyError, + IndexError + ): return ( "Google Drive ID could not be found in the provided link", None, @@ -21,6 +28,7 @@ def count(self, link, user_id): None, None, ) + self.service = self.authorize() LOGGER.info(f"File ID: {file_id}") try: @@ -60,18 +68,18 @@ def count(self, link, user_id): ) def _proceed_count(self, file_id): - meta = self.getFileMetadata(file_id) + meta = self.get_file_metadata(file_id) name = meta["name"] LOGGER.info(f"Counting: {name}") mime_type = meta.get("mimeType") if mime_type == self.G_DRIVE_DIR_MIME_TYPE: - self._gDrive_directory(meta) + self._google_drive_directory(meta) mime_type = "Folder" else: if mime_type is None: mime_type = "File" self.total_files += 1 - self._gDrive_file(meta) + self._google_drive_file(meta) return ( name, mime_type, @@ -80,15 +88,15 @@ def _proceed_count(self, file_id): self.total_folders ) - def _gDrive_file(self, filee): + def _google_drive_file(self, filee): size = int(filee.get( "size", 0 )) self.proc_bytes += size - def _gDrive_directory(self, drive_folder): - files = self.getFilesByFolderId(drive_folder["id"]) + def _google_drive_directory(self, drive_folder): + files = self.get_files_by_folder_id(drive_folder["id"]) if len(files) == 0: return for filee in files: @@ -96,12 +104,12 @@ def _gDrive_directory(self, drive_folder): if shortcut_details is not None: mime_type = shortcut_details["targetMimeType"] file_id = shortcut_details["targetId"] - filee = self.getFileMetadata(file_id) + filee = self.get_file_metadata(file_id) else: mime_type = filee.get("mimeType") if mime_type == self.G_DRIVE_DIR_MIME_TYPE: self.total_folders += 1 - self._gDrive_directory(filee) + self._google_drive_directory(filee) else: self.total_files += 1 - self._gDrive_file(filee) + self._google_drive_file(filee) diff --git a/bot/helper/task_utils/gdrive_utils/delete.py b/bot/helper/task_utils/gdrive_utils/delete.py index 67dc29d05354..94bc53999434 100644 --- a/bot/helper/task_utils/gdrive_utils/delete.py +++ b/bot/helper/task_utils/gdrive_utils/delete.py @@ -1,18 +1,19 @@ from googleapiclient.errors import HttpError from logging import getLogger -from bot.helper.task_utils.gdrive_utils.helper import GoogleDriveHelper +from ...task_utils.gdrive_utils.helper import GoogleDriveHelper LOGGER = getLogger(__name__) -class gdDelete(GoogleDriveHelper): +class GoogleDriveDelete(GoogleDriveHelper): + def __init__(self): super().__init__() - def deletefile(self, link, user_id): + def delete_file(self, link, user_id): try: - file_id = self.getIdFromUrl( + file_id = self.get_id_from_url( link, user_id ) @@ -42,7 +43,7 @@ def deletefile(self, link, user_id): self.alt_auth = True self.use_sa = False LOGGER.error("File not found. Trying with token.pickle...") - return self.deletefile(link, user_id) + return self.delete_file(link, user_id) err = "File not found or insufficientFilePermissions!" LOGGER.error(f"Delete Result: {err}") msg = str(err) diff --git a/bot/helper/task_utils/gdrive_utils/download.py b/bot/helper/task_utils/gdrive_utils/download.py index e2b699547d3c..3ee96583f92a 100644 --- a/bot/helper/task_utils/gdrive_utils/download.py +++ b/bot/helper/task_utils/gdrive_utils/download.py @@ -11,14 +11,15 @@ RetryError, ) -from bot.helper.ext_utils.bot_utils import async_to_sync -from bot.helper.ext_utils.bot_utils import setInterval -from bot.helper.task_utils.gdrive_utils.helper import GoogleDriveHelper +from ...ext_utils.bot_utils import async_to_sync +from ...ext_utils.bot_utils import SetInterval +from ...task_utils.gdrive_utils.helper import GoogleDriveHelper LOGGER = getLogger(__name__) -class gdDownload(GoogleDriveHelper): +class GoogleDriveDownload(GoogleDriveHelper): + def __init__( self, listener, @@ -31,17 +32,17 @@ def __init__( self.is_downloading = True def download(self): - file_id = self.getIdFromUrl( + file_id = self.get_id_from_url( self.listener.link, - self.listener.userId + self.listener.user_id ) self.service = self.authorize() - self._updater = setInterval( + self._updater = SetInterval( self.update_interval, self.progress ) try: - meta = self.getFileMetadata(file_id) + meta = self.get_file_metadata(file_id) if meta.get("mimeType") == self.G_DRIVE_DIR_MIME_TYPE: self._download_folder( file_id, @@ -87,15 +88,15 @@ def download(self): return self.download() err = "File not found!" async_to_sync( - self.listener.onDownloadError, + self.listener.on_download_error, err ) - self.listener.isCancelled = True + self.listener.is_cancelled = True finally: self._updater.cancel() - if self.listener.isCancelled: + if self.listener.is_cancelled: return - async_to_sync(self.listener.onDownloadComplete) + async_to_sync(self.listener.on_download_complete) def _download_folder(self, folder_id, path, folder_name): folder_name = folder_name.replace( @@ -105,7 +106,7 @@ def _download_folder(self, folder_id, path, folder_name): if not ospath.exists(f"{path}/{folder_name}"): makedirs(f"{path}/{folder_name}") path += f"/{folder_name}" - result = self.getFilesByFolderId(folder_id) + result = self.get_files_by_folder_id(folder_id) if len(result) == 0: return result = sorted( @@ -129,7 +130,7 @@ def _download_folder(self, folder_id, path, folder_name): ) elif ( not ospath.isfile(f"{path}{filename}") - and not filename.lower().endswith(tuple(self.listener.extensionFilter)) + and not filename.lower().endswith(tuple(self.listener.extension_filter)) ): self._download_file( file_id, @@ -137,7 +138,7 @@ def _download_folder(self, folder_id, path, folder_name): filename, mime_type ) - if self.listener.isCancelled: + if self.listener.is_cancelled: break @retry( @@ -163,7 +164,7 @@ def _download_file(self, file_id, path, filename, mime_type): filename = f"{filename[:245]}{ext}" if self.listener.name.endswith(ext): self.listener.name = filename - if self.listener.isCancelled: + if self.listener.is_cancelled: return fh = FileIO( f"{path}/{filename}", @@ -177,7 +178,7 @@ def _download_file(self, file_id, path, filename, mime_type): done = False retries = 0 while not done: - if self.listener.isCancelled: + if self.listener.is_cancelled: fh.close() break try: @@ -211,9 +212,9 @@ def _download_file(self, file_id, path, filename, mime_type): ) raise err else: - if self.listener.isCancelled: + if self.listener.is_cancelled: return - self.switchServiceAccount() + self.switch_service_account() LOGGER.info(f"Got: {reason}, Trying Again...") return self._download_file( file_id, diff --git a/bot/helper/task_utils/gdrive_utils/helper.py b/bot/helper/task_utils/gdrive_utils/helper.py index 9aee9ace86b4..e47150a705ce 100644 --- a/bot/helper/task_utils/gdrive_utils/helper.py +++ b/bot/helper/task_utils/gdrive_utils/helper.py @@ -19,13 +19,14 @@ ) from bot import config_dict -from bot.helper.ext_utils.links_utils import is_gdrive_id +from ...ext_utils.links_utils import is_gdrive_id LOGGER = getLogger(__name__) getLogger("googleapiclient.discovery").setLevel(ERROR) class GoogleDriveHelper: + def __init__(self): self._OAUTH_SCOPE = ["https://www.googleapis.com/auth/drive"] self.token_path = "token.pickle" @@ -104,7 +105,7 @@ def authorize(self): cache_discovery=False ) - def switchServiceAccount(self): + def switch_service_account(self): if self.sa_index == self.sa_number - 1: self.sa_index = 0 else: @@ -113,7 +114,7 @@ def switchServiceAccount(self): LOGGER.info(f"Switching to {self.sa_index} index") self.service = self.authorize() - def getIdFromUrl(self, link, user_id=""): + def get_id_from_url(self, link, user_id=""): if ( user_id and link.startswith("mtp:") @@ -191,7 +192,7 @@ def set_permission(self, file_id): stop=stop_after_attempt(3), retry=retry_if_exception_type(Exception), ) - def getFileMetadata(self, file_id): + def get_file_metadata(self, file_id): return ( self.service.files() # type: ignore .get( @@ -211,7 +212,7 @@ def getFileMetadata(self, file_id): stop=stop_after_attempt(3), retry=retry_if_exception_type(Exception), ) - def getFilesByFolderId(self, folder_id, item_type=""): + def get_files_by_folder_id(self, folder_id, item_type=""): page_token = None files = [] if not item_type: @@ -291,43 +292,19 @@ def escapes(self, estr): ) return estr.strip() - """ - def get_recursive_list(self, file, rootId): - rtnlist = [] - if not rootId: - rootId = file.get("teamDriveId") - if rootId == "root": - rootId = self.service.files().get( - fileId="root", - fields="id" - ).execute().get("id") - x = file.get("name") - y = file.get("id") - while (y != rootId): - rtnlist.append(x) - file = self.service.files().get( - fileId=file.get("parents")[0], - supportsAllDrives=True, - fields="id, name, parents" - ).execute() - x = file.get("name") - y = file.get("id") - rtnlist.reverse() - return rtnlist - """ async def cancel_task(self): - self.listener.isCancelled = True # type: ignore + self.listener.is_cancelled = True # type: ignore if self.is_downloading: LOGGER.info(f"Cancelling Download: {self.listener.name}") # type: ignore - await self.listener.onDownloadError("Download stopped by user!") # type: ignore + await self.listener.on_download_error("Download stopped by user!") # type: ignore elif self.is_cloning: LOGGER.info(f"Cancelling Clone: {self.listener.name}") # type: ignore - await self.listener.onUploadError( # type: ignore + await self.listener.on_upload_error( # type: ignore "Your clone has been stopped and cloned data has been deleted!" ) elif self.is_uploading: LOGGER.info(f"Cancelling Upload: {self.listener.name}") # type: ignore - await self.listener.onUploadError( # type: ignore + await self.listener.on_upload_error( # type: ignore "Your upload has been stopped and uploaded data has been deleted!" ) diff --git a/bot/helper/task_utils/gdrive_utils/list.py b/bot/helper/task_utils/gdrive_utils/list.py index 00c35f28ae69..6cfbd6cd797b 100644 --- a/bot/helper/task_utils/gdrive_utils/list.py +++ b/bot/helper/task_utils/gdrive_utils/list.py @@ -16,18 +16,21 @@ from time import time from bot import config_dict -from bot.helper.ext_utils.bot_utils import update_user_ldata -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.bot_utils import ( + new_task, + update_user_ldata +) +from ...ext_utils.db_handler import database +from ...ext_utils.status_utils import ( get_readable_file_size, get_readable_time ) -from bot.helper.task_utils.gdrive_utils.helper import GoogleDriveHelper -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.message_utils import ( - sendMessage, - editMessage, - deleteMessage, +from ...task_utils.gdrive_utils.helper import GoogleDriveHelper +from ...telegram_helper.button_build import ButtonMaker +from ...telegram_helper.message_utils import ( + send_message, + edit_message, + delete_message, auto_delete_message, ) @@ -36,15 +39,16 @@ LIST_LIMIT = 6 +@new_task async def id_updates(_, query, obj): await query.answer() message = query.message data = query.data.split() if data[1] == "cancel": obj.id = "Task has been cancelled!" - obj.listener.isCancelled = True + obj.listener.is_cancelled = True obj.event.set() - await deleteMessage(message) + await delete_message(message) return if obj.query_proc: return @@ -84,7 +88,7 @@ async def id_updates(_, query, obj): ) await obj.get_items() else: - await deleteMessage(message) + await delete_message(message) obj.event.set() elif data[1] == "ps": if obj.page_step == int(data[2]): @@ -99,7 +103,7 @@ async def id_updates(_, query, obj): obj.item_type = data[2] await obj.get_items() elif data[1] == "cur": - await deleteMessage(message) + await delete_message(message) obj.event.set() elif data[1] == "def": if obj.token_path != obj.user_token_path: @@ -110,15 +114,15 @@ async def id_updates(_, query, obj): ) else: id_ = f"mtp:{obj.id}" - if id_ != obj.listener.userDict.get("gdrive_id"): + if id_ != obj.listener.user_dict.get("gdrive_id"): update_user_ldata( - obj.listener.userId, + obj.listener.user_id, "gdrive_id", id_ ) await obj.get_items_buttons() if config_dict["DATABASE_URL"]: - await DbManager().update_user_data(obj.listener.userId) + await database.update_user_data(obj.listener.user_id) elif data[1] == "owner": obj.token_path = "token.pickle" obj.use_sa = False @@ -140,7 +144,7 @@ async def id_updates(_, query, obj): obj.query_proc = False -class gdriveList(GoogleDriveHelper): +class GoogleDriveList(GoogleDriveHelper): def __init__(self, listener): self.listener = listener self._token_user = False @@ -153,7 +157,7 @@ def __init__(self, listener): self.query_proc = False self.item_type = "folders" self.event = Event() - self.user_token_path = f"tokens/{self.listener.userId}.pickle" + self.user_token_path = f"tokens/{self.listener.user_id}.pickle" self.id = "" self.parents = [] self.list_status = "" @@ -167,7 +171,7 @@ async def _event_handler(self): handler = self.listener.client.add_handler( CallbackQueryHandler( pfunc, - filters=regex("^gdq") & user(self.listener.userId) + filters=regex("^gdq") & user(self.listener.user_id) ), group=-1, ) @@ -178,7 +182,7 @@ async def _event_handler(self): ) except: self.id = "Timed Out. Task has been cancelled!" - self.listener.isCancelled = True + self.listener.is_cancelled = True await auto_delete_message( self.listener.message, self.id @@ -188,15 +192,15 @@ async def _event_handler(self): self.listener.client.remove_handler(*handler) async def _send_list_message(self, msg, button): - if not self.listener.isCancelled: + if not self.listener.is_cancelled: if self._reply_to is None: - self._reply_to = await sendMessage( + self._reply_to = await send_message( self.listener.message, msg, button ) else: - await editMessage( + await edit_message( self._reply_to, msg, button @@ -229,7 +233,7 @@ async def get_items_buttons(self): else: ptype = "fi" name = f"[{get_readable_file_size(float(item['size']))}] {item['name']}" # type: ignore - buttons.ibutton( + buttons.data_button( name, f"gdq pa {ptype} {orig_index}" ) @@ -244,30 +248,30 @@ async def get_items_buttons(self): 50, 100 ]: - buttons.ibutton( + buttons.data_button( i, f"gdq ps {i}", position="header" ) - buttons.ibutton( + buttons.data_button( "Previous", "gdq pre", position="footer" ) - buttons.ibutton( + buttons.data_button( "Next", "gdq nex", position="footer" ) if self.list_status == "gdd": if self.item_type == "folders": - buttons.ibutton( + buttons.data_button( "Files", "gdq itype files", position="footer" ) else: - buttons.ibutton( + buttons.data_button( "Folders", "gdq itype folders", position="footer" @@ -276,13 +280,13 @@ async def get_items_buttons(self): "gdu" or len(self.items_list) > 0 ): - buttons.ibutton( + buttons.data_button( "Choose Current Path", "gdq cur", position="footer" ) if self.list_status == "gdu": - buttons.ibutton( + buttons.data_button( "Set as Default Path", "gdq def", position="footer" @@ -293,18 +297,18 @@ async def get_items_buttons(self): or self._token_user and self._token_owner ): - buttons.ibutton( + buttons.data_button( "Back", "gdq back pa", position="footer" ) if len(self.parents) > 1: - buttons.ibutton( + buttons.data_button( "Back To Root", "gdq root", position="footer" ) - buttons.ibutton( + buttons.data_button( "Cancel", "gdq cancel", position="footer" @@ -317,7 +321,7 @@ async def get_items_buttons(self): ) if self.list_status == "gdu": default_id = ( - self.listener.userDict.get("gdrive_id") + self.listener.user_dict.get("gdrive_id") or config_dict["GDRIVE_ID"] ) msg += ( @@ -343,11 +347,11 @@ async def get_items(self, itype=""): elif self.list_status == "gdu": self.item_type == "folders" # type: ignore try: - files = self.getFilesByFolderId( + files = self.get_files_by_folder_id( self.id, self.item_type ) - if self.listener.isCancelled: + if self.listener.is_cancelled: return except Exception as err: if isinstance( @@ -412,12 +416,12 @@ async def list_drives(self): self._token_user and self._token_owner ): - buttons.ibutton( + buttons.data_button( "Back", "gdq back dr", position="footer" ) - buttons.ibutton( + buttons.data_button( "Cancel", "gdq cancel", position="footer" @@ -456,7 +460,7 @@ async def list_drives(self): self.drives.clear() self.parents.clear() if not self.use_sa: - buttons.ibutton( + buttons.data_button( "root", "gdq dr 0" ) @@ -476,17 +480,17 @@ async def list_drives(self): "name": item["name"] } ) - buttons.ibutton( + buttons.data_button( item["name"], f"gdq dr {index}" ) if self._token_user and self._token_owner: - buttons.ibutton( + buttons.data_button( "Back", "gdq back dr", position="footer" ) - buttons.ibutton( + buttons.data_button( "Cancel", "gdq cancel", position="footer" @@ -516,21 +520,21 @@ async def choose_token(self): ) buttons = ButtonMaker() if self._token_owner: - buttons.ibutton( + buttons.data_button( "Owner Token", "gdq owner" ) if self._sa_owner: - buttons.ibutton( + buttons.data_button( "Service Accounts", "gdq sa" ) if self._token_user: - buttons.ibutton( + buttons.data_button( "My Token", "gdq user" ) - buttons.ibutton( + buttons.data_button( "Cancel", "gdq cancel" ) @@ -588,8 +592,8 @@ async def get_target_id(self, status, token_path=None): await self.list_drives() await self._event_handler() if self._reply_to: - await deleteMessage(self._reply_to) - if not self.listener.isCancelled: + await delete_message(self._reply_to) + if not self.listener.is_cancelled: if self.token_path == self.user_token_path: return f"mtp:{self.id}" else: diff --git a/bot/helper/task_utils/gdrive_utils/search.py b/bot/helper/task_utils/gdrive_utils/search.py index 908ce8ba4c52..8463686fb5b7 100644 --- a/bot/helper/task_utils/gdrive_utils/search.py +++ b/bot/helper/task_utils/gdrive_utils/search.py @@ -2,49 +2,50 @@ from bot import ( config_dict, - DRIVES_NAMES, - DRIVES_IDS, - INDEX_URLS, + drives_names, + drives_ids, + index_urls, user_data ) -from bot.helper.ext_utils.status_utils import get_readable_file_size -from bot.helper.task_utils.gdrive_utils.helper import GoogleDriveHelper +from ...ext_utils.status_utils import get_readable_file_size +from ...task_utils.gdrive_utils.helper import GoogleDriveHelper LOGGER = getLogger(__name__) -class gdSearch(GoogleDriveHelper): +class GoogleDriveSearch(GoogleDriveHelper): + def __init__( self, - stopDup=False, - noMulti=False, - isRecursive=True, - itemType="" + stop_dup=False, + no_multi=False, + is_recursive=True, + item_type="" ): super().__init__() - self._stopDup = stopDup - self._noMulti = noMulti - self._isRecursive = isRecursive - self._itemType = itemType + self._stop_dup = stop_dup + self._no_multi = no_multi + self._is_recursive = is_recursive + self._item_type = item_type - def _drive_query(self, dirId, fileName, isRecursive): + def _drive_query(self, dir_id, file_name, is_recursive): try: - if isRecursive: - if self._stopDup: - query = f"name = '{fileName}' and " + if is_recursive: + if self._stop_dup: + query = f"name = '{file_name}' and " else: - fileName = fileName.split() + file_name = file_name.split() query = "".join( f"name contains '{name}' and " - for name in fileName + for name in file_name if name != "" ) - if self._itemType == "files": + if self._item_type == "files": query += f"mimeType != '{self.G_DRIVE_DIR_MIME_TYPE}' and " - elif self._itemType == "folders": + elif self._item_type == "folders": query += f"mimeType = '{self.G_DRIVE_DIR_MIME_TYPE}' and " query += "trashed = false" - if dirId == "root": + if dir_id == "root": return ( self.service.files() .list( @@ -62,7 +63,7 @@ def _drive_query(self, dirId, fileName, isRecursive): .list( supportsAllDrives=True, includeItemsFromAllDrives=True, - driveId=dirId, + driveId=dir_id, q=query, spaces="drive", pageSize=150, @@ -73,17 +74,17 @@ def _drive_query(self, dirId, fileName, isRecursive): .execute() ) else: - if self._stopDup: - query = f"'{dirId}' in parents and name = '{fileName}' and " + if self._stop_dup: + query = f"'{dir_id}' in parents and name = '{file_name}' and " else: - query = f"'{dirId}' in parents and " - fileName = fileName.split() - for name in fileName: + query = f"'{dir_id}' in parents and " + file_name = file_name.split() + for name in file_name: if name != "": query += f"name contains '{name}' and " - if self._itemType == "files": + if self._item_type == "files": query += f"mimeType != '{self.G_DRIVE_DIR_MIME_TYPE}' and " - elif self._itemType == "folders": + elif self._item_type == "folders": query += f"mimeType = '{self.G_DRIVE_DIR_MIME_TYPE}' and " query += "trashed = false" return ( @@ -110,9 +111,9 @@ def _drive_query(self, dirId, fileName, isRecursive): LOGGER.error(err) return {"files": []} - def drive_list(self, fileName, target_id="", user_id=""): + def drive_list(self, file_name, target_id="", user_id=""): msg = "" - fileName = self.escapes(str(fileName)) + file_name = self.escapes(str(file_name)) contents_no = 0 telegraph_content = [] Title = False @@ -131,44 +132,48 @@ def drive_list(self, fileName, target_id="", user_id=""): "", 1 ), - INDEX_URLS[0] - if INDEX_URLS + index_urls[0] + if index_urls else "", ) ] else: drives = zip( - DRIVES_NAMES, - DRIVES_IDS, - INDEX_URLS + drives_names, + drives_ids, + index_urls ) if ( not target_id.startswith("mtp:") - and len(DRIVES_IDS) > 1 + and len(drives_ids) > 1 or target_id.startswith("tp:") ): self.use_sa = False self.service = self.authorize() - for drive_name, dir_id, index_url in drives: + for ( + drive_name, + dir_id, + index_url + ) in drives: isRecur = ( False - if self._isRecursive and len(dir_id) > 23 - else self._isRecursive + if self._is_recursive and len(dir_id) > 23 + else self._is_recursive ) response = self._drive_query( dir_id, - fileName, + file_name, isRecur ) if not response["files"]: - if self._noMulti: + if self._no_multi: break else: continue if not Title: - msg += f"

Search Result For {fileName}

" + msg += f"

Search Result For {file_name}

" Title = True if drive_name: msg += f"╾────────────╼
{drive_name}
╾────────────╼
" @@ -207,7 +212,7 @@ def drive_list(self, fileName, target_id="", user_id=""): if len(msg.encode("utf-8")) > 39000: telegraph_content.append(msg) msg = "" - if self._noMulti: + if self._no_multi: break if msg != "": diff --git a/bot/helper/task_utils/gdrive_utils/upload.py b/bot/helper/task_utils/gdrive_utils/upload.py index d4038f07a38e..2c8b9b5511fb 100644 --- a/bot/helper/task_utils/gdrive_utils/upload.py +++ b/bot/helper/task_utils/gdrive_utils/upload.py @@ -15,17 +15,18 @@ ) from bot import config_dict -from bot.helper.ext_utils.bot_utils import ( +from ...ext_utils.bot_utils import ( async_to_sync, - setInterval + SetInterval ) -from bot.helper.ext_utils.files_utils import get_mime_type -from bot.helper.task_utils.gdrive_utils.helper import GoogleDriveHelper +from ...ext_utils.files_utils import get_mime_type +from ...task_utils.gdrive_utils.helper import GoogleDriveHelper LOGGER = getLogger(__name__) -class gdUpload(GoogleDriveHelper): +class GoogleDriveUpload(GoogleDriveHelper): + def __init__( self, listener, @@ -39,23 +40,23 @@ def __init__( self.is_uploading = True def user_setting(self): - if self.listener.upDest.startswith("mtp:"): - self.token_path = f"tokens/{self.listener.userId}.pickle" - self.listener.upDest = self.listener.upDest.replace( + if self.listener.up_dest.startswith("mtp:"): + self.token_path = f"tokens/{self.listener.user_id}.pickle" + self.listener.up_dest = self.listener.up_dest.replace( "mtp:", "", 1 ) self.use_sa = False - elif self.listener.upDest.startswith("tp:"): - self.listener.upDest = self.listener.upDest.replace( + elif self.listener.up_dest.startswith("tp:"): + self.listener.up_dest = self.listener.up_dest.replace( "tp:", "", 1 ) self.use_sa = False - elif self.listener.upDest.startswith("sa:"): - self.listener.upDest = self.listener.upDest.replace( + elif self.listener.up_dest.startswith("sa:"): + self.listener.up_dest = self.listener.up_dest.replace( "sa:", "", 1 @@ -66,13 +67,13 @@ def upload(self, unwanted_files, ft_delete): self.user_setting() self.service = self.authorize() LOGGER.info(f"Uploading: {self._path}") - self._updater = setInterval( + self._updater = SetInterval( self.update_interval, self.progress ) try: if ospath.isfile(self._path): - if self._path.lower().endswith(tuple(self.listener.extensionFilter)): + if self._path.lower().endswith(tuple(self.listener.extension_filter)): raise Exception( "This file extension is excluded by extension filter!" ) @@ -81,11 +82,11 @@ def upload(self, unwanted_files, ft_delete): self._path, self.listener.name, mime_type, - self.listener.upDest, + self.listener.up_dest, ft_delete, in_dir=False, ) - if self.listener.isCancelled: + if self.listener.is_cancelled: return if link is None: raise Exception("Upload has been manually cancelled") @@ -94,7 +95,7 @@ def upload(self, unwanted_files, ft_delete): mime_type = "Folder" dir_id = self.create_directory( ospath.basename(ospath.abspath(self.listener.name)), - self.listener.upDest, + self.listener.up_dest, ) result = self._upload_dir( self._path, @@ -105,7 +106,7 @@ def upload(self, unwanted_files, ft_delete): if result is None: raise Exception("Upload has been manually cancelled!") link = self.G_DRIVE_DIR_BASE_DOWNLOAD_URL.format(dir_id) - if self.listener.isCancelled: + if self.listener.is_cancelled: return LOGGER.info(f"Uploaded To G-Drive: {self.listener.name}") except Exception as err: @@ -123,14 +124,14 @@ def upload(self, unwanted_files, ft_delete): "" ) async_to_sync( - self.listener.onUploadError, + self.listener.on_upload_error, err ) self._is_errored = True finally: self._updater.cancel() if ( - self.listener.isCancelled + self.listener.is_cancelled and not self._is_errored ): if mime_type == "Folder": @@ -148,7 +149,7 @@ def upload(self, unwanted_files, ft_delete): self.total_files, self.total_folders, mime_type, - dir_id=self.getIdFromUrl(link), + dir_id=self.get_id_from_url(link), ) def _upload_dir(self, input_directory, dest_id, unwanted_files, ft_delete): @@ -175,7 +176,7 @@ def _upload_dir(self, input_directory, dest_id, unwanted_files, ft_delete): self.total_folders += 1 elif ( current_file_name not in unwanted_files - and not item.lower().endswith(tuple(self.listener.extensionFilter)) + and not item.lower().endswith(tuple(self.listener.extension_filter)) ): mime_type = get_mime_type(current_file_name) file_name = current_file_name.split("/")[-1] @@ -191,11 +192,11 @@ def _upload_dir(self, input_directory, dest_id, unwanted_files, ft_delete): else: if ( not self.listener.seed - or self.listener.newDir + or self.listener.new_dir ): remove(current_file_name) new_id = "filter" - if self.listener.isCancelled: + if self.listener.is_cancelled: break return new_id @@ -266,7 +267,7 @@ def _upload_file( ) response = None retries = 0 - while response is None and not self.listener.isCancelled: + while response is None and not self.listener.is_cancelled: try: self.status, response = drive_file.next_chunk() except HttpError as err: @@ -298,9 +299,9 @@ def _upload_file( ) raise err else: - if self.listener.isCancelled: + if self.listener.is_cancelled: return - self.switchServiceAccount() + self.switch_service_account() LOGGER.info(f"Got: {reason}, Trying Again.") return self._upload_file( file_path, @@ -313,11 +314,11 @@ def _upload_file( else: LOGGER.error(f"Got: {reason}") raise err - if self.listener.isCancelled: + if self.listener.is_cancelled: return if ( not self.listener.seed - or self.listener.newDir + or self.listener.new_dir or file_path in ft_delete ): try: diff --git a/bot/helper/task_utils/rclone_utils/list.py b/bot/helper/task_utils/rclone_utils/list.py index 462ffdb6f71f..ee1bb1a7cb2a 100644 --- a/bot/helper/task_utils/rclone_utils/list.py +++ b/bot/helper/task_utils/rclone_utils/list.py @@ -1,10 +1,10 @@ from aiofiles import open as aiopen from aiofiles.os import path as aiopath from asyncio import ( - wait_for, Event, - wrap_future, - gather + gather, + wait_for, + wrap_future ) from configparser import ConfigParser from functools import partial @@ -16,28 +16,33 @@ from nekozee.handlers import CallbackQueryHandler from time import time -from bot import LOGGER, config_dict -from bot.helper.ext_utils.bot_utils import ( +from bot import ( + LOGGER, + config_dict +) +from ...ext_utils.bot_utils import ( cmd_exec, - new_thread, + loop_thread, + new_task, update_user_ldata, ) -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.db_handler import database +from ...ext_utils.status_utils import ( get_readable_file_size, get_readable_time ) -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.message_utils import ( - sendMessage, - editMessage, - deleteMessage, +from ...telegram_helper.button_build import ButtonMaker +from ...telegram_helper.message_utils import ( + send_message, + edit_message, + delete_message, auto_delete_message, ) LIST_LIMIT = 6 +@new_task async def path_updates(_, query, obj): await query.answer() message = query.message @@ -45,9 +50,9 @@ async def path_updates(_, query, obj): if data[1] == "cancel": obj.remote = "Task has been cancelled!" obj.path = "" - obj.listener.isCancelled = True + obj.listener.is_cancelled = True obj.event.set() - await deleteMessage(message) + await delete_message(message) return if obj.query_proc: return @@ -78,7 +83,7 @@ async def path_updates(_, query, obj): if data[2] == "fo": await obj.get_path() else: - await deleteMessage(message) + await delete_message(message) obj.event.set() elif data[1] == "ps": if obj.page_step == int(data[2]): @@ -92,7 +97,7 @@ async def path_updates(_, query, obj): obj.item_type = data[2] await obj.get_path() elif data[1] == "cur": - await deleteMessage(message) + await delete_message(message) obj.event.set() elif data[1] == "def": path = ( @@ -100,15 +105,15 @@ async def path_updates(_, query, obj): if obj.config_path == "rclone.conf" else f"mrcc:{obj.remote}{obj.path}" ) - if path != obj.listener.userDict.get("rclone_path"): + if path != obj.listener.user_dict.get("rclone_path"): update_user_ldata( - obj.listener.userId, + obj.listener.user_id, "rclone_path", path ) await obj.get_path_buttons() if config_dict["DATABASE_URL"]: - await DbManager().update_user_data(obj.listener.userId) + await database.update_user_data(obj.listener.user_id) elif data[1] == "owner": obj.config_path = "rclone.conf" obj.path = "" @@ -123,6 +128,7 @@ async def path_updates(_, query, obj): class RcloneList: + def __init__( self, listener @@ -138,7 +144,7 @@ def __init__( self.query_proc = False self.item_type = "--dirs-only" self.event = Event() - self.user_rcc_path = f"rclone/{self.listener.userId}.conf" + self.user_rcc_path = f"rclone/{self.listener.user_id}.conf" self.config_path = "" self.path = "" self.list_status = "" @@ -146,7 +152,7 @@ def __init__( self.iter_start = 0 self.page_step = 1 - @new_thread + @loop_thread async def _event_handler(self): pfunc = partial( path_updates, @@ -155,7 +161,7 @@ async def _event_handler(self): handler = self.listener.client.add_handler( CallbackQueryHandler( pfunc, - filters=regex("^rcq") & user(self.listener.userId) + filters=regex("^rcq") & user(self.listener.user_id) ), group=-1, ) @@ -167,7 +173,7 @@ async def _event_handler(self): except: self.path = "" self.remote = "Timed Out. Task has been cancelled!" - self.listener.isCancelled = True + self.listener.is_cancelled = True await auto_delete_message( self.listener.message, self.remote @@ -177,15 +183,15 @@ async def _event_handler(self): self.listener.client.remove_handler(*handler) async def _send_list_message(self, msg, button): - if not self.listener.isCancelled: + if not self.listener.is_cancelled: if self._reply_to is None: - self._reply_to = await sendMessage( + self._reply_to = await send_message( self.listener.message, msg, button ) else: - await editMessage( + await edit_message( self._reply_to, msg, button @@ -214,7 +220,7 @@ async def get_path_buttons(self): else: ptype = "fi" name = f"[{get_readable_file_size(idict['Size'])}] {idict['Path']}" - buttons.ibutton( + buttons.data_button( name, f"rcq pa {ptype} {orig_index}" ) @@ -229,30 +235,30 @@ async def get_path_buttons(self): 50, 100 ]: - buttons.ibutton( + buttons.data_button( i, f"rcq ps {i}", position="header" ) - buttons.ibutton( + buttons.data_button( "Previous", "rcq pre", position="footer" ) - buttons.ibutton( + buttons.data_button( "Next", "rcq nex", position="footer" ) if self.list_status == "rcd": if self.item_type == "--dirs-only": - buttons.ibutton( + buttons.data_button( "Files", "rcq itype --files-only", position="footer" ) else: - buttons.ibutton( + buttons.data_button( "Folders", "rcq itype --dirs-only", position="footer" @@ -261,13 +267,13 @@ async def get_path_buttons(self): self.list_status == "rcu" or len(self.path_list) > 0 ): - buttons.ibutton( + buttons.data_button( "Choose Current Path", "rcq cur", position="footer" ) if self.list_status == "rcu": - buttons.ibutton( + buttons.data_button( "Set as Default Path", "rcq def", position="footer" @@ -278,18 +284,18 @@ async def get_path_buttons(self): or self._rc_user and self._rc_owner ): - buttons.ibutton( + buttons.data_button( "Back", "rcq back pa", position="footer" ) if self.path: - buttons.ibutton( + buttons.data_button( "Back To Root", "rcq root", position="footer" ) - buttons.ibutton( + buttons.data_button( "Cancel", "rcq cancel", position="footer" @@ -331,7 +337,7 @@ async def get_path(self, itype=""): self.config_path, f"{self.remote}{self.path}", ] - if self.listener.isCancelled: + if self.listener.is_cancelled: return ( res, @@ -394,17 +400,17 @@ async def list_remotes(self): ) buttons = ButtonMaker() for remote in self._sections: - buttons.ibutton( + buttons.data_button( remote, f"rcq re {remote}:" ) if self._rc_user and self._rc_owner: - buttons.ibutton( + buttons.data_button( "Back", "rcq back re", position="footer" ) - buttons.ibutton( + buttons.data_button( "Cancel", "rcq cancel", position="footer" @@ -426,15 +432,15 @@ async def list_config(self): f"\nTimeout: {get_readable_time(self._timeout - (time() - self._time))}" # type: ignore ) buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "Owner Config", "rcq owner" ) - buttons.ibutton( + buttons.data_button( "My Config", "rcq user" ) - buttons.ibutton( + buttons.data_button( "Cancel", "rcq cancel" ) @@ -484,10 +490,10 @@ async def get_rclone_path(self, status, config_path=None): self.config_path = config_path await self.list_remotes() await wrap_future(future) # type: ignore - await deleteMessage(self._reply_to) + await delete_message(self._reply_to) if ( self.config_path != "rclone.conf" - and not self.listener.isCancelled + and not self.listener.is_cancelled ): return f"mrcc:{self.remote}{self.path}" return f"{self.remote}{self.path}" diff --git a/bot/helper/task_utils/rclone_utils/transfer.py b/bot/helper/task_utils/rclone_utils/transfer.py index 70ec6736d577..2cfbe26d5f2f 100644 --- a/bot/helper/task_utils/rclone_utils/transfer.py +++ b/bot/helper/task_utils/rclone_utils/transfer.py @@ -16,11 +16,11 @@ from re import findall as re_findall from bot import config_dict -from bot.helper.ext_utils.bot_utils import ( +from ...ext_utils.bot_utils import ( cmd_exec, sync_to_async ) -from bot.helper.ext_utils.files_utils import ( +from ...ext_utils.files_utils import ( get_mime_type, count_files_and_folders, clean_unwanted, @@ -68,7 +68,7 @@ def size(self): async def _progress(self): while not ( self._proc is None - or self._listener.isCancelled + or self._listener.is_cancelled ): try: data = (await self._proc.stdout.readline()).decode() # type: ignore @@ -88,7 +88,7 @@ async def _progress(self): self._eta, ) = data[0] - def _switchServiceAccount(self): + def _switch_service_account(self): if self._sa_index == self._sa_number - 1: self._sa_index = 0 else: @@ -146,11 +146,11 @@ async def _start_download(self, cmd, remote_type): self._proc.wait() ) - if self._listener.isCancelled: + if self._listener.is_cancelled: return if return_code == 0: - await self._listener.onDownloadComplete() + await self._listener.on_download_complete() elif return_code != -9: error = (await self._proc.stderr.read()).decode().strip() # type: ignore if ( @@ -170,12 +170,12 @@ async def _start_download(self, cmd, remote_type): and self._use_service_accounts ): if self._sa_count < self._sa_number: - remote = self._switchServiceAccount() + remote = self._switch_service_account() cmd[6] = f"{remote}:{cmd[6].split( ':', 1 )[1]}" - if self._listener.isCancelled: + if self._listener.is_cancelled: return return await self._start_download( cmd, @@ -186,7 +186,7 @@ async def _start_download(self, cmd, remote_type): f"Reached maximum number of service accounts switching, which is {self._sa_count}" ) - await self._listener.onDownloadError(error[:4000]) + await self._listener.on_download_error(error[:4000]) async def download(self, remote, config_path, path): self._is_download = True @@ -196,7 +196,7 @@ async def download(self, remote, config_path, path): remote ) except Exception as err: - await self._listener.onDownloadError(str(err)) + await self._listener.on_download_error(str(err)) return remote_type = remote_opts["type"] @@ -218,7 +218,7 @@ async def download(self, remote, config_path, path): remote = f"sa{self._sa_index:03}" LOGGER.info(f"Download with service account {remote}") - cmd = self._getUpdatedCommand( + cmd = self._get_updated_command( config_path, f"{remote}:{self._listener.link}", path, @@ -228,7 +228,7 @@ async def download(self, remote, config_path, path): if ( remote_type == "drive" and not config_dict["RCLONE_FLAGS"] - and not self._listener.rcFlags + and not self._listener.rc_flags ): cmd.append("--drive-acknowledge-abuse") elif remote_type != "drive": @@ -315,7 +315,7 @@ async def _start_upload(self, cmd, remote_type): self._proc.wait() ) - if self._listener.isCancelled: + if self._listener.is_cancelled: return False if return_code == -9: @@ -338,14 +338,14 @@ async def _start_upload(self, cmd, remote_type): and self._use_service_accounts ): if self._sa_count < self._sa_number: - remote = self._switchServiceAccount() + remote = self._switch_service_account() cmd[7] = f"{remote}:{cmd[7].split( ':', 1 )[1]}" return ( False - if self._listener.isCancelled + if self._listener.is_cancelled else await self._start_upload( cmd, remote_type @@ -355,20 +355,20 @@ async def _start_upload(self, cmd, remote_type): LOGGER.info( f"Reached maximum number of service accounts switching, which is {self._sa_count}" ) - await self._listener.onUploadError(error[:4000]) + await self._listener.on_upload_error(error[:4000]) return False else: return True async def upload(self, path, unwanted_files, ft_delete): self._is_upload = True - rc_path = self._listener.upDest.strip("/") + rc_path = self._listener.up_dest.strip("/") if rc_path.startswith("mrcc:"): rc_path = rc_path.split( "mrcc:", 1 )[1] - oconfig_path = f"rclone/{self._listener.userId}.conf" + oconfig_path = f"rclone/{self._listener.user_id}.conf" else: oconfig_path = "rclone.conf" @@ -381,7 +381,7 @@ async def upload(self, path, unwanted_files, ft_delete): mime_type = "Folder" folders, files = await count_files_and_folders( path, - self._listener.extensionFilter, + self._listener.extension_filter, unwanted_files ) rc_path += ( @@ -390,8 +390,8 @@ async def upload(self, path, unwanted_files, ft_delete): else self._listener.name ) else: - if path.lower().endswith(tuple(self._listener.extensionFilter)): - await self._listener.onUploadError( + if path.lower().endswith(tuple(self._listener.extension_filter)): + await self._listener.on_upload_error( "This file extension is excluded by extension filter!" ) return @@ -408,7 +408,7 @@ async def upload(self, path, unwanted_files, ft_delete): oremote ) except Exception as err: - await self._listener.onUploadError(str(err)) + await self._listener.on_upload_error(str(err)) return remote_type = remote_opts["type"] @@ -435,10 +435,10 @@ async def upload(self, path, unwanted_files, ft_delete): method = ( "move" if not self._listener.seed - or self._listener.newDir + or self._listener.new_dir else "copy" ) - cmd = self._getUpdatedCommand( + cmd = self._get_updated_command( fconfig_path, path, f"{fremote}:{rc_path}", @@ -448,7 +448,7 @@ async def upload(self, path, unwanted_files, ft_delete): if ( remote_type == "drive" and not config_dict["RCLONE_FLAGS"] - and not self._listener.rcFlags + and not self._listener.rc_flags ): cmd.extend(( "--drive-chunk-size", @@ -502,12 +502,12 @@ async def upload(self, path, unwanted_files, ft_delete): err = "Use /shell cat rlog.txt to see more information" LOGGER.error(f"while getting link. Path: {destination} | Stderr: {err}") link = "" - if self._listener.isCancelled: + if self._listener.is_cancelled: return LOGGER.info(f"Upload Done. Path: {destination}") if ( self._listener.seed and not - self._listener.newDir + self._listener.new_dir ): await clean_unwanted( path, @@ -522,7 +522,7 @@ async def upload(self, path, unwanted_files, ft_delete): ) async def clone(self, config_path, src_remote, src_path, mime_type, method): - destination = self._listener.upDest + destination = self._listener.up_dest ( dst_remote, dst_path @@ -546,7 +546,7 @@ async def clone(self, config_path, src_remote, src_path, mime_type, method): ), ) except Exception as err: - await self._listener.onUploadError(str(err)) + await self._listener.on_upload_error(str(err)) return ( None, None @@ -560,14 +560,14 @@ async def clone(self, config_path, src_remote, src_path, mime_type, method): dst_remote_opt["type"], ) - cmd = self._getUpdatedCommand( + cmd = self._get_updated_command( config_path, f"{src_remote}:{src_path}", destination, method ) if ( - not self._listener.rcFlags + not self._listener.rc_flags and not config_dict["RCLONE_FLAGS"] ): if ( @@ -596,7 +596,7 @@ async def clone(self, config_path, src_remote, src_path, mime_type, method): self._proc.wait() ) - if self._listener.isCancelled: + if self._listener.is_cancelled: return ( None, None @@ -613,7 +613,7 @@ async def clone(self, config_path, src_remote, src_path, mime_type, method): or "Use /shell cat rlog.txt to see more information" ) LOGGER.error(error) - await self._listener.onUploadError(error[:4000]) + await self._listener.on_upload_error(error[:4000]) return ( None, None @@ -631,7 +631,7 @@ async def clone(self, config_path, src_remote, src_path, mime_type, method): None, None ) - if self._listener.isCancelled + if self._listener.is_cancelled else ( link, destination @@ -658,7 +658,7 @@ async def clone(self, config_path, src_remote, src_path, mime_type, method): code ) = await cmd_exec(cmd) - if self._listener.isCancelled: + if self._listener.is_cancelled: return ( None, None @@ -677,7 +677,7 @@ async def clone(self, config_path, src_remote, src_path, mime_type, method): destination ) - def _getUpdatedCommand( + def _get_updated_command( self, config_path, source, @@ -687,7 +687,7 @@ def _getUpdatedCommand( ): if unwanted_files is None: unwanted_files = [] - ext = "*.{" + ",".join(self._listener.extensionFilter) + "}" + ext = "*.{" + ",".join(self._listener.extension_filter) + "}" cmd = [ "rclone", method, @@ -711,7 +711,7 @@ def _getUpdatedCommand( "DEBUG", ] if rcflags := ( - self._listener.rcFlags + self._listener.rc_flags or config_dict["RCLONE_FLAGS"] ): rcflags = rcflags.split("|") @@ -763,7 +763,7 @@ async def _get_remote_options(config_path, remote): } async def cancel_task(self): - self._listener.isCancelled = True + self._listener.is_cancelled = True if self._proc is not None: try: self._proc.kill() @@ -771,10 +771,10 @@ async def cancel_task(self): pass if self._is_download: LOGGER.info(f"Cancelling Download: {self._listener.name}") - await self._listener.onDownloadError("Download stopped by user!") + await self._listener.on_download_error("Download stopped by user!") elif self._is_upload: LOGGER.info(f"Cancelling Upload: {self._listener.name}") - await self._listener.onUploadError("Your upload has been stopped!") + await self._listener.on_upload_error("Your upload has been stopped!") else: LOGGER.info(f"Cancelling Clone: {self._listener.name}") - await self._listener.onUploadError("Your clone has been stopped!") + await self._listener.on_upload_error("Your clone has been stopped!") diff --git a/bot/helper/task_utils/status_utils/aria2_status.py b/bot/helper/task_utils/status_utils/aria2_status.py index 9901d34fe809..b23b37063eea 100644 --- a/bot/helper/task_utils/status_utils/aria2_status.py +++ b/bot/helper/task_utils/status_utils/aria2_status.py @@ -1,8 +1,8 @@ from time import time from bot import aria2, LOGGER -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.bot_utils import sync_to_async +from ...ext_utils.status_utils import ( MirrorStatus, get_readable_time ) @@ -21,6 +21,7 @@ def get_download(gid, old_info=None): class Aria2Status: + def __init__( self, listener, @@ -113,11 +114,11 @@ def gid(self): return self._gid async def cancel_task(self): - self.listener.isCancelled = True + self.listener.is_cancelled = True await sync_to_async(self.update) if self._download.seeder and self.seeding: # type: ignore LOGGER.info(f"Cancelling Seed: {self.name()}") - await self.listener.onUploadError( + await self.listener.on_upload_error( f"Seeding stopped with Ratio: {self.ratio()} and Time: {self.seeding_time()}" ) await sync_to_async( @@ -128,7 +129,7 @@ async def cancel_task(self): ) elif downloads := self._download.followed_by: # type: ignore LOGGER.info(f"Cancelling Download: {self.name()}") - await self.listener.onDownloadError("Download cancelled by user!") + await self.listener.on_download_error("Download cancelled by user!") downloads.append(self._download) await sync_to_async( aria2.remove, @@ -143,7 +144,7 @@ async def cancel_task(self): else: LOGGER.info(f"Cancelling Download: {self.name()}") msg = "Download stopped by user!" - await self.listener.onDownloadError(msg) + await self.listener.on_download_error(msg) await sync_to_async( aria2.remove, [self._download], diff --git a/bot/helper/task_utils/status_utils/direct_status.py b/bot/helper/task_utils/status_utils/direct_status.py index 4299e2ba1ac4..a6d1375c8012 100644 --- a/bot/helper/task_utils/status_utils/direct_status.py +++ b/bot/helper/task_utils/status_utils/direct_status.py @@ -1,5 +1,5 @@ from bot import aria2 -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.status_utils import ( MirrorStatus, get_readable_file_size, get_readable_time, diff --git a/bot/helper/task_utils/status_utils/extract_status.py b/bot/helper/task_utils/status_utils/extract_status.py index ef73a237f119..5731e670fd70 100644 --- a/bot/helper/task_utils/status_utils/extract_status.py +++ b/bot/helper/task_utils/status_utils/extract_status.py @@ -1,8 +1,8 @@ from time import time from bot import LOGGER, subprocess_lock -from bot.helper.ext_utils.files_utils import get_path_size -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.files_utils import get_path_size +from ...ext_utils.status_utils import ( get_readable_file_size, MirrorStatus, get_readable_time, @@ -73,8 +73,8 @@ def processed_bytes(self): return get_readable_file_size(self._proccessed_bytes) async def processed_raw(self): - if self.listener.newDir: - self._proccessed_bytes = await get_path_size(self.listener.newDir) + if self.listener.new_dir: + self._proccessed_bytes = await get_path_size(self.listener.new_dir) else: self._proccessed_bytes = await get_path_size(self.listener.dir) - self._size @@ -83,11 +83,11 @@ def task(self): async def cancel_task(self): LOGGER.info(f"Cancelling Extract: {self.listener.name}") - self.listener.isCancelled = True + self.listener.is_cancelled = True async with subprocess_lock: if ( self.listener.suproc is not None and self.listener.suproc.returncode is None ): self.listener.suproc.kill() - await self.listener.onUploadError("extracting stopped by user!") + await self.listener.on_upload_error("extracting stopped by user!") diff --git a/bot/helper/task_utils/status_utils/gdrive_status.py b/bot/helper/task_utils/status_utils/gdrive_status.py index b33effc7f661..c072dc4acd59 100644 --- a/bot/helper/task_utils/status_utils/gdrive_status.py +++ b/bot/helper/task_utils/status_utils/gdrive_status.py @@ -1,4 +1,4 @@ -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.status_utils import ( MirrorStatus, get_readable_file_size, get_readable_time, @@ -6,7 +6,7 @@ from pkg_resources import get_distribution -class GdriveStatus: +class GoogleDriveStatus: def __init__( self, listener, diff --git a/bot/helper/task_utils/status_utils/jdownloader_status.py b/bot/helper/task_utils/status_utils/jdownloader_status.py index 0bbb89083d6f..43ed2724bc73 100644 --- a/bot/helper/task_utils/status_utils/jdownloader_status.py +++ b/bot/helper/task_utils/status_utils/jdownloader_status.py @@ -3,12 +3,12 @@ jd_lock, jd_downloads ) -from bot.helper.ext_utils.bot_utils import ( +from ...ext_utils.bot_utils import ( retry_function, async_to_sync ) -from bot.helper.ext_utils.jdownloader_booter import jdownloader -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.jdownloader_booter import jdownloader +from ...ext_utils.status_utils import ( MirrorStatus, get_readable_file_size, get_readable_time, @@ -177,7 +177,7 @@ def gid(self): return self._gid async def cancel_task(self): - self.listener.isCancelled = True + self.listener.is_cancelled = True LOGGER.info(f"Cancelling Download: {self.name()}") await retry_function( jdownloader.device.downloads.remove_links, # type: ignore @@ -185,4 +185,4 @@ async def cancel_task(self): ) async with jd_lock: del jd_downloads[int(self._gid)] - await self.listener.onDownloadError("Download cancelled by user!") + await self.listener.on_download_error("Download cancelled by user!") diff --git a/bot/helper/task_utils/status_utils/media_convert_status.py b/bot/helper/task_utils/status_utils/media_convert_status.py index 2301ad08b3ba..a0b52ba0d710 100644 --- a/bot/helper/task_utils/status_utils/media_convert_status.py +++ b/bot/helper/task_utils/status_utils/media_convert_status.py @@ -1,12 +1,12 @@ from time import time from bot import LOGGER -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.status_utils import ( get_readable_file_size, get_readable_time, MirrorStatus ) from subprocess import run as frun -from bot.helper.ext_utils.files_utils import get_path_size +from ...ext_utils.files_utils import get_path_size class MediaConvertStatus: @@ -69,8 +69,8 @@ def status(self): return MirrorStatus.STATUS_CONVERTING async def processed_raw(self): - if self.listener.newDir: - self._proccessed_bytes = await get_path_size(self.listener.newDir) + if self.listener.new_dir: + self._proccessed_bytes = await get_path_size(self.listener.new_dir) else: self._proccessed_bytes = await get_path_size(self.listener.dir) - self._size @@ -82,7 +82,7 @@ def task(self): async def cancel_task(self): LOGGER.info(f"Cancelling Converting: {self.listener.name}") - self.listener.isCancelled = True + self.listener.is_cancelled = True if self.listener.suproc is not None and self.listener.suproc.returncode is None: self.listener.suproc.kill() - await self.listener.onUploadError("Converting stopped by user!") + await self.listener.on_upload_error("Converting stopped by user!") diff --git a/bot/helper/task_utils/status_utils/mega_download_status.py b/bot/helper/task_utils/status_utils/mega_download_status.py index 3590adab03c5..5febd8481040 100644 --- a/bot/helper/task_utils/status_utils/mega_download_status.py +++ b/bot/helper/task_utils/status_utils/mega_download_status.py @@ -1,7 +1,6 @@ -#!/usr/bin/env python3 from mega import MegaApi -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.status_utils import ( MirrorStatus, get_readable_file_size, get_readable_time diff --git a/bot/helper/task_utils/status_utils/meta_status.py b/bot/helper/task_utils/status_utils/meta_status.py index bc20cb5e8d71..20ea0b7f1e41 100644 --- a/bot/helper/task_utils/status_utils/meta_status.py +++ b/bot/helper/task_utils/status_utils/meta_status.py @@ -2,14 +2,14 @@ LOGGER, subprocess_lock ) -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.status_utils import ( get_readable_file_size, get_readable_time, MirrorStatus ) from subprocess import run as frun from time import time -from bot.helper.ext_utils.files_utils import get_path_size +from ...ext_utils.files_utils import get_path_size class MetaStatus: @@ -53,11 +53,11 @@ def task(self): async def cancel_task(self): LOGGER.info(f"Cancelling metadata editor: {self.listener.name}") - self.listener.isCancelled = True + self.listener.is_cancelled = True async with subprocess_lock: if ( self.listener.suproc is not None and self.listener.suproc.returncode is None ): self.listener.suproc.kill() - await self.listener.onUploadError("Metadata editing stopped by user!") + await self.listener.on_upload_error("Metadata editing stopped by user!") diff --git a/bot/helper/task_utils/status_utils/nzb_status.py b/bot/helper/task_utils/status_utils/nzb_status.py index c1f7e1ea0ece..827f83fa6b19 100644 --- a/bot/helper/task_utils/status_utils/nzb_status.py +++ b/bot/helper/task_utils/status_utils/nzb_status.py @@ -6,8 +6,8 @@ nzb_jobs, nzb_listener_lock ) -from bot.helper.ext_utils.bot_utils import async_to_sync -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.bot_utils import async_to_sync +from ...ext_utils.status_utils import ( MirrorStatus, get_readable_file_size, get_readable_time, @@ -105,11 +105,11 @@ def gid(self): return self._gid async def cancel_task(self): - self.listener.isCancelled = True + self.listener.is_cancelled = True await self.update() LOGGER.info(f"Cancelling Download: {self.name()}") await gather( - self.listener.onDownloadError("Download stopped by user!"), + self.listener.on_download_error("Download stopped by user!"), sabnzbd_client.delete_job(self._gid, delete_files=True), sabnzbd_client.delete_category(f"{self.listener.mid}"), ) diff --git a/bot/helper/task_utils/status_utils/qbit_status.py b/bot/helper/task_utils/status_utils/qbit_status.py index d94ce95aa36a..440f237c7568 100644 --- a/bot/helper/task_utils/status_utils/qbit_status.py +++ b/bot/helper/task_utils/status_utils/qbit_status.py @@ -3,11 +3,11 @@ from bot import ( LOGGER, qbittorrent_client, - QbTorrents, + qb_torrents, qb_listener_lock ) -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.bot_utils import sync_to_async +from ...ext_utils.status_utils import ( MirrorStatus, get_readable_file_size, get_readable_time, @@ -131,7 +131,7 @@ def hash(self): return self._info.hash # type: ignore async def cancel_task(self): - self.listener.isCancelled = True + self.listener.is_cancelled = True await sync_to_async(self.update) await sync_to_async( qbittorrent_client.torrents_pause, @@ -146,7 +146,7 @@ async def cancel_task(self): msg = "Download stopped by user!" await sleep(0.3) await gather( - self.listener.onDownloadError(msg), + self.listener.on_download_error(msg), sync_to_async( qbittorrent_client.torrents_delete, torrent_hashes=self._info.hash, # type: ignore @@ -158,5 +158,5 @@ async def cancel_task(self): ), ) async with qb_listener_lock: - if self._info.tags in QbTorrents: # type: ignore - del QbTorrents[self._info.tags] # type: ignore + if self._info.tags in qb_torrents: # type: ignore + del qb_torrents[self._info.tags] # type: ignore diff --git a/bot/helper/task_utils/status_utils/queue_status.py b/bot/helper/task_utils/status_utils/queue_status.py index ce8b0c475d18..315bf5fd1afc 100644 --- a/bot/helper/task_utils/status_utils/queue_status.py +++ b/bot/helper/task_utils/status_utils/queue_status.py @@ -1,5 +1,5 @@ from bot import LOGGER -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.status_utils import ( get_readable_file_size, MirrorStatus ) @@ -39,13 +39,13 @@ def task(self): return self async def cancel_task(self): - self.listener.isCancelled = True + self.listener.is_cancelled = True LOGGER.info(f"Cancelling Queue{self._status}: {self.listener.name}") if self._status == "dl": - await self.listener.onDownloadError( + await self.listener.on_download_error( "task have been removed from queue/download" ) else: - await self.listener.onUploadError( + await self.listener.on_upload_error( "task have been removed from queue/upload" ) diff --git a/bot/helper/task_utils/status_utils/rclone_status.py b/bot/helper/task_utils/status_utils/rclone_status.py index b33781e6129c..3f801ffcae25 100644 --- a/bot/helper/task_utils/status_utils/rclone_status.py +++ b/bot/helper/task_utils/status_utils/rclone_status.py @@ -1,4 +1,4 @@ -from bot.helper.ext_utils.status_utils import MirrorStatus +from ...ext_utils.status_utils import MirrorStatus from subprocess import run as rrun diff --git a/bot/helper/task_utils/status_utils/sample_video_status.py b/bot/helper/task_utils/status_utils/sample_video_status.py index 1c2d82d40454..42940a017f05 100644 --- a/bot/helper/task_utils/status_utils/sample_video_status.py +++ b/bot/helper/task_utils/status_utils/sample_video_status.py @@ -1,12 +1,12 @@ from bot import LOGGER -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.status_utils import ( get_readable_file_size, MirrorStatus, get_readable_time ) from subprocess import run as frun from time import time -from bot.helper.ext_utils.files_utils import get_path_size +from ...ext_utils.files_utils import get_path_size class SampleVideoStatus: @@ -72,8 +72,8 @@ def status(self): async def processed_raw(self): try: - if self.listener.newDir: - self._proccessed_bytes = await get_path_size(self.listener.newDir) + if self.listener.new_dir: + self._proccessed_bytes = await get_path_size(self.listener.new_dir) else: self._proccessed_bytes = await get_path_size(self.listener.dir) - self._size except: @@ -90,10 +90,10 @@ def task(self): async def cancel_task(self): LOGGER.info(f"Cancelling Sample Video: {self.listener.name}") - self.listener.isCancelled = True + self.listener.is_cancelled = True if ( self.listener.suproc is not None and self.listener.suproc.returncode is None ): self.listener.suproc.kill() - await self.listener.onUploadError("Creating sample video stopped by user!") + await self.listener.on_upload_error("Creating sample video stopped by user!") diff --git a/bot/helper/task_utils/status_utils/split_status.py b/bot/helper/task_utils/status_utils/split_status.py index 5c0a2f96e1f0..7eb05e87eab1 100644 --- a/bot/helper/task_utils/status_utils/split_status.py +++ b/bot/helper/task_utils/status_utils/split_status.py @@ -2,14 +2,14 @@ LOGGER, subprocess_lock ) -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.status_utils import ( get_readable_file_size, get_readable_time, MirrorStatus ) from subprocess import run as frun from time import time -from bot.helper.ext_utils.files_utils import get_path_size +from ...ext_utils.files_utils import get_path_size class SplitStatus: @@ -26,7 +26,7 @@ def __init__( self.engine = self._eng_ver() def _eng_ver(self): - if self.listener.asDoc: + if self.listener.as_doc: pkg = "Split v" _engine = frun( [ @@ -89,8 +89,8 @@ def status(self): return MirrorStatus.STATUS_SPLITTING async def processed_raw(self): - if self.listener.newDir: - self._proccessed_bytes = await get_path_size(self.listener.newDir) + if self.listener.new_dir: + self._proccessed_bytes = await get_path_size(self.listener.new_dir) else: self._proccessed_bytes = await get_path_size(self.listener.dir) - self._size @@ -102,11 +102,11 @@ def task(self): async def cancel_task(self): LOGGER.info(f"Cancelling Split: {self.listener.name}") - self.listener.isCancelled = True + self.listener.is_cancelled = True async with subprocess_lock: if ( self.listener.suproc is not None and self.listener.suproc.returncode is None ): self.listener.suproc.kill() - await self.listener.onUploadError("splitting stopped by user!") + await self.listener.on_upload_error("splitting stopped by user!") diff --git a/bot/helper/task_utils/status_utils/telegram_status.py b/bot/helper/task_utils/status_utils/telegram_status.py index 22ef95e71c1c..eef7140cfd36 100644 --- a/bot/helper/task_utils/status_utils/telegram_status.py +++ b/bot/helper/task_utils/status_utils/telegram_status.py @@ -1,4 +1,4 @@ -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.status_utils import ( MirrorStatus, get_readable_file_size, get_readable_time, @@ -13,7 +13,7 @@ def __init__(self, listener, obj, gid, status): self._size = self.listener.size self._gid = gid self._status = status - self.engine = f"NekoZee v{self._eng_ver()}" + self.engine = f"Telegram v{self._eng_ver()}" def _eng_ver(self): return get_distribution("nekozee").version diff --git a/bot/helper/task_utils/status_utils/yt_dlp_download_status.py b/bot/helper/task_utils/status_utils/yt_dlp_download_status.py index bc0da5b0bf76..7eda644c8499 100644 --- a/bot/helper/task_utils/status_utils/yt_dlp_download_status.py +++ b/bot/helper/task_utils/status_utils/yt_dlp_download_status.py @@ -1,5 +1,5 @@ -from bot.helper.ext_utils.files_utils import get_path_size -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.files_utils import get_path_size +from ...ext_utils.status_utils import ( MirrorStatus, get_readable_file_size, get_readable_time, diff --git a/bot/helper/task_utils/status_utils/zip_status.py b/bot/helper/task_utils/status_utils/zip_status.py index 7f51eef8527e..b8a9720bc5d0 100644 --- a/bot/helper/task_utils/status_utils/zip_status.py +++ b/bot/helper/task_utils/status_utils/zip_status.py @@ -4,8 +4,8 @@ LOGGER, subprocess_lock ) -from bot.helper.ext_utils.files_utils import get_path_size -from bot.helper.ext_utils.status_utils import ( +from ...ext_utils.files_utils import get_path_size +from ...ext_utils.status_utils import ( get_readable_file_size, MirrorStatus, get_readable_time, @@ -73,8 +73,8 @@ def status(self): return MirrorStatus.STATUS_ARCHIVING async def processed_raw(self): - if self.listener.newDir: - self._proccessed_bytes = await get_path_size(self.listener.newDir) + if self.listener.new_dir: + self._proccessed_bytes = await get_path_size(self.listener.new_dir) else: self._proccessed_bytes = await get_path_size(self.listener.dir) - self._size @@ -86,11 +86,11 @@ def task(self): async def cancel_task(self): LOGGER.info(f"Cancelling Archive: {self.listener.name}") - self.listener.isCancelled = True + self.listener.is_cancelled = True async with subprocess_lock: if ( self.listener.suproc is not None and self.listener.suproc.returncode is None ): self.listener.suproc.kill() - await self.listener.onUploadError("archiving stopped by user!") + await self.listener.on_upload_error("archiving stopped by user!") diff --git a/bot/helper/task_utils/telegram_uploader.py b/bot/helper/task_utils/telegram_uploader.py index 95ff9e0b1649..ed806784a9b1 100644 --- a/bot/helper/task_utils/telegram_uploader.py +++ b/bot/helper/task_utils/telegram_uploader.py @@ -1,5 +1,3 @@ -from PIL import Image -from html import escape from aiofiles.os import ( remove, path as aiopath, @@ -11,21 +9,14 @@ rmtree ) from asyncio import sleep +from html import escape from logging import getLogger from natsort import natsorted from os import ( walk, path as ospath ) -from nekozee.errors import ( - FloodWait, - RPCError -) -from nekozee.types import ( - InputMediaVideo, - InputMediaDocument, - InputMediaPhoto -) +from PIL import Image from re import ( match as re_match, sub as re_sub @@ -39,25 +30,41 @@ ) from time import time -from bot import bot, config_dict, user, IS_PREMIUM_USER -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.files_utils import ( +from nekozee.errors import ( + FloodWait, + RPCError +) +from nekozee.types import ( + InputMediaVideo, + InputMediaDocument, + InputMediaPhoto +) + +from bot import ( + IS_PREMIUM_USER, + bot, + config_dict, + user +) +from ..ext_utils.bot_utils import sync_to_async +from ..ext_utils.files_utils import ( clean_unwanted, - is_archive, - get_base_name + get_base_name, + is_archive ) -from bot.helper.ext_utils.media_utils import ( +from ..ext_utils.media_utils import ( get_media_info, get_document_type, - create_thumbnail, - get_audio_thumb, + get_video_thumbnail, + get_audio_thumbnail, + get_multiple_frames_thumbnail ) -from bot.helper.telegram_helper.message_utils import deleteMessage +from ..telegram_helper.message_utils import delete_message LOGGER = getLogger(__name__) -class TgUploader: +class TelegramUploader: def __init__(self, listener, path): self._last_uploaded = 0 self._processed_bytes = 0 @@ -65,7 +72,7 @@ def __init__(self, listener, path): self._path = path self._start_time = time() self._total_files = 0 - self._thumb = self._listener.thumb or f"Thumbnails/{listener.userId}.jpg" + self._thumb = self._listener.thumb or f"Thumbnails/{listener.user_id}.jpg" self._msgs_dict = {} self._corrupted = 0 self._is_corrupted = False @@ -79,10 +86,10 @@ def __init__(self, listener, path): self._is_private = False self._sent_msg = None self._sent_DMmsg = None - self._user_session = self._listener.userTransmission + self._user_session = self._listener.user_transmission async def _upload_progress(self, current, _): - if self._listener.isCancelled: + if self._listener.is_cancelled: if self._user_session: user.stop_transmission() # type: ignore else: @@ -92,24 +99,24 @@ async def _upload_progress(self, current, _): self._processed_bytes += chunk_size async def _user_settings(self): - self._media_group = self._listener.userDict.get("media_group") or ( + self._media_group = self._listener.user_dict.get("media_group") or ( config_dict["MEDIA_GROUP"] - if "media_group" not in self._listener.userDict + if "media_group" not in self._listener.user_dict else False ) - self._lprefix = self._listener.userDict.get("lprefix") or ( + self._lprefix = self._listener.user_dict.get("lprefix") or ( config_dict["LEECH_FILENAME_PREFIX"] - if "lprefix" not in self._listener.userDict + if "lprefix" not in self._listener.user_dict else "" ) - self._lsuffix = self._listener.userDict.get("lsuffix") or ( + self._lsuffix = self._listener.user_dict.get("lsuffix") or ( config_dict["LEECH_FILENAME_SUFFIX"] - if "lsuffix" not in self._listener.userDict + if "lsuffix" not in self._listener.user_dict else "" ) - self._lcapfont = self._listener.userDict.get("lcapfont") or ( + self._lcapfont = self._listener.user_dict.get("lcapfont") or ( config_dict["LEECH_CAPTION_FONT"] - if "lcapfont" not in self._listener.userDict + if "lcapfont" not in self._listener.user_dict else "" ) if not await aiopath.exists(self._thumb): # type: ignore @@ -117,8 +124,8 @@ async def _user_settings(self): async def _msg_to_reply(self): if DUMP_CHAT_ID := config_dict["DUMP_CHAT_ID"]: - if self._listener.logMessage: - self._sent_msg = await self._listener.logMessage.copy(DUMP_CHAT_ID) + if self._listener.log_message: + self._sent_msg = await self._listener.log_message.copy(DUMP_CHAT_ID) else: msg = f"File Name: {escape(self._listener.name)}\n\n" msg += f"#Leech_Started!\n" @@ -129,8 +136,8 @@ async def _msg_to_reply(self): msg, disable_web_page_preview=True ) - if self._listener.dmMessage: - self._sent_DMmsg = self._listener.dmMessage + if self._listener.dm_message: + self._sent_DMmsg = self._listener.dm_message if IS_PREMIUM_USER: try: self._sent_msg = await user.get_messages( # type: ignore @@ -138,14 +145,14 @@ async def _msg_to_reply(self): message_ids=self._sent_msg.id ) except RPCError as e: - await self._listener.onUploadError( + await self._listener.on_upload_error( f"{e.NAME} [{e.CODE}]: {e.MESSAGE}" ) except Exception as e: - await self._listener.onUploadError(e) + await self._listener.on_upload_error(e) elif IS_PREMIUM_USER: - if not self._listener.isSuperChat: - await self._listener.onUploadError( + if not self._listener.is_super_chat: + await self._listener.on_upload_error( "Use SuperGroup to leech with User!" ) return False @@ -156,19 +163,19 @@ async def _msg_to_reply(self): message_ids=self._sent_msg.id ) except RPCError as e: - await self._listener.onUploadError( + await self._listener.on_upload_error( f"{e.NAME} [{e.CODE}]: {e.MESSAGE}" ) except Exception as e: - await self._listener.onUploadError(e) - if self._listener.dmMessage: - self._sent_DMmsg = self._listener.dmMessage - elif self._listener.dmMessage: - self._sent_msg = self._listener.dmMessage + await self._listener.on_upload_error(e) + if self._listener.dm_message: + self._sent_DMmsg = self._listener.dm_message + elif self._listener.dm_message: + self._sent_msg = self._listener.dm_message else: self._sent_msg = self._listener.message if self._sent_msg is None: - await self._listener.onUploadError( + await self._listener.on_upload_error( "Cannot find the message to reply" ) return False @@ -195,7 +202,7 @@ async def _prepare_file(self, file_, dirpath, delete_file): ) if ( self._listener.seed - and not self._listener.newDir + and not self._listener.new_dir and not dirpath.endswith("/splited_files_zee") and not delete_file ): @@ -252,7 +259,7 @@ async def _prepare_file(self, file_, dirpath, delete_file): name = name[:remain] if ( self._listener.seed - and not self._listener.newDir + and not self._listener.new_dir and not dirpath.endswith("/splited_files_zee") and not delete_file ): @@ -349,13 +356,19 @@ async def _send_screenshots(self, dirpath, outputs): ) for p in outputs ] - self._sent_msg = ( - await self._sent_msg.reply_media_group( # type: ignore - media=inputs, - quote=True, - disable_notification=True, - ) - )[-1] + for i in range( + 0, + len(inputs), + 10 + ): + batch = inputs[i : i + 10] + self._sent_msg = ( + await self._sent_msg.reply_media_group( # type: ignore + media=batch, + quote=True, + disable_notification=True, + ) + )[-1] if self._sent_DMmsg: try: self._sent_DMmsg = ( @@ -376,7 +389,7 @@ async def _send_media_group(self, subkey, key, msgs): index, msg ) in enumerate(msgs): - if self._listener.mixedLeech or not self._user_session: # type: ignore + if self._listener.mixed_leech or not self._user_session: # type: ignore msgs[index] = await self._listener.client.get_messages( chat_id=msg[0], message_ids=msg[1] @@ -397,11 +410,11 @@ async def _send_media_group(self, subkey, key, msgs): for msg in msgs: if msg.link in self._msgs_dict: del self._msgs_dict[msg.link] - await deleteMessage(msg) + await delete_message(msg) del self._media_dict[key][subkey] if ( - self._listener.isSuperChat - or self._listener.upDest + self._listener.is_super_chat + or self._listener.up_dest or config_dict["DUMP_CHAT_ID"] ): for m in msgs_list: @@ -465,11 +478,11 @@ async def upload(self, o_files, ft_delete): if self._up_path in o_files: continue if file_.lower().endswith( - tuple(self._listener.extensionFilter) + tuple(self._listener.extension_filter) ): if ( not self._listener.seed - or self._listener.newDir + or self._listener.new_dir ): await remove(self._up_path) continue @@ -482,7 +495,7 @@ async def upload(self, o_files, ft_delete): ) self._corrupted += 1 continue - if self._listener.isCancelled: + if self._listener.is_cancelled: return cap_mono = await self._prepare_file( file_, @@ -518,12 +531,12 @@ async def upload(self, o_files, ft_delete): key, msgs ) - if self._listener.mixedLeech: + if self._listener.mixed_leech: self._user_session = f_size > 2097152000 if self._user_session: self._sent_msg = await user.get_messages( # type: ignore - chat_id=self._sent_msg.chat.id, - message_ids=self._sent_msg.id, + chat_id=self._sent_msg.chat.id, # type: ignore + message_ids=self._sent_msg.id, # type: ignore ) else: self._sent_msg = await self._listener.client.get_messages( @@ -537,11 +550,11 @@ async def upload(self, o_files, ft_delete): file_, f_path ) - if self._listener.isCancelled: + if self._listener.is_cancelled: return if ( not self._is_corrupted - and (self._listener.isSuperChat or self._listener.upDest) + and (self._listener.is_super_chat or self._listener.up_dest) and not self._is_private ): self._msgs_dict[self._sent_msg.link] = file_ # type: ignore @@ -557,16 +570,16 @@ async def upload(self, o_files, ft_delete): err = err.last_attempt.exception() # type: ignore LOGGER.error(f"{err}. Path: {self._up_path}") self._corrupted += 1 - if self._listener.isCancelled: + if self._listener.is_cancelled: return continue finally: if ( - not self._listener.isCancelled + not self._listener.is_cancelled and await aiopath.exists(self._up_path) and ( not self._listener.seed - or self._listener.newDir + or self._listener.new_dir or dirpath.endswith("/splited_files_zee") or "/copied_zee/" in self._up_path or delete_file @@ -589,20 +602,20 @@ async def upload(self, o_files, ft_delete): LOGGER.info( f"While sending media group at the end of task. Error: {e}" ) - if self._listener.isCancelled: + if self._listener.is_cancelled: return if ( self._listener.seed - and not self._listener.newDir + and not self._listener.new_dir ): await clean_unwanted(self._path) if self._total_files == 0: - await self._listener.onUploadError( + await self._listener.on_upload_error( "No files to upload. In case you have filled EXTENSION_FILTER, then check if all files have those extensions or not." ) return if self._total_files <= self._corrupted: - await self._listener.onUploadError( + await self._listener.on_upload_error( "Files Corrupted or unable to upload. Check logs!" ) return @@ -687,10 +700,10 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): if await aiopath.isfile(thumb_path): thumb = thumb_path elif is_audio and not is_video: - thumb = await get_audio_thumb(self._up_path) + thumb = await get_audio_thumbnail(self._up_path) if ( - self._listener.asDoc + self._listener.as_doc or force_document or ( not is_video @@ -700,12 +713,12 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): ): key = "documents" if is_video and thumb is None: - thumb = await create_thumbnail( + thumb = await get_video_thumbnail( self._up_path, None ) - if self._listener.isCancelled: + if self._listener.is_cancelled: return self._sent_msg = await self._sent_msg.reply_document( # type: ignore document=self._up_path, @@ -719,8 +732,14 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): elif is_video: key = "videos" duration = (await get_media_info(self._up_path))[0] + if thumb is None and self._listener.thumbnail_layout: + thumb = await get_multiple_frames_thumbnail( + self._up_path, + self._listener.thumbnail_layout, + self._listener.screen_shots, + ) if thumb is None: - thumb = await create_thumbnail( + thumb = await get_video_thumbnail( self._up_path, duration ) @@ -733,7 +752,7 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): else: width = 480 height = 320 - if self._listener.isCancelled: + if self._listener.is_cancelled: return self._sent_msg = await self._sent_msg.reply_video( # type: ignore video=self._up_path, @@ -750,7 +769,7 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): elif is_audio: key = "audios" duration, artist, title = await get_media_info(self._up_path) - if self._listener.isCancelled: + if self._listener.is_cancelled: return self._sent_msg = await self._sent_msg.reply_audio( # type: ignore audio=self._up_path, @@ -765,7 +784,7 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): ) else: key = "photos" - if self._listener.isCancelled: + if self._listener.is_cancelled: return self._sent_msg = await self._sent_msg.reply_photo( # type: ignore photo=self._up_path, @@ -776,7 +795,7 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): ) if ( - not self._listener.isCancelled + not self._listener.is_cancelled and self._media_group and ( self._sent_msg.video @@ -817,12 +836,12 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): else: self._last_msg_in_group = True elif ( - not self._listener.isCancelled + not self._listener.is_cancelled and self._sent_DMmsg ): await self._send_dm() elif ( - not self._listener.isCancelled + not self._listener.is_cancelled and self._sent_DMmsg ): await self._send_dm() @@ -888,6 +907,6 @@ def processed_bytes(self): return self._processed_bytes async def cancel_task(self): - self._listener.isCancelled = True + self._listener.is_cancelled = True LOGGER.info(f"Cancelling Upload: {self._listener.name}") - await self._listener.onUploadError("Your upload has been cancelled!") + await self._listener.on_upload_error("Your upload has been cancelled!") diff --git a/bot/helper/telegram_helper/button_build.py b/bot/helper/telegram_helper/button_build.py index 2335a296ed97..f0ece5195cec 100644 --- a/bot/helper/telegram_helper/button_build.py +++ b/bot/helper/telegram_helper/button_build.py @@ -10,7 +10,7 @@ def __init__(self): self._header_button = [] self._footer_button = [] - def ubutton(self, key, link, position=None): + def url_button(self, key, link, position=None): if not position: self._button.append( InlineKeyboardButton( @@ -33,7 +33,7 @@ def ubutton(self, key, link, position=None): ) ) - def ibutton(self, key, data, position=None): + def data_button(self, key, data, position=None): if not position: self._button.append( InlineKeyboardButton( diff --git a/bot/helper/telegram_helper/filters.py b/bot/helper/telegram_helper/filters.py index 2b4abe4c65fa..2cc63a65971c 100644 --- a/bot/helper/telegram_helper/filters.py +++ b/bot/helper/telegram_helper/filters.py @@ -1,20 +1,23 @@ from nekozee.filters import create -from bot import user_data, OWNER_ID +from bot import ( + config_dict, + user_data +) class CustomFilters: - async def owner_filter(self, _, update): + async def ownerFilter(self, _, update): user = ( update.from_user or update.sender_chat ) uid = user.id - return uid == OWNER_ID + return uid == config_dict["OWNER_ID"] - owner = create(owner_filter) + owner = create(ownerFilter) - async def authorized_user(self, _, update): + async def authorizedUser(self, _, update): user = ( update.from_user or update.sender_chat @@ -22,7 +25,7 @@ async def authorized_user(self, _, update): uid = user.id chat_id = update.chat.id return bool( - uid == OWNER_ID + uid == config_dict["OWNER_ID"] or ( uid in user_data and ( @@ -45,18 +48,18 @@ async def authorized_user(self, _, update): ) ) - authorized = create(authorized_user) + authorized = create(authorizedUser) - async def sudo_user(self, _, update): + async def sudoUser(self, _, update): user = ( update.from_user or update.sender_chat ) uid = user.id return bool( - uid == OWNER_ID + uid == config_dict["OWNER_ID"] or uid in user_data and user_data[uid].get("is_sudo") ) - sudo = create(sudo_user) + sudo = create(sudoUser) diff --git a/bot/helper/telegram_helper/message_utils.py b/bot/helper/telegram_helper/message_utils.py index 05848abe73a3..2ec17514a755 100644 --- a/bot/helper/telegram_helper/message_utils.py +++ b/bot/helper/telegram_helper/message_utils.py @@ -2,6 +2,14 @@ sleep, create_task, ) +from re import match as re_match +from time import time +from datetime import ( + datetime, + timedelta, + timezone, +) + from nekozee.errors import ( FloodWait, PeerIdInvalid, @@ -10,32 +18,25 @@ ) from nekozee.types import ChatPermissions from nekozee.enums import ChatAction -from re import match as re_match -from time import time -from datetime import ( - datetime, - timedelta, - timezone, -) from bot import ( + LOGGER, bot, bot_name, cached_dict, config_dict, - Intervals, - LOGGER, + intervals, status_dict, task_dict_lock, user, ) -from bot.helper.ext_utils.bot_utils import setInterval -from bot.helper.ext_utils.exceptions import TgLinkException -from bot.helper.ext_utils.status_utils import get_readable_message -from bot.helper.telegram_helper.button_build import ButtonMaker +from ..ext_utils.bot_utils import SetInterval +from ..ext_utils.exceptions import TgLinkException +from ..ext_utils.status_utils import get_readable_message +from ..telegram_helper.button_build import ButtonMaker -async def sendMessage(message, text, buttons=None, block=True): +async def send_message(message, text, buttons=None, block=True): try: return await message.reply( text=text, @@ -48,7 +49,7 @@ async def sendMessage(message, text, buttons=None, block=True): LOGGER.warning(str(f)) if block: await sleep(f.value * 1.2) # type: ignore - return await sendMessage( + return await send_message( message, text, buttons @@ -59,7 +60,7 @@ async def sendMessage(message, text, buttons=None, block=True): return str(e) -async def editMessage(message, text, buttons=None, block=True): +async def edit_message(message, text, buttons=None, block=True): try: await message.edit( text=text, @@ -70,7 +71,7 @@ async def editMessage(message, text, buttons=None, block=True): LOGGER.warning(str(f)) if block: await sleep(f.value * 1.2) # type: ignore - return await editMessage( + return await edit_message( message, text, buttons @@ -81,7 +82,7 @@ async def editMessage(message, text, buttons=None, block=True): return str(e) -async def sendFile(message, file, caption=""): +async def send_file(message, file, caption=""): try: return await message.reply_document( document=file, @@ -92,7 +93,7 @@ async def sendFile(message, file, caption=""): except FloodWait as f: LOGGER.warning(str(f)) await sleep(f.value * 1.2) # type: ignore - return await sendFile( + return await send_file( message, file, caption @@ -102,7 +103,7 @@ async def sendFile(message, file, caption=""): return str(e) -async def sendRss(text): +async def send_rss(text): try: app = user or bot return await app.send_message( # type: ignore @@ -114,13 +115,13 @@ async def sendRss(text): except FloodWait as f: LOGGER.warning(str(f)) await sleep(f.value * 1.2) # type: ignore - return await sendRss(text) + return await send_rss(text) except Exception as e: LOGGER.error(str(e)) return str(e) -async def deleteMessage(message): +async def delete_message(message): try: await message.delete() except Exception as e: @@ -137,24 +138,24 @@ async def auto_delete_message( async def delete_delay(): await sleep(config_dict["AUTO_DELETE_MESSAGE_DURATION"]) if cmd_message is not None: - await deleteMessage(cmd_message) + await delete_message(cmd_message) if bot_message is not None: - await deleteMessage(bot_message) + await delete_message(bot_message) create_task(delete_delay()) async def delete_links(message): if config_dict["DELETE_LINKS"]: if reply_to := message.reply_to_message: - await deleteMessage(reply_to) - await deleteMessage(message) + await delete_message(reply_to) + await delete_message(message) async def delete_status(): async with task_dict_lock: for key, data in list(status_dict.items()): try: - await deleteMessage(data["message"]) + await delete_message(data["message"]) del status_dict[key] except Exception as e: LOGGER.error(str(e)) @@ -259,13 +260,13 @@ async def get_tg_link_message(link): async def update_status_message(sid, force=False): - if Intervals["stopAll"]: + if intervals["stopAll"]: return async with task_dict_lock: if not status_dict.get(sid): - if obj := Intervals["status"].get(sid): + if obj := intervals["status"].get(sid): obj.cancel() - del Intervals["status"][sid] + del intervals["status"][sid] return if not force and time() - status_dict[sid]["time"] < 3: return @@ -283,12 +284,12 @@ async def update_status_message(sid, force=False): ) if text is None: del status_dict[sid] - if obj := Intervals["status"].get(sid): + if obj := intervals["status"].get(sid): obj.cancel() - del Intervals["status"][sid] + del intervals["status"][sid] return if text != status_dict[sid]["message"].text: - message = await editMessage( + message = await edit_message( status_dict[sid]["message"], text, buttons, @@ -297,9 +298,9 @@ async def update_status_message(sid, force=False): if isinstance(message, str): if message.startswith("Telegram says: [400"): del status_dict[sid] - if obj := Intervals["status"].get(sid): + if obj := intervals["status"].get(sid): obj.cancel() - del Intervals["status"][sid] + del intervals["status"][sid] else: LOGGER.error( f"Status with id: {sid} haven't been updated. Error: {message}" @@ -309,8 +310,8 @@ async def update_status_message(sid, force=False): status_dict[sid]["time"] = time() -async def sendStatusMessage(msg, user_id=0): - if Intervals["stopAll"]: +async def send_status_message(msg, user_id=0): + if intervals["stopAll"]: return async with task_dict_lock: sid = user_id or msg.chat.id @@ -328,13 +329,13 @@ async def sendStatusMessage(msg, user_id=0): ) if text is None: del status_dict[sid] - if obj := Intervals["status"].get(sid): + if obj := intervals["status"].get(sid): obj.cancel() - del Intervals["status"][sid] + del intervals["status"][sid] return message = status_dict[sid]["message"] - await deleteMessage(message) - message = await sendMessage( + await delete_message(message) + message = await send_message( msg, text, buttons, @@ -360,7 +361,7 @@ async def sendStatusMessage(msg, user_id=0): ) if text is None: return - message = await sendMessage( + message = await send_message( msg, text, buttons, @@ -381,20 +382,20 @@ async def sendStatusMessage(msg, user_id=0): "is_user": is_user, } if ( - not Intervals["status"].get(sid) + not intervals["status"].get(sid) and not is_user ): - Intervals["status"][sid] = setInterval( + intervals["status"][sid] = SetInterval( config_dict["STATUS_UPDATE_INTERVAL"], update_status_message, sid ) -async def user_info(client, userId): - return await client.get_users(userId) +async def user_info(client, user_id): + return await client.get_users(user_id) -async def isBot_canDm(message, dmMode, button=None): +async def is_bot_can_dm(message, dmMode, button=None): if not dmMode: return None, button await user_info( @@ -410,7 +411,7 @@ async def isBot_canDm(message, dmMode, button=None): if button is None: button = ButtonMaker() _msg = "You need to Start me in DM." - button.ubutton( + button.url_button( "ꜱᴛᴀʀᴛ\nᴍᴇ", f"https://t.me/{bot_name}?start=start", "header" @@ -425,10 +426,10 @@ async def isBot_canDm(message, dmMode, button=None): ) -async def send_to_chat(client, chatId, text, buttons=None): +async def send_to_chat(client, chat_id, text, buttons=None): try: return await client.send_message( - chatId, + chat_id, text=text, disable_web_page_preview=True, disable_notification=True, @@ -439,7 +440,7 @@ async def send_to_chat(client, chatId, text, buttons=None): await sleep(f.value * 1.2) # type: ignore return await send_to_chat( client, - chatId, + chat_id, text, buttons ) @@ -449,7 +450,7 @@ async def send_to_chat(client, chatId, text, buttons=None): LOGGER.error(str(e)) -async def sendLogMessage(message, link, tag): +async def send_log_message(message, link, tag): if not (log_chat := config_dict["LOG_CHAT_ID"]): return try: @@ -480,7 +481,7 @@ async def sendLogMessage(message, link, tag): except FloodWait as r: LOGGER.warning(str(r)) await sleep(r.value * 1.2) # type: ignore - return await sendLogMessage( + return await send_log_message( message, link, tag @@ -491,7 +492,7 @@ async def sendLogMessage(message, link, tag): LOGGER.error(str(e)) -async def isAdmin(message, user_id=None): +async def is_admin(message, user_id=None): if message.chat.type == message.chat.type.PRIVATE: return if user_id: @@ -504,7 +505,7 @@ async def isAdmin(message, user_id=None): ] -async def forcesub(message, ids, button=None): +async def force_subscribe(message, ids, button=None): join_button = {} _msg = "" for channel_id in ids.split(): @@ -539,7 +540,7 @@ async def forcesub(message, ids, button=None): key, value ) in join_button.items(): - button.ubutton( + button.url_button( f"{key}", value, "footer" @@ -556,19 +557,19 @@ async def message_filter(message): _msg = "" if reply_to := message.reply_to_message: if reply_to.forward_date: - await deleteMessage(reply_to) + await delete_message(reply_to) _msg = "You can't mirror or leech forward messages." elif reply_to.reply_markup: - await deleteMessage(reply_to) + await delete_message(reply_to) _msg = "You can't mirror or leech messages with buttons." elif reply_to.caption: - await deleteMessage(reply_to) + await delete_message(reply_to) _msg = "You can't mirror or leech with captions text." elif message.reply_markup: - await deleteMessage(message) + await delete_message(message) _msg = "You can't mirror or leech messages with buttons." elif message.forward_date: - await deleteMessage(message) + await delete_message(message) _msg = "You can't mirror or leech forward messages." if _msg: message.id = None @@ -578,24 +579,24 @@ async def message_filter(message): async def anno_checker(message, pmsg=None): msg_id = message.id buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ᴠᴇʀɪꜰʏ", f"verify admin {msg_id}" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", f"verify no {msg_id}" ) user = None cached_dict[msg_id] = user if pmsg is not None: - await editMessage( + await edit_message( pmsg, f"{message.sender_chat.type.name} Anon Verification", buttons.build_menu(2) ) else: - await sendMessage( + await send_message( message, f"{message.sender_chat.type.name} Anon Verification", buttons.build_menu(2) @@ -660,7 +661,7 @@ async def request_limiter(message=None, query=None): show_alert=True ) else: - m69 = await sendMessage( + m69 = await send_message( message, "Oops, Spam detected! I will mute you for 69 seconds." ) diff --git a/bot/helper/z_utils.py b/bot/helper/z_utils.py index 723b47263f0b..07d5dbdaeec8 100644 --- a/bot/helper/z_utils.py +++ b/bot/helper/z_utils.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from hashlib import sha1 from os import ( path, @@ -23,29 +22,28 @@ ) from bot import ( - DATABASE_URL, KEY, LOGGER, config_dict ) -from bot.helper.ext_utils.links_utils import ( +from .ext_utils.links_utils import ( is_magnet, is_gdrive_link ) -from bot.helper.ext_utils.task_manager import check_user_tasks -from bot.helper.ext_utils.token_manager import checking_access -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.task_utils.gdrive_utils.helper import GoogleDriveHelper -from bot.helper.telegram_helper.message_utils import ( +from .ext_utils.task_manager import check_user_tasks +from .ext_utils.token_manager import checking_access +from .ext_utils.db_handler import database +from .task_utils.gdrive_utils.helper import GoogleDriveHelper +from .telegram_helper.message_utils import ( auto_delete_message, delete_links, - forcesub, + force_subscribe, message_filter, - sendMessage + send_message ) -async def extract_link(link, shouldDel=False): +async def extract_link(link, should_delete=False): try: if link and is_magnet(link): raw_link = search( @@ -53,7 +51,7 @@ async def extract_link(link, shouldDel=False): link ).group(0).lower() # type: ignore elif is_gdrive_link(link): - raw_link = GoogleDriveHelper().getIdFromUrl(link) + raw_link = GoogleDriveHelper().get_id_from_url(link) elif path.exists(link): if link.endswith(".nzb"): tree = ET.parse(link) @@ -71,7 +69,7 @@ async def extract_link(link, shouldDel=False): ) as f: decodedDict = bdecode(f.read()) raw_link = str(sha1(bencode(decodedDict[b"info"])).hexdigest()) - if shouldDel: + if should_delete: remove(link) else: raw_link = link @@ -83,7 +81,7 @@ async def extract_link(link, shouldDel=False): async def stop_duplicate_tasks(message, link, file_=None): if ( - DATABASE_URL + config_dict["DATABASE_URL"] and config_dict["STOP_DUPLICATE_TASKS"] ): raw_url = ( @@ -91,12 +89,12 @@ async def stop_duplicate_tasks(message, link, file_=None): if file_ else await extract_link(link) ) - exist = await DbManager().check_download(raw_url) # type: ignore + exist = await database.check_download(raw_url) # type: ignore if exist: _msg = f'Download is already added by {exist["tag"]}\n' _msg += f'Check the download status in @{exist["botname"]}\n\n' _msg += f'Link: {exist["_id"]}' - reply_message = await sendMessage( + reply_message = await send_message( message, _msg ) @@ -109,10 +107,10 @@ async def stop_duplicate_tasks(message, link, file_=None): return raw_url -async def none_admin_utils(message, isLeech=False): +async def none_admin_utils(message, is_leech=False): msg = [] if ( - isLeech + is_leech and config_dict["DISABLE_LEECH"] ): msg.append("Leech is disabled on this bot.\n💡Use other bots;)") @@ -130,7 +128,7 @@ async def none_admin_utils(message, isLeech=False): msg.append(f"Your tasks limit exceeded!\n💡Use other bots.\n\nTasks limit: {maxtask}") button = None if ( - isLeech + is_leech and config_dict["DISABLE_LEECH"] ): msg.append("Leech is disabled!\n💡 Use other bots...") @@ -152,7 +150,7 @@ async def none_admin_utils(message, isLeech=False): ( _msg, button - ) = await forcesub( + ) = await force_subscribe( message, ids, button diff --git a/bot/modules/anonymous.py b/bot/modules/anonymous.py index 6430ffd16b77..520612ad4ff9 100644 --- a/bot/modules/anonymous.py +++ b/bot/modules/anonymous.py @@ -5,46 +5,46 @@ bot, cached_dict ) -from bot.helper.telegram_helper.message_utils import ( - deleteMessage, - editMessage, - isAdmin +from ..helper.telegram_helper.message_utils import ( + delete_message, + edit_message, + is_admin ) -async def verifyAnno(_, query): +async def verify_annon(_, query): message = query.message data = query.data.split() msg_id = int(data[2]) if msg_id not in cached_dict: - return await editMessage( + return await edit_message( message, "Old Verification Message" ) user = query.from_user - is_admin = await isAdmin( + if_admin = await is_admin( message, user.id ) if ( data[1] == "admin" - and is_admin + and if_admin ): await query.answer(f"Username: {user.username}\nYour userid : {user.id}") cached_dict[msg_id] = user - await deleteMessage(message) + await delete_message(message) elif data[1] == "admin": await query.answer("You are not an admin") else: await query.answer() - await editMessage( + await edit_message( message, "Cancel Verification" ) bot.add_handler( # type: ignore CallbackQueryHandler( - verifyAnno, + verify_annon, filters=regex( "^verify" ) diff --git a/bot/modules/authorize.py b/bot/modules/authorize.py index 8bd8c3f2a997..f18d1cf2cae2 100644 --- a/bot/modules/authorize.py +++ b/bot/modules/authorize.py @@ -2,17 +2,21 @@ from nekozee.handlers import MessageHandler from bot import ( - user_data, - DATABASE_URL, - bot + bot, + config_dict, + user_data ) -from bot.helper.ext_utils.bot_utils import update_user_ldata -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import sendMessage +from ..helper.ext_utils.bot_utils import ( + new_task, + update_user_ldata +) +from ..helper.ext_utils.db_handler import database +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import send_message +@new_task async def authorize(client, message): msg = message.text.split() if len(msg) > 1: @@ -36,15 +40,16 @@ async def authorize(client, message): "is_auth", True ) - if DATABASE_URL: - await DbManager().update_user_data(id_) + if config_dict["DATABASE_URL"]: + await database.update_user_data(id_) msg = "Authorized" - await sendMessage( + await send_message( message, msg ) +@new_task async def unauthorize(client, message): msg = message.text.split() if len(msg) > 1: @@ -66,17 +71,18 @@ async def unauthorize(client, message): "is_auth", False ) - if DATABASE_URL: - await DbManager().update_user_data(id_) + if config_dict["DATABASE_URL"]: + await database.update_user_data(id_) msg = "Unauthorized" else: msg = "Already Unauthorized!" - await sendMessage( + await send_message( message, msg ) +@new_task async def addSudo(client, message): id_ = "" msg = message.text.split() @@ -100,17 +106,18 @@ async def addSudo(client, message): "is_sudo", True ) - if DATABASE_URL: - await DbManager().update_user_data(id_) + if config_dict["DATABASE_URL"]: + await database.update_user_data(id_) msg = "Promoted as Sudo" else: msg = "Give ID or Reply To message of whom you want to Promote." - await sendMessage( + await send_message( message, msg ) +@new_task async def removeSudo(client, message): id_ = "" msg = message.text.split() @@ -132,12 +139,12 @@ async def removeSudo(client, message): "is_sudo", False ) - if DATABASE_URL: - await DbManager().update_user_data(id_) + if config_dict["DATABASE_URL"]: + await database.update_user_data(id_) msg = "Demoted" else: msg = "Give ID or Reply To message of whom you want to remove from Sudo" - await sendMessage( + await send_message( message, msg ) diff --git a/bot/modules/bot_settings.py b/bot/modules/bot_settings.py index 23e1b8c4b8dc..17e2173cf169 100644 --- a/bot/modules/bot_settings.py +++ b/bot/modules/bot_settings.py @@ -29,59 +29,59 @@ ) from bot import ( - config_dict, - user_data, - DATABASE_URL, - extra_buttons, + IS_PREMIUM_USER, + LOGGER, MAX_SPLIT_SIZE, - DRIVES_IDS, - DRIVES_NAMES, - INDEX_URLS, aria2, - GLOBAL_EXTENSION_FILTER, - Intervals, aria2_options, aria2c_global, - IS_PREMIUM_USER, - task_dict, - qbit_options, - qbittorrent_client, - sabnzbd_client, - LOGGER, bot, - jd_downloads, - nzb_options, + config_dict, + drives_ids, + drives_names, + extra_buttons, get_nzb_options, get_qb_options, + global_extension_filter, + index_urls, + intervals, + jd_downloads, + nzb_options, + qbit_options, + qbittorrent_client, + sabnzbd_client, shorteneres_list, + task_dict, + user_data ) -from bot.helper.ext_utils.bot_utils import ( +from ..helper.ext_utils.bot_utils import ( + SetInterval, + new_task, set_commands, - setInterval, sync_to_async, retry_function, ) -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.ext_utils.jdownloader_booter import jdownloader -from bot.helper.ext_utils.status_utils import get_readable_file_size -from bot.helper.ext_utils.task_manager import start_from_queued -from bot.helper.task_utils.rclone_utils.serve import rclone_serve_booter -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( - sendMessage, - sendFile, - editMessage, +from ..helper.ext_utils.db_handler import database +from ..helper.ext_utils.jdownloader_booter import jdownloader +from ..helper.ext_utils.status_utils import get_readable_file_size +from ..helper.ext_utils.task_manager import start_from_queued +from ..helper.task_utils.rclone_utils.serve import rclone_serve_booter +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.button_build import ButtonMaker +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( + send_message, + send_file, + edit_message, update_status_message, - deleteMessage, + delete_message, ) -from bot.modules.rss import addJob -from bot.modules.torrent_search import initiate_search_tools +from ..modules.rss import add_job +from ..modules.torrent_search import initiate_search_tools -START = 0 -STATE = "view" -default_values = { +start = 0 +state = "view" +DEFAULT_VALUES = { "DOWNLOAD_DIR": "/usr/src/app/downloads/", "LEECH_SPLIT_SIZE": MAX_SPLIT_SIZE, "RSS_DELAY": 600, @@ -92,34 +92,34 @@ } -async def get_buttons(key=None, edit_type=None): +async def get_buttons(id=None, key=None, edit_type=None): buttons = ButtonMaker() if key is None: - buttons.ibutton( + buttons.data_button( "ᴄᴏɴꜰɪɢ\nᴠᴀʀɪᴀʙʟᴇꜱ", "botset var" ) - buttons.ibutton( + buttons.data_button( "ᴘʀɪᴠᴀᴛᴇ\nꜰɪʟᴇꜱ", "botset private" ) - buttons.ibutton( + buttons.data_button( "Qʙɪᴛᴛᴏʀʀᴇɴᴛ\nꜱᴇᴛᴛɪɴɢꜱ", "botset qbit" ) - buttons.ibutton( + buttons.data_button( "ᴀʀɪᴀ2ᴄ\nꜱᴇᴛᴛɪɴɢꜱ", "botset aria" ) - buttons.ibutton( + buttons.data_button( "ꜱᴀʙɴᴢʙᴅ\nꜱᴇᴛᴛɪɴɢꜱ", "botset nzb" ) - buttons.ibutton( + buttons.data_button( "ᴊᴅᴏᴡɴʟᴏᴀᴅᴇʀ\nꜱʏɴᴄ", "botset syncjd" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close", position="footer" @@ -128,7 +128,7 @@ async def get_buttons(key=None, edit_type=None): elif edit_type is not None: if edit_type == "botvar": msg = "" - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset var" ) @@ -138,11 +138,11 @@ async def get_buttons(key=None, edit_type=None): "OWNER_ID", "BOT_TOKEN" ]: - buttons.ibutton( + buttons.data_button( "ᴅᴇꜰᴀᴜʟᴛ", f"botset resetvar {key}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -158,23 +158,36 @@ async def get_buttons(key=None, edit_type=None): "BOT_TOKEN", "DOWNLOAD_DIR", ]: - msg += "Restart required for this edit to take effect!\n\n" - msg += f"Send a valid value for {key}. Current value is '{config_dict[key]}'. Timeout: 60 sec" + msg += "Restart required for this edit to take effect!\n\n" + if key in [ + "DATABASE_URL", + "TELEGRAM_API", + "TELEGRAM_HASH", + "UPSTREAM_REPO", + "USER_SESSION_STRING", + "MEGA_PASSWORD", + "BOT_TOKEN", + "JD_PASS", + "USENET_SERVERS", + ]: + msg += f"Send a valid value for {key}.\nTimeout: 60 sec" + else: + msg += f"Send a valid value for {key}. Current value is '{config_dict[key]}'.\n\nTimeout: 60 sec" elif edit_type == "ariavar": - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset aria" ) if key != "newkey": - buttons.ibutton( + buttons.data_button( "ᴅᴇꜰᴀᴜʟᴛ", f"botset resetaria {key}" ) - buttons.ibutton( + buttons.data_button( "ᴇᴍᴘᴛʏ\nꜱᴛʀɪɴɢ", f"botset emptyaria {key}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -184,33 +197,33 @@ async def get_buttons(key=None, edit_type=None): else f"Send a valid value for {key}. Current value is '{aria2_options[key]}'. Timeout: 60 sec" ) elif edit_type == "qbitvar": - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset qbit" ) - buttons.ibutton( + buttons.data_button( "ᴇᴍᴘᴛʏ\nꜱᴛʀɪɴɢ", f"botset emptyqbit {key}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) msg = f"Send a valid value for {key}. Current value is '{qbit_options[key]}'. Timeout: 60 sec" elif edit_type == "nzbvar": - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset nzb" ) - buttons.ibutton( + buttons.data_button( "ᴅᴇꜰᴀᴜʟᴛ", f"botset resetnzb {key}" ) - buttons.ibutton( + buttons.data_button( "ᴇᴍᴘᴛʏ\nꜱᴛʀɪɴɢ", f"botset emptynzb {key}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -226,16 +239,16 @@ async def get_buttons(key=None, edit_type=None): ) ) ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"botset nzbser{index}" ) if key != "newser": - buttons.ibutton( + buttons.data_button( "ᴇᴍᴘᴛʏ", f"botset emptyserkey {index} {key}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -244,26 +257,26 @@ async def get_buttons(key=None, edit_type=None): else: msg = f"Send a valid value for {key} in server {config_dict["USENET_SERVERS"][index]["name"]}. Current value is '{config_dict["USENET_SERVERS"][index][key]}'. Timeout: 60 sec" elif key == "var": - for k in list(config_dict.keys())[START : 10 + START]: - buttons.ibutton( + for k in list(config_dict.keys())[start : 10 + start]: + buttons.data_button( k, f"botset botvar {k}" ) - if STATE == "view": - buttons.ibutton( + if state == "view": + buttons.data_button( "ᴇᴅɪᴛ", "botset edit var" ) else: - buttons.ibutton( + buttons.data_button( "ᴠɪᴇᴡ", "botset view var" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset back" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -272,18 +285,18 @@ async def get_buttons(key=None, edit_type=None): len(config_dict), 10 ): - buttons.ibutton( + buttons.data_button( f"{int(x / 10)}", f"botset start var {x}", position="footer" ) - msg = f"Config Variables | Page: {int(START / 10)} | State: {STATE}" + msg = f"Config Variables | Page: {int(start / 10)} | State: {state}" elif key == "private": - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset back" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -297,30 +310,30 @@ async def get_buttons(key=None, edit_type=None): Timeout: 60 sec. """ elif key == "aria": - for k in list(aria2_options.keys())[START : 10 + START]: - buttons.ibutton( + for k in list(aria2_options.keys())[start : 10 + start]: + buttons.data_button( k, f"botset ariavar {k}" ) - if STATE == "view": - buttons.ibutton( + if state == "view": + buttons.data_button( "ᴇᴅɪᴛ", "botset edit aria" ) else: - buttons.ibutton( + buttons.data_button( "ᴠɪᴇᴡ", "botset view aria" ) - buttons.ibutton( + buttons.data_button( "ᴀᴅᴅ ɴᴇᴡ ᴋᴇʏ", "botset ariavar newkey" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset back" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -329,37 +342,37 @@ async def get_buttons(key=None, edit_type=None): len(aria2_options), 10 ): - buttons.ibutton( + buttons.data_button( f"{int(x / 10)}", f"botset start aria {x}", position="footer" ) - msg = f"Aria2c Options | Page: {int(START / 10)} | State: {STATE}" + msg = f"Aria2c Options | Page: {int(start / 10)} | State: {state}" elif key == "qbit": - for k in list(qbit_options.keys())[START : 10 + START]: - buttons.ibutton( + for k in list(qbit_options.keys())[start : 10 + start]: + buttons.data_button( k, f"botset qbitvar {k}" ) - if STATE == "view": - buttons.ibutton( + if state == "view": + buttons.data_button( "ᴇᴅɪᴛ", "botset edit qbit" ) else: - buttons.ibutton( + buttons.data_button( "ᴠɪᴇᴡ", "botset view qbit" ) - buttons.ibutton( + buttons.data_button( "Qʙɪᴛᴛᴏʀʀᴇɴᴛ\nꜱʏɴᴄ", "botset syncqbit" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset back" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -368,41 +381,41 @@ async def get_buttons(key=None, edit_type=None): len(qbit_options), 10 ): - buttons.ibutton( + buttons.data_button( f"{int(x / 10)}", f"botset start qbit {x}", position="footer" ) - msg = f"Qbittorrent Options | Page: {int(START / 10)} | State: {STATE}" + msg = f"Qbittorrent Options | Page: {int(start / 10)} | State: {state}" elif key == "nzb": - for k in list(nzb_options.keys())[START : 10 + START]: - buttons.ibutton( + for k in list(nzb_options.keys())[start : 10 + start]: + buttons.data_button( k, f"botset nzbvar {k}" ) - if STATE == "view": - buttons.ibutton( + if state == "view": + buttons.data_button( "ᴇᴅɪᴛ", "botset edit nzb" ) else: - buttons.ibutton( + buttons.data_button( "ᴠɪᴇᴡ", "botset view nzb" ) - buttons.ibutton( + buttons.data_button( "ꜱᴇʀᴠᴇʀꜱ", "botset nzbserver" ) - buttons.ibutton( + buttons.data_button( "ꜱᴀʙɴᴢʙᴅ\nꜱʏɴᴄ", "botset syncnzb" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset back" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -411,33 +424,33 @@ async def get_buttons(key=None, edit_type=None): len(nzb_options), 10 ): - buttons.ibutton( + buttons.data_button( f"{int(x / 10)}", f"botset start nzb {x}", position="footer" ) - msg = f"Sabnzbd Options | Page: {int(START / 10)} | State: {STATE}" + msg = f"Sabnzbd Options | Page: {int(start / 10)} | State: {state}" elif key == "nzbserver": if len(config_dict["USENET_SERVERS"]) > 0: for ( index, k ) in enumerate( - config_dict["USENET_SERVERS"][START : 10 + START] + config_dict["USENET_SERVERS"][start : 10 + start] ): - buttons.ibutton( + buttons.data_button( k["name"], f"botset nzbser{index}" ) - buttons.ibutton( + buttons.data_button( "ᴀᴅᴅ\nɴᴇᴡ", "botset nzbsevar newser" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset nzb" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -447,41 +460,41 @@ async def get_buttons(key=None, edit_type=None): len(config_dict["USENET_SERVERS"]), 10 ): - buttons.ibutton( + buttons.data_button( f"{int(x / 10)}", f"botset start nzbser {x}", position="footer" ) - msg = f"Usenet Servers | Page: {int(START / 10)} | State: {STATE}" + msg = f"Usenet Servers | Page: {int(start / 10)} | State: {state}" elif key.startswith("nzbser"): index = int(key.replace( "nzbser", "" )) - for k in list(config_dict["USENET_SERVERS"][index].keys())[START : 10 + START]: - buttons.ibutton( + for k in list(config_dict["USENET_SERVERS"][index].keys())[start : 10 + start]: + buttons.data_button( k, f"botset nzbsevar{index} {k}" ) - if STATE == "view": - buttons.ibutton( + if state == "view": + buttons.data_button( "ᴇᴅɪᴛ", f"botset edit {key}" ) else: - buttons.ibutton( + buttons.data_button( "ᴠɪᴇᴡ", f"botset view {key}" ) - buttons.ibutton( + buttons.data_button( "ʀᴇᴍᴏᴠᴇ\nꜱᴇʀᴠᴇʀ", f"botset remser {index}" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "botset nzbserver" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "botset close" ) @@ -491,12 +504,12 @@ async def get_buttons(key=None, edit_type=None): len(config_dict["USENET_SERVERS"][index]), 10 ): - buttons.ibutton( + buttons.data_button( f"{int(x / 10)}", f"botset start {key} {x}", position="footer" ) - msg = f"Server Keys | Page: {int(START / 10)} | State: {STATE}" + msg = f"Server Keys | Page: {int(start / 10)} | State: {state}" button = buttons.build_menu(2) return ( @@ -510,24 +523,25 @@ async def update_buttons(message, key=None, edit_type=None): msg, button ) = await get_buttons( - key, - edit_type + key=key, + edit_type=edit_type ) - await editMessage( + await edit_message( message, msg, button ) +@new_task async def edit_variable(message, pre_message, key): value = message.text if value.lower() == "true": value = True elif value.lower() == "false": value = False - if key == "INCOMPLETE_TASK_NOTIFIER" and DATABASE_URL: - await DbManager().trunc_table("tasks") + if key == "INCOMPLETE_TASK_NOTIFIER" and config_dict["DATABASE_URL"]: + await database.trunc_table("tasks") elif key == "DOWNLOAD_DIR": if not value.endswith("/"): value += "/" @@ -544,14 +558,14 @@ async def edit_variable(message, pre_message, key): value = int(value) if ( len(task_dict) != 0 - and (st := Intervals["status"]) + and (st := intervals["status"]) ): for ( cid, intvl ) in list(st.items()): intvl.cancel() - Intervals["status"][cid] = setInterval( + intervals["status"][cid] = SetInterval( value, update_status_message, cid @@ -596,8 +610,8 @@ async def edit_variable(message, pre_message, key): ) elif key == "EXTENSION_FILTER": fx = value.split() - GLOBAL_EXTENSION_FILTER.clear() - GLOBAL_EXTENSION_FILTER.extend( + global_extension_filter.clear() + global_extension_filter.extend( [ "aria2", "!qB" @@ -605,23 +619,23 @@ async def edit_variable(message, pre_message, key): ) for x in fx: x = x.lstrip(".") - GLOBAL_EXTENSION_FILTER.append(x.strip().lower()) + global_extension_filter.append(x.strip().lower()) elif key == "GDRIVE_ID": if ( - DRIVES_NAMES and - DRIVES_NAMES[0] == "Main" + drives_names and + drives_names[0] == "Main" ): - DRIVES_IDS[0] = value + drives_ids[0] = value else: - DRIVES_IDS.insert(0, value) + drives_ids.insert(0, value) elif key == "INDEX_URL": if ( - DRIVES_NAMES and - DRIVES_NAMES[0] == "Main" + drives_names and + drives_names[0] == "Main" ): - INDEX_URLS[0] = value + index_urls[0] = value else: - INDEX_URLS.insert( + index_urls.insert( 0, value ) @@ -647,9 +661,11 @@ async def edit_variable(message, pre_message, key): pre_message, "var" ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_config({key: value}) + await delete_message(message) + if key == "DATABASE_URL": + await database.connect() + if config_dict["DATABASE_URL"]: + await database.update_config({key: value}) if key in [ "SEARCH_PLUGINS", "SEARCH_API_LINK" @@ -674,7 +690,7 @@ async def edit_variable(message, pre_message, key): ]: jdownloader.initiate() # type: ignore elif key == "RSS_DELAY": - addJob() + add_job() elif key == "USET_SERVERS": for s in value: # type: ignore await sabnzbd_client.set_special_config( @@ -685,6 +701,7 @@ async def edit_variable(message, pre_message, key): await set_commands(bot) +@new_task async def edit_aria(message, pre_message, key): value = message.text if key == "newkey": @@ -722,14 +739,15 @@ async def edit_aria(message, pre_message, key): pre_message, "aria" ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_aria2( + await delete_message(message) + if config_dict["DATABASE_URL"]: + await database.update_aria2( key, value ) +@new_task async def edit_qbit(message, pre_message, key): value = message.text if value.lower() == "true": @@ -749,14 +767,15 @@ async def edit_qbit(message, pre_message, key): pre_message, "qbit" ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_qbittorrent( + await delete_message(message) + if config_dict["DATABASE_URL"]: + await database.update_qbittorrent( key, value ) +@new_task async def edit_nzb(message, pre_message, key): value = message.text if value.isdigit(): @@ -776,11 +795,12 @@ async def edit_nzb(message, pre_message, key): pre_message, "nzb" ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_nzb_config() + await delete_message(message) + if config_dict["DATABASE_URL"]: + await database.update_nzb_config() +@new_task async def edit_nzb_server(message, pre_message, key, index=0): value = message.text if ( @@ -791,7 +811,7 @@ async def edit_nzb_server(message, pre_message, key, index=0): try: value = eval(value) except: - await sendMessage( + await send_message( message, "Invalid dict format!" ) @@ -802,7 +822,7 @@ async def edit_nzb_server(message, pre_message, key, index=0): return res = await sabnzbd_client.add_server(value) if not res["config"]["servers"][0]["host"]: - await sendMessage( + await send_message( message, "Invalid server!" ) @@ -826,7 +846,7 @@ async def edit_nzb_server(message, pre_message, key, index=0): } ) if res["config"]["servers"][0][key] == "": - await sendMessage( + await send_message( message, "Invalid value" ) @@ -836,16 +856,16 @@ async def edit_nzb_server(message, pre_message, key, index=0): pre_message, f"nzbser{index}" ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_config( + await delete_message(message) + if config_dict["DATABASE_URL"]: + await database.update_config( {"USENET_SERVERS": config_dict["USENET_SERVERS"]} ) async def sync_jdownloader(): if ( - not DATABASE_URL + not config_dict["DATABASE_URL"] or jdownloader.device is None ): return @@ -884,9 +904,10 @@ async def sync_jdownloader(): "/JDownloader/cfg" ) ).wait() - await DbManager().update_private_file("cfg.zip") + await database.update_private_file("cfg.zip") +@new_task async def update_private_file(message, pre_message): if not message.media and (file_name := message.text): fn = file_name.rsplit( @@ -910,8 +931,8 @@ async def update_private_file(message, pre_message): ignore_errors=True ) config_dict["USE_SERVICE_ACCOUNTS"] = False - if DATABASE_URL: - await DbManager().update_config({"USE_SERVICE_ACCOUNTS": False}) + if config_dict["DATABASE_URL"]: + await database.update_config({"USE_SERVICE_ACCOUNTS": False}) elif file_name in [ "buttons.txt", "buttons" @@ -940,7 +961,7 @@ async def update_private_file(message, pre_message): ".netrc", "/root/.netrc" )).wait() - await deleteMessage(message) + await delete_message(message) elif doc := message.document: file_name = doc.file_name await message.download(file_name=f"{getcwd()}/{file_name}") @@ -975,13 +996,13 @@ async def update_private_file(message, pre_message): ) ).wait() elif file_name == "list_drives.txt": - DRIVES_IDS.clear() - DRIVES_NAMES.clear() - INDEX_URLS.clear() + drives_ids.clear() + drives_names.clear() + index_urls.clear() if GDRIVE_ID := config_dict["GDRIVE_ID"]: - DRIVES_NAMES.append("Main") - DRIVES_IDS.append(GDRIVE_ID) - INDEX_URLS.append(config_dict["INDEX_URL"]) + drives_names.append("Main") + drives_ids.append(GDRIVE_ID) + index_urls.append(config_dict["INDEX_URL"]) async with aiopen( "list_drives.txt", "r+" @@ -989,15 +1010,15 @@ async def update_private_file(message, pre_message): lines = await f.readlines() for line in lines: temp = line.strip().split() - DRIVES_IDS.append(temp[1]) - DRIVES_NAMES.append(temp[0].replace( + drives_ids.append(temp[1]) + drives_names.append(temp[0].replace( "_", " " )) if len(temp) > 2: - INDEX_URLS.append(temp[2]) + index_urls.append(temp[2]) else: - INDEX_URLS.append("") + index_urls.append("") elif file_name == "shorteners.txt": shorteneres_list.clear() with open( @@ -1059,26 +1080,26 @@ async def update_private_file(message, pre_message): if "@github.com" in config_dict["UPSTREAM_REPO"]: buttons = ButtonMaker() msg = "Push to UPSTREAM_REPO ?" - buttons.ibutton( + buttons.data_button( "ʏᴇꜱ!", f"botset push {file_name}" ) - buttons.ibutton( + buttons.data_button( "ɴᴏ", "botset close" ) - await sendMessage( + await send_message( message, msg, buttons.build_menu(2) ) else: - await deleteMessage(message) + await delete_message(message) if file_name == "rclone.conf": await rclone_serve_booter() await update_buttons(pre_message) - if DATABASE_URL: - await DbManager().update_private_file(file_name) + if config_dict["DATABASE_URL"]: + await database.update_private_file(file_name) if await aiopath.exists("accounts.zip"): await remove("accounts.zip") @@ -1096,6 +1117,7 @@ async def event_handler(client, query, document=False): timeout=60, ) +@new_task async def edit_bot_settings(client, query): message = query.message await client.stop_listening( @@ -1105,11 +1127,11 @@ async def edit_bot_settings(client, query): data = query.data.split() if data[1] == "close": await query.answer() - await deleteMessage(message.reply_to_message) - await deleteMessage(message) + await delete_message(message.reply_to_message) + await delete_message(message) elif data[1] == "back": await query.answer() - globals()["START"] = 0 + globals()["start"] = 0 await update_buttons( message, None @@ -1145,7 +1167,7 @@ async def edit_bot_settings(client, query): "nzbser" ): if data[1] == "nzbserver": - globals()["START"] = 0 + globals()["start"] = 0 await query.answer() await update_buttons( message, @@ -1154,23 +1176,23 @@ async def edit_bot_settings(client, query): elif data[1] == "resetvar": await query.answer() value = "" - if data[2] in default_values: - value = default_values[data[2]] + if data[2] in DEFAULT_VALUES: + value = DEFAULT_VALUES[data[2]] if ( data[2] == "STATUS_UPDATE_INTERVAL" and len(task_dict) != 0 - and (st := Intervals["status"]) + and (st := intervals["status"]) ): for key, intvl in list(st.items()): intvl.cancel() - Intervals["status"][key] = setInterval( + intervals["status"][key] = SetInterval( value, update_status_message, key ) elif data[2] == "EXTENSION_FILTER": - GLOBAL_EXTENSION_FILTER.clear() - GLOBAL_EXTENSION_FILTER.extend( + global_extension_filter.clear() + global_extension_filter.extend( [ "aria2", "!qB" @@ -1189,8 +1211,8 @@ async def edit_bot_settings(client, query): except Exception as e: LOGGER.error(e) aria2_options["bt-stop-timeout"] = "0" - if DATABASE_URL: - await DbManager().update_aria2( + if config_dict["DATABASE_URL"]: + await database.update_aria2( "bt-stop-timeout", "0" ) @@ -1216,18 +1238,18 @@ async def edit_bot_settings(client, query): "gunicorn web.wserver:app --bind 0.0.0.0:80 --worker-class gevent --log-level error" ) elif data[2] == "GDRIVE_ID": - if DRIVES_NAMES and DRIVES_NAMES[0] == "Main": - DRIVES_NAMES.pop(0) - DRIVES_IDS.pop(0) - INDEX_URLS.pop(0) + if drives_names and drives_names[0] == "Main": + drives_names.pop(0) + drives_ids.pop(0) + index_urls.pop(0) elif data[2] == "INDEX_URL": - if DRIVES_NAMES and DRIVES_NAMES[0] == "Main": - INDEX_URLS[0] = "" + if drives_names and drives_names[0] == "Main": + index_urls[0] = "" elif ( data[2] == "INCOMPLETE_TASK_NOTIFIER" - and DATABASE_URL + and config_dict["DATABASE_URL"] ): - await DbManager().trunc_table("tasks") + await database.trunc_table("tasks") elif data[2] in [ "JD_EMAIL", "JD_PASS" @@ -1251,8 +1273,8 @@ async def edit_bot_settings(client, query): message, "var" ) - if DATABASE_URL: - await DbManager().update_config({data[2]: value}) + if config_dict["DATABASE_URL"]: + await database.update_config({data[2]: value}) if data[2] in [ "SEARCH_PLUGINS", "SEARCH_API_LINK" @@ -1294,8 +1316,11 @@ async def edit_bot_settings(client, query): ) except Exception as e: LOGGER.error(e) - if DATABASE_URL: - await DbManager().update_aria2(data[2], value) + if config_dict["DATABASE_URL"]: + await database.update_aria2( + data[2], + value + ) elif data[1] == "resetnzb": await query.answer() res = await sabnzbd_client.set_config_default(data[2]) @@ -1304,24 +1329,24 @@ async def edit_bot_settings(client, query): message, "nzb" ) - if DATABASE_URL: - await DbManager().update_nzb_config() + if config_dict["DATABASE_URL"]: + await database.update_nzb_config() elif data[1] == "syncnzb": await query.answer( "Syncronization Started. It takes up to 2 sec!", show_alert=True ) await get_nzb_options() - if DATABASE_URL: - await DbManager().update_nzb_config() + if config_dict["DATABASE_URL"]: + await database.update_nzb_config() elif data[1] == "syncqbit": await query.answer( "Syncronization Started. It takes up to 2 sec!", show_alert=True ) - await get_qb_options() # type: ignore - if DATABASE_URL: - await DbManager().save_qbit_settings() + await sync_to_async(get_qb_options) + if config_dict["DATABASE_URL"]: + await database.save_qbit_settings() elif data[1] == "emptyaria": await query.answer() aria2_options[data[2]] = "" @@ -1340,8 +1365,8 @@ async def edit_bot_settings(client, query): ) except Exception as e: LOGGER.error(e) - if DATABASE_URL: - await DbManager().update_aria2( + if config_dict["DATABASE_URL"]: + await database.update_aria2( data[2], "" ) @@ -1356,8 +1381,8 @@ async def edit_bot_settings(client, query): message, "qbit" ) - if DATABASE_URL: - await DbManager().update_qbittorrent( + if config_dict["DATABASE_URL"]: + await database.update_qbittorrent( data[2], "" ) @@ -1373,8 +1398,8 @@ async def edit_bot_settings(client, query): message, "nzb" ) - if DATABASE_URL: - await DbManager().update_nzb_config() + if config_dict["DATABASE_URL"]: + await database.update_nzb_config() elif data[1] == "remser": index = int(data[2]) await sabnzbd_client.delete_config( @@ -1386,8 +1411,8 @@ async def edit_bot_settings(client, query): message, "nzbserver" ) - if DATABASE_URL: - await DbManager().update_config( + if config_dict["DATABASE_URL"]: + await database.update_config( {"USENET_SERVERS": config_dict["USENET_SERVERS"]} ) elif data[1] == "private": @@ -1413,7 +1438,7 @@ async def edit_bot_settings(client, query): ) elif ( data[1] == "botvar" - and STATE == "edit" + and state == "edit" ): await query.answer() await update_buttons( @@ -1441,7 +1466,7 @@ async def edit_bot_settings(client, query): ) elif ( data[1] == "botvar" - and STATE == "view" + and state == "view" ): value = f"{config_dict[data[2]]}" if value and data[2] in [ @@ -1451,16 +1476,19 @@ async def edit_bot_settings(client, query): "UPSTREAM_REPO", "USER_SESSION_STRING", "MEGA_PASSWORD", + "BOT_TOKEN", + "JD_PASS", + "USENET_SERVERS", ] and not await CustomFilters.owner( client, query ): value = "Only owner can view this!" - if len(value) > 200: + if len(value) > 500: await query.answer() with BytesIO(str.encode(value)) as out_file: out_file.name = f"{data[2]}.txt" - await sendFile( + await send_file( message, out_file ) @@ -1487,7 +1515,7 @@ async def edit_bot_settings(client, query): elif ( data[1] == "ariavar" and ( - STATE == "edit" + state == "edit" or data[2] == "newkey" ) ): @@ -1517,14 +1545,14 @@ async def edit_bot_settings(client, query): ) elif ( data[1] == "ariavar" - and STATE == "view" + and state == "view" ): value = f"{aria2_options[data[2]]}" if len(value) > 200: await query.answer() with BytesIO(str.encode(value)) as out_file: out_file.name = f"{data[2]}.txt" - await sendFile( + await send_file( message, out_file ) @@ -1537,7 +1565,7 @@ async def edit_bot_settings(client, query): ) elif ( data[1] == "qbitvar" - and STATE == "edit" + and state == "edit" ): await query.answer() await update_buttons( @@ -1565,14 +1593,14 @@ async def edit_bot_settings(client, query): ) elif ( data[1] == "qbitvar" - and STATE == "view" + and state == "view" ): value = f"{qbit_options[data[2]]}" if len(value) > 200: await query.answer() with BytesIO(str.encode(value)) as out_file: out_file.name = f"{data[2]}.txt" - await sendFile( + await send_file( message, out_file ) @@ -1585,7 +1613,7 @@ async def edit_bot_settings(client, query): ) elif ( data[1] == "nzbvar" - and STATE == "edit" + and state == "edit" ): await query.answer() await update_buttons( @@ -1613,14 +1641,14 @@ async def edit_bot_settings(client, query): ) elif ( data[1] == "nzbvar" - and STATE == "view" + and state == "view" ): value = f"{nzb_options[data[2]]}" if len(value) > 200: await query.answer() with BytesIO(str.encode(value)) as out_file: out_file.name = f"{data[2]}.txt" - await sendFile( + await send_file( message, out_file ) @@ -1647,14 +1675,14 @@ async def edit_bot_settings(client, query): config_dict["USENET_SERVERS"][index][data[3]] = res["config"]["servers"][0][ data[3] ] - if DATABASE_URL: - await DbManager().update_config( + if config_dict["DATABASE_URL"]: + await database.update_config( {"USENET_SERVERS": config_dict["USENET_SERVERS"]} ) elif ( data[1].startswith("nzbsevar") and ( - STATE == "edit" + state == "edit" or data[2] == "newser" ) ): @@ -1693,7 +1721,7 @@ async def edit_bot_settings(client, query): ) elif ( data[1].startswith("nzbsevar") - and STATE == "view" + and state == "view" ): index = int(data[1].replace( "nzbsevar", @@ -1704,7 +1732,7 @@ async def edit_bot_settings(client, query): await query.answer() with BytesIO(str.encode(value)) as out_file: out_file.name = f"{data[2]}.txt" - await sendFile( + await send_file( message, out_file ) @@ -1717,22 +1745,22 @@ async def edit_bot_settings(client, query): ) elif data[1] == "edit": await query.answer() - globals()["STATE"] = "edit" + globals()["state"] = "edit" await update_buttons( message, data[2] ) elif data[1] == "view": await query.answer() - globals()["STATE"] = "view" + globals()["state"] = "view" await update_buttons( message, data[2] ) elif data[1] == "start": await query.answer() - if START != int(data[3]): - globals()["START"] = int(data[3]) + if start != int(data[3]): + globals()["start"] = int(data[3]) await update_buttons( message, data[2] @@ -1756,21 +1784,23 @@ async def edit_bot_settings(client, query): && git push origin {config_dict["UPSTREAM_BRANCH"]} -qf" ) ).wait() - await deleteMessage(message.reply_to_message) - await deleteMessage(message) + await delete_message(message.reply_to_message) + await delete_message(message) +@new_task async def bot_settings(client, message): + uid = message.from_user.id await client.stop_listening( chat_id=message.chat.id, - user_id=message.from_user.id + user_id=uid ) ( msg, button - ) = await get_buttons() - globals()["START"] = 0 - await sendMessage( + ) = await get_buttons(id=uid) + globals()["start"] = 0 + await send_message( message, msg, button @@ -1879,15 +1909,15 @@ async def load_config(): ) if len(EXTENSION_FILTER) > 0: fx = EXTENSION_FILTER.split() - GLOBAL_EXTENSION_FILTER.clear() - GLOBAL_EXTENSION_FILTER.extend([ + global_extension_filter.clear() + global_extension_filter.extend([ "aria2", "!qB" ]) for x in fx: if x.strip().startswith("."): x = x.lstrip(".") - GLOBAL_EXTENSION_FILTER.append(x.strip().lower()) + global_extension_filter.append(x.strip().lower()) JD_EMAIL = environ.get( "JD_EMAIL", @@ -2023,14 +2053,14 @@ async def load_config(): STATUS_UPDATE_INTERVAL = int(STATUS_UPDATE_INTERVAL) if ( len(task_dict) != 0 - and (st := Intervals["status"]) + and (st := intervals["status"]) ): for ( key, intvl ) in list(st.items()): intvl.cancel() - Intervals["status"][key] = setInterval( + intervals["status"][key] = SetInterval( STATUS_UPDATE_INTERVAL, update_status_message, key @@ -2130,8 +2160,8 @@ async def load_config(): except Exception as e: LOGGER.error(e) aria2_options["bt-stop-timeout"] = "0" - if DATABASE_URL: - await DbManager().update_aria2( + if config_dict["DATABASE_URL"]: + await database.update_aria2( "bt-stop-timeout", "0" ) @@ -2148,8 +2178,8 @@ async def load_config(): except Exception as e: LOGGER.error(e) aria2_options["bt-stop-timeout"] = TORRENT_TIMEOUT - if DATABASE_URL: - await DbManager().update_aria2( + if config_dict["DATABASE_URL"]: + await database.update_aria2( "bt-stop-timeout", TORRENT_TIMEOUT ) @@ -2192,9 +2222,9 @@ async def load_config(): INCOMPLETE_TASK_NOTIFIER = INCOMPLETE_TASK_NOTIFIER.lower() == "true" if ( not INCOMPLETE_TASK_NOTIFIER - and DATABASE_URL + and config_dict["DATABASE_URL"] ): - await DbManager().trunc_table("tasks") + await database.trunc_table("tasks") STOP_DUPLICATE = environ.get( "STOP_DUPLICATE", @@ -2307,6 +2337,16 @@ async def load_config(): and IS_PREMIUM_USER ) + THUMBNAIL_LAYOUT = environ.get( + "THUMBNAIL_LAYOUT", + "" + ) + THUMBNAIL_LAYOUT = ( + "" + if len(THUMBNAIL_LAYOUT) == 0 + else THUMBNAIL_LAYOUT + ) + await (await create_subprocess_exec( "pkill", "-9", @@ -2619,14 +2659,14 @@ async def load_config(): MEGA_EMAIL = "" MEGA_PASSWORD = "" - DRIVES_IDS.clear() - DRIVES_NAMES.clear() - INDEX_URLS.clear() + drives_ids.clear() + drives_names.clear() + index_urls.clear() if GDRIVE_ID: - DRIVES_NAMES.append("Main") - DRIVES_IDS.append(GDRIVE_ID) - INDEX_URLS.append(INDEX_URL) + drives_names.append("Main") + drives_ids.append(GDRIVE_ID) + index_urls.append(INDEX_URL) if await aiopath.exists("list_drives.txt"): async with aiopen( @@ -2636,15 +2676,15 @@ async def load_config(): lines = await f.readlines() for line in lines: temp = line.strip().split() - DRIVES_IDS.append(temp[1]) - DRIVES_NAMES.append(temp[0].replace( + drives_ids.append(temp[1]) + drives_names.append(temp[0].replace( "_", " " )) if len(temp) > 2: - INDEX_URLS.append(temp[2]) + index_urls.append(temp[2]) else: - INDEX_URLS.append("") + index_urls.append("") extra_buttons.clear() if await aiopath.exists("buttons.txt"): @@ -2763,6 +2803,7 @@ async def load_config(): "SUDO_USERS": SUDO_USERS, "TELEGRAM_API": TELEGRAM_API, "TELEGRAM_HASH": TELEGRAM_HASH, + "THUMBNAIL_LAYOUT": THUMBNAIL_LAYOUT, "TORRENT_TIMEOUT": TORRENT_TIMEOUT, "USER_TRANSMISSION": USER_TRANSMISSION, "UPSTREAM_REPO": UPSTREAM_REPO, @@ -2775,14 +2816,18 @@ async def load_config(): } ) - if DATABASE_URL: - await DbManager().update_config(config_dict) + if config_dict["DATABASE_URL"]: + await database.connect() + await database.update_config(config_dict) + else: + await database.disconnect() + await gather( initiate_search_tools(), start_from_queued(), rclone_serve_booter() ) - addJob() + add_job() bot.add_handler( # type: ignore diff --git a/bot/modules/cancel_task.py b/bot/modules/cancel_task.py index 8b9c541efdda..d12f3bd51f96 100644 --- a/bot/modules/cancel_task.py +++ b/bot/modules/cancel_task.py @@ -1,5 +1,6 @@ from asyncio import sleep from re import search as re_search + from nekozee.filters import ( command, regex @@ -10,32 +11,34 @@ ) from bot import ( + OWNER_ID, bot, bot_name, multi_tags, - OWNER_ID, task_dict, task_dict_lock, user_data ) -from bot.helper.ext_utils.status_utils import ( - getTaskByGid, - getAllTasks, +from ..helper.ext_utils.bot_utils import new_task +from ..helper.ext_utils.status_utils import ( + get_task_by_gid, + get_all_tasks, MirrorStatus ) -from bot.helper.telegram_helper import button_build -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.telegram_helper import button_build +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( anno_checker, delete_links, - sendMessage, + send_message, auto_delete_message, - deleteMessage, - editMessage + delete_message, + edit_message ) +@new_task async def cancel_task(_, message): if not message.from_user: message.from_user = await anno_checker(message) @@ -53,9 +56,9 @@ async def cancel_task(_, message): multi_tags.discard(gid) return else: - task = await getTaskByGid(gid) + task = await get_task_by_gid(gid) if task is None: - tmsg = await sendMessage( + tmsg = await send_message( message, f"GID: {gid} Not Found." ) @@ -68,7 +71,7 @@ async def cancel_task(_, message): async with task_dict_lock: task = task_dict.get(reply_to_id) if task is None: - tmsg = await sendMessage( + tmsg = await send_message( message, "This is not an active task!" ) @@ -82,7 +85,7 @@ async def cancel_task(_, message): "Reply to an active Command message which was used to start the download" f" or send /{BotCommands.CancelTaskCommand[0]} GID to cancel it!" ) - tmsg = await sendMessage( + tmsg = await send_message( message, msg ) @@ -93,13 +96,13 @@ async def cancel_task(_, message): return if ( OWNER_ID != user_id - and task.listener.userId != user_id + and task.listener.user_id != user_id and ( user_id not in user_data or not user_data[user_id].get("is_sudo") ) ): - tmsg = await sendMessage( + tmsg = await send_message( message, "This task is not for you!" ) @@ -113,6 +116,7 @@ async def cancel_task(_, message): await delete_links(message) +@new_task async def cancel_multi(_, query): data = query.data.split() user_id = query.from_user.id @@ -138,13 +142,13 @@ async def cancel_multi(_, query): msg, show_alert=True ) - await deleteMessage(query.message) + await delete_message(query.message) -async def cancel_all(status, userId): - matches = await getAllTasks( +async def cancel_all(status, user_id): + matches = await get_all_tasks( status.strip(), - userId + user_id ) if not matches: return False @@ -155,83 +159,84 @@ async def cancel_all(status, userId): return True -def create_cancel_buttons(isSudo, userId=""): +def create_cancel_buttons(isSudo, user_id=""): buttons = button_build.ButtonMaker() - buttons.ibutton( + buttons.data_button( "ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ", - f"canall ms {(MirrorStatus.STATUS_DOWNLOADING).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_DOWNLOADING).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ᴜᴘʟᴏᴀᴅɪɴɢ", - f"canall ms {(MirrorStatus.STATUS_UPLOADING).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_UPLOADING).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ꜱᴇᴇᴅɪɴɢ", - f"canall ms {(MirrorStatus.STATUS_SEEDING).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_SEEDING).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ꜱᴘʟᴛᴛɪɴɢ", - f"canall ms {(MirrorStatus.STATUS_SPLITTING).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_SPLITTING).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏɴɪɴɢ", - f"canall ms {(MirrorStatus.STATUS_CLONING).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_CLONING).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ᴇxᴛʀᴀᴄᴛɪɴɢ", - f"canall ms {(MirrorStatus.STATUS_EXTRACTING).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_EXTRACTING).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ᴀʀᴄʜɪᴠɪɴɢ", - f"canall ms {(MirrorStatus.STATUS_ARCHIVING).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_ARCHIVING).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "Qᴜᴇᴜᴇᴅᴅʟ", - f"canall ms {(MirrorStatus.STATUS_QUEUEDL).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_QUEUEDL).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "Qᴜᴇᴜᴇᴅᴜᴘ", - f"canall ms {(MirrorStatus.STATUS_QUEUEUP).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_QUEUEUP).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ꜱᴀᴍᴘʟᴇᴠɪᴅᴇᴏ", - f"canall ms {(MirrorStatus.STATUS_SAMVID).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_SAMVID).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ᴄᴏɴᴠᴇʀᴛᴍᴇᴅɪᴀ", - f"canall ms {(MirrorStatus.STATUS_CONVERTING).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_CONVERTING).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ᴘᴀᴜꜱᴇᴅ", - f"canall ms {(MirrorStatus.STATUS_PAUSED).split(' ')[0]} {userId}" + f"canall ms {(MirrorStatus.STATUS_PAUSED).split(' ')[0]} {user_id}" ) - buttons.ibutton( + buttons.data_button( "ᴀʟʟ", - f"canall ms All {userId}" + f"canall ms All {user_id}" ) if isSudo: - if userId: - buttons.ibutton( + if user_id: + buttons.data_button( "ᴀʟʟ ᴀᴅᴅᴇᴅ ᴛᴀꜱᴋꜱ", - f"canall bot ms {userId}" + f"canall bot ms {user_id}" ) else: - buttons.ibutton( + buttons.data_button( "ᴍʏ ᴛᴀꜱᴋꜱ", - f"canall user ms {userId}" + f"canall user ms {user_id}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", - f"canall close ms {userId}" + f"canall close ms {user_id}" ) return buttons.build_menu(2) +@new_task async def cancell_all_buttons(_, message): async with task_dict_lock: count = len(task_dict) if count == 0: - tmsg = await sendMessage( + tmsg = await send_message( message, "No active tasks!" ) @@ -253,7 +258,7 @@ async def cancell_all_buttons(_, message): isSudo, uid ) - can_msg = await sendMessage( + can_msg = await send_message( message, "Choose tasks to cancel!", button @@ -265,11 +270,12 @@ async def cancell_all_buttons(_, message): ) +@new_task async def cancel_all_update(_, query): data = query.data.split() message = query.message reply_to = message.reply_to_message - userId = ( + user_id = ( int(data[3]) if len(data) > 3 else "" @@ -280,8 +286,8 @@ async def cancel_all_update(_, query): ) if ( not isSudo - and userId - and userId != query.from_user.id + and user_id + and user_id != query.from_user.id ): await query.answer( "Not Yours!", @@ -290,14 +296,14 @@ async def cancel_all_update(_, query): else: await query.answer() if data[1] == "close": - await deleteMessage(reply_to) - await deleteMessage(message) + await delete_message(reply_to) + await delete_message(message) elif data[1] == "back": button = create_cancel_buttons( isSudo, - userId # type: ignore + user_id # type: ignore ) - await editMessage( + await edit_message( message, "Choose tasks to cancel!", button @@ -307,7 +313,7 @@ async def cancel_all_update(_, query): isSudo, "" ) - await editMessage( + await edit_message( message, "Choose tasks to cancel!", button @@ -317,27 +323,27 @@ async def cancel_all_update(_, query): isSudo, query.from_user.id ) - await editMessage( + await edit_message( message, "Choose tasks to cancel!", button ) elif data[1] == "ms": buttons = button_build.ButtonMaker() - buttons.ibutton( + buttons.data_button( "ʏᴇꜱ!", - f"canall {data[2]} confirm {userId}" + f"canall {data[2]} confirm {user_id}" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", - f"canall back confirm {userId}" + f"canall back confirm {user_id}" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", - f"canall close confirm {userId}" + f"canall close confirm {user_id}" ) button = buttons.build_menu(2) - await editMessage( + await edit_message( message, f"Are you sure you want to cancel all {data[2]} tasks", button @@ -345,19 +351,19 @@ async def cancel_all_update(_, query): else: button = create_cancel_buttons( isSudo, - userId # type: ignore + user_id # type: ignore ) - await editMessage( + await edit_message( message, "Choose tasks to cancel.", button ) res = await cancel_all( data[1], - userId + user_id ) if not res: - tmsg = await sendMessage( + tmsg = await send_message( reply_to, f"No matching tasks for {data[1]}!" ) diff --git a/bot/modules/clone.py b/bot/modules/clone.py index e8e1b9842fae..f01539f4dbdf 100644 --- a/bot/modules/clone.py +++ b/bot/modules/clone.py @@ -11,40 +11,40 @@ bot, bot_loop ) -from bot.helper.ext_utils.bot_utils import ( +from ..helper.ext_utils.bot_utils import ( sync_to_async, cmd_exec, arg_parser, COMMAND_USAGE ) -from bot.helper.ext_utils.exceptions import DirectDownloadLinkException -from bot.helper.ext_utils.links_utils import ( +from ..helper.ext_utils.exceptions import DirectDownloadLinkException +from ..helper.ext_utils.links_utils import ( is_gdrive_link, is_share_link, is_rclone_path, is_gdrive_id ) -from bot.helper.ext_utils.task_manager import ( +from ..helper.ext_utils.task_manager import ( limit_checker, stop_duplicate_check ) -from bot.helper.listeners.task_listener import TaskListener -from bot.helper.task_utils.download_utils.direct_link_generator import ( +from ..helper.listeners.task_listener import TaskListener +from ..helper.task_utils.download_utils.direct_link_generator import ( direct_link_generator ) -from bot.helper.task_utils.gdrive_utils.clone import gdClone -from bot.helper.task_utils.gdrive_utils.count import gdCount -from bot.helper.task_utils.rclone_utils.transfer import RcloneTransferHelper -from bot.helper.task_utils.status_utils.gdrive_status import GdriveStatus -from bot.helper.task_utils.status_utils.rclone_status import RcloneStatus -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.task_utils.gdrive_utils.clone import GoogleDriveClone +from ..helper.task_utils.gdrive_utils.count import GoogleDriveCount +from ..helper.task_utils.rclone_utils.transfer import RcloneTransferHelper +from ..helper.task_utils.status_utils.gdrive_status import GoogleDriveStatus +from ..helper.task_utils.status_utils.rclone_status import RcloneStatus +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendMessage, - deleteMessage, - sendStatusMessage + send_message, + delete_message, + send_status_message ) @@ -59,22 +59,22 @@ def __init__( ____=None, _____=None, bulk=None, - multiTag=None, + multi_tag=None, options="", ): if bulk is None: bulk = [] self.message = message self.client = client - self.multiTag = multiTag + self.multi_tag = multi_tag self.options = options - self.sameDir = {} + self.same_dir = {} self.bulk = bulk super().__init__() - self.isClone = True + self.is_clone = True - async def newEvent(self): - self.pmsg = await sendMessage( + async def new_event(self): + self.pmsg = await send_message( self.message, "Processing your request..." ) @@ -100,28 +100,28 @@ async def newEvent(self): except: self.multi = 0 - self.upDest = args["-up"] - self.rcFlags = args["-rcf"] + self.up_dest = args["-up"] + self.rc_flags = args["-rcf"] self.link = args["link"] - isBulk = args["-b"] + is_bulk = args["-b"] sync = args["-sync"] bulk_start = 0 bulk_end = 0 self.file_ = None - await self.getId() + await self.get_id() - if not isinstance(isBulk, bool): - dargs = isBulk.split(":") + if not isinstance(is_bulk, bool): + dargs = is_bulk.split(":") bulk_start = dargs[0] or 0 if len(dargs) == 2: bulk_end = dargs[1] or 0 - isBulk = True + is_bulk = True - if isBulk: - await deleteMessage(self.pmsg) - await self.initBulk( + if is_bulk: + await delete_message(self.pmsg) + await self.init_bulk( input_list, bulk_start, bulk_end, @@ -129,7 +129,7 @@ async def newEvent(self): ) return - await self.getTag(text) + await self.get_tag(text) if ( not self.link @@ -137,19 +137,19 @@ async def newEvent(self): ): self.link = reply_to.text.split("\n", 1)[0].strip() - self.run_multi( + await self.run_multi( input_list, "", Clone - ) # type: ignore + ) if len(self.link) == 0: - hmsg = await sendMessage( + hmsg = await send_message( self.message, COMMAND_USAGE["clone"][0], COMMAND_USAGE["clone"][1] ) - await deleteMessage(self.pmsg) + await delete_message(self.pmsg) await auto_delete_message( self.message, hmsg @@ -157,14 +157,14 @@ async def newEvent(self): return LOGGER.info(self.link) - if await self.permissionCheck() != True: + if await self.permission_check() != True: return - await deleteMessage(self.pmsg) + await delete_message(self.pmsg) try: - await self.beforeStart() + await self.before_start() except Exception as e: - emsg = await sendMessage( + emsg = await send_message( self.message, e ) @@ -173,9 +173,9 @@ async def newEvent(self): emsg ) return - await self._proceedToClone(sync) + await self._proceed_to_clone(sync) - async def _proceedToClone(self, sync): + async def _proceed_to_clone(self, sync): if is_share_link(self.link): try: self.link = await sync_to_async( @@ -186,7 +186,7 @@ async def _proceedToClone(self, sync): except DirectDownloadLinkException as e: LOGGER.error(str(e)) if str(e).startswith("ERROR:"): - smsg = await sendMessage( + smsg = await send_message( self.message, str(e) ) @@ -207,12 +207,12 @@ async def _proceedToClone(self, sync): files, _ ) = await sync_to_async( - gdCount().count, + GoogleDriveCount().count, self.link, - self.userId + self.user_id ) if mime_type is None: - smsg = await sendMessage( + smsg = await send_message( self.message, self.name ) @@ -223,7 +223,7 @@ async def _proceedToClone(self, sync): return msg, button = await stop_duplicate_check(self) if msg: - smsg = await sendMessage( + smsg = await send_message( self.message, msg, button @@ -235,7 +235,7 @@ async def _proceedToClone(self, sync): return if limit_exceeded := await limit_checker(self): LOGGER.info(f"Clone Limit Exceeded: Name: {self.name} | Size: {self.size}") - smsg = await sendMessage( + smsg = await send_message( self.message, limit_exceeded ) @@ -244,11 +244,11 @@ async def _proceedToClone(self, sync): smsg ) return - await self.onDownloadStart() + await self.on_download_start() LOGGER.info(f"Clone Started: Name: {self.name} - Source: {self.link}") - drive = gdClone(self) + drive = GoogleDriveClone(self) if files <= 10: - msg = await sendMessage( + msg = await send_message( self.message, f"Cloning: {self.link}" ) @@ -257,14 +257,14 @@ async def _proceedToClone(self, sync): msg = "" gid = token_urlsafe(12) async with task_dict_lock: - task_dict[self.mid] = GdriveStatus( + task_dict[self.mid] = GoogleDriveStatus( self, drive, gid, "cl" ) if self.multi <= 1: - await sendStatusMessage(self.message) + await send_status_message(self.message) ( flink, mime_type, @@ -273,7 +273,7 @@ async def _proceedToClone(self, sync): dir_id ) = await sync_to_async(drive.clone) if msg: - await deleteMessage(msg) + await delete_message(msg) if not flink: return await self.onUploadComplete( @@ -291,12 +291,12 @@ async def _proceedToClone(self, sync): "", 1 ) - self.upDest = self.upDest.replace( + self.up_dest = self.up_dest.replace( "mrcc:", "", 1 ) - config_path = f"rclone/{self.userId}.conf" + config_path = f"rclone/{self.user_id}.conf" else: config_path = "rclone.conf" @@ -320,7 +320,7 @@ async def _proceedToClone(self, sync): if res[2] != 0: if res[2] != -9: msg = f"Error: While getting rclone stat. Path: {remote}:{src_path}. Stderr: {res[1][:4000]}" - smsg = await sendMessage( + smsg = await send_message( self.message, msg ) @@ -336,9 +336,9 @@ async def _proceedToClone(self, sync): if src_path else remote ) - self.upDest += ( + self.up_dest += ( self.name - if self.upDest.endswith(":") + if self.up_dest.endswith(":") else f"/{self.name}" ) @@ -350,11 +350,11 @@ async def _proceedToClone(self, sync): )[-1] mime_type = rstat["MimeType"] - await self.onDownloadStart() + await self.on_download_start() RCTransfer = RcloneTransferHelper(self) LOGGER.info( - f"Clone Started: Name: {self.name} - Source: {self.link} - Destination: {self.upDest}" + f"Clone Started: Name: {self.name} - Source: {self.link} - Destination: {self.up_dest}" ) gid = token_urlsafe(12) async with task_dict_lock: @@ -365,7 +365,7 @@ async def _proceedToClone(self, sync): "cl" ) if self.multi <= 1: - await sendStatusMessage(self.message) + await send_status_message(self.message) method = ( "sync" if sync @@ -445,7 +445,7 @@ async def _proceedToClone(self, sync): destination ) else: - smsg = await sendMessage( + smsg = await send_message( self.message, COMMAND_USAGE["clone"][0], COMMAND_USAGE["clone"][1] @@ -461,7 +461,7 @@ async def clone(client, message): Clone( client, message - ).newEvent()) + ).new_event()) bot.add_handler( # type: ignore diff --git a/bot/modules/exec.py b/bot/modules/exec.py index 7a32c91875e1..43c75736203d 100644 --- a/bot/modules/exec.py +++ b/bot/modules/exec.py @@ -6,18 +6,26 @@ getcwd, chdir ) + from nekozee.filters import command from nekozee.handlers import MessageHandler + from textwrap import indent from traceback import format_exc -from bot import LOGGER, bot -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( - sendFile, - sendMessage +from bot import ( + LOGGER, + bot +) +from ..helper.ext_utils.bot_utils import ( + new_task, + sync_to_async +) +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( + send_file, + send_message ) namespaces = {} @@ -46,18 +54,19 @@ async def send(msg, message): if len(str(msg)) > 2000: with BytesIO(str.encode(msg)) as out_file: out_file.name = "output.txt" - await sendFile( + await send_file( message, out_file ) else: LOGGER.info(f"OUT: '{msg}'") - await sendMessage( + await send_message( message, f"{msg}" ) +@new_task async def aioexecute(_, message): await send( await do( @@ -68,6 +77,7 @@ async def aioexecute(_, message): ) +@new_task async def execute(_, message): await send( await do( @@ -155,6 +165,7 @@ async def do(func, message): return result +@new_task async def clear(_, message): log_input(message) global namespaces diff --git a/bot/modules/file_selector.py b/bot/modules/file_selector.py index 0674cdc2ec3a..420a7bea4445 100644 --- a/bot/modules/file_selector.py +++ b/bot/modules/file_selector.py @@ -1,52 +1,55 @@ from aiofiles.os import ( - remove, - path as aiopath + path as aiopath, + remove ) + from nekozee.filters import ( command, regex ) from nekozee.handlers import ( - MessageHandler, - CallbackQueryHandler + CallbackQueryHandler, + MessageHandler ) from bot import ( - bot, - aria2, - task_dict, - task_dict_lock, - OWNER_ID, - user_data, LOGGER, + OWNER_ID, + aria2, + bot, config_dict, qbittorrent_client, sabnzbd_client, + task_dict, + task_dict_lock, + user_data ) -from bot.helper.ext_utils.bot_utils import ( +from ..helper.ext_utils.bot_utils import ( bt_selection_buttons, + new_task, sync_to_async ) -from bot.helper.ext_utils.status_utils import ( +from ..helper.ext_utils.status_utils import ( get_readable_file_size, - getTaskByGid, + get_task_by_gid, MirrorStatus ) -from bot.helper.ext_utils.task_manager import limit_checker -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.ext_utils.task_manager import limit_checker +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( auto_delete_message, delete_links, - sendMessage, - sendStatusMessage, - deleteMessage, + delete_message, + send_message, + send_status_message ) +@new_task async def select(_, message): if not config_dict["BASE_URL"]: - smsg = await sendMessage( + smsg = await send_message( message, "Base URL not defined!" ) @@ -59,9 +62,9 @@ async def select(_, message): msg = message.text.split() if len(msg) > 1: gid = msg[1] - task = await getTaskByGid(gid) + task = await get_task_by_gid(gid) if task is None: - smsg = await sendMessage( + smsg = await send_message( message, f"GID: {gid} Not Found." ) @@ -74,7 +77,7 @@ async def select(_, message): async with task_dict_lock: task = task_dict.get(reply_to_id) if task is None: - smsg = await sendMessage( + smsg = await send_message( message, "This is not an active task!" ) @@ -89,7 +92,7 @@ async def select(_, message): + "This command mainly for selection incase you decided to select files from already added torrent/nzb. " + "But you can always use /cmd with arg `s` to select files before download start." ) - smsg = await sendMessage( + smsg = await send_message( message, msg ) @@ -101,13 +104,13 @@ async def select(_, message): if ( OWNER_ID != user_id - and task.listener.userId != user_id + and task.listener.user_id != user_id and ( user_id not in user_data or not user_data[user_id].get("is_sudo") ) ): - smsg = await sendMessage( + smsg = await send_message( message, "This task is not for you!" ) @@ -121,7 +124,7 @@ async def select(_, message): MirrorStatus.STATUS_PAUSED, MirrorStatus.STATUS_QUEUEDL, ]: - smsg = await sendMessage( + smsg = await send_message( message, "Task should be in download or pause (incase message deleted by wrong) or queued status (incase you have used torrent or nzb file)!", ) @@ -134,7 +137,7 @@ async def select(_, message): task.name().startswith("[METADATA]") or task.name().startswith("Trying") ): - smsg = await sendMessage( + smsg = await send_message( message, "Try after downloading metadata finished!" ) @@ -147,9 +150,9 @@ async def select(_, message): try: id_ = task.gid() if not task.queued: - if task.listener.isNzb: + if task.listener.is_nzb: await sabnzbd_client.pause_job(id_) - elif task.listener.isQbit: + elif task.listener.is_qbit: await sync_to_async(task.update) id_ = task.hash() await sync_to_async( @@ -169,7 +172,7 @@ async def select(_, message): ) task.listener.select = True except: - smsg = await sendMessage( + smsg = await send_message( message, "This is not a bittorrent or sabnzbd task!" ) @@ -181,26 +184,27 @@ async def select(_, message): SBUTTONS = bt_selection_buttons(id_) msg = "Your download paused. Choose files then press Done Selecting button to resume downloading." - await sendMessage( + await send_message( message, msg, SBUTTONS ) +@new_task async def get_confirm(_, query): user_id = query.from_user.id data = query.data.split() message = query.message - task = await getTaskByGid(data[2]) + task = await get_task_by_gid(data[2]) if task is None: await query.answer( "This task has been cancelled!", show_alert=True ) - await deleteMessage(message) + await delete_message(message) return - if user_id != task.listener.userId: + if user_id != task.listener.user_id: await query.answer( "This task is not for you!", show_alert=True @@ -217,7 +221,7 @@ async def get_confirm(_, query): task, "seeding" ): - if task.listener.isQbit: + if task.listener.is_qbit: tor_info = ( await sync_to_async( qbittorrent_client.torrents_info, @@ -262,7 +266,7 @@ async def get_confirm(_, query): LOGGER.info(f"Total size after selection: {get_readable_file_size(task.listener.size)}") if limit_exceeded := await limit_checker(task.listener): LOGGER.info(f"Aria2 Limit Exceeded: {task.listener.name} | {get_readable_file_size(task.listener.size)}") - amsg = await task.listener.onDownloadError(limit_exceeded) + amsg = await task.listener.on_download_error(limit_exceeded) await sync_to_async( aria2.client.remove, id_ @@ -289,12 +293,12 @@ async def get_confirm(_, query): LOGGER.error( f"{e} Error in resume, this mostly happens after abuse aria2. Try to use select cmd again!" ) - elif task.listener.isNzb: + elif task.listener.is_nzb: await sabnzbd_client.resume_job(id_) - await sendStatusMessage(message) - await deleteMessage(message) + await send_status_message(message) + await delete_message(message) else: - await deleteMessage(message) + await delete_message(message) await task.cancel_task() diff --git a/bot/modules/force_start.py b/bot/modules/force_start.py index 6b8e8a66966e..ed749a7de28a 100644 --- a/bot/modules/force_start.py +++ b/bot/modules/force_start.py @@ -2,28 +2,30 @@ from nekozee.handlers import MessageHandler from bot import ( - task_dict, - bot, - task_dict_lock, OWNER_ID, - user_data, + bot, queued_up, queued_dl, queue_dict_lock, + task_dict, + task_dict_lock, + user_data, ) -from bot.helper.ext_utils.status_utils import getTaskByGid -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.ext_utils.bot_utils import new_task +from ..helper.ext_utils.status_utils import get_task_by_gid +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( auto_delete_message, - sendMessage + send_message ) -from bot.helper.ext_utils.task_manager import ( +from ..helper.ext_utils.task_manager import ( start_dl_from_queued, start_up_from_queued ) +@new_task async def remove_from_queue(_, message): user_id = ( message.from_user.id @@ -45,9 +47,9 @@ async def remove_from_queue(_, message): or not status and len(msg) > 1 ): gid = msg[2] if status else msg[1] - task = await getTaskByGid(gid) + task = await get_task_by_gid(gid) if task is None: - smsg = await sendMessage( + smsg = await send_message( message, f"GID: {gid} Not Found." ) @@ -60,7 +62,7 @@ async def remove_from_queue(_, message): async with task_dict_lock: task = task_dict.get(reply_to_id) if task is None: - smsg = await sendMessage( + smsg = await send_message( message, "This is not an active task!" ) @@ -77,7 +79,7 @@ async def remove_from_queue(_, message): "Reply to an active Command message which was used to start the download" f" or send /{BotCommands.ForceStartCommand[0]} GID to force start download and upload! Add you can use /cmd fd to force downlaod only or /cmd fu to force upload only!" ) - smsg = await sendMessage( + smsg = await send_message( message, msg ) @@ -88,13 +90,13 @@ async def remove_from_queue(_, message): return if ( OWNER_ID != user_id - and task.listener.userId != user_id + and task.listener.user_id != user_id and ( user_id not in user_data or not user_data[user_id].get("is_sudo") ) ): - smsg = await sendMessage( + smsg = await send_message( message, "This task is not for you!" ) @@ -107,18 +109,18 @@ async def remove_from_queue(_, message): msg = "" async with queue_dict_lock: if status == "fu": - listener.forceUpload = True + listener.force_upload = True if listener.mid in queued_up: await start_up_from_queued(listener.mid) msg = "Task have been force started to upload!" elif status == "fd": - listener.forceDownload = True + listener.force_download = True if listener.mid in queued_dl: await start_dl_from_queued(listener.mid) msg = "Task have been force started to download only!" else: - listener.forceDownload = True - listener.forceUpload = True + listener.force_download = True + listener.force_upload = True if listener.mid in queued_up: await start_up_from_queued(listener.mid) msg = "Task have been force started to upload!" @@ -126,7 +128,7 @@ async def remove_from_queue(_, message): await start_dl_from_queued(listener.mid) msg = "Task have been force started to download and upload will start once download finish!" if msg: - smsg = await sendMessage( + smsg = await send_message( message, msg ) diff --git a/bot/modules/gd_count.py b/bot/modules/gd_count.py index 6643d4df57da..28b5333b8fb5 100644 --- a/bot/modules/gd_count.py +++ b/bot/modules/gd_count.py @@ -2,21 +2,25 @@ from nekozee.handlers import MessageHandler from bot import bot -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.links_utils import is_gdrive_link -from bot.helper.ext_utils.status_utils import get_readable_file_size -from bot.helper.task_utils.gdrive_utils.count import gdCount -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.ext_utils.bot_utils import ( + new_task, + sync_to_async +) +from ..helper.ext_utils.links_utils import is_gdrive_link +from ..helper.ext_utils.status_utils import get_readable_file_size +from ..helper.task_utils.gdrive_utils.count import GoogleDriveCount +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( anno_checker, auto_delete_message, - deleteMessage, - sendMessage + delete_message, + send_message ) -async def countNode(_, message): +@new_task +async def count_node(_, message): args = message.text.split() from_user = message.from_user if not from_user: @@ -37,7 +41,7 @@ async def countNode(_, message): link = reply_to.text.split(maxsplit=1)[0].strip() if is_gdrive_link(link): - msg = await sendMessage( + msg = await send_message( message, f"Counting: {link}" ) @@ -47,12 +51,12 @@ async def countNode(_, message): size, files, folders ) = await sync_to_async( - gdCount().count, + GoogleDriveCount().count, link, from_user.id ) if mime_type is None: - smsg = await sendMessage( + smsg = await send_message( message, name ) @@ -61,7 +65,7 @@ async def countNode(_, message): smsg ) return - await deleteMessage(msg) + await delete_message(msg) msg = f"Name: {name}" msg += f"\n\nSize: {get_readable_file_size(size)}" msg += f"\n\nType: {mime_type}" @@ -74,7 +78,7 @@ async def countNode(_, message): "Send Gdrive link along with command or by replying to the link by command" ) - smsg = await sendMessage( + smsg = await send_message( message, msg ) @@ -86,7 +90,7 @@ async def countNode(_, message): bot.add_handler( # type: ignore MessageHandler( - countNode, + count_node, filters=command( BotCommands.CountCommand, case_sensitive=True diff --git a/bot/modules/gd_delete.py b/bot/modules/gd_delete.py index f7e76526e8ac..d749a18dbe9f 100644 --- a/bot/modules/gd_delete.py +++ b/bot/modules/gd_delete.py @@ -2,19 +2,23 @@ from nekozee.handlers import MessageHandler from bot import bot, LOGGER -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.links_utils import is_gdrive_link -from bot.helper.task_utils.gdrive_utils.delete import gdDelete -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.ext_utils.bot_utils import ( + new_task, + sync_to_async +) +from ..helper.ext_utils.links_utils import is_gdrive_link +from ..helper.task_utils.gdrive_utils.delete import GoogleDriveDelete +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( anno_checker, auto_delete_message, - sendMessage + send_message ) -async def deletefile(_, message): +@new_task +async def delete_file(_, message): args = message.text.split() from_user = message.from_user if not from_user: @@ -28,7 +32,7 @@ async def deletefile(_, message): if is_gdrive_link(link): LOGGER.info(link) msg = await sync_to_async( - gdDelete().deletefile, + GoogleDriveDelete().delete_file, link, from_user.id ) @@ -36,7 +40,7 @@ async def deletefile(_, message): msg = ( "Send Gdrive link along with command or by replying to the link by command" ) - reply_message = await sendMessage( + reply_message = await send_message( message, msg ) @@ -48,7 +52,7 @@ async def deletefile(_, message): bot.add_handler( # type: ignore MessageHandler( - deletefile, + delete_file, filters=command( BotCommands.DeleteCommand, case_sensitive=True diff --git a/bot/modules/gd_search.py b/bot/modules/gd_search.py index 75cdad15e8ab..354a0fac07ab 100644 --- a/bot/modules/gd_search.py +++ b/bot/modules/gd_search.py @@ -14,44 +14,45 @@ bot, user_data ) -from bot.helper.ext_utils.bot_utils import ( +from ..helper.ext_utils.bot_utils import ( + new_task, sync_to_async, get_telegraph_list ) -from bot.helper.ext_utils.status_utils import get_readable_time -from bot.helper.task_utils.gdrive_utils.search import gdSearch -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.ext_utils.status_utils import get_readable_time +from ..helper.task_utils.gdrive_utils.search import GoogleDriveSearch +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.button_build import ButtonMaker +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( anno_checker, auto_delete_message, - sendMessage, - editMessage + send_message, + edit_message ) -async def list_buttons(user_id, isRecursive=True, user_token=False): +async def list_buttons(user_id, is_recursive=True, user_token=False): buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ꜰᴏʟᴅᴇʀꜱ", - f"list_types {user_id} folders {isRecursive} {user_token}" + f"list_types {user_id} folders {is_recursive} {user_token}" ) - buttons.ibutton( + buttons.data_button( "ꜰɪʟᴇꜱ", - f"list_types {user_id} files {isRecursive} {user_token}") - buttons.ibutton( + f"list_types {user_id} files {is_recursive} {user_token}") + buttons.data_button( "ʙᴏᴛʜ", - f"list_types {user_id} both {isRecursive} {user_token}") - buttons.ibutton( - f"ʀᴇᴄᴜʀꜱɪᴠᴇ: {isRecursive}", - f"list_types {user_id} rec {isRecursive} {user_token}", + f"list_types {user_id} both {is_recursive} {user_token}") + buttons.data_button( + f"ʀᴇᴄᴜʀꜱɪᴠᴇ: {is_recursive}", + f"list_types {user_id} rec {is_recursive} {user_token}", ) - buttons.ibutton( + buttons.data_button( f"ᴜꜱᴇʀ\nᴛᴏᴋᴇɴ: {user_token}", - f"list_types {user_id} ut {isRecursive} {user_token}", + f"list_types {user_id} ut {is_recursive} {user_token}", ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", f"list_types {user_id} cancel") return buttons.build_menu(2) @@ -61,7 +62,7 @@ async def _list_drive( key, message, item_type, - isRecursive, + is_recursive, user_token, user_id ): @@ -91,9 +92,9 @@ async def _list_drive( telegraph_content, contents_no ) = await sync_to_async( - gdSearch( - isRecursive=isRecursive, - itemType=item_type + GoogleDriveSearch( + is_recursive=is_recursive, + item_type=item_type ).drive_list, key, target_id, @@ -106,24 +107,24 @@ async def _list_drive( button = await get_telegraph_list(telegraph_content) except Exception as e: emsg = f"{e}" - await editMessage( + await edit_message( message, emsg ) return emsg = f"Found {contents_no} result for {key}\n" - emsg += f"Type: {item_type}\nRecursive list: {isRecursive}\n" + emsg += f"Type: {item_type}\nRecursive list: {is_recursive}\n" emsg += f"Elapsed: {elapsed}\n\ncc: {tag}" - await editMessage( + await edit_message( message, emsg, button ) else: emsg = f"No result found for {key}\n" - emsg += f"Type: {item_type}\nRecursive list: {isRecursive}\n" + emsg += f"Type: {item_type}\nRecursive list: {is_recursive}\n" emsg += f"Elapsed: {elapsed}\n\ncc: {tag}" - await editMessage( + await edit_message( message, emsg ) @@ -134,6 +135,7 @@ async def _list_drive( ) +@new_task async def select_type(_, query): user_id = query.from_user.id message = query.message @@ -147,14 +149,14 @@ async def select_type(_, query): ) elif data[2] == "rec": await query.answer() - isRecursive = not bool(eval(data[3])) + is_recursive = not bool(eval(data[3])) buttons = await list_buttons( user_id, - isRecursive, + is_recursive, eval(data[4]) ) emsg = "Choose list options:" - await editMessage( + await edit_message( message, emsg, buttons @@ -169,7 +171,7 @@ async def select_type(_, query): user_token ) emsg = "Choose list options:" - await editMessage( + await edit_message( message, emsg, buttons @@ -178,7 +180,7 @@ async def select_type(_, query): elif data[2] == "cancel": await query.answer() emsg = "list has been canceled!" - await editMessage( + await edit_message( message, emsg, ) @@ -190,9 +192,9 @@ async def select_type(_, query): ) await query.answer() item_type = data[2] - isRecursive = eval(data[3]) + is_recursive = eval(data[3]) user_token = eval(data[4]) - await editMessage( + await edit_message( message, f"Searching for {key}" ) @@ -200,18 +202,19 @@ async def select_type(_, query): key, message, item_type, - isRecursive, + is_recursive, user_token, user_id ) +@new_task async def gdrive_search(_, message): from_user = message.from_user if not from_user: from_user = await anno_checker(message) if len(message.text.split()) == 1: - gmsg = await sendMessage( + gmsg = await send_message( message, "Send a search key along with command" ) @@ -222,7 +225,7 @@ async def gdrive_search(_, message): return user_id = from_user.id buttons = await list_buttons(user_id) - gmsg = await sendMessage( + gmsg = await send_message( message, "Choose list options:", buttons diff --git a/bot/modules/help.py b/bot/modules/help.py index 1836fc61433a..6f66e455086a 100644 --- a/bot/modules/help.py +++ b/bot/modules/help.py @@ -2,77 +2,81 @@ from nekozee.handlers import CallbackQueryHandler from bot import bot -from bot.helper.ext_utils.bot_utils import COMMAND_USAGE -from bot.helper.ext_utils.help_messages import ( +from ..helper.ext_utils.bot_utils import ( + COMMAND_USAGE, + new_task +) +from ..helper.ext_utils.help_messages import ( YT_HELP_DICT, MIRROR_HELP_DICT, CLONE_HELP_DICT, ) -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.message_utils import ( - editMessage, - deleteMessage, +from ..helper.telegram_helper.button_build import ButtonMaker +from ..helper.telegram_helper.message_utils import ( + edit_message, + delete_message, delete_links ) -async def argUsage(_, query): +@new_task +async def arg_usage(_, query): data = query.data.split() message = query.message if data[1] == "close": await delete_links(message) - await deleteMessage(message) + await delete_message(message) elif data[1] == "back": if data[2] == "m": - await editMessage( + await edit_message( message, COMMAND_USAGE["mirror"][0], COMMAND_USAGE["mirror"][1] ) elif data[2] == "y": - await editMessage( + await edit_message( message, COMMAND_USAGE["yt"][0], COMMAND_USAGE["yt"][1] ) elif data[2] == "c": - await editMessage( + await edit_message( message, COMMAND_USAGE["clone"][0], COMMAND_USAGE["clone"][1] ) elif data[1] == "mirror": buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "help back m" ) button = buttons.build_menu() - await editMessage( + await edit_message( message, MIRROR_HELP_DICT[data[2] + "\n" + data[3]], button ) elif data[1] == "yt": buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "help back y" ) button = buttons.build_menu() - await editMessage( + await edit_message( message, YT_HELP_DICT[data[2] + "\n" + data[3]], button ) elif data[1] == "clone": buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", "help back c" ) button = buttons.build_menu() - await editMessage( + await edit_message( message, CLONE_HELP_DICT[data[2] + "\n" + data[3]], button @@ -81,7 +85,7 @@ async def argUsage(_, query): bot.add_handler( # type: ignore CallbackQueryHandler( - argUsage, + arg_usage, filters=regex("^help") ) ) diff --git a/bot/modules/leech_del.py b/bot/modules/leech_del.py index 77e1b73834bc..cbfebf94bcbe 100644 --- a/bot/modules/leech_del.py +++ b/bot/modules/leech_del.py @@ -1,16 +1,14 @@ -#!/usr/bin/env python3 from asyncio import sleep from nekozee.filters import command from nekozee.handlers import MessageHandler from bot import bot -from bot.helper.ext_utils.bot_utils import new_task -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( - editMessage, - sendMessage +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( + edit_message, + send_message ) delete = set() @@ -26,7 +24,7 @@ async def delete_leech(client, message): link = "" if not link.startswith("https://t.me/"): msg = "Send telegram message link along with command or by replying to the link by command" - return await sendMessage( + return await send_message( message, msg ) @@ -35,7 +33,7 @@ async def delete_leech(client, message): message_id = int(link[-1]) if message_id in delete: msg = "Already deleting in progress" - return await sendMessage( + return await send_message( message, msg ) @@ -43,7 +41,7 @@ async def delete_leech(client, message): if chat_id.isdigit(): chat_id = f"-100{chat_id}" chat_id = int(chat_id) - reply_message = await sendMessage( + reply_message = await send_message( message, msg ) @@ -95,12 +93,12 @@ async def deleting(client, chat_id, message_id, message): ) if len(each100) > 100: await sleep(1) - await editMessage( + await edit_message( message, f"{deleted}/{total_ids} message deleted" ) except Exception as e: - await editMessage(message, str(e)) + await edit_message(message, str(e)) delete.remove(message_id) bot.add_handler( # type: ignore diff --git a/bot/modules/mirror_leech.py b/bot/modules/mirror_leech.py index e2702f0d3046..88905cdf3b1e 100644 --- a/bot/modules/mirror_leech.py +++ b/bot/modules/mirror_leech.py @@ -3,24 +3,25 @@ remove ) from base64 import b64encode +from re import match as re_match + from nekozee.filters import command from nekozee.handlers import MessageHandler -from re import match as re_match from bot import ( - bot, DOWNLOAD_DIR, LOGGER, + bot, bot_loop ) -from bot.helper.ext_utils.bot_utils import ( +from ..helper.ext_utils.bot_utils import ( + COMMAND_USAGE, get_content_type, sync_to_async, - arg_parser, - COMMAND_USAGE, + arg_parser ) -from bot.helper.ext_utils.exceptions import DirectDownloadLinkException -from bot.helper.ext_utils.links_utils import ( +from ..helper.ext_utils.exceptions import DirectDownloadLinkException +from ..helper.ext_utils.links_utils import ( is_url, is_magnet, is_gdrive_id, @@ -29,35 +30,25 @@ is_rclone_path, is_telegram_link, ) -from bot.helper.listeners.task_listener import TaskListener -from bot.helper.task_utils.download_utils.aria2_download import ( - add_aria2c_download, -) -from bot.helper.task_utils.download_utils.direct_downloader import ( - add_direct_download, -) -from bot.helper.task_utils.download_utils.direct_link_generator import ( - direct_link_generator, -) -from bot.helper.task_utils.download_utils.gd_download import add_gd_download -from bot.helper.task_utils.download_utils.jd_download import add_jd_download -from bot.helper.task_utils.download_utils.mega_download import add_mega_download -from bot.helper.task_utils.download_utils.qbit_download import add_qb_torrent -from bot.helper.task_utils.download_utils.nzb_downloader import add_nzb -from bot.helper.task_utils.download_utils.rclone_download import ( - add_rclone_download, -) -from bot.helper.task_utils.download_utils.telegram_download import ( - TelegramDownloadHelper, -) -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.listeners.task_listener import TaskListener +from ..helper.task_utils.download_utils.aria2_download import add_aria2c_download +from ..helper.task_utils.download_utils.direct_downloader import add_direct_download +from ..helper.task_utils.download_utils.direct_link_generator import direct_link_generator +from ..helper.task_utils.download_utils.gd_download import add_gd_download +from ..helper.task_utils.download_utils.jd_download import add_jd_download +from ..helper.task_utils.download_utils.mega_download import add_mega_download +from ..helper.task_utils.download_utils.qbit_download import add_qb_torrent +from ..helper.task_utils.download_utils.nzb_downloader import add_nzb +from ..helper.task_utils.download_utils.rclone_download import add_rclone_download +from ..helper.task_utils.download_utils.telegram_download import TelegramDownloadHelper +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( auto_delete_message, - deleteMessage, + delete_message, get_tg_link_message, - sendMessage, - editMessage, + send_message, + edit_message, ) from myjd.exception import MYJDException @@ -67,34 +58,34 @@ def __init__( self, client, message, - isQbit=False, - isLeech=False, - isJd=False, - isNzb=False, - sameDir=None, + is_qbit=False, + is_leech=False, + is_jd=False, + is_nzb=False, + same_dir=None, bulk=None, - multiTag=None, + multi_tag=None, options="", ): - if sameDir is None: - sameDir = {} + if same_dir is None: + same_dir = {} if bulk is None: bulk = [] self.message = message self.client = client - self.multiTag = multiTag + self.multi_tag = multi_tag self.options = options - self.sameDir = sameDir + self.same_dir = same_dir self.bulk = bulk super().__init__() - self.isQbit = isQbit - self.isLeech = isLeech - self.isJd = isJd - self.isNzb = isNzb + self.is_qbit = is_qbit + self.is_leech = is_leech + self.is_jd = is_jd + self.is_nzb = is_nzb self.file_ = None - async def newEvent(self): - self.pmsg = await sendMessage( + async def new_event(self): + self.pmsg = await send_message( self.message, "Processing your request..." ) @@ -106,7 +97,7 @@ async def newEvent(self): ) except Exception as e: LOGGER.error(e) - await editMessage( + await edit_message( self.pmsg, f"ERROR: {e}" ) @@ -126,6 +117,8 @@ async def newEvent(self): "-fd": False, "-forcedownload": False, "-fu": False, "-forceupload": False, "-ml": False, "-mixedleech": False, + "-doc": False, "-document": False, + "-med": False, "-media": False, "-m": 0, "-sp": 0, "-splitsize": 0, "link": "", @@ -142,6 +135,7 @@ async def newEvent(self): "-ns": "", "-namesub": "", "-md": "", "-metadata": "", "-mda": "", "-metaattachment": "", + "-tl": "", "-thumblayout": "", } arg_parser( @@ -152,28 +146,31 @@ async def newEvent(self): self.select = args["-s"] or args["-select"] self.seed = args["-d"] or args["-seed"] self.name = args["-n"] or args["-rename"] - self.upDest = args["-up"] or args["-upload"] - self.rcFlags = args["-rcf"] + self.up_dest = args["-up"] or args["-upload"] + self.rc_flags = args["-rcf"] self.link = args["link"] self.compress = args["-z"] or args["-zip"] or args["-compress"] self.extract = args["-e"] or args["-extract"] or args["-uz"] or args["-unzip"] self.join = args["-j"] or args["-join"] self.thumb = args["-t"] or args["-thumb"] - self.splitSize = args["-sp"] or args["-splitsize"] - self.sampleVideo = args["-sv"] or args["-samplevideo"] - self.screenShots = args["-ss"] or args["-screenshot"] - self.forceRun = args["-f"] or args["-forcerun"] - self.forceDownload = args["-fd"] or args["-forcedownload"] - self.forceUpload = args["-fu"] or args["-forceupload"] - self.convertAudio = args["-ca"] or args["-convertaudio"] - self.convertVideo = args["-cv"] or args["-convertvideo"] - self.nameSub = args["-ns"] or args["-namesub"] - self.mixedLeech = args["-ml"] or args["-mixedleech"] - self.metaData = args["-md"] or args["-metadata"] - self.metaAttachment = args["-mda"] or args["-metaattachment"] + self.split_size = args["-sp"] or args["-splitsize"] + self.sample_video = args["-sv"] or args["-samplevideo"] + self.screen_shots = args["-ss"] or args["-screenshot"] + self.force_run = args["-f"] or args["-forcerun"] + self.force_download = args["-fd"] or args["-forcedownload"] + self.force_upload = args["-fu"] or args["-forceupload"] + self.convert_audio = args["-ca"] or args["-convertaudio"] + self.convert_video = args["-cv"] or args["-convertvideo"] + self.name_sub = args["-ns"] or args["-namesub"] + self.mixed_leech = args["-ml"] or args["-mixedleech"] + self.metadata = args["-md"] or args["-metadata"] + self.m_attachment = args["-mda"] or args["-metaattachment"] + self.thumbnail_layout = args["-tl"] or args["-thumblayout"] + self.as_doc = args["-doc"] or args["-document"] + self.as_med = args["-med"] or args["-media"] headers = args["-h"] or args["-headers"] - isBulk = args["-b"] or args["-bulk"] + is_bulk = args["-b"] or args["-bulk"] folder_name = args["-sd"] or args["-samedir"] bulk_start = 0 @@ -183,9 +180,8 @@ async def newEvent(self): reply_to = None session = "" - await self.getId() - - await self.getTag(text) + await self.get_id() + await self.get_tag(text) try: self.multi = int(args["-m"]) @@ -205,8 +201,8 @@ async def newEvent(self): ) self.seed = True - if not isinstance(isBulk, bool): - dargs = isBulk.split(":") + if not isinstance(is_bulk, bool): + dargs = is_bulk.split(":") bulk_start = ( dargs[0] or 0 @@ -216,27 +212,27 @@ async def newEvent(self): dargs[1] or 0 ) - isBulk = True + is_bulk = True - if not isBulk: + if not is_bulk: if folder_name: self.seed = False ratio = None seed_time = None folder_name = f"/{folder_name}" - if not self.sameDir: - self.sameDir = { + if not self.same_dir: + self.same_dir = { "total": self.multi, "tasks": set(), "name": folder_name, } - self.sameDir["tasks"].add(self.mid) - elif self.sameDir: - self.sameDir["total"] -= 1 + self.same_dir["tasks"].add(self.mid) + elif self.same_dir: + self.same_dir["total"] -= 1 else: - await deleteMessage(self.pmsg) - await self.initBulk( + await delete_message(self.pmsg) + await self.init_bulk( input_list, bulk_start, bulk_end, @@ -247,11 +243,11 @@ async def newEvent(self): if len(self.bulk) != 0: del self.bulk[0] - self.run_multi( + await self.run_multi( input_list, folder_name, Mirror - ) # type: ignore + ) path = f"{DOWNLOAD_DIR}{self.mid}{folder_name}" @@ -264,6 +260,7 @@ async def newEvent(self): "\n", 1 )[0].strip() + if is_telegram_link(self.link): try: result = await get_tg_link_message(self.link) @@ -272,12 +269,12 @@ async def newEvent(self): except Exception as e: e = str(e) if "group" in e: - tmsg = await sendMessage( + tmsg = await send_message( self.message, f"ERROR: This is a TG invite link.\nSend media links to download.\n\ncc: {self.tag}" ) return tmsg - tmsg = await sendMessage( + tmsg = await send_message( self.message, f"ERROR: {e}\n\ncc: {self.tag}" ) @@ -285,19 +282,17 @@ async def newEvent(self): self.message, tmsg ) - self.removeFromSameDir() - await deleteMessage(self.pmsg) + self.remove_from_same_dir() + await delete_message(self.pmsg) return if isinstance(reply_to, list): self.bulk = reply_to - self.sameDir = {} + self.same_dir = {} b_msg = input_list[:1] self.options = " ".join(input_list[1:]) - b_msg.append( - f"{self.bulk[0]} -m {len(self.bulk)} {self.options}" - ) - nextmsg = await sendMessage( + b_msg.append(f"{self.bulk[0]} -m {len(self.bulk)} {self.options}") + nextmsg = await send_message( self.message, " ".join(b_msg) ) @@ -305,22 +300,24 @@ async def newEvent(self): chat_id=self.message.chat.id, message_ids=nextmsg.id # type: ignore ) + if self.message.from_user: nextmsg.from_user = self.user else: nextmsg.sender_chat = self.user + await Mirror( self.client, nextmsg, - self.isQbit, - self.isLeech, - self.isJd, - self.isNzb, - self.sameDir, + self.is_qbit, + self.is_leech, + self.is_jd, + self.is_nzb, + self.same_dir, self.bulk, - self.multiTag, + self.multi_tag, self.options, - ).newEvent() + ).new_event() return if reply_to: @@ -369,35 +366,35 @@ async def newEvent(self): and not is_gdrive_link(self.link) and not is_mega_link(self.link) ): - cmsg = await sendMessage( + cmsg = await send_message( self.message, COMMAND_USAGE["mirror"][0], COMMAND_USAGE["mirror"][1] ) - self.removeFromSameDir() - await deleteMessage(self.pmsg) + self.remove_from_same_dir() + await delete_message(self.pmsg) await auto_delete_message( self.message, cmsg ) return - if self.link: + if len(self.link) > 0: LOGGER.info(self.link) - if await self.permissionCheck() != True: + if await self.permission_check() != True: return - await deleteMessage(self.pmsg) + await delete_message(self.pmsg) try: - await self.beforeStart() + await self.before_start() except Exception as e: - emsg = await sendMessage( + emsg = await send_message( self.message, e ) - self.removeFromSameDir() - await deleteMessage(self.pmsg) + self.remove_from_same_dir() + await delete_message(self.pmsg) await auto_delete_message( self.message, emsg @@ -405,9 +402,9 @@ async def newEvent(self): return if ( - not self.isJd - and not self.isNzb - and not self.isQbit + not self.is_jd + and not self.is_nzb + and not self.is_qbit and not is_magnet(self.link) and not is_rclone_path(self.link) and not is_gdrive_link(self.link) @@ -441,11 +438,11 @@ async def newEvent(self): if "This link requires a password!" not in e: LOGGER.info(e) if e.startswith("ERROR:"): - dmsg = await sendMessage( + dmsg = await send_message( self.message, e ) - self.removeFromSameDir() + self.remove_from_same_dir() await auto_delete_message( self.message, dmsg @@ -466,7 +463,7 @@ async def newEvent(self): self, path ) - elif self.isJd: + elif self.is_jd: try: await add_jd_download( self, @@ -476,11 +473,11 @@ async def newEvent(self): Exception, MYJDException ) as e: - jmsg = await sendMessage( + jmsg = await send_message( self.message, f"{e}".strip() ) - self.removeFromSameDir() + self.remove_from_same_dir() await auto_delete_message( self.message, jmsg @@ -489,14 +486,14 @@ async def newEvent(self): finally: if await aiopath.exists(str(self.link)): await remove(str(self.link)) - elif self.isQbit: + elif self.is_qbit: await add_qb_torrent( self, path, ratio, seed_time ) - elif self.isNzb: + elif self.is_nzb: await add_nzb( self, path @@ -540,66 +537,66 @@ async def mirror(client, message): bot_loop.create_task(Mirror( client, message - ).newEvent()) # type: ignore + ).new_event()) # type: ignore async def qb_mirror(client, message): bot_loop.create_task(Mirror( client, message, - isQbit=True - ).newEvent()) # type: ignore + is_qbit=True + ).new_event()) # type: ignore async def jd_mirror(client, message): bot_loop.create_task(Mirror( client, message, - isJd=True - ).newEvent()) # type: ignore + is_jd=True + ).new_event()) # type: ignore async def nzb_mirror(client, message): bot_loop.create_task(Mirror( client, message, - isNzb=True - ).newEvent()) # type: ignore + is_nzb=True + ).new_event()) # type: ignore async def leech(client, message): bot_loop.create_task(Mirror( client, message, - isLeech=True - ).newEvent()) # type: ignore + is_leech=True + ).new_event()) # type: ignore async def qb_leech(client, message): bot_loop.create_task(Mirror( client, message, - isQbit=True, - isLeech=True - ).newEvent()) # type: ignore + is_qbit=True, + is_leech=True + ).new_event()) # type: ignore async def jd_leech(client, message): bot_loop.create_task(Mirror( client, message, - isLeech=True, - isJd=True - ).newEvent()) # type: ignore + is_leech=True, + is_jd=True + ).new_event()) # type: ignore async def nzb_leech(client, message): bot_loop.create_task(Mirror( client, message, - isLeech=True, - isNzb=True - ).newEvent()) # type: ignore + is_leech=True, + is_nzb=True + ).new_event()) # type: ignore bot.add_handler( # type: ignore diff --git a/bot/modules/rmdb.py b/bot/modules/rmdb.py index 1c1dc446ead7..1ff487170a5d 100644 --- a/bot/modules/rmdb.py +++ b/bot/modules/rmdb.py @@ -1,37 +1,39 @@ -#!/usr/bin/env python3 from nekozee.filters import command from nekozee.handlers import MessageHandler -from bot import DATABASE_URL, bot, config_dict -from bot.helper.ext_utils.links_utils import ( +from bot import ( + bot, + config_dict +) +from ..helper.ext_utils.links_utils import ( is_magnet, is_url ) -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.z_utils import extract_link -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import sendMessage +from ..helper.ext_utils.db_handler import database +from ..helper.z_utils import extract_link +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import send_message -async def rmAllTokens(_, message): - if DATABASE_URL: - await DbManager().delete_all_access_tokens() +async def remove_all_tokens(_, message): + if config_dict["DATABASE_URL"]: + await database.delete_all_access_tokens() msg = "All access tokens have been removed from the database." else: msg = "Database URL not added." - return await sendMessage( + return await send_message( message, msg ) -async def rmdbNode(_, message): +async def remove_specific_task(_, message): if ( - DATABASE_URL + config_dict["DATABASE_URL"] and not config_dict["STOP_DUPLICATE_TASKS"] ): - return await sendMessage( + return await send_message( message, "STOP_DUPLICATE_TASKS feature is not enabled" ) @@ -41,7 +43,7 @@ async def rmdbNode(_, message): maxsplit=1 ) file = None - shouldDel = False + should_delete = False try: link = message_args[1] except IndexError: @@ -89,35 +91,35 @@ async def rmdbNode(_, message): pass elif file.mime_type == "application/x-bittorrent": link = await reply_to.download() - shouldDel = True + should_delete = True else: link = file.file_unique_id if not link: msg = "Something went wrong!!" - return await sendMessage( + return await send_message( message, msg ) raw_url = await extract_link( link, - shouldDel + should_delete ) - if exist := await DbManager().check_download(raw_url): - await DbManager().remove_download(exist["_id"]) + if exist := await database.check_download(raw_url): + await database.remove_download(exist["_id"]) msg = "Download is removed from database successfully" msg += f"\n{exist["tag"]} Your download is removed." else: msg = "This download is not exists in database" - return await sendMessage( + return await send_message( message, msg ) -if DATABASE_URL: +if config_dict["DATABASE_URL"]: bot.add_handler( # type: ignore MessageHandler( - rmdbNode, + remove_specific_task, filters=command( BotCommands.RmdbCommand, case_sensitive=True @@ -126,7 +128,7 @@ async def rmdbNode(_, message): ) bot.add_handler( # type: ignore MessageHandler( - rmAllTokens, + remove_all_tokens, filters=command( BotCommands.RmalltokensCommand, case_sensitive=True diff --git a/bot/modules/rss.py b/bot/modules/rss.py index bf2f6a7b0633..cfe274252ee8 100644 --- a/bot/modules/rss.py +++ b/bot/modules/rss.py @@ -1,13 +1,17 @@ -from httpx import AsyncClient -from apscheduler.triggers.interval import IntervalTrigger from asyncio import ( Lock, sleep, gather ) -from datetime import datetime, timedelta -from feedparser import parse as feedparse +from apscheduler.triggers.interval import IntervalTrigger +from datetime import ( + datetime, + timedelta +) +from feedparser import parse as feed_parse +from httpx import AsyncClient from io import BytesIO + from nekozee.filters import ( command, regex @@ -22,59 +26,61 @@ ) from bot import ( - scheduler, - rss_dict, LOGGER, - DATABASE_URL, + bot, config_dict, - bot + rss_dict, + scheduler +) +from ..helper.ext_utils.bot_utils import ( + arg_parser, + new_task ) -from bot.helper.ext_utils.bot_utils import arg_parser -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.ext_utils.exceptions import RssShutdownException -from bot.helper.ext_utils.help_messages import RSS_HELP_MESSAGE -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( - sendMessage, - editMessage, - sendRss, - sendFile, - deleteMessage, +from ..helper.ext_utils.db_handler import database +from ..helper.ext_utils.exceptions import RssShutdownException +from ..helper.ext_utils.help_messages import RSS_HELP_MESSAGE +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.button_build import ButtonMaker +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( + send_message, + edit_message, + send_rss, + send_file, + delete_message, ) rss_dict_lock = Lock() -async def rssMenu(event): +async def rss_menu(event): user_id = event.from_user.id buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "Subscribe", f"rss sub {user_id}" ) - buttons.ibutton( + buttons.data_button( "Subscriptions", f"rss list {user_id} 0" ) - buttons.ibutton( + buttons.data_button( "Get Items", f"rss get {user_id}" ) - buttons.ibutton( + buttons.data_button( "Edit", f"rss edit {user_id}" ) - buttons.ibutton( + buttons.data_button( "Pause", f"rss pause {user_id}" ) - buttons.ibutton( + buttons.data_button( "Resume", f"rss resume {user_id}" ) - buttons.ibutton( + buttons.data_button( "Unsubscribe", f"rss unsubscribe {user_id}" ) @@ -82,37 +88,37 @@ async def rssMenu(event): "", # type: ignore event ): - buttons.ibutton( + buttons.data_button( "All Subscriptions", f"rss listall {user_id} 0" ) - buttons.ibutton( + buttons.data_button( "Pause All", f"rss allpause {user_id}" ) - buttons.ibutton( + buttons.data_button( "Resume All", f"rss allresume {user_id}" ) - buttons.ibutton( + buttons.data_button( "Unsubscribe All", f"rss allunsub {user_id}" ) - buttons.ibutton( + buttons.data_button( "Delete User", f"rss deluser {user_id}" ) if scheduler.running: - buttons.ibutton( + buttons.data_button( "Shutdown Rss", f"rss shutdown {user_id}" ) else: - buttons.ibutton( + buttons.data_button( "Start Rss", f"rss start {user_id}" ) - buttons.ibutton( + buttons.data_button( "Close", f"rss close {user_id}" ) @@ -124,16 +130,17 @@ async def rssMenu(event): ) -async def updateRssMenu(query): - msg, button = await rssMenu(query) - await editMessage( +async def update_rss_menu(query): + msg, button = await rss_menu(query) + await edit_message( query.message, msg, button ) -async def getRssMenu(client, message): +@new_task +async def get_rss_menu(client, message): await client.stop_listening( chat_id=message.chat.id, user_id=message.from_user.id @@ -141,15 +148,16 @@ async def getRssMenu(client, message): ( msg, button - ) = await rssMenu(message) - await sendMessage( + ) = await rss_menu(message) + await send_message( message, msg, button ) -async def rssSub(message): +@new_task +async def rss_sub(message): user_id = message.from_user.id if username := message.from_user.username: tag = f"@{username}" @@ -163,7 +171,7 @@ async def rssSub(message): ): args = item.split() if len(args) < 2: - await sendMessage( + await send_message( message, f"{item}. Wrong Input format. Read help message before adding new subcription!", ) @@ -176,7 +184,7 @@ async def rssSub(message): )) and title in user_feeds ): - await sendMessage( + await send_message( message, f"This title {title} already subscribed! Choose another title!" ) @@ -187,7 +195,7 @@ async def rssSub(message): "-exf", "-c" )): - await sendMessage( + await send_message( message, f"Wrong input in line {index}! Add Title! Read the example!", ) @@ -230,7 +238,7 @@ async def rssSub(message): async with AsyncClient(verify=False) as client: res = await client.get(feed_link) html = res.text - rss_d = feedparse(html) + rss_d = feed_parse(html) last_title = rss_d.entries[0]["title"] msg += "Subscribed!" msg += f"\nTitle: {title}\nFeed Url: {feed_link}" @@ -283,19 +291,19 @@ async def rssSub(message): ) except (IndexError, AttributeError) as e: emsg = f"The link: {feed_link} doesn't seem to be a RSS feed or it's region-blocked!" - await sendMessage( + await send_message( message, emsg + "\nError: " + str(e) ) except Exception as e: - await sendMessage( + await send_message( message, str(e) ) if msg: - if DATABASE_URL and rss_dict[user_id]: - await DbManager().rss_update(user_id) - await sendMessage( + if config_dict["DATABASE_URL"] and rss_dict[user_id]: + await database.rss_update(user_id) + await send_message( message, msg ) @@ -306,11 +314,11 @@ async def rssSub(message): if scheduler.state == 2: scheduler.resume() elif is_sudo and not scheduler.running: - addJob() + add_job() scheduler.start() -async def getUserId(title): +async def get_user_id(title): async with rss_dict_lock: return next( ( @@ -326,7 +334,8 @@ async def getUserId(title): ) -async def rssUpdate(message, state): +@new_task +async def rss_update(message, state): user_id = message.from_user.id titles = message.text.split() is_sudo = await CustomFilters.sudo( @@ -338,10 +347,10 @@ async def rssUpdate(message, state): title = title.strip() if not (res := rss_dict[user_id].get(title, False)): if is_sudo: - res, user_id = await getUserId(title) + res, user_id = await get_user_id(title) if not res: user_id = message.from_user.id - await sendMessage( + await send_message( message, f"{title} not found!" ) @@ -351,7 +360,7 @@ async def rssUpdate(message, state): istate and state == "pause" or not istate and state == "resume" ): - await sendMessage( + await send_message( message, f"{title} already {state}d!" ) @@ -368,35 +377,35 @@ async def rssUpdate(message, state): if scheduler.state == 2: scheduler.resume() elif is_sudo and not scheduler.running: - addJob() + add_job() scheduler.start() if ( is_sudo - and DATABASE_URL + and config_dict["DATABASE_URL"] and user_id != message.from_user.id ): - await DbManager().rss_update(user_id) + await database.rss_update(user_id) if not rss_dict[user_id]: async with rss_dict_lock: del rss_dict[user_id] - if DATABASE_URL: - await DbManager().rss_delete(user_id) + if config_dict["DATABASE_URL"]: + await database.rss_delete(user_id) if not rss_dict: - await DbManager().trunc_table("rss") + await database.trunc_table("rss") if updated: LOGGER.info(f"Rss link with Title(s): {updated} has been {state}d!") - await sendMessage( + await send_message( message, f"Rss links with Title(s): {updated} has been {state}d!", ) if ( - DATABASE_URL and + config_dict["DATABASE_URL"] and rss_dict.get(user_id) ): - await DbManager().rss_update(user_id) + await database.rss_update(user_id) -async def rssList(query, start, all_users=False): +async def rss_list(query, start, all_users=False): user_id = query.from_user.id buttons = ButtonMaker() if all_users: @@ -443,11 +452,11 @@ async def rssList(query, start, all_users=False): )}\n" ) list_feed += f"Paused: {data['paused']}\n" - buttons.ibutton( + buttons.data_button( "Back", f"rss back {user_id}" ) - buttons.ibutton( + buttons.data_button( "Close", f"rss close {user_id}" ) @@ -457,7 +466,7 @@ async def rssList(query, start, all_users=False): keysCount, 5 ): - buttons.ibutton( + buttons.data_button( f"{int(x / 5)}", f"rss list {user_id} {x}", position="footer" @@ -465,18 +474,19 @@ async def rssList(query, start, all_users=False): button = buttons.build_menu(2) if query.message.text.html == list_feed: return - await editMessage( + await edit_message( query.message, list_feed, button ) -async def rssGet(message): +@new_task +async def rss_get(message): user_id = message.from_user.id args = message.text.split() if len(args) < 2: - await sendMessage( + await send_message( message, f"{args}. Wrong Input format. You should add number of the items you want to get. Read help message before adding new subcription!", ) @@ -487,13 +497,13 @@ async def rssGet(message): data = rss_dict[user_id].get(title, False) if data and count > 0: try: - msg = await sendMessage( + msg = await send_message( message, f"Getting the last {count} item(s) from {title}" ) async with AsyncClient(verify=False) as client: res = await client.get(data["link"]) html = res.text - rss_d = feedparse(html) + rss_d = feed_parse(html) item_info = "" for item_num in range(count): try: @@ -505,43 +515,44 @@ async def rssGet(message): item_info_ecd = item_info.encode() if len(item_info_ecd) > 4000: with BytesIO(item_info_ecd) as out_file: - out_file.name = f"rssGet {title} items_no. {count}.txt" - await sendFile( + out_file.name = f"rss_get {title} items_no. {count}.txt" + await send_file( message, out_file ) - await deleteMessage(msg) + await delete_message(msg) else: - await editMessage( + await edit_message( msg, item_info ) except IndexError as e: LOGGER.error(str(e)) - await editMessage( + await edit_message( msg, "Parse depth exceeded. Try again with a lower value." ) except Exception as e: LOGGER.error(str(e)) - await editMessage( + await edit_message( msg, str(e) ) else: - await sendMessage( + await send_message( message, "Enter a valid title. Title not found!" ) except Exception as e: LOGGER.error(str(e)) - await sendMessage( + await send_message( message, f"Enter a valid value!. {e}" ) -async def rssEdit(message): +@new_task +async def rss_edit(message): user_id = message.from_user.id items = message.text.split("\n") updated = False @@ -549,7 +560,7 @@ async def rssEdit(message): args = item.split() title = args[0].strip() if len(args) < 2: - await sendMessage( + await send_message( message, f"{item}. Wrong Input format. Read help message before editing!", ) @@ -558,7 +569,7 @@ async def rssEdit(message): title, False ): - await sendMessage( + await send_message( message, "Enter a valid title. Title not found!" ) @@ -602,18 +613,19 @@ async def rssEdit(message): y = x.split(" or ") exf_lists.append(y) rss_dict[user_id][title]["exf"] = exf_lists - if DATABASE_URL and updated: - await DbManager().rss_update(user_id) + if config_dict["DATABASE_URL"] and updated: + await database.rss_update(user_id) -async def rssDelete(message): +@new_task +async def rss_delete(message): users = message.text.split() for user in users: user = int(user) async with rss_dict_lock: del rss_dict[user] - if DATABASE_URL: - await DbManager().rss_delete(user) + if config_dict["DATABASE_URL"]: + await database.rss_delete(user) async def event_handler(client, query): @@ -624,7 +636,8 @@ async def event_handler(client, query): ) -async def rssListener(client, query): +@new_task +async def rss_listener(client, query): user_id = query.from_user.id message = query.message data = query.data.split() @@ -641,24 +654,24 @@ async def rssListener(client, query): ) elif data[1] == "close": await query.answer() - await deleteMessage(message.reply_to_message) - await deleteMessage(message) + await delete_message(message.reply_to_message) + await delete_message(message) elif data[1] == "back": await query.answer() - await updateRssMenu(query) + await update_rss_menu(query) elif data[1] == "sub": await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "Back", f"rss back {user_id}" ) - buttons.ibutton( + buttons.data_button( "Close", f"rss close {user_id}" ) button = buttons.build_menu(2) - await editMessage( + await edit_message( message, RSS_HELP_MESSAGE, button @@ -669,13 +682,13 @@ async def rssListener(client, query): query ) except ListenerTimeout: - await updateRssMenu(query) + await update_rss_menu(query) except ListenerStopped: pass else: await gather( - rssSub(event), - updateRssMenu(query) + rss_sub(event), + update_rss_menu(query) ) elif data[1] == "list": if len(rss_dict.get(int(data[2]), {})) == 0: @@ -686,7 +699,7 @@ async def rssListener(client, query): else: await query.answer() start = int(data[3]) - await rssList( + await rss_list( query, start ) @@ -699,16 +712,16 @@ async def rssListener(client, query): else: await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "Back", f"rss back {user_id}" ) - buttons.ibutton( + buttons.data_button( "Close", f"rss close {user_id}" ) button = buttons.build_menu(2) - await editMessage( + await edit_message( message, "Send one title with value separated by space get last X items.\nTitle Value\nTimeout: 60 sec.", button, @@ -719,13 +732,13 @@ async def rssListener(client, query): query ) except ListenerTimeout: - await updateRssMenu(query) + await update_rss_menu(query) except ListenerStopped: pass else: await gather( - rssGet(event), - updateRssMenu(query) + rss_get(event), + update_rss_menu(query) ) elif data[1] in [ "unsubscribe", @@ -740,31 +753,31 @@ async def rssListener(client, query): else: await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "Back", f"rss back {user_id}" ) if data[1] == "pause": - buttons.ibutton( + buttons.data_button( "Pause AllMyFeeds", f"rss uallpause {user_id}" ) elif data[1] == "resume": - buttons.ibutton( + buttons.data_button( "Resume AllMyFeeds", f"rss uallresume {user_id}" ) elif data[1] == "unsubscribe": - buttons.ibutton( + buttons.data_button( "Unsub AllMyFeeds", f"rss uallunsub {user_id}" ) - buttons.ibutton( + buttons.data_button( "Close", f"rss close {user_id}" ) button = buttons.build_menu(2) - await editMessage( + await edit_message( message, f"Send one or more rss titles separated by space to {data[1]}.\nTimeout: 60 sec.", button, @@ -775,16 +788,16 @@ async def rssListener(client, query): query ) except ListenerTimeout: - await updateRssMenu(query) + await update_rss_menu(query) except ListenerStopped: pass else: await gather( - rssUpdate( + rss_update( event, data[1] ), - updateRssMenu(query) + update_rss_menu(query) ) elif data[1] == "edit": if len(rss_dict.get(int(data[2]), {})) == 0: @@ -795,11 +808,11 @@ async def rssListener(client, query): else: await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "Back", f"rss back {user_id}" ) - buttons.ibutton( + buttons.data_button( "Close", f"rss close {user_id}" ) @@ -812,7 +825,7 @@ async def rssListener(client, query): Note: Only what you provide will be edited, the rest will be the same like example 2: exf will stay same as it is. Timeout: 60 sec. Argument -c for command and arguments """ - await editMessage( + await edit_message( message, msg, button @@ -823,13 +836,13 @@ async def rssListener(client, query): query ) except ListenerTimeout: - await updateRssMenu(query) + await update_rss_menu(query) except ListenerStopped: pass else: await gather( - rssEdit(event), - updateRssMenu(query) + rss_edit(event), + update_rss_menu(query) ) elif data[1].startswith("uall"): if len(rss_dict.get(int(data[2]), {})) == 0: @@ -842,24 +855,24 @@ async def rssListener(client, query): if data[1].endswith("unsub"): async with rss_dict_lock: del rss_dict[int(data[2])] - if DATABASE_URL: - await DbManager().rss_delete(int(data[2])) - await updateRssMenu(query) + if config_dict["DATABASE_URL"]: + await database.rss_delete(int(data[2])) + await update_rss_menu(query) elif data[1].endswith("pause"): async with rss_dict_lock: for title in list(rss_dict[int(data[2])].keys()): rss_dict[int(data[2])][title]["paused"] = True - if DATABASE_URL: - await DbManager().rss_update(int(data[2])) + if config_dict["DATABASE_URL"]: + await database.rss_update(int(data[2])) elif data[1].endswith("resume"): async with rss_dict_lock: for title in list(rss_dict[int(data[2])].keys()): rss_dict[int(data[2])][title]["paused"] = False if scheduler.state == 2: scheduler.resume() - if DATABASE_URL: - await DbManager().rss_update(int(data[2])) - await updateRssMenu(query) + if config_dict["DATABASE_URL"]: + await database.rss_update(int(data[2])) + await update_rss_menu(query) elif data[1].startswith("all"): if len(rss_dict) == 0: await query.answer( @@ -871,9 +884,9 @@ async def rssListener(client, query): if data[1].endswith("unsub"): async with rss_dict_lock: rss_dict.clear() - if DATABASE_URL: - await DbManager().trunc_table("rss") - await updateRssMenu(query) + if config_dict["DATABASE_URL"]: + await database.trunc_table("rss") + await update_rss_menu(query) elif data[1].endswith("pause"): async with rss_dict_lock: for user in list(rss_dict.keys()): @@ -881,8 +894,8 @@ async def rssListener(client, query): rss_dict[int(data[2])][title]["paused"] = True if scheduler.running: scheduler.pause() - if DATABASE_URL: - await DbManager().rss_update_all() + if config_dict["DATABASE_URL"]: + await database.rss_update_all() elif data[1].endswith("resume"): async with rss_dict_lock: for user in list(rss_dict.keys()): @@ -891,10 +904,10 @@ async def rssListener(client, query): if scheduler.state == 2: scheduler.resume() elif not scheduler.running: - addJob() + add_job() scheduler.start() - if DATABASE_URL: - await DbManager().rss_update_all() + if config_dict["DATABASE_URL"]: + await database.rss_update_all() elif data[1] == "deluser": if len(rss_dict) == 0: await query.answer( @@ -904,16 +917,16 @@ async def rssListener(client, query): else: await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "Back", f"rss back {user_id}" ) - buttons.ibutton( + buttons.data_button( "Close", f"rss close {user_id}") button = buttons.build_menu(2) msg = "Send one or more user_id separated by space to delete their resources.\nTimeout: 60 sec." - await editMessage( + await edit_message( message, msg, button @@ -924,13 +937,13 @@ async def rssListener(client, query): query ) except ListenerTimeout: - await updateRssMenu(query) + await update_rss_menu(query) except ListenerStopped: pass else: await gather( - rssDelete(event), - updateRssMenu(query) + rss_delete(event), + update_rss_menu(query) ) elif data[1] == "listall": if not rss_dict: @@ -941,7 +954,7 @@ async def rssListener(client, query): else: await query.answer() start = int(data[3]) - await rssList( + await rss_list( query, start, all_users=True @@ -951,7 +964,7 @@ async def rssListener(client, query): await query.answer() scheduler.shutdown(wait=False) await sleep(0.5) - await updateRssMenu(query) + await update_rss_menu(query) else: await query.answer( text="Already Stopped!", @@ -960,9 +973,9 @@ async def rssListener(client, query): elif data[1] == "start": if not scheduler.running: await query.answer() - addJob() + add_job() scheduler.start() - await updateRssMenu(query) + await update_rss_menu(query) else: await query.answer( text="Already Running!", @@ -970,7 +983,7 @@ async def rssListener(client, query): ) -async def rssMonitor(): +async def rss_monitor(): if not config_dict["RSS_CHAT"]: scheduler.shutdown(wait=False) return @@ -995,7 +1008,7 @@ async def rssMonitor(): if tries > 3: raise continue - rss_d = feedparse(html) + rss_d = feed_parse(html) try: last_link = rss_d.entries[0]["links"][1]["href"] except IndexError: @@ -1052,7 +1065,7 @@ async def rssMonitor(): for x in flist ) ) or ( - data.get("sensitive", False) + not data.get("sensitive", False) and any( x in item_title for x in flist @@ -1075,7 +1088,7 @@ async def rssMonitor(): feed_msg += ( f"\nTag: {data['tag']} {user}" ) - await sendRss(feed_msg) + await send_rss(feed_msg) feed_count += 1 async with rss_dict_lock: if ( @@ -1092,7 +1105,7 @@ async def rssMonitor(): "last_title": last_title } ) - await DbManager().rss_update(user) + await database.rss_update(user) LOGGER.info(f"Feed Name: {title}") LOGGER.info(f"Last item: {last_link}") except RssShutdownException as ex: @@ -1105,9 +1118,9 @@ async def rssMonitor(): scheduler.pause() -def addJob(): +def add_job(): scheduler.add_job( - rssMonitor, + rss_monitor, trigger=IntervalTrigger(seconds=config_dict["RSS_DELAY"]), id="0", name="RSS", @@ -1118,11 +1131,12 @@ def addJob(): ) -addJob() +add_job() scheduler.start() + bot.add_handler( # type: ignore MessageHandler( - getRssMenu, + get_rss_menu, filters=command( BotCommands.RssCommand, case_sensitive=True @@ -1131,7 +1145,7 @@ def addJob(): ) bot.add_handler( # type: ignore CallbackQueryHandler( - rssListener, + rss_listener, filters=regex("^rss") ) ) diff --git a/bot/modules/shell.py b/bot/modules/shell.py index bc54118fe9ad..d83275773908 100644 --- a/bot/modules/shell.py +++ b/bot/modules/shell.py @@ -1,24 +1,32 @@ from io import BytesIO + from nekozee.filters import command from nekozee.handlers import ( MessageHandler, EditedMessageHandler ) -from bot import LOGGER, bot -from bot.helper.ext_utils.bot_utils import cmd_exec -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( - sendMessage, - sendFile +from bot import ( + LOGGER, + bot +) +from ..helper.ext_utils.bot_utils import ( + cmd_exec, + new_task + ) +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( + send_message, + send_file ) +@new_task async def shell(_, message): cmd = message.text.split(maxsplit=1) if len(cmd) == 1: - await sendMessage( + await send_message( message, "No command to execute was given." ) @@ -42,17 +50,17 @@ async def shell(_, message): if len(reply) > 3000: with BytesIO(str.encode(reply)) as out_file: out_file.name = "shell_output.txt" - await sendFile( + await send_file( message, out_file ) elif len(reply) != 0: - await sendMessage( + await send_message( message, reply ) else: - await sendMessage( + await send_message( message, "No Reply" ) diff --git a/bot/modules/status.py b/bot/modules/status.py index 9f4fbb4ba032..5d02c08e114d 100644 --- a/bot/modules/status.py +++ b/bot/modules/status.py @@ -1,79 +1,80 @@ -from nekozee.filters import ( - command, - regex -) -from nekozee.handlers import ( - MessageHandler, - CallbackQueryHandler -) -from time import time +from aiofiles.os import path as aiopath from datetime import datetime as dt -from bot.helper.z_utils import def_media from httpx import AsyncClient as xclient -from aiofiles.os import path as aiopath - from psutil import ( boot_time, cpu_count, cpu_freq, cpu_percent, disk_usage, + net_io_counters, swap_memory, - virtual_memory, - net_io_counters + virtual_memory +) +from time import time + +from nekozee.filters import ( + command, + regex +) +from nekozee.handlers import ( + MessageHandler, + CallbackQueryHandler ) from bot import ( BASE, - config_dict, LOGGER, - task_dict_lock, + bot, + bot_start_time, + config_dict, + intervals, status_dict, task_dict, - botStartTime, - DOWNLOAD_DIR, - Intervals, - bot, + task_dict_lock ) -from bot.helper.ext_utils.bot_utils import ( +from ..helper.ext_utils.bot_utils import ( cmd_exec, + new_task, sync_to_async ) -from bot.helper.ext_utils.status_utils import ( +from ..helper.ext_utils.status_utils import ( MirrorStatus, get_progress_bar_string, get_readable_file_size, get_readable_time, - getSpecificTasks, + get_specific_tasks, speed_string_to_bytes, ) -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( - isAdmin, +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( + is_admin, request_limiter, - sendMessage, - deleteMessage, + send_message, + delete_message, auto_delete_message, - sendStatusMessage, + send_status_message, update_status_message, ) -from bot.helper.telegram_helper.button_build import ButtonMaker +from ..helper.telegram_helper.button_build import ButtonMaker +from ..helper.z_utils import def_media +@new_task async def mirror_status(_, message): async with task_dict_lock: count = len(task_dict) if count == 0: - currentTime = get_readable_time(time() - botStartTime) # type: ignore - free = get_readable_file_size(disk_usage(DOWNLOAD_DIR).free) + currentTime = get_readable_time(time() - bot_start_time) # type: ignore + free = get_readable_file_size(disk_usage(config_dict["DOWNLOAD_DIR"]).free) msg = "Stop it!\nGet some help!\n\nNo Active Tasks!\n\n" msg += f"Get your tasks status by adding me or user_id after cmd: /{BotCommands.StatusCommand[0]} me\n\n" msg += ( f"\nCPU: {cpu_percent()}% | FREE: {free}" f"\nRAM: {virtual_memory().percent}% | UPTIME: {currentTime}" ) - reply_message = await sendMessage( + reply_message = await send_message( message, msg ) @@ -92,20 +93,21 @@ async def mirror_status(_, message): else: user_id = 0 sid = message.chat.id - if obj := Intervals["status"].get(sid): + if obj := intervals["status"].get(sid): obj.cancel() - del Intervals["status"][sid] - await sendStatusMessage( + del intervals["status"][sid] + await send_status_message( message, user_id ) - await deleteMessage(message) + await delete_message(message) +@new_task async def status_pages(_, query): user_id = query.from_user.id spam = ( - not await isAdmin( + not await is_admin( query.message, user_id ) @@ -114,13 +116,13 @@ async def status_pages(_, query): if spam: return if ( - not await isAdmin( + not await is_admin( query.message, user_id ) and user_id and not await sync_to_async( - getSpecificTasks, + get_specific_tasks, "All", user_id ) @@ -265,8 +267,13 @@ def bot_sys_stats(): async def stats(_, message, edit_mode=False): buttons = ButtonMaker() sysTime = get_readable_time(time() - boot_time()) # type: ignore - botTime = get_readable_time(time() - botStartTime) # type: ignore - total, used, free, disk = disk_usage("/") + botTime = get_readable_time(time() - bot_start_time) # type: ignore + ( + total, + used, + free, + disk + ) = disk_usage("/") total = get_readable_file_size(total) used = get_readable_file_size(used) free = get_readable_file_size(free) @@ -310,19 +317,19 @@ async def stats(_, message, edit_mode=False): f"DISK: {get_progress_bar_string(disk)} {disk}%\n" \ f"Total: {total} | Free: {free}" - buttons.ibutton( + buttons.data_button( "ꜱʏꜱᴛᴇᴍ\nꜱᴛᴀᴛꜱ", "show_sys_stats" ) - buttons.ibutton( + buttons.data_button( "ʀᴇᴘᴏ\nꜱᴛᴀᴛꜱ", "show_repo_stats" ) - buttons.ibutton( + buttons.data_button( "ʙᴏᴛ\nʟɪᴍɪᴛꜱ", "show_bot_limits" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "close_signal" ) @@ -335,6 +342,7 @@ async def stats(_, message, edit_mode=False): return bot_stats, sys_stats +@new_task async def send_bot_stats(_, query): buttons = ButtonMaker() ( @@ -345,19 +353,19 @@ async def send_bot_stats(_, query): query.message, edit_mode=True ) - buttons.ibutton( + buttons.data_button( "ꜱʏꜱᴛᴇᴍ\nꜱᴛᴀᴛꜱ", "show_sys_stats" ) - buttons.ibutton( + buttons.data_button( "ʀᴇᴘᴏ\nꜱᴛᴀᴛꜱ", "show_repo_stats" ) - buttons.ibutton( + buttons.data_button( "ʙᴏᴛ\nʟɪᴍɪᴛꜱ", "show_bot_limits" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "close_signal" ) @@ -369,6 +377,7 @@ async def send_bot_stats(_, query): ) +@new_task async def send_sys_stats(_, query): buttons = ButtonMaker() ( @@ -379,19 +388,19 @@ async def send_sys_stats(_, query): query.message, edit_mode=True ) - buttons.ibutton( + buttons.data_button( "ʙᴏᴛ\nꜱᴛᴀᴛꜱ", "show_bot_stats" ) - buttons.ibutton( + buttons.data_button( "ʀᴇᴘᴏ\nꜱᴛᴀᴛꜱ", "show_repo_stats" ) - buttons.ibutton( + buttons.data_button( "ʙᴏᴛ\nʟɪᴍɪᴛꜱ", "show_bot_limits" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "close_signal" ) @@ -403,6 +412,7 @@ async def send_sys_stats(_, query): ) +@new_task async def send_repo_stats(_, query): buttons = ButtonMaker() commit_date = "Official Repo not available" @@ -488,19 +498,19 @@ async def send_repo_stats(_, query): f"- Changelog : {change_log} \n\n" \ f"{update_info}" - buttons.ibutton( + buttons.data_button( "ʙᴏᴛ\nꜱᴛᴀᴛꜱ", "show_bot_stats" ) - buttons.ibutton( + buttons.data_button( "ꜱʏꜱᴛᴇᴍ\nꜱᴛᴀᴛꜱ", "show_sys_stats" ) - buttons.ibutton( + buttons.data_button( "ʙᴏᴛ\nʟɪᴍɪᴛꜱ", "show_bot_limits" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "close_signal" ) @@ -512,6 +522,7 @@ async def send_repo_stats(_, query): ) +@new_task async def send_bot_limits(_, query): buttons = ButtonMaker() DIR = "Unlimited" if config_dict["DIRECT_LIMIT"] == "" else config_dict["DIRECT_LIMIT"] @@ -543,19 +554,19 @@ async def send_bot_limits(_, query): f"User Tasks: {UMT}\n" \ f"Bot Tasks : {BMT}" - buttons.ibutton( + buttons.data_button( "ʙᴏᴛ\nꜱᴛᴀᴛꜱ", "show_bot_stats" ) - buttons.ibutton( + buttons.data_button( "ꜱʏꜱᴛᴇᴍ\nꜱᴛᴀᴛꜱ", "show_sys_stats" ) - buttons.ibutton( + buttons.data_button( "ʀᴇᴘᴏ\nꜱᴛᴀᴛꜱ", "show_repo_stats" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", "close_signal" ) @@ -570,10 +581,10 @@ async def send_bot_limits(_, query): async def send_close_signal(_, query): await query.answer() try: - await deleteMessage(query.message.reply_to_message) + await delete_message(query.message.reply_to_message) except Exception as e: LOGGER.error(e) - await deleteMessage(query.message) + await delete_message(query.message) bot.add_handler( # type: ignore diff --git a/bot/modules/torrent_search.py b/bot/modules/torrent_search.py index c43ae221e9f8..76b216ec012f 100644 --- a/bot/modules/torrent_search.py +++ b/bot/modules/torrent_search.py @@ -1,5 +1,7 @@ from html import escape from httpx import AsyncClient +from urllib.parse import quote + from nekozee.filters import ( command, regex @@ -8,26 +10,28 @@ MessageHandler, CallbackQueryHandler ) -from urllib.parse import quote from bot import ( - bot, LOGGER, + bot, config_dict, qbittorrent_client ) -from bot.helper.ext_utils.bot_utils import sync_to_async -from bot.helper.ext_utils.status_utils import get_readable_file_size -from bot.helper.ext_utils.telegraph_helper import telegraph -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.ext_utils.bot_utils import ( + new_task, + sync_to_async +) +from ..helper.ext_utils.status_utils import get_readable_file_size +from ..helper.ext_utils.telegraph_helper import telegraph +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.button_build import ButtonMaker +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( anno_checker, auto_delete_message, delete_links, - editMessage, - sendMessage + edit_message, + send_message ) PLUGINS = [] @@ -79,7 +83,7 @@ async def initiate_search_tools(): SITES = None -async def _search(key, site, message, method): +async def search(key, site, message, method): if method.startswith("api"): SEARCH_API_LINK = config_dict["SEARCH_API_LINK"] SEARCH_LIMIT = config_dict["SEARCH_LIMIT"] @@ -111,7 +115,7 @@ async def _search(key, site, message, method): "error" in search_results or search_results["total"] == 0 ): - await editMessage( + await edit_message( message, f"No result found for {key}\nTorrent Site:- {SITES.get(site)}", # type: ignore ) @@ -135,7 +139,7 @@ async def _search(key, site, message, method): msg += f" result(s) for {key}\nTorrent Site:- {SITES.get(site)}" # type: ignore search_results = search_results["data"] except Exception as e: - await editMessage( + await edit_message( message, str(e) ) @@ -169,7 +173,7 @@ async def _search(key, site, message, method): search_results = dict_search_results.results total_results = dict_search_results.total if total_results == 0: - await editMessage( + await edit_message( message, f"No result found for {key}\nTorrent Site:- {site.capitalize()}", ) @@ -188,19 +192,19 @@ async def _search(key, site, message, method): qbittorrent_client.search_delete, search_id=search_id ) - link = await _getResult( + link = await get_result( search_results, key, message, method ) buttons = ButtonMaker() - buttons.ubutton( + buttons.url_button( "🔎 ᴠɪᴇᴡ\nʀᴇꜱᴜʟᴛꜱ", link ) button = buttons.build_menu(1) - await editMessage( + await edit_message( message, msg, button @@ -211,7 +215,7 @@ async def _search(key, site, message, method): ) -async def _getResult(search_results, key, message, method): +async def get_result(search_results, key, message, method): telegraph_content = [] if method == "apirecent": msg = "

API Recent Results

" @@ -274,7 +278,7 @@ async def _getResult(search_results, key, message, method): if msg != "": telegraph_content.append(msg) - emsg = await editMessage( + emsg = await edit_message( message, f"Creating {len(telegraph_content)} Telegraph pages." ) path = [ @@ -287,7 +291,7 @@ async def _getResult(search_results, key, message, method): for content in telegraph_content ] if len(path) > 1: - emsg = await editMessage( + emsg = await edit_message( message, f"Editing {len(telegraph_content)} Telegraph pages." ) @@ -303,46 +307,47 @@ async def _getResult(search_results, key, message, method): return f"https://telegra.ph/{path[0]}" -def _api_buttons(user_id, method): +def api_buttons(user_id, method): buttons = ButtonMaker() for ( data, name ) in SITES.items(): # type: ignore - buttons.ibutton( + buttons.data_button( name, f"torser {user_id} {data} {method}" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", f"torser {user_id} cancel" ) return buttons.build_menu(2) -async def _plugin_buttons(user_id): +async def plugin_buttons(user_id): buttons = ButtonMaker() if not PLUGINS: pl = await sync_to_async(qbittorrent_client.search_plugins) for name in pl: PLUGINS.append(name["name"]) for siteName in PLUGINS: - buttons.ibutton( + buttons.data_button( siteName.capitalize(), f"torser {user_id} {siteName} plugin" ) - buttons.ibutton( + buttons.data_button( "ᴀʟʟ\nꜱɪᴛᴇꜱ", f"torser {user_id} all plugin" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", f"torser {user_id} cancel" ) return buttons.build_menu(2) -async def torrentSearch(_, message): +@new_task +async def torrent_search(_, message): from_user = message.from_user if not from_user: from_user = await anno_checker(message) @@ -351,30 +356,30 @@ async def torrentSearch(_, message): key = message.text.split() SEARCH_PLUGINS = config_dict["SEARCH_PLUGINS"] if SITES is None and not SEARCH_PLUGINS: - smsg = await sendMessage( + smsg = await send_message( message, "No API link or search PLUGINS added for this function" ) elif len(key) == 1 and SITES is None: - smsg = await sendMessage( + smsg = await send_message( message, "Send a search key along with command" ) elif len(key) == 1: - buttons.ibutton( + buttons.data_button( "ᴛʀᴇɴᴅɪɴɢ", f"torser {user_id} apitrend" ) - buttons.ibutton( + buttons.data_button( "ʀᴇᴄᴇɴᴛ", f"torser {user_id} apirecent" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", f"torser {user_id} cancel" ) button = buttons.build_menu(2) - smsg = await sendMessage( + smsg = await send_message( message, "Send a search key along with command", button @@ -383,37 +388,37 @@ async def torrentSearch(_, message): SITES is not None and SEARCH_PLUGINS ): - buttons.ibutton( + buttons.data_button( "ᴀᴘɪ", f"torser {user_id} apisearch" ) - buttons.ibutton( + buttons.data_button( "ᴘʟᴜɢɪɴꜱ", f"torser {user_id} plugin" ) - buttons.ibutton( + buttons.data_button( "ᴄᴀɴᴄᴇʟ", f"torser {user_id} cancel" ) button = buttons.build_menu(2) - smsg = await sendMessage( + smsg = await send_message( message, "Choose tool to search:", button ) elif SITES is not None: - button = _api_buttons( + button = api_buttons( user_id, "apisearch" ) - smsg = await sendMessage( + smsg = await send_message( message, "Choose site to search | API:", button ) else: - button = await _plugin_buttons(user_id) - smsg = await sendMessage( + button = await plugin_buttons(user_id) + smsg = await send_message( message, "Choose site to search | Plugins:", button @@ -426,7 +431,8 @@ async def torrentSearch(_, message): ) -async def torrentSearchUpdate(_, query): +@new_task +async def torrent_search_update(_, query): user_id = query.from_user.id message = query.message key = message.reply_to_message.text.split(maxsplit=1) @@ -444,21 +450,21 @@ async def torrentSearchUpdate(_, query): ) elif data[2].startswith("api"): await query.answer() - button = _api_buttons( + button = api_buttons( user_id, data[2] ) emsg = "Choose site:" - await editMessage( + await edit_message( message, emsg, button ) elif data[2] == "plugin": await query.answer() - button = await _plugin_buttons(user_id) + button = await plugin_buttons(user_id) emsg = "Choose site:" - await editMessage( + await edit_message( message, emsg, button @@ -474,23 +480,23 @@ async def torrentSearchUpdate(_, query): elif method == "apitrend": endpoint = "Trending" emsg = f"Listing {endpoint} Items...\nTorrent Site:- {SITES.get(site)}" # type: ignore - await editMessage( + await edit_message( message, emsg, ) else: emsg = f"Searching for {key}\nTorrent Site:- {SITES.get(site)}" # type: ignore - await editMessage( + await edit_message( message, emsg, ) else: emsg = f"Searching for {key}\nTorrent Site:- {site.capitalize()}" - await editMessage( + await edit_message( message, emsg, ) - await _search( + await search( key, site, message, @@ -499,7 +505,7 @@ async def torrentSearchUpdate(_, query): else: await query.answer() emsg = "Search has been canceled!" - await editMessage( + await edit_message( message, emsg ) @@ -512,7 +518,7 @@ async def torrentSearchUpdate(_, query): bot.add_handler( # type: ignore MessageHandler( - torrentSearch, + torrent_search, filters=command( BotCommands.SearchCommand, case_sensitive=True @@ -521,7 +527,7 @@ async def torrentSearchUpdate(_, query): ) bot.add_handler( # type: ignore CallbackQueryHandler( - torrentSearchUpdate, + torrent_search_update, filters=regex("^torser") ) ) diff --git a/bot/modules/users_settings.py b/bot/modules/users_settings.py index 1a812ff31bd6..483e11ced33c 100644 --- a/bot/modules/users_settings.py +++ b/bot/modules/users_settings.py @@ -1,8 +1,8 @@ from asyncio import gather from aiofiles.os import ( - remove, + makedirs, path as aiopath, - makedirs + remove ) from html import escape from io import BytesIO @@ -25,31 +25,33 @@ ) from bot import ( - bot, - user_data, - config_dict, IS_PREMIUM_USER, JAVA, - DATABASE_URL, MAX_SPLIT_SIZE, - GLOBAL_EXTENSION_FILTER, + bot, + config_dict, + global_extension_filter, + user_data ) -from bot.helper.ext_utils.bot_utils import update_user_ldata -from bot.helper.ext_utils.db_handler import DbManager -from bot.helper.ext_utils.media_utils import createThumb -from bot.helper.ext_utils.status_utils import get_readable_file_size -from bot.helper.telegram_helper.bot_commands import BotCommands -from bot.helper.telegram_helper.button_build import ButtonMaker -from bot.helper.telegram_helper.filters import CustomFilters -from bot.helper.telegram_helper.message_utils import ( +from ..helper.ext_utils.bot_utils import ( + new_task, + update_user_ldata +) +from ..helper.ext_utils.db_handler import database +from ..helper.ext_utils.media_utils import create_thumb +from ..helper.ext_utils.status_utils import get_readable_file_size +from ..helper.telegram_helper.bot_commands import BotCommands +from ..helper.telegram_helper.button_build import ButtonMaker +from ..helper.telegram_helper.filters import CustomFilters +from ..helper.telegram_helper.message_utils import ( anno_checker, auto_delete_message, - sendMessage, - editMessage, - sendFile, - deleteMessage, + delete_message, + edit_message, + send_file, + send_message, ) -from bot.helper.z_utils import def_media +from ..helper.z_utils import def_media async def get_user_settings(from_user): @@ -74,9 +76,9 @@ async def get_user_settings(from_user): ltype = "MEDIA" thumbmsg = ( - "Exists" + "Added" if await aiopath.exists(thumbpath) - else "Not Exists" + else "Not Added" ) if user_dict.get( @@ -206,19 +208,19 @@ async def get_user_settings(from_user): else: attachmenturl = "Not Added" - buttons.ibutton( + buttons.data_button( "ʟᴇᴇᴄʜ\nꜱᴇᴛᴛɪɴɢꜱ", f"userset {user_id} leech" ) - buttons.ibutton( + buttons.data_button( "ʀᴄʟᴏɴᴇ\nᴛᴏᴏʟꜱ", f"userset {user_id} rclone" ) rccmsg = ( - "Exists" + "Added" if await aiopath.exists(rclone_conf) - else "Not Exists" + else "Not Added" ) if user_dict.get( "rclone_path", @@ -230,14 +232,14 @@ async def get_user_settings(from_user): else: rccpath = "Not Added" - buttons.ibutton( + buttons.data_button( "ɢᴅʀɪᴠᴇ\nᴛᴏᴏʟꜱ", f"userset {user_id} gdrive" ) tokenmsg = ( - "Exists" + "Added" if await aiopath.exists(token_pickle) - else "Not Exists" + else "Not Added" ) gdrive_id = ( "Added" @@ -275,7 +277,7 @@ async def get_user_settings(from_user): ) else "Not Added" ) - buttons.ibutton( + buttons.data_button( "ᴜᴘʟᴏᴀᴅ\nᴘᴀᴛʜꜱ", f"userset {user_id} upload_paths" ) @@ -287,22 +289,22 @@ async def get_user_settings(from_user): ) or config_dict["DEFAULT_UPLOAD"] ) - du = ( - "Gdrive API" + dum = ( + "Gdrive" if default_upload == "gd" else "Rclone" ) dub = ( - "Gdrive API" + "Gdrive" if default_upload != "gd" else "Rclone" ) - buttons.ibutton( - f"ᴜᴘʟᴏᴀᴅ\nᴜꜱɪɴɢ {dub}", + buttons.data_button( + f"ᴜᴘʟᴏᴀᴅ\nᴛᴏ {dub}", f"userset {user_id} {default_upload}" ) - buttons.ibutton( + buttons.data_button( "ᴇxᴛᴇɴꜱɪᴏɴ\nꜰɪʟᴛᴇʀ", f"userset {user_id} ex_ex" ) @@ -323,12 +325,12 @@ async def get_user_settings(from_user): ) else "Not Added" ) - buttons.ibutton( + buttons.data_button( "ɴᴀᴍᴇ\nꜱᴜʙꜱᴛɪᴛᴜᴛᴇ", f"userset {user_id} name_substitute" ) - buttons.ibutton( + buttons.data_button( "ʏᴛ-ᴅʟᴘ\nᴏᴘᴛɪᴏɴꜱ", f"userset {user_id} yto" ) @@ -345,13 +347,26 @@ async def get_user_settings(from_user): else: ytopt = "Not Added" + if user_dict.get( + "thumb_layout", + False + ): + thumb_layout = user_dict["thumb_layout"] + elif ( + "thumb_layout" not in user_dict + and config_dict["THUMBNAIL_LAYOUT"] + ): + thumb_layout = config_dict["THUMBNAIL_LAYOUT"] + else: + thumb_layout = "1 x 1" + if user_dict: - buttons.ibutton( + buttons.data_button( "ʀᴇꜱᴇᴛ ᴀʟʟ\nᴄʜᴀɴɢᴇꜱ", f"userset {user_id} reset" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" @@ -367,11 +382,12 @@ async def get_user_settings(from_user): Leech Suffix : {lsuffix} Leech Cap Font : {lcapfont} Leech Split Size : {split_size} -Leech Destination: {leech_dest} +Leech Dest : {leech_dest} Metadata Text : {metatxt} Attachment Url : {attachmenturl} Thumbnail : {thumbmsg} +Thumb Layout : {thumb_layout} Equal Splits : {equal_splits} Media Group : {media_group} Upload Client : {leech_method} session @@ -385,7 +401,7 @@ async def get_user_settings(from_user): Index Link : {index} Stop Duplicate : {sd_msg} -Default Upload : {du} +Default Upload : {dum} Upload Paths : {upload_paths} Name Substitute : {ns_msg} Extension Filter : {ex_ex} @@ -415,6 +431,7 @@ async def update_user_settings(query): ) +@new_task async def user_settings(client, message): await client.stop_listening( chat_id=message.chat.id, @@ -441,9 +458,10 @@ async def user_settings(client, message): ) +@new_task async def set_thumb(message): user_id = message.from_user.id - des_dir = await createThumb( + des_dir = await create_thumb( message, user_id ) @@ -452,15 +470,16 @@ async def set_thumb(message): "thumb", des_dir ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_user_doc( + await delete_message(message) + if config_dict["DATABASE_URL"]: + await database.update_user_doc( user_id, "thumb", des_dir ) +@new_task async def add_rclone(message): user_id = message.from_user.id rpath = f"{getcwd()}/rclone/" @@ -472,15 +491,16 @@ async def add_rclone(message): "rclone_config", f"rclone/{user_id}.conf" ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_user_doc( + await delete_message(message) + if config_dict["DATABASE_URL"]: + await database.update_user_doc( user_id, "rclone_config", des_dir ) +@new_task async def add_token_pickle(message): user_id = message.from_user.id tpath = f"{getcwd()}/tokens/" @@ -492,15 +512,16 @@ async def add_token_pickle(message): "token_pickle", f"tokens/{user_id}.pickle" ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_user_doc( + await delete_message(message) + if config_dict["DATABASE_URL"]: + await database.update_user_doc( user_id, "token_pickle", des_dir ) +@new_task async def delete_path(message): user_id = message.from_user.id user_dict = user_data.get(user_id, {}) @@ -514,21 +535,22 @@ async def delete_path(message): "upload_paths", new_value ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_user_doc( + await delete_message(message) + if config_dict["DATABASE_URL"]: + await database.update_user_doc( user_id, "upload_paths", new_value ) +@new_task async def set_option(message, option): user_id = message.from_user.id value = message.text if option == "split_size": if re_search(r"[a-zA-Z]", value): - smsg = await sendMessage( + smsg = await send_message( message, "Invalid format! Send only numbers.\nEx: 4, 2, 0.5, 2.5." ) @@ -558,7 +580,7 @@ async def set_option(message, option): for line in lines: data = line.split(maxsplit=1) if len(data) != 2: - smsg = await sendMessage( + smsg = await send_message( message, "Wrong format! Add " ) @@ -578,9 +600,9 @@ async def set_option(message, option): option, value ) - await deleteMessage(message) - if DATABASE_URL: - await DbManager().update_user_data(user_id) + await delete_message(message) + if config_dict["DATABASE_URL"]: + await database.update_user_data(user_id) async def event_handler(client, query, photo=False, document=False): @@ -598,6 +620,7 @@ async def event_handler(client, query, photo=False, document=False): ) +@new_task async def edit_user_settings(client, query): from_user = query.from_user user_id = from_user.id @@ -635,8 +658,8 @@ async def edit_user_settings(client, query): ) await query.answer() await update_user_settings(query) - if DATABASE_URL: - await DbManager().update_user_data(user_id) + if config_dict["DATABASE_URL"]: + await database.update_user_data(user_id) elif data[2] in [ "thumb", "rclone_config", @@ -657,8 +680,8 @@ async def edit_user_settings(client, query): "" ) await update_user_settings(query) - if DATABASE_URL: - await DbManager().update_user_doc( + if config_dict["DATABASE_URL"]: + await database.update_user_doc( user_id, data[2] ) @@ -677,6 +700,7 @@ async def edit_user_settings(client, query): "lcapfont", "index_url", "name_sub", + "thumb_layout" ]: await query.answer() update_user_ldata( @@ -685,18 +709,18 @@ async def edit_user_settings(client, query): "" ) await update_user_settings(query) - if DATABASE_URL: - await DbManager().update_user_data(user_id) + if config_dict["DATABASE_URL"]: + await database.update_user_data(user_id) elif data[2] == "excluded_extensions": await query.answer() update_user_ldata( user_id, data[2], - f"{GLOBAL_EXTENSION_FILTER}" + f"{global_extension_filter}" ) await update_user_settings(query) - if DATABASE_URL: - await DbManager().update_user_data(user_id) + if config_dict["DATABASE_URL"]: + await database.update_user_data(user_id) elif data[2] in [ "split_size", "leech_dest", @@ -707,22 +731,22 @@ async def edit_user_settings(client, query): if data[2] in user_data.get(user_id, {}): del user_data[user_id][data[2]] await update_user_settings(query) - if DATABASE_URL: - await DbManager().update_user_data(user_id) + if config_dict["DATABASE_URL"]: + await database.update_user_data(user_id) elif data[2] == "leech": await query.answer() thumbpath = f"Thumbnails/{user_id}.jpg" buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ᴛʜᴜᴍʙ", f"userset {user_id} sthumb" ) thumbmsg = ( - "Exists" + "Added" if await aiopath.exists(thumbpath) - else "Not Exists" + else "Not Added" ) - buttons.ibutton( + buttons.data_button( "ꜱᴘʟɪᴛ\nꜱɪᴢᴇ", f"userset {user_id} lss" ) @@ -734,7 +758,7 @@ async def edit_user_settings(client, query): else: split_size = config_dict["LEECH_SPLIT_SIZE"] split_size = get_readable_file_size(split_size) - buttons.ibutton( + buttons.data_button( "ʟᴇᴇᴄʜ\nᴅᴇꜱᴛ", f"userset {user_id} ldest" ) @@ -750,7 +774,7 @@ async def edit_user_settings(client, query): leech_dest = LD else: leech_dest = "None" - buttons.ibutton( + buttons.data_button( "ᴘʀᴇꜰɪx", f"userset {user_id} leech_prefix" ) @@ -759,13 +783,11 @@ async def edit_user_settings(client, query): False ): lprefix = user_dict["lprefix"] - elif "lprefix" not in user_dict and ( - LP := config_dict["LEECH_FILENAME_PREFIX"] - ): - lprefix = LP + elif "lprefix" not in user_dict and config_dict["LEECH_FILENAME_PREFIX"]: + lprefix = config_dict["LEECH_FILENAME_PREFIX"] else: lprefix = "None" - buttons.ibutton( + buttons.data_button( "ꜱᴜꜰꜰɪx", f"userset {user_id} leech_suffix" ) @@ -780,7 +802,7 @@ async def edit_user_settings(client, query): lsuffix = LS else: lsuffix = "None" - buttons.ibutton( + buttons.data_button( "ᴄᴀᴘ\nꜰᴏɴᴛ", f"userset {user_id} leech_cap_font" ) @@ -804,13 +826,13 @@ async def edit_user_settings(client, query): and config_dict["AS_DOCUMENT"] ): ltype = "DOCUMENT" - buttons.ibutton( + buttons.data_button( "ᴜᴘʟᴏᴀᴅ\nᴀꜱ ᴍᴇᴅɪᴀ", f"userset {user_id} as_doc false" ) else: ltype = "MEDIA" - buttons.ibutton( + buttons.data_button( "ᴜᴘʟᴏᴀᴅ\nᴀꜱ ᴅᴏᴄᴜᴍᴇɴᴛ", f"userset {user_id} as_doc true" ) @@ -822,13 +844,13 @@ async def edit_user_settings(client, query): or "equal_splits" not in user_dict and config_dict["EQUAL_SPLITS"] ): - buttons.ibutton( + buttons.data_button( "ᴅɪꜱᴀʙʟᴇ\nᴇQᴜᴀʟ ꜱᴘʟɪᴛꜱ", f"userset {user_id} equal_splits false" ) equal_splits = "Enabled" else: - buttons.ibutton( + buttons.data_button( "ᴇɴᴀʙʟᴇ\nᴇQᴜᴀʟ ꜱᴘʟɪᴛꜱ", f"userset {user_id} equal_splits true" ) @@ -841,13 +863,13 @@ async def edit_user_settings(client, query): or "media_group" not in user_dict and config_dict["MEDIA_GROUP"] ): - buttons.ibutton( + buttons.data_button( "ᴅɪꜱᴀʙʟᴇ\nᴍᴇᴅɪᴀ ɢʀᴏᴜᴘ", f"userset {user_id} media_group false" ) media_group = "Enabled" else: - buttons.ibutton( + buttons.data_button( "ᴇɴᴀʙʟᴇ\nᴍᴇᴅɪᴀ ɢʀᴏᴜᴘ", f"userset {user_id} media_group true" ) @@ -861,14 +883,14 @@ async def edit_user_settings(client, query): or "user_transmission" not in user_dict and config_dict["USER_TRANSMISSION"] ): - buttons.ibutton( + buttons.data_button( "ᴜᴘʟᴏᴀᴅ\nᴡɪᴛʜ ʙᴏᴛ", f"userset {user_id} user_transmission false" ) leech_method = "user" elif IS_PREMIUM_USER: leech_method = "bot" - buttons.ibutton( + buttons.data_button( "ᴜᴘʟᴏᴀᴅ\nᴡɪᴛʜ ᴜꜱᴇʀ", f"userset {user_id} user_transmission true" ) @@ -885,19 +907,35 @@ async def edit_user_settings(client, query): and config_dict["MIXED_LEECH"] ): mixed_leech = "Enabled" - buttons.ibutton( + buttons.data_button( "ᴅɪꜱᴀʙʟᴇ\nʜʏʙʀɪᴅ ᴜᴘʟᴏᴀᴅ", f"userset {user_id} mixed_leech false" ) elif IS_PREMIUM_USER: mixed_leech = "Disabled" - buttons.ibutton( + buttons.data_button( "ᴇɴᴀʙʟᴇ\nʜʏʙʀɪᴅ ᴜᴘʟᴏᴀᴅ", f"userset {user_id} mixed_leech true" ) else: mixed_leech = "Disabled" - buttons.ibutton( + buttons.data_button( + "ᴛʜᴜᴍʙ\nʟᴀʏᴏᴜᴛ", + f"userset {user_id} tlayout" + ) + if user_dict.get( + "thumb_layout", + False + ): + thumb_layout = user_dict["thumb_layout"] + elif ( + "thumb_layout" not in user_dict + and config_dict["THUMBNAIL_LAYOUT"] + ): + thumb_layout = config_dict["THUMBNAIL_LAYOUT"] + else: + thumb_layout = "1 x 1" + buttons.data_button( "ᴍᴇᴛᴀᴅᴀᴛᴀ\nᴛᴇxᴛ", f"userset {user_id} metadata_text" ) @@ -908,7 +946,7 @@ async def edit_user_settings(client, query): metatxt = user_dict["metatxt"] else: metatxt = "None" - buttons.ibutton( + buttons.data_button( "ᴀᴛᴛᴀᴄʜᴍᴇɴᴛ\nᴜʀʟ", f"userset {user_id} attachment_url" ) @@ -919,12 +957,12 @@ async def edit_user_settings(client, query): attachmenturl = user_dict["attachmenturl"] else: attachmenturl = "None" - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} back", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" @@ -942,41 +980,42 @@ async def edit_user_settings(client, query): Attachment Url : {escape(attachmenturl)} Thumbnail : {thumbmsg} +Thumb Layout : {thumb_layout} Equal Splits : {equal_splits} Media Group : {media_group} Upload Client : {leech_method} session Hybrid Upload : {mixed_leech} """ - await editMessage( + await edit_message( message, text, - buttons.build_menu(3) + buttons.build_menu(2) ) elif data[2] == "rclone": await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ʀᴄʟᴏɴᴇ\nᴄᴏɴꜰɪɢ", f"userset {user_id} rcc" ) - buttons.ibutton( + buttons.data_button( "ᴅᴇꜰᴀᴜʟᴛ\nʀᴄʟᴏɴᴇ ᴘᴀᴛʜ", f"userset {user_id} rcp" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} back", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) rccmsg = ( - "Exists" + "Added" if await aiopath.exists(rclone_conf) - else "Not Exists" + else "Not Added" ) if user_dict.get( "rclone_path", @@ -993,7 +1032,7 @@ async def edit_user_settings(client, query): Rclone Config : {rccmsg} Rclone Path : {rccpath} """ - await editMessage( + await edit_message( message, text, buttons.build_menu(2) @@ -1001,15 +1040,15 @@ async def edit_user_settings(client, query): elif data[2] == "gdrive": await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ᴜᴘʟᴏᴀᴅ\nᴛᴏᴋᴇɴ ᴘɪᴄᴋʟᴇ", f"userset {user_id} token" ) - buttons.ibutton( + buttons.data_button( "ᴅᴇꜰᴀᴜʟᴛ\nɢᴅʀɪᴠᴇ ɪᴅ", f"userset {user_id} gdid" ) - buttons.ibutton( + buttons.data_button( "ɪɴᴅᴇx ᴜʀʟ", f"userset {user_id} index" ) @@ -1021,31 +1060,31 @@ async def edit_user_settings(client, query): or "stop_duplicate" not in user_dict and config_dict["STOP_DUPLICATE"] ): - buttons.ibutton( + buttons.data_button( "ᴅɪꜱᴀʙʟᴇ\nꜱᴛᴏᴘ ᴅᴜᴘʟɪᴄᴀᴛᴇ", f"userset {user_id} stop_duplicate false" ) sd_msg = "Enabled" else: - buttons.ibutton( + buttons.data_button( "ᴇɴᴀʙʟᴇ\nꜱᴛᴏᴘ ᴅᴜᴘʟɪᴄᴀᴛᴇ", f"userset {user_id} stop_duplicate true" ) sd_msg = "Disabled" - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} back", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) tokenmsg = ( - "Exists" + "Added" if await aiopath.exists(token_pickle) - else "Not Exists" + else "Not Added" ) if user_dict.get( "gdrive_id", @@ -1074,7 +1113,7 @@ async def edit_user_settings(client, query): Stop Duplicate : {sd_msg} """ - await editMessage( + await edit_message( message, text, buttons.build_menu(2) @@ -1083,21 +1122,21 @@ async def edit_user_settings(client, query): await query.answer() buttons = ButtonMaker() if await aiopath.exists(thumb_path): - buttons.ibutton( + buttons.data_button( "ᴅᴇʟᴇᴛᴇ\nᴛʜᴜᴍʙɴᴀɪʟ", f"userset {user_id} thumb" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} leech", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) - await editMessage( + await edit_message( message, "Send a photo to save it as custom thumbnail. Timeout: 60 sec", buttons.build_menu(2), @@ -1124,17 +1163,17 @@ async def edit_user_settings(client, query): "yt_opt", False ) or config_dict["YT_DLP_OPTIONS"]: - buttons.ibutton( + buttons.data_button( "ʀᴇᴍᴏᴠᴇ\nʏᴛ-ᴅʟᴘ ᴏᴘᴛɪᴏɴꜱ", f"userset {user_id} yt_opt", "header" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} back", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" @@ -1149,7 +1188,7 @@ async def edit_user_settings(client, query): Check all yt-dlp api options from this FILE or use this script to convert cli arguments to api options. """ - await editMessage( + await edit_message( message, rmsg, buttons.build_menu(2) @@ -1178,23 +1217,23 @@ async def edit_user_settings(client, query): "split_size", False ): - buttons.ibutton( + buttons.data_button( "ʀᴇꜱᴇᴛ\nꜱᴘʟɪᴛ ꜱɪᴢᴇ", f"userset {user_id} split_size" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} leech", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) sp_msg = "Send Leech split size.\nDon't add unit(MB, GB), default unit is GB\n" sp_msg += "\nExamples:\nSend 4 for 4GB\nor 0.5 for 512MB\n\nTimeout: 60 sec" - await editMessage( + await edit_message( message, sp_msg, buttons.build_menu(2), @@ -1220,21 +1259,21 @@ async def edit_user_settings(client, query): await query.answer() buttons = ButtonMaker() if await aiopath.exists(rclone_conf): - buttons.ibutton( + buttons.data_button( "ᴅᴇʟᴇᴛᴇ\nʀᴄʟᴏɴᴇ.ᴄᴏɴꜰ", f"userset {user_id} rclone_config" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} rclone", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) - await editMessage( + await edit_message( message, "Send rclone.conf. Timeout: 60 sec", buttons.build_menu(2) @@ -1261,22 +1300,22 @@ async def edit_user_settings(client, query): "rclone_path", False ): - buttons.ibutton( + buttons.data_button( "ʀᴇꜱᴇᴛ\nʀᴄʟᴏɴᴇ ᴘᴀᴛʜ", f"userset {user_id} rclone_path" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} rclone", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) rmsg = "Send Rclone Path. Timeout: 60 sec" - await editMessage( + await edit_message( message, rmsg, buttons.build_menu(2) @@ -1302,21 +1341,21 @@ async def edit_user_settings(client, query): await query.answer() buttons = ButtonMaker() if await aiopath.exists(token_pickle): - buttons.ibutton( + buttons.data_button( "ᴅᴇʟᴇᴛᴇ\nᴛᴏᴋᴇɴ.ᴘɪᴄᴋʟᴇ", f"userset {user_id} token_pickle" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} gdrive", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) - await editMessage( + await edit_message( message, "Send token.pickle.\n\nTimeout: 60 sec", buttons.build_menu(2) @@ -1343,22 +1382,22 @@ async def edit_user_settings(client, query): "gdrive_id", False ): - buttons.ibutton( + buttons.data_button( "ʀᴇꜱᴇᴛ\nɢᴅʀɪᴠᴇ ɪᴅ", f"userset {user_id} gdrive_id" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} gdrive", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) rmsg = "Send Gdrive ID.\n\nTimeout: 60 sec" - await editMessage( + await edit_message( message, rmsg, buttons.build_menu(2) @@ -1387,22 +1426,22 @@ async def edit_user_settings(client, query): "index_url", False ): - buttons.ibutton( + buttons.data_button( "ʀᴇᴍᴏᴠᴇ\nɪɴᴅᴇx ᴜʀʟ", f"userset {user_id} index_url" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} gdrive", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) rmsg = "Send Index URL.\n\nTimeout: 60 sec" - await editMessage( + await edit_message( message, rmsg, buttons.build_menu(2) @@ -1435,21 +1474,21 @@ async def edit_user_settings(client, query): or "lprefix" not in user_dict and config_dict["LEECH_FILENAME_PREFIX"] ): - buttons.ibutton( + buttons.data_button( "ʀᴇᴍᴏᴠᴇ\nᴘʀᴇꜰɪx", f"userset {user_id} lprefix" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} leech", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) - await editMessage( + await edit_message( message, "Send Leech Filename Prefix.\nYou can add HTML tags.\n\nTimeout: 60 sec", buttons.build_menu(2), @@ -1471,32 +1510,35 @@ async def edit_user_settings(client, query): ), update_user_settings(query) ) - - elif data[2] == "metadata_text": + elif data[2] == "leech_suffix": await query.answer() buttons = ButtonMaker() if ( user_dict.get( - "metatxt", + "lsuffix", False ) + or "lsuffix" not in user_dict + and config_dict["LEECH_FILENAME_SUFFIX"] ): - buttons.ibutton( - "ʀᴇᴍᴏᴠᴇ\nᴍᴇᴛᴀᴅᴀᴛᴀ ᴛᴇxᴛ", - f"userset {user_id} metatxt" + buttons.data_button( + "ʀᴇᴍᴏᴠᴇ\nꜱᴜꜰꜰɪx", + f"userset {user_id} lsuffix" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", - f"userset {user_id} leech" + f"userset {user_id} leech", + position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", - f"userset {user_id} close" + f"userset {user_id} close", + position="footer" ) - await editMessage( + await edit_message( message, - "Send Leech Metadata Text, Whatever You want to add in the Videos.\n\nTimeout: 60 sec", - buttons.build_menu(1), + "Send Leech Filename Suffix.\nYou can add HTML tags.\n\nTimeout: 60 sec", + buttons.build_menu(2), ) try: event = await event_handler( @@ -1511,36 +1553,54 @@ async def edit_user_settings(client, query): await gather( set_option( event, - "metatxt" + "lsuffix" ), update_user_settings(query) ) - - elif data[2] == "attachment_url": + elif data[2] == "leech_cap_font": await query.answer() buttons = ButtonMaker() if ( user_dict.get( - "attachmenturl", + "lcapfont", False ) + or "lcapfont" not in user_dict + and config_dict["LEECH_CAPTION_FONT"] ): - buttons.ibutton( - "ʀᴇᴍᴏᴠᴇ ᴀᴛᴛᴀᴄʜᴍᴇɴᴛ ᴜʀʟ", - f"userset {user_id} attachmenturl" + buttons.data_button( + "ʀᴇᴍᴏᴠᴇ\nᴄᴀᴘᴛɪᴏɴ ꜰᴏɴᴛ", + f"userset {user_id} lcapfont" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", - f"userset {user_id} leech" + f"userset {user_id} leech", + position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", - f"userset {user_id} close" + f"userset {user_id} close", + position="footer" ) - await editMessage( + msg = """ +Send Leech Caption Font. Default is regular. + +Options: +b or bold for bold +i or italic for italic +u or underline for underline +bi for bold italic +bu for bold underline +iu for italic underline +biu for bold italic underline +m or mono or monospace for monospace + +Timeout: 60 sec +""" + await edit_message( message, - "Send Leech Attachment Url, which you want to get embedded with the video.\n\nTimeout: 60 sec", - buttons.build_menu(1), + msg, + buttons.build_menu(2), ) try: event = await event_handler( @@ -1555,38 +1615,38 @@ async def edit_user_settings(client, query): await gather( set_option( event, - "attachmenturl" + "lcapfont" ), update_user_settings(query) ) - elif data[2] == "leech_suffix": + elif data[2] == "ldest": await query.answer() buttons = ButtonMaker() if ( user_dict.get( - "lsuffix", + "leech_dest", False ) - or "lsuffix" not in user_dict - and config_dict["LEECH_FILENAME_SUFFIX"] + or "leech_dest" not in user_dict + and config_dict["USER_LEECH_DESTINATION"] ): - buttons.ibutton( - "ʀᴇᴍᴏᴠᴇ\nꜱᴜꜰꜰɪx", - f"userset {user_id} lsuffix" + buttons.data_button( + "ʀᴇꜱᴇᴛ\nʟᴇᴇᴄʜ ᴅᴇꜱᴛɪɴᴀᴛɪᴏɴ", + f"userset {user_id} leech_dest" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} leech", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) - await editMessage( + await edit_message( message, - "Send Leech Filename Suffix.\nYou can add HTML tags.\n\nTimeout: 60 sec", + "Send leech destination\nID or USERNAME or PM.\n\nTimeout: 60 sec", buttons.build_menu(2), ) try: @@ -1602,54 +1662,35 @@ async def edit_user_settings(client, query): await gather( set_option( event, - "lsuffix" + "leech_dest" ), update_user_settings(query) ) - elif data[2] == "leech_cap_font": + elif data[2] == "metadata_text": await query.answer() buttons = ButtonMaker() if ( user_dict.get( - "lcapfont", + "metatxt", False ) - or "lcapfont" not in user_dict - and config_dict["LEECH_CAPTION_FONT"] ): - buttons.ibutton( - "ʀᴇᴍᴏᴠᴇ\nᴄᴀᴘᴛɪᴏɴ ꜰᴏɴᴛ", - f"userset {user_id} lcapfont" + buttons.data_button( + "ʀᴇᴍᴏᴠᴇ\nᴍᴇᴛᴀᴅᴀᴛᴀ ᴛᴇxᴛ", + f"userset {user_id} metatxt" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", - f"userset {user_id} leech", - position="footer" + f"userset {user_id} leech" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", - f"userset {user_id} close", - position="footer" + f"userset {user_id} close" ) - msg = """ -Send Leech Caption Font. Default is regular. - -Options: -b or bold for bold -i or italic for italic -u or underline for underline -bi for bold italic -bu for bold underline -iu for italic underline -biu for bold italic underline -m or mono or monospace for monospace - -Timeout: 60 sec -""" - await editMessage( + await edit_message( message, - msg, - buttons.build_menu(2), + "Send Leech Metadata Text, Whatever You want to add in the Videos.\n\nTimeout: 60 sec", + buttons.build_menu(1), ) try: event = await event_handler( @@ -1664,39 +1705,35 @@ async def edit_user_settings(client, query): await gather( set_option( event, - "lcapfont" + "metatxt" ), update_user_settings(query) ) - elif data[2] == "ldest": + elif data[2] == "attachment_url": await query.answer() buttons = ButtonMaker() if ( user_dict.get( - "leech_dest", + "attachmenturl", False ) - or "leech_dest" not in user_dict - and config_dict["USER_LEECH_DESTINATION"] ): - buttons.ibutton( - "ʀᴇꜱᴇᴛ\nʟᴇᴇᴄʜ ᴅᴇꜱᴛɪɴᴀᴛɪᴏɴ", - f"userset {user_id} leech_dest" + buttons.data_button( + "ʀᴇᴍᴏᴠᴇ ᴀᴛᴛᴀᴄʜᴍᴇɴᴛ ᴜʀʟ", + f"userset {user_id} attachmenturl" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", - f"userset {user_id} leech", - position="footer" + f"userset {user_id} leech" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", - f"userset {user_id} close", - position="footer" + f"userset {user_id} close" ) - await editMessage( + await edit_message( message, - "Send leech destination\nID or USERNAME or PM.\n\nTimeout: 60 sec", - buttons.build_menu(2), + "Send Leech Attachment Url, which you want to get embedded with the video.\n\nTimeout: 60 sec", + buttons.build_menu(1), ) try: event = await event_handler( @@ -1711,7 +1748,52 @@ async def edit_user_settings(client, query): await gather( set_option( event, - "leech_dest" + "attachmenturl" + ), + update_user_settings(query) + ) + elif data[2] == "tlayout": + await query.answer() + buttons = ButtonMaker() + if ( + user_dict.get( + "thumb_layout", + False + ) + or "thumb_layout" not in user_dict + and config_dict["THUMBNAIL_LAYOUT"] + ): + buttons.data_button( + "ʀᴇꜱᴇᴛ\nᴛʜᴜᴍʙ ʟᴀʏᴏᴜᴛ", + f"userset {user_id} thumb_layout" + ) + buttons.data_button( + "ʙᴀᴄᴋ", + f"userset {user_id} leech" + ) + buttons.data_button( + "ᴄʟᴏꜱᴇ", + f"userset {user_id} close" + ) + await edit_message( + message, + "Send thumbnail layout as Width x Height (2x2, 3x3, 2x4, 4x4) etc.\n\nTimeout: 60 sec", + buttons.build_menu(1), + ) + try: + event = await event_handler( + client, + query + ) + except ListenerTimeout: + await update_user_settings(query) + except ListenerStopped: + pass + else: + await gather( + set_option( + event, + "thumb_layout" ), update_user_settings(query) ) @@ -1724,26 +1806,26 @@ async def edit_user_settings(client, query): False ) or "excluded_extensions" not in user_dict - and GLOBAL_EXTENSION_FILTER + and global_extension_filter ): - buttons.ibutton( + buttons.data_button( "ʀᴇᴍᴏᴠᴇ\nᴇxᴄʟᴜᴅᴇᴅ ᴇxᴛᴇɴꜱɪᴏɴꜱ", f"userset {user_id} excluded_extensions" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} back", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) ex_msg = "Send exluded extenions seperated by space without dot at beginning.\n" ex_msg += "Ex: zip mp4 jpg\nTimeout: 60 sec\n\n" - ex_msg += f"Added by Owner: {GLOBAL_EXTENSION_FILTER}" - await editMessage( + ex_msg += f"Added by Owner: {global_extension_filter}" + await edit_message( message, ex_msg, buttons.build_menu(2), @@ -1772,16 +1854,16 @@ async def edit_user_settings(client, query): "name_sub", False ): - buttons.ibutton( + buttons.data_button( "ʀᴇᴍᴏᴠᴇ\nɴᴀᴍᴇ ꜱᴜʙꜱᴛɪᴛᴜᴛᴇ", f"userset {user_id} name_sub" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} back", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" @@ -1790,21 +1872,17 @@ async def edit_user_settings(client, query): Word Substitutions. You can add pattern instead of normal text. Timeout: 60 sec NOTE: You must add \ before any character, those are the characters: \^$.|?*+()[]{}- - -Example-1: text : code : s|mirror : leech|tea : : s|clone - -1. text will get replaced by code with sensitive case +Example: script/code/s | mirror/leech | tea/ /s | clone | cpu/ | \[ZEE\]/ZEE | \\text\\/text/s +1. script will get replaced by code with sensitive case 2. mirror will get replaced by leech -4. tea will get removed with sensitive case +4. tea will get replaced by space with sensitive case 5. clone will get removed - -Example-2: \(text\) | \[test\] : test | \\text\\ : text : s -1. (text) will get removed -2. [test] will get replaced by test -3. \text\ will get replaced by text with sensitive case +6. cpu will get replaced by space +7. [ZEE] will get replaced by ZEE +8. \text\ will get replaced by text with sensitive case """ emsg += f"Your Current Value is {user_dict.get('name_sub') or 'not added yet!'}" - await editMessage( + await edit_message( message, emsg, buttons.build_menu(2), @@ -1842,12 +1920,12 @@ async def edit_user_settings(client, query): du ) await update_user_settings(query) - if DATABASE_URL: - await DbManager().update_user_data(user_id) + if config_dict["DATABASE_URL"]: + await database.update_user_data(user_id) elif data[2] == "upload_paths": await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ɴᴇᴡ\nᴘᴀᴛʜ", f"userset {user_id} new_path" ) @@ -1855,25 +1933,25 @@ async def edit_user_settings(client, query): data[2], False ): - buttons.ibutton( + buttons.data_button( "ꜱʜᴏᴡ\nᴀʟʟ ᴘᴀᴛʜꜱ", f"userset {user_id} show_path" ) - buttons.ibutton( + buttons.data_button( "ʀᴇᴍᴏᴠᴇ\nᴘᴀᴛʜ", f"userset {user_id} rm_path" ) - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} back", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) - await editMessage( + await edit_message( message, "Add or remove upload path.\n", buttons.build_menu(2), @@ -1881,17 +1959,17 @@ async def edit_user_settings(client, query): elif data[2] == "new_path": await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} upload_paths", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) - await editMessage( + await edit_message( message, ( "Send path name(no space in name) which you will use it as" @@ -1920,17 +1998,17 @@ async def edit_user_settings(client, query): elif data[2] == "rm_path": await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} upload_paths", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" ) - await editMessage( + await edit_message( message, "Send paths names which you want to delete, separated by space.\n\nTimeout: 60 sec", buttons.build_menu(2), @@ -1952,12 +2030,12 @@ async def edit_user_settings(client, query): elif data[2] == "show_path": await query.answer() buttons = ButtonMaker() - buttons.ibutton( + buttons.data_button( "ʙᴀᴄᴋ", f"userset {user_id} upload_paths", position="footer" ) - buttons.ibutton( + buttons.data_button( "ᴄʟᴏꜱᴇ", f"userset {user_id} close", position="footer" @@ -1970,7 +2048,7 @@ async def edit_user_settings(client, query): f"{key}: {value}\n" for key, value in user_dict["upload_paths"].items() ) - await editMessage( + await edit_message( message, msg, buttons.build_menu(2), @@ -1994,8 +2072,8 @@ async def edit_user_settings(client, query): else: user_data[user_id].clear() await update_user_settings(query) - if DATABASE_URL: - await DbManager().update_user_data(user_id) + if config_dict["DATABASE_URL"]: + await database.update_user_data(user_id) for fpath in [ thumb_path, rclone_conf, @@ -2008,10 +2086,11 @@ async def edit_user_settings(client, query): await update_user_settings(query) else: await query.answer() - await deleteMessage(message.reply_to_message) - await deleteMessage(message) + await delete_message(message.reply_to_message) + await delete_message(message) +@new_task async def send_users_settings(_, message): if user_data: msg = "" @@ -2028,17 +2107,17 @@ async def send_users_settings(_, message): if len(msg_ecd) > 4000: with BytesIO(msg_ecd) as ofile: ofile.name = "users_settings.txt" - await sendFile( + await send_file( message, ofile ) else: - await sendMessage( + await send_message( message, msg ) else: - await sendMessage( + await send_message( message, "No users data!" ) diff --git a/bot/modules/ytdlp.py b/bot/modules/ytdlp.py index 97f465c470e6..c8e301b14aa4 100644 --- a/bot/modules/ytdlp.py +++ b/bot/modules/ytdlp.py @@ -1,20 +1,20 @@ from bot import ( DOWNLOAD_DIR, - bot, - config_dict, LOGGER, - bot_loop + bot, + bot_loop, + config_dict ) from bot.helper.ext_utils.bot_utils import ( - sync_to_async, - arg_parser, COMMAND_USAGE, + arg_parser, + sync_to_async ) from bot.helper.ext_utils.links_utils import is_url from bot.helper.listeners.ytdlp_listener import ( - YtSelection, + extract_info, mdisk, - extract_info + YtSelection ) from bot.helper.listeners.task_listener import TaskListener from bot.helper.task_utils.download_utils.yt_dlp_download import YoutubeDLHelper @@ -22,8 +22,8 @@ from bot.helper.telegram_helper.filters import CustomFilters from bot.helper.telegram_helper.message_utils import ( auto_delete_message, - deleteMessage, - sendMessage, + delete_message, + send_message, ) from nekozee.filters import command @@ -36,30 +36,30 @@ def __init__( client, message, _=None, - isLeech=False, + is_leech=False, __=None, ___=None, - sameDir=None, + same_dir=None, bulk=None, - multiTag=None, + multi_tag=None, options="", ): - if sameDir is None: - sameDir = {} + if same_dir is None: + same_dir = {} if bulk is None: bulk = [] self.message = message self.client = client - self.multiTag = multiTag + self.multi_tag = multi_tag self.options = options - self.sameDir = sameDir + self.same_dir = same_dir self.bulk = bulk super().__init__() - self.isYtDlp = True - self.isLeech = isLeech + self.is_ytdlp = True + self.is_leech = is_leech - async def newEvent(self): - self.pmsg = await sendMessage( + async def new_event(self): + self.pmsg = await send_message( self.message, "Processing your request..." ) @@ -68,6 +68,8 @@ async def newEvent(self): qual = "" args = { + "-doc": False, + "-med": False, "-s": False, "-b": False, "-z": False, @@ -89,6 +91,7 @@ async def newEvent(self): "-ca": "", "-cv": "", "-ns": "", + "-tl": "", } arg_parser( @@ -103,23 +106,26 @@ async def newEvent(self): self.select = args["-s"] self.name = args["-n"] - self.upDest = args["-up"] - self.rcFlags = args["-rcf"] + self.up_dest = args["-up"] + self.rc_flags = args["-rcf"] self.link = args["link"] self.compress = args["-z"] self.thumb = args["-t"] - self.splitSize = args["-sp"] - self.sampleVideo = args["-sv"] - self.screenShots = args["-ss"] - self.forceRun = args["-f"] - self.forceDownload = args["-fd"] - self.forceUpload = args["-fu"] - self.convertAudio = args["-ca"] - self.convertVideo = args["-cv"] - self.nameSub = args["-ns"] - self.mixedLeech = args["-ml"] - - isBulk = args["-b"] + self.split_size = args["-sp"] + self.sample_video = args["-sv"] + self.screen_shots = args["-ss"] + self.force_run = args["-f"] + self.force_download = args["-fd"] + self.force_upload = args["-fu"] + self.convert_audio = args["-ca"] + self.convert_video = args["-cv"] + self.name_sub = args["-ns"] + self.mixed_leech = args["-ml"] + self.thumbnail_layout = args["-tl"] + self.as_doc = args["-doc"] + self.as_med = args["-med"] + + is_bulk = args["-b"] folder_name = args["-sd"] bulk_start = 0 @@ -128,30 +134,30 @@ async def newEvent(self): opt = args["-opt"] self.file_ = None - await self.getId() + await self.get_id() - if not isinstance(isBulk, bool): - dargs = isBulk.split(":") + if not isinstance(is_bulk, bool): + dargs = is_bulk.split(":") bulk_start = dargs[0] or None if len(dargs) == 2: bulk_end = dargs[1] or None - isBulk = True + is_bulk = True - if not isBulk: + if not is_bulk: if folder_name: folder_name = f"/{folder_name}" - if not self.sameDir: - self.sameDir = { + if not self.same_dir: + self.same_dir = { "total": self.multi, "tasks": set(), "name": folder_name, } - self.sameDir["tasks"].add(self.mid) - elif self.sameDir: - self.sameDir["total"] -= 1 + self.same_dir["tasks"].add(self.mid) + elif self.same_dir: + self.same_dir["total"] -= 1 else: - await deleteMessage(self.pmsg) - await self.initBulk( + await delete_message(self.pmsg) + await self.init_bulk( input_list, bulk_start, bulk_end, @@ -164,11 +170,11 @@ async def newEvent(self): path = f"{DOWNLOAD_DIR}{self.mid}{folder_name}" - await self.getTag(text) + await self.get_tag(text) opt = ( opt - or self.userDict.get("yt_opt") + or self.user_dict.get("yt_opt") or config_dict["YT_DLP_OPTIONS"] ) @@ -182,13 +188,13 @@ async def newEvent(self): )[0].strip() if not is_url(self.link): - hmsg = await sendMessage( + hmsg = await send_message( self.message, COMMAND_USAGE["yt"][0], COMMAND_USAGE["yt"][1] ) - self.removeFromSameDir() - await deleteMessage(self.pmsg) + self.remove_from_same_dir() + await delete_message(self.pmsg) await auto_delete_message( self.message, hmsg @@ -204,18 +210,18 @@ async def newEvent(self): self.name ) - if await self.permissionCheck() != True: + if await self.permission_check() != True: return - await deleteMessage(self.pmsg) + await delete_message(self.pmsg) try: - await self.beforeStart() + await self.before_start() except Exception as e: - emsg = await sendMessage( + emsg = await send_message( self.message, e ) - self.removeFromSameDir() + self.remove_from_same_dir() await auto_delete_message( self.message, emsg @@ -239,7 +245,10 @@ async def newEvent(self): 1 ) ) - if key == "postprocessors": + if key in [ + "postprocessors", + "download_ranges" + ]: continue if key == "format" and not self.select: if value.startswith("ba/b-"): @@ -294,30 +303,30 @@ async def newEvent(self): ">", " " ) - emsg = await sendMessage( + emsg = await send_message( self.message, f"{self.tag} {msg}" ) - self.removeFromSameDir() + self.remove_from_same_dir() await auto_delete_message( self.message, emsg ) return finally: - self.run_multi( + await self.run_multi( input_list, folder_name, YtDlp - ) # type: ignore + ) if not qual: qual = await YtSelection(self).get_quality(result) if qual is None: - self.removeFromSameDir() + self.remove_from_same_dir() return - await deleteMessage(self.pmsg) + await delete_message(self.pmsg) LOGGER.info(f"Downloading with YT-DLP: {self.link}") playlist = "entries" in result @@ -334,15 +343,15 @@ async def ytdl(client, message): bot_loop.create_task(YtDlp( client, message - ).newEvent()) # type: ignore + ).new_event()) # type: ignore -async def ytdlleech(client, message): +async def ytdl_leech(client, message): bot_loop.create_task(YtDlp( client, message, - isLeech=True - ).newEvent()) # type: ignore + is_leech=True + ).new_event()) # type: ignore bot.add_handler( # type: ignore @@ -357,7 +366,7 @@ async def ytdlleech(client, message): bot.add_handler( # type: ignore MessageHandler( - ytdlleech, + ytdl_leech, filters=command( BotCommands.YtdlLeechCommand, case_sensitive=True diff --git a/config_sample.env b/config_sample.env index 00c026d827b0..cc304f5c35d5 100644 --- a/config_sample.env +++ b/config_sample.env @@ -66,6 +66,7 @@ USER_LEECH_DESTINATION = "PM" # PM or DM or chat_id NAME_SUBSTITUTE = "" METADATA_TXT = "" META_ATTACHMENT = "" +THUMBNAIL_LAYOUT = "" # Options: 2x2 or 3x3 or 2x4 or 4x4 # Super Group Settings REQUEST_LIMITS = "4" # Enter only numbers in seconds diff --git a/myjd/__init__.py b/myjd/__init__.py index 678c8a490cf3..233385ad69dd 100644 --- a/myjd/__init__.py +++ b/myjd/__init__.py @@ -32,6 +32,6 @@ MYJDTooManyRequestsException, MYJDUnknownException, ) -from .myjdapi import Myjdapi +from .myjdapi import MyJdApi __version__ = "1.1.7" diff --git a/myjd/myjdapi.py b/myjd/myjdapi.py index ff8306b183d8..3de1825a5d2d 100644 --- a/myjd/myjdapi.py +++ b/myjd/myjdapi.py @@ -238,7 +238,7 @@ async def force_download(self, link_ids, package_ids): package_ids ] return await self.device.action( - f"{self.url}/forceDownload", + f"{self.url}/force_download", params ) @@ -838,7 +838,7 @@ async def force_download(self, link_ids=None, package_ids=None): package_ids ] return await self.device.action( - f"{self.url}/forceDownload", + f"{self.url}/force_download", params ) @@ -1100,7 +1100,7 @@ async def request(self, method: str, url: str, **kwargs): ) -class Myjdapi: +class MyJdApi: def __init__(self): self.__request_id = int(time() * 1000) diff --git a/sabnzbdapi/__init__.py b/sabnzbdapi/__init__.py index 9b6034069e44..176a64af8c97 100644 --- a/sabnzbdapi/__init__.py +++ b/sabnzbdapi/__init__.py @@ -1 +1,3 @@ -from sabnzbdapi.requests import sabnzbdClient +from sabnzbdapi.requests import SabnzbdClient + +__all__ = ["SabnzbdClient"] diff --git a/sabnzbdapi/requests.py b/sabnzbdapi/requests.py index d17643e00305..7fb833daafa3 100644 --- a/sabnzbdapi/requests.py +++ b/sabnzbdapi/requests.py @@ -12,7 +12,7 @@ from .exception import APIConnectionError -class sabnzbdSession(AsyncClient): +class SabnzbdSession(AsyncClient): @wraps(AsyncClient.request) async def request( self, @@ -40,7 +40,7 @@ async def request( ) -class sabnzbdClient(JobFunctions): +class SabnzbdClient(JobFunctions): LOGGED_IN = False @@ -77,7 +77,7 @@ def _session(self): verify=self._VERIFY_CERTIFICATE ) - self._http_session = sabnzbdSession(transport=transport) + self._http_session = SabnzbdSession(transport=transport) self._http_session.verify = self._VERIFY_CERTIFICATE diff --git a/update.py b/update.py index 1e3c13c282f0..f5923570a5ad 100644 --- a/update.py +++ b/update.py @@ -59,7 +59,7 @@ log_error("BOT_TOKEN variable is missing! Exiting now") exit(1) -bot_id = BOT_TOKEN.split( +BOT_ID = BOT_TOKEN.split( ":", 1 )[0] @@ -78,8 +78,8 @@ server_api=ServerApi("1") ) db = conn.zee - old_config = db.settings.deployConfig.find_one({"_id": bot_id}) - config_dict = db.settings.config.find_one({"_id": bot_id}) + old_config = db.settings.deployConfig.find_one({"_id": BOT_ID}) + config_dict = db.settings.config.find_one({"_id": BOT_ID}) if old_config is not None: del old_config["_id"] if ( diff --git a/web/wserver.py b/web/wserver.py index cda226b808d8..a93316120416 100644 --- a/web/wserver.py +++ b/web/wserver.py @@ -15,19 +15,27 @@ ) from qbittorrentapi import ( NotFound404Error, - Client as qbClient + Client as QbClient ) from time import sleep -from sabnzbdapi import sabnzbdClient -from asyncio import get_event_loop +from sabnzbdapi import SabnzbdClient +from asyncio import ( + get_running_loop, + new_event_loop, + set_event_loop +) from web.nodes import make_tree app = Flask(__name__) -web_loop = get_event_loop() +try: + web_loop = get_running_loop() +except RuntimeError: + web_loop = new_event_loop() + set_event_loop(web_loop) -qbittorrent_client = qbClient( +qbittorrent_client = QbClient( host="localhost", port=8090, VERIFY_WEBUI_CERTIFICATE=False, @@ -41,7 +49,7 @@ }, ) -sabnzbd_client = sabnzbdClient( +sabnzbd_client = SabnzbdClient( host="http://localhost", api_key="zee", port="8070",