/gdata/__init__.py
http://radioappz.googlecode.com/ · Python · 835 lines · 662 code · 82 blank · 91 comment · 44 complexity · 5dcaa4ad36cb319798ea710077c41115 MD5 · raw file
- #!/usr/bin/python
- #
- # Copyright (C) 2006 Google Inc.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- """Contains classes representing Google Data elements.
- Extends Atom classes to add Google Data specific elements.
- """
- __author__ = 'j.s@google.com (Jeffrey Scudder)'
- import os
- import atom
- try:
- from xml.etree import cElementTree as ElementTree
- except ImportError:
- try:
- import cElementTree as ElementTree
- except ImportError:
- try:
- from xml.etree import ElementTree
- except ImportError:
- from elementtree import ElementTree
- # XML namespaces which are often used in GData entities.
- GDATA_NAMESPACE = 'http://schemas.google.com/g/2005'
- GDATA_TEMPLATE = '{http://schemas.google.com/g/2005}%s'
- OPENSEARCH_NAMESPACE = 'http://a9.com/-/spec/opensearchrss/1.0/'
- OPENSEARCH_TEMPLATE = '{http://a9.com/-/spec/opensearchrss/1.0/}%s'
- BATCH_NAMESPACE = 'http://schemas.google.com/gdata/batch'
- GACL_NAMESPACE = 'http://schemas.google.com/acl/2007'
- GACL_TEMPLATE = '{http://schemas.google.com/acl/2007}%s'
- # Labels used in batch request entries to specify the desired CRUD operation.
- BATCH_INSERT = 'insert'
- BATCH_UPDATE = 'update'
- BATCH_DELETE = 'delete'
- BATCH_QUERY = 'query'
- class Error(Exception):
- pass
- class MissingRequiredParameters(Error):
- pass
- class MediaSource(object):
- """GData Entries can refer to media sources, so this class provides a
- place to store references to these objects along with some metadata.
- """
- def __init__(self, file_handle=None, content_type=None, content_length=None,
- file_path=None, file_name=None):
- """Creates an object of type MediaSource.
- Args:
- file_handle: A file handle pointing to the file to be encapsulated in the
- MediaSource
- content_type: string The MIME type of the file. Required if a file_handle
- is given.
- content_length: int The size of the file. Required if a file_handle is
- given.
- file_path: string (optional) A full path name to the file. Used in
- place of a file_handle.
- file_name: string The name of the file without any path information.
- Required if a file_handle is given.
- """
- self.file_handle = file_handle
- self.content_type = content_type
- self.content_length = content_length
- self.file_name = file_name
- if (file_handle is None and content_type is not None and
- file_path is not None):
- self.setFile(file_path, content_type)
- def setFile(self, file_name, content_type):
- """A helper function which can create a file handle from a given filename
- and set the content type and length all at once.
- Args:
- file_name: string The path and file name to the file containing the media
- content_type: string A MIME type representing the type of the media
- """
- self.file_handle = open(file_name, 'rb')
- self.content_type = content_type
- self.content_length = os.path.getsize(file_name)
- self.file_name = os.path.basename(file_name)
- class LinkFinder(atom.LinkFinder):
- """An "interface" providing methods to find link elements
- GData Entry elements often contain multiple links which differ in the rel
- attribute or content type. Often, developers are interested in a specific
- type of link so this class provides methods to find specific classes of
- links.
- This class is used as a mixin in GData entries.
- """
- def GetSelfLink(self):
- """Find the first link with rel set to 'self'
- Returns:
- An atom.Link or none if none of the links had rel equal to 'self'
- """
- for a_link in self.link:
- if a_link.rel == 'self':
- return a_link
- return None
- def GetEditLink(self):
- for a_link in self.link:
- if a_link.rel == 'edit':
- return a_link
- return None
- def GetEditMediaLink(self):
- """The Picasa API mistakenly returns media-edit rather than edit-media, but
- this may change soon.
- """
- for a_link in self.link:
- if a_link.rel == 'edit-media':
- return a_link
- if a_link.rel == 'media-edit':
- return a_link
- return None
- def GetHtmlLink(self):
- """Find the first link with rel of alternate and type of text/html
- Returns:
- An atom.Link or None if no links matched
- """
- for a_link in self.link:
- if a_link.rel == 'alternate' and a_link.type == 'text/html':
- return a_link
- return None
- def GetPostLink(self):
- """Get a link containing the POST target URL.
- The POST target URL is used to insert new entries.
- Returns:
- A link object with a rel matching the POST type.
- """
- for a_link in self.link:
- if a_link.rel == 'http://schemas.google.com/g/2005#post':
- return a_link
- return None
- def GetAclLink(self):
- for a_link in self.link:
- if a_link.rel == 'http://schemas.google.com/acl/2007#accessControlList':
- return a_link
- return None
- def GetFeedLink(self):
- for a_link in self.link:
- if a_link.rel == 'http://schemas.google.com/g/2005#feed':
- return a_link
- return None
- def GetNextLink(self):
- for a_link in self.link:
- if a_link.rel == 'next':
- return a_link
- return None
- def GetPrevLink(self):
- for a_link in self.link:
- if a_link.rel == 'previous':
- return a_link
- return None
- class TotalResults(atom.AtomBase):
- """opensearch:TotalResults for a GData feed"""
- _tag = 'totalResults'
- _namespace = OPENSEARCH_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- def __init__(self, extension_elements=None,
- extension_attributes=None, text=None):
- self.text = text
- self.extension_elements = extension_elements or []
- self.extension_attributes = extension_attributes or {}
- def TotalResultsFromString(xml_string):
- return atom.CreateClassFromXMLString(TotalResults, xml_string)
- class StartIndex(atom.AtomBase):
- """The opensearch:startIndex element in GData feed"""
- _tag = 'startIndex'
- _namespace = OPENSEARCH_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- def __init__(self, extension_elements=None,
- extension_attributes=None, text=None):
- self.text = text
- self.extension_elements = extension_elements or []
- self.extension_attributes = extension_attributes or {}
- def StartIndexFromString(xml_string):
- return atom.CreateClassFromXMLString(StartIndex, xml_string)
- class ItemsPerPage(atom.AtomBase):
- """The opensearch:itemsPerPage element in GData feed"""
- _tag = 'itemsPerPage'
- _namespace = OPENSEARCH_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- def __init__(self, extension_elements=None,
- extension_attributes=None, text=None):
- self.text = text
- self.extension_elements = extension_elements or []
- self.extension_attributes = extension_attributes or {}
- def ItemsPerPageFromString(xml_string):
- return atom.CreateClassFromXMLString(ItemsPerPage, xml_string)
- class ExtendedProperty(atom.AtomBase):
- """The Google Data extendedProperty element.
- Used to store arbitrary key-value information specific to your
- application. The value can either be a text string stored as an XML
- attribute (.value), or an XML node (XmlBlob) as a child element.
- This element is used in the Google Calendar data API and the Google
- Contacts data API.
- """
- _tag = 'extendedProperty'
- _namespace = GDATA_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- _attributes['name'] = 'name'
- _attributes['value'] = 'value'
- def __init__(self, name=None, value=None, extension_elements=None,
- extension_attributes=None, text=None):
- self.name = name
- self.value = value
- self.text = text
- self.extension_elements = extension_elements or []
- self.extension_attributes = extension_attributes or {}
- def GetXmlBlobExtensionElement(self):
- """Returns the XML blob as an atom.ExtensionElement.
- Returns:
- An atom.ExtensionElement representing the blob's XML, or None if no
- blob was set.
- """
- if len(self.extension_elements) < 1:
- return None
- else:
- return self.extension_elements[0]
- def GetXmlBlobString(self):
- """Returns the XML blob as a string.
- Returns:
- A string containing the blob's XML, or None if no blob was set.
- """
- blob = self.GetXmlBlobExtensionElement()
- if blob:
- return blob.ToString()
- return None
- def SetXmlBlob(self, blob):
- """Sets the contents of the extendedProperty to XML as a child node.
- Since the extendedProperty is only allowed one child element as an XML
- blob, setting the XML blob will erase any preexisting extension elements
- in this object.
- Args:
- blob: str, ElementTree Element or atom.ExtensionElement representing
- the XML blob stored in the extendedProperty.
- """
- # Erase any existing extension_elements, clears the child nodes from the
- # extendedProperty.
- self.extension_elements = []
- if isinstance(blob, atom.ExtensionElement):
- self.extension_elements.append(blob)
- elif ElementTree.iselement(blob):
- self.extension_elements.append(atom._ExtensionElementFromElementTree(
- blob))
- else:
- self.extension_elements.append(atom.ExtensionElementFromString(blob))
- def ExtendedPropertyFromString(xml_string):
- return atom.CreateClassFromXMLString(ExtendedProperty, xml_string)
- class GDataEntry(atom.Entry, LinkFinder):
- """Extends Atom Entry to provide data processing"""
- _tag = atom.Entry._tag
- _namespace = atom.Entry._namespace
- _children = atom.Entry._children.copy()
- _attributes = atom.Entry._attributes.copy()
- def __GetId(self):
- return self.__id
- # This method was created to strip the unwanted whitespace from the id's
- # text node.
- def __SetId(self, id):
- self.__id = id
- if id is not None and id.text is not None:
- self.__id.text = id.text.strip()
- id = property(__GetId, __SetId)
- def IsMedia(self):
- """Determines whether or not an entry is a GData Media entry.
- """
- if (self.GetEditMediaLink()):
- return True
- else:
- return False
- def GetMediaURL(self):
- """Returns the URL to the media content, if the entry is a media entry.
- Otherwise returns None.
- """
- if not self.IsMedia():
- return None
- else:
- return self.content.src
- def GDataEntryFromString(xml_string):
- """Creates a new GDataEntry instance given a string of XML."""
- return atom.CreateClassFromXMLString(GDataEntry, xml_string)
- class GDataFeed(atom.Feed, LinkFinder):
- """A Feed from a GData service"""
- _tag = 'feed'
- _namespace = atom.ATOM_NAMESPACE
- _children = atom.Feed._children.copy()
- _attributes = atom.Feed._attributes.copy()
- _children['{%s}totalResults' % OPENSEARCH_NAMESPACE] = ('total_results',
- TotalResults)
- _children['{%s}startIndex' % OPENSEARCH_NAMESPACE] = ('start_index',
- StartIndex)
- _children['{%s}itemsPerPage' % OPENSEARCH_NAMESPACE] = ('items_per_page',
- ItemsPerPage)
- # Add a conversion rule for atom:entry to make it into a GData
- # Entry.
- _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [GDataEntry])
- def __GetId(self):
- return self.__id
- def __SetId(self, id):
- self.__id = id
- if id is not None and id.text is not None:
- self.__id.text = id.text.strip()
- id = property(__GetId, __SetId)
- def __GetGenerator(self):
- return self.__generator
- def __SetGenerator(self, generator):
- self.__generator = generator
- if generator is not None:
- self.__generator.text = generator.text.strip()
- generator = property(__GetGenerator, __SetGenerator)
- def __init__(self, author=None, category=None, contributor=None,
- generator=None, icon=None, atom_id=None, link=None, logo=None,
- rights=None, subtitle=None, title=None, updated=None, entry=None,
- total_results=None, start_index=None, items_per_page=None,
- extension_elements=None, extension_attributes=None, text=None):
- """Constructor for Source
- Args:
- author: list (optional) A list of Author instances which belong to this
- class.
- category: list (optional) A list of Category instances
- contributor: list (optional) A list on Contributor instances
- generator: Generator (optional)
- icon: Icon (optional)
- id: Id (optional) The entry's Id element
- link: list (optional) A list of Link instances
- logo: Logo (optional)
- rights: Rights (optional) The entry's Rights element
- subtitle: Subtitle (optional) The entry's subtitle element
- title: Title (optional) the entry's title element
- updated: Updated (optional) the entry's updated element
- entry: list (optional) A list of the Entry instances contained in the
- feed.
- text: String (optional) The text contents of the element. This is the
- contents of the Entry's XML text node.
- (Example: <foo>This is the text</foo>)
- extension_elements: list (optional) A list of ExtensionElement instances
- which are children of this element.
- extension_attributes: dict (optional) A dictionary of strings which are
- the values for additional XML attributes of this element.
- """
- self.author = author or []
- self.category = category or []
- self.contributor = contributor or []
- self.generator = generator
- self.icon = icon
- self.id = atom_id
- self.link = link or []
- self.logo = logo
- self.rights = rights
- self.subtitle = subtitle
- self.title = title
- self.updated = updated
- self.entry = entry or []
- self.total_results = total_results
- self.start_index = start_index
- self.items_per_page = items_per_page
- self.text = text
- self.extension_elements = extension_elements or []
- self.extension_attributes = extension_attributes or {}
- def GDataFeedFromString(xml_string):
- return atom.CreateClassFromXMLString(GDataFeed, xml_string)
- class BatchId(atom.AtomBase):
- _tag = 'id'
- _namespace = BATCH_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- def BatchIdFromString(xml_string):
- return atom.CreateClassFromXMLString(BatchId, xml_string)
- class BatchOperation(atom.AtomBase):
- _tag = 'operation'
- _namespace = BATCH_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- _attributes['type'] = 'type'
- def __init__(self, op_type=None, extension_elements=None,
- extension_attributes=None,
- text=None):
- self.type = op_type
- atom.AtomBase.__init__(self,
- extension_elements=extension_elements,
- extension_attributes=extension_attributes,
- text=text)
- def BatchOperationFromString(xml_string):
- return atom.CreateClassFromXMLString(BatchOperation, xml_string)
- class BatchStatus(atom.AtomBase):
- """The batch:status element present in a batch response entry.
- A status element contains the code (HTTP response code) and
- reason as elements. In a single request these fields would
- be part of the HTTP response, but in a batch request each
- Entry operation has a corresponding Entry in the response
- feed which includes status information.
- See http://code.google.com/apis/gdata/batch.html#Handling_Errors
- """
- _tag = 'status'
- _namespace = BATCH_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- _attributes['code'] = 'code'
- _attributes['reason'] = 'reason'
- _attributes['content-type'] = 'content_type'
- def __init__(self, code=None, reason=None, content_type=None,
- extension_elements=None, extension_attributes=None, text=None):
- self.code = code
- self.reason = reason
- self.content_type = content_type
- atom.AtomBase.__init__(self, extension_elements=extension_elements,
- extension_attributes=extension_attributes,
- text=text)
- def BatchStatusFromString(xml_string):
- return atom.CreateClassFromXMLString(BatchStatus, xml_string)
- class BatchEntry(GDataEntry):
- """An atom:entry for use in batch requests.
- The BatchEntry contains additional members to specify the operation to be
- performed on this entry and a batch ID so that the server can reference
- individual operations in the response feed. For more information, see:
- http://code.google.com/apis/gdata/batch.html
- """
- _tag = GDataEntry._tag
- _namespace = GDataEntry._namespace
- _children = GDataEntry._children.copy()
- _children['{%s}operation' % BATCH_NAMESPACE] = ('batch_operation', BatchOperation)
- _children['{%s}id' % BATCH_NAMESPACE] = ('batch_id', BatchId)
- _children['{%s}status' % BATCH_NAMESPACE] = ('batch_status', BatchStatus)
- _attributes = GDataEntry._attributes.copy()
- def __init__(self, author=None, category=None, content=None,
- contributor=None, atom_id=None, link=None, published=None, rights=None,
- source=None, summary=None, control=None, title=None, updated=None,
- batch_operation=None, batch_id=None, batch_status=None,
- extension_elements=None, extension_attributes=None, text=None):
- self.batch_operation = batch_operation
- self.batch_id = batch_id
- self.batch_status = batch_status
- GDataEntry.__init__(self, author=author, category=category,
- content=content, contributor=contributor, atom_id=atom_id, link=link,
- published=published, rights=rights, source=source, summary=summary,
- control=control, title=title, updated=updated,
- extension_elements=extension_elements,
- extension_attributes=extension_attributes, text=text)
- def BatchEntryFromString(xml_string):
- return atom.CreateClassFromXMLString(BatchEntry, xml_string)
- class BatchInterrupted(atom.AtomBase):
- """The batch:interrupted element sent if batch request was interrupted.
- Only appears in a feed if some of the batch entries could not be processed.
- See: http://code.google.com/apis/gdata/batch.html#Handling_Errors
- """
- _tag = 'interrupted'
- _namespace = BATCH_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- _attributes['reason'] = 'reason'
- _attributes['success'] = 'success'
- _attributes['failures'] = 'failures'
- _attributes['parsed'] = 'parsed'
- def __init__(self, reason=None, success=None, failures=None, parsed=None,
- extension_elements=None, extension_attributes=None, text=None):
- self.reason = reason
- self.success = success
- self.failures = failures
- self.parsed = parsed
- atom.AtomBase.__init__(self, extension_elements=extension_elements,
- extension_attributes=extension_attributes,
- text=text)
- def BatchInterruptedFromString(xml_string):
- return atom.CreateClassFromXMLString(BatchInterrupted, xml_string)
- class BatchFeed(GDataFeed):
- """A feed containing a list of batch request entries."""
- _tag = GDataFeed._tag
- _namespace = GDataFeed._namespace
- _children = GDataFeed._children.copy()
- _attributes = GDataFeed._attributes.copy()
- _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [BatchEntry])
- _children['{%s}interrupted' % BATCH_NAMESPACE] = ('interrupted', BatchInterrupted)
- def __init__(self, author=None, category=None, contributor=None,
- generator=None, icon=None, atom_id=None, link=None, logo=None,
- rights=None, subtitle=None, title=None, updated=None, entry=None,
- total_results=None, start_index=None, items_per_page=None,
- interrupted=None,
- extension_elements=None, extension_attributes=None, text=None):
- self.interrupted = interrupted
- GDataFeed.__init__(self, author=author, category=category,
- contributor=contributor, generator=generator,
- icon=icon, atom_id=atom_id, link=link,
- logo=logo, rights=rights, subtitle=subtitle,
- title=title, updated=updated, entry=entry,
- total_results=total_results, start_index=start_index,
- items_per_page=items_per_page,
- extension_elements=extension_elements,
- extension_attributes=extension_attributes,
- text=text)
- def AddBatchEntry(self, entry=None, id_url_string=None,
- batch_id_string=None, operation_string=None):
- """Logic for populating members of a BatchEntry and adding to the feed.
- If the entry is not a BatchEntry, it is converted to a BatchEntry so
- that the batch specific members will be present.
- The id_url_string can be used in place of an entry if the batch operation
- applies to a URL. For example query and delete operations require just
- the URL of an entry, no body is sent in the HTTP request. If an
- id_url_string is sent instead of an entry, a BatchEntry is created and
- added to the feed.
- This method also assigns the desired batch id to the entry so that it
- can be referenced in the server's response. If the batch_id_string is
- None, this method will assign a batch_id to be the index at which this
- entry will be in the feed's entry list.
- Args:
- entry: BatchEntry, atom.Entry, or another Entry flavor (optional) The
- entry which will be sent to the server as part of the batch request.
- The item must have a valid atom id so that the server knows which
- entry this request references.
- id_url_string: str (optional) The URL of the entry to be acted on. You
- can find this URL in the text member of the atom id for an entry.
- If an entry is not sent, this id will be used to construct a new
- BatchEntry which will be added to the request feed.
- batch_id_string: str (optional) The batch ID to be used to reference
- this batch operation in the results feed. If this parameter is None,
- the current length of the feed's entry array will be used as a
- count. Note that batch_ids should either always be specified or
- never, mixing could potentially result in duplicate batch ids.
- operation_string: str (optional) The desired batch operation which will
- set the batch_operation.type member of the entry. Options are
- 'insert', 'update', 'delete', and 'query'
- Raises:
- MissingRequiredParameters: Raised if neither an id_ url_string nor an
- entry are provided in the request.
- Returns:
- The added entry.
- """
- if entry is None and id_url_string is None:
- raise MissingRequiredParameters('supply either an entry or URL string')
- if entry is None and id_url_string is not None:
- entry = BatchEntry(atom_id=atom.Id(text=id_url_string))
- # TODO: handle cases in which the entry lacks batch_... members.
- #if not isinstance(entry, BatchEntry):
- # Convert the entry to a batch entry.
- if batch_id_string is not None:
- entry.batch_id = BatchId(text=batch_id_string)
- elif entry.batch_id is None or entry.batch_id.text is None:
- entry.batch_id = BatchId(text=str(len(self.entry)))
- if operation_string is not None:
- entry.batch_operation = BatchOperation(op_type=operation_string)
- self.entry.append(entry)
- return entry
- def AddInsert(self, entry, batch_id_string=None):
- """Add an insert request to the operations in this batch request feed.
- If the entry doesn't yet have an operation or a batch id, these will
- be set to the insert operation and a batch_id specified as a parameter.
- Args:
- entry: BatchEntry The entry which will be sent in the batch feed as an
- insert request.
- batch_id_string: str (optional) The batch ID to be used to reference
- this batch operation in the results feed. If this parameter is None,
- the current length of the feed's entry array will be used as a
- count. Note that batch_ids should either always be specified or
- never, mixing could potentially result in duplicate batch ids.
- """
- entry = self.AddBatchEntry(entry=entry, batch_id_string=batch_id_string,
- operation_string=BATCH_INSERT)
- def AddUpdate(self, entry, batch_id_string=None):
- """Add an update request to the list of batch operations in this feed.
- Sets the operation type of the entry to insert if it is not already set
- and assigns the desired batch id to the entry so that it can be
- referenced in the server's response.
- Args:
- entry: BatchEntry The entry which will be sent to the server as an
- update (HTTP PUT) request. The item must have a valid atom id
- so that the server knows which entry to replace.
- batch_id_string: str (optional) The batch ID to be used to reference
- this batch operation in the results feed. If this parameter is None,
- the current length of the feed's entry array will be used as a
- count. See also comments for AddInsert.
- """
- entry = self.AddBatchEntry(entry=entry, batch_id_string=batch_id_string,
- operation_string=BATCH_UPDATE)
- def AddDelete(self, url_string=None, entry=None, batch_id_string=None):
- """Adds a delete request to the batch request feed.
- This method takes either the url_string which is the atom id of the item
- to be deleted, or the entry itself. The atom id of the entry must be
- present so that the server knows which entry should be deleted.
- Args:
- url_string: str (optional) The URL of the entry to be deleted. You can
- find this URL in the text member of the atom id for an entry.
- entry: BatchEntry (optional) The entry to be deleted.
- batch_id_string: str (optional)
- Raises:
- MissingRequiredParameters: Raised if neither a url_string nor an entry
- are provided in the request.
- """
- entry = self.AddBatchEntry(entry=entry, id_url_string=url_string,
- batch_id_string=batch_id_string,
- operation_string=BATCH_DELETE)
- def AddQuery(self, url_string=None, entry=None, batch_id_string=None):
- """Adds a query request to the batch request feed.
- This method takes either the url_string which is the query URL
- whose results will be added to the result feed. The query URL will
- be encapsulated in a BatchEntry, and you may pass in the BatchEntry
- with a query URL instead of sending a url_string.
- Args:
- url_string: str (optional)
- entry: BatchEntry (optional)
- batch_id_string: str (optional)
- Raises:
- MissingRequiredParameters
- """
- entry = self.AddBatchEntry(entry=entry, id_url_string=url_string,
- batch_id_string=batch_id_string,
- operation_string=BATCH_QUERY)
- def GetBatchLink(self):
- for link in self.link:
- if link.rel == 'http://schemas.google.com/g/2005#batch':
- return link
- return None
- def BatchFeedFromString(xml_string):
- return atom.CreateClassFromXMLString(BatchFeed, xml_string)
- class EntryLink(atom.AtomBase):
- """The gd:entryLink element"""
- _tag = 'entryLink'
- _namespace = GDATA_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- # The entry used to be an atom.Entry, now it is a GDataEntry.
- _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', GDataEntry)
- _attributes['rel'] = 'rel'
- _attributes['readOnly'] = 'read_only'
- _attributes['href'] = 'href'
- def __init__(self, href=None, read_only=None, rel=None,
- entry=None, extension_elements=None,
- extension_attributes=None, text=None):
- self.href = href
- self.read_only = read_only
- self.rel = rel
- self.entry = entry
- self.text = text
- self.extension_elements = extension_elements or []
- self.extension_attributes = extension_attributes or {}
- def EntryLinkFromString(xml_string):
- return atom.CreateClassFromXMLString(EntryLink, xml_string)
- class FeedLink(atom.AtomBase):
- """The gd:feedLink element"""
- _tag = 'feedLink'
- _namespace = GDATA_NAMESPACE
- _children = atom.AtomBase._children.copy()
- _attributes = atom.AtomBase._attributes.copy()
- _children['{%s}feed' % atom.ATOM_NAMESPACE] = ('feed', GDataFeed)
- _attributes['rel'] = 'rel'
- _attributes['readOnly'] = 'read_only'
- _attributes['countHint'] = 'count_hint'
- _attributes['href'] = 'href'
- def __init__(self, count_hint=None, href=None, read_only=None, rel=None,
- feed=None, extension_elements=None, extension_attributes=None,
- text=None):
- self.count_hint = count_hint
- self.href = href
- self.read_only = read_only
- self.rel = rel
- self.feed = feed
- self.text = text
- self.extension_elements = extension_elements or []
- self.extension_attributes = extension_attributes or {}
- def FeedLinkFromString(xml_string):
- return atom.CreateClassFromXMLString(FeedLink, xml_string)