The python description for ChangePhoto says:

*ChangePhoto*(self, media, contact_entry_or_url, content_type=None, 
content_length=None)
Change the photo for the contact by uploading a new photo.
 
Performs a PUT against the photo edit URL to send the binary data for the
photo.
 
Args:
  media: filename, file-like-object, or a gdata.MediaSource object to send.

Note that it says media argument can be file-like-object, so I tried passing 
a file() and urllib2.urlopen(), but both fail with this error (I replaced 
the base64 data with ...):

>>> gd_client.ChangePhoto(file('/tmp/t.jpg'), contact_entry, 
content_type='image/jpeg')
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (6, 0))

---------------------------------------------------------------------------
RequestError                              Traceback (most recent call last)
/Users/hdara/bin/python/bin/<ipython-input-186-40d7554fdfc3> in <module>()
----> 1 gd_client.ChangePhoto(file('/tmp/t.jpg'), contact_entry)

/Users/hdara/bin/python/lib/python2.6/site-packages/gdata/contacts/service.pyc 
in ChangePhoto(self, media, contact_entry_or_url, content_type, 
content_length)
    243       payload = gdata.MediaSource(content_type=content_type, 
    244           content_length=content_length, file_path=media)
--> 245     return self.Put(payload, url)
    246 
    247   def GetPhoto(self, contact_entry_or_url):

/Users/hdara/bin/python/lib/python2.6/site-packages/gdata/service.pyc in 
Put(self, data, uri, extra_headers, url_params, escape_params, 
redirects_remaining, media_source, converter)
   1393         extra_headers=extra_headers, url_params=url_params,
   1394         escape_params=escape_params, 
redirects_remaining=redirects_remaining,
-> 1395         media_source=media_source, converter=converter)
   1396 
   1397   def Delete(self, uri, extra_headers=None, url_params=None, 

/Users/hdara/bin/python/lib/python2.6/site-packages/gdata/service.pyc in 
PostOrPut(self, verb, data, uri, extra_headers, url_params, escape_params, 
redirects_remaining, media_source, converter)
   1356     else:
   1357       raise RequestError, {'status': server_response.status,
-> 1358           'reason': server_response.reason, 'body': result_body}
   1359 
   1360   def Put(self, data, uri, extra_headers=None, url_params=None, 

RequestError: {'status': 400, 'body': '<!DOCTYPE html>\n<html lang=en>\n  
<meta charset=utf-8>\n  <title>Error 400 (Bad Request)!!1</title>\n  
<style>\n    *{margin:0;padding:0}html,code{font:15px/22px 
arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{background:url(data:image/png;base64,...)
 
100% 5px no-repeat;margin:7% auto 
0;max-width:390px;min-height:180px;padding:30px 0 15px}* > 
body{padding-right:205px}p{margin:22px 0 
0;overflow:hidden}ins,#g{text-decoration:none}ins{color:#777}a 
img{border:0}#g{background:url(data:image/png;base64,...);display:block;height:55px;margin:0
 
0 -7px;width:150px}* > #g{margin-left:-2px}#g img{visibility:hidden}* html 
#g img{visibility:visible}*+html #g img{visibility:visible}\n  </style>\n  
<a href=//www.google.com/ id=g><img src=//www.google.com/images/logo_sm.gif 
alt=Google></a>\n  <p><b>400.</b> <ins>That\xe2\x80\x99s an error.</ins>\n  
<p>Your client has issued a malformed or illegal request.  
<ins>That\xe2\x80\x99s all we know.</ins>\n', 'reason': 'Bad Request'}

See how the it says "image/png" (that too twice), even though I am 
specifying "image/jpeg" as the content type. 

However, if I directly reference the filename, it works, like this:

>>> gd_client.ChangePhoto('/tmp/t.jpg', contact_entry, 
content_type='image/jpeg')

I also tried creating MediaSource like this: 
gdata.MediaSource(file_handle=file('/tmp/t.jpg'), 
content_type='image/jpeg') and passing in as the first argument, but it too 
got the same error. I need to set photo from a URL, so I guess the 
workaround is to download it to a temp file and pass the filename, but per 
the documentation it should have worked.

Walking through the MediaSource, the only difference I observed between 
passing the filepath and a file-like object was the content-length, so I 
tried setting it and it made all the difference.

>>> gd_client.ChangePhoto(file('/tmp/t.jpg'), contact_entry, 
content_type='image/jpeg', content_length=13761)

The issue however is that I can't figure out the content-length from the 
response, so I would have to read the entire content and pass it back as a 
buffer along with the length. My guess is Post() has a bug that doesn't 
handle the content properly unless the content-length is known in advance. 
Can this be fixed easily?

-- 
You received this message because you are subscribed to the Google
Groups "Google Contacts, Shared Contacts and User Profiles APIs" group.
To post to this group, send email to
[email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://code.google.com/apis/contacts/community/forum.html

Reply via email to