/atom/data.py
Python | 339 lines | 230 code | 56 blank | 53 comment | 0 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 17 18# This module is used for version 2 of the Google Data APIs. 19 20 21__author__ = 'j.s@google.com (Jeff Scudder)' 22 23 24import atom.core 25 26 27ATOM_TEMPLATE = '{http://www.w3.org/2005/Atom}%s' 28APP_TEMPLATE_V1 = '{http://purl.org/atom/app#}%s' 29APP_TEMPLATE_V2 = '{http://www.w3.org/2007/app}%s' 30 31 32class Name(atom.core.XmlElement): 33 """The atom:name element.""" 34 _qname = ATOM_TEMPLATE % 'name' 35 36 37class Email(atom.core.XmlElement): 38 """The atom:email element.""" 39 _qname = ATOM_TEMPLATE % 'email' 40 41 42class Uri(atom.core.XmlElement): 43 """The atom:uri element.""" 44 _qname = ATOM_TEMPLATE % 'uri' 45 46 47class Person(atom.core.XmlElement): 48 """A foundation class which atom:author and atom:contributor extend. 49 50 A person contains information like name, email address, and web page URI for 51 an author or contributor to an Atom feed. 52 """ 53 name = Name 54 email = Email 55 uri = Uri 56 57 58class Author(Person): 59 """The atom:author element. 60 61 An author is a required element in Feed unless each Entry contains an Author. 62 """ 63 _qname = ATOM_TEMPLATE % 'author' 64 65 66class Contributor(Person): 67 """The atom:contributor element.""" 68 _qname = ATOM_TEMPLATE % 'contributor' 69 70 71class Link(atom.core.XmlElement): 72 """The atom:link element.""" 73 _qname = ATOM_TEMPLATE % 'link' 74 href = 'href' 75 rel = 'rel' 76 type = 'type' 77 hreflang = 'hreflang' 78 title = 'title' 79 length = 'length' 80 81 82class Generator(atom.core.XmlElement): 83 """The atom:generator element.""" 84 _qname = ATOM_TEMPLATE % 'generator' 85 uri = 'uri' 86 version = 'version' 87 88 89class Text(atom.core.XmlElement): 90 """A foundation class from which atom:title, summary, etc. extend. 91 92 This class should never be instantiated. 93 """ 94 type = 'type' 95 96 97class Title(Text): 98 """The atom:title element.""" 99 _qname = ATOM_TEMPLATE % 'title' 100 101 102class Subtitle(Text): 103 """The atom:subtitle element.""" 104 _qname = ATOM_TEMPLATE % 'subtitle' 105 106 107class Rights(Text): 108 """The atom:rights element.""" 109 _qname = ATOM_TEMPLATE % 'rights' 110 111 112class Summary(Text): 113 """The atom:summary element.""" 114 _qname = ATOM_TEMPLATE % 'summary' 115 116 117class Content(Text): 118 """The atom:content element.""" 119 _qname = ATOM_TEMPLATE % 'content' 120 src = 'src' 121 122 123class Category(atom.core.XmlElement): 124 """The atom:category element.""" 125 _qname = ATOM_TEMPLATE % 'category' 126 term = 'term' 127 scheme = 'scheme' 128 label = 'label' 129 130 131class Id(atom.core.XmlElement): 132 """The atom:id element.""" 133 _qname = ATOM_TEMPLATE % 'id' 134 135 136class Icon(atom.core.XmlElement): 137 """The atom:icon element.""" 138 _qname = ATOM_TEMPLATE % 'icon' 139 140 141class Logo(atom.core.XmlElement): 142 """The atom:logo element.""" 143 _qname = ATOM_TEMPLATE % 'logo' 144 145 146class Draft(atom.core.XmlElement): 147 """The app:draft element which indicates if this entry should be public.""" 148 _qname = (APP_TEMPLATE_V1 % 'draft', APP_TEMPLATE_V2 % 'draft') 149 150 151class Control(atom.core.XmlElement): 152 """The app:control element indicating restrictions on publication. 153 154 The APP control element may contain a draft element indicating whether or 155 not this entry should be publicly available. 156 """ 157 _qname = (APP_TEMPLATE_V1 % 'control', APP_TEMPLATE_V2 % 'control') 158 draft = Draft 159 160 161class Date(atom.core.XmlElement): 162 """A parent class for atom:updated, published, etc.""" 163 164 165class Updated(Date): 166 """The atom:updated element.""" 167 _qname = ATOM_TEMPLATE % 'updated' 168 169 170class Published(Date): 171 """The atom:published element.""" 172 _qname = ATOM_TEMPLATE % 'published' 173 174 175class LinkFinder(object): 176 """An "interface" providing methods to find link elements 177 178 Entry elements often contain multiple links which differ in the rel 179 attribute or content type. Often, developers are interested in a specific 180 type of link so this class provides methods to find specific classes of 181 links. 182 183 This class is used as a mixin in Atom entries and feeds. 184 """ 185 186 def find_url(self, rel): 187 """Returns the URL in a link with the desired rel value.""" 188 for link in self.link: 189 if link.rel == rel and link.href: 190 return link.href 191 return None 192 193 FindUrl = find_url 194 195 def get_link(self, rel): 196 """Returns a link object which has the desired rel value. 197 198 If you are interested in the URL instead of the link object, 199 consider using find_url instead. 200 """ 201 for link in self.link: 202 if link.rel == rel and link.href: 203 return link 204 return None 205 206 GetLink = get_link 207 208 def find_self_link(self): 209 """Find the first link with rel set to 'self' 210 211 Returns: 212 A str containing the link's href or None if none of the links had rel 213 equal to 'self' 214 """ 215 return self.find_url('self') 216 217 FindSelfLink = find_self_link 218 219 def get_self_link(self): 220 return self.get_link('self') 221 222 GetSelfLink = get_self_link 223 224 def find_edit_link(self): 225 return self.find_url('edit') 226 227 FindEditLink = find_edit_link 228 229 def get_edit_link(self): 230 return self.get_link('edit') 231 232 GetEditLink = get_edit_link 233 234 def find_edit_media_link(self): 235 link = self.find_url('edit-media') 236 # Search for media-edit as well since Picasa API used media-edit instead. 237 if link is None: 238 return self.find_url('media-edit') 239 return link 240 241 FindEditMediaLink = find_edit_media_link 242 243 def get_edit_media_link(self): 244 link = self.get_link('edit-media') 245 if link is None: 246 return self.get_link('media-edit') 247 return link 248 249 GetEditMediaLink = get_edit_media_link 250 251 def find_next_link(self): 252 return self.find_url('next') 253 254 FindNextLink = find_next_link 255 256 def get_next_link(self): 257 return self.get_link('next') 258 259 GetNextLink = get_next_link 260 261 def find_license_link(self): 262 return self.find_url('license') 263 264 FindLicenseLink = find_license_link 265 266 def get_license_link(self): 267 return self.get_link('license') 268 269 GetLicenseLink = get_license_link 270 271 def find_alternate_link(self): 272 return self.find_url('alternate') 273 274 FindAlternateLink = find_alternate_link 275 276 def get_alternate_link(self): 277 return self.get_link('alternate') 278 279 GetAlternateLink = get_alternate_link 280 281 282class FeedEntryParent(atom.core.XmlElement, LinkFinder): 283 """A super class for atom:feed and entry, contains shared attributes""" 284 author = [Author] 285 category = [Category] 286 contributor = [Contributor] 287 id = Id 288 link = [Link] 289 rights = Rights 290 title = Title 291 updated = Updated 292 293 def __init__(self, atom_id=None, text=None, *args, **kwargs): 294 if atom_id is not None: 295 self.id = atom_id 296 atom.core.XmlElement.__init__(self, text=text, *args, **kwargs) 297 298 299class Source(FeedEntryParent): 300 """The atom:source element.""" 301 _qname = ATOM_TEMPLATE % 'source' 302 generator = Generator 303 icon = Icon 304 logo = Logo 305 subtitle = Subtitle 306 307 308class Entry(FeedEntryParent): 309 """The atom:entry element.""" 310 _qname = ATOM_TEMPLATE % 'entry' 311 content = Content 312 published = Published 313 source = Source 314 summary = Summary 315 control = Control 316 317 318class Feed(Source): 319 """The atom:feed element which contains entries.""" 320 _qname = ATOM_TEMPLATE % 'feed' 321 entry = [Entry] 322 323 324class ExtensionElement(atom.core.XmlElement): 325 """Provided for backwards compatibility to the v1 atom.ExtensionElement.""" 326 327 def __init__(self, tag=None, namespace=None, attributes=None, 328 children=None, text=None, *args, **kwargs): 329 if namespace: 330 self._qname = '{%s}%s' % (namespace, tag) 331 else: 332 self._qname = tag 333 self.children = children or [] 334 self.attributes = attributes or {} 335 self.text = text 336 337 _BecomeChildElement = atom.core.XmlElement._become_child 338 339