175 lines
5.7 KiB
Python
175 lines
5.7 KiB
Python
from apiclient.discovery import build
|
|
from apiclient.http import MediaFileUpload
|
|
from apiclient.errors import ResumableUploadError
|
|
from oauth2client.client import OAuth2WebServerFlow
|
|
from oauth2client.file import Storage
|
|
from oauth2client import file, client, tools
|
|
from oauth2client.client import HttpAccessTokenRefreshError
|
|
from mimetypes import guess_type
|
|
import httplib2
|
|
import os
|
|
from bot import LOGGER, CLIENT_ID, CLIENT_SECRET, parent_id, DOWNLOAD_DIR
|
|
from bot.helper.exceptions import DriveAuthError
|
|
|
|
G_DRIVE_TOKEN_FILE = "auth_token.txt"
|
|
# 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"
|
|
|
|
|
|
if CLIENT_ID is None or CLIENT_SECRET is None or parent_id is None:
|
|
LOGGER.error("Please Setup Config Properly.")
|
|
|
|
|
|
def upload(fileName):
|
|
filePath = DOWNLOAD_DIR + fileName
|
|
try:
|
|
with open(G_DRIVE_TOKEN_FILE) as f:
|
|
pass
|
|
except IOError:
|
|
storage = create_token_file(G_DRIVE_TOKEN_FILE)
|
|
http = authorize(G_DRIVE_TOKEN_FILE, storage)
|
|
|
|
LOGGER.info("Uploading File: "+fileName)
|
|
if os.path.isfile(filePath):
|
|
http = authorize(G_DRIVE_TOKEN_FILE, None)
|
|
file_name, mime_type = file_ops(filePath)
|
|
try:
|
|
g_drive_link = upload_file(http, filePath, file_name, mime_type,parent_id)
|
|
LOGGER.info("Uploaded To G-Drive: " + filePath)
|
|
link = g_drive_link
|
|
except Exception as e:
|
|
LOGGER.error(str(e))
|
|
pass
|
|
else:
|
|
http = authorize(G_DRIVE_TOKEN_FILE, None)
|
|
file_name, mime_type = file_ops(filePath)
|
|
try:
|
|
dir_id = create_directory(http, os.path.basename(os.path.abspath(fileName)), parent_id)
|
|
DoTeskWithDir(http,filePath, dir_id)
|
|
LOGGER.info("Uploaded To G-Drive: "+fileName)
|
|
dir_link = "https://drive.google.com/folderview?id={}".format(dir_id)
|
|
link = dir_link
|
|
except Exception as e:
|
|
LOGGER.error(str(e))
|
|
raise Exception('Error: {}'.format(str(e)))
|
|
return link
|
|
|
|
def create_directory(http, directory_name, parent_id):
|
|
drive_service = build("drive", "v2", http=http, cache_discovery=False)
|
|
permissions = {
|
|
"role": "reader",
|
|
"type": "anyone",
|
|
"value": None,
|
|
"withLink": True
|
|
}
|
|
file_metadata = {
|
|
"title": directory_name,
|
|
"mimeType": G_DRIVE_DIR_MIME_TYPE
|
|
}
|
|
if parent_id is not None:
|
|
file_metadata["parents"] = [{"id": parent_id}]
|
|
file = drive_service.files().insert(body=file_metadata).execute()
|
|
file_id = file.get("id")
|
|
drive_service.permissions().insert(fileId=file_id, body=permissions).execute()
|
|
LOGGER.info("Created Gdrive Folder:\nName: {}\nID: {} ".format(file.get("title"), 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
|
|
|
|
|
|
|