/atom/data.py

http://radioappz.googlecode.com/ · Python · 339 lines · 218 code · 61 blank · 60 comment · 8 complexity · 91492a5d0076f6774022e7e5f8718aa3 MD5 · raw file

  1. #!/usr/bin/env python
  2. #
  3. # Copyright (C) 2009 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. # This module is used for version 2 of the Google Data APIs.
  17. __author__ = 'j.s@google.com (Jeff Scudder)'
  18. import atom.core
  19. ATOM_TEMPLATE = '{http://www.w3.org/2005/Atom}%s'
  20. APP_TEMPLATE_V1 = '{http://purl.org/atom/app#}%s'
  21. APP_TEMPLATE_V2 = '{http://www.w3.org/2007/app}%s'
  22. class Name(atom.core.XmlElement):
  23. """The atom:name element."""
  24. _qname = ATOM_TEMPLATE % 'name'
  25. class Email(atom.core.XmlElement):
  26. """The atom:email element."""
  27. _qname = ATOM_TEMPLATE % 'email'
  28. class Uri(atom.core.XmlElement):
  29. """The atom:uri element."""
  30. _qname = ATOM_TEMPLATE % 'uri'
  31. class Person(atom.core.XmlElement):
  32. """A foundation class which atom:author and atom:contributor extend.
  33. A person contains information like name, email address, and web page URI for
  34. an author or contributor to an Atom feed.
  35. """
  36. name = Name
  37. email = Email
  38. uri = Uri
  39. class Author(Person):
  40. """The atom:author element.
  41. An author is a required element in Feed unless each Entry contains an Author.
  42. """
  43. _qname = ATOM_TEMPLATE % 'author'
  44. class Contributor(Person):
  45. """The atom:contributor element."""
  46. _qname = ATOM_TEMPLATE % 'contributor'
  47. class Link(atom.core.XmlElement):
  48. """The atom:link element."""
  49. _qname = ATOM_TEMPLATE % 'link'
  50. href = 'href'
  51. rel = 'rel'
  52. type = 'type'
  53. hreflang = 'hreflang'
  54. title = 'title'
  55. length = 'length'
  56. class Generator(atom.core.XmlElement):
  57. """The atom:generator element."""
  58. _qname = ATOM_TEMPLATE % 'generator'
  59. uri = 'uri'
  60. version = 'version'
  61. class Text(atom.core.XmlElement):
  62. """A foundation class from which atom:title, summary, etc. extend.
  63. This class should never be instantiated.
  64. """
  65. type = 'type'
  66. class Title(Text):
  67. """The atom:title element."""
  68. _qname = ATOM_TEMPLATE % 'title'
  69. class Subtitle(Text):
  70. """The atom:subtitle element."""
  71. _qname = ATOM_TEMPLATE % 'subtitle'
  72. class Rights(Text):
  73. """The atom:rights element."""
  74. _qname = ATOM_TEMPLATE % 'rights'
  75. class Summary(Text):
  76. """The atom:summary element."""
  77. _qname = ATOM_TEMPLATE % 'summary'
  78. class Content(Text):
  79. """The atom:content element."""
  80. _qname = ATOM_TEMPLATE % 'content'
  81. src = 'src'
  82. class Category(atom.core.XmlElement):
  83. """The atom:category element."""
  84. _qname = ATOM_TEMPLATE % 'category'
  85. term = 'term'
  86. scheme = 'scheme'
  87. label = 'label'
  88. class Id(atom.core.XmlElement):
  89. """The atom:id element."""
  90. _qname = ATOM_TEMPLATE % 'id'
  91. class Icon(atom.core.XmlElement):
  92. """The atom:icon element."""
  93. _qname = ATOM_TEMPLATE % 'icon'
  94. class Logo(atom.core.XmlElement):
  95. """The atom:logo element."""
  96. _qname = ATOM_TEMPLATE % 'logo'
  97. class Draft(atom.core.XmlElement):
  98. """The app:draft element which indicates if this entry should be public."""
  99. _qname = (APP_TEMPLATE_V1 % 'draft', APP_TEMPLATE_V2 % 'draft')
  100. class Control(atom.core.XmlElement):
  101. """The app:control element indicating restrictions on publication.
  102. The APP control element may contain a draft element indicating whether or
  103. not this entry should be publicly available.
  104. """
  105. _qname = (APP_TEMPLATE_V1 % 'control', APP_TEMPLATE_V2 % 'control')
  106. draft = Draft
  107. class Date(atom.core.XmlElement):
  108. """A parent class for atom:updated, published, etc."""
  109. class Updated(Date):
  110. """The atom:updated element."""
  111. _qname = ATOM_TEMPLATE % 'updated'
  112. class Published(Date):
  113. """The atom:published element."""
  114. _qname = ATOM_TEMPLATE % 'published'
  115. class LinkFinder(object):
  116. """An "interface" providing methods to find link elements
  117. Entry elements often contain multiple links which differ in the rel
  118. attribute or content type. Often, developers are interested in a specific
  119. type of link so this class provides methods to find specific classes of
  120. links.
  121. This class is used as a mixin in Atom entries and feeds.
  122. """
  123. def find_url(self, rel):
  124. """Returns the URL in a link with the desired rel value."""
  125. for link in self.link:
  126. if link.rel == rel and link.href:
  127. return link.href
  128. return None
  129. FindUrl = find_url
  130. def get_link(self, rel):
  131. """Returns a link object which has the desired rel value.
  132. If you are interested in the URL instead of the link object,
  133. consider using find_url instead.
  134. """
  135. for link in self.link:
  136. if link.rel == rel and link.href:
  137. return link
  138. return None
  139. GetLink = get_link
  140. def find_self_link(self):
  141. """Find the first link with rel set to 'self'
  142. Returns:
  143. A str containing the link's href or None if none of the links had rel
  144. equal to 'self'
  145. """
  146. return self.find_url('self')
  147. FindSelfLink = find_self_link
  148. def get_self_link(self):
  149. return self.get_link('self')
  150. GetSelfLink = get_self_link
  151. def find_edit_link(self):
  152. return self.find_url('edit')
  153. FindEditLink = find_edit_link
  154. def get_edit_link(self):
  155. return self.get_link('edit')
  156. GetEditLink = get_edit_link
  157. def find_edit_media_link(self):
  158. link = self.find_url('edit-media')
  159. # Search for media-edit as well since Picasa API used media-edit instead.
  160. if link is None:
  161. return self.find_url('media-edit')
  162. return link
  163. FindEditMediaLink = find_edit_media_link
  164. def get_edit_media_link(self):
  165. link = self.get_link('edit-media')
  166. if link is None:
  167. return self.get_link('media-edit')
  168. return link
  169. GetEditMediaLink = get_edit_media_link
  170. def find_next_link(self):
  171. return self.find_url('next')
  172. FindNextLink = find_next_link
  173. def get_next_link(self):
  174. return self.get_link('next')
  175. GetNextLink = get_next_link
  176. def find_license_link(self):
  177. return self.find_url('license')
  178. FindLicenseLink = find_license_link
  179. def get_license_link(self):
  180. return self.get_link('license')
  181. GetLicenseLink = get_license_link
  182. def find_alternate_link(self):
  183. return self.find_url('alternate')
  184. FindAlternateLink = find_alternate_link
  185. def get_alternate_link(self):
  186. return self.get_link('alternate')
  187. GetAlternateLink = get_alternate_link
  188. class FeedEntryParent(atom.core.XmlElement, LinkFinder):
  189. """A super class for atom:feed and entry, contains shared attributes"""
  190. author = [Author]
  191. category = [Category]
  192. contributor = [Contributor]
  193. id = Id
  194. link = [Link]
  195. rights = Rights
  196. title = Title
  197. updated = Updated
  198. def __init__(self, atom_id=None, text=None, *args, **kwargs):
  199. if atom_id is not None:
  200. self.id = atom_id
  201. atom.core.XmlElement.__init__(self, text=text, *args, **kwargs)
  202. class Source(FeedEntryParent):
  203. """The atom:source element."""
  204. _qname = ATOM_TEMPLATE % 'source'
  205. generator = Generator
  206. icon = Icon
  207. logo = Logo
  208. subtitle = Subtitle
  209. class Entry(FeedEntryParent):
  210. """The atom:entry element."""
  211. _qname = ATOM_TEMPLATE % 'entry'
  212. content = Content
  213. published = Published
  214. source = Source
  215. summary = Summary
  216. control = Control
  217. class Feed(Source):
  218. """The atom:feed element which contains entries."""
  219. _qname = ATOM_TEMPLATE % 'feed'
  220. entry = [Entry]
  221. class ExtensionElement(atom.core.XmlElement):
  222. """Provided for backwards compatibility to the v1 atom.ExtensionElement."""
  223. def __init__(self, tag=None, namespace=None, attributes=None,
  224. children=None, text=None, *args, **kwargs):
  225. if namespace:
  226. self._qname = '{%s}%s' % (namespace, tag)
  227. else:
  228. self._qname = tag
  229. self.children = children or []
  230. self.attributes = attributes or {}
  231. self.text = text
  232. _BecomeChildElement = atom.core.XmlElement._become_child