Last active
March 9, 2023 20:58
-
-
Save rajarsheem/1d9790f0e9846fb429d7 to your computer and use it in GitHub Desktop.
Python terminal client for Google Drive for easy uploading, deleting, listing, sharing files or folders. (See usage in the comment)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"installed":{"client_id":"698477346386-5kbs1fh3c6eu46op4qvf30ehp6md8o56.apps.googleusercontent.com","project_id":"proven-dryad-122714","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"9j4oMk4HI0ZyPvQrz0jFFA4q","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import print_function | |
import sys | |
import io | |
import pip | |
import httplib2 | |
import os | |
from mimetypes import MimeTypes | |
try: | |
from googleapiclient.errors import HttpError | |
from apiclient import discovery | |
import oauth2client | |
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload | |
from oauth2client import client | |
from oauth2client import tools | |
except ImportError: | |
print('goole-api-python-client is not installed. Try:') | |
print('sudo pip install --upgrade google-api-python-client') | |
sys.exit(1) | |
import sys | |
class Flag: | |
auth_host_name = 'localhost' | |
noauth_local_webserver = False | |
auth_host_port = [8080, 8090] | |
logging_level = 'ERROR' | |
try: | |
import argparse | |
# flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args() | |
flags = Flag() | |
except ImportError: | |
flags = None | |
# If modifying these scopes, delete your previously saved credentials | |
# at ~/.credentials/drive-python-quickstart.json | |
SCOPES = 'https://www.googleapis.com/auth/drive' | |
CLIENT_SECRET_FILE = 'client_secret.json' | |
APPLICATION_NAME = 'GDrive' | |
def get_credentials(): | |
home_dir = os.path.expanduser('~') | |
credential_dir = os.path.join(home_dir, '.credentials') | |
if not os.path.exists(credential_dir): | |
os.makedirs(credential_dir) | |
credential_path = os.path.join(credential_dir, | |
'drive-python-quickstart.json') | |
store = oauth2client.file.Storage(credential_path) | |
credentials = store.get() | |
if not credentials or credentials.invalid: | |
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES) | |
flow.user_agent = APPLICATION_NAME | |
# if flags: | |
credentials = tools.run_flow(flow, store, flags) | |
# else: # Needed only for compatibility with Python 2.6 | |
# credentials = tools.run(flow, store) | |
print('Storing credentials to ' + credential_path) | |
return credentials | |
def upload(path, parent_id=None): | |
mime = MimeTypes() | |
credentials = get_credentials() | |
http = credentials.authorize(httplib2.Http()) | |
service = discovery.build('drive', 'v3', http=http) | |
file_metadata = { | |
'name': os.path.basename(path), | |
# 'mimeType' : 'application/vnd.google-apps.spreadsheet' | |
} | |
if parent_id: | |
file_metadata['parents'] = [parent_id] | |
media = MediaFileUpload(path, | |
mimetype=mime.guess_type(os.path.basename(path))[0], | |
resumable=True) | |
try: | |
file = service.files().create(body=file_metadata, | |
media_body=media, | |
fields='id').execute() | |
except HttpError: | |
print('corrupted file') | |
pass | |
print(file.get('id')) | |
def share(file_id, email): | |
def callback(request_id, response, exception): | |
if exception: | |
# Handle error | |
print(exception) | |
else: | |
print(response.get('id')) | |
credentials = get_credentials() | |
http = credentials.authorize(httplib2.Http()) | |
service = discovery.build('drive', 'v3', http=http) | |
batch = service.new_batch_http_request(callback=callback) | |
user_permission = { | |
'type': 'user', | |
'role': 'reader', | |
'emailAddress': email | |
} | |
batch.add(service.permissions().create( | |
fileId=file_id, | |
body=user_permission, | |
fields='id', | |
)) | |
batch.execute() | |
def listfiles(): | |
results = service.files().list(fields="nextPageToken, files(id, name,mimeType)").execute() | |
items = results.get('files', []) | |
if not items: | |
print('No files found.') | |
else: | |
print('Files:') | |
print('Filename (File ID)') | |
for item in items: | |
print('{0} ({1})'.format(item['name'].encode('utf-8'), item['id'])) | |
print('Total=', len(items)) | |
def delete(fileid): | |
service.files().delete(fileId=fileid).execute() | |
def download(file_id, path=os.getcwd()): | |
request = service.files().get_media(fileId=file_id) | |
name = service.files().get(fileId=file_id).execute()['name'] | |
fh = io.BytesIO() | |
downloader = MediaIoBaseDownload(fh, request) | |
done = False | |
while done is False: | |
status, done = downloader.next_chunk() | |
print(int(status.progress() * 100)) | |
f = open(path + '/' + name, 'wb') | |
f.write(fh.getvalue()) | |
print('File downloaded at', path) | |
f.close() | |
def createfolder(folder, recursive=False): | |
if recursive: | |
print('recursive ON') | |
ids = {} | |
for root, sub, files in os.walk(folder): | |
par = os.path.dirname(root) | |
file_metadata = { | |
'name': os.path.basename(root), | |
'mimeType': 'application/vnd.google-apps.folder' | |
} | |
if par in ids.keys(): | |
file_metadata['parents'] = [ids[par]] | |
print(root) | |
file = service.files().create(body=file_metadata, | |
fields='id').execute() | |
id = file.get('id') | |
print(id) | |
ids[root] = id | |
for f in files: | |
print(root+'/'+f) | |
upload(root + '/' + f, id) | |
else: | |
print('recursive OFF') | |
file_metadata = { | |
'name': os.path.basename(folder), | |
'mimeType': 'application/vnd.google-apps.folder' | |
} | |
file = service.files().create(body=file_metadata, | |
fields='id').execute() | |
print(file.get('id')) | |
if __name__ == '__main__': | |
credentials = get_credentials() | |
http = credentials.authorize(httplib2.Http()) | |
service = discovery.build('drive', 'v3', http=http) | |
method = sys.argv[1] | |
if method == 'upload': | |
if os.path.isdir(sys.argv[2]): | |
if len(sys.argv) == 4 and sys.argv[3] == 'R': | |
createfolder(sys.argv[2], True) | |
else: | |
createfolder(os.path.basename(sys.argv[2])) | |
else: | |
upload(sys.argv[2]) | |
elif method == 'list': | |
listfiles() | |
elif method == 'delete': | |
delete(sys.argv[2]) | |
elif method == 'download': | |
download(sys.argv[2], sys.argv[3]) | |
elif method == 'share': | |
share(sys.argv[2], sys.argv[3]) | |
elif method == 'folder': | |
createfolder(sys.argv[2]) | |
elif method == 'debug': | |
print(os.getcwd()) |
method = sys.argv[1]
IndexError: list index out of range
Hello I am trying to upload files to google drive by using your codes.
But I found an error above.
Could you explain what kinds of files I need to put into the same path?
Thank you so much!
and if you want to download any file then you can use the full path as described....
python googledrive.py download 0B2dKgMvsrJBbS291YlMzZV9YSGM "C:\Users\shyam\Desktop\GoogleDrivePython\out"
How to return the folder id based on folder name
If you'd like to "update" an existing file you can use the code in my fork to do so.
add the following value on line 76, it works for me:
http.redirect_codes = http.redirect_codes - {308}
add the following value on line 19, it works for me:
from oauth2client import file
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Keep GDrive.py and client_secret.json in same dir. Better if you add them in path.
Run Usage :
python GDrive.py list (list all files with their IDs)
python GDrive.py upload path (if path is file, uploads it. if path is dir, uploads empty dir)
python GDrive.py upload path R (path should be dir. dir is uploaded recursively. all files and sub dirs are uploaded)
python GDrive.py delete id (delete file or dir with given id)
python GDrive.py download id (download dir or file with given id to current dir)
python GDrive.py download id path (download dir or file with given id to given path on local machine)
python GDrive.py share id email (share file or dir with given id with email)