Implemented multipart-formdata image packing method. Added profile image and backgrou...
authorJosh Roesslein <jroesslein@gmail.com>
Sat, 15 Aug 2009 06:07:21 +0000 (01:07 -0500)
committerJosh Roesslein <jroesslein@gmail.com>
Sat, 15 Aug 2009 06:07:21 +0000 (01:07 -0500)
ROADMAP
tweepy/api.py
tweepy/binder.py

diff --git a/ROADMAP b/ROADMAP
index 9959f2a73ccf7e51c9b8e3c229f355a5e7620a5b..7f69a9725ba899f56eedea9e4f6aac43fc81a82a 100644 (file)
--- 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]
index 0592b474d3f677887c32c3ab8e917caa5bb79a6b..81c42a4958bd62dcb7a808666925a8999a8a59f5 100644 (file)
@@ -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)
+
index 5608aa9c110137d1d6bb4b16e3a1c0305e668faa..c91b68f0c8226e23df3f0cc21831c89c67ecf731 100644 (file)
@@ -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 = {}