diff --git a/README.md b/README.md
index 53a406581915..d52558a56cab 100644
--- a/README.md
+++ b/README.md
@@ -27,9 +27,10 @@ programming in Python.
## Rclone
- - Rclone transfer (download/upload/clone-server-side) without or with random service accounts (global and user option)
- - Ability to choose config, remote and path from list with buttons (global, user and task option)
- - Ability to set rclone flags for each task or globally from config (global, user and task option)
+ - Transfer (download/upload/clone-server-side) without or with random service accounts (global and user option)
+ - Ability to choose config, remote and path from list with or without buttons (global, user and task option)
+ - Ability to set flags for each task or globally from config (global, user and task option)
+ - Abitity to select specific files or folders to download/copy using buttons (task option)
- Rclone.conf (global and user option)
- Rclone serve for combine remote to use it as index from all remotes (global option)
- Upload destination (global, user and task option)
@@ -378,13 +379,13 @@ programming in Python.
1. Seed will get disbaled while using this option
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
+ - 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`
diff --git a/bot/__main__.py b/bot/__main__.py
index 0ba07039ac24..5ef6a04a2b18 100644
--- a/bot/__main__.py
+++ b/bot/__main__.py
@@ -192,7 +192,7 @@ async def log(_, message):
/{BotCommands.RmSudoCommand}: Remove sudo users (Only Owner).
Maintainance:
-/{BotCommands.RestartCommand}: Restart and update the bot (Only Owner & Sudo).
+/{BotCommands.RestartCommand[0]}: Restart and update the bot (Only Owner & Sudo).
/{BotCommands.LogCommand}: Get a log file of the bot. Handy for getting crash reports (Only Owner & Sudo).
/{BotCommands.ShellCommand}: Run shell commands (Only Owner).
/{BotCommands.AExecCommand}: Exec async functions (Only Owner).
diff --git a/bot/helper/ext_utils/media_utils.py b/bot/helper/ext_utils/media_utils.py
index b03a864bd3eb..ae2787bf4ede 100644
--- a/bot/helper/ext_utils/media_utils.py
+++ b/bot/helper/ext_utils/media_utils.py
@@ -162,7 +162,7 @@ async def create_thumb(msg, _id=""):
_id = msg.id
path = f"{DOWNLOAD_DIR}Thumbnails"
else:
- path = 'Thumbnails'
+ path = "Thumbnails"
await makedirs(
path,
exist_ok=True
@@ -184,6 +184,7 @@ async def create_thumb(msg, _id=""):
await remove(photo_dir)
return output
+
global_streams = {}
async def is_multi_streams(path):
try:
diff --git a/bot/helper/listeners/jdownloader_listener.py b/bot/helper/listeners/jdownloader_listener.py
index 0122d6fd2483..9211c0d84871 100644
--- a/bot/helper/listeners/jdownloader_listener.py
+++ b/bot/helper/listeners/jdownloader_listener.py
@@ -116,22 +116,21 @@ async def _jd_listener():
k,
v
) in list(jd_downloads.items()):
- if (
- v["status"] == "down" and
- k not in all_packages
- ):
- cdi = jd_downloads[k]["ids"]
- if len(cdi) > 1:
- await update_download(k, v)
+ if v["status"] == "down":
+ if k in all_packages:
+ for (
+ index,
+ pid
+ ) in enumerate(v["ids"]):
+ if pid not in all_packages:
+ del jd_downloads[k]["ids"][index]
+
else:
- await remove_download(k)
- else:
- for (
- index,
- pid
- ) in enumerate(v["ids"]):
- if pid not in all_packages:
- del jd_downloads[k]["ids"][index]
+ cdi = jd_downloads[k]["ids"]
+ if len(cdi) > 1:
+ await update_download(k, v)
+ else:
+ await remove_download(k)
for gid in finished:
if (
diff --git a/bot/helper/task_utils/download_utils/jd_download.py b/bot/helper/task_utils/download_utils/jd_download.py
index e1e8a6341e62..05e540a62b98 100644
--- a/bot/helper/task_utils/download_utils/jd_download.py
+++ b/bot/helper/task_utils/download_utils/jd_download.py
@@ -323,8 +323,7 @@ async def add_jd_download(listener, path):
jdownloader.device.linkgrabber.remove_links,
package_ids=packages_to_remove,
)
- async with jd_lock:
- del jd_downloads[gid]
+ del jd_downloads[gid]
return
jd_downloads[gid]["ids"] = online_packages
@@ -385,18 +384,43 @@ async def add_jd_download(listener, path):
)
return
- if (
- listener.select and
- await JDownloaderHelper(listener).wait_for_configurations()
- ):
- await retry_function(
- jdownloader.device.linkgrabber.remove_links,
- package_ids=online_packages,
- )
- listener.remove_from_same_dir()
- return
+ if listener.select:
+ if await JDownloaderHelper(listener).wait_for_configurations():
+ await retry_function(
+ jdownloader.device.linkgrabber.remove_links,
+ package_ids=online_packages,
+ )
+ listener.remove_from_same_dir()
+ return
+ else:
+ queued_downloads = await retry_function(
+ jdownloader.device.linkgrabber.query_packages,
+ [{"saveTo": True}]
+ )
+ updated_packages = [
+ qd["uuid"]
+ for qd
+ in queued_downloads
+ if qd["saveTo"].startswith(path)
+ ]
+ async with jd_lock:
+ online_packages = [
+ pack
+ for pack
+ in online_packages
+ if pack
+ in updated_packages
+ ]
+ if gid not in online_packages:
+ del jd_downloads[gid]
+ gid = online_packages[0]
+ jd_downloads[gid] = {"status": "collect"}
+ jd_downloads[gid]["ids"] = online_packages
- add_to_queue, event = await check_running_tasks(listener)
+ (
+ add_to_queue,
+ event
+ ) = await check_running_tasks(listener)
if add_to_queue:
LOGGER.info(f"Added to Queue/Download: {listener.name}")
async with task_dict_lock:
@@ -406,9 +430,11 @@ async def add_jd_download(listener, path):
"dl"
)
await listener.on_download_start()
+
if listener.multi <= 1:
await send_status_message(listener.message)
await event.wait() # type: ignore
+
if listener.is_cancelled:
return
async with queue_dict_lock:
diff --git a/bot/helper/task_utils/download_utils/rclone_download.py b/bot/helper/task_utils/download_utils/rclone_download.py
index ed8e71fbefa5..3f449e07d64b 100644
--- a/bot/helper/task_utils/download_utils/rclone_download.py
+++ b/bot/helper/task_utils/download_utils/rclone_download.py
@@ -1,6 +1,7 @@
from asyncio import gather
from json import loads
from secrets import token_urlsafe
+from aiofiles.os import remove
from bot import (
task_dict,
@@ -42,6 +43,13 @@ async def add_rclone_download(listener, path):
listener.link
) = listener.link.split(":", 1)
listener.link = listener.link.strip("/")
+ rclone_select = False
+
+ if listener.link.startswith("rclone_select"):
+ rclone_select = True
+ rpath = ""
+ else:
+ rpath = listener.link
cmd1 = [
"rclone",
@@ -52,7 +60,7 @@ async def add_rclone_download(listener, path):
"--no-modtime",
"--config",
config_path,
- f"{remote}:{listener.link}",
+ f"{remote}:{rpath}",
]
cmd2 = [
"rclone",
@@ -61,68 +69,98 @@ async def add_rclone_download(listener, path):
"--json",
"--config",
config_path,
- f"{remote}:{listener.link}",
+ f"{remote}:{rpath}",
]
- res1, res2 = await gather(
- cmd_exec(cmd1),
- cmd_exec(cmd2)
- )
- if res1[2] != res2[2] != 0:
- if res1[2] != -9:
- err = (
- res1[1]
- or res2[1]
- 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.on_download_error(msg)
- return
- try:
- rstat = loads(res1[0])
- rsize = loads(res2[0])
- except Exception as err:
- if not str(err):
- err = "Use /shell cat rlog.txt
to see more information"
- await listener.on_download_error(f"RcloneDownload JsonLoad: {err}")
- return
- if rstat["IsDir"]:
+ if rclone_select:
+ cmd2.extend(("--files-from", listener.link))
+ res = await cmd_exec(cmd2)
+ if res[2] != 0:
+ if res[2] != -9:
+ err = (res[1]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.on_download_error(msg)
+ return
+ try:
+ rsize = loads(res[0])
+ except Exception as err:
+ if not str(err):
+ err = "Use /shell cat rlog.txt
to see more information"
+ await listener.on_download_error(f"RcloneDownload JsonLoad: {err}")
+ return
if not listener.name:
- listener.name = (
- listener.link.rsplit("/", 1)[-1]
- if listener.link
- else remote
- )
+ listener.name = listener.link
path += listener.name
else:
- listener.name = listener.link.rsplit(
- "/",
- 1
- )[-1]
+ (
+ res1,
+ res2
+ ) = await gather(
+ cmd_exec(cmd1),
+ cmd_exec(cmd2)
+ )
+ if res1[2] != res2[2] != 0:
+ if res1[2] != -9:
+ err = (
+ res1[1]
+ or res2[1]
+ 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.on_download_error(msg)
+ return
+ try:
+ rstat = loads(res1[0])
+ rsize = loads(res2[0])
+ except Exception as err:
+ if not str(err):
+ err = "Use /shell cat rlog.txt
to see more information"
+ await listener.on_download_error(f"RcloneDownload JsonLoad: {err}")
+ return
+ if rstat["IsDir"]:
+ if not listener.name:
+ listener.name = (
+ listener.link.rsplit(
+ "/",
+ 1
+ )[-1]
+ if listener.link
+ else remote
+ )
+ path += listener.name
+ else:
+ listener.name = listener.link.rsplit(
+ "/",
+ 1
+ )[-1]
listener.size = rsize["bytes"]
gid = token_urlsafe(12)
- (
- msg,
- button
- ) = await stop_duplicate_check(listener)
- if msg:
- await listener.on_download_error(
+ if not rclone_select:
+ (
msg,
button
- )
- return
- 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 send_message(
- listener.message,
- limit_exceeded
- )
- await delete_links(listener.message)
- await auto_delete_message(
- listener.message,
- rmsg
- )
- return
+ ) = await stop_duplicate_check(listener)
+ if msg:
+ await listener.on_download_error(
+ msg,
+ button
+ )
+ return
+ 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 send_message(
+ listener.message,
+ limit_exceeded
+ )
+ await delete_links(listener.message)
+ await auto_delete_message(
+ listener.message,
+ rmsg
+ )
+ return
(
add_to_queue,
@@ -162,8 +200,10 @@ async def add_rclone_download(listener, path):
await send_status_message(listener.message)
LOGGER.info(f"Download with rclone: {listener.link}")
- await RCTransfer.download(
+ await RCTransfer.download( # type: ignore
remote,
config_path,
path
)
+ if rclone_select:
+ await remove(listener.link)
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 fec4a8da4e6b..8d9b7c942436 100644
--- a/bot/helper/task_utils/download_utils/yt_dlp_download.py
+++ b/bot/helper/task_utils/download_utils/yt_dlp_download.py
@@ -329,6 +329,11 @@ async def add_download(self, path, qual, playlist, options):
"default": f"{path}/{self._listener.name}/%(title,fulltitle,alt_title)s%(season_number& |)s%(season_number&S|)s%(season_number|)02d%(episode_number&E|)s%(episode_number|)02d%(height& |)s%(height|)s%(height&p|)s%(fps|)s%(fps&fps|)s%(tbr& |)s%(tbr|)d.%(ext)s",
"thumbnail": f"{path}/yt-dlp-thumb/%(title,fulltitle,alt_title)s%(season_number& |)s%(season_number&S|)s%(season_number|)02d%(episode_number&E|)s%(episode_number|)02d%(height& |)s%(height|)s%(height&p|)s%(fps|)s%(fps&fps|)s%(tbr& |)s%(tbr|)d.%(ext)s",
}
+ elif "download_ranges" in options:
+ self.opts["outtmpl"] = {
+ "default": f"{path}/{base_name}/%(section_number|)s%(section_number&.|)s%(section_title|)s%(section_title&-|)s%(title,fulltitle,alt_title)s %(section_start)s to %(section_end)s.%(ext)s",
+ "thumbnail": f"{path}/yt-dlp-thumb/%(section_number|)s%(section_number&.|)s%(section_title|)s%(section_title&-|)s%(title,fulltitle,alt_title)s %(section_start)s to %(section_end)s.%(ext)s",
+ }
elif any(
key in options
for key in [
diff --git a/bot/helper/task_utils/gdrive_utils/list.py b/bot/helper/task_utils/gdrive_utils/list.py
index 6cfbd6cd797b..6b1d4a7d36d4 100644
--- a/bot/helper/task_utils/gdrive_utils/list.py
+++ b/bot/helper/task_utils/gdrive_utils/list.py
@@ -92,6 +92,7 @@ async def id_updates(_, query, obj):
obj.event.set()
elif data[1] == "ps":
if obj.page_step == int(data[2]):
+ obj.query_proc = False
return
obj.page_step = int(data[2])
await obj.get_items_buttons()
diff --git a/bot/helper/task_utils/rclone_utils/list.py b/bot/helper/task_utils/rclone_utils/list.py
index ee1bb1a7cb2a..071ab531204b 100644
--- a/bot/helper/task_utils/rclone_utils/list.py
+++ b/bot/helper/task_utils/rclone_utils/list.py
@@ -63,6 +63,9 @@ async def path_updates(_, query, obj):
elif data[1] == "nex":
obj.iter_start += LIST_LIMIT * obj.page_step
await obj.get_path_buttons()
+ elif data[1] == "select":
+ obj.select = not obj.select
+ await obj.get_path_buttons()
elif data[1] == "back":
if data[2] == "re":
await obj.list_config()
@@ -73,8 +76,31 @@ async def path_updates(_, query, obj):
data = query.data.split(maxsplit=2)
obj.remote = data[2]
await obj.get_path()
+ elif data[1] == "clear":
+ obj.selected_pathes = set()
+ await obj.get_path_buttons()
+ elif data[1] == "ds":
+ obj.path = f"rclone_select_{time()}.txt"
+ async with aiopen(obj.path, "w") as txt_file:
+ for f in obj.selected_pathes:
+ await txt_file.write(f"{f}\n")
+ await delete_message(message)
+ obj.event.set()
elif data[1] == "pa":
index = int(data[3])
+ if obj.select:
+ path = obj.path + (
+ f"/{obj.path_list[index]['Path']}"
+ if obj.path
+ else obj.path_list[index]["Path"]
+ )
+ if path in obj.selected_pathes:
+ obj.selected_pathes.remove(path)
+ else:
+ obj.selected_pathes.add(path)
+ await obj.get_path_buttons()
+ obj.query_proc = False
+ return
obj.path += (
f"/{obj.path_list[index]['Path']}"
if obj.path
@@ -87,6 +113,7 @@ async def path_updates(_, query, obj):
obj.event.set()
elif data[1] == "ps":
if obj.page_step == int(data[2]):
+ obj.query_proc = False
return
obj.page_step = int(data[2])
await obj.get_path_buttons()
@@ -151,6 +178,8 @@ def __init__(
self.path_list = []
self.iter_start = 0
self.page_step = 1
+ self.select = False
+ self.selected_pathes = set()
@loop_thread
async def _event_handler(self):
@@ -214,12 +243,16 @@ async def get_path_buttons(self):
self.path_list[self.iter_start : LIST_LIMIT + self.iter_start]
):
orig_index = index + self.iter_start
+ name = idict["Path"]
+ if name in self.selected_pathes or any(
+ p.endswith(f"/{name}") for p in self.selected_pathes
+ ):
+ name = f"✅ {name}"
if idict["IsDir"]:
ptype = "fo"
- name = idict["Path"]
else:
ptype = "fi"
- name = f"[{get_readable_file_size(idict['Size'])}] {idict['Path']}"
+ name = f"[{get_readable_file_size(idict['Size'])}] {name}"
buttons.data_button(
name,
f"rcq pa {ptype} {orig_index}"
@@ -272,6 +305,23 @@ async def get_path_buttons(self):
"rcq cur",
position="footer"
)
+ if self.list_status == "rcd":
+ buttons.data_button(
+ f"Select: {'Enabled' if self.select else 'Disabled'}",
+ "rcq select",
+ position="footer",
+ )
+ if len(self.selected_pathes) > 1:
+ buttons.data_button(
+ "Done With Selection",
+ "rcq ds",
+ position="footer"
+ )
+ buttons.data_button(
+ "Clear Selection",
+ "rcq clear",
+ position="footer"
+ )
if self.list_status == "rcu":
buttons.data_button(
"Set as Default Path",
diff --git a/bot/helper/task_utils/rclone_utils/transfer.py b/bot/helper/task_utils/rclone_utils/transfer.py
index 2cfbe26d5f2f..b0d018a7b046 100644
--- a/bot/helper/task_utils/rclone_utils/transfer.py
+++ b/bot/helper/task_utils/rclone_utils/transfer.py
@@ -44,6 +44,7 @@ def __init__(self, listener):
self._sa_index = 0
self._sa_number = 0
self._use_service_accounts = config_dict["USE_SERVICE_ACCOUNTS"]
+ self.rclone_select = False
@property
def transferred_size(self):
@@ -152,7 +153,10 @@ async def _start_download(self, cmd, remote_type):
if return_code == 0:
await self._listener.on_download_complete()
elif return_code != -9:
- error = (await self._proc.stderr.read()).decode().strip() # type: ignore
+ error = (
+ (await self._proc.stderr.read()).decode().strip() # type: ignore
+ or "Use /shell cat rlog.txt
to see more information"
+ )
if (
not error
and remote_type == "drive"
@@ -321,7 +325,10 @@ async def _start_upload(self, cmd, remote_type):
if return_code == -9:
return False
elif return_code != 0:
- error = (await self._proc.stderr.read()).decode().strip() # type: ignore
+ error = (
+ (await self._proc.stderr.read()).decode().strip() # type: ignore
+ or "Use /shell cat rlog.txt
to see more information"
+ )
if (
not error
and remote_type == "drive"
@@ -687,7 +694,11 @@ def _get_updated_command(
):
if unwanted_files is None:
unwanted_files = []
- ext = "*.{" + ",".join(self._listener.extension_filter) + "}"
+ if source.split(":")[-1].startswith("rclone_select"):
+ source = f"{source.split(":")[0]}:"
+ self.rclone_select = True
+ else:
+ ext = "*.{" + ",".join(self._listener.extension_filter) + "}"
cmd = [
"rclone",
method,
@@ -697,8 +708,6 @@ def _get_updated_command(
"-P",
source,
destination,
- "--exclude",
- ext,
"--retries-sleep",
"3s",
"--ignore-case",
@@ -710,10 +719,17 @@ def _get_updated_command(
"--log-level",
"DEBUG",
]
- if rcflags := (
- self._listener.rc_flags
- or config_dict["RCLONE_FLAGS"]
- ):
+ if self.rclone_select:
+ cmd.extend((
+ "--files-from",
+ self._listener.link
+ ))
+ else:
+ cmd.extend((
+ "--exclude",
+ ext
+ ))
+ if rcflags := self._listener.rc_flags or config_dict["RCLONE_FLAGS"]:
rcflags = rcflags.split("|")
for flag in rcflags:
if ":" in flag:
diff --git a/bot/helper/task_utils/status_utils/jdownloader_status.py b/bot/helper/task_utils/status_utils/jdownloader_status.py
index 43ed2724bc73..06cb4b6239f9 100644
--- a/bot/helper/task_utils/status_utils/jdownloader_status.py
+++ b/bot/helper/task_utils/status_utils/jdownloader_status.py
@@ -42,8 +42,8 @@ def _get_combined_info(result):
"speed",
0
)
- if not status:
- status = "UnknownError"
+ if len(status) == 0:
+ status = "UnknownError Check Web Interface"
try:
eta = (bytesTotal - bytesLoaded) / speed
except:
@@ -164,6 +164,8 @@ def status(self):
"status",
"jdlimit"
)
+ if len(state) == 0:
+ return "UnknownError Check Web Interface"
return (
MirrorStatus.STATUS_QUEUEDL
if state == "jdlimit"
diff --git a/bot/helper/telegram_helper/bot_commands.py b/bot/helper/telegram_helper/bot_commands.py
index 60fe3482c810..7e495fd409ea 100644
--- a/bot/helper/telegram_helper/bot_commands.py
+++ b/bot/helper/telegram_helper/bot_commands.py
@@ -71,7 +71,11 @@ def __init__(self):
f"ping{CMD_SUFFIX}",
"p",
]
- self.RestartCommand = f"restart{CMD_SUFFIX}"
+ self.RestartCommand = [
+ f"restart{CMD_SUFFIX}",
+ f"r{CMD_SUFFIX}",
+ "rall"
+ ]
self.StatsCommand = [
f"stats{CMD_SUFFIX}",
"s",
diff --git a/bot/modules/bot_settings.py b/bot/modules/bot_settings.py
index 17e2173cf169..0a97020bd29c 100644
--- a/bot/modules/bot_settings.py
+++ b/bot/modules/bot_settings.py
@@ -1484,7 +1484,7 @@ async def edit_bot_settings(client, query):
query
):
value = "Only owner can view this!"
- if len(value) > 500:
+ if len(value) > 200:
await query.answer()
with BytesIO(str.encode(value)) as out_file:
out_file.name = f"{data[2]}.txt"
diff --git a/bot/modules/clone.py b/bot/modules/clone.py
index f01539f4dbdf..fa0272c5dd07 100644
--- a/bot/modules/clone.py
+++ b/bot/modules/clone.py
@@ -3,6 +3,7 @@
from nekozee.filters import command
from nekozee.handlers import MessageHandler
from secrets import token_urlsafe
+from aiofiles.os import remove
from bot import (
LOGGER,
@@ -85,6 +86,7 @@ async def new_event(self):
"link": "",
"-m": 0,
"-b": False,
+ "-n": "",
"-up": "",
"-rcf": "",
"-sync": False,
@@ -103,6 +105,7 @@ async def new_event(self):
self.up_dest = args["-up"]
self.rc_flags = args["-rcf"]
self.link = args["link"]
+ self.name = args["-n"]
is_bulk = args["-b"]
sync = args["-sync"]
@@ -304,51 +307,62 @@ async def _proceed_to_clone(self, sync):
remote,
src_path
) = self.link.split(":", 1)
- src_path = src_path.strip("/")
-
- cmd = [
- "rclone",
- "lsjson",
- "--fast-list",
- "--stat",
- "--no-modtime",
- "--config",
- config_path,
- f"{remote}:{src_path}",
- ]
- res = await cmd_exec(cmd)
- 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 send_message(
- self.message,
- msg
- )
- await auto_delete_message(
- self.message,
- smsg
- )
- return
- rstat = loads(res[0])
- if rstat["IsDir"]:
- self.name = (
- src_path.rsplit("/", 1)[-1]
- if src_path
- else remote
- )
- self.up_dest += (
- self.name
- if self.up_dest.endswith(":")
- else f"/{self.name}"
- )
-
+ self.link = src_path.strip("/")
+ if self.link.startswith("rclone_select"):
mime_type = "Folder"
+ src_path = ""
+ if not self.name:
+ self.name = self.link
else:
- self.name = src_path.rsplit(
- "/",
- 1
- )[-1]
- mime_type = rstat["MimeType"]
+ src_path = self.link
+ cmd = [
+ "rclone",
+ "lsjson",
+ "--fast-list",
+ "--stat",
+ "--no-modtime",
+ "--config",
+ config_path,
+ f"{remote}:{src_path}",
+ ]
+ res = await cmd_exec(cmd)
+ 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 send_message(
+ self.message,
+ msg
+ )
+ await auto_delete_message(
+ self.message,
+ smsg
+ )
+ return
+ rstat = loads(res[0])
+ if rstat["IsDir"]:
+ if not self.name:
+ self.name = (
+ src_path.rsplit(
+ "/",
+ 1
+ )[-1]
+ if src_path
+ else remote
+ )
+ self.up_dest += (
+ self.name
+ if self.up_dest.endswith(":")
+ else f"/{self.name}"
+ )
+
+ mime_type = "Folder"
+ else:
+ if not self.name:
+ self.name = src_path.rsplit(
+ "/",
+ 1
+ )[-1]
+ mime_type = rstat["MimeType"]
await self.on_download_start()
@@ -371,13 +385,18 @@ async def _proceed_to_clone(self, sync):
if sync
else "copy"
)
- flink, destination = await RCTransfer.clone(
+ (
+ flink,
+ destination
+ ) = await RCTransfer.clone(
config_path,
remote,
src_path,
mime_type,
method,
) # type: ignore
+ if self.link.startswith("rclone_select"):
+ await remove(self.link)
if not destination:
return
LOGGER.info(f"Cloning Done: {self.name}")
diff --git a/bot/modules/users_settings.py b/bot/modules/users_settings.py
index 483e11ced33c..28e196c925ee 100644
--- a/bot/modules/users_settings.py
+++ b/bot/modules/users_settings.py
@@ -414,8 +414,12 @@ async def get_user_settings(from_user):
)
+@new_task
async def update_user_settings(query):
- msg, button = await get_user_settings(query.from_user)
+ (
+ msg,
+ button
+ ) = await get_user_settings(query.from_user)
user_id = query.from_user.id
media = (
f"Thumbnails/{user_id}.jpg"
@@ -441,7 +445,10 @@ async def user_settings(client, message):
if not from_user:
from_user = await anno_checker(message)
user_id = from_user.id
- msg, button = await get_user_settings(from_user)
+ (
+ msg,
+ button
+ ) = await get_user_settings(from_user)
media = (
f"Thumbnails/{user_id}.jpg"
if os_path.exists(f"Thumbnails/{user_id}.jpg")
@@ -783,7 +790,10 @@ async def edit_user_settings(client, query):
False
):
lprefix = user_dict["lprefix"]
- elif "lprefix" not in user_dict and config_dict["LEECH_FILENAME_PREFIX"]:
+ elif (
+ "lprefix" not in user_dict
+ and config_dict["LEECH_FILENAME_PREFIX"]
+ ):
lprefix = config_dict["LEECH_FILENAME_PREFIX"]
else:
lprefix = "None"
@@ -1231,8 +1241,10 @@ async def edit_user_settings(client, query):
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"
+ sp_msg = (
+ "Send Leech split size.\nDon't add unit(MB, GB), default unit is GB\n"
+ "\nExamples:\nSend 4 for 4GB\nor 0.5 for 512MB\n\nTimeout: 60 sec"
+ )
await edit_message(
message,
sp_msg,
@@ -1777,7 +1789,7 @@ async def edit_user_settings(client, query):
)
await edit_message(
message,
- "Send thumbnail layout as Width x Height (2x2, 3x3, 2x4, 4x4) etc.\n\nTimeout: 60 sec",
+ "Send thumbnail layout as WIDTH x HEIGHT (2x2, 3x3, 2x4, 4x4) etc.\n\nTimeout: 60 sec",
buttons.build_menu(1),
)
try: