From 68906549fb5c893fa9595401bc475aaa76951273 Mon Sep 17 00:00:00 2001 From: Josh Roesslein Date: Sat, 15 Aug 2009 01:07:21 -0500 Subject: [PATCH] Implemented multipart-formdata image packing method. Added profile image and backgroud image methods to API. Binder can now accept post data. --- ROADMAP | 5 +++-- tweepy/api.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++- tweepy/binder.py | 7 +++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/ROADMAP b/ROADMAP index 9959f2a..7f69a97 100644 --- a/ROADMAP +++ b/ROADMAP @@ -2,15 +2,16 @@ The plan of attack for the next version of Tweepy. 1.0 -> 1.0.1 ============ -+ command line client example + changing profile and background images + full coverage of current code in tests + prepare for social graph changes mentioned on mailinglist + finish search api + autodetect authenticated user's ID [DONE] -+ retweet api ++ timeline paging Future... ========= + database-based cache ? + rate limit governor ++ command line client example ++ retweet api [DONE BUT NEEDS TESTING] diff --git a/tweepy/api.py b/tweepy/api.py index 0592b47..81c42a4 100644 --- a/tweepy/api.py +++ b/tweepy/api.py @@ -242,7 +242,24 @@ class API(object): require_auth = True ) - # TODO: add support for changing profile and background images + """Update profile image""" + def update_profile_image(self, filename): + bind_api( + path = '/account/update_profile_image.json', + method = 'POST', + parser = parse_user, + require_auth = True + )(self, post_data = _pack_image(filename, 700)) + + """Update profile background image""" + def update_profile_image(self, filename, *args, **kargs): + bind_api( + path = '/account/update_profile_background_image.json', + method = 'POST', + parser = parse_user, + allowed_param = ['tile'] + require_auth = True + )(self, post_data = _pack_image(filename, 800)) """Update profile""" update_profile = bind_api( @@ -399,3 +416,35 @@ class API(object): parser = parse_trend_results )(self) +def _pack_image(filename, max_size): + """Pack image from file into multipart-formdata post body""" + # image must be less than 700kb in size + try: + if os.path.getsize(filename) > (max_size * 1024): + raise TweepError('File is too big, must be less than 700kb.') + except os.error, e: + raise TweepError('Unable to access file') + + # image must be gif, jpeg, or png + file_type = mimetypes.guess_type(filename) + if file_type is None: + raise TweepError('Could not determine file type') + if file_type is not 'image/gif' and file_type is not 'image/jpeg' + and file_type is not 'image/png': + raise TweepError('Invalid file type for image') + + # build the mulitpart-formdata body + fp = open(filename, 'rb') + BOUNDARY = '--Tw3ePy' + body = [] + body.append('--' + BOUNDARY) + body.append('Content-Disposition: form-data; name="image"; filename="%s"' % filename) + body.append('Content-Type: %s' % file_type) + body.append('') + body.append(fp.read()) + body.append('--' + BOUNDARY + '--') + body.append('') + fp.close() + + return '\r\n'.join(body) + diff --git a/tweepy/binder.py b/tweepy/binder.py index 5608aa9..c91b68f 100644 --- a/tweepy/binder.py +++ b/tweepy/binder.py @@ -16,6 +16,13 @@ def bind_api(path, parser, allowed_param=None, method='GET', require_auth=False, if require_auth and not api.auth_handler: raise TweepError('Authentication required!') + # check for post_data parameter + if 'post_data' in kargs: + post_data = kargs['post_data'] + del kargs['post_data'] + else: + post_data = None + # build parameter dict if allowed_param: parameters = {} -- 2.25.1