Last active
April 23, 2024 20:48
-
-
Save bonelifer/6c0dc8e2ea8f371206e197d56f32805d to your computer and use it in GitHub Desktop.
Collection of Python scripts to backup Google Drive files. Created using chatGPT. These are not meant to be sync clients. As such edit docuements online, then download them. This is a one way process to backup your Drive contents locally.
This file contains hidden or 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
#!/usr/bin/env python3 | |
""" | |
Script: drive-backup.py | |
Description: Downloads the entire contents of a Google Drive using Google Drive API. | |
Requirements: | |
- Google Client Library: `pip install google-api-python-client` | |
- Create a project in Google Cloud Console, enable Drive API, and generate credentials (OAuth 2.0 Client IDs). | |
- Save the credentials JSON file as 'credentials.json' in the same directory as this script. | |
Usage: | |
1. Run the script. | |
""" | |
import os | |
from google.oauth2.credentials import Credentials | |
from googleapiclient.discovery import build | |
from google.auth.transport.requests import Request | |
from google_auth_oauthlib.flow import InstalledAppFlow | |
# If modifying these scopes, delete the file token.json. | |
SCOPES = ['https://www.googleapis.com/auth/drive.readonly'] | |
def authenticate(): | |
""" | |
Authenticates user and returns credentials. | |
""" | |
creds = None | |
# The file token.json stores the user's access and refresh tokens, and is | |
# created automatically when the authorization flow completes for the first time. | |
if os.path.exists('token.json'): | |
creds = Credentials.from_authorized_user_file('token.json') | |
# 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.json', 'w') as token: | |
token.write(creds.to_json()) | |
return creds | |
def download_files(service, folder_id, folder_name): | |
""" | |
Downloads files recursively from a Google Drive folder. | |
""" | |
# Create folder for downloads | |
if not os.path.exists(folder_name): | |
os.makedirs(folder_name) | |
# List files in the folder | |
results = service.files().list( | |
q=f"'{folder_id}' in parents", | |
fields="files(id, name, mimeType)").execute() | |
items = results.get('files', []) | |
for item in items: | |
file_id = item['id'] | |
file_name = item['name'] | |
file_mime_type = item['mimeType'] | |
# Skip Google Apps Scripts | |
if file_mime_type == 'application/vnd.google-apps.script': | |
print(f"Skipped Google Apps Script: {file_name}") | |
continue | |
# Skip folders | |
if 'application/vnd.google-apps.folder' in file_mime_type: | |
# Create a local folder to mirror the Google Drive folder structure | |
subfolder_name = os.path.join(folder_name, file_name) | |
if not os.path.exists(subfolder_name): | |
os.makedirs(subfolder_name) | |
# Recursively download files from the subfolder | |
download_files(service, file_id, subfolder_name) | |
else: | |
# Download file if it's not a folder or Google Apps file | |
if not file_mime_type.startswith('application/vnd.google-apps'): | |
request = service.files().get_media(fileId=file_id) | |
with open(os.path.join(folder_name, file_name), 'wb') as f: | |
f.write(request.execute()) | |
print(f"Downloaded: {file_name}") | |
def main(): | |
creds = authenticate() | |
service = build('drive', 'v3', credentials=creds) | |
# Get the root folder ID of Google Drive | |
root_folder_id = 'root' | |
# Specify the name of the local folder where files will be downloaded | |
local_folder_name = 'drive' | |
download_files(service, root_folder_id, local_folder_name) | |
if __name__ == '__main__': | |
main() |
This file contains hidden or 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
#!/usr/bin/env python | |
""" | |
Script: gaps-backup.py | |
Description: Downloads Google Docs, Sheets, and Slides files from Google Drive. | |
Requirements: | |
- google-auth | |
- google-auth-oauthlib | |
- google-auth-httplib2 | |
- google-api-python-client | |
- OAuth 2.0 Client ID credentials file named `credentials.json` in the same directory as this script. | |
Usage: | |
1. Make sure you have 'credentials.json' with your Google Drive API credentials. | |
2. Run the script. It will authenticate you through your browser. | |
3. It will then download Google Docs, Google Sheets, and Google Slides files from the root folder of your Google Drive and save them locally. | |
Note: This script assumes you have appropriate permissions to access the files. | |
""" | |
import os | |
import pickle | |
from google.auth.transport.requests import Request | |
from google.oauth2.credentials import Credentials | |
from google_auth_oauthlib.flow import InstalledAppFlow | |
from googleapiclient.discovery import build | |
# Define the scopes | |
SCOPES = ['https://www.googleapis.com/auth/drive.readonly'] | |
def authenticate(): | |
"""Authenticate the user and return the credentials.""" | |
creds = None | |
if os.path.exists('token.pickle'): | |
with open('token.pickle', 'rb') as token: | |
creds = pickle.load(token) | |
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) | |
with open('token.pickle', 'wb') as token: | |
pickle.dump(creds, token) | |
return creds | |
def download_files(service, folder_id, local_folder_name): | |
"""Download files from Google Drive.""" | |
if not os.path.exists(local_folder_name): | |
os.makedirs(local_folder_name) | |
try: | |
results = service.files().list( | |
q=f"'{folder_id}' in parents", | |
fields="files(id, name, mimeType)").execute() | |
items = results.get('files', []) | |
except Exception as e: | |
print(f"An error occurred while listing files: {e}") | |
return | |
if not items: | |
print('No files found.') | |
else: | |
print('Files:') | |
for item in items: | |
file_id = item['id'] | |
file_name = item['name'] | |
file_mime_type = item['mimeType'] | |
# Initialize save_folder with None | |
save_folder = None | |
# Define download formats based on file type | |
download_formats = [] | |
if 'application/vnd.google-apps.document' in file_mime_type: | |
download_formats = [ | |
{'mimeType': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'extension': '.docx'}, | |
{'mimeType': 'application/vnd.oasis.opendocument.text', 'extension': '.odt'}, | |
{'mimeType': 'application/pdf', 'extension': '.pdf'} | |
] | |
save_folder = 'local-exported-docs' | |
elif 'application/vnd.google-apps.spreadsheet' in file_mime_type: | |
download_formats = [ | |
{'mimeType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'extension': '.xlsx'}, | |
{'mimeType': 'application/vnd.oasis.opendocument.spreadsheet', 'extension': '.ods'}, | |
{'mimeType': 'application/pdf', 'extension': '.pdf'} | |
] | |
save_folder = 'local-exported-sheets' | |
elif 'application/vnd.google-apps.presentation' in file_mime_type: | |
download_formats = [ | |
{'mimeType': 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'extension': '.pptx'}, | |
{'mimeType': 'application/vnd.oasis.opendocument.presentation', 'extension': '.odp'}, | |
{'mimeType': 'application/pdf', 'extension': '.pdf'} | |
] | |
save_folder = 'local-exported-slides' | |
# Create subfolder if not empty | |
if save_folder: | |
subfolder_path = os.path.join(local_folder_name, save_folder) | |
if not os.path.exists(subfolder_path): | |
os.makedirs(subfolder_path) | |
file_path = os.path.join(subfolder_path, file_name.replace(' ', '_')) | |
else: | |
file_path = os.path.join(local_folder_name, file_name.replace(' ', '_')) | |
# Export Google Docs, Sheets, and Slides files in various formats | |
for download_format in download_formats: | |
mime_type = download_format['mimeType'] | |
extension = download_format['extension'] | |
if mime_type and file_path: | |
request = service.files().export_media(fileId=file_id, mimeType=mime_type) | |
with open(file_path + extension, 'wb') as f: | |
f.write(request.execute()) | |
print(f"Downloaded {file_name}{extension}") | |
def main(): | |
"""Authenticate and download files from Google Drive.""" | |
creds = authenticate() | |
if creds: | |
service = build('drive', 'v3', credentials=creds) | |
root_folder_id = 'root' | |
local_folder_name = 'drive' | |
download_files(service, root_folder_id, local_folder_name) | |
else: | |
print("Authentication failed.") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/spreadsheets
Using the credentials.json:
This single
credentials.json
file can be used to access both Drive and Sheets/Docs APIs in your code. The specific library you use will determine how to reference this file for authentication.Important Note:
For more detailed instructions and code examples, you can refer to the official Google Sheets API quickstart guide: https://www.youtube.com/watch?v=BeIwYBfWPVs