/gdata/base/__init__.py

http://radioappz.googlecode.com/ · Python · 687 lines · 560 code · 51 blank · 76 comment · 30 complexity · 65e1bcb23bb05a28b86e601f6618dc44 MD5 · raw file

  1. #!/usr/bin/python
  2. #
  3. # Copyright (C) 2006 Google Inc.
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. """Contains extensions to Atom objects used with Google Base."""
  17. __author__ = 'api.jscudder (Jeffrey Scudder)'
  18. try:
  19. from xml.etree import cElementTree as ElementTree
  20. except ImportError:
  21. try:
  22. import cElementTree as ElementTree
  23. except ImportError:
  24. try:
  25. from xml.etree import ElementTree
  26. except ImportError:
  27. from elementtree import ElementTree
  28. import atom
  29. import gdata
  30. # XML namespaces which are often used in Google Base entities.
  31. GBASE_NAMESPACE = 'http://base.google.com/ns/1.0'
  32. GBASE_TEMPLATE = '{http://base.google.com/ns/1.0}%s'
  33. GMETA_NAMESPACE = 'http://base.google.com/ns-metadata/1.0'
  34. GMETA_TEMPLATE = '{http://base.google.com/ns-metadata/1.0}%s'
  35. class ItemAttributeContainer(object):
  36. """Provides methods for finding Google Base Item attributes.
  37. Google Base item attributes are child nodes in the gbase namespace. Google
  38. Base allows you to define your own item attributes and this class provides
  39. methods to interact with the custom attributes.
  40. """
  41. def GetItemAttributes(self, name):
  42. """Returns a list of all item attributes which have the desired name.
  43. Args:
  44. name: str The tag of the desired base attributes. For example, calling
  45. this method with 'rating' would return a list of ItemAttributes
  46. represented by a 'g:rating' tag.
  47. Returns:
  48. A list of matching ItemAttribute objects.
  49. """
  50. result = []
  51. for attrib in self.item_attributes:
  52. if attrib.name == name:
  53. result.append(attrib)
  54. return result
  55. def FindItemAttribute(self, name):
  56. """Get the contents of the first Base item attribute which matches name.
  57. This method is deprecated, please use GetItemAttributes instead.
  58. Args:
  59. name: str The tag of the desired base attribute. For example, calling
  60. this method with name = 'rating' would search for a tag rating
  61. in the GBase namespace in the item attributes.
  62. Returns:
  63. The text contents of the item attribute, or none if the attribute was
  64. not found.
  65. """
  66. for attrib in self.item_attributes:
  67. if attrib.name == name:
  68. return attrib.text
  69. return None
  70. def AddItemAttribute(self, name, value, value_type=None, access=None):
  71. """Adds a new item attribute tag containing the value.
  72. Creates a new extension element in the GBase namespace to represent a
  73. Google Base item attribute.
  74. Args:
  75. name: str The tag name for the new attribute. This must be a valid xml
  76. tag name. The tag will be placed in the GBase namespace.
  77. value: str Contents for the item attribute
  78. value_type: str (optional) The type of data in the vlaue, Examples: text
  79. float
  80. access: str (optional) Used to hide attributes. The attribute is not
  81. exposed in the snippets feed if access is set to 'private'.
  82. """
  83. new_attribute = ItemAttribute(name, text=value,
  84. text_type=value_type, access=access)
  85. self.item_attributes.append(new_attribute)
  86. def SetItemAttribute(self, name, value):
  87. """Changes an existing item attribute's value."""
  88. for attrib in self.item_attributes:
  89. if attrib.name == name:
  90. attrib.text = value
  91. return
  92. def RemoveItemAttribute(self, name):
  93. """Deletes the first extension element which matches name.
  94. Deletes the first extension element which matches name.
  95. """
  96. for i in xrange(len(self.item_attributes)):
  97. if self.item_attributes[i].name == name:
  98. del self.item_attributes[i]
  99. return
  100. # We need to overwrite _ConvertElementTreeToMember to add special logic to
  101. # convert custom attributes to members
  102. def _ConvertElementTreeToMember(self, child_tree):
  103. # Find the element's tag in this class's list of child members
  104. if self.__class__._children.has_key(child_tree.tag):
  105. member_name = self.__class__._children[child_tree.tag][0]
  106. member_class = self.__class__._children[child_tree.tag][1]
  107. # If the class member is supposed to contain a list, make sure the
  108. # matching member is set to a list, then append the new member
  109. # instance to the list.
  110. if isinstance(member_class, list):
  111. if getattr(self, member_name) is None:
  112. setattr(self, member_name, [])
  113. getattr(self, member_name).append(atom._CreateClassFromElementTree(
  114. member_class[0], child_tree))
  115. else:
  116. setattr(self, member_name,
  117. atom._CreateClassFromElementTree(member_class, child_tree))
  118. elif child_tree.tag.find('{%s}' % GBASE_NAMESPACE) == 0:
  119. # If this is in the gbase namespace, make it into an extension element.
  120. name = child_tree.tag[child_tree.tag.index('}')+1:]
  121. value = child_tree.text
  122. if child_tree.attrib.has_key('type'):
  123. value_type = child_tree.attrib['type']
  124. else:
  125. value_type = None
  126. self.AddItemAttribute(name, value, value_type)
  127. else:
  128. atom.ExtensionContainer._ConvertElementTreeToMember(self, child_tree)
  129. # We need to overwtite _AddMembersToElementTree to add special logic to
  130. # convert custom members to XML nodes.
  131. def _AddMembersToElementTree(self, tree):
  132. # Convert the members of this class which are XML child nodes.
  133. # This uses the class's _children dictionary to find the members which
  134. # should become XML child nodes.
  135. member_node_names = [values[0] for tag, values in
  136. self.__class__._children.iteritems()]
  137. for member_name in member_node_names:
  138. member = getattr(self, member_name)
  139. if member is None:
  140. pass
  141. elif isinstance(member, list):
  142. for instance in member:
  143. instance._BecomeChildElement(tree)
  144. else:
  145. member._BecomeChildElement(tree)
  146. # Convert the members of this class which are XML attributes.
  147. for xml_attribute, member_name in self.__class__._attributes.iteritems():
  148. member = getattr(self, member_name)
  149. if member is not None:
  150. tree.attrib[xml_attribute] = member
  151. # Convert all special custom item attributes to nodes
  152. for attribute in self.item_attributes:
  153. attribute._BecomeChildElement(tree)
  154. # Lastly, call the ExtensionContainers's _AddMembersToElementTree to
  155. # convert any extension attributes.
  156. atom.ExtensionContainer._AddMembersToElementTree(self, tree)
  157. class ItemAttribute(atom.Text):
  158. """An optional or user defined attribute for a GBase item.
  159. Google Base allows items to have custom attribute child nodes. These nodes
  160. have contents and a type attribute which tells Google Base whether the
  161. contents are text, a float value with units, etc. The Atom text class has
  162. the same structure, so this class inherits from Text.
  163. """
  164. _namespace = GBASE_NAMESPACE
  165. _children = atom.Text._children.copy()
  166. _attributes = atom.Text._attributes.copy()
  167. _attributes['access'] = 'access'
  168. def __init__(self, name, text_type=None, access=None, text=None,
  169. extension_elements=None, extension_attributes=None):
  170. """Constructor for a GBase item attribute
  171. Args:
  172. name: str The name of the attribute. Examples include
  173. price, color, make, model, pages, salary, etc.
  174. text_type: str (optional) The type associated with the text contents
  175. access: str (optional) If the access attribute is set to 'private', the
  176. attribute will not be included in the item's description in the
  177. snippets feed
  178. text: str (optional) The text data in the this element
  179. extension_elements: list (optional) A list of ExtensionElement
  180. instances
  181. extension_attributes: dict (optional) A dictionary of attribute
  182. value string pairs
  183. """
  184. self.name = name
  185. self.type = text_type
  186. self.access = access
  187. self.text = text
  188. self.extension_elements = extension_elements or []
  189. self.extension_attributes = extension_attributes or {}
  190. def _BecomeChildElement(self, tree):
  191. new_child = ElementTree.Element('')
  192. tree.append(new_child)
  193. new_child.tag = '{%s}%s' % (self.__class__._namespace,
  194. self.name)
  195. self._AddMembersToElementTree(new_child)
  196. def _ToElementTree(self):
  197. new_tree = ElementTree.Element('{%s}%s' % (self.__class__._namespace,
  198. self.name))
  199. self._AddMembersToElementTree(new_tree)
  200. return new_tree
  201. def ItemAttributeFromString(xml_string):
  202. element_tree = ElementTree.fromstring(xml_string)
  203. return _ItemAttributeFromElementTree(element_tree)
  204. def _ItemAttributeFromElementTree(element_tree):
  205. if element_tree.tag.find(GBASE_TEMPLATE % '') == 0:
  206. to_return = ItemAttribute('')
  207. to_return._HarvestElementTree(element_tree)
  208. to_return.name = element_tree.tag[element_tree.tag.index('}')+1:]
  209. if to_return.name and to_return.name != '':
  210. return to_return
  211. return None
  212. class Label(atom.AtomBase):
  213. """The Google Base label element"""
  214. _tag = 'label'
  215. _namespace = GBASE_NAMESPACE
  216. _children = atom.AtomBase._children.copy()
  217. _attributes = atom.AtomBase._attributes.copy()
  218. def __init__(self, text=None, extension_elements=None,
  219. extension_attributes=None):
  220. self.text = text
  221. self.extension_elements = extension_elements or []
  222. self.extension_attributes = extension_attributes or {}
  223. def LabelFromString(xml_string):
  224. return atom.CreateClassFromXMLString(Label, xml_string)
  225. class Thumbnail(atom.AtomBase):
  226. """The Google Base thumbnail element"""
  227. _tag = 'thumbnail'
  228. _namespace = GMETA_NAMESPACE
  229. _children = atom.AtomBase._children.copy()
  230. _attributes = atom.AtomBase._attributes.copy()
  231. _attributes['width'] = 'width'
  232. _attributes['height'] = 'height'
  233. def __init__(self, width=None, height=None, text=None, extension_elements=None,
  234. extension_attributes=None):
  235. self.text = text
  236. self.extension_elements = extension_elements or []
  237. self.extension_attributes = extension_attributes or {}
  238. self.width = width
  239. self.height = height
  240. def ThumbnailFromString(xml_string):
  241. return atom.CreateClassFromXMLString(Thumbnail, xml_string)
  242. class ImageLink(atom.Text):
  243. """The Google Base image_link element"""
  244. _tag = 'image_link'
  245. _namespace = GBASE_NAMESPACE
  246. _children = atom.Text._children.copy()
  247. _attributes = atom.Text._attributes.copy()
  248. _children['{%s}thumbnail' % GMETA_NAMESPACE] = ('thumbnail', [Thumbnail])
  249. def __init__(self, thumbnail=None, text=None, extension_elements=None,
  250. text_type=None, extension_attributes=None):
  251. self.thumbnail = thumbnail or []
  252. self.text = text
  253. self.type = text_type
  254. self.extension_elements = extension_elements or []
  255. self.extension_attributes = extension_attributes or {}
  256. def ImageLinkFromString(xml_string):
  257. return atom.CreateClassFromXMLString(ImageLink, xml_string)
  258. class ItemType(atom.Text):
  259. """The Google Base item_type element"""
  260. _tag = 'item_type'
  261. _namespace = GBASE_NAMESPACE
  262. _children = atom.Text._children.copy()
  263. _attributes = atom.Text._attributes.copy()
  264. def __init__(self, text=None, extension_elements=None,
  265. text_type=None, extension_attributes=None):
  266. self.text = text
  267. self.type = text_type
  268. self.extension_elements = extension_elements or []
  269. self.extension_attributes = extension_attributes or {}
  270. def ItemTypeFromString(xml_string):
  271. return atom.CreateClassFromXMLString(ItemType, xml_string)
  272. class MetaItemType(ItemType):
  273. """The Google Base item_type element"""
  274. _tag = 'item_type'
  275. _namespace = GMETA_NAMESPACE
  276. _children = ItemType._children.copy()
  277. _attributes = ItemType._attributes.copy()
  278. def MetaItemTypeFromString(xml_string):
  279. return atom.CreateClassFromXMLString(MetaItemType, xml_string)
  280. class Value(atom.AtomBase):
  281. """Metadata about common values for a given attribute
  282. A value is a child of an attribute which comes from the attributes feed.
  283. The value's text is a commonly used value paired with an attribute name
  284. and the value's count tells how often this value appears for the given
  285. attribute in the search results.
  286. """
  287. _tag = 'value'
  288. _namespace = GMETA_NAMESPACE
  289. _children = atom.AtomBase._children.copy()
  290. _attributes = atom.AtomBase._attributes.copy()
  291. _attributes['count'] = 'count'
  292. def __init__(self, count=None, text=None, extension_elements=None,
  293. extension_attributes=None):
  294. """Constructor for Attribute metadata element
  295. Args:
  296. count: str (optional) The number of times the value in text is given
  297. for the parent attribute.
  298. text: str (optional) The value which appears in the search results.
  299. extension_elements: list (optional) A list of ExtensionElement
  300. instances
  301. extension_attributes: dict (optional) A dictionary of attribute value
  302. string pairs
  303. """
  304. self.count = count
  305. self.text = text
  306. self.extension_elements = extension_elements or []
  307. self.extension_attributes = extension_attributes or {}
  308. def ValueFromString(xml_string):
  309. return atom.CreateClassFromXMLString(Value, xml_string)
  310. class Attribute(atom.Text):
  311. """Metadata about an attribute from the attributes feed
  312. An entry from the attributes feed contains a list of attributes. Each
  313. attribute describes the attribute's type and count of the items which
  314. use the attribute.
  315. """
  316. _tag = 'attribute'
  317. _namespace = GMETA_NAMESPACE
  318. _children = atom.Text._children.copy()
  319. _attributes = atom.Text._attributes.copy()
  320. _children['{%s}value' % GMETA_NAMESPACE] = ('value', [Value])
  321. _attributes['count'] = 'count'
  322. _attributes['name'] = 'name'
  323. def __init__(self, name=None, attribute_type=None, count=None, value=None,
  324. text=None, extension_elements=None, extension_attributes=None):
  325. """Constructor for Attribute metadata element
  326. Args:
  327. name: str (optional) The name of the attribute
  328. attribute_type: str (optional) The type for the attribute. Examples:
  329. test, float, etc.
  330. count: str (optional) The number of times this attribute appears in
  331. the query results.
  332. value: list (optional) The values which are often used for this
  333. attirbute.
  334. text: str (optional) The text contents of the XML for this attribute.
  335. extension_elements: list (optional) A list of ExtensionElement
  336. instances
  337. extension_attributes: dict (optional) A dictionary of attribute value
  338. string pairs
  339. """
  340. self.name = name
  341. self.type = attribute_type
  342. self.count = count
  343. self.value = value or []
  344. self.text = text
  345. self.extension_elements = extension_elements or []
  346. self.extension_attributes = extension_attributes or {}
  347. def AttributeFromString(xml_string):
  348. return atom.CreateClassFromXMLString(Attribute, xml_string)
  349. class Attributes(atom.AtomBase):
  350. """A collection of Google Base metadata attributes"""
  351. _tag = 'attributes'
  352. _namespace = GMETA_NAMESPACE
  353. _children = atom.AtomBase._children.copy()
  354. _attributes = atom.AtomBase._attributes.copy()
  355. _children['{%s}attribute' % GMETA_NAMESPACE] = ('attribute', [Attribute])
  356. def __init__(self, attribute=None, extension_elements=None,
  357. extension_attributes=None, text=None):
  358. self.attribute = attribute or []
  359. self.extension_elements = extension_elements or []
  360. self.extension_attributes = extension_attributes or {}
  361. self.text = text
  362. class GBaseItem(ItemAttributeContainer, gdata.BatchEntry):
  363. """An Google Base flavor of an Atom Entry.
  364. Google Base items have required attributes, recommended attributes, and user
  365. defined attributes. The required attributes are stored in this class as
  366. members, and other attributes are stored as extension elements. You can
  367. access the recommended and user defined attributes by using
  368. AddItemAttribute, SetItemAttribute, FindItemAttribute, and
  369. RemoveItemAttribute.
  370. The Base Item
  371. """
  372. _tag = 'entry'
  373. _namespace = atom.ATOM_NAMESPACE
  374. _children = gdata.BatchEntry._children.copy()
  375. _attributes = gdata.BatchEntry._attributes.copy()
  376. _children['{%s}label' % GBASE_NAMESPACE] = ('label', [Label])
  377. _children['{%s}item_type' % GBASE_NAMESPACE] = ('item_type', ItemType)
  378. def __init__(self, author=None, category=None, content=None,
  379. contributor=None, atom_id=None, link=None, published=None, rights=None,
  380. source=None, summary=None, title=None, updated=None, control=None,
  381. label=None, item_type=None, item_attributes=None,
  382. batch_operation=None, batch_id=None, batch_status=None,
  383. text=None, extension_elements=None, extension_attributes=None):
  384. self.author = author or []
  385. self.category = category or []
  386. self.content = content
  387. self.contributor = contributor or []
  388. self.id = atom_id
  389. self.link = link or []
  390. self.published = published
  391. self.rights = rights
  392. self.source = source
  393. self.summary = summary
  394. self.title = title
  395. self.updated = updated
  396. self.control = control
  397. self.label = label or []
  398. self.item_type = item_type
  399. self.item_attributes = item_attributes or []
  400. self.batch_operation = batch_operation
  401. self.batch_id = batch_id
  402. self.batch_status = batch_status
  403. self.text = text
  404. self.extension_elements = extension_elements or []
  405. self.extension_attributes = extension_attributes or {}
  406. def GBaseItemFromString(xml_string):
  407. return atom.CreateClassFromXMLString(GBaseItem, xml_string)
  408. class GBaseSnippet(GBaseItem):
  409. _tag = 'entry'
  410. _namespace = atom.ATOM_NAMESPACE
  411. _children = GBaseItem._children.copy()
  412. _attributes = GBaseItem._attributes.copy()
  413. def GBaseSnippetFromString(xml_string):
  414. return atom.CreateClassFromXMLString(GBaseSnippet, xml_string)
  415. class GBaseAttributeEntry(gdata.GDataEntry):
  416. """An Atom Entry from the attributes feed"""
  417. _tag = 'entry'
  418. _namespace = atom.ATOM_NAMESPACE
  419. _children = gdata.GDataEntry._children.copy()
  420. _attributes = gdata.GDataEntry._attributes.copy()
  421. _children['{%s}attribute' % GMETA_NAMESPACE] = ('attribute', [Attribute])
  422. def __init__(self, author=None, category=None, content=None,
  423. contributor=None, atom_id=None, link=None, published=None, rights=None,
  424. source=None, summary=None, title=None, updated=None, label=None,
  425. attribute=None, control=None,
  426. text=None, extension_elements=None, extension_attributes=None):
  427. self.author = author or []
  428. self.category = category or []
  429. self.content = content
  430. self.contributor = contributor or []
  431. self.id = atom_id
  432. self.link = link or []
  433. self.published = published
  434. self.rights = rights
  435. self.source = source
  436. self.summary = summary
  437. self.control = control
  438. self.title = title
  439. self.updated = updated
  440. self.label = label or []
  441. self.attribute = attribute or []
  442. self.text = text
  443. self.extension_elements = extension_elements or []
  444. self.extension_attributes = extension_attributes or {}
  445. def GBaseAttributeEntryFromString(xml_string):
  446. return atom.CreateClassFromXMLString(GBaseAttributeEntry, xml_string)
  447. class GBaseItemTypeEntry(gdata.GDataEntry):
  448. """An Atom entry from the item types feed
  449. These entries contain a list of attributes which are stored in one
  450. XML node called attributes. This class simplifies the data structure
  451. by treating attributes as a list of attribute instances.
  452. Note that the item_type for an item type entry is in the Google Base meta
  453. namespace as opposed to item_types encountered in other feeds.
  454. """
  455. _tag = 'entry'
  456. _namespace = atom.ATOM_NAMESPACE
  457. _children = gdata.GDataEntry._children.copy()
  458. _attributes = gdata.GDataEntry._attributes.copy()
  459. _children['{%s}attributes' % GMETA_NAMESPACE] = ('attributes', Attributes)
  460. _children['{%s}attribute' % GMETA_NAMESPACE] = ('attribute', [Attribute])
  461. _children['{%s}item_type' % GMETA_NAMESPACE] = ('item_type', MetaItemType)
  462. def __init__(self, author=None, category=None, content=None,
  463. contributor=None, atom_id=None, link=None, published=None, rights=None,
  464. source=None, summary=None, title=None, updated=None, label=None,
  465. item_type=None, control=None, attribute=None, attributes=None,
  466. text=None, extension_elements=None, extension_attributes=None):
  467. self.author = author or []
  468. self.category = category or []
  469. self.content = content
  470. self.contributor = contributor or []
  471. self.id = atom_id
  472. self.link = link or []
  473. self.published = published
  474. self.rights = rights
  475. self.source = source
  476. self.summary = summary
  477. self.title = title
  478. self.updated = updated
  479. self.control = control
  480. self.label = label or []
  481. self.item_type = item_type
  482. self.attributes = attributes
  483. self.attribute = attribute or []
  484. self.text = text
  485. self.extension_elements = extension_elements or []
  486. self.extension_attributes = extension_attributes or {}
  487. def GBaseItemTypeEntryFromString(xml_string):
  488. return atom.CreateClassFromXMLString(GBaseItemTypeEntry, xml_string)
  489. class GBaseItemFeed(gdata.BatchFeed):
  490. """A feed containing Google Base Items"""
  491. _tag = 'feed'
  492. _namespace = atom.ATOM_NAMESPACE
  493. _children = gdata.BatchFeed._children.copy()
  494. _attributes = gdata.BatchFeed._attributes.copy()
  495. _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [GBaseItem])
  496. def GBaseItemFeedFromString(xml_string):
  497. return atom.CreateClassFromXMLString(GBaseItemFeed, xml_string)
  498. class GBaseSnippetFeed(gdata.GDataFeed):
  499. """A feed containing Google Base Snippets"""
  500. _tag = 'feed'
  501. _namespace = atom.ATOM_NAMESPACE
  502. _children = gdata.GDataFeed._children.copy()
  503. _attributes = gdata.GDataFeed._attributes.copy()
  504. _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [GBaseSnippet])
  505. def GBaseSnippetFeedFromString(xml_string):
  506. return atom.CreateClassFromXMLString(GBaseSnippetFeed, xml_string)
  507. class GBaseAttributesFeed(gdata.GDataFeed):
  508. """A feed containing Google Base Attributes
  509. A query sent to the attributes feed will return a feed of
  510. attributes which are present in the items that match the
  511. query.
  512. """
  513. _tag = 'feed'
  514. _namespace = atom.ATOM_NAMESPACE
  515. _children = gdata.GDataFeed._children.copy()
  516. _attributes = gdata.GDataFeed._attributes.copy()
  517. _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry',
  518. [GBaseAttributeEntry])
  519. def GBaseAttributesFeedFromString(xml_string):
  520. return atom.CreateClassFromXMLString(GBaseAttributesFeed, xml_string)
  521. class GBaseLocalesFeed(gdata.GDataFeed):
  522. """The locales feed from Google Base.
  523. This read-only feed defines the permitted locales for Google Base. The
  524. locale value identifies the language, currency, and date formats used in a
  525. feed.
  526. """
  527. _tag = 'feed'
  528. _namespace = atom.ATOM_NAMESPACE
  529. _children = gdata.GDataFeed._children.copy()
  530. _attributes = gdata.GDataFeed._attributes.copy()
  531. def GBaseLocalesFeedFromString(xml_string):
  532. return atom.CreateClassFromXMLString(GBaseLocalesFeed, xml_string)
  533. class GBaseItemTypesFeed(gdata.GDataFeed):
  534. """A feed from the Google Base item types feed"""
  535. _tag = 'feed'
  536. _namespace = atom.ATOM_NAMESPACE
  537. _children = gdata.GDataFeed._children.copy()
  538. _attributes = gdata.GDataFeed._attributes.copy()
  539. _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [GBaseItemTypeEntry])
  540. def GBaseItemTypesFeedFromString(xml_string):
  541. return atom.CreateClassFromXMLString(GBaseItemTypesFeed, xml_string)