Last active
September 8, 2015 10:35
-
-
Save tgray/ea28780f4fae618fa37c to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env python | |
# !/usr/bin/python | |
from flickrapi import FlickrAPI | |
from os.path import basename, splitext | |
import sys, os | |
import argparse | |
import errno | |
import shutil | |
import mimetypes | |
from random import randint | |
import datetime | |
import pytz | |
import json | |
import subprocess as sb | |
import shlex | |
myTZ = pytz.timezone('US/Eastern') | |
timeperiod = datetime.timedelta(days=1) | |
timeperiod = timeperiod - datetime.timedelta(minutes=10) | |
# Flickr parameters | |
def get_rc(): | |
"""Get flickr credentials for ~/.flickr_rc.""" | |
# The blog's XMLRPC URL and username. | |
try: | |
f = open(os.path.join(os.environ['HOME'], '.flickr_rc')) | |
lines = f.read() | |
lines = lines.strip().split('\n') | |
userdat = dict([[a.strip() for a in l.split(':', 1)] for l in lines]) | |
f.close() | |
except: | |
print """Must set flickr credentials in .flickr_rc file. Obtain at: | |
https://www.flickr.com/services/apps/create/apply/ | |
Example contents: | |
fuser: username | |
key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
secret: xxxxxxxxxxxxxxxx | |
upphotodir: /path/of/photos/to/upload/ | |
upoutdir: /directory/to/move/uploaded/photos/to/""" | |
sys.exit(1) | |
return userdat | |
# the following two auth functions are taken from | |
# http://stuvel.eu/media/flickrapi-docs/documentation/3-auth.html | |
def auth_web(flickr): | |
flickr.authenticate_via_browser(perms='read') | |
def auth_cli(flickr): | |
import webbrowser | |
print('Step 1: authenticate') | |
# Only do this if we don't have a valid token already | |
if not flickr.token_valid(perms='read'): | |
# Get a request token | |
flickr.get_request_token(oauth_callback='oob') | |
# | |
# Open a browser at the authentication URL. Do this however | |
# you want, as long as the user visits that URL. | |
authorize_url = flickr.auth_url(perms='read') | |
webbrowser.open_new_tab(authorize_url) | |
# Get the verifier code from the user. Do this however you | |
# want, as long as the user gives the application the code. | |
verifier = unicode(raw_input('Verifier code: ')) | |
# Trade the request token for an access token | |
flickr.get_access_token(verifier) | |
def get_xmp(fn): | |
cmd = 'exiftool -json ' + fn | |
cmd2 = shlex.split(cmd) | |
out = sb.check_output(cmd2) | |
outj = json.loads(out) | |
return outj[0] | |
def upload(fn, dryrun = False): | |
print "Uploading %s..." % fn | |
t = splitext(basename(fn))[0] # file name w/o extension | |
try: | |
dat = get_xmp(fn) | |
except: | |
dat = {} | |
title = dat.get('Headline', t) | |
descrip = dat.get('Description', ' ') | |
if not dryrun: | |
response = flickr.upload(filename=fn, title=title, description = | |
descrip, is_public=public, format='etree') | |
photoID = response.find('photoid').text | |
photoURL = 'http://www.flickr.com/photos/%s/%s/' % (fuser, photoID) | |
print " %s" % photoURL | |
try: | |
shutil.move(fn, outdir) | |
except: | |
print 'move problem' | |
sys.exit(2) | |
def not_already_uploaded(): | |
l = flickr.test_login() | |
userid = l[0].attrib['id'] | |
out = flickr.people_getPublicPhotos(user_id=userid, per_page=1) | |
photoid = out[0][0].attrib['id'] | |
p = flickr.photos_getInfo(photo_id=photoid) | |
d = p[0].attrib['dateuploaded'] | |
dt = datetime.datetime.utcfromtimestamp(float(d)) | |
utc = pytz.utc | |
mydt = utc.localize(dt).astimezone(myTZ) | |
# period since last picture | |
d = myTZ.localize(datetime.datetime.now()) - mydt | |
# must be greater than timeperiod specified | |
out = d > timeperiod | |
if not out: | |
print('Already uploaded a file {} ago on {}.'.format(d, mydt)) | |
print('Must wait {}, until {}.'.format(timeperiod, mydt+timeperiod)) | |
return out | |
userdat = get_rc() | |
fuser = userdat['fuser'] | |
photodir = userdat['upphotodir'] | |
outdir = userdat['upoutdir'] | |
try: | |
parser = argparse.ArgumentParser( | |
description = ('Upload pictures to flickr.')) | |
parser.add_argument('-n', '--number', | |
dest = 'number', | |
action = 'store', | |
default = 1, | |
type = int, | |
metavar = 'N', | |
help = 'number of images to upload') | |
parser.add_argument('-p', '--private', | |
dest = 'private', | |
action = 'store_true', | |
help = 'make uploads private') | |
parser.add_argument('--dry-run', | |
dest = 'dryrun', | |
action = 'store_true', | |
help = 'dry run - does not upload and move files') | |
parser.add_argument('-l', '--last', | |
dest = 'last', | |
action = 'store_true', | |
help = "only uploads if a photo hasn't been uploaded in the last day") | |
parser.add_argument('-a', '--auth', | |
dest = 'auth', | |
action = 'store_true', | |
help = "authenticate with flickr with a web browser") | |
parser.add_argument('--auth-cli', | |
dest = 'authcli', | |
action = 'store_true', | |
help = "authenticate with flickr from the CLI") | |
parser.add_argument('file', | |
nargs = '*', | |
help = 'file to upload') | |
args = parser.parse_args() | |
except: | |
sys.exit(2) | |
if args.private: | |
public = 0 | |
else: | |
public = 1 | |
# Upload the files on the command line. | |
flickr = FlickrAPI(api_key=userdat['key'], secret=userdat['secret']) | |
if args.auth or args.authcli: | |
if args.auth: | |
auth_web(flickr) | |
elif args.authcli: | |
auth_cli(flickr) | |
if flickr.token_valid(perms='write'): | |
print('authenticated') | |
sys.exit(0) | |
else: | |
print('error authenticating') | |
sys.exit(1) | |
# make our outdir | |
try: | |
os.mkdir(outdir) | |
except OSError, e: | |
if e.errno != errno.EEXIST: | |
raise e | |
pass | |
# upload our selected number of images, randomly selected | |
if args.file: | |
for fn in args.file: | |
upload(os.path.abspath(fn), args.dryrun) | |
elif not args.last or not_already_uploaded(): | |
files = os.listdir(photodir) | |
ftypes = [mimetypes.guess_type(f)[0] for f in files] | |
fileinfo = zip(files, ftypes) | |
# get just images | |
files = [f[0] for f in fileinfo if (f[1] and f[1].startswith('image/'))] | |
cwd = os.getcwd() | |
os.chdir(photodir) | |
for i in xrange(args.number): | |
try: | |
n = randint(0, len(files)-1) | |
fn = files.pop(n) | |
except: | |
print 'no more files' | |
sys.exit(2) | |
upload(os.path.abspath(fn), args.dryrun) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment