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()