From 0369615e6ef449d9b41cb2e0fa42c61478ab1212 Mon Sep 17 00:00:00 2001 From: 5hojib Date: Sat, 28 Dec 2024 14:27:13 +0600 Subject: [PATCH] sync with latest --- Dockerfile | 4 +- bot/__main__.py | 30 +++- bot/core/config_manager.py | 12 +- bot/core/handlers.py | 13 ++ bot/core/startup.py | 6 +- bot/helper/common.py | 8 +- bot/helper/ext_utils/bot_utils.py | 57 ++++--- bot/helper/ext_utils/help_messages.py | 2 +- bot/helper/ext_utils/status_utils.py | 6 +- .../download_utils/telegram_download.py | 2 +- .../download_utils/yt_dlp_download.py | 10 +- .../mirror_leech_utils/gdrive_utils/helper.py | 2 +- .../rclone_utils/transfer.py | 2 +- .../mirror_leech_utils/telegram_uploader.py | 10 +- bot/helper/telegram_helper/bot_commands.py | 1 + bot/modules/__init__.py | 9 +- bot/modules/bot_settings.py | 3 + bot/modules/force_start.py | 20 ++- bot/modules/restart.py | 159 +++++++++++------- config_sample.py | 91 ++++++++++ sam_conf.py | 0 21 files changed, 330 insertions(+), 117 deletions(-) create mode 100644 config_sample.py delete mode 100644 sam_conf.py diff --git a/Dockerfile b/Dockerfile index e7aa56b05..5ff0c0e01 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ -FROM 5hojib/aeon:beta +FROM 5hojib/aeon:latest WORKDIR /usr/src/app RUN chmod 777 /usr/src/app COPY requirements.txt . -RUN pip3 install --break-system-packages --ignore-installed --no-cache-dir -r requirements.txt +RUN uv pip install --break-system-packages --system --no-cache-dir -r requirements.txt COPY . . CMD ["bash", "start.sh"] diff --git a/bot/__main__.py b/bot/__main__.py index da71ca3af..f850f0892 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -13,7 +13,7 @@ update_qb_options, update_variables, ) -from .helper.ext_utils.bot_utils import create_help_buttons, sync_to_async +from .helper.ext_utils.bot_utils import create_help_buttons, sync_to_async, new_task from .helper.ext_utils.files_utils import clean_all, exit_clean_up from .helper.ext_utils.telegraph_helper import telegraph from .helper.listeners.aria2_listener import start_aria2_listener @@ -23,9 +23,31 @@ initiate_search_tools, restart_notification, ) +from .helper.telegram_helper.filters import CustomFilters +from pyrogram.filters import regex +from pyrogram.handlers import CallbackQueryHandler Config.load() +@new_task +async def restart_sessions_confirm(_, query): + data = query.data.split() + message = query.message + if data[1] == "confirm": + reply_to = message.reply_to_message + restart_message = await send_message(reply_to, "Restarting Session(s)...") + await delete_message(message) + await TgClient.reload() + add_handlers() + TgClient.bot.add_handler( + CallbackQueryHandler( + restart_sessions_confirm, + filters=regex("^sessionrestart") & CustomFilters.sudo, + ) + ) + await edit_message(restart_message, "Session(s) Restarted Successfully!") + else: + await delete_message(message) async def main(): await load_settings() @@ -47,6 +69,12 @@ async def main(): ) create_help_buttons() add_handlers() + TgClient.bot.add_handler( + CallbackQueryHandler( + restart_sessions_confirm, + filters=regex("^sessionrestart") & CustomFilters.sudo, + ) + ) LOGGER.info("Bot Started!") signal(SIGINT, exit_clean_up) diff --git a/bot/core/config_manager.py b/bot/core/config_manager.py index f06c46be5..a8855efa8 100644 --- a/bot/core/config_manager.py +++ b/bot/core/config_manager.py @@ -84,12 +84,12 @@ def load(cls): for attr in dir(settings): if hasattr(cls, attr): value = getattr(settings, attr) - if isinstance(value, str): - value = value.strip() if not value: continue - if attr == "DEFAULT_UPLOAD" and value != "rc": - value = "gd" + if isinstance(value, str): + value = value.strip() + if attr == "DEFAULT_UPLOAD" and value != "gd": + value = "rc" elif attr == "DOWNLOAD_DIR" and not value.endswith("/"): value = f"{value}/" setattr(cls, attr, value) @@ -104,8 +104,8 @@ def load(cls): def load_dict(cls, config_dict): for key, value in config_dict.items(): if hasattr(cls, key): - if key == "DEFAULT_UPLOAD" and value != "rc": - value = "gd" + if key == "DEFAULT_UPLOAD" and value != "gd": + value = "rc" elif key == "DOWNLOAD_DIR": if not value.endswith("/"): value = f"{value}/" diff --git a/bot/core/handlers.py b/bot/core/handlers.py index d672d365e..229173c21 100644 --- a/bot/core/handlers.py +++ b/bot/core/handlers.py @@ -288,3 +288,16 @@ def add_handlers(): & CustomFilters.authorized, ), ) + TgClient.bot.add_handler( + CallbackQueryHandler( + confirm_restart, filters=regex("^botrestart") & CustomFilters.sudo + ) + ) + TgClient.bot.add_handler( + MessageHandler( + restart_sessions, + filters=command(BotCommands.RestartSessionsCommand, case_sensitive=True) + & CustomFilters.sudo, + ) + ) + \ No newline at end of file diff --git a/bot/core/startup.py b/bot/core/startup.py index f46731832..bc038c882 100644 --- a/bot/core/startup.py +++ b/bot/core/startup.py @@ -209,9 +209,6 @@ async def update_variables(): else: index_urls.append("") - if not await aiopath.exists("accounts"): - Config.USE_SERVICE_ACCOUNTS = False - async def load_configurations(): if not await aiopath.exists(".netrc"): @@ -240,3 +237,6 @@ async def load_configurations(): ).wait() await (await create_subprocess_exec("chmod", "-R", "777", "accounts")).wait() await remove("accounts.zip") + + if not await aiopath.exists("accounts"): + Config.USE_SERVICE_ACCOUNTS = False diff --git a/bot/helper/common.py b/bot/helper/common.py index b8052f42c..ace24bbae 100644 --- a/bot/helper/common.py +++ b/bot/helper/common.py @@ -412,7 +412,7 @@ async def before_start(self): ) ) - if is_telegram_link(self.thumb): + if self.thumb != "none" and is_telegram_link(self.thumb): msg = (await get_tg_link_message(self.thumb))[0] self.thumb = ( await create_thumb(msg) if msg.photo or msg.document else "" @@ -1199,6 +1199,9 @@ async def proceed_ffmpeg(self, dl_path, gid): res = await run_ffmpeg_cmd(self, cmd, file_path) if res and delete_files: await remove(file_path) + if "ffmpeg." in res: + newres = res.replace("ffmpeg.", "") + await move(res, newres) else: for dirpath, _, files in await sync_to_async( walk, @@ -1233,6 +1236,9 @@ async def proceed_ffmpeg(self, dl_path, gid): res = await run_ffmpeg_cmd(self, cmd, f_path) if res and delete_files: await remove(f_path) + if "ffmpeg." in res: + newres = res.replace("ffmpeg.", "") + await move(res, newres) if checked: cpu_eater_lock.release() return dl_path diff --git a/bot/helper/ext_utils/bot_utils.py b/bot/helper/ext_utils/bot_utils.py index a3401b0b3..217747f06 100644 --- a/bot/helper/ext_utils/bot_utils.py +++ b/bot/helper/ext_utils/bot_utils.py @@ -91,8 +91,14 @@ async def get_telegraph_list(telegraph_content): def arg_parser(items, arg_base): + if not items: return + + arg_start = -1 + i = 0 + total = len(items) + bool_arg_set = { "-b", "-e", @@ -110,16 +116,28 @@ def arg_parser(items, arg_base): "-doc", "-med", } - t = len(items) - i = 0 - arg_start = -1 - - while i + 1 <= t: + def process_argument_with_values(start_index): + values = [] + for j in range(start_index + 1, total): + if items[j] in arg_base: + break + values.append(items[j]) + return values + + def process_nested_list(start_index): + values = [] + end_index = start_index + 1 + while end_index < total and items[end_index] != "]": + values.append(items[end_index]) + end_index += 1 + return values, end_index - start_index + + while i < total: part = items[i] if part in arg_base: if arg_start == -1: arg_start = i - if (i + 1 == t and part in bool_arg_set) or part in [ + if (i + 1 == total and part in bool_arg_set) or part in [ "-s", "-j", "-f", @@ -131,27 +149,20 @@ def arg_parser(items, arg_base): "-med", ]: arg_base[part] = True + elif part == "-ff" and i + 1 < total and items[i + 1].startswith("["): + nested_values, skip_count = process_nested_list(i + 1) + arg_base[part] = nested_values + i += skip_count else: - sub_list = [] - for j in range(i + 1, t): - item = items[j] - if item in arg_base: - if part in bool_arg_set and not sub_list: - arg_base[part] = True - break - sub_list.append(item) - i += 1 + sub_list = process_argument_with_values(i) if sub_list: arg_base[part] = " ".join(sub_list) + i += len(sub_list) i += 1 - if "link" in arg_base and items[0] not in arg_base: - link = [] - if arg_start == -1: - link.extend(iter(items)) - else: - link.extend(items[r] for r in range(arg_start)) - if link: - arg_base["link"] = " ".join(link) + if "link" in arg_base: + link_items = items[:arg_start] if arg_start != -1 else items + if link_items: + arg_base["link"] = " ".join(link_items) def get_size_bytes(size): diff --git a/bot/helper/ext_utils/help_messages.py b/bot/helper/ext_utils/help_messages.py index 76ad85874..b77ee6906 100644 --- a/bot/helper/ext_utils/help_messages.py +++ b/bot/helper/ext_utils/help_messages.py @@ -56,7 +56,7 @@ thumb = """Thumbnail for current task: -t -/cmd link -t tg-message-link(doc or photo)""" +/cmd link -t tg-message-link (doc or photo) or none (file without thumb)""" split_size = """Split size for current task: -sp diff --git a/bot/helper/ext_utils/status_utils.py b/bot/helper/ext_utils/status_utils.py index 7398e7ead..642d60a24 100644 --- a/bot/helper/ext_utils/status_utils.py +++ b/bot/helper/ext_utils/status_utils.py @@ -40,13 +40,13 @@ class MirrorStatus: "AR": MirrorStatus.STATUS_ARCHIVE, "EX": MirrorStatus.STATUS_EXTRACT, "SD": MirrorStatus.STATUS_SEED, + "CL": MirrorStatus.STATUS_CLONE, "CM": MirrorStatus.STATUS_CONVERT, "SP": MirrorStatus.STATUS_SPLIT, - "CK": MirrorStatus.STATUS_CHECK, "SV": MirrorStatus.STATUS_SAMVID, "FF": MirrorStatus.STATUS_FFMPEG, - "CL": MirrorStatus.STATUS_CLONE, "PA": MirrorStatus.STATUS_PAUSED, + "CK": MirrorStatus.STATUS_CHECK, } @@ -245,7 +245,7 @@ async def get_readable_message(sid, is_user, page_no=1, status="All", page_step= for i in [1, 2, 4, 6, 8, 10, 15]: buttons.data_button(i, f"status {sid} ps {i}", position="footer") if status != "All" or tasks_no > 20: - for label, status_value in list(STATUSES.items())[:9]: + for label, status_value in list(STATUSES.items()): if status_value != status: buttons.data_button(label, f"status {sid} st {status_value}") buttons.data_button("♻️", f"status {sid} ref", position="header") diff --git a/bot/helper/mirror_leech_utils/download_utils/telegram_download.py b/bot/helper/mirror_leech_utils/download_utils/telegram_download.py index 3cd39fe0f..8eb30af03 100644 --- a/bot/helper/mirror_leech_utils/download_utils/telegram_download.py +++ b/bot/helper/mirror_leech_utils/download_utils/telegram_download.py @@ -174,4 +174,4 @@ async def cancel_task(self): LOGGER.info( f"Cancelling download on user request: name: {self._listener.name} id: {self._id}", ) - await self._on_download_error("Cancelled by user!") + await self._on_download_error("Stopped by user!") diff --git a/bot/helper/mirror_leech_utils/download_utils/yt_dlp_download.py b/bot/helper/mirror_leech_utils/download_utils/yt_dlp_download.py index ebcec1e58..7a9433f1a 100644 --- a/bot/helper/mirror_leech_utils/download_utils/yt_dlp_download.py +++ b/bot/helper/mirror_leech_utils/download_utils/yt_dlp_download.py @@ -156,9 +156,9 @@ def _extract_meta_data(self): if not entry: continue if "filesize_approx" in entry: - self._listener.size += entry["filesize_approx"] + self._listener.size += entry.get("filesize_approx", 0) elif "filesize" in entry: - self._listener.size += entry["filesize"] + self._listener.size += entry.get("filesize", 0) if not self._listener.name: outtmpl_ = "%(series,playlist_title,channel)s%(season_number& |)s%(season_number&S|)s%(season_number|)02d.%(ext)s" self._listener.name, ext = ospath.splitext( @@ -197,8 +197,8 @@ def _download(self, path): if self._listener.is_cancelled: return async_to_sync(self._listener.on_download_complete) - except ValueError: - self._on_download_error("Download Stopped by User!") + except Exception: + pass async def add_download(self, path, qual, playlist, options): if playlist: @@ -352,7 +352,7 @@ async def add_download(self, path, qual, playlist, options): async def cancel_task(self): self._listener.is_cancelled = True LOGGER.info(f"Cancelling Download: {self._listener.name}") - await self._listener.on_download_error("Download Cancelled by User!") + await self._listener.on_download_error("Stopped by User!") def _set_options(self, options): options = options.split("|") diff --git a/bot/helper/mirror_leech_utils/gdrive_utils/helper.py b/bot/helper/mirror_leech_utils/gdrive_utils/helper.py index 1622dc3b4..d6d333cde 100644 --- a/bot/helper/mirror_leech_utils/gdrive_utils/helper.py +++ b/bot/helper/mirror_leech_utils/gdrive_utils/helper.py @@ -254,7 +254,7 @@ async def cancel_task(self): self.listener.is_cancelled = True if self.is_downloading: LOGGER.info(f"Cancelling Download: {self.listener.name}") - await self.listener.on_download_error("Download stopped by user!") + await self.listener.on_download_error("Stopped by user!") elif self.is_cloning: LOGGER.info(f"Cancelling Clone: {self.listener.name}") await self.listener.on_upload_error( diff --git a/bot/helper/mirror_leech_utils/rclone_utils/transfer.py b/bot/helper/mirror_leech_utils/rclone_utils/transfer.py index 2dc3a4963..1fff29b14 100644 --- a/bot/helper/mirror_leech_utils/rclone_utils/transfer.py +++ b/bot/helper/mirror_leech_utils/rclone_utils/transfer.py @@ -577,7 +577,7 @@ async def cancel_task(self): self._proc.kill() if self._is_download: LOGGER.info(f"Cancelling Download: {self._listener.name}") - await self._listener.on_download_error("Download stopped by user!") + await self._listener.on_download_error("Stopped by user!") elif self._is_upload: LOGGER.info(f"Cancelling Upload: {self._listener.name}") await self._listener.on_upload_error("your upload has been stopped!") diff --git a/bot/helper/mirror_leech_utils/telegram_uploader.py b/bot/helper/mirror_leech_utils/telegram_uploader.py index 6f843ffdf..cb34e7443 100644 --- a/bot/helper/mirror_leech_utils/telegram_uploader.py +++ b/bot/helper/mirror_leech_utils/telegram_uploader.py @@ -94,7 +94,7 @@ async def _user_settings(self): if "lprefix" not in self._listener.user_dict else "" ) - if not await aiopath.exists(self._thumb): + if self._thumb != "none" and not await aiopath.exists(self._thumb): self._thumb = None async def _msg_to_reply(self): @@ -398,7 +398,7 @@ async def upload(self, o_files, ft_delete): retry=retry_if_exception_type(Exception), ) async def _upload_file(self, cap_mono, file, o_path, force_document=False): - if self._thumb is not None and not await aiopath.exists(self._thumb): + if self._thumb is not None and not await aiopath.exists(self._thumb) and self._thumb != "none": self._thumb = None thumb = self._thumb self._is_corrupted = False @@ -424,6 +424,8 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): if self._listener.is_cancelled: return None + if thumb == "none": + thumb = None self._sent_msg = await self._sent_msg.reply_document( document=self._up_path, quote=True, @@ -444,7 +446,7 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): ) if thumb is None: thumb = await get_video_thumbnail(self._up_path, duration) - if thumb is not None: + if thumb is not None and thumb != "none": with Image.open(thumb) as img: width, height = img.size else: @@ -452,6 +454,8 @@ async def _upload_file(self, cap_mono, file, o_path, force_document=False): height = 320 if self._listener.is_cancelled: return None + if thumb == "none": + thumb = None self._sent_msg = await self._sent_msg.reply_video( video=self._up_path, quote=True, diff --git a/bot/helper/telegram_helper/bot_commands.py b/bot/helper/telegram_helper/bot_commands.py index 1a7442a29..73ef93c8b 100644 --- a/bot/helper/telegram_helper/bot_commands.py +++ b/bot/helper/telegram_helper/bot_commands.py @@ -41,6 +41,7 @@ def __init__(self): self.RmSudoCommand = f"rmsudo{Config.CMD_SUFFIX}" self.PingCommand = f"ping{Config.CMD_SUFFIX}" self.RestartCommand = f"restart{Config.CMD_SUFFIX}" + self.RestartSessionsCommand = f"restartses{Config.CMD_SUFFIX}" self.StatsCommand = f"stats{Config.CMD_SUFFIX}" self.HelpCommand = f"help{Config.CMD_SUFFIX}" self.LogCommand = f"log{Config.CMD_SUFFIX}" diff --git a/bot/modules/__init__.py b/bot/modules/__init__.py index 4eef0b41d..01f8f0a91 100644 --- a/bot/modules/__init__.py +++ b/bot/modules/__init__.py @@ -15,7 +15,12 @@ qb_leech, qb_mirror, ) -from .restart import restart_bot, restart_notification +from .restart import ( + restart_bot, + restart_notification, + confirm_restart, + restart_sessions, +) from .rss import get_rss_menu, rss_listener from .search import initiate_search_tools, torrent_search, torrent_search_update from .services import log, ping, start @@ -63,6 +68,8 @@ "remove_sudo", "restart_bot", "restart_notification", + "confirm_restart", + "restart_sessions", "rss_listener", "run_shell", "select", diff --git a/bot/modules/bot_settings.py b/bot/modules/bot_settings.py index a1fa69edc..a33bedfde 100644 --- a/bot/modules/bot_settings.py +++ b/bot/modules/bot_settings.py @@ -481,6 +481,9 @@ async def load_config(): index_urls.clear() await update_variables() + if not await aiopath.exists("accounts"): + Config.USE_SERVICE_ACCOUNTS = False + if len(task_dict) != 0 and (st := intervals["status"]): for key, intvl in list(st.items()): intvl.cancel() diff --git a/bot/modules/force_start.py b/bot/modules/force_start.py index 7b294a484..52764684e 100644 --- a/bot/modules/force_start.py +++ b/bot/modules/force_start.py @@ -35,10 +35,16 @@ async def remove_from_queue(_, message): await send_message(message, "This is not an active task!") return elif len(msg) in {1, 2}: - msg = ( - "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!" - ) + msg = f"""Reply to an active Command message which was used to start the download/upload. +/{BotCommands.ForceStartCommand[0]} fd (to remove it from download queue) or fu (to remove it from upload queue) or nothing to start remove it from both download and upload queue. +Also send /{BotCommands.ForceStartCommand[0]} GID fu|fd or obly gid to force start by removeing the task rom queue! +Examples: +/{BotCommands.ForceStartCommand[1]} GID fu (force upload) +/{BotCommands.ForceStartCommand[1]} GID (force download and upload) +By reply to task cmd: +/{BotCommands.ForceStartCommand[1]} (force download and upload) +/{BotCommands.ForceStartCommand[1]} fd (force download) +""" await send_message(message, msg) return if user_id not in (Config.OWNER_ID, task.listener.user_id) and ( @@ -54,11 +60,15 @@ async def remove_from_queue(_, message): if listener.mid in queued_up: await start_up_from_queued(listener.mid) msg = "Task have been force started to upload!" + else: + msg = "Force upload enabled for this task!" elif status == "fd": 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: + msg = "This task not in download queue!" else: listener.force_download = True listener.force_upload = True @@ -68,5 +78,7 @@ async def remove_from_queue(_, message): elif listener.mid in queued_dl: await start_dl_from_queued(listener.mid) msg = "Task have been force started to download and upload will start once download finish!" + else: + msg = "This task not in queue!" if msg: await send_message(message, msg) diff --git a/bot/modules/restart.py b/bot/modules/restart.py index 809256aee..52777f887 100644 --- a/bot/modules/restart.py +++ b/bot/modules/restart.py @@ -1,44 +1,61 @@ -import contextlib -from asyncio import create_subprocess_exec, gather -from os import execl as osexecl from sys import executable - from aiofiles import open as aiopen -from aiofiles.os import path as aiopath -from aiofiles.os import remove +from aiofiles.os import path as aiopath, remove +from asyncio import gather, create_subprocess_exec +from os import execl as osexecl -from bot import LOGGER, intervals, scheduler -from bot.core.aeon_client import TgClient -from bot.core.config_manager import Config -from bot.helper.ext_utils.bot_utils import new_task, sync_to_async -from bot.helper.ext_utils.db_handler import database -from bot.helper.ext_utils.files_utils import clean_all -from bot.helper.telegram_helper.message_utils import send_message +from .. import intervals, scheduler, sabnzbd_client, LOGGER +from ..helper.ext_utils.bot_utils import new_task, sync_to_async +from ..helper.telegram_helper.message_utils import ( + send_message, + delete_message, +) +from ..helper.ext_utils.db_handler import database +from ..helper.ext_utils.files_utils import clean_all +from ..helper.telegram_helper import button_build +from ..core.mltb_client import TgClient +from ..core.config_manager import Config @new_task async def restart_bot(_, message): - intervals["stopAll"] = True - restart_message = await send_message(message, "Restarting...") - if scheduler.running: - scheduler.shutdown(wait=False) - if qb := intervals["qb"]: - qb.cancel() - if st := intervals["status"]: - for intvl in list(st.values()): - intvl.cancel() - await sync_to_async(clean_all) - proc1 = await create_subprocess_exec( - "pkill", - "-9", - "-f", - "gunicorn|aria2c|qbittorrent-nox|ffmpeg|rclone|java|sabnzbdplus", + buttons = button_build.ButtonMaker() + buttons.data_button("Yes!", "botrestart confirm") + buttons.data_button("Cancel", "botrestart cancel") + button = buttons.build_menu(2) + await send_message(message, "Are you sure you want to restart the bot ?!", button) + + +@new_task +async def restart_sessions(_, message): + buttons = button_build.ButtonMaker() + buttons.data_button("Yes!", "sessionrestart confirm") + buttons.data_button("Cancel", "sessionrestart cancel") + button = buttons.build_menu(2) + await send_message( + message, "Are you sure you want to restart the session(s) ?!", button ) - proc2 = await create_subprocess_exec("python3", "update.py") - await gather(proc1.wait(), proc2.wait()) - async with aiopen(".restartmsg", "w") as f: - await f.write(f"{restart_message.chat.id}\n{restart_message.id}\n") - osexecl(executable, executable, "-m", "bot") + + +async def send_incomplete_task_message(cid, msg_id, msg): + try: + if msg.startswith("Restarted Successfully!"): + await TgClient.bot.edit_message_text( + chat_id=cid, + message_id=msg_id, + text=msg, + disable_web_page_preview=True, + ) + await remove(".restartmsg") + else: + await TgClient.bot.send_message( + chat_id=cid, + text=msg, + disable_web_page_preview=True, + disable_notification=True, + ) + except Exception as e: + LOGGER.error(e) async def restart_notification(): @@ -48,46 +65,66 @@ async def restart_notification(): else: chat_id, msg_id = 0, 0 - async def send_incomplete_task_message(cid, msg): - try: - if msg.startswith("Restarted Successfully!"): - await TgClient.bot.edit_message_text( - chat_id=chat_id, - message_id=msg_id, - text=msg, - ) - await remove(".restartmsg") - else: - await TgClient.bot.send_message( - chat_id=cid, - text=msg, - disable_web_page_preview=True, - disable_notification=True, - ) - except Exception as e: - LOGGER.error(e) - if Config.INCOMPLETE_TASK_NOTIFIER and Config.DATABASE_URL: if notifier_dict := await database.get_incomplete_tasks(): for cid, data in notifier_dict.items(): - msg = ( - "Restarted Successfully!" if cid == chat_id else "Bot Restarted!" - ) + msg = "Restarted Successfully!" if cid == chat_id else "Bot Restarted!" for tag, links in data.items(): msg += f"\n\n{tag}: " for index, link in enumerate(links, start=1): msg += f" {index} |" if len(msg.encode()) > 4000: - await send_incomplete_task_message(cid, msg) + await send_incomplete_task_message(cid, msg_id, msg) msg = "" if msg: - await send_incomplete_task_message(cid, msg) + await send_incomplete_task_message(cid, msg_id, msg) if await aiopath.isfile(".restartmsg"): - with contextlib.suppress(Exception): + try: await TgClient.bot.edit_message_text( - chat_id=chat_id, - message_id=msg_id, - text="Restarted Successfully!", + chat_id=chat_id, message_id=msg_id, text="Restarted Successfully!" ) + except: + pass await remove(".restartmsg") + + +@new_task +async def confirm_restart(_, query): + await query.answer() + data = query.data.split() + message = query.message + await delete_message(message) + if data[1] == "confirm": + reply_to = message.reply_to_message + intervals["stopAll"] = True + restart_message = await send_message(reply_to, "Restarting...") + await delete_message(message) + await TgClient.stop() + if scheduler.running: + scheduler.shutdown(wait=False) + if qb := intervals["qb"]: + qb.cancel() + if st := intervals["status"]: + for intvl in list(st.values()): + intvl.cancel() + await sync_to_async(clean_all) + if sabnzbd_client.LOGGED_IN: + await gather( + sabnzbd_client.pause_all(), + sabnzbd_client.purge_all(True), + sabnzbd_client.delete_history("all", delete_files=True), + ) + proc1 = await create_subprocess_exec( + "pkill", + "-9", + "-f", + "gunicorn|xria|xnox|xtra|xone", + ) + proc2 = await create_subprocess_exec("python3", "update.py") + await gather(proc1.wait(), proc2.wait()) + async with aiopen(".restartmsg", "w") as f: + await f.write(f"{restart_message.chat.id}\n{restart_message.id}\n") + osexecl(executable, executable, "-m", "bot") + else: + await delete_message(message) diff --git a/config_sample.py b/config_sample.py new file mode 100644 index 000000000..b0cd0b7e9 --- /dev/null +++ b/config_sample.py @@ -0,0 +1,91 @@ +# REQUIRED CONFIG +BOT_TOKEN = "" +OWNER_ID = 0 +TELEGRAM_API = 0 +TELEGRAM_HASH = "" + +# OPTIONAL CONFIG +USER_SESSION_STRING = "" +DOWNLOAD_DIR = "/usr/src/app/downloads/" +CMD_SUFFIX = "" +AUTHORIZED_CHATS = "" +SUDO_USERS = "" +DATABASE_URL = "" +STATUS_LIMIT = 10 +DEFAULT_UPLOAD = "rc" +STATUS_UPDATE_INTERVAL = 15 +FILELION_API = "" +STREAMWISH_API = "" +EXTENSION_FILTER = "" +INCOMPLETE_TASK_NOTIFIER = False +YT_DLP_OPTIONS = "" +USE_SERVICE_ACCOUNTS = False +NAME_SUBSTITUTE = "" +FFMPEG_CMDS = [] + +# GDrive Tools +GDRIVE_ID = "" +IS_TEAM_DRIVE = False +STOP_DUPLICATE = False +INDEX_URL = "" + +# Rclone +RCLONE_PATH = "" +RCLONE_FLAGS = "" +RCLONE_SERVE_URL = "" +RCLONE_SERVE_PORT = 0 +RCLONE_SERVE_USER = "" +RCLONE_SERVE_PASS = "" + +# Update +UPSTREAM_REPO = "https://github.com/AeonOrg/Aeon-MLTB" +UPSTREAM_BRANCH = "main" + +# Leech +LEECH_SPLIT_SIZE = 0 +AS_DOCUMENT = False +EQUAL_SPLITS = False +MEDIA_GROUP = False +USER_TRANSMISSION = False +MIXED_LEECH = False +LEECH_FILENAME_PREFIX = "" +LEECH_DUMP_CHAT = "" +THUMBNAIL_LAYOUT = "" + +# qBittorrent/Aria2c +TORRENT_TIMEOUT = 0 +BASE_URL = "" +BASE_URL_PORT = 0 +WEB_PINCODE = False + +# Queueing system +QUEUE_ALL = 0 +QUEUE_DOWNLOAD = 0 +QUEUE_UPLOAD = 0 + +# RSS +RSS_DELAY = 600 +RSS_CHAT = "" + +# Torrent Search +SEARCH_API_LINK = "" +SEARCH_LIMIT = 0 +SEARCH_PLUGINS = [ + "https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/piratebay.py", + "https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/limetorrents.py", + "https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/torlock.py", + "https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/torrentscsv.py", + "https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/eztv.py", + "https://raw.githubusercontent.com/qbittorrent/search-plugins/master/nova3/engines/torrentproject.py", + "https://raw.githubusercontent.com/MaurizioRicci/qBittorrent_search_engines/master/kickass_torrent.py", + "https://raw.githubusercontent.com/MaurizioRicci/qBittorrent_search_engines/master/yts_am.py", + "https://raw.githubusercontent.com/MadeOfMagicAndWires/qBit-plugins/master/engines/linuxtracker.py", + "https://raw.githubusercontent.com/MadeOfMagicAndWires/qBit-plugins/master/engines/nyaasi.py", + "https://raw.githubusercontent.com/LightDestory/qBittorrent-Search-Plugins/master/src/engines/ettv.py", + "https://raw.githubusercontent.com/LightDestory/qBittorrent-Search-Plugins/master/src/engines/glotorrents.py", + "https://raw.githubusercontent.com/LightDestory/qBittorrent-Search-Plugins/master/src/engines/thepiratebay.py", + "https://raw.githubusercontent.com/v1k45/1337x-qBittorrent-search-plugin/master/leetx.py", + "https://raw.githubusercontent.com/nindogo/qbtSearchScripts/master/magnetdl.py", + "https://raw.githubusercontent.com/msagca/qbittorrent_plugins/main/uniondht.py", + "https://raw.githubusercontent.com/khensolomon/leyts/master/yts.py", +] \ No newline at end of file diff --git a/sam_conf.py b/sam_conf.py deleted file mode 100644 index e69de29bb..000000000