Skip to content

Instantly share code, notes, and snippets.

@gnahum12345
Last active April 21, 2020 04:15
Show Gist options
  • Save gnahum12345/96af33b65f57c62b1c66e828d6792173 to your computer and use it in GitHub Desktop.
Save gnahum12345/96af33b65f57c62b1c66e828d6792173 to your computer and use it in GitHub Desktop.
Upload directory + subdirectories into Google Drive

Requirements to Run:

  1. You need a credentials.json which can be found if you enable the google api key here: link

  2. Then you need to run pip install -r requirements.txt

  3. run upload_gdrive.py

google-api-python-client
google-auth-httplib2
google-auth-oauthlib
from __future__ import print_function
import pickle
import os.path
from googleapiclient.http import MediaFileUpload
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from argparse import ArgumentParser
import os
import sys
import ast
def parse_args():
'''
Parse Arguments
'''
parser = ArgumentParser(description="Upload local folder to Google Drive ")
parser.add_argument("-s", "--source", type=str, default='.', help="Folder to upload in local")
parser.add_argument("-d", "--destination", type=str, default='', help="Destination Folder in GDrive")
parser.add_argument("-p", "--parent", type=str, default='', help="Parent Folder in GDrive")
parser.add_argument("-gp", "--grandparent", type=str, default='', help="GrandParent Folder in GDrive")
return parser.parse_args()
def authenticate():
creds = None
SCOPES = [
'https://www.googleapis.com/auth/drive.metadata.readonly',
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive.appdata',
]
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('drive', 'v3', credentials=creds)
return service
# gauth = GoogleAuth()
# return GoogleDrive(gauth)
def get_folder_id(drive, folder_name, parent_folder_name):
"""
Check if destination folder exists and return it's ID
"""
page_token = None
# while True:
print("name={}".format(folder_name))
response = drive.files().list(q="name={} and mimeType = 'application/vnd.google-apps.folder'".format(repr(folder_name)), fields="files(id, name, parents)").execute()
for file in response.get('files', []):
if file.get('parents') is not None and parent_folder_name != '': #there is a parent.
parent_folder = drive.files().get(fileId=file.get('parents')[0]).execute()
if parent_folder.get('name') == parent_folder_name:
if file.get('name') == folder_name:
print('Found file: %s (%s)' % (file.get('name'), file.get('id')))
return file.get('id')
else: # there is no parent.
if file.get('name') == folder_name:
print('Found file: %s (%s)' % (file.get('name'), file.get('id')))
return file.get('id')
def create_folder(drive, folder_name, parent_folder_id):
'''
Create folder on GDrive
'''
folder_metadata = {
'name': folder_name,
'mimeType': 'application/vnd.google-apps.folder',
'parents' : [parent_folder_id]
}
folder = drive.files().create(body=folder_metadata, fields='id, name').execute()
# folder = drive.CreateFile(folder_metadata)
# folder.Upload()
print('title: %s, id: %s' % (folder.get('name'), folder.get('id')))
return folder.get('id')
def upload_file(drive, folder_id, file):
media_body = MediaFileUpload(
file,
# mimetype=MIMETYPE,
resumable=False
)
body = {
'name': file,
'parents': [folder_id],
'description': 'uploading file from python'
}
new_file = drive.files().create(body=body, media_body=media_body, fields='id').execute()
print('Uploaded file %s (id: %s) to parent %s' %
(new_file.get('name'), new_file.get('id'), folder_id))
return new_file.get('id')
def upload_files(drive, folder_id, src_folder_name):
try:
print("\033[91m \033[01m" + os.path.abspath(src_folder_name) + "\033[00m")
os.chdir(os.path.abspath(src_folder_name))
except OSError:
print('src : ' + src + ' is missing')
for f in os.listdir('.'):
if os.path.isfile(f):
print('Uploading ' + os.path.abspath(f))
upload_file(drive, folder_id, f)
else:
d_id = create_folder(drive, f, folder_id)
print("creating directory %s with id %s. \nUploading the files now: " % (f, d_id))
upload_files(drive, d_id, f)
os.chdir('..')
def main():
'''
main
'''
args = parse_args()
src_folder_name = args.source
dst_folder_name = args.destination
parent_folder_name = args.parent
grandparent_folder_name = args.grandparent
drive = authenticate()
parent_folder_id = get_folder_id(drive, parent_folder_name, grandparent_folder_name)
folder_id = get_folder_id(drive, dst_folder_name, parent_folder_name)
if not folder_id:
print('Create folder (%s) in gdrive ' % dst_folder_name)
folder_id = create_folder(drive, dst_folder_name, parent_folder_id)
else:
print('Folder (%s) exists in gdrive ' % dst_folder_name)
upload_files(drive, folder_id, src_folder_name)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment