parent
aa8428fdfa
commit
0096b6328c
|
|
@ -1,4 +1,4 @@
|
|||
FROM lzzy12/mega-sdk-python:latest
|
||||
FROM ubuntu:18.04
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
RUN chmod 777 /usr/src/app
|
||||
|
|
@ -24,5 +24,3 @@ COPY netrc /root/.netrc
|
|||
RUN chmod +x aria.sh
|
||||
|
||||
CMD ["bash","start.sh"]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -60,10 +60,7 @@ Fill up rest of the fields. Meaning of each fields are discussed below:
|
|||
- **API_KEY** : This is to authenticate to your telegram account for downloading Telegram files. You can get this from https://my.telegram.org DO NOT put this in quotes.
|
||||
- **API_HASH** : This is to authenticate to your telegram account for downloading Telegram files. You can get this from https://my.telegram.org
|
||||
- **USER_SESSION_STRING** : Session string generated by running:
|
||||
- **MEGA_API_KEY**: Mega.nz api key to mirror mega.nz links. Get it from [Mega SDK Page](https://mega.nz/sdk)
|
||||
- **MEGA_EMAIL_ID**: Your email id you used to sign up on mega.nz for using premium accounts (Leave th)
|
||||
- **MEGA_PASSWORD**: Your password for your mega.nz account
|
||||
```
|
||||
|
||||
python3 generate_string_session.py
|
||||
```
|
||||
Note: You can limit maximum concurrent downloads by changing the value of MAX_CONCURRENT_DOWNLOADS in aria.sh. By default, it's set to 2
|
||||
|
|
@ -73,7 +70,7 @@ Note: You can limit maximum concurrent downloads by changing the value of MAX_CO
|
|||
- Visit the [Google Cloud Console](https://console.developers.google.com/apis/credentials)
|
||||
- Go to the OAuth Consent tab, fill it, and save.
|
||||
- Go to the Credentials tab and click Create Credentials -> OAuth Client ID
|
||||
- Choose Desktop and Create.
|
||||
- Choose Other and Create.
|
||||
- Use the download button to download your credentials.
|
||||
- Move that file to the root of mirror-bot, and rename it to credentials.json
|
||||
- Visit [Google API page](https://console.developers.google.com/apis/library)
|
||||
|
|
|
|||
|
|
@ -79,21 +79,6 @@ try:
|
|||
except KeyError as e:
|
||||
LOGGER.error("One or more env variables missing! Exiting now")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
MEGA_API_KEY = getConfig('MEGA_API_KEY')
|
||||
except KeyError:
|
||||
logging.warning('MEGA API KEY not provided!')
|
||||
MEGA_API_KEY = None
|
||||
try:
|
||||
MEGA_EMAIL_ID = getConfig('MEGA_EMAIL_ID')
|
||||
MEGA_PASSWORD = getConfig('MEGA_PASSWORD')
|
||||
if len(MEGA_EMAIL_ID) == 0 or len(MEGA_PASSWORD) == 0:
|
||||
raise KeyError
|
||||
except KeyError:
|
||||
logging.warning('MEGA Credentials not provided!')
|
||||
MEGA_EMAIL_ID = None
|
||||
MEGA_PASSWORD = None
|
||||
try:
|
||||
INDEX_URL = getConfig('INDEX_URL')
|
||||
if len(INDEX_URL) == 0:
|
||||
|
|
|
|||
|
|
@ -139,11 +139,6 @@ def is_magnet(url: str):
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
def is_mega_link(url: str):
|
||||
return "mega.nz" in url
|
||||
|
||||
|
||||
def new_thread(fn):
|
||||
"""To use as decorator to make a function call threaded.
|
||||
Needs import
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
from bot import LOGGER, MEGA_API_KEY, download_dict_lock, download_dict, MEGA_EMAIL_ID, MEGA_PASSWORD
|
||||
import threading
|
||||
from mega import (MegaApi, MegaListener, MegaRequest, MegaTransfer, MegaError)
|
||||
from bot.helper.telegram_helper.message_utils import update_all_messages
|
||||
import os
|
||||
from bot.helper.mirror_utils.status_utils.mega_download_status import MegaDownloadStatus
|
||||
import random
|
||||
import string
|
||||
|
||||
class MegaDownloaderException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class MegaAppListener(MegaListener):
|
||||
_NO_EVENT_ON = (MegaRequest.TYPE_LOGIN,
|
||||
MegaRequest.TYPE_FETCH_NODES)
|
||||
|
||||
def __init__(self, continue_event: threading.Event, listener):
|
||||
self.continue_event = continue_event
|
||||
self.node = None
|
||||
self.listener = listener
|
||||
self.uid = listener.uid
|
||||
self.__bytes_transferred = 0
|
||||
self.is_cancelled = False
|
||||
self.__speed = 0
|
||||
self.__name = ''
|
||||
self.__size = 0
|
||||
self.error = None
|
||||
self.gid = ""
|
||||
super(MegaAppListener, self).__init__()
|
||||
|
||||
@property
|
||||
def speed(self):
|
||||
"""Returns speed of the download in bytes/second"""
|
||||
return self.__speed
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Returns name of the download"""
|
||||
return self.__name
|
||||
|
||||
def setValues(self, name, size, gid):
|
||||
self.__name = name
|
||||
self.__size = size
|
||||
self.gid = gid
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
"""Size of download in bytes"""
|
||||
return self.__size
|
||||
|
||||
@property
|
||||
def downloaded_bytes(self):
|
||||
return self.__bytes_transferred
|
||||
|
||||
def onRequestStart(self, api, request):
|
||||
LOGGER.info('Request start ({})'.format(request))
|
||||
|
||||
def onRequestFinish(self, api, request, error):
|
||||
LOGGER.info('Mega Request finished ({}); Result: {}'
|
||||
.format(request, error))
|
||||
|
||||
request_type = request.getType()
|
||||
if request_type == MegaRequest.TYPE_LOGIN:
|
||||
api.fetchNodes()
|
||||
elif request_type == MegaRequest.TYPE_GET_PUBLIC_NODE:
|
||||
self.node = request.getPublicMegaNode()
|
||||
elif request_type == MegaRequest.TYPE_FETCH_NODES:
|
||||
LOGGER.info("Fetching Root Node.")
|
||||
self.node = api.getRootNode()
|
||||
if request_type not in self._NO_EVENT_ON:
|
||||
self.continue_event.set()
|
||||
|
||||
def onRequestTemporaryError(self, api, request, error: MegaError):
|
||||
self.listener.onDownloadError(error.toString())
|
||||
self.error = error.toString()
|
||||
self.continue_event.set()
|
||||
|
||||
def onTransferStart(self, api: MegaApi, transfer: MegaTransfer):
|
||||
LOGGER.info(f"Transfer Started: {transfer.getFileName()}")
|
||||
|
||||
def onTransferUpdate(self, api: MegaApi, transfer: MegaTransfer):
|
||||
if self.is_cancelled:
|
||||
api.cancelTransfer(transfer, None)
|
||||
self.__speed = transfer.getSpeed()
|
||||
self.__bytes_transferred = transfer.getTransferredBytes()
|
||||
|
||||
def onTransferFinish(self, api: MegaApi, transfer: MegaTransfer, error):
|
||||
try:
|
||||
LOGGER.info(f'Transfer finished ({transfer}); Result: {transfer.getFileName()}')
|
||||
if str(error) != "No error" and self.is_cancelled:
|
||||
self.is_cancelled = False
|
||||
return self.listener.onDownloadError(error.toString())
|
||||
if transfer.isFolderTransfer() and transfer.isFinished() and not self.is_cancelled or transfer.getFileName() == self.name and not self.is_cancelled:
|
||||
self.listener.onDownloadComplete()
|
||||
except Exception as e:
|
||||
LOGGER.error(e)
|
||||
|
||||
def onTransferTemporaryError(self, api, transfer, error):
|
||||
LOGGER.info(f'Mega download error in file {transfer} {transfer.getFileName()}: {error}')
|
||||
self.listener.onDownloadError(error.toString())
|
||||
self.error = error.toString()
|
||||
self.continue_event.set()
|
||||
|
||||
def cancel_download(self):
|
||||
self.is_cancelled = True
|
||||
|
||||
|
||||
class AsyncExecutor:
|
||||
|
||||
def __init__(self):
|
||||
self.continue_event = threading.Event()
|
||||
|
||||
def do(self, function, args):
|
||||
self.continue_event.clear()
|
||||
function(*args)
|
||||
self.continue_event.wait()
|
||||
|
||||
|
||||
class MegaDownloadHelper:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def add_download(mega_link: str, path: str, listener):
|
||||
if MEGA_API_KEY is None:
|
||||
raise MegaDownloaderException('Mega API KEY not provided! Cannot mirror mega links')
|
||||
executor = AsyncExecutor()
|
||||
api = MegaApi(MEGA_API_KEY, None, None, 'telegram-mirror-bot')
|
||||
mega_listener = MegaAppListener(executor.continue_event, listener)
|
||||
os.makedirs(path)
|
||||
api.addListener(mega_listener)
|
||||
if MEGA_EMAIL_ID is not None and MEGA_PASSWORD is not None:
|
||||
executor.do(api.login, (MEGA_EMAIL_ID, MEGA_PASSWORD))
|
||||
executor.do(api.getPublicNode, (mega_link,))
|
||||
node = mega_listener.node
|
||||
if node is None:
|
||||
executor.do(api.loginToFolder, (mega_link,))
|
||||
node = mega_listener.node
|
||||
if mega_listener.error is not None:
|
||||
return listener.onDownloadError(str(mega_listener.error))
|
||||
gid = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=8))
|
||||
mega_listener.setValues(node.getName(), api.getSize(node), gid)
|
||||
with download_dict_lock:
|
||||
download_dict[listener.uid] = MegaDownloadStatus(mega_listener, listener)
|
||||
threading.Thread(target=executor.do, args=(api.startDownload, (node, path))).start()
|
||||
update_all_messages()
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
from bot.helper.ext_utils.bot_utils import get_readable_file_size,MirrorStatus, get_readable_time
|
||||
from bot import DOWNLOAD_DIR
|
||||
from .status import Status
|
||||
|
||||
|
||||
class MegaDownloadStatus(Status):
|
||||
|
||||
def __init__(self, obj, listener):
|
||||
self.uid = obj.uid
|
||||
self.listener = listener
|
||||
self.obj = obj
|
||||
|
||||
def name(self) -> str:
|
||||
return self.obj.name
|
||||
|
||||
def progress_raw(self):
|
||||
try:
|
||||
return round(self.processed_bytes() / self.obj.size * 100,2)
|
||||
except ZeroDivisionError:
|
||||
return 0.0
|
||||
|
||||
def progress(self):
|
||||
"""Progress of download in percentage"""
|
||||
return f"{self.progress_raw()}%"
|
||||
|
||||
def status(self) -> str:
|
||||
return MirrorStatus.STATUS_DOWNLOADING
|
||||
|
||||
def processed_bytes(self):
|
||||
return self.obj.downloaded_bytes
|
||||
|
||||
def eta(self):
|
||||
try:
|
||||
seconds = (self.size_raw() - self.processed_bytes()) / self.speed_raw()
|
||||
return f'{get_readable_time(seconds)}'
|
||||
except ZeroDivisionError:
|
||||
return '-'
|
||||
|
||||
def size_raw(self):
|
||||
return self.obj.size
|
||||
|
||||
def size(self) -> str:
|
||||
return get_readable_file_size(self.size_raw())
|
||||
|
||||
def downloaded(self) -> str:
|
||||
return get_readable_file_size(self.obj.downloadedBytes)
|
||||
|
||||
def speed_raw(self):
|
||||
return self.obj.speed
|
||||
|
||||
def speed(self) -> str:
|
||||
return f'{get_readable_file_size(self.speed_raw())}/s'
|
||||
|
||||
def gid(self) -> str:
|
||||
return self.obj.gid
|
||||
|
||||
def path(self) -> str:
|
||||
return f"{DOWNLOAD_DIR}{self.uid}"
|
||||
|
||||
def download(self):
|
||||
return self.obj
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
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, NotSupportedExtractionArchive
|
||||
from bot.helper.mirror_utils.download_utils.aria2_download import AriaDownloadHelper
|
||||
from bot.helper.mirror_utils.download_utils.mega_downloader import MegaDownloadHelper
|
||||
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
|
||||
|
|
@ -28,7 +27,7 @@ ariaDlManager.start_listener()
|
|||
|
||||
|
||||
class MirrorListener(listeners.MirrorListeners):
|
||||
def __init__(self, bot, update, isTar=False, tag=None, extract=False):
|
||||
def __init__(self, bot, update, isTar=False,tag=None, extract=False):
|
||||
super().__init__(bot, update)
|
||||
self.isTar = isTar
|
||||
self.tag = tag
|
||||
|
|
@ -172,7 +171,6 @@ class MirrorListener(listeners.MirrorListeners):
|
|||
else:
|
||||
update_all_messages()
|
||||
|
||||
|
||||
def _mirror(bot, update, isTar=False, extract=False):
|
||||
message_args = update.message.text.split(' ')
|
||||
try:
|
||||
|
|
@ -214,11 +212,7 @@ def _mirror(bot, update, isTar=False, extract=False):
|
|||
except DirectDownloadLinkException as e:
|
||||
LOGGER.info(f'{link}: {e}')
|
||||
listener = MirrorListener(bot, update, isTar, tag, extract)
|
||||
if bot_utils.is_mega_link(link):
|
||||
mega_dl = MegaDownloadHelper()
|
||||
mega_dl.add_download(link, f'{DOWNLOAD_DIR}/{listener.uid}/', listener)
|
||||
else:
|
||||
ariaDlManager.add_download(link, f'{DOWNLOAD_DIR}/{listener.uid}/', listener)
|
||||
ariaDlManager.add_download(link, f'{DOWNLOAD_DIR}/{listener.uid}/',listener)
|
||||
sendStatusMessage(update, bot)
|
||||
if len(Interval) == 0:
|
||||
Interval.append(setInterval(DOWNLOAD_STATUS_UPDATE_INTERVAL, update_all_messages))
|
||||
|
|
@ -236,7 +230,7 @@ def tar_mirror(update, context):
|
|||
|
||||
@run_async
|
||||
def unzip_mirror(update, context):
|
||||
_mirror(context.bot, update, extract=True)
|
||||
_mirror(context.bot,update, extract=True)
|
||||
|
||||
|
||||
mirror_handler = CommandHandler(BotCommands.MirrorCommand, mirror,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,3 @@ USER_SESSION_STRING = ""
|
|||
TELEGRAM_API =
|
||||
TELEGRAM_HASH = ""
|
||||
USE_SERVICE_ACCOUNTS = ""
|
||||
MEGA_API_KEY = ""
|
||||
MEGA_EMAIL_ID = ""
|
||||
MEGA_PASSWORD = ""
|
||||
Loading…
Reference in New Issue