Created
March 5, 2014 09:40
-
-
Save anonymous/9364179 to your computer and use it in GitHub Desktop.
Organize Dropbox Camera Uploads
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
# I use the Dropbox iPhone app, and I love it - automatically backing up my photos to the cloud? Great! | |
# However, automatic uploads from your camera roll go to "Camera Uploads". If, like me, you can often | |
# forget to go in and sort your photos for a while, pretty soon there's so much in there it becomes slow | |
# to load. Use this script from the command line to move your photos in to a folder named "Unsorted Photos | |
# By Date" (you can change that on line 75 by setting basefolder) with subfolders for YEAR and then MONTH. | |
# Run this manually whenever things get out of hand, or have it running as a cron job or similar to automatically | |
# stay on top of things. | |
# You'll need the Dropbox Python SDK installed, as well as Colorama (pip install colorama) | |
import dropbox | |
import json | |
import sys, getopt | |
from colorama import init, Fore, Back, Style | |
init(autoreset=True) | |
def main(argv): | |
# Get your app key and secret from the Dropbox developer website | |
app_key = 'YOUR_APP_KEY_HERE' | |
app_secret = 'YOUR_APP_SECRET_HERE' | |
flow = dropbox.client.DropboxOAuth2FlowNoRedirect(app_key, app_secret) | |
# Have the user sign in and authorize this token | |
authorize_url = flow.start() | |
print '1. Go to: ' + authorize_url | |
print '2. Click "Allow" (you might have to log in first)' | |
print '3. Copy the authorization code.' | |
code = raw_input("Enter the authorization code here: ").strip() | |
# This will fail if the user enters an invalid authorization code | |
access_token, user_id = flow.finish(code) | |
# You may tire of doing the above each time you run it. You can always | |
# Copy the access token that comes back the first time and hardcode it | |
# Here to save time. If you do that, comment out lines 22 - 32 | |
print 'Your Access Token: ' + access_token | |
#access_token = 'YOUR_ACCESS_TOKEN_HERE' | |
client = dropbox.client.DropboxClient(access_token) | |
print 'linked account: ', client.account_info() | |
#defaults | |
createFolders = 1 # Attempt to create folder for year/month as we go through | |
fullerrors = 0 # Print out all errors, including those that have been handled ok | |
try: | |
# Set up the ability to handle command line arguments | |
opts, args = getopt.getopt(argv, "hde", ["--disable-folder-creation", "--show-full-errors"]) | |
except getopt.GetOptError: | |
print "python dropboxorganize.py" | |
sys.exit(2) | |
for opt, arg in opts: | |
# -h will show help | |
if opt == '-h': | |
print "python dropboxorganize.py" | |
print "Optional:" | |
print "-d --disable-folder-creation Don't create folders (speeds up script if folders exist already) Default: Create folders" | |
print "-e --show-full-errors Show full error information (can be noisy) Default: Don't show full errors" | |
sys.exit(2) | |
elif opt in ("-d", "--disable-folder-creation"): | |
# -d or --disable-folder-creation will skip the creation of the folders | |
# this is useful if the folders were manually created or we already ran this script | |
# as the execution will be faster | |
createFolders = 0 | |
elif opt in ("-e", "--show-full-errors"): | |
# -e or --show-full-errors will show the full error messages, including errors like "could not | |
# create folder - folder exists" which will be common. | |
fullerrors = 1 | |
# Always nice to summarize the affected files, so lets keep a count of how many we move | |
movedfiles = 0 | |
# Name of your folder (from the root level of your Dropbox) that you wish to house the unsorted photos | |
basefolder = '/Unsorted Photos By Date' | |
# Collection of years to include | |
years = ['2014', '2015', '2016'] | |
# The 12 months of the year in a collection | |
months = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'] | |
for year in years: | |
sectionheaderneeded = 1 #Only print out the Year / Month header if there are files to move in that year & month | |
for month in months: | |
monthheaderneeded = 1 | |
if createFolders: | |
try: | |
response = client.file_create_folder(basefolder + '/' + year + '/' + month) | |
except dropbox.rest.ErrorResponse as e: | |
if fullerrors: | |
print '# ERROR creating folder (' + basefolder + '/' + year + '/' + month + '):' | |
print '# ' + str(e.error_msg) | |
try: | |
search = year + '-' + month | |
target = basefolder + '/' + year + '/' + month | |
print '# Search for /Camera Uploads/' + search + ' move to ' + target | |
data = client.search('/Camera Uploads', search) | |
for x in data: | |
a = json.dumps(x) | |
b = json.loads(a) | |
o = b["path"] | |
n = b["path"].replace('/Camera Uploads', target) | |
try: | |
if sectionheaderneeded: | |
print '--------------------------------------------------------------------------------' | |
print '# ' + year | |
print '# ' | |
sectionheaderneeded = 0 | |
if monthheaderneeded: | |
print '# Month: ' + month + ' -------------------------------------------------------------------' | |
monthheaderneeded = 0 | |
print '# ' + Fore.GREEN + 'Move ' + o + ' to ' + n | |
moveOp = client.file_move(o,n) | |
movedfiles += 1 | |
except dropbox.rest.ErrorResponse as e: | |
print '# ' + Fore.RED + 'ERROR moving file ' + o + ' to ' + n + ':' | |
print '# ' + Fore.RED + str(e) | |
except dropbox.rest.ErrorResponse as e: | |
print '# ' + Fore.RED + 'ERROR in search (' + search + '):' | |
print '# ' + Fore.RED + str(e) | |
print '--------------------------------------------------------------------------------' | |
print '# SUMMARY' | |
print '# ' + Fore.BLUE + str(movedfiles) + ' Files moved to ' + basefolder | |
print '--------------------------------------------------------------------------------' | |
print '' | |
print 'Goodbye!' | |
if __name__ == "__main__": | |
main(sys.argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment