mirror of
https://github.com/anasty17/mirror-leech-telegram-bot.git
synced 2025-01-08 12:07:33 +08:00
Ability to zip/unzip multi links in same directory. Mostly helpful in unziping tg file parts
- Revert media group only for parts. Signed-off-by: anasty17 <e.anastayyar@gmail.com>
This commit is contained in:
parent
e3e1965388
commit
2360113d5a
@ -25,7 +25,7 @@ In each single file there is a major change from base code, it's almost totaly d
|
||||
- 4GB file upload with premium account
|
||||
- Upload all files to specific superGroup/channel.
|
||||
- Leech Split size and equal split size settings for each user
|
||||
- Ability to leech files in media group. Setting for each user
|
||||
- Ability to leech splitted file parts in media group. Setting for each user
|
||||
### Google
|
||||
- Stop duplicates for all tasks except yt-dlp tasks
|
||||
- Download from Google Drive
|
||||
@ -73,13 +73,14 @@ In each single file there is a major change from base code, it's almost totaly d
|
||||
- Docker image support for linux `amd64, arm64/v8, arm/v7, s390x`
|
||||
- Edit variables and overwrite the private files while bot running
|
||||
- Update bot at startup and with restart command using `UPSTREAM_REPO`
|
||||
- Improve Telegraph. Based on [Sreeraj](https://github.com/SVR666) loaderX-bot.
|
||||
- Improve Telegraph. Based on [Sreeraj](https://github.com/SVR666) loaderX-bot
|
||||
- Mirror/Leech/Watch/Clone/Count/Del by reply
|
||||
- Mirror/Leech/Clone multi links/files with one command
|
||||
- Custom name for all links except torrents. For files you should add extension except yt-dlp links
|
||||
- Extensions Filter for the files to be uploaded/cloned
|
||||
- View Link button. Extra button to open index link in broswer instead of direct download for file
|
||||
- Queueing System
|
||||
- Ability to zip/unzip multi links in same directory. Mostly helpful in unziping tg file parts
|
||||
- Almost all repository functions have been improved and many other details can't mention all of them
|
||||
- Many bugs have been fixed
|
||||
|
||||
@ -182,7 +183,7 @@ Fill up rest of the fields. Meaning of each field is discussed below. **NOTE**:
|
||||
- `LEECH_SPLIT_SIZE`: Size of split in bytes. Default is `2GB`. Default is `4GB` if your account is premium. `Int`
|
||||
- `AS_DOCUMENT`: Default type of Telegram file upload. Default is `False` mean as media. `Bool`
|
||||
- `EQUAL_SPLITS`: Split files larger than **LEECH_SPLIT_SIZE** into equal parts size (Not working with zip cmd). Default is `False`. `Bool`
|
||||
- `MEDIA_GROUP`: View Uploaded files in media group. Default is `False`. `Bool`.**NOTE**: Some files will end without any reply, it's hard to manage. Maybe in future i will fix it.
|
||||
- `MEDIA_GROUP`: View Uploaded splitted file parts in media group. Default is `False`. `Bool`.
|
||||
- `LEECH_FILENAME_PREFIX`: Add custom word to leeched file name. `Str`
|
||||
- `DUMP_CHAT`: Chat ID. Upload files to specific chat. `str`. **NOTE**: Only available for superGroup/channel. Add `-100` before channel/superGroup id. In short don't add bot id or your id!
|
||||
- `USER_SESSION_STRING`: To download/upload from your telegram account. If you own premium account. To generate session string use this command `python3 generate_string_session.py` after mounting repo folder for sure. `Str`. **NOTE**: You can't use bot with private message. Use it with superGroup.
|
||||
@ -411,7 +412,7 @@ python3 gen_sa_accounts.py --download-keys $PROJECTID
|
||||
```
|
||||
>**NOTE:** 1 Service Account can upload/copy around 750 GB a day, 1 project can make 100 Service Accounts so you can upload 75 TB a day.
|
||||
|
||||
>**NOTE:** All people can copy `2TB/DAY` from each file creator (uploader account), so if you got error `userRateLimitExceeded` that doesn't your limit exceeded but but file creator limit have been exceeded which is `2TB/DAY`.
|
||||
>**NOTE:** All people can copy `2TB/DAY` from each file creator (uploader account), so if you got error `userRateLimitExceeded` that doesn't mean your limit exceeded but file creator limit have been exceeded which is `2TB/DAY`.
|
||||
|
||||
#### Two methods to create service accounts
|
||||
Choose one of these methods
|
||||
|
@ -202,7 +202,7 @@ def add_mega_download(mega_link, path, listener, name, from_queue=False):
|
||||
download_dict[listener.uid] = MegaDownloadStatus(mega_listener, listener)
|
||||
with queue_dict_lock:
|
||||
non_queued_dl.add(listener.uid)
|
||||
makedirs(path)
|
||||
makedirs(path, exist_ok=True)
|
||||
mega_listener.setValues(mname, size, gid)
|
||||
if not from_queue:
|
||||
listener.onDownloadStart()
|
||||
|
@ -171,6 +171,7 @@ def __stop_duplicate(client, tor):
|
||||
|
||||
@new_thread
|
||||
def __onDownloadComplete(client, tor):
|
||||
sleep(2)
|
||||
download = getDownloadByGid(tor.hash[:12])
|
||||
try:
|
||||
listener = download.listener()
|
||||
|
@ -717,7 +717,7 @@ class GoogleDriveHelper:
|
||||
if meta.get("mimeType") == self.__G_DRIVE_DIR_MIME_TYPE:
|
||||
self.__download_folder(file_id, self.__path, self.name)
|
||||
else:
|
||||
makedirs(self.__path)
|
||||
makedirs(self.__path, exist_ok=True)
|
||||
self.__download_file(file_id, self.__path, self.name, meta.get('mimeType'))
|
||||
except Exception as err:
|
||||
if isinstance(err, RetryError):
|
||||
|
@ -1,11 +1,12 @@
|
||||
from logging import getLogger, ERROR
|
||||
from os import remove as osremove, walk, path as ospath, rename as osrename
|
||||
from time import time, sleep
|
||||
from pyrogram.types import InputMediaVideo, InputMediaDocument, InputMediaAudio, InputMediaPhoto
|
||||
from pyrogram.types import InputMediaVideo, InputMediaDocument
|
||||
from pyrogram.errors import FloodWait, RPCError
|
||||
from PIL import Image
|
||||
from threading import RLock
|
||||
from tenacity import retry, wait_exponential, stop_after_attempt, retry_if_exception_type, RetryError
|
||||
from re import search as re_search
|
||||
|
||||
from bot import config_dict, user_data, GLOBAL_EXTENSION_FILTER, app
|
||||
from bot.helper.ext_utils.fs_utils import take_ss, get_media_info, get_media_streams, clean_unwanted
|
||||
@ -34,7 +35,8 @@ class TgUploader:
|
||||
self.__resource_lock = RLock()
|
||||
self.__is_corrupted = False
|
||||
self.__size = size
|
||||
self.__media_dict = {'videos': {}, 'documents': {}, 'audios': {}, 'photos': {}}
|
||||
self.__media_dict = {'videos': {}, 'documents': {}}
|
||||
self.__last_msg_in_group = False
|
||||
self.__msg_to_reply()
|
||||
self.__user_settings()
|
||||
|
||||
@ -55,22 +57,23 @@ class TgUploader:
|
||||
continue
|
||||
if self.__is_cancelled:
|
||||
return
|
||||
if self.__media_group:
|
||||
if self.__last_msg_in_group:
|
||||
group_lists = [x for v in self.__media_dict.values() for x in v.keys()]
|
||||
if dirpath not in group_lists:
|
||||
if (match := re_search(r'.+(?=\.0*\d+$)|.+(?=\.part\d+\..+)', up_path)) \
|
||||
and not match.group(0) in group_lists:
|
||||
for key, value in list(self.__media_dict.items()):
|
||||
for subkey, msgs in list(value.items()):
|
||||
if len(msgs) > 1:
|
||||
self.__send_media_group(subkey, key, msgs)
|
||||
self.__last_msg_in_group = False
|
||||
up_path, cap_mono = self.__prepare_file(up_path, file_, dirpath)
|
||||
self._last_uploaded = 0
|
||||
self.__upload_file(up_path, dirpath, cap_mono)
|
||||
if not self.__is_cancelled and \
|
||||
(not self.__listener.seed or self.__listener.newDir or dirpath.endswith("splited_files_mltb")):
|
||||
osremove(up_path)
|
||||
self.__upload_file(up_path, cap_mono)
|
||||
if self.__is_cancelled:
|
||||
return
|
||||
if (not self.__listener.isPrivate or config_dict['DUMP_CHAT']) and not self.__is_corrupted:
|
||||
if not self.__listener.seed or self.__listener.newDir or dirpath.endswith("splited_files_mltb"):
|
||||
osremove(up_path)
|
||||
if not self.__is_corrupted and (not self.__listener.isPrivate or config_dict['DUMP_CHAT']):
|
||||
self.__msgs_dict[self.__sent_msg.link] = file_
|
||||
sleep(1)
|
||||
except Exception as err:
|
||||
@ -109,7 +112,7 @@ class TgUploader:
|
||||
|
||||
@retry(wait=wait_exponential(multiplier=2, min=4, max=8), stop=stop_after_attempt(3),
|
||||
retry=retry_if_exception_type(Exception))
|
||||
def __upload_file(self, up_path, dirpath, cap_mono, force_document=False):
|
||||
def __upload_file(self, up_path, cap_mono, force_document=False):
|
||||
if self.__thumb is not None and not ospath.lexists(self.__thumb):
|
||||
self.__thumb = None
|
||||
thumb = self.__thumb
|
||||
@ -179,26 +182,32 @@ class TgUploader:
|
||||
caption=cap_mono,
|
||||
disable_notification=True,
|
||||
progress=self.__upload_progress)
|
||||
if self.__media_group and not self.__sent_msg.animation:
|
||||
if dirpath in self.__media_dict[key].keys():
|
||||
self.__media_dict[key][dirpath].append(self.__sent_msg)
|
||||
else:
|
||||
self.__media_dict[key][dirpath] = [self.__sent_msg]
|
||||
msgs = self.__media_dict[key][dirpath]
|
||||
if len(msgs) == 10:
|
||||
self.__send_media_group(dirpath, key, msgs)
|
||||
if not self.__is_cancelled and self.__media_group and (self.__sent_msg.video or self.__sent_msg.document):
|
||||
key = 'documents' if self.__sent_msg.document else 'videos'
|
||||
if match := re_search(r'.+(?=\.0*\d+$)|.+(?=\.part\d+\..+)', up_path):
|
||||
pname = match.group(0)
|
||||
if pname in self.__media_dict[key].keys():
|
||||
self.__media_dict[key][pname].append(self.__sent_msg)
|
||||
else:
|
||||
self.__media_dict[key][pname] = [self.__sent_msg]
|
||||
msgs = self.__media_dict[key][pname]
|
||||
if len(msgs) == 10:
|
||||
self.__send_media_group(pname, key, msgs)
|
||||
else:
|
||||
self.__last_msg_in_group = True
|
||||
except FloodWait as f:
|
||||
LOGGER.warning(str(f))
|
||||
sleep(f.value)
|
||||
except Exception as err:
|
||||
err_type = "RPCError: " if isinstance(err, RPCError) else ""
|
||||
LOGGER.error(f"{err_type}{err}. Path: {up_path}")
|
||||
if self.__thumb is None and thumb is not None and ospath.lexists(thumb):
|
||||
osremove(thumb)
|
||||
if 'Telegram says: [400' in str(err) and key != 'documents':
|
||||
LOGGER.error(f"Retrying As Document. Path: {up_path}")
|
||||
return self.__upload_file(up_path, dirpath, cap_mono, True)
|
||||
raise err
|
||||
finally:
|
||||
if self.__thumb is None and thumb is not None and ospath.lexists(thumb):
|
||||
osremove(thumb)
|
||||
|
||||
def __upload_progress(self, current, total):
|
||||
if self.__is_cancelled:
|
||||
@ -232,12 +241,8 @@ class TgUploader:
|
||||
for msg in self.__media_dict[key][subkey]:
|
||||
if key == 'videos':
|
||||
input_media = InputMediaVideo(media=msg.video.file_id, caption=msg.caption)
|
||||
elif key == 'documents':
|
||||
input_media = InputMediaDocument(media=msg.document.file_id, caption=msg.caption)
|
||||
elif key == 'photos':
|
||||
input_media = InputMediaPhoto(media=msg.photo.file_id, caption=msg.caption)
|
||||
else:
|
||||
input_media = InputMediaAudio(media=msg.audio.file_id, caption=msg.caption)
|
||||
input_media = InputMediaDocument(media=msg.document.file_id, caption=msg.caption)
|
||||
rlist.append(input_media)
|
||||
return rlist
|
||||
|
||||
|
@ -380,11 +380,16 @@ def get_buttons(key=None, edit_type=None):
|
||||
buttons.sbutton(int(x/10), f"botset start qbit {x}", position='footer')
|
||||
msg = f'Qbittorrent Options | Page: {int(START/10)} | State: {STATE}'
|
||||
elif edit_type == 'editvar':
|
||||
msg = ''
|
||||
buttons.sbutton('Back', "botset back var")
|
||||
if key not in ['TELEGRAM_HASH', 'TELEGRAM_API', 'OWNER_ID', 'BOT_TOKEN']:
|
||||
buttons.sbutton('Default', f"botset resetvar {key}")
|
||||
buttons.sbutton('Close', "botset close")
|
||||
msg = f'Send a valid value for {key}. Timeout: 60 sec'
|
||||
if key in ['SUDO_USERS', 'RSS_USER_SESSION_STRING', 'IGNORE_PENDING_REQUESTS', 'CMD_SUFFIX', 'OWNER_ID',
|
||||
'USER_SESSION_STRING', 'TELEGRAM_HASH', 'TELEGRAM_API', 'AUTHORIZED_CHATS', 'RSS_DELAY'
|
||||
'DATABASE_URL', 'BOT_TOKEN', 'DOWNLOAD_DIR']:
|
||||
msg += 'Restart required for this edit to take effect!\n\n'
|
||||
msg += f'Send a valid value for {key}. Timeout: 60 sec'
|
||||
elif edit_type == 'editaria':
|
||||
buttons.sbutton('Back', "botset back aria")
|
||||
if key != 'newkey':
|
||||
@ -717,12 +722,7 @@ def edit_bot_settings(update, context):
|
||||
update_buttons(message)
|
||||
dispatcher.remove_handler(file_handler)
|
||||
elif data[1] == 'editvar' and STATE == 'edit':
|
||||
if data[2] in ['SUDO_USERS', 'RSS_USER_SESSION_STRING', 'IGNORE_PENDING_REQUESTS', 'CMD_SUFFIX', 'OWNER_ID',
|
||||
'USER_SESSION_STRING', 'TELEGRAM_HASH', 'TELEGRAM_API', 'AUTHORIZED_CHATS', 'RSS_DELAY'
|
||||
'DATABASE_URL', 'BOT_TOKEN', 'DOWNLOAD_DIR']:
|
||||
query.answer(text='Restart required for this edit to take effect!', show_alert=True)
|
||||
else:
|
||||
query.answer()
|
||||
query.answer()
|
||||
if handler_dict.get(message.chat.id):
|
||||
handler_dict[message.chat.id] = False
|
||||
sleep(0.5)
|
||||
|
@ -1,9 +1,10 @@
|
||||
from requests import utils as rutils
|
||||
from re import search as re_search
|
||||
from time import sleep
|
||||
from os import path as ospath, remove as osremove, listdir, walk
|
||||
from os import path as ospath, remove as osremove, listdir, walk, rename, makedirs
|
||||
from subprocess import Popen
|
||||
from html import escape
|
||||
from shutil import move
|
||||
|
||||
from bot import Interval, aria2, DOWNLOAD_DIR, download_dict, download_dict_lock, LOGGER, DATABASE_URL, MAX_SPLIT_SIZE, config_dict, status_reply_dict_lock, user_data, non_queued_up, non_queued_dl, queued_up, queued_dl, queue_dict_lock
|
||||
from bot.helper.ext_utils.fs_utils import get_base_name, get_path_size, split_file, clean_download, clean_target
|
||||
@ -23,7 +24,7 @@ from bot.helper.ext_utils.db_handler import DbManger
|
||||
|
||||
|
||||
class MirrorLeechListener:
|
||||
def __init__(self, bot, message, isZip=False, extract=False, isQbit=False, isLeech=False, pswd=None, tag=None, select=False, seed=False):
|
||||
def __init__(self, bot, message, isZip=False, extract=False, isQbit=False, isLeech=False, pswd=None, tag=None, select=False, seed=False, sameDir=''):
|
||||
self.bot = bot
|
||||
self.message = message
|
||||
self.uid = message.message_id
|
||||
@ -40,6 +41,7 @@ class MirrorLeechListener:
|
||||
self.isPrivate = message.chat.type in ['private', 'group']
|
||||
self.suproc = None
|
||||
self.queuedUp = False
|
||||
self.sameDir = sameDir
|
||||
|
||||
def clean(self):
|
||||
try:
|
||||
@ -57,13 +59,28 @@ class MirrorLeechListener:
|
||||
|
||||
def onDownloadComplete(self):
|
||||
with download_dict_lock:
|
||||
if len(self.sameDir) > 1:
|
||||
LOGGER.info(self.sameDir)
|
||||
self.sameDir.remove(self.uid)
|
||||
LOGGER.info(self.sameDir)
|
||||
folder_name = listdir(self.dir)[-1]
|
||||
path = f"{self.dir}/{folder_name}"
|
||||
des_path = f"{DOWNLOAD_DIR}{list(self.sameDir)[0]}/{folder_name}"
|
||||
makedirs(des_path, exist_ok=True)
|
||||
for subdir in listdir(path):
|
||||
sub_path = f"{self.dir}/{folder_name}/{subdir}"
|
||||
if subdir in listdir(des_path):
|
||||
sub_path = rename(sub_path, f"{self.dir}/{folder_name}/1-{subdir}")
|
||||
move(sub_path, des_path)
|
||||
del download_dict[self.uid]
|
||||
return
|
||||
download = download_dict[self.uid]
|
||||
name = str(download.name()).replace('/', '')
|
||||
gid = download.gid()
|
||||
LOGGER.info(f"Download completed: {name}")
|
||||
if name == "None" or self.isQbit or not ospath.exists(f"{self.dir}/{name}"):
|
||||
name = listdir(self.dir)[-1]
|
||||
m_path = f'{self.dir}/{name}'
|
||||
m_path = f"{self.dir}/{name}"
|
||||
size = get_path_size(m_path)
|
||||
with queue_dict_lock:
|
||||
if self.uid in non_queued_dl:
|
||||
@ -324,6 +341,8 @@ class MirrorLeechListener:
|
||||
if self.uid in download_dict.keys():
|
||||
del download_dict[self.uid]
|
||||
count = len(download_dict)
|
||||
if self.uid in self.sameDir:
|
||||
self.sameDir.remove(self.uid)
|
||||
msg = f"{self.tag} your download has been stopped due to: {escape(error)}"
|
||||
sendMessage(msg, self.bot, self.message)
|
||||
if count == 0:
|
||||
@ -355,6 +374,8 @@ class MirrorLeechListener:
|
||||
if self.uid in download_dict.keys():
|
||||
del download_dict[self.uid]
|
||||
count = len(download_dict)
|
||||
if self.uid in self.sameDir:
|
||||
self.sameDir.remove(self.uid)
|
||||
sendMessage(f"{self.tag} {escape(error)}", self.bot, self.message)
|
||||
if count == 0:
|
||||
self.clean()
|
||||
|
@ -21,7 +21,7 @@ from bot.helper.telegram_helper.message_utils import sendMessage
|
||||
from .listener import MirrorLeechListener
|
||||
|
||||
|
||||
def _mirror_leech(bot, message, isZip=False, extract=False, isQbit=False, isLeech=False):
|
||||
def _mirror_leech(bot, message, isZip=False, extract=False, isQbit=False, isLeech=False, sameDir=''):
|
||||
if not isLeech and not config_dict['GDRIVE_ID']:
|
||||
sendMessage('GDRIVE_ID not Provided!', bot, message)
|
||||
return
|
||||
@ -34,9 +34,10 @@ def _mirror_leech(bot, message, isZip=False, extract=False, isQbit=False, isLeec
|
||||
seed = False
|
||||
multi = 0
|
||||
link = ''
|
||||
folder_name = ''
|
||||
|
||||
if len(message_args) > 1:
|
||||
args = mesg[0].split(maxsplit=3)
|
||||
args = mesg[0].split(maxsplit=4)
|
||||
for x in args:
|
||||
x = x.strip()
|
||||
if x in ['|', 'pswd:']:
|
||||
@ -57,12 +58,23 @@ def _mirror_leech(bot, message, isZip=False, extract=False, isQbit=False, isLeec
|
||||
elif x.isdigit():
|
||||
multi = int(x)
|
||||
mi = index
|
||||
elif x.startswith('m:'):
|
||||
marg = x.split('m:', 1)
|
||||
if len(marg) > 1:
|
||||
folder_name = f"/{marg[-1]}"
|
||||
if not sameDir:
|
||||
sameDir = set()
|
||||
sameDir.add(message.message_id)
|
||||
if multi == 0:
|
||||
message_args = mesg[0].split(maxsplit=index)
|
||||
if len(message_args) > index:
|
||||
link = message_args[index].strip()
|
||||
if link.startswith(("|", "pswd:")):
|
||||
link = ''
|
||||
if len(folder_name) > 0:
|
||||
seed = False
|
||||
ratio = None
|
||||
seed_time = None
|
||||
|
||||
def __run_multi():
|
||||
if multi > 1:
|
||||
@ -72,9 +84,13 @@ def _mirror_leech(bot, message, isZip=False, extract=False, isQbit=False, isLeec
|
||||
msg = message.text.split(maxsplit=mi+1)
|
||||
msg[mi] = f"{multi - 1}"
|
||||
nextmsg = sendMessage(" ".join(msg), bot, nextmsg)
|
||||
if len(folder_name) > 0:
|
||||
sameDir.add(nextmsg.message_id)
|
||||
nextmsg.from_user.id = message.from_user.id
|
||||
sleep(4)
|
||||
Thread(target=_mirror_leech, args=(bot, nextmsg, isZip, extract, isQbit, isLeech)).start()
|
||||
Thread(target=_mirror_leech, args=(bot, nextmsg, isZip, extract, isQbit, isLeech, sameDir)).start()
|
||||
|
||||
path = f'{DOWNLOAD_DIR}{message.message_id}{folder_name}'
|
||||
|
||||
name = mesg[0].split('|', maxsplit=1)
|
||||
if len(name) > 1:
|
||||
@ -113,8 +129,8 @@ def _mirror_leech(bot, message, isZip=False, extract=False, isQbit=False, isLeec
|
||||
elif isinstance(file_, list):
|
||||
link = file_[-1].get_file().file_path
|
||||
elif not isQbit and file_.mime_type != "application/x-bittorrent":
|
||||
listener = MirrorLeechListener(bot, message, isZip, extract, isQbit, isLeech, pswd, tag)
|
||||
Thread(target=TelegramDownloadHelper(listener).add_download, args=(message, f'{DOWNLOAD_DIR}{listener.uid}/', name)).start()
|
||||
listener = MirrorLeechListener(bot, message, isZip, extract, isQbit, isLeech, pswd, tag, sameDir=sameDir)
|
||||
Thread(target=TelegramDownloadHelper(listener).add_download, args=(message, f'{path}/', name)).start()
|
||||
__run_multi()
|
||||
return
|
||||
else:
|
||||
@ -145,6 +161,10 @@ Those options should be always before |newname or pswd:
|
||||
<code>/cmd</code> 10(number of links/files)
|
||||
Number should be always before |newname or pswd:
|
||||
|
||||
<b>Multi links within same upload directory only by replying to first link/file:</b>
|
||||
<code>/cmd</code> 10(number of links/files) m:folder_name
|
||||
Number and m:folder_name should be always before |newname or pswd:
|
||||
|
||||
<b>NOTES:</b>
|
||||
1. When use cmd by reply don't add any option in link msg! always add them after cmd msg!
|
||||
2. You can't add those options <b>|newname, pswd:</b> randomly. They should be arranged like exmaple above, rename then pswd. Those options should be after the link if link along with the cmd and after any other option
|
||||
@ -201,7 +221,7 @@ Number should be always before |newname or pswd:
|
||||
__run_multi()
|
||||
return
|
||||
|
||||
listener = MirrorLeechListener(bot, message, isZip, extract, isQbit, isLeech, pswd, tag, select, seed)
|
||||
listener = MirrorLeechListener(bot, message, isZip, extract, isQbit, isLeech, pswd, tag, select, seed, sameDir)
|
||||
|
||||
if is_gdrive_link(link):
|
||||
if not isZip and not extract and not isLeech:
|
||||
@ -210,11 +230,11 @@ Number should be always before |newname or pswd:
|
||||
gmsg += f"Use /{BotCommands.UnzipMirrorCommand[0]} to extracts Google Drive archive folder/file"
|
||||
sendMessage(gmsg, bot, message)
|
||||
else:
|
||||
Thread(target=add_gd_download, args=(link, f'{DOWNLOAD_DIR}{listener.uid}', listener, name)).start()
|
||||
Thread(target=add_gd_download, args=(link, path, listener, name)).start()
|
||||
elif is_mega_link(link):
|
||||
Thread(target=add_mega_download, args=(link, f'{DOWNLOAD_DIR}{listener.uid}/', listener, name)).start()
|
||||
Thread(target=add_mega_download, args=(link, f'{path}/', listener, name)).start()
|
||||
elif isQbit and (is_magnet(link) or ospath.exists(link)):
|
||||
Thread(target=add_qb_torrent, args=(link, f'{DOWNLOAD_DIR}{listener.uid}', listener,
|
||||
Thread(target=add_qb_torrent, args=(link, path, listener,
|
||||
ratio, seed_time)).start()
|
||||
else:
|
||||
if len(mesg) > 1:
|
||||
@ -227,7 +247,7 @@ Number should be always before |newname or pswd:
|
||||
auth = "Basic " + b64encode(auth.encode()).decode('ascii')
|
||||
else:
|
||||
auth = ''
|
||||
Thread(target=add_aria2c_download, args=(link, f'{DOWNLOAD_DIR}{listener.uid}', listener, name,
|
||||
Thread(target=add_aria2c_download, args=(link, path, listener, name,
|
||||
auth, ratio, seed_time)).start()
|
||||
__run_multi()
|
||||
|
||||
|
@ -44,10 +44,8 @@ def get_user_settings(from_user):
|
||||
MG = config_dict['MEDIA_GROUP']
|
||||
if not user_dict and MG or user_dict.get('media_group') or 'media_group' not in user_dict and MG:
|
||||
media_group = 'Enabled'
|
||||
buttons.sbutton("Disable Media Group", f"userset {user_id} mgroup")
|
||||
else:
|
||||
media_group = 'Disabled'
|
||||
buttons.sbutton("Enable Media Group", f"userset {user_id} mgroup")
|
||||
|
||||
buttons.sbutton("YT-DLP Quality", f"userset {user_id} ytq")
|
||||
YQ = config_dict['YT_DLP_QUALITY']
|
||||
@ -191,7 +189,7 @@ def edit_user_settings(update, context):
|
||||
handler_dict[user_id] = True
|
||||
buttons = ButtonMaker()
|
||||
buttons.sbutton("Back", f"userset {user_id} back")
|
||||
if user_dict.get('yt_ql'):
|
||||
if user_dict.get('yt_ql') or config_dict['YT_DLP_QUALITY']:
|
||||
buttons.sbutton("Remove YT-DLP Quality", f"userset {user_id} rytq", 'header')
|
||||
buttons.sbutton("Close", f"userset {user_id} close")
|
||||
rmsg = f'''
|
||||
@ -228,10 +226,16 @@ Check all available qualities options <a href="https://github.com/yt-dlp/yt-dlp#
|
||||
buttons = ButtonMaker()
|
||||
if user_dict.get('split_size'):
|
||||
buttons.sbutton("Reset Split Size", f"userset {user_id} rlss")
|
||||
if not user_dict and config_dict['EQUAL_SPLITS'] or user_dict.get('equal_splits'):
|
||||
ES = config_dict['EQUAL_SPLITS']
|
||||
if not user_dict and ES or user_dict.get('equal_splits') or 'equal_splits' not in user_dict and ES:
|
||||
buttons.sbutton("Disable Equal Splits", f"userset {user_id} esplits")
|
||||
else:
|
||||
buttons.sbutton("Enable Equal Splits", f"userset {user_id} esplits")
|
||||
MG = config_dict['MEDIA_GROUP']
|
||||
if not user_dict and MG or user_dict.get('media_group') or 'media_group' not in user_dict and MG:
|
||||
buttons.sbutton("Disable Media Group", f"userset {user_id} mgroup")
|
||||
else:
|
||||
buttons.sbutton("Enable Media Group", f"userset {user_id} mgroup")
|
||||
buttons.sbutton("Back", f"userset {user_id} back")
|
||||
buttons.sbutton("Close", f"userset {user_id} close")
|
||||
editMessage(f'Send Leech split size in bytes. IS_PREMIUM_USER: {IS_PREMIUM_USER}. Timeout: 60 sec', message, buttons.build_menu(1))
|
||||
@ -260,6 +264,7 @@ Check all available qualities options <a href="https://github.com/yt-dlp/yt-dlp#
|
||||
DbManger().update_user_data(user_id)
|
||||
elif data[2] == 'mgroup':
|
||||
query.answer()
|
||||
handler_dict[user_id] = False
|
||||
update_user_ldata(user_id, 'media_group', not bool(user_dict.get('media_group')))
|
||||
update_user_settings(message, query.from_user)
|
||||
if DATABASE_URL:
|
||||
|
@ -14,7 +14,7 @@ from .listener import MirrorLeechListener
|
||||
|
||||
listener_dict = {}
|
||||
|
||||
def _ytdl(bot, message, isZip=False, isLeech=False):
|
||||
def _ytdl(bot, message, isZip=False, isLeech=False, sameDir=''):
|
||||
if not isLeech and not config_dict['GDRIVE_ID']:
|
||||
sendMessage('GDRIVE_ID not Provided!', bot, message)
|
||||
return
|
||||
@ -26,6 +26,7 @@ def _ytdl(bot, message, isZip=False, isLeech=False):
|
||||
multi = 0
|
||||
index = 1
|
||||
link = ''
|
||||
folder_name = ''
|
||||
|
||||
args = mssg.split(maxsplit=2)
|
||||
if len(args) > 1:
|
||||
@ -39,6 +40,13 @@ def _ytdl(bot, message, isZip=False, isLeech=False):
|
||||
elif x.strip().isdigit():
|
||||
multi = int(x)
|
||||
mi = index
|
||||
elif x.startswith('m:'):
|
||||
marg = x.split('m:', 1)
|
||||
if len(marg) > 1:
|
||||
folder_name = f"/{marg[-1]}"
|
||||
if not sameDir:
|
||||
sameDir = set()
|
||||
sameDir.add(message.message_id)
|
||||
if multi == 0:
|
||||
args = mssg.split(maxsplit=index)
|
||||
if len(args) > index:
|
||||
@ -57,9 +65,13 @@ def _ytdl(bot, message, isZip=False, isLeech=False):
|
||||
ymsg = mssg.split(maxsplit=mi+1)
|
||||
ymsg[mi] = f"{multi - 1}"
|
||||
nextmsg = sendMessage(" ".join(ymsg), bot, nextmsg)
|
||||
if len(folder_name) > 0:
|
||||
sameDir.add(nextmsg.message_id)
|
||||
nextmsg.from_user.id = message.from_user.id
|
||||
sleep(4)
|
||||
Thread(target=_ytdl, args=(bot, nextmsg, isZip, isLeech)).start()
|
||||
Thread(target=_ytdl, args=(bot, nextmsg, isZip, isLeech, sameDir)).start()
|
||||
|
||||
path = f'{DOWNLOAD_DIR}{message.message_id}{folder_name}'
|
||||
|
||||
name = mssg.split('|', maxsplit=1)
|
||||
if len(name) > 1:
|
||||
@ -109,6 +121,10 @@ This option should be always before |newname, pswd: and opt:
|
||||
<code>/cmd</code> 10(number of links)
|
||||
Number should be always before |newname, pswd: and opt:
|
||||
|
||||
<b>Multi links within same upload directory only by replying to first link:</b>
|
||||
<code>/cmd</code> 10(number of links) m:folder_name
|
||||
Number and m:folder_name should be always before |newname, pswd: and opt:
|
||||
|
||||
<b>Options Note:</b> Add `^` before integer, some values must be integer 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.
|
||||
@ -123,7 +139,7 @@ Check all yt-dlp api options from this <a href='https://github.com/yt-dlp/yt-dlp
|
||||
"""
|
||||
return sendMessage(help_msg, bot, message)
|
||||
|
||||
listener = MirrorLeechListener(bot, message, isZip, isLeech=isLeech, pswd=pswd, tag=tag)
|
||||
listener = MirrorLeechListener(bot, message, isZip, isLeech=isLeech, pswd=pswd, tag=tag, sameDir=sameDir)
|
||||
ydl = YoutubeDLHelper(listener)
|
||||
try:
|
||||
result = ydl.extractMetaData(link, name, opt, True)
|
||||
@ -147,7 +163,7 @@ Check all yt-dlp api options from this <a href='https://github.com/yt-dlp/yt-dlp
|
||||
if qual:
|
||||
playlist = 'entries' in result
|
||||
LOGGER.info(f"Downloading with YT-DLP: {link}")
|
||||
Thread(target=ydl.add_download, args=(link, f'{DOWNLOAD_DIR}{msg_id}', name, qual, playlist, opt)).start()
|
||||
Thread(target=ydl.add_download, args=(link, path, name, qual, playlist, opt)).start()
|
||||
else:
|
||||
buttons = ButtonMaker()
|
||||
best_video = "bv*+ba/b"
|
||||
@ -168,7 +184,6 @@ Check all yt-dlp api options from this <a href='https://github.com/yt-dlp/yt-dlp
|
||||
buttons.sbutton("Best Audios", f"qu {msg_id} {best_audio} t")
|
||||
buttons.sbutton("Cancel", f"qu {msg_id} cancel")
|
||||
YTBUTTONS = buttons.build_menu(3)
|
||||
listener_dict[msg_id] = [listener, user_id, link, name, YTBUTTONS, opt, formats_dict]
|
||||
bmsg = sendMessage('Choose Playlist Videos Quality:', bot, message, YTBUTTONS)
|
||||
else:
|
||||
formats = result.get('formats')
|
||||
@ -222,9 +237,9 @@ Check all yt-dlp api options from this <a href='https://github.com/yt-dlp/yt-dlp
|
||||
buttons.sbutton("Best Audio", f"qu {msg_id} {best_audio}")
|
||||
buttons.sbutton("Cancel", f"qu {msg_id} cancel")
|
||||
YTBUTTONS = buttons.build_menu(2)
|
||||
listener_dict[msg_id] = [listener, user_id, link, name, YTBUTTONS, opt, formats_dict]
|
||||
bmsg = sendMessage('Choose Video Quality:', bot, message, YTBUTTONS)
|
||||
|
||||
listener_dict[msg_id] = [listener, user_id, link, name, YTBUTTONS, opt, formats_dict, path]
|
||||
Thread(target=_auto_cancel, args=(bmsg, msg_id)).start()
|
||||
|
||||
__run_multi()
|
||||
@ -294,6 +309,7 @@ def select_format(update, context):
|
||||
name = task_info[3]
|
||||
opt = task_info[5]
|
||||
qual = data[2]
|
||||
path = task_info[7]
|
||||
if len(data) == 4:
|
||||
playlist = True
|
||||
if '|' in qual:
|
||||
@ -305,7 +321,7 @@ def select_format(update, context):
|
||||
qual = task_info[6][b_name][tbr][1]
|
||||
ydl = YoutubeDLHelper(listener)
|
||||
LOGGER.info(f"Downloading with YT-DLP: {link}")
|
||||
Thread(target=ydl.add_download, args=(link, f'{DOWNLOAD_DIR}{task_id}', name, qual, playlist, opt)).start()
|
||||
Thread(target=ydl.add_download, args=(link, path, name, qual, playlist, opt)).start()
|
||||
query.message.delete()
|
||||
del listener_dict[task_id]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user