Wednesday, December 1, 2010

Using Flickr for crash recorder backup

I have been looking at the possibility of using flickr to backup my crash recording videos. Since I used python and sl4a to create my crash recorder program I looked for python scripts which performed uploads to flickr. I found some and got one working (with a few updates/modifications). Unfortunately I found it very difficult to work out exactly what the script was doing due to unnecessarily complex nested calls and sorting, json, xml and mime_types methods. Flickr tells you exactly what data strings are needed (to provide you with what you require) so it really doesn't need hard to follow programs to achieve this. Therefore, I decided to write my own flickr upload script. To write your own flickr app you need to go to the flickr api garden and apply for your own flickr api_key and secret. Anybody who wants to use your app needs to have a flickr account and obtain an authorisation token. This is a 'one-off -' process so I have written 2 scripts: one to enable a user to get a token (only needs running once); the other to use the token to allow photo/video uploads.


# by John Karwatzki November 2010
# Get a flickr authentication token to use an app

import hashlib, urllib, android
droid = android.Android()

# flickr key and secret for the crash recorder app
apikey = '88e6f2645d45df438689358aac3de9bb'
secret = '000f5e98af65ece4'

# write your own app with a new key and secret from flickr app garden
url = ''

# get api signature and url
dstring = secret+'api_key'+apikey+'methodflickr.auth.getFrob'
apisig = hashlib.md5(dstring).hexdigest() # encrypt signature

# get the frob needed for a new flickrToken
args = 'method=flickr.auth.getFrob&api_key='+apikey+'&api_sig='+ apisig
f = urllib.urlopen(url + args)
resp =
fr = resp.find('frob') # no need for json or xml routines
end = resp.find('</frob')
frob = resp[fr+5:end]

# get a flickr login signature and url using the frob
dstring = secret+'api_key'+ apikey +'frob' + frob + 'permswrite'
apisig = hashlib.md5(dstring).hexdigest()
logurl = '' + apikey + '&perms=write&frob=' + frob + '&api_sig=' + apisig
droid.webViewShow(logurl, True) # login to flickr

# on exit from webView get a token for the app
dstring = secret+'api_key'+apikey+'frob'+frob+'methodflickr.auth.getToken'
apisig = hashlib.md5(dstring).hexdigest()
args = 'method=flickr.auth.getToken&' + 'api_key=' + apikey + '&frob=' + frob + '&api_sig=' + apisig
f = urllib.urlopen(url + args)
resp =
print resp # this will show up any errors
tok = resp.find('token')
end = resp.find('</token')
token = resp[tok+6:end]

# save the token on your phone's sdcard
f = file('/sdcard/token.txt', 'w')
# by John Karwatzki November 2010

import hashlib, urllib, httplib

def upload(filename):
  apikey = '88e6f2645d45df438689358aac3de9bb'
  secret = '000f5e98af65ece4'

  # Check a flickr token exists on the phone's sdcard
    f = file('/sdcard/token.txt', 'r')
    token =
    if not token:
      raise IOError
  except IOError:
    print 'Token not found.  Run'

  # get file mimetype (my phone only has jpg mp4 and 3gp)
  dot = filename.find('.')
  ext = filename[dot+1:dot+4]
  if ext == 'jpg':
    mtype = 'image/jpeg'
  elif ext == 'mp4':
    mtype = 'video/mp4'
  elif ext == '3gp':
    mtype = 'video/3gp'
  f = file(filename, 'rb') # get file data
  fdata =

  # get apisig for upload
  dstring = secret+'api_key'+apikey+'auth_token'+token
  apisig = hashlib.md5(dstring).hexdigest()

  # get multipart mime information string
  nl = '\r\n'
  boundary = '----boundary'
  content_type = 'multipart/form-data; boundary=' + boundary
  hd = '--' + boundary + nl + 'Content-Disposition: form-data; name='
  mp = hd + '"api_key"' + nl + nl + apikey + nl
  mp = mp + hd + '"auth_token"' + nl + nl + token + nl
  mp = mp + hd + '"api_sig"' + nl + nl + apisig + nl
  mp = mp + hd + '"photo"; filename="' + filename + '"' + nl
  mp = mp + 'Content-Type: ' + mtype + nl + nl
  mp = mp + fdata + nl + '--' + boundary + '--' + nl

  # send file to user's flickr account
  up = httplib.HTTP('')
  up.putrequest('POST', '/services/upload/')
  up.putheader('content-type', content_type)
  up.putheader('content-length', str(len(mp)))
  print # check for any errors

# This is all you need to call upload

No comments:

Post a Comment