Skip to content

Instantly share code, notes, and snippets.

@ahxxm
Created September 7, 2015 13:22
Show Gist options
  • Save ahxxm/e1decbdf6a6eaefa7479 to your computer and use it in GitHub Desktop.
Save ahxxm/e1decbdf6a6eaefa7479 to your computer and use it in GitHub Desktop.
google_drive_podcast_uploader
import os
import trollius
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
# Auth Google Drive
gauth = GoogleAuth()
gauth.LoadCredentialsFile("creds.json")
if gauth.credentials is None:
gauth.CommandLineAuth()
elif gauth.access_token_expired:
gauth.Refresh()
else:
gauth.Authorize()
gauth.SaveCredentialsFile("creds.json")
drive = GoogleDrive(gauth)
# Local files
myFolder = "/podcast/pod/podcasts/"
os.chdir(myFolder)
fileSet = set()
# walk through
for root, dirs, files in os.walk(myFolder):
for fileName in files:
fileSet.add(os.path.join(root[len(myFolder):], fileName))
# Remote files
def create_subfolder(parent_folder_instance, sub_folder_name):
# parent_folder_instance: GoogleDriveFile ( which could be a folder .. )
# sub_folder_name: str
new_folder = drive.CreateFile({'title':'{}'.format(sub_folder_name), 'mimeType':'application/vnd.google-apps.folder'})
if parent_folder_instance is not None:
new_folder['parents'] = [{u'id': parent_folder_instance['id']}]
new_folder.Upload()
return new_folder
def list_folder(folder_id):
# folder_id: GoogleDriveFile['id']
_q = {'q': "'{}' in parents and trashed=false".format(folder_id)}
return drive.ListFile(_q).GetList()
# Get `Podcast` folder
podcast_folder_instance = None
file_list = drive.ListFile({'q': "'root' in parents and trashed=false"}).GetList()
for folder in file_list:
if folder['title'] == 'Podcast':
podcast_folder_instance = folder
if not podcast_folder_instance:
podcast_folder_instance = create_subfolder(None, 'Podcast')
assert podcast_folder_instance
# Get all sub-folders(subscriptions): {folder_name: id}
raw_sub_folders_of_podcast = list_folder(podcast_folder_instance['id'])
subfolder_name_id = {item['title']:item['id'] for item in raw_sub_folders_of_podcast}
# And all files under these folders, a dict:
# 'folder_name': [file list]
all_files = dict()
def upload_file(filepath):
# Relative path like: 'the-memory-palace/20150907Dwight.mp3'
# We have already chdir before.
folder, filename = filepath.split('/')
# Google Drive use a child/parent structure, specify unique folder id
# could result in uploaded file there
upload_folder_id = None
# Check if this folder exists, if not, create and add to the list,
# This should not fail
if folder not in subfolder_name_id:
new_folder = create_subfolder(podcast_folder_instance, folder)
assert new_folder['id'], new_folder['title']
upload_folder_id = new_folder['id']
subfolder_name_id[new_folder['title']] = new_folder['id']
all_files[new_folder['title']] = None
else:
upload_folder_id = subfolder_name_id[folder]
# Check if all files under this folder is already cached
if folder not in all_files:
files_under_this_folder = list_folder(upload_folder_id)
file_name_id = {item['title']:item['id'] for item in files_under_this_folder}
all_files[folder] = file_name_id
# If hit filename cache
current_folder_filelist = all_files[folder]
if current_folder_filelist:
for file_item in current_folder_filelist:
if str(file_item) == filename:
print('Hit cache! ', filename)
return
upload = drive.CreateFile({'title': filename, 'parents': [{u'id': upload_folder_id}]})
try:
upload.SetContentFile(filepath)
upload.Upload()
print('uploaded', folder, filename)
except:
pass
@trollius.coroutine
def uploader():
while True:
filename = yield
upload_file(filename)
upload_coroutine = uploader()
next(upload_coroutine)
for filepath in fileSet:
upload_coroutine.send(filepath)
@ahxxm
Copy link
Author

ahxxm commented Sep 7, 2015

sync podcast folder to Google Drive.

python2 only, require trollius and pydrive, and a client_secret.json from https://developers.google.com/: create an app, enable Google Drive API, add Oauth 2.0 credentials and download it.

First time it would prompt an url that requires manual authentication, just paste the code to command line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment