def testIdShouldBeCleaned(self): entry = gdata.GDataEntryFromString(test_data.XML_ENTRY_1) element_tree = ElementTree.fromstring(test_data.XML_ENTRY_1) self.assert_( element_tree.findall('{http://www.w3.org/2005/Atom}id')[0].text != entry.id.text) self.assert_(entry.id.text == 'http://www.google.com/test/id/url')
def put(self, profileId): if self.request.headers.get('Content-Type').startswith("application/atom+xml"): entry = gdata.GDataEntryFromString(self.request.body) if entry: profile = Profile.get(key_from_request(self.request, profileId)) profile.name = entry.title.text profile.put() render_template('profile_list_entry.xml', self, locals())
def put(self): # NEW if self.request.headers.get('Content-Type').startswith("application/atom+xml"): entry = gdata.GDataEntryFromString(self.request.body) if entry: account = get_auth_account(self.request) profile = Profile(key_name=key_name(), parent=account, account=account, name=entry.title.text, author=account.email) profile.put() render_template('profile_list_entry.xml', self, locals())
def populate_file(file, content_type, payload): if content_type.startswith("multipart/related"): fp = email.parser.FeedParser() fp.feed(payload) msg = fp.close() for x in msg.walk(): if not x.get_content_type().startswith("multipart/related"): file = populate_file(file, x.get_content_type(), x.get_payload()) elif content_type.startswith("application/atom+xml"): entry = gdata.GDataEntryFromString(payload) if entry: file.title = entry.title.text file.description = entry.content.text elif content_type: file.file = db.Blob(payload) file.mime = content_type return file
def Put(self, data, uri, extra_headers=None, url_params=None, escape_params=True, redirects_remaining=3, media_source=None, converter=None): """Updates an entry at the given URI. Args: data: string, ElementTree._Element, or xml_wrapper.ElementWrapper The XML containing the updated data. uri: string A URI indicating entry to which the update will be applied. Example: '/base/feeds/items/ITEM-ID' extra_headers: dict (optional) HTTP headers which are to be included. The client automatically sets the Content-Type, Authorization, and Content-Length headers. url_params: dict (optional) Additional URL parameters to be included in the URI. These are translated into query arguments in the form '&dict_key=value&...'. Example: {'max-results': '250'} becomes &max-results=250 escape_params: boolean (optional) If false, the calling code has already ensured that the query will form a valid URL (all reserved characters have been escaped). If true, this method will escape the query and any URL parameters provided. converter: func (optional) A function which will be executed on the server's response. Often this is a function like GDataEntryFromString which will parse the body of the server's response and return a GDataEntry. Returns: If the put succeeded, this method will return a GDataFeed, GDataEntry, or the results of running converter on the server's result body (if converter was specified). """ if extra_headers is None: extra_headers = {} # Add the authentication header to the Get request if self.__auth_token: extra_headers['Authorization'] = self.__auth_token if self.__gsessionid is not None: if uri.find('gsessionid=') < 0: if uri.find('?') > -1: uri += '&gsessionid=%s' % (self.__gsessionid, ) else: uri += '?gsessionid=%s' % (self.__gsessionid, ) if media_source and data: if ElementTree.iselement(data): data_str = ElementTree.tostring(data) else: data_str = str(data) multipart = [] multipart.append('Media multipart posting\r\n--END_OF_PART\r\n' + \ 'Content-Type: application/atom+xml\r\n\r\n') multipart.append('\r\n--END_OF_PART\r\nContent-Type: ' + \ media_source.content_type+'\r\n\r\n') multipart.append('\r\n--END_OF_PART--\r\n') extra_headers[ 'Content-Type'] = 'multipart/related; boundary=END_OF_PART' extra_headers['MIME-version'] = '1.0' extra_headers['Content-Length'] = str( len(multipart[0]) + len(multipart[1]) + len(multipart[2]) + len(data_str) + media_source.content_length) insert_connection = atom.service.AtomService._CreateConnection( self, uri, 'PUT', extra_headers, url_params, escape_params) insert_connection.send(multipart[0]) insert_connection.send(data_str) insert_connection.send(multipart[1]) while 1: binarydata = media_source.file_handle.read(100000) if (binarydata == ""): break insert_connection.send(binarydata) insert_connection.send(multipart[2]) server_response = insert_connection.getresponse() result_body = server_response.read() elif media_source: extra_headers['Content-Type'] = media_source.content_type extra_headers['Content-Length'] = media_source.content_length insert_connection = atom.service.AtomService._CreateConnection( self, uri, 'PUT', extra_headers, url_params, escape_params) while 1: binarydata = media_source.file_handle.read(100000) if (binarydata == ""): break insert_connection.send(binarydata) server_response = insert_connection.getresponse() result_body = server_response.read() else: http_data = data content_type = 'application/atom+xml' server_response = atom.service.AtomService.Put( self, http_data, uri, extra_headers, url_params, escape_params, content_type) result_body = server_response.read() if server_response.status == 200: if converter: return converter(result_body) feed = gdata.GDataFeedFromString(result_body) if not feed: entry = gdata.GDataEntryFromString(result_body) if not entry: return result_body return entry return feed elif server_response.status == 302: if redirects_remaining > 0: location = server_response.getheader('Location') if location is not None: m = re.compile('[\?\&]gsessionid=(\w*)').search(location) if m is not None: self.__gsessionid = m.group(1) return self.Put(data, location, extra_headers, url_params, escape_params, redirects_remaining - 1, media_source=media_source, converter=converter) else: raise RequestError, { 'status': server_response.status, 'reason': '302 received without Location header', 'body': result_body } else: raise RequestError, { 'status': server_response.status, 'reason': 'Redirect received, but redirects_remaining <= 0', 'body': result_body } else: raise RequestError, { 'status': server_response.status, 'reason': server_response.reason, 'body': result_body }
def Get(self, uri, extra_headers=None, redirects_remaining=4, encoding='UTF-8', converter=None): """Query the GData API with the given URI The uri is the portion of the URI after the server value (ex: www.google.com). To perform a query against Google Base, set the server to 'base.google.com' and set the uri to '/base/feeds/...', where ... is your query. For example, to find snippets for all digital cameras uri should be set to: '/base/feeds/snippets?bq=digital+camera' Args: uri: string The query in the form of a URI. Example: '/base/feeds/snippets?bq=digital+camera'. extra_headers: dictionary (optional) Extra HTTP headers to be included in the GET request. These headers are in addition to those stored in the client's additional_headers property. The client automatically sets the Content-Type and Authorization headers. redirects_remaining: int (optional) Tracks the number of additional redirects this method will allow. If the service object receives a redirect and remaining is 0, it will not follow the redirect. This was added to avoid infinite redirect loops. encoding: string (optional) The character encoding for the server's response. Default is UTF-8 converter: func (optional) A function which will transform the server's results before it is returned. Example: use GDataFeedFromString to parse the server response as if it were a GDataFeed. Returns: If there is no ResultsTransformer specified in the call, a GDataFeed or GDataEntry depending on which is sent from the server. If the response is niether a feed or entry and there is no ResultsTransformer, return a string. If there is a ResultsTransformer, the returned value will be that of the ResultsTransformer function. """ if extra_headers is None: extra_headers = {} # Add the authentication header to the Get request if self.__auth_token: extra_headers['Authorization'] = self.__auth_token if self.__gsessionid is not None: if uri.find('gsessionid=') < 0: if uri.find('?') > -1: uri += '&gsessionid=%s' % (self.__gsessionid, ) else: uri += '?gsessionid=%s' % (self.__gsessionid, ) server_response = atom.service.AtomService.Get(self, uri, extra_headers) result_body = server_response.read() if server_response.status == 200: if converter: return converter(result_body) # There was no ResultsTransformer specified, so try to convert the # server's response into a GDataFeed. feed = gdata.GDataFeedFromString(result_body) if not feed: # If conversion to a GDataFeed failed, try to convert the server's # response to a GDataEntry. entry = gdata.GDataEntryFromString(result_body) if not entry: # The server's response wasn't a feed, or an entry, so return the # response body as a string. return result_body return entry return feed elif server_response.status == 302: if redirects_remaining > 0: location = server_response.getheader('Location') if location is not None: m = re.compile('[\?\&]gsessionid=(\w*)').search(location) if m is not None: self.__gsessionid = m.group(1) return self.Get(location, extra_headers, redirects_remaining - 1, encoding=encoding, converter=converter) else: raise RequestError, { 'status': server_response.status, 'reason': '302 received without Location header', 'body': result_body } else: raise RequestError, { 'status': server_response.status, 'reason': 'Redirect received, but redirects_remaining <= 0', 'body': result_body } else: raise RequestError, { 'status': server_response.status, 'reason': server_response.reason, 'body': result_body }
def setUp(self): self.entry = gdata.GDataEntryFromString(test_data.XML_ENTRY_1)
def PostOrPut(self, verb, data, uri, extra_headers=None, url_params=None, escape_params=True, redirects_remaining=4, media_source=None, converter=None): """Insert data into a GData service at the given URI. Args: verb: string, either 'POST' or 'PUT' data: string, ElementTree._Element, atom.Entry, or gdata.GDataEntry The XML to be sent to the uri. uri: string The location (feed) to which the data should be inserted. Example: '/base/feeds/items'. extra_headers: dict (optional) HTTP headers which are to be included. The client automatically sets the Content-Type, Authorization, and Content-Length headers. url_params: dict (optional) Additional URL parameters to be included in the URI. These are translated into query arguments in the form '&dict_key=value&...'. Example: {'max-results': '250'} becomes &max-results=250 escape_params: boolean (optional) If false, the calling code has already ensured that the query will form a valid URL (all reserved characters have been escaped). If true, this method will escape the query and any URL parameters provided. media_source: MediaSource (optional) Container for the media to be sent along with the entry, if provided. converter: func (optional) A function which will be executed on the server's response. Often this is a function like GDataEntryFromString which will parse the body of the server's response and return a GDataEntry. Returns: If the post succeeded, this method will return a GDataFeed, GDataEntry, or the results of running converter on the server's result body (if converter was specified). """ if extra_headers is None: extra_headers = {} # Add the authentication header to the Get request if self.__auth_token: extra_headers['Authorization'] = self.__auth_token if self.__gsessionid is not None: if uri.find('gsessionid=') < 0: if uri.find('?') > -1: uri += '&gsessionid=%s' % (self.__gsessionid, ) else: uri += '?gsessionid=%s' % (self.__gsessionid, ) if data and media_source: if ElementTree.iselement(data): data_str = ElementTree.tostring(data) else: data_str = str(data) multipart = [] multipart.append('Media multipart posting\r\n--END_OF_PART\r\n' + \ 'Content-Type: application/atom+xml\r\n\r\n') multipart.append('\r\n--END_OF_PART\r\nContent-Type: ' + \ media_source.content_type+'\r\n\r\n') multipart.append('\r\n--END_OF_PART--\r\n') extra_headers['MIME-version'] = '1.0' extra_headers['Content-Length'] = str( len(multipart[0]) + len(multipart[1]) + len(multipart[2]) + len(data_str) + media_source.content_length) server_response = self.handler.HttpRequest( self, verb, [ multipart[0], data_str, multipart[1], media_source.file_handle, multipart[2] ], uri, extra_headers=extra_headers, url_params=url_params, escape_params=escape_params, content_type='multipart/related; boundary=END_OF_PART') result_body = server_response.read() elif media_source or isinstance(data, gdata.MediaSource): if isinstance(data, gdata.MediaSource): media_source = data extra_headers['Content-Length'] = media_source.content_length server_response = self.handler.HttpRequest( self, verb, media_source.file_handle, uri, extra_headers=extra_headers, url_params=url_params, escape_params=escape_params, content_type=media_source.content_type) result_body = server_response.read() else: http_data = data content_type = 'application/atom+xml' server_response = self.handler.HttpRequest( self, verb, http_data, uri, extra_headers=extra_headers, url_params=url_params, escape_params=escape_params, content_type=content_type) result_body = server_response.read() # Server returns 201 for most post requests, but when performing a batch # request the server responds with a 200 on success. if server_response.status == 201 or server_response.status == 200: if converter: return converter(result_body) feed = gdata.GDataFeedFromString(result_body) if not feed: entry = gdata.GDataEntryFromString(result_body) if not entry: return result_body return entry return feed elif server_response.status == 302: if redirects_remaining > 0: location = server_response.getheader('Location') if location is not None: m = re.compile('[\?\&]gsessionid=(\w*)').search(location) if m is not None: self.__gsessionid = m.group(1) return self.Post(data, location, extra_headers, url_params, escape_params, redirects_remaining - 1, media_source, converter=converter) else: raise RequestError, { 'status': server_response.status, 'reason': '302 received without Location header', 'body': result_body } else: raise RequestError, { 'status': server_response.status, 'reason': 'Redirect received, but redirects_remaining <= 0', 'body': result_body } else: raise RequestError, { 'status': server_response.status, 'reason': server_response.reason, 'body': result_body }