import md5, urllib, httplib, camera, key_codes, os, os.path
API_KEY = "c62dcNiOgTeVhAaLdIxDsdf17ee3afe9"
SECRET = "c932fFxAkK9E648d"
API_URL = "http://flickr.com/services/rest/"
UPLOAD_URL = "http://api.flickr.com/services/upload/"
IMG_FILE = u"E:\\Data\\Instaflickr\\instaflickr.jpg"
TOKEN_FILE = u"E:\\Data\\Instaflickr\\instaflickr.txt"
BLOCKSIZE = 8192
PROGRESS_COLOR = (0, 255, 0)
TEXT_COLOR = (255, 0, 0)
if not os.path.exists("E:\\Data\\Instaflickr"):
os.makedirs("E:\\Data\\Instaflickr")
def naive_xml_parser(key, xml):
key = key.lower()
for tag in xml.split("<"):
tokens = tag.split()
if tokens and tokens[0].lower().startswith(key):
return tag.split(">")[1].strip()
return None
def load_token():
global flickr_token
try:
flickr_token = file(TOKEN_FILE).read()
except:
new_token()
def new_token():
global flickr_token
mini_token = appuifw.query(u"Give Flickr mini-token "
u"(e.g. 123456100)", "number")
if not mini_token:
return
params = {"method": "flickr.auth.getFullToken",
"api_key": API_KEY,
"mini_token": str(mini_token)}
flickr_token = naive_xml_parser("token",
flickr_signed_call(params))
if flickr_token:
try:
f = file(TOKEN_FILE, "w")
f.write(flickr_token)
f.close()
appuifw.note(u"Token saved!", "info")
except:
appuifw.note(u"Could not save token",
"error")
else:
appuifw.note(u"Invalid token", "error")
def flickr_signed_call(params):
keys = params.keys()
keys.sort()
msg = SECRET
for k in keys:
if k != "photo":
msg += k + params[k]
params['api_sig'] = md5.new(msg).hexdigest()
if "photo" in params:
return flickr_multipart_post(params)
else:
url = API_URL + "?" + urllib.urlencode(params)
return urllib.urlopen(url).read()
def flickr_multipart_post(params):
BOUNDARY = "----ds9io349sfdfd!%#!dskm"
body = []
for k, v in params.items():
body.append("--" + BOUNDARY)
part_head = 'Content-Disposition: '
'form-data; name="%s"' % k
if k == "photo":
body.append(part_head +
';filename="up.jpg"')
body.append('Content-Type: image/jpeg')
else:
body.append(part_head)
body.append('')
body.append(v)
body.append("--" + BOUNDARY + "--")
body_txt = "\r\n".join(body)
proto, tmp, host, path = UPLOAD_URL.split('/', 3)
h = httplib.HTTP(host)
h.putrequest('POST', "/%s" % path)
h.putheader('content-type',
"multipart/form-data; boundary=%s" % BOUNDARY)
h.putheader('content-length', str(len(body_txt)))
h.endheaders()
try:
offs = 0
for i in range(0, len(body_txt), BLOCKSIZE):
offs += BLOCKSIZE
h.send(body_txt[i: offs])
progress_bar(min(1.0,
offs / float(len(body_txt))))
errcode, errmsg, headers = h.getreply()
return h.file.read()
except:
return None
def progress_bar(p):
y = canvas.size[1] / 2
max_w = canvas.size[0] - 30
canvas.rectangle((15, y, p * max_w, y + 10),\
fill = PROGRESS_COLOR)
def show_text(txt):
s = canvas.size
canvas.text((10, s[1] / 2 - 15), txt,\
fill=TEXT_COLOR, font="title")
def finder_cb(im):
canvas.blit(im)
def start_viewfinder():
if flickr_token:
camera.start_finder(finder_cb)
canvas.bind(key_codes.EKeySelect, take_photo)
else:
appuifw.note(u"Give a Flickr token first",
"error")
def take_photo():
canvas.bind(key_codes.EKeySelect, None)
camera.stop_finder()
show_text(u"Hold still!")
image = camera.take_photo(size = (640, 480))
s = canvas.size
canvas.blit(image,target=(0,0,s[0],(s[0]/4*3)), scale=1)
show_text(u"Uploading to Flickr...")
image.save(IMG_FILE)
jpeg = file(IMG_FILE, "r").read()
params = {'api_key': API_KEY, 'title': 'InstaFlickr',
'auth_token': flickr_token,\
'photo': jpeg}
ret = flickr_signed_call(params)
canvas.clear((255, 255, 255))
if ret:
show_text(u"Photo sent ok!")
else:
show_text(u"Network error")
def access_point():
global ap_id
ap_id = socket.select_access_point()
apo = socket.access_point(ap_id)
socket.set_default_access_point(apo)
def quit():
camera.stop_finder()
app_lock.signal()
appuifw.app.exit_key_handler = quit
appuifw.app.title = u"InstaFlickr"
appuifw.app.menu = [(u"Take photo", start_viewfinder),
(u"New token", new_token),
(u"Access point", access_point),
(u"Quit", quit)]
appuifw.app.body = canvas = appuifw.Canvas()
canvas.clear((255, 255, 255))
show_text(u"Welcome to InstaFlickr")
load_token()
app_lock = e32.Ao_lock()
app_lock.wait()