Separated telegram related code from download upload related code
Signed-off-by: lzzy12 <jhashivam2020@gmail.com>
This commit is contained in:
parent
d6b6933ee8
commit
1c56b18724
|
|
@ -6,4 +6,7 @@ config.ini
|
||||||
downloads/*
|
downloads/*
|
||||||
download/*
|
download/*
|
||||||
data*
|
data*
|
||||||
.vscode
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.json
|
||||||
|
*.pickle
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
This is a telegram bot writen in python for mirroring files on the internet to our beloved Google Drive.\n
|
||||||
|
Documentation is coming as soon as we finish implementing all the basic features of the bot
|
||||||
2
aria.sh
2
aria.sh
|
|
@ -1 +1 @@
|
||||||
aria2c --enable-rpc --rpc-listen-all=false --rpc-listen-port 6800 --max-connection-per-server=10 --rpc-max-request-size=1024M --seed-time=0.01 --min-split-size=10M --follow-torrent=mem --split=10 --daemon=true --allow-overwrite=true
|
aria2c --enable-rpc --rpc-listen-all=false --rpc-listen-port 6800 --max-connection-per-server=10 --rpc-max-request-size=1024M --seed-time=0.01 --min-split-size=10M --follow-torrent=mem --split=10 --daemon=true --allow-overwrite=true
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
import logging
|
import logging
|
||||||
import configparser
|
import configparser
|
||||||
from telegram.ext import Updater
|
from telegram.ext import Updater
|
||||||
|
|
||||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||||
level=logging.INFO)
|
level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read('bot/config.ini')
|
config.read('bot/config.ini')
|
||||||
|
|
||||||
|
|
||||||
def getConfig(name: str):
|
def getConfig(name: str):
|
||||||
return config['DEFAULT'][name]
|
return config['DEFAULT'][name]
|
||||||
|
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -21,13 +20,23 @@ try:
|
||||||
exit()
|
exit()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
BOT_TOKEN = getConfig('BOT_TOKEN')
|
DOWNLOAD_DIR = None
|
||||||
CLIENT_ID = getConfig('G_DRIVE_CLIENT_ID')
|
BOT_TOKEN = None
|
||||||
CLIENT_SECRET = getConfig('G_DRIVE_CLIENT_SECRET')
|
try:
|
||||||
parent_id = getConfig('GDRIVE_FOLDER_ID')
|
BOT_TOKEN = getConfig('BOT_TOKEN')
|
||||||
DOWNLOAD_DIR = getConfig('DOWNLOAD_DIR')
|
CLIENT_ID = getConfig('G_DRIVE_CLIENT_ID')
|
||||||
if DOWNLOAD_DIR[-1] != '/' or DOWNLOAD_DIR[-1] != '\\':
|
CLIENT_SECRET = getConfig('G_DRIVE_CLIENT_SECRET')
|
||||||
DOWNLOAD_DIR = DOWNLOAD_DIR + '/'
|
parent_id = getConfig('GDRIVE_FOLDER_ID')
|
||||||
|
DOWNLOAD_DIR = getConfig('DOWNLOAD_DIR')
|
||||||
|
if DOWNLOAD_DIR[-1] != '/' or DOWNLOAD_DIR[-1] != '\\':
|
||||||
|
DOWNLOAD_DIR = DOWNLOAD_DIR + '/'
|
||||||
|
DOWNLOAD_STATUS_UPDATE_INTERVAL = int(getConfig('DOWNLOAD_STATUS_UPDATE_INTERVAL'))
|
||||||
|
download_list = {}
|
||||||
|
|
||||||
|
except KeyError as e:
|
||||||
|
LOGGER.error("One or more env variables missing! Exiting now")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
updater = Updater(token=BOT_TOKEN, use_context=True)
|
updater = Updater(token=BOT_TOKEN, use_context=True)
|
||||||
dispatcher = updater.dispatcher
|
dispatcher = updater.dispatcher
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,21 @@ from telegram.ext import CommandHandler, run_async
|
||||||
from bot import dispatcher, LOGGER, updater
|
from bot import dispatcher, LOGGER, updater
|
||||||
import bot.mirror
|
import bot.mirror
|
||||||
|
|
||||||
|
|
||||||
@run_async
|
@run_async
|
||||||
def start(update, context):
|
def start(update, context):
|
||||||
print(update)
|
print(update)
|
||||||
context.bot.send_message(chat_id=update.message.chat_id, text="I'm a bot, please talk to me!")
|
context.bot.send_message(chat_id=update.message.chat_id, text="I'm a bot, please talk to me!")
|
||||||
|
|
||||||
|
|
||||||
LOGGER.info('__main__.py')
|
LOGGER.info('__main__.py')
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
start_handler = CommandHandler('start', start)
|
start_handler = CommandHandler('start', start)
|
||||||
dispatcher.add_handler(start_handler)
|
dispatcher.add_handler(start_handler)
|
||||||
LOGGER.info("Bot Started!")
|
LOGGER.info("Bot Started!")
|
||||||
updater.start_polling()
|
updater.start_polling()
|
||||||
|
|
||||||
main()
|
|
||||||
|
main()
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,5 @@ BOT_TOKEN =
|
||||||
G_DRIVE_CLIENT_ID =
|
G_DRIVE_CLIENT_ID =
|
||||||
G_DRIVE_CLIENT_SECRET =
|
G_DRIVE_CLIENT_SECRET =
|
||||||
GDRIVE_FOLDER_ID =
|
GDRIVE_FOLDER_ID =
|
||||||
DOWNLOAD_DIR = ./download
|
DOWNLOAD_DIR = ./download
|
||||||
|
DOWNLOAD_STATUS_UPDATE_INTERVAL = 5
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
import aria2p
|
|
||||||
import os
|
|
||||||
from time import sleep
|
|
||||||
from bot import LOGGER,DOWNLOAD_DIR
|
|
||||||
|
|
||||||
|
|
||||||
EDIT_SLEEP_TIME_OUT = 5
|
|
||||||
|
|
||||||
aria2 = aria2p.API(
|
|
||||||
aria2p.Client(
|
|
||||||
host="http://localhost",
|
|
||||||
port=6800,
|
|
||||||
secret=""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
allDls = {}
|
|
||||||
|
|
||||||
def check_metadata(gid):
|
|
||||||
file = aria2.get_download(gid)
|
|
||||||
if file.followed_by_ids[0] != None:
|
|
||||||
new_gid = file.followed_by_ids[0]
|
|
||||||
LOGGER.info("Changing GID "+gid+" to "+new_gid)
|
|
||||||
return new_gid
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def add_download(link,message):
|
|
||||||
if "magnet" in link:
|
|
||||||
download = aria2.add_magnet(link,{'dir':DOWNLOAD_DIR})
|
|
||||||
allDls[message[0]] = [download,message[1]]
|
|
||||||
LOGGER.info("Adding: "+link)
|
|
||||||
return download
|
|
||||||
else:
|
|
||||||
download = aria2.add_uris([link],{'dir':DOWNLOAD_DIR})
|
|
||||||
allDls[message[0]] = [download,message[1]]
|
|
||||||
LOGGER.info("Adding: "+link)
|
|
||||||
return download
|
|
||||||
|
|
||||||
|
|
||||||
def remove_download(message):
|
|
||||||
del allDls[message]
|
|
||||||
aria2.remove_download(allDls[message].gid)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def get_file_name(download):
|
|
||||||
file = aria2.get_download(download.gid)
|
|
||||||
return file.name
|
|
||||||
|
|
||||||
def get_download_by_message(message):
|
|
||||||
if allDls[message] == None:
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
download = allDls[message]
|
|
||||||
return download[0]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def progress_status(context,update,previous):
|
|
||||||
download = get_download_by_message(update)
|
|
||||||
file = aria2.get_download(download.gid)
|
|
||||||
if not file.is_complete:
|
|
||||||
if not file.error_message:
|
|
||||||
msg = "<i>" + file.name +"</i>:- " + file.progress_string()+" of " + file.total_length_string() + \
|
|
||||||
" at " + file.download_speed_string() + " ,ETA: " + file.eta_string()
|
|
||||||
if previous != msg:
|
|
||||||
LOGGER.info("Editing message")
|
|
||||||
try:
|
|
||||||
context.bot.edit_message_text(text=msg,message_id=update.message_id,chat_id=update.chat.id,parse_mode='HTMl')
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
previous = msg
|
|
||||||
sleep(5)
|
|
||||||
return progress_status(context,update,previous)
|
|
||||||
else:
|
|
||||||
LOGGER.error(file.error_message)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
new_gid = check_metadata(file.gid)
|
|
||||||
except:
|
|
||||||
new_gid = None
|
|
||||||
pass
|
|
||||||
if new_gid:
|
|
||||||
download = aria2.get_download(new_gid)
|
|
||||||
allDls[update][0] = download
|
|
||||||
return progress_status(context,update,previous=None)
|
|
||||||
else:
|
|
||||||
LOGGER.info(file.name+" Completed.")
|
|
||||||
msg = "<i>" + file.name +"</i>:- Uploading."
|
|
||||||
context.bot.edit_message_text(text=msg,message_id=update.message_id,chat_id=update.chat.id,parse_mode='HTMl')
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
class Message:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Download:
|
||||||
|
def __init__(self, gid, download):
|
||||||
|
self.isDownloading = download.is_complete
|
||||||
|
self.gid = gid
|
||||||
|
self.download = download
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
import aria2p
|
||||||
|
from time import sleep
|
||||||
|
from bot import LOGGER, DOWNLOAD_DIR, DOWNLOAD_STATUS_UPDATE_INTERVAL, download_list
|
||||||
|
from bot.helper.listeners import *
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
from aria2p import Options
|
||||||
|
|
||||||
|
|
||||||
|
def is_url(url: str):
|
||||||
|
try:
|
||||||
|
urlparse(url)
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def is_magnet(url: str):
|
||||||
|
if "magnet" in url:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class DownloadHelper:
|
||||||
|
|
||||||
|
def __init__(self, listener: MirrorListeners):
|
||||||
|
self.__aria2 = aria2p.API(
|
||||||
|
aria2p.Client(
|
||||||
|
host="http://localhost",
|
||||||
|
port=6800,
|
||||||
|
secret="",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.__listener = listener
|
||||||
|
|
||||||
|
def add_download(self, link: str):
|
||||||
|
download = None
|
||||||
|
if is_url(link):
|
||||||
|
download = self.__aria2.add_uris([link], {'dir': DOWNLOAD_DIR + str(self.__listener.update.update_id),
|
||||||
|
'max_download_limit': 1})
|
||||||
|
elif is_magnet(link):
|
||||||
|
download = self.__aria2.add_magnet(link, {'dir': DOWNLOAD_DIR})
|
||||||
|
else:
|
||||||
|
self.__listener.onDownloadError("No download URL or URL malformed")
|
||||||
|
return
|
||||||
|
download_list[self.__listener.update.update_id] = download.gid
|
||||||
|
self.__listener.onDownloadStarted(link)
|
||||||
|
self.__update_download_status()
|
||||||
|
|
||||||
|
def get_downloads_status_str_list(self):
|
||||||
|
"""
|
||||||
|
Generates a human readable string of progress of all the downloads
|
||||||
|
:return: list of strings of progress of all the downloads
|
||||||
|
"""
|
||||||
|
str_list = []
|
||||||
|
LOGGER.info(download_list)
|
||||||
|
for gid in list(download_list.values()):
|
||||||
|
download = self.__aria2.get_download(gid)
|
||||||
|
str_list.append("<b>" + download.name + "</b>:- "
|
||||||
|
+ download.progress_string() + " of "
|
||||||
|
+ download.total_length_string()
|
||||||
|
+ " at " + download.download_speed_string()
|
||||||
|
+ " ,ETA: " + download.eta_string()
|
||||||
|
)
|
||||||
|
return str_list
|
||||||
|
|
||||||
|
def __get_download(self):
|
||||||
|
return self.__aria2.get_download(download_list[self.__listener.update.update_id])
|
||||||
|
|
||||||
|
def __update_download_status(self):
|
||||||
|
# TODO: Try to find a way to move this code to mirror.py and send only a
|
||||||
|
# list of Download objects to onDownloadProgress()
|
||||||
|
previous = None
|
||||||
|
LOGGER.info(self.get_downloads_status_str_list())
|
||||||
|
while not self.__get_download().is_complete:
|
||||||
|
if self.__get_download().has_failed:
|
||||||
|
self.__listener.onDownloadError(self.__get_download().error_message)
|
||||||
|
break
|
||||||
|
progress_str_list = self.get_downloads_status_str_list()
|
||||||
|
if progress_str_list != previous:
|
||||||
|
self.__listener.onDownloadProgress(progress_str_list)
|
||||||
|
previous = progress_str_list
|
||||||
|
sleep(DOWNLOAD_STATUS_UPDATE_INTERVAL)
|
||||||
|
|
||||||
|
self.__listener.onDownloadComplete(self.__get_download())
|
||||||
|
|
@ -1,174 +1,150 @@
|
||||||
from apiclient.discovery import build
|
from googleapiclient.discovery import build
|
||||||
from apiclient.http import MediaFileUpload
|
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||||
from apiclient.errors import ResumableUploadError
|
from google.auth.transport.requests import Request
|
||||||
from oauth2client.client import OAuth2WebServerFlow
|
from googleapiclient.http import MediaFileUpload
|
||||||
from oauth2client.file import Storage
|
import pickle
|
||||||
from oauth2client import file, client, tools
|
|
||||||
from oauth2client.client import HttpAccessTokenRefreshError
|
|
||||||
from mimetypes import guess_type
|
from mimetypes import guess_type
|
||||||
import httplib2
|
|
||||||
import os
|
import os
|
||||||
from bot import LOGGER, CLIENT_ID, CLIENT_SECRET, parent_id, DOWNLOAD_DIR
|
from bot import LOGGER, CLIENT_ID, CLIENT_SECRET, parent_id, DOWNLOAD_DIR, download_list
|
||||||
from bot.helper.exceptions import DriveAuthError
|
from .listeners import MirrorListeners
|
||||||
|
from shutil import rmtree
|
||||||
|
|
||||||
G_DRIVE_TOKEN_FILE = "auth_token.txt"
|
class GoogleDriveHelper:
|
||||||
# Check https://developers.google.com/drive/scopes for all available scopes
|
|
||||||
OAUTH_SCOPE = "https://www.googleapis.com/auth/drive.file"
|
|
||||||
# Redirect URI for installed apps, can be left as is
|
|
||||||
REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob"
|
|
||||||
G_DRIVE_DIR_MIME_TYPE = "application/vnd.google-apps.folder"
|
|
||||||
|
|
||||||
|
def __init__(self, listener: MirrorListeners):
|
||||||
|
self.__G_DRIVE_TOKEN_FILE = "token.pickle"
|
||||||
|
# Check https://developers.google.com/drive/scopes for all available scopes
|
||||||
|
self.__OAUTH_SCOPE = "https://www.googleapis.com/auth/drive.file"
|
||||||
|
# Redirect URI for installed apps, can be left as is
|
||||||
|
self.__REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob"
|
||||||
|
self.__G_DRIVE_DIR_MIME_TYPE = "application/vnd.google-apps.folder"
|
||||||
|
self.__G_DRIVE_BASE_DOWNLOAD_URL = "https://drive.google.com/uc?id={}&export=download"
|
||||||
|
self.__listener = listener
|
||||||
|
if CLIENT_ID is None or CLIENT_SECRET is None or parent_id is None:
|
||||||
|
LOGGER.error("Please Setup Config Properly.")
|
||||||
|
|
||||||
if CLIENT_ID is None or CLIENT_SECRET is None or parent_id is None:
|
self.__service = self.authorize()
|
||||||
LOGGER.error("Please Setup Config Properly.")
|
|
||||||
|
|
||||||
|
def upload_file(self, file_path, file_name, mime_type, parent_id):
|
||||||
|
# File body description
|
||||||
|
media_body = MediaFileUpload(file_path,
|
||||||
|
mimetype=mime_type,
|
||||||
|
resumable=True)
|
||||||
|
body = {
|
||||||
|
'title': file_name,
|
||||||
|
'description': 'backup',
|
||||||
|
'mimeType': mime_type,
|
||||||
|
}
|
||||||
|
if parent_id is not None:
|
||||||
|
body["parents"] = [{"id": parent_id}]
|
||||||
|
# Permissions body description: anyone who has link can upload
|
||||||
|
# Other permissions can be found at https://developers.google.com/drive/v2/reference/permissions
|
||||||
|
permissions = {
|
||||||
|
'role': 'reader',
|
||||||
|
'type': 'anyone',
|
||||||
|
'value': None,
|
||||||
|
'withLink': True
|
||||||
|
}
|
||||||
|
# Insert a file
|
||||||
|
drive_file = self.__service.files().create(body=body, media_body=media_body).execute()
|
||||||
|
# Insert new permissions
|
||||||
|
self.__service.permissions().create(fileId=drive_file['id'], body=permissions).execute()
|
||||||
|
# Define file instance and get url for download
|
||||||
|
drive_file = self.__service.files().get(fileId=drive_file['id']).execute()
|
||||||
|
download_url = self.__G_DRIVE_BASE_DOWNLOAD_URL.format(drive_file.get('id'))
|
||||||
|
return download_url
|
||||||
|
|
||||||
def upload(fileName):
|
def file_ops(self, file_path):
|
||||||
filePath = DOWNLOAD_DIR + fileName
|
mime_type = guess_type(file_path)[0]
|
||||||
try:
|
mime_type = mime_type if mime_type else "text/plain"
|
||||||
with open(G_DRIVE_TOKEN_FILE) as f:
|
file_name = file_path.split("/")[-1]
|
||||||
pass
|
return file_name, mime_type
|
||||||
except IOError:
|
|
||||||
storage = create_token_file(G_DRIVE_TOKEN_FILE)
|
|
||||||
http = authorize(G_DRIVE_TOKEN_FILE, storage)
|
|
||||||
|
|
||||||
LOGGER.info("Uploading File: "+fileName)
|
def upload(self, file_name: str):
|
||||||
if os.path.isfile(filePath):
|
self.__listener.onUploadStarted(file_name)
|
||||||
http = authorize(G_DRIVE_TOKEN_FILE, None)
|
file_dir = "{}/{}".format(DOWNLOAD_DIR, self.__listener.update.update_id)
|
||||||
file_name, mime_type = file_ops(filePath)
|
file_path = "{}/{}".format(file_dir, file_name)
|
||||||
try:
|
link = None
|
||||||
g_drive_link = upload_file(http, filePath, file_name, mime_type,parent_id)
|
LOGGER.info("Uploading File: " + file_name)
|
||||||
LOGGER.info("Uploaded To G-Drive: " + filePath)
|
if os.path.isfile(file_path):
|
||||||
link = g_drive_link
|
file_name, mime_type = self.file_ops(file_path)
|
||||||
except Exception as e:
|
try:
|
||||||
LOGGER.error(str(e))
|
g_drive_link = self.upload_file(file_path, file_name, mime_type, parent_id)
|
||||||
pass
|
LOGGER.info("Uploaded To G-Drive: " + file_path)
|
||||||
else:
|
link = g_drive_link
|
||||||
http = authorize(G_DRIVE_TOKEN_FILE, None)
|
except Exception as e:
|
||||||
file_name, mime_type = file_ops(filePath)
|
LOGGER.error(str(e))
|
||||||
try:
|
pass
|
||||||
dir_id = create_directory(http, os.path.basename(os.path.abspath(fileName)), parent_id)
|
else:
|
||||||
DoTeskWithDir(http,filePath, dir_id)
|
file_name, mime_type = self.file_ops(file_path)
|
||||||
LOGGER.info("Uploaded To G-Drive: "+fileName)
|
try:
|
||||||
dir_link = "https://drive.google.com/folderview?id={}".format(dir_id)
|
dir_id = self.create_directory(os.path.basename(os.path.abspath(file_name)), parent_id)
|
||||||
link = dir_link
|
self.upload_dir(file_path, dir_id)
|
||||||
except Exception as e:
|
LOGGER.info("Uploaded To G-Drive: " + file_name)
|
||||||
LOGGER.error(str(e))
|
link = "https://drive.google.com/folderview?id={}".format(dir_id)
|
||||||
raise Exception('Error: {}'.format(str(e)))
|
except Exception as e:
|
||||||
return link
|
LOGGER.error(str(e))
|
||||||
|
self.__listener.onUploadError(str(e))
|
||||||
|
raise Exception('Error: {}'.format(str(e)))
|
||||||
|
del download_list[self.__listener.update.update_id]
|
||||||
|
LOGGER.info(download_list)
|
||||||
|
self.__listener.onUploadComplete(link, file_name)
|
||||||
|
LOGGER.info("Deleting downloaded file/folder..")
|
||||||
|
rmtree(file_dir)
|
||||||
|
return link
|
||||||
|
|
||||||
def create_directory(http, directory_name, parent_id):
|
def create_directory(self, directory_name, parent_id):
|
||||||
drive_service = build("drive", "v2", http=http, cache_discovery=False)
|
permissions = {
|
||||||
permissions = {
|
"role": "reader",
|
||||||
"role": "reader",
|
"type": "anyone",
|
||||||
"type": "anyone",
|
"value": None,
|
||||||
"value": None,
|
"withLink": True
|
||||||
"withLink": True
|
}
|
||||||
}
|
file_metadata = {
|
||||||
file_metadata = {
|
"title": directory_name,
|
||||||
"title": directory_name,
|
"mimeType": self.__G_DRIVE_DIR_MIME_TYPE
|
||||||
"mimeType": G_DRIVE_DIR_MIME_TYPE
|
}
|
||||||
}
|
if parent_id is not None:
|
||||||
if parent_id is not None:
|
file_metadata["parents"] = [{"id": parent_id}]
|
||||||
file_metadata["parents"] = [{"id": parent_id}]
|
file = self.__service.files().create(body=file_metadata).execute()
|
||||||
file = drive_service.files().insert(body=file_metadata).execute()
|
file_id = file.get("id")
|
||||||
file_id = file.get("id")
|
self.__service.permissions().create(fileId=file_id, body=permissions).execute()
|
||||||
drive_service.permissions().insert(fileId=file_id, body=permissions).execute()
|
LOGGER.info("Created Google-Drive Folder:\nName: {}\nID: {} ".format(file.get("title"), file_id))
|
||||||
LOGGER.info("Created Gdrive Folder:\nName: {}\nID: {} ".format(file.get("title"), file_id))
|
return file_id
|
||||||
return file_id
|
|
||||||
|
|
||||||
|
|
||||||
def DoTeskWithDir(http, input_directory, parent_id):
|
|
||||||
list_dirs = os.listdir(input_directory)
|
|
||||||
if len(list_dirs) == 0:
|
|
||||||
return parent_id
|
|
||||||
r_p_id = None
|
|
||||||
for a_c_f_name in list_dirs:
|
|
||||||
current_file_name = os.path.join(input_directory, a_c_f_name)
|
|
||||||
if os.path.isdir(current_file_name):
|
|
||||||
current_dir_id = create_directory(http, a_c_f_name, parent_id)
|
|
||||||
r_p_id = DoTeskWithDir(http, current_file_name,current_dir_id)
|
|
||||||
else:
|
|
||||||
file_name, mime_type = file_ops(current_file_name)
|
|
||||||
# current_file_name will have the full path
|
|
||||||
g_drive_link = upload_file(http, current_file_name, file_name, mime_type, parent_id)
|
|
||||||
r_p_id = parent_id
|
|
||||||
# TODO: there is a #bug here :(
|
|
||||||
return r_p_id
|
|
||||||
|
|
||||||
def file_ops(file_path):
|
|
||||||
mime_type = guess_type(file_path)[0]
|
|
||||||
mime_type = mime_type if mime_type else "text/plain"
|
|
||||||
file_name = file_path.split("/")[-1]
|
|
||||||
return file_name, mime_type
|
|
||||||
|
|
||||||
|
|
||||||
def create_token_file(token_file):
|
|
||||||
# Run through the OAuth flow and retrieve credentials
|
|
||||||
flow = OAuth2WebServerFlow(
|
|
||||||
CLIENT_ID,
|
|
||||||
CLIENT_SECRET,
|
|
||||||
OAUTH_SCOPE,
|
|
||||||
redirect_uri=REDIRECT_URI
|
|
||||||
)
|
|
||||||
authorize_url = flow.step1_get_authorize_url()
|
|
||||||
print('Go to the following link in your browser: ' + authorize_url)
|
|
||||||
code = input('Enter verification code: ').strip()
|
|
||||||
credentials = flow.step2_exchange(code)
|
|
||||||
storage = Storage(token_file)
|
|
||||||
storage.put(credentials)
|
|
||||||
return storage
|
|
||||||
|
|
||||||
def authorize(token_file, storage):
|
|
||||||
# Get credentials
|
|
||||||
if storage is None:
|
|
||||||
storage = Storage(token_file)
|
|
||||||
credentials = storage.get()
|
|
||||||
# Create an httplib2.Http object and authorize it with our credentials
|
|
||||||
try:
|
|
||||||
http = httplib2.Http()
|
|
||||||
credentials.refresh(http)
|
|
||||||
http = credentials.authorize(http)
|
|
||||||
except HttpAccessTokenRefreshError as e:
|
|
||||||
LOGGER.error(str(e))
|
|
||||||
LOGGER.info('Deleting {} file'.format(G_DRIVE_TOKEN_FILE))
|
|
||||||
os.remove(G_DRIVE_TOKEN_FILE)
|
|
||||||
raise DriveAuthError(str(e))
|
|
||||||
return http
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def upload_file(http, file_path,file_name, mime_type, parent_id):
|
|
||||||
# Create Google Drive service instance
|
|
||||||
drive_service = build('drive', 'v2', http=http, cache_discovery=False)
|
|
||||||
# File body description
|
|
||||||
media_body = MediaFileUpload(file_path,
|
|
||||||
mimetype=mime_type,
|
|
||||||
resumable=True)
|
|
||||||
body = {
|
|
||||||
'title': file_name,
|
|
||||||
'description': 'backup',
|
|
||||||
'mimeType': mime_type,
|
|
||||||
}
|
|
||||||
if parent_id is not None:
|
|
||||||
body["parents"] = [{"id": parent_id}]
|
|
||||||
# Permissions body description: anyone who has link can upload
|
|
||||||
# Other permissions can be found at https://developers.google.com/drive/v2/reference/permissions
|
|
||||||
permissions = {
|
|
||||||
'role': 'reader',
|
|
||||||
'type': 'anyone',
|
|
||||||
'value': None,
|
|
||||||
'withLink': True
|
|
||||||
}
|
|
||||||
# Insert a file
|
|
||||||
file = drive_service.files().insert(body=body, media_body=media_body).execute()
|
|
||||||
# Insert new permissions
|
|
||||||
drive_service.permissions().insert(fileId=file['id'], body=permissions).execute()
|
|
||||||
# Define file instance and get url for download
|
|
||||||
file = drive_service.files().get(fileId=file['id']).execute()
|
|
||||||
download_url = file.get('webContentLink')
|
|
||||||
return download_url
|
|
||||||
|
|
||||||
|
def upload_dir(self, input_directory, parent_id):
|
||||||
|
list_dirs = os.listdir(input_directory)
|
||||||
|
if len(list_dirs) == 0:
|
||||||
|
return parent_id
|
||||||
|
r_p_id = None
|
||||||
|
for a_c_f_name in list_dirs:
|
||||||
|
current_file_name = os.path.join(input_directory, a_c_f_name)
|
||||||
|
if os.path.isdir(current_file_name):
|
||||||
|
current_dir_id = self.create_directory(a_c_f_name, parent_id)
|
||||||
|
r_p_id = self.upload_dir(current_file_name, current_dir_id)
|
||||||
|
else:
|
||||||
|
file_name, mime_type = self.file_ops(current_file_name)
|
||||||
|
# current_file_name will have the full path
|
||||||
|
self.upload_file(current_file_name, file_name, mime_type, parent_id)
|
||||||
|
r_p_id = parent_id
|
||||||
|
return r_p_id
|
||||||
|
|
||||||
|
def authorize(self):
|
||||||
|
# Get credentials
|
||||||
|
credentials = None
|
||||||
|
if os.path.exists(self.__G_DRIVE_TOKEN_FILE):
|
||||||
|
with open(self.__G_DRIVE_TOKEN_FILE, 'rb') as f:
|
||||||
|
credentials = pickle.load(f)
|
||||||
|
if credentials is None or not credentials.valid:
|
||||||
|
if credentials and credentials.expired and credentials.refresh_token:
|
||||||
|
credentials.refresh(Request())
|
||||||
|
else:
|
||||||
|
flow = InstalledAppFlow.from_client_secrets_file(
|
||||||
|
'credentials.json', self.__OAUTH_SCOPE)
|
||||||
|
LOGGER.info(flow)
|
||||||
|
credentials = flow.run_local_server(port=0)
|
||||||
|
|
||||||
|
# Save the credentials for the next run
|
||||||
|
with open(self.__G_DRIVE_TOKEN_FILE, 'wb') as token:
|
||||||
|
pickle.dump(credentials, token)
|
||||||
|
return build('drive', 'v3', credentials=credentials, cache_discovery=False)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
class MirrorListeners:
|
||||||
|
def __init__(self, context, update, reply_message):
|
||||||
|
self.context = context
|
||||||
|
self.update = update
|
||||||
|
self.reply_message = reply_message
|
||||||
|
|
||||||
|
def onDownloadStarted(self, link: str):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def onDownloadProgress(self, progress_str_list: list):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def onDownloadComplete(self, download):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def onDownloadError(self, error: str):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def onUploadStarted(self, filename: str):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def onUploadComplete(self, link: str, file_name: str):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def onUploadError(self, error: str):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
@ -1,27 +1,72 @@
|
||||||
from telegram.ext import CommandHandler, run_async
|
from telegram.ext import CommandHandler, run_async
|
||||||
from bot.helper import ariaTools, gdriveTools
|
from bot.helper import download_tools, gdriveTools, listeners
|
||||||
from bot import config, LOGGER, dispatcher
|
from bot import config, LOGGER, dispatcher
|
||||||
from bot.helper.exceptions import DriveAuthError
|
from bot.helper.exceptions import DriveAuthError
|
||||||
|
|
||||||
LOGGER.info('mirror.py')
|
LOGGER.info('mirror.py')
|
||||||
|
|
||||||
|
|
||||||
|
class MirrorListener(listeners.MirrorListeners):
|
||||||
|
def __init__(self, context, update, reply_message):
|
||||||
|
super().__init__(context, update, reply_message)
|
||||||
|
|
||||||
|
def onDownloadStarted(self, link):
|
||||||
|
LOGGER.info("Adding link: " + link)
|
||||||
|
|
||||||
|
def onDownloadProgress(self, progress_str_list: list):
|
||||||
|
LOGGER.info("Editing message")
|
||||||
|
msg = "Status:\n"
|
||||||
|
for progress_str in progress_str_list:
|
||||||
|
msg += progress_str + '\n\n'
|
||||||
|
self.context.bot.edit_message_text(text=msg, message_id=self.reply_message.message_id,
|
||||||
|
chat_id=self.reply_message.chat.id,
|
||||||
|
parse_mode='HTMl')
|
||||||
|
|
||||||
|
def onDownloadComplete(self, download):
|
||||||
|
msg = "Downloaded"
|
||||||
|
LOGGER.info("Download completed")
|
||||||
|
self.context.bot.edit_message_text(text=msg, message_id=self.reply_message.message_id,
|
||||||
|
chat_id=self.reply_message.chat.id,
|
||||||
|
parse_mode='HTMl')
|
||||||
|
gdrive = gdriveTools.GoogleDriveHelper(self)
|
||||||
|
gdrive.upload(download.name)
|
||||||
|
|
||||||
|
def onDownloadError(self, error):
|
||||||
|
LOGGER.error(error)
|
||||||
|
self.context.bot.edit_message_text(text=error, message_id=self.reply_message.message_id,
|
||||||
|
chat_id=self.reply_message.chat.id,
|
||||||
|
parse_mode='HTMl')
|
||||||
|
|
||||||
|
def onUploadStarted(self, filename: str):
|
||||||
|
msg = "<i>" + filename + "</i>:- Uploading."
|
||||||
|
self.context.bot.edit_message_text(text=msg, message_id=self.reply_message.message_id,
|
||||||
|
chat_id=self.reply_message.chat.id,
|
||||||
|
parse_mode='HTMl')
|
||||||
|
|
||||||
|
def onUploadComplete(self, link: str, file_name: str):
|
||||||
|
msg = '<a href="{}">{}</a>'.format(link, file_name)
|
||||||
|
self.context.bot.delete_message(chat_id=self.reply_message.chat.id, message_id=self.reply_message.message_id)
|
||||||
|
self.context.bot.send_message(chat_id=self.update.message.chat_id,
|
||||||
|
reply_to_message_id=self.update.message.message_id,
|
||||||
|
text=msg, parse_mode='HTMl')
|
||||||
|
|
||||||
|
def onUploadError(self, error: str):
|
||||||
|
LOGGER.error(error)
|
||||||
|
self.context.bot.edit_message_text(text=error, message_id=self.reply_message.message_id,
|
||||||
|
chat_id=self.reply_message.chat.id,
|
||||||
|
parse_mode='HTMl')
|
||||||
|
|
||||||
|
|
||||||
@run_async
|
@run_async
|
||||||
def mirror(update,context):
|
def mirror(update, context):
|
||||||
message = update.message.text
|
message = update.message.text
|
||||||
link = message.replace('/mirror','')[1:]
|
link = message.replace('/mirror', '')[1:]
|
||||||
reply_msg = context.bot.send_message(chat_id=update.message.chat_id, reply_to_message_id=update.message.message_id, text="Starting Download")
|
reply_msg = context.bot.send_message(chat_id=update.message.chat_id, reply_to_message_id=update.message.message_id,
|
||||||
download = ariaTools.add_download(link,[reply_msg,update])
|
text="Starting Download")
|
||||||
ariaTools.progress_status(context,reply_msg,previous=None)
|
listener = MirrorListener(context, update, reply_msg)
|
||||||
file_name = ariaTools.get_file_name(download)
|
aria = download_tools.DownloadHelper(listener)
|
||||||
LOGGER.info("File-Name: "+file_name)
|
aria.add_download(link)
|
||||||
try:
|
|
||||||
link = gdriveTools.upload(file_name)
|
|
||||||
msg = '<a href="{}">{}</a>'.format(link,file_name)
|
|
||||||
except DriveAuthError as e:
|
|
||||||
msg = 'Authentication error: {}'.format(str(e))
|
|
||||||
except Exception as e:
|
|
||||||
msg = str(e)
|
|
||||||
|
|
||||||
context.bot.edit_message_text(text=msg,message_id=reply_msg.message_id,chat_id=reply_msg.chat.id,parse_mode='HTMl')
|
|
||||||
|
|
||||||
|
|
||||||
mirror_handler = CommandHandler('mirror', mirror)
|
mirror_handler = CommandHandler('mirror', mirror)
|
||||||
dispatcher.add_handler(mirror_handler)
|
dispatcher.add_handler(mirror_handler)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
python-telegram-bot
|
python-telegram-bot
|
||||||
google-api-python-client>=1.7.3
|
google-api-python-client>=1.7.3
|
||||||
google-auth>=1.5.0
|
|
||||||
google-auth-httplib2<=0.0.3
|
google-auth-httplib2<=0.0.3
|
||||||
|
google-auth-oauthlib
|
||||||
httplib2>=0.11.3
|
httplib2>=0.11.3
|
||||||
more-itertools>=4.2.0
|
more-itertools>=4.2.0
|
||||||
ndg-httpsclient>=0.4.0
|
ndg-httpsclient>=0.4.0
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue