diff --git a/Dockerfile b/Dockerfile
index 5ef3fce..2537f0e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -5,7 +5,8 @@ RUN chmod 777 /usr/src/app
RUN apt-get -qq update && \
DEBIAN_FRONTEND="noninteractive" apt-get -qq install -y tzdata aria2 git python3 python3-pip \
locales python3-lxml \
- curl pv jq ffmpeg
+ curl pv jq ffmpeg \
+ p7zip-full p7zip-rar
COPY requirements.txt .
RUN pip3 install --no-cache-dir -r requirements.txt && \
apt-get -qq purge git
diff --git a/bot/__init__.py b/bot/__init__.py
index 1f5cf40..3097979 100644
--- a/bot/__init__.py
+++ b/bot/__init__.py
@@ -54,7 +54,7 @@ status_reply_dict_lock = threading.Lock()
# Value: telegram.Message
status_reply_dict = {}
# Key: update.message.message_id
-# Value: An object of DownloadStatus
+# Value: An object of Status
download_dict = {}
# Stores list of users and chats the bot is authorized to use in
AUTHORIZED_CHATS = set()
diff --git a/bot/__main__.py b/bot/__main__.py
index 4140a3b..bc432bb 100644
--- a/bot/__main__.py
+++ b/bot/__main__.py
@@ -1,9 +1,10 @@
-import shutil
+import shutil, psutil
import signal
import pickle
from os import execl, path, remove
from sys import executable
+import time
from telegram.ext import CommandHandler, run_async
from bot import dispatcher, updater, botStartTime
@@ -22,17 +23,24 @@ def stats(update, context):
total = get_readable_file_size(total)
used = get_readable_file_size(used)
free = get_readable_file_size(free)
+ cpuUsage = psutil.cpu_percent(interval=0.5)
+ memory = psutil.virtual_memory().percent
stats = f'Bot Uptime: {currentTime}\n' \
f'Total disk space: {total}\n' \
f'Used: {used}\n' \
- f'Free: {free}'
+ f'Free: {free}\n' \
+ f'CPU: {cpuUsage}%\n' \
+ f'RAM: {memory}%'
sendMessage(stats, context.bot, update)
@run_async
def start(update, context):
- sendMessage("This is a bot which can mirror all your links to Google drive!\n"
- "Type /help to get a list of available commands", context.bot, update)
+ start_string = f'''
+This is a bot which can mirror all your links to Google drive!
+Type /{BotCommands.HelpCommand} to get a list of available commands
+'''
+ sendMessage(start_string, context.bot, update)
@run_async
@@ -65,6 +73,8 @@ def bot_help(update, context):
/{BotCommands.MirrorCommand} [download_url][magnet_link]: Start mirroring the link to google drive
+/{BotCommands.UnzipMirrorCommand} [download_url][magnet_link] : starts mirroring and if downloaded file is any archive , extracts it to google drive
+
/{BotCommands.TarMirrorCommand} [download_url][magnet_link]: start mirroring and upload the archived (.tar) version of the download
/{BotCommands.WatchCommand} [youtube-dl supported link]: Mirror through youtube-dl
diff --git a/bot/helper/ext_utils/bot_utils.py b/bot/helper/ext_utils/bot_utils.py
index 5998e53..56bc930 100644
--- a/bot/helper/ext_utils/bot_utils.py
+++ b/bot/helper/ext_utils/bot_utils.py
@@ -19,6 +19,7 @@ class MirrorStatus:
STATUS_FAILED = "Failed. Cleaning download"
STATUS_CANCELLED = "Cancelled"
STATUS_ARCHIVING = "Archiving"
+ STATUS_EXTRACTING = "Extracting"
PROGRESS_MAX_SIZE = 100 // 8
@@ -61,7 +62,9 @@ def get_readable_file_size(size_in_bytes) -> str:
def getDownloadByGid(gid):
with download_dict_lock:
for dl in download_dict.values():
- if dl.status() != MirrorStatus.STATUS_UPLOADING and dl.status() != MirrorStatus.STATUS_ARCHIVING:
+ status = dl.status()
+ if status != MirrorStatus.STATUS_UPLOADING and status != MirrorStatus.STATUS_ARCHIVING\
+ and status != MirrorStatus.STATUS_EXTRACTING:
if dl.gid() == gid:
return dl
return None
@@ -91,7 +94,7 @@ def get_readable_message():
for download in list(download_dict.values()):
msg += f"{download.name()} - "
msg += download.status()
- if download.status() != MirrorStatus.STATUS_ARCHIVING:
+ if download.status() != MirrorStatus.STATUS_ARCHIVING and download.status() != MirrorStatus.STATUS_EXTRACTING:
msg += f"\n{get_progress_bar_string(download)} {download.progress()} of " \
f"{download.size()}" \
f" at {download.speed()}, ETA: {download.eta()} "
@@ -140,8 +143,10 @@ def new_thread(fn):
"""To use as decorator to make a function call threaded.
Needs import
from threading import Thread"""
+
def wrapper(*args, **kwargs):
thread = threading.Thread(target=fn, args=args, kwargs=kwargs)
thread.start()
return thread
- return wrapper
\ No newline at end of file
+
+ return wrapper
diff --git a/bot/helper/ext_utils/exceptions.py b/bot/helper/ext_utils/exceptions.py
index 25ff87f..a2f600c 100644
--- a/bot/helper/ext_utils/exceptions.py
+++ b/bot/helper/ext_utils/exceptions.py
@@ -1,2 +1,8 @@
class DirectDownloadLinkException(Exception):
+ """Not method found for extracting direct download link from the http link"""
+ pass
+
+
+class NotSupportedExtractionArchive(Exception):
+ """The archive format use is trying to extract is not supported"""
pass
diff --git a/bot/helper/ext_utils/fs_utils.py b/bot/helper/ext_utils/fs_utils.py
index 0b92aa0..cbf50b2 100644
--- a/bot/helper/ext_utils/fs_utils.py
+++ b/bot/helper/ext_utils/fs_utils.py
@@ -5,6 +5,7 @@ import os
import pathlib
import magic
import tarfile
+from .exceptions import NotSupportedExtractionArchive
def clean_download(path: str):
@@ -56,6 +57,33 @@ def tar(org_path):
return tar_path
+def get_base_name(orig_path: str):
+ if orig_path.endswith(".tar.bz2"):
+ return orig_path.replace(".tar.bz2", "")
+ elif orig_path.endswith(".tar.gz"):
+ return orig_path.replace(".tar.gz", "")
+ elif orig_path.endswith(".bz2"):
+ return orig_path.replace(".bz2", "")
+ elif orig_path.endswith(".gz"):
+ return orig_path.replace(".gz", "")
+ elif orig_path.endswith(".tar"):
+ return orig_path.replace(".tar", "")
+ elif orig_path.endswith(".tbz2"):
+ return orig_path.replace("tbz2", "")
+ elif orig_path.endswith(".tgz"):
+ return orig_path.replace(".tgz", "")
+ elif orig_path.endswith(".zip"):
+ return orig_path.replace(".zip", "")
+ elif orig_path.endswith(".7z"):
+ return orig_path.replace(".7z", "")
+ elif orig_path.endswith(".Z"):
+ return orig_path.replace(".Z", "")
+ elif orig_path.endswith(".rar"):
+ return orig_path.replace(".rar", "")
+ else:
+ raise NotSupportedExtractionArchive('File format not supported for extraction')
+
+
def get_mime_type(file_path):
mime = magic.Magic(mime=True)
mime_type = mime.from_file(file_path)
diff --git a/bot/helper/mirror_utils/download_utils/aria2_download.py b/bot/helper/mirror_utils/download_utils/aria2_download.py
index 9473e46..a610f81 100644
--- a/bot/helper/mirror_utils/download_utils/aria2_download.py
+++ b/bot/helper/mirror_utils/download_utils/aria2_download.py
@@ -24,9 +24,10 @@ class AriaDownloadHelper(DownloadHelper):
download = api.get_download(gid)
if download.followed_by_ids:
new_gid = download.followed_by_ids[0]
+ new_download = api.get_download(new_gid)
with download_dict_lock:
download_dict[dl.uid()] = AriaDownloadStatus(new_gid, dl.getListener())
- if download.is_torrent:
+ if new_download.is_torrent:
download_dict[dl.uid()].is_torrent = True
update_all_messages()
LOGGER.info(f'Changed gid from {gid} to {new_gid}')
@@ -62,15 +63,16 @@ class AriaDownloadHelper(DownloadHelper):
on_download_stop=self.__onDownloadStopped,
on_download_complete=self.__onDownloadComplete)
- def add_download(self, link: str, path, listener):
+
+ def add_download(self, link: str, path,listener):
if is_magnet(link):
download = aria2.add_magnet(link, {'dir': path})
else:
download = aria2.add_uris([link], {'dir': path})
-
if download.error_message: # no need to proceed further at this point
listener.onDownloadError(download.error_message)
return
with download_dict_lock:
download_dict[listener.uid] = AriaDownloadStatus(download.gid, listener)
LOGGER.info(f"Started: {download.gid} DIR:{download.dir} ")
+
diff --git a/bot/helper/mirror_utils/status_utils/aria_download_status.py b/bot/helper/mirror_utils/status_utils/aria_download_status.py
index c3199f7..ef04a79 100644
--- a/bot/helper/mirror_utils/status_utils/aria_download_status.py
+++ b/bot/helper/mirror_utils/status_utils/aria_download_status.py
@@ -20,6 +20,7 @@ class AriaDownloadStatus(Status):
self.message = listener.message
self.last = None
self.is_waiting = False
+ self.is_extracting = False
def __update(self):
self.__download = get_download(self.__gid)
diff --git a/bot/helper/mirror_utils/status_utils/extract_status.py b/bot/helper/mirror_utils/status_utils/extract_status.py
new file mode 100644
index 0000000..41b6ff5
--- /dev/null
+++ b/bot/helper/mirror_utils/status_utils/extract_status.py
@@ -0,0 +1,36 @@
+from .status import Status
+from bot.helper.ext_utils.bot_utils import get_readable_file_size, MirrorStatus
+
+
+class ExtractStatus(Status):
+ def __init__(self, name, path, size):
+ self.__name = name
+ self.__path = path
+ self.__size = size
+
+ # The progress of extract function cannot be tracked. So we just return dummy values.
+ # If this is possible in future,we should implement it
+
+ def progress(self):
+ return '0'
+
+ def speed(self):
+ return '0'
+
+ def name(self):
+ return self.__name
+
+ def path(self):
+ return self.__path
+
+ def size(self):
+ return get_readable_file_size(self.__size)
+
+ def eta(self):
+ return '0s'
+
+ def status(self):
+ return MirrorStatus.STATUS_EXTRACTING
+
+ def processed_bytes(self):
+ return 0
diff --git a/bot/helper/mirror_utils/upload_utils/gdriveTools.py b/bot/helper/mirror_utils/upload_utils/gdriveTools.py
index 0fe2f19..554c789 100644
--- a/bot/helper/mirror_utils/upload_utils/gdriveTools.py
+++ b/bot/helper/mirror_utils/upload_utils/gdriveTools.py
@@ -289,46 +289,32 @@ class GoogleDriveHelper:
msg = ""
LOGGER.info(f"File ID: {file_id}")
try:
- meta = self.__service.files().get(supportsAllDrives=True, fileId=file_id,
- fields="name,id,mimeType,size").execute()
- except Exception as e:
- return f"{str(e).replace('>', '').replace('<', '')}"
- if meta.get("mimeType") == self.__G_DRIVE_DIR_MIME_TYPE:
- dir_id = self.create_directory(meta.get('name'), parent_id)
- try:
+ meta = self.getFileMetadata(file_id)
+ if meta.get("mimeType") == self.__G_DRIVE_DIR_MIME_TYPE:
+ dir_id = self.create_directory(meta.get('name'), parent_id)
result = self.cloneFolder(meta.get('name'), meta.get('name'), meta.get('id'), dir_id)
- except Exception as e:
- if isinstance(e, RetryError):
- LOGGER.info(f"Total Attempts: {e.last_attempt.attempt_number}")
- err = e.last_attempt.exception()
- else:
- err = str(e).replace('>', '').replace('<', '')
- LOGGER.error(err)
- return err
- msg += f'{meta.get("name")}' \
- f' ({get_readable_file_size(self.transferred_size)})'
- if INDEX_URL is not None:
- url = requests.utils.requote_uri(f'{INDEX_URL}/{meta.get("name")}/')
- msg += f' | Index URL'
- else:
- try:
- file = self.copyFile(meta.get('id'), parent_id)
- except Exception as e:
- if isinstance(e, RetryError):
- LOGGER.info(f"Total Attempts: {e.last_attempt.attempt_number}")
- err = e.last_attempt.exception()
- else:
- err = str(e).replace('>', '').replace('<', '')
- LOGGER.error(err)
- return err
- msg += f'{file.get("name")}'
- try:
- msg += f' ({get_readable_file_size(int(meta.get("size")))}) '
+ msg += f'{meta.get("name")}' \
+ f' ({get_readable_file_size(self.transferred_size)})'
if INDEX_URL is not None:
- url = requests.utils.requote_uri(f'{INDEX_URL}/{file.get("name")}')
+ url = requests.utils.requote_uri(f'{INDEX_URL}/{meta.get("name")}/')
msg += f' | Index URL'
- except TypeError:
- pass
+ else:
+ file = self.copyFile(meta.get('id'), parent_id)
+ msg += f'{file.get("name")}'
+ try:
+ msg += f' ({get_readable_file_size(int(meta.get("size")))}) '
+ except TypeError:
+ pass
+ if INDEX_URL is not None:
+ url = requests.utils.requote_uri(f'{INDEX_URL}/{file.get("name")}')
+ msg += f' | Index URL'
+ except Exception as err:
+ if isinstance(err, RetryError):
+ LOGGER.info(f"Total Attempts: {err.last_attempt.attempt_number}")
+ err = err.last_attempt.exception()
+ err = str(err).replace('>', '').replace('<', '')
+ LOGGER.error(err)
+ return err
return msg
def cloneFolder(self, name, local_path, folder_id, parent_id):
@@ -421,8 +407,15 @@ class GoogleDriveHelper:
scopes=self.__OAUTH_SCOPE)
return build('drive', 'v3', credentials=credentials, cache_discovery=False)
+ def escapes(self, str):
+ chars = ['\\', "'", '"', r'\a', r'\b', r'\f', r'\n', r'\r', r'\t']
+ for char in chars:
+ str = str.replace(char, '\\'+char)
+ return str
+
def drive_list(self, fileName):
msg = ""
+ fileName = self.escapes(str(fileName))
# Create Search Query for API request.
query = f"'{parent_id}' in parents and (name contains '{fileName}')"
response = self.__service.files().list(supportsTeamDrives=True,
diff --git a/bot/helper/telegram_helper/bot_commands.py b/bot/helper/telegram_helper/bot_commands.py
index fee3fa2..bd1af0c 100644
--- a/bot/helper/telegram_helper/bot_commands.py
+++ b/bot/helper/telegram_helper/bot_commands.py
@@ -2,6 +2,7 @@ class _BotCommands:
def __init__(self):
self.StartCommand = 'start'
self.MirrorCommand = 'mirror'
+ self.UnzipMirrorCommand = 'unzipmirror'
self.TarMirrorCommand = 'tarmirror'
self.CancelMirror = 'cancel'
self.CancelAllCommand = 'cancelall'
diff --git a/bot/helper/telegram_helper/filters.py b/bot/helper/telegram_helper/filters.py
index a65445f..3cd3c93 100644
--- a/bot/helper/telegram_helper/filters.py
+++ b/bot/helper/telegram_helper/filters.py
@@ -1,5 +1,6 @@
from telegram.ext import BaseFilter
-from bot import AUTHORIZED_CHATS, OWNER_ID
+from telegram import Message
+from bot import AUTHORIZED_CHATS, OWNER_ID, download_dict, download_dict_lock
class CustomFilters:
@@ -21,3 +22,22 @@ class CustomFilters:
return bool(message.chat.id in AUTHORIZED_CHATS)
authorized_chat = _AuthorizedChat()
+
+ class _MirrorOwner(BaseFilter):
+ def filter(self, message: Message):
+ user_id = message.from_user.id
+ if user_id == OWNER_ID:
+ return True
+ args = str(message.text).split(' ')
+ if len(args) > 1:
+ # Cancelling by gid
+ with download_dict_lock:
+ for message_id, status in download_dict.items():
+ if status.gid() == args[1] and status.message.from_user.id == user_id:
+ return True
+ else:
+ return False
+ # Cancelling by replying to original mirror message
+ reply_user = message.reply_to_message.from_user.id
+ return bool(reply_user == user_id)
+ mirror_owner_filter = _MirrorOwner()
diff --git a/bot/helper/telegram_helper/message_utils.py b/bot/helper/telegram_helper/message_utils.py
index bc209dd..9d3eb02 100644
--- a/bot/helper/telegram_helper/message_utils.py
+++ b/bot/helper/telegram_helper/message_utils.py
@@ -9,9 +9,12 @@ from bot import bot
def sendMessage(text: str, bot, update: Update):
- return bot.send_message(update.message.chat_id,
+ try:
+ return bot.send_message(update.message.chat_id,
reply_to_message_id=update.message.message_id,
text=text, parse_mode='HTMl')
+ except Exception as e:
+ LOGGER.error(str(e))
def editMessage(text: str, message: Message):
@@ -19,9 +22,8 @@ def editMessage(text: str, message: Message):
bot.edit_message_text(text=text, message_id=message.message_id,
chat_id=message.chat.id,
parse_mode='HTMl')
- except TimedOut as e:
+ except Exception as e:
LOGGER.error(str(e))
- pass
def deleteMessage(bot, message: Message):
@@ -56,10 +58,8 @@ def delete_all_messages():
try:
deleteMessage(bot, message)
del status_reply_dict[message.chat.id]
- except BadRequest as e:
- LOGGER.info(str(e))
- del status_reply_dict[message.chat.id]
- pass
+ except Exception as e:
+ LOGGER.error(str(e))
def update_all_messages():
@@ -69,7 +69,7 @@ def update_all_messages():
if status_reply_dict[chat_id] and msg != status_reply_dict[chat_id].text:
try:
editMessage(msg, status_reply_dict[chat_id])
- except BadRequest as e:
+ except Exception as e:
LOGGER.error(str(e))
status_reply_dict[chat_id].text = msg
diff --git a/bot/modules/cancel_mirror.py b/bot/modules/cancel_mirror.py
index c25c460..a4d2d74 100644
--- a/bot/modules/cancel_mirror.py
+++ b/bot/modules/cancel_mirror.py
@@ -11,14 +11,14 @@ from bot.helper.ext_utils.bot_utils import getDownloadByGid, MirrorStatus
@run_async
-def cancel_mirror(update,context):
- args = update.message.text.split(" ",maxsplit=1)
+def cancel_mirror(update, context):
+ args = update.message.text.split(" ", maxsplit=1)
mirror_message = None
if len(args) > 1:
gid = args[1]
dl = getDownloadByGid(gid)
if not dl:
- sendMessage(f"GID: {gid} not found.",context.bot,update)
+ sendMessage(f"GID: {gid} not found.", context.bot, update)
return
with download_dict_lock:
keys = list(download_dict.keys())
@@ -33,11 +33,11 @@ def cancel_mirror(update,context):
if BotCommands.MirrorCommand in mirror_message.text or \
BotCommands.TarMirrorCommand in mirror_message.text:
msg = "Mirror already have been cancelled"
- sendMessage(msg,context.bot,update)
+ sendMessage(msg, context.bot, update)
return
else:
msg = "Please reply to the /mirror message which was used to start the download or /cancel gid to cancel it!"
- sendMessage(msg,context.bot,update)
+ sendMessage(msg, context.bot, update)
return
if dl.status() == "Uploading":
sendMessage("Upload in Progress, Don't Cancel it.", context.bot, update)
@@ -56,16 +56,16 @@ def cancel_all(update, context):
with download_dict_lock:
count = 0
for dlDetails in list(download_dict.values()):
- if dlDetails.status() == MirrorStatus.STATUS_DOWNLOADING\
+ if dlDetails.status() == MirrorStatus.STATUS_DOWNLOADING \
or dlDetails.status() == MirrorStatus.STATUS_WAITING:
dlDetails.download().cancel_download()
count += 1
delete_all_messages()
- sendMessage(f'Cancelled {count} downloads!', context.bot,update)
+ sendMessage(f'Cancelled {count} downloads!', context.bot, update)
cancel_mirror_handler = CommandHandler(BotCommands.CancelMirror, cancel_mirror,
- filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
+ filters=(CustomFilters.authorized_chat | CustomFilters.authorized_user) & CustomFilters.mirror_owner_filter)
cancel_all_handler = CommandHandler(BotCommands.CancelAllCommand, cancel_all,
filters=CustomFilters.owner_filter)
dispatcher.add_handler(cancel_all_handler)
diff --git a/bot/modules/mirror.py b/bot/modules/mirror.py
index a69c8d4..8bdb8d7 100644
--- a/bot/modules/mirror.py
+++ b/bot/modules/mirror.py
@@ -1,35 +1,36 @@
import requests
from telegram.ext import CommandHandler, run_async
-from bot import Interval, INDEX_URL
+from bot import Interval, INDEX_URL,LOGGER
from bot import dispatcher, DOWNLOAD_DIR, DOWNLOAD_STATUS_UPDATE_INTERVAL, download_dict, download_dict_lock
from bot.helper.ext_utils import fs_utils, bot_utils
from bot.helper.ext_utils.bot_utils import setInterval
-from bot.helper.ext_utils.exceptions import DirectDownloadLinkException
+from bot.helper.ext_utils.exceptions import DirectDownloadLinkException, NotSupportedExtractionArchive
from bot.helper.mirror_utils.download_utils.aria2_download import AriaDownloadHelper
from bot.helper.mirror_utils.download_utils.direct_link_generator import direct_link_generator
from bot.helper.mirror_utils.download_utils.telegram_downloader import TelegramDownloadHelper
from bot.helper.mirror_utils.status_utils import listeners
+from bot.helper.mirror_utils.status_utils.extract_status import ExtractStatus
from bot.helper.mirror_utils.status_utils.tar_status import TarStatus
from bot.helper.mirror_utils.status_utils.upload_status import UploadStatus
from bot.helper.mirror_utils.upload_utils import gdriveTools
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 bot.helper.mirror_utils.download_utils.youtube_dl_download_helper import YoutubeDLHelper
import pathlib
import os
+import subprocess
+import threading
ariaDlManager = AriaDownloadHelper()
ariaDlManager.start_listener()
-
class MirrorListener(listeners.MirrorListeners):
-
- def __init__(self, bot, update, isTar=False, tag=None):
+ def __init__(self, bot, update, isTar=False,tag=None, extract=False):
super().__init__(bot, update)
self.isTar = isTar
self.tag = tag
+ self.extract = extract
def onDownloadStarted(self):
pass
@@ -63,8 +64,31 @@ class MirrorListener(listeners.MirrorListeners):
LOGGER.info('File to archive not found!')
self.onUploadError('Internal error occurred!!')
return
+ elif self.extract:
+ download.is_extracting = True
+ try:
+ path = fs_utils.get_base_name(m_path)
+ LOGGER.info(
+ f"Extracting : {name} "
+ )
+ with download_dict_lock:
+ download_dict[self.uid] = ExtractStatus(name, m_path, size)
+ archive_result = subprocess.run(["extract", m_path])
+ if archive_result.returncode == 0:
+ threading.Thread(target=os.remove, args=(m_path,)).start()
+ LOGGER.info(f"Deleting archive : {m_path}")
+ else:
+ LOGGER.warning('Unable to extract archive! Uploading anyway')
+ path = f'{DOWNLOAD_DIR}{self.uid}/{name}'
+ LOGGER.info(
+ f'got path : {path}'
+ )
+
+ except NotSupportedExtractionArchive:
+ LOGGER.info("Not any valid archive, uploading file as it is.")
+ path = f'{DOWNLOAD_DIR}{self.uid}/{name}'
else:
- path = f'{DOWNLOAD_DIR}{self.uid}/{download_dict[self.uid].name()}'
+ path = f'{DOWNLOAD_DIR}{self.uid}/{name}'
up_name = pathlib.PurePath(path).name
LOGGER.info(f"Upload Name : {up_name}")
drive = gdriveTools.GoogleDriveHelper(up_name, self)
@@ -132,7 +156,7 @@ class MirrorListener(listeners.MirrorListeners):
update_all_messages()
def onUploadError(self, error):
- e_str = str(error.last_attempt.exception()).replace('<', '').replace('>', '')
+ e_str = error.replace('<', '').replace('>', '')
with download_dict_lock:
try:
fs_utils.clean_download(download_dict[self.uid].path())
@@ -146,8 +170,7 @@ class MirrorListener(listeners.MirrorListeners):
else:
update_all_messages()
-
-def _mirror(bot, update, isTar=False):
+def _mirror(bot, update, isTar=False, extract=False):
message_args = update.message.text.split(' ')
try:
link = message_args[1]
@@ -187,7 +210,8 @@ def _mirror(bot, update, isTar=False):
link = direct_link_generator(link)
except DirectDownloadLinkException as e:
LOGGER.info(f'{link}: {e}')
- listener = MirrorListener(bot, update, isTar, tag)
+
+ listener = MirrorListener(bot, update, isTar, tag, extract)
ariaDlManager.add_download(link, f'{DOWNLOAD_DIR}/{listener.uid}/',listener)
sendStatusMessage(update, bot)
if len(Interval) == 0:
@@ -204,9 +228,17 @@ def tar_mirror(update, context):
_mirror(context.bot, update, True)
+@run_async
+def unzip_mirror(update, context):
+ _mirror(context.bot,update, extract=True)
+
+
mirror_handler = CommandHandler(BotCommands.MirrorCommand, mirror,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
tar_mirror_handler = CommandHandler(BotCommands.TarMirrorCommand, tar_mirror,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
+unzip_mirror_handler = CommandHandler(BotCommands.UnzipMirrorCommand, unzip_mirror,
+ filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
dispatcher.add_handler(mirror_handler)
dispatcher.add_handler(tar_mirror_handler)
+dispatcher.add_handler(unzip_mirror_handler)
diff --git a/extract b/extract
new file mode 100755
index 0000000..da9847b
--- /dev/null
+++ b/extract
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+if [ $# -lt 1 ]; then
+ echo "Usage: $(basename $0) FILES"
+ exit 1
+fi
+
+extract() {
+ arg="$1"
+ cd "$(dirname "$arg")" || exit
+ case "$arg" in
+ *.tar.bz2)
+ tar xjf "$arg" --one-top-level
+ local code=$?
+ ;;
+ *.tar.gz)
+ tar xzf "$arg" --one-top-level
+ local code=$?
+ ;;
+ *.bz2)
+ bunzip2 "$arg"
+ local code=$?
+ ;;
+ *.gz)
+ gunzip "$arg"
+ local code=$?
+ ;;
+ *.tar)
+ tar xf "$arg" --one-top-level
+ local code=$?
+ ;;
+ *.tbz2)
+ (tar xjf "$arg" --one-top-level)
+ local code=$?
+ ;;
+ *.tgz)
+ tar xzf "$arg" --one-top-level
+ local code=$?
+ ;;
+ *.zip)
+ a_dir=$(expr "$arg" : '\(.*\).zip')
+ 7z x "$arg" -o"$a_dir"
+ local code=$?
+ ;;
+ *.7z)
+ a_dir=$(expr "$arg" : '\(.*\).7z')
+ 7z x "$arg" -o"$a_dir"
+ local code=$?
+ ;;
+ *.Z)
+ uncompress "$arg"
+ local code=$?
+ ;;
+ *.rar)
+ a_dir=$(expr "$arg" : '\(.*\).rar')
+ mkdir "$a_dir"
+ 7z x "$arg" -o"$a_dir"
+ local code=$?
+ ;;
+ *)
+ echo "'$arg' cannot be extracted via extract()" 1>&2
+ exit 1
+ ;;
+ esac
+ cd - || exit $?
+ exit $code
+}
+
+extract "$1"
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 078a15e..9a915ff 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
requests
+psutil
python-telegram-bot==12.6.1
google-api-python-client>=1.7.11,<1.7.20
google-auth-httplib2>=0.0.3,<0.1.0