Last active
November 27, 2024 02:45
-
-
Save hiroshil/927155dac02253e50fb3430f87f9214d to your computer and use it in GitHub Desktop.
Script to upload files or folders to a Google Drive folder using PyDrive2 (with Tqdm progress bar supported)
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
import re | |
from pathlib import Path | |
from tqdm import tqdm as Tqdm | |
from pydrive2.auth import GoogleAuth | |
from pydrive2.drive import GoogleDrive | |
param = "FolderID" #FileID is the simple file hash, like 0B1NzlxZ5RpdKS0NOS0x0Ym9kR0U | |
err_fmt = False | |
if len(param) > 33: | |
match = re.search(r"https:\/\/drive\.google\.com\/drive\/folders\/([^/]+)\/view\?usp=drive_link", param) | |
if match: | |
PARENT_ID = match.group(1) | |
else: | |
err_fmt = True | |
elif len(param) < 33: | |
err_fmt = True | |
else: | |
PARENT_ID = param | |
if err_fmt: | |
print("String not found in the any format.") | |
exit() | |
LOCAL_PATH = 'FOLDER_OR_FILE_PATH' | |
gauth = GoogleAuth() | |
# use any auth method that you like, in my case i use this one | |
# Try to load saved client credentials | |
gauth.LoadCredentialsFile("credentials.json") | |
if gauth.credentials is None: | |
# Authenticate if they're not there | |
# This is what solved the issues: https://stackoverflow.com/questions/24419188/automating-pydrive-verification-process/55876179#55876179 | |
gauth.GetFlow() | |
gauth.flow.params.update({'access_type': 'offline'}) | |
gauth.flow.params.update({'approval_prompt': 'force'}) | |
gauth.LocalWebserverAuth() | |
elif gauth.access_token_expired: | |
# Refresh them if expired | |
gauth.Refresh() | |
else: | |
# Initialize the saved creds | |
gauth.Authorize() | |
# Save the current credentials to a file | |
gauth.SaveCredentialsFile("credentials.json") | |
drive = GoogleDrive(gauth) | |
def upload_single_file(item, parent_id): | |
# Upload a file to Google Drive | |
myFileName = item.name | |
# Check if file name already exists in folder. | |
file_list = drive.ListFile( | |
{ | |
"q": '"{}" in parents and title="{}" and trashed=false'.format( | |
parent_id, myFileName | |
) | |
} | |
).GetList() | |
# If file is found, update it, otherwise create new file. | |
if len(file_list) == 1: | |
myFile = file_list[0] | |
else: | |
myFile = drive.CreateFile( | |
{"parents": [{"kind": "drive#fileLink", "id": parent_id}]} | |
) | |
# The `convert` flag indicates to Google Drive whether to convert the | |
# uploaded file into a Google Drive native format, i.e. Google Sheet for | |
# CSV or Google Document for DOCX. | |
# myFile.Upload({"convert": True}) | |
no_progress_bar=False | |
progress_name="" | |
with open(item, "rb") as fobj: | |
total = item.stat().st_size | |
with Tqdm.wrapattr( | |
fobj, | |
"read", | |
desc=progress_name, | |
total=total, | |
disable=no_progress_bar, | |
) as wrapped: | |
# PyDrive doesn't like content property setting for empty files | |
# https://github.com/gsuitedevs/PyDrive/issues/121 | |
if total: | |
myFile.content = wrapped | |
myFile["title"] = myFileName | |
myFile.Upload({"convert": True}) | |
print(f"Uploaded file: {str(item)}") | |
def upload_folder(folder_path, parent_id, drive): | |
for item in folder_path.iterdir(): | |
if item.is_dir(): | |
# Create a new folder in Google Drive | |
folder = drive.CreateFile({'title': item.name, 'parents': [{'id': parent_id}], 'mimeType': 'application/vnd.google-apps.folder'}) | |
folder.Upload() | |
print(f"Created folder: {item.name}") | |
# Recursively upload contents of the subfolder | |
upload_folder(item, folder['id'], drive) | |
else: | |
upload_single_file(item, parent_id) | |
input_path = Path(LOCAL_PATH) | |
if input_path.is_dir(): | |
upload_folder(input_path, PARENT_ID, drive) | |
else: | |
upload_single_file(input_path, PARENT_ID) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment