Add Clone Status

-add clone status for folders have more than 15 files
-clean up

Signed-off-by: anas <e.anastayyar@gmail.com>
This commit is contained in:
anas 2021-07-19 07:55:45 +03:00
parent 45eec691d1
commit 80d3343071
7 changed files with 159 additions and 64 deletions

View File

@ -23,6 +23,7 @@ PAGE_NO = 1
class MirrorStatus:
STATUS_UPLOADING = "Uploading...📤"
STATUS_DOWNLOADING = "Downloading...📥"
STATUS_CLONING = "Cloning...♻️"
STATUS_WAITING = "Queued...📝"
STATUS_FAILED = "Failed 🚫. Cleaning Download..."
STATUS_ARCHIVING = "Archiving...🔐"
@ -123,6 +124,8 @@ def get_readable_message():
msg += f"\n<code>{get_progress_bar_string(download)} {download.progress()}</code>"
if download.status() == MirrorStatus.STATUS_DOWNLOADING:
msg += f"\n<b>Downloaded:</b> {get_readable_file_size(download.processed_bytes())} of {download.size()}"
elif download.status() == MirrorStatus.STATUS_CLONING:
msg += f"\n<b>Cloned:</b> {get_readable_file_size(download.processed_bytes())} of {download.size()}"
else:
msg += f"\n<b>Uploaded:</b> {get_readable_file_size(download.processed_bytes())} of {download.size()}"
msg += f"\n<b>Speed:</b> {download.speed()}" \
@ -134,7 +137,7 @@ def get_readable_message():
except:
pass
msg += f'\n<b>User:</b> <a href="tg://user?id={download.message.from_user.id}">{download.message.from_user.first_name}</a> (<code>{download.message.from_user.id}</code>)'
if download.status() == MirrorStatus.STATUS_DOWNLOADING:
if download.status() == MirrorStatus.STATUS_DOWNLOADING or download.status() == MirrorStatus.STATUS_CLONING:
msg += f"\n<b>To Stop:</b> <code>/{BotCommands.CancelMirror} {download.gid()}</code>"
msg += "\n\n"
if STATUS_LIMIT is not None:

View File

@ -0,0 +1,56 @@
from .status import Status
from bot.helper.ext_utils.bot_utils import MirrorStatus, get_readable_file_size, get_readable_time
class CloneStatus(Status):
def __init__(self, obj, size, update, gid):
self.cobj = obj
self.__csize = size
self.message = update.message
self.__cgid = gid
def processed_bytes(self):
return self.cobj.transferred_size
def size_raw(self):
return self.__csize
def size(self):
return get_readable_file_size(self.__csize)
def status(self):
return MirrorStatus.STATUS_CLONING
def name(self):
return self.cobj.name
def gid(self) -> str:
return self.__cgid
def progress_raw(self):
try:
return self.cobj.transferred_size / self.__csize * 100
except ZeroDivisionError:
return 0
def progress(self):
return f'{round(self.progress_raw(), 2)}%'
def speed_raw(self):
"""
:return: Download speed in Bytes/Seconds
"""
return self.cobj.cspeed()
def speed(self):
return f'{get_readable_file_size(self.speed_raw())}/s'
def eta(self):
try:
seconds = (self.__csize - self.cobj.transferred_size) / self.speed_raw()
return f'{get_readable_time(seconds)}'
except ZeroDivisionError:
return '-'
def download(self):
return self.cobj

View File

@ -22,7 +22,7 @@ from telegram import InlineKeyboardMarkup
from bot.helper.telegram_helper import button_build
from telegraph import Telegraph
from bot import parent_id, DOWNLOAD_DIR, IS_TEAM_DRIVE, INDEX_URL, \
USE_SERVICE_ACCOUNTS, download_dict, telegraph_token, BUTTON_FOUR_NAME, BUTTON_FOUR_URL, BUTTON_FIVE_NAME, BUTTON_FIVE_URL, BUTTON_SIX_NAME, BUTTON_SIX_URL, SHORTENER, SHORTENER_API, IMAGE_URL, VIEW_LINK
USE_SERVICE_ACCOUNTS, telegraph_token, BUTTON_FOUR_NAME, BUTTON_FOUR_URL, BUTTON_FIVE_NAME, BUTTON_FIVE_URL, BUTTON_SIX_NAME, BUTTON_SIX_URL, SHORTENER, SHORTENER_API, IMAGE_URL, VIEW_LINK
from bot.helper.ext_utils.bot_utils import *
from bot.helper.ext_utils.fs_utils import get_mime_type, get_path_size
@ -44,17 +44,15 @@ class GoogleDriveHelper:
self.__G_DRIVE_DIR_BASE_DOWNLOAD_URL = "https://drive.google.com/drive/folders/{}"
self.__listener = listener
self.__service = self.authorize()
self.__listener = listener
self._file_uploaded_bytes = 0
self._file_downloaded_bytes = 0
self.uploaded_bytes = 0
self.downloaded_bytes = 0
self.UPDATE_INTERVAL = 5
self.start_time = 0
self.total_time = 0
self.dtotal_time = 0
self._should_update = True
self.is_uploading = True
self.is_downloading = False
self.is_cloning = False
self.is_cancelled = False
self.status = None
self.dstatus = None
@ -66,12 +64,9 @@ class GoogleDriveHelper:
self.total_bytes = 0
self.total_files = 0
self.total_folders = 0
self.transferred_size = 0
self.sa_count = 0
def cancel(self):
self.is_cancelled = True
self.is_uploading = False
def speed(self):
"""
It calculates the average upload speed and returns it in bytes/seconds unit
@ -86,7 +81,13 @@ class GoogleDriveHelper:
try:
return self.downloaded_bytes / self.dtotal_time
except ZeroDivisionError:
return 0
return 0
def cspeed(self):
try:
return self.transferred_size / int(time.time() - self.start_time)
except ZeroDivisionError:
return 0
@staticmethod
def getIdFromUrl(link: str):
@ -236,7 +237,6 @@ class GoogleDriveHelper:
file_path = f"{file_dir}/{file_name}"
size = get_readable_file_size(get_path_size(file_path))
LOGGER.info("Uploading File: " + file_path)
self.start_time = time.time()
self.updater = setInterval(self.update_interval, self._on_upload_progress)
if os.path.isfile(file_path):
try:
@ -275,7 +275,6 @@ class GoogleDriveHelper:
return
finally:
self.updater.cancel()
LOGGER.info(download_dict)
files = self.total_files
folders = self.total_folders
typ = self.typee
@ -338,7 +337,8 @@ class GoogleDriveHelper:
return files
def clone(self, link):
self.transferred_size = 0
self.is_cloning = True
self.start_time = time.time()
self.total_files = 0
self.total_folders = 0
if USE_SERVICE_ACCOUNTS:
@ -355,11 +355,16 @@ class GoogleDriveHelper:
if meta.get("mimeType") == self.__G_DRIVE_DIR_MIME_TYPE:
dir_id = self.create_directory(meta.get('name'), parent_id)
self.cloneFolder(meta.get('name'), meta.get('name'), meta.get('id'), dir_id)
durl = self.__G_DRIVE_DIR_BASE_DOWNLOAD_URL.format(dir_id)
if self.is_cancelled:
LOGGER.info("Deleting cloned data from drive...")
msg = self.deletefile(durl)
LOGGER.info(f"{msg}")
return "Your clone has been stopped and cloned data has been deleted!", "cancelled"
msg += f'<b>Filename: </b><code>{meta.get("name")}</code>\n<b>Size: </b><code>{get_readable_file_size(self.transferred_size)}</code>'
msg += f'\n<b>Type: </b><code>Folder</code>'
msg += f'\n<b>SubFolders: </b><code>{self.total_folders}</code>'
msg += f'\n<b>Files: </b><code>{self.total_files}</code>'
durl = self.__G_DRIVE_DIR_BASE_DOWNLOAD_URL.format(dir_id)
buttons = button_build.ButtonMaker()
if SHORTENER is not None and SHORTENER_API is not None:
surl = requests.get(f'https://{SHORTENER}/api?api={SHORTENER_API}&url={durl}&format=text').text
@ -723,6 +728,7 @@ class GoogleDriveHelper:
except TypeError:
pass
clonesize = self.total_bytes
files = self.total_files
except Exception as err:
err = str(err).replace('>', '').replace('<', '')
LOGGER.error(err)
@ -731,13 +737,13 @@ class GoogleDriveHelper:
else:
msg = f"Error.\n{err}"
return msg, "", ""
return "", clonesize, name
return "", clonesize, name, files
def download(self, link):
self.is_downloading = True
file_id = self.getIdFromUrl(link)
if USE_SERVICE_ACCOUNTS:
self.service_account_count = len(os.listdir("accounts"))
self.start_time = time.time()
self.updater = setInterval(self.update_interval, self._on_download_progress)
try:
meta = self.getFileMetadata(file_id)
@ -834,5 +840,8 @@ class GoogleDriveHelper:
def cancel_download(self):
self.is_cancelled = True
LOGGER.info(f"Cancelling Download: {self.name}")
self.__listener.onDownloadError('Download stopped by user!')
if self.is_downloading:
LOGGER.info(f"Cancelling Download: {self.name}")
self.__listener.onDownloadError('Download stopped by user!')
elif self.is_cloning:
LOGGER.info(f"Cancelling Clone: {self.name}")

View File

@ -93,7 +93,7 @@ def update_all_messages():
uldl_bytes += float(speedy.split('M')[0]) * 1048576
dlspeed = get_readable_file_size(dlspeed_bytes)
ulspeed = get_readable_file_size(uldl_bytes)
msg += f"\n<b>FREE:</b> {free} | <b>UPTIME:</b> {currentTime}\n<b>DL:</b> {dlspeed}ps 🔻 | <b>UL:</b> {ulspeed}ps 🔺\n"
msg += f"\n<b>FREE:</b> {free} | <b>UPTIME:</b> {currentTime}\n<b>DL:</b> {dlspeed}/s 🔻 | <b>UL:</b> {ulspeed}/s 🔺\n"
with status_reply_dict_lock:
for chat_id in list(status_reply_dict.keys()):
if status_reply_dict[chat_id] and msg != status_reply_dict[chat_id].text:
@ -134,7 +134,7 @@ def sendStatusMessage(msg, bot):
uldl_bytes += float(speedy.split('M')[0]) * 1048576
dlspeed = get_readable_file_size(dlspeed_bytes)
ulspeed = get_readable_file_size(uldl_bytes)
progress += f"\n<b>FREE:</b> {free} | <b>UPTIME:</b> {currentTime}\n<b>DL:</b> {dlspeed}ps 🔻 | <b>UL:</b> {ulspeed}ps 🔺\n"
progress += f"\n<b>FREE:</b> {free} | <b>UPTIME:</b> {currentTime}\n<b>DL:</b> {dlspeed}/s 🔻 | <b>UL:</b> {ulspeed}/s 🔺\n"
with status_reply_dict_lock:
if msg.message.chat.id in list(status_reply_dict.keys()):
try:

View File

@ -72,7 +72,6 @@ def cancel_all(update, context):
count += 1
else:
break
delete_all_messages()
sendMessage(f'{count} Download(s) has been Cancelled!', context.bot, update)

View File

@ -1,56 +1,84 @@
from telegram.ext import CommandHandler
from bot.helper.mirror_utils.upload_utils.gdriveTools import GoogleDriveHelper
from bot.helper.telegram_helper.message_utils import sendMarkup, deleteMessage, sendMessage
from bot.helper.mirror_utils.upload_utils import gdriveTools
from bot.helper.telegram_helper.message_utils import *
from bot.helper.telegram_helper.filters import CustomFilters
from bot.helper.telegram_helper.bot_commands import BotCommands
from bot import dispatcher, LOGGER, CLONE_LIMIT, STOP_DUPLICATE_CLONE
from bot.helper.ext_utils.bot_utils import get_readable_file_size
from bot.helper.mirror_utils.status_utils.clone_status import CloneStatus
from bot import dispatcher, LOGGER, CLONE_LIMIT, STOP_DUPLICATE_CLONE, download_dict, download_dict_lock, Interval, DOWNLOAD_STATUS_UPDATE_INTERVAL
from bot.helper.ext_utils.bot_utils import get_readable_file_size, setInterval
import random
import string
def cloneNode(update, context):
args = update.message.text.split(" ", maxsplit=1)
if len(args) > 1:
link = args[1]
gd = GoogleDriveHelper()
if CLONE_LIMIT is not None or STOP_DUPLICATE_CLONE:
res, clonesize, name = gd.clonehelper(link)
if res != "":
sendMessage(res, context.bot, update)
return
if STOP_DUPLICATE_CLONE:
LOGGER.info(f"Checking File/Folder if already in Drive...")
smsg, button = gd.drive_list(name)
if smsg:
msg3 = "File/Folder is already available in Drive.\nHere are the search results:"
sendMarkup(msg3, context.bot, update, button)
gd = gdriveTools.GoogleDriveHelper()
res, clonesize, name, files = gd.clonehelper(link)
if res != "":
sendMessage(res, context.bot, update)
return
if STOP_DUPLICATE_CLONE:
LOGGER.info(f"Checking File/Folder if already in Drive...")
smsg, button = gd.drive_list(name)
if smsg:
msg3 = "File/Folder is already available in Drive.\nHere are the search results:"
sendMarkup(msg3, context.bot, update, button)
return
if CLONE_LIMIT is not None:
LOGGER.info(f"Checking File/Folder Size...")
limit = CLONE_LIMIT
limit = limit.split(' ', maxsplit=1)
limitint = int(limit[0])
msg2 = f'Failed, Clone limit is {CLONE_LIMIT}.\nYour File/Folder size is {get_readable_file_size(clonesize)}.'
if 'G' in limit[1] or 'g' in limit[1]:
if clonesize > limitint * 1024**3:
sendMessage(msg2, context.bot, update)
return
if CLONE_LIMIT is not None:
LOGGER.info(f"Checking File/Folder Size...")
limit = CLONE_LIMIT
limit = limit.split(' ', maxsplit=1)
limitint = int(limit[0])
msg2 = f'Failed, Clone limit is {CLONE_LIMIT}.\nYour File/Folder size is {get_readable_file_size(clonesize)}.'
if 'G' in limit[1] or 'g' in limit[1]:
if clonesize > limitint * 1024**3:
sendMessage(msg2, context.bot, update)
return
elif 'T' in limit[1] or 't' in limit[1]:
if clonesize > limitint * 1024**4:
sendMessage(msg2, context.bot, update)
return
msg = sendMessage(f"Cloning: <code>{link}</code>", context.bot, update)
result, button = gd.clone(link)
deleteMessage(context.bot, msg)
if button == "":
sendMessage(result, context.bot, update)
elif 'T' in limit[1] or 't' in limit[1]:
if clonesize > limitint * 1024**4:
sendMessage(msg2, context.bot, update)
return
if files < 15:
msg = sendMessage(f"Cloning: <code>{link}</code>", context.bot, update)
result, button = gd.clone(link)
deleteMessage(context.bot, msg)
else:
drive = gdriveTools.GoogleDriveHelper(name)
gid = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=12))
clone_status = CloneStatus(drive, clonesize, update, gid)
with download_dict_lock:
download_dict[update.message.message_id] = clone_status
if len(Interval) == 0:
Interval.append(setInterval(DOWNLOAD_STATUS_UPDATE_INTERVAL, update_all_messages))
sendStatusMessage(update, context.bot)
result, button = drive.clone(link)
if update.message.from_user.username:
uname = f'@{update.message.from_user.username}'
else:
uname = f'<a href="tg://user?id={update.message.from_user.id}">{update.message.from_user.first_name}</a>'
if uname is not None:
cc = f'\n\ncc: {uname}'
men = f'{uname} '
if button == "cancelled":
sendMessage(men + result, context.bot, update)
elif button == "":
sendMessage(men + result, context.bot, update)
else:
if update.message.from_user.username:
uname = f'@{update.message.from_user.username}'
else:
uname = f'<a href="tg://user?id={update.message.from_user.id}">{update.message.from_user.first_name}</a>'
if uname is not None:
cc = f'\n\ncc: {uname}'
sendMarkup(result + cc, context.bot, update, button)
try:
with download_dict_lock:
del download_dict[update.message.message_id]
count = len(download_dict)
if count == 0:
Interval[0].cancel()
del Interval[0]
delete_all_messages()
else:
update_all_messages()
except IndexError:
pass
else:
sendMessage('Provide G-Drive Shareable Link to Clone.', context.bot, update)

View File

@ -302,7 +302,7 @@ def _mirror(bot, update, isTar=False, extract=False):
if not isTar and not extract:
sendMessage(f"Use /{BotCommands.CloneCommand} to clone Google Drive file/folder\nUse /{BotCommands.TarMirrorCommand} to make tar of Google Drive folder\nUse /{BotCommands.UnzipMirrorCommand} to extracts archive Google Drive file", bot, update)
return
res, size, name = gdriveTools.GoogleDriveHelper().clonehelper(link)
res, size, name, files = gdriveTools.GoogleDriveHelper().clonehelper(link)
if res != "":
sendMessage(res, bot, update)
return