add ability to unzip files (#93)

handle unsupported request

use shell utils to extract archives

use shell utils to extract archives

update mirror calls for unzipmirror

fix extract location of files

install deps

handling if archive is not extracted correctly

typo fix

implement Extract Status

handle filenames with spaces

handle special character
This commit is contained in:
Nageen Chand 2020-05-28 00:26:22 +05:30 committed by GitHub
parent 9f5942deaa
commit b6b8a416e9
Signed by untrusted user: GitHub
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 142 additions and 8 deletions

View File

@ -3,10 +3,12 @@ FROM ubuntu:18.04
WORKDIR /usr/src/app WORKDIR /usr/src/app
RUN chmod 777 /usr/src/app RUN chmod 777 /usr/src/app
RUN apt-get -qq update RUN apt-get -qq update
RUN apt-get -qq install -y aria2 python3 python3-pip \ RUN apt-get -qq install -y aria2 python3 python3-pip rar unzip \
locales python3-lxml \ locales python3-lxml \
curl pv jq ffmpeg curl pv jq ffmpeg
COPY requirements.txt . COPY requirements.txt .
COPY extract /usr/local/bin
RUN chmod +x /usr/local/bin/extract
RUN pip3 install --no-cache-dir -r requirements.txt RUN pip3 install --no-cache-dir -r requirements.txt
RUN locale-gen en_US.UTF-8 RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8 ENV LANG en_US.UTF-8

View File

@ -65,6 +65,8 @@ def bot_help(update, context):
/{BotCommands.MirrorCommand} [download_url][magnet_link]: Start mirroring the link to google drive /{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.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 /{BotCommands.WatchCommand} [youtube-dl supported link]: Mirror through youtube-dl

View File

@ -19,6 +19,7 @@ class MirrorStatus:
STATUS_FAILED = "Failed. Cleaning download" STATUS_FAILED = "Failed. Cleaning download"
STATUS_CANCELLED = "Cancelled" STATUS_CANCELLED = "Cancelled"
STATUS_ARCHIVING = "Archiving" STATUS_ARCHIVING = "Archiving"
STATUS_EXTRACTING = "Extracting"
PROGRESS_MAX_SIZE = 100 // 8 PROGRESS_MAX_SIZE = 100 // 8
@ -91,7 +92,7 @@ def get_readable_message():
for download in list(download_dict.values()): for download in list(download_dict.values()):
msg += f"<i>{download.name()}</i> - " msg += f"<i>{download.name()}</i> - "
msg += download.status() msg += download.status()
if download.status() != MirrorStatus.STATUS_ARCHIVING: if download.status() != MirrorStatus.STATUS_ARCHIVING and download.status() != MirrorStatus.STATUS_EXTRACTING:
msg += f"\n<code>{get_progress_bar_string(download)} {download.progress()}</code> of " \ msg += f"\n<code>{get_progress_bar_string(download)} {download.progress()}</code> of " \
f"{download.size()}" \ f"{download.size()}" \
f" at {download.speed()}, ETA: {download.eta()} " f" at {download.speed()}, ETA: {download.eta()} "

View File

@ -56,6 +56,31 @@ def tar(org_path):
return tar_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(".Z"):
return orig_path.replace(".Z","")
elif orig_path.endswith(".rar"):
return orig_path.replace(".rar","")
else:
return "unsupported"
def get_mime_type(file_path): def get_mime_type(file_path):
mime = magic.Magic(mime=True) mime = magic.Magic(mime=True)
mime_type = mime.from_file(file_path) mime_type = mime.from_file(file_path)

View File

@ -20,6 +20,7 @@ class AriaDownloadStatus(Status):
self.message = listener.message self.message = listener.message
self.last = None self.last = None
self.is_waiting = False self.is_waiting = False
self.is_extracting = False
def __update(self): def __update(self):
self.__download = get_download(self.__gid) self.__download = get_download(self.__gid)

View File

@ -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 Tar 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

View File

@ -2,6 +2,7 @@ class _BotCommands:
def __init__(self): def __init__(self):
self.StartCommand = 'start' self.StartCommand = 'start'
self.MirrorCommand = 'mirror' self.MirrorCommand = 'mirror'
self.UnzipMirrorCommand = 'unzipmirror'
self.TarMirrorCommand = 'tarmirror' self.TarMirrorCommand = 'tarmirror'
self.CancelMirror = 'cancel' self.CancelMirror = 'cancel'
self.CancelAllCommand = 'cancelall' self.CancelAllCommand = 'cancelall'

View File

@ -10,6 +10,7 @@ from bot.helper.mirror_utils.download_utils.aria2_download import AriaDownloadHe
from bot.helper.mirror_utils.download_utils.direct_link_generator import direct_link_generator 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.download_utils.telegram_downloader import TelegramDownloadHelper
from bot.helper.mirror_utils.status_utils import listeners 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.tar_status import TarStatus
from bot.helper.mirror_utils.status_utils.upload_status import UploadStatus from bot.helper.mirror_utils.status_utils.upload_status import UploadStatus
from bot.helper.mirror_utils.upload_utils import gdriveTools from bot.helper.mirror_utils.upload_utils import gdriveTools
@ -24,11 +25,11 @@ ariaDlManager.start_listener()
class MirrorListener(listeners.MirrorListeners): class MirrorListener(listeners.MirrorListeners):
def __init__(self, bot, update, isTar=False,tag=None, extract=False):
def __init__(self, bot, update, isTar=False, tag=None):
super().__init__(bot, update) super().__init__(bot, update)
self.isTar = isTar self.isTar = isTar
self.tag = tag self.tag = tag
self.extract = extract
def onDownloadStarted(self): def onDownloadStarted(self):
pass pass
@ -62,6 +63,30 @@ class MirrorListener(listeners.MirrorListeners):
LOGGER.info('File to archive not found!') LOGGER.info('File to archive not found!')
self.onUploadError('Internal error occurred!!') self.onUploadError('Internal error occurred!!')
return return
elif self.extract:
download.is_extracting = True
path = fs_utils.get_base_name(m_path)
if path != "unsupported":
LOGGER.info(
f"Extracting : {download_dict[self.uid].name()} "
)
download_dict[self.uid] = ExtractStatus(name, m_path, size)
os.system(f"extract '{m_path}'")
if not os.path.exists(path):
self.onUploadError("Cannot extract file, check integrity of the file")
return
LOGGER.info(
f'got path : {path}'
)
try:
os.remove(m_path)
LOGGER.info(f"Deleting archive : {m_path}")
except Exception as e:
LOGGER.error(str(e))
else:
LOGGER.info("Not any valid archive, uploading file as it is.")
path = f'{DOWNLOAD_DIR}{self.uid}/{download_dict[self.uid].name()}'
else: else:
path = f'{DOWNLOAD_DIR}{self.uid}/{download_dict[self.uid].name()}' path = f'{DOWNLOAD_DIR}{self.uid}/{download_dict[self.uid].name()}'
up_name = pathlib.PurePath(path).name up_name = pathlib.PurePath(path).name
@ -145,8 +170,7 @@ class MirrorListener(listeners.MirrorListeners):
else: else:
update_all_messages() update_all_messages()
def _mirror(bot, update, isTar=False, extract=False):
def _mirror(bot, update, isTar=False):
message_args = update.message.text.split(' ') message_args = update.message.text.split(' ')
try: try:
link = message_args[1] link = message_args[1]
@ -186,7 +210,7 @@ def _mirror(bot, update, isTar=False):
link = direct_link_generator(link) link = direct_link_generator(link)
except DirectDownloadLinkException as e: except DirectDownloadLinkException as e:
LOGGER.info(f'{link}: {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) ariaDlManager.add_download(link, f'{DOWNLOAD_DIR}/{listener.uid}/',listener)
sendStatusMessage(update, bot) sendStatusMessage(update, bot)
if len(Interval) == 0: if len(Interval) == 0:
@ -203,9 +227,17 @@ def tar_mirror(update, context):
_mirror(context.bot, update, True) _mirror(context.bot, update, True)
@run_async
def unzip_mirror(update, context):
_mirror(context.bot,update, extract=True)
mirror_handler = CommandHandler(BotCommands.MirrorCommand, mirror, mirror_handler = CommandHandler(BotCommands.MirrorCommand, mirror,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user) filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
tar_mirror_handler = CommandHandler(BotCommands.TarMirrorCommand, tar_mirror, tar_mirror_handler = CommandHandler(BotCommands.TarMirrorCommand, tar_mirror,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user) 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(mirror_handler)
dispatcher.add_handler(tar_mirror_handler) dispatcher.add_handler(tar_mirror_handler)
dispatcher.add_handler(unzip_mirror_handler)

34
extract Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
if [ $# -lt 1 ];then
echo "Usage: `basename $0` FILES"
exit 1
fi
extract () {
arg="$1"
cd $(dirname "$arg")
case "$arg" in
*.tar.bz2)
tar xjf "$arg" --one-top-level ;;
*.tar.gz)
tar xzf "$arg" --one-top-level ;;
*.bz2) bunzip2 "$arg" ;;
*.gz) gunzip "$arg" ;;
*.tar) tar xf "$arg" --one-top-level ;;
*.tbz2) tar xjf "$arg" --one-top-level ;;
*.tgz) tar xzf "$arg" --one-top-level ;;
*.zip)
a_dir=`expr "$arg" : '\(.*\).zip'`
unzip "$arg" -d "$a_dir" ;;
*.Z) uncompress "$arg" ;;
*.rar)
a_dir=`expr "$arg" : '\(.*\).rar'` ;
mkdir "$a_dir" ;
rar x "$arg" "$a_dir" ;; # 'rar' must to be installed
*) echo "'$arg' cannot be extracted via extract()" ;;
esac
cd -
}
extract "$1"