Created
September 7, 2015 13:22
-
-
Save ahxxm/e1decbdf6a6eaefa7479 to your computer and use it in GitHub Desktop.
google_drive_podcast_uploader
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 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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
sync podcast folder to Google Drive.
python2 only, require
trollius
andpydrive
, and a client_secret.json fromhttps://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.