PageRenderTime 30ms CodeModel.GetById 12ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/gdata/docs/data.py

http://radioappz.googlecode.com/
Python | 280 lines | 218 code | 17 blank | 45 comment | 6 complexity | 3d461b5ff8bc78098a0a2ac803826b21 MD5 | raw file
  1#!/usr/bin/python
  2#
  3# Copyright 2009 Google Inc. All Rights Reserved.
  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"""Data model classes for parsing and generating XML for the DocList Data API"""
 18
 19__author__ = 'e.bidelman (Eric Bidelman)'
 20
 21
 22import re
 23import atom.core
 24import atom.data
 25import gdata.acl.data
 26import gdata.data
 27
 28DOCUMENTS_NS = 'http://schemas.google.com/docs/2007'
 29DOCUMENTS_TEMPLATE = '{http://schemas.google.com/docs/2007}%s'
 30ACL_FEEDLINK_REL = 'http://schemas.google.com/acl/2007#accessControlList'
 31REVISION_FEEDLINK_REL = DOCUMENTS_NS + '/revisions'
 32
 33# XML Namespaces used in Google Documents entities.
 34DATA_KIND_SCHEME = 'http://schemas.google.com/g/2005#kind'
 35DOCUMENT_LABEL = 'document'
 36SPREADSHEET_LABEL = 'spreadsheet'
 37PRESENTATION_LABEL = 'presentation'
 38FOLDER_LABEL = 'folder'
 39PDF_LABEL = 'pdf'
 40
 41LABEL_SCHEME = 'http://schemas.google.com/g/2005/labels'
 42STARRED_LABEL_TERM = LABEL_SCHEME + '#starred'
 43TRASHED_LABEL_TERM = LABEL_SCHEME + '#trashed'
 44HIDDEN_LABEL_TERM = LABEL_SCHEME + '#hidden'
 45MINE_LABEL_TERM = LABEL_SCHEME + '#mine'
 46PRIVATE_LABEL_TERM = LABEL_SCHEME + '#private'
 47SHARED_WITH_DOMAIN_LABEL_TERM = LABEL_SCHEME + '#shared-with-domain'
 48VIEWED_LABEL_TERM = LABEL_SCHEME + '#viewed'
 49
 50DOCS_PARENT_LINK_REL = DOCUMENTS_NS + '#parent'
 51DOCS_PUBLISH_LINK_REL = DOCUMENTS_NS + '#publish'
 52
 53FILE_EXT_PATTERN = re.compile('.*\.([a-zA-Z]{3,}$)')
 54RESOURCE_ID_PATTERN = re.compile('^([a-z]*)(:|%3A)([\w-]*)$')
 55
 56# File extension/mimetype pairs of common format.
 57MIMETYPES = {
 58  'CSV': 'text/csv',
 59  'TSV': 'text/tab-separated-values',
 60  'TAB': 'text/tab-separated-values',
 61  'DOC': 'application/msword',
 62  'DOCX': ('application/vnd.openxmlformats-officedocument.'
 63           'wordprocessingml.document'),
 64  'ODS': 'application/x-vnd.oasis.opendocument.spreadsheet',
 65  'ODT': 'application/vnd.oasis.opendocument.text',
 66  'RTF': 'application/rtf',
 67  'SXW': 'application/vnd.sun.xml.writer',
 68  'TXT': 'text/plain',
 69  'XLS': 'application/vnd.ms-excel',
 70  'XLSX': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
 71  'PDF': 'application/pdf',
 72  'PNG': 'image/png',
 73  'PPT': 'application/vnd.ms-powerpoint',
 74  'PPS': 'application/vnd.ms-powerpoint',
 75  'HTM': 'text/html',
 76  'HTML': 'text/html',
 77  'ZIP': 'application/zip',
 78  'SWF': 'application/x-shockwave-flash'
 79  }
 80
 81
 82def make_kind_category(label):
 83  """Builds the appropriate atom.data.Category for the label passed in.
 84
 85  Args:
 86    label: str The value for the category entry.
 87
 88  Returns:
 89    An atom.data.Category or None if label is None.
 90  """
 91  if label is None:
 92    return None
 93
 94  return atom.data.Category(
 95    scheme=DATA_KIND_SCHEME, term='%s#%s' % (DOCUMENTS_NS, label), label=label)
 96
 97MakeKindCategory = make_kind_category
 98
 99def make_content_link_from_resource_id(resource_id):
100  """Constructs export URL for a given resource.
101
102  Args:
103    resource_id: str The document/item's resource id. Example presentation:
104        'presentation%3A0A1234567890'.
105
106  Raises:
107    gdata.client.ValueError if the resource_id is not a valid format.
108  """
109  match = RESOURCE_ID_PATTERN.match(resource_id)
110
111  if match:
112    label = match.group(1)
113    doc_id = match.group(3)
114    if label == DOCUMENT_LABEL:
115      return '/feeds/download/documents/Export?docId=%s' % doc_id
116    if label == PRESENTATION_LABEL:
117      return '/feeds/download/presentations/Export?docId=%s' % doc_id
118    if label == SPREADSHEET_LABEL:
119      return ('http://spreadsheets.google.com/feeds/download/spreadsheets/'
120              'Export?key=%s' % doc_id)
121  raise ValueError, ('Invalid resource id: %s, or manually creating the '
122                     'download url for this type of doc is not possible'
123                     % resource_id)
124
125MakeContentLinkFromResourceId = make_content_link_from_resource_id
126
127
128class ResourceId(atom.core.XmlElement):
129  """The DocList gd:resourceId element."""
130  _qname = gdata.data.GDATA_TEMPLATE  % 'resourceId'
131
132
133class LastModifiedBy(atom.data.Person):
134  """The DocList gd:lastModifiedBy element."""
135  _qname = gdata.data.GDATA_TEMPLATE  % 'lastModifiedBy'
136
137
138class LastViewed(atom.data.Person):
139  """The DocList gd:lastViewed element."""
140  _qname = gdata.data.GDATA_TEMPLATE  % 'lastViewed'
141
142
143class WritersCanInvite(atom.core.XmlElement):
144  """The DocList docs:writersCanInvite element."""
145  _qname = DOCUMENTS_TEMPLATE  % 'writersCanInvite'
146  value = 'value'
147
148
149class QuotaBytesUsed(atom.core.XmlElement):
150  """The DocList gd:quotaBytesUsed element."""
151  _qname = gdata.data.GDATA_TEMPLATE  % 'quotaBytesUsed'
152
153
154class Publish(atom.core.XmlElement):
155  """The DocList docs:publish element."""
156  _qname = DOCUMENTS_TEMPLATE  % 'publish'
157  value = 'value'
158
159
160class PublishAuto(atom.core.XmlElement):
161  """The DocList docs:publishAuto element."""
162  _qname = DOCUMENTS_TEMPLATE  % 'publishAuto'
163  value = 'value'
164
165
166class PublishOutsideDomain(atom.core.XmlElement):
167  """The DocList docs:publishOutsideDomain element."""
168  _qname = DOCUMENTS_TEMPLATE  % 'publishOutsideDomain'
169  value = 'value'
170
171
172class DocsEntry(gdata.data.GDEntry):
173  """A DocList version of an Atom Entry."""
174
175  last_viewed = LastViewed
176  last_modified_by = LastModifiedBy
177  resource_id = ResourceId
178  writers_can_invite = WritersCanInvite
179  quota_bytes_used = QuotaBytesUsed
180  feed_link = [gdata.data.FeedLink]
181
182  def get_document_type(self):
183    """Extracts the type of document this DocsEntry is.
184
185    This method returns the type of document the DocsEntry represents. Possible
186    values are document, presentation, spreadsheet, folder, or pdf.
187
188    Returns:
189      A string representing the type of document.
190    """
191    if self.category:
192      for category in self.category:
193        if category.scheme == DATA_KIND_SCHEME:
194          return category.label
195    else:
196      return None
197
198  GetDocumentType = get_document_type
199
200  def get_acl_feed_link(self):
201    """Extracts the DocsEntry's ACL feed <gd:feedLink>.
202
203    Returns:
204      A gdata.data.FeedLink object.
205    """
206    for feed_link in self.feed_link:
207      if feed_link.rel == ACL_FEEDLINK_REL:
208        return feed_link
209    return None
210
211  GetAclFeedLink = get_acl_feed_link
212
213  def get_revisions_feed_link(self):
214    """Extracts the DocsEntry's revisions feed <gd:feedLink>.
215
216    Returns:
217      A gdata.data.FeedLink object.
218    """
219    for feed_link in self.feed_link:
220      if feed_link.rel == REVISION_FEEDLINK_REL:
221        return feed_link
222    return None
223
224  GetRevisionsFeedLink = get_revisions_feed_link
225
226  def in_folders(self):
227    """Returns the parents link(s) (folders) of this entry."""
228    links = []
229    for link in self.link:
230      if link.rel == DOCS_PARENT_LINK_REL and link.href:
231        links.append(link)
232    return links
233
234  InFolders = in_folders
235
236
237class Acl(gdata.acl.data.AclEntry):
238  """A document ACL entry."""
239
240
241class DocList(gdata.data.GDFeed):
242  """The main DocList feed containing a list of Google Documents."""
243  entry = [DocsEntry]
244
245
246class AclFeed(gdata.acl.data.AclFeed):
247  """A DocList ACL feed."""
248  entry = [Acl]
249
250
251class Revision(gdata.data.GDEntry):
252  """A document Revision entry."""
253  publish = Publish
254  publish_auto = PublishAuto
255  publish_outside_domain = PublishOutsideDomain
256
257  def find_publish_link(self):
258    """Get the link that points to the published document on the web.
259
260    Returns:
261      A str for the URL in the link with a rel ending in #publish.
262    """
263    return self.find_url(DOCS_PUBLISH_LINK_REL)
264
265  FindPublishLink = find_publish_link
266
267  def get_publish_link(self):
268    """Get the link that points to the published document on the web.
269
270    Returns:
271      A gdata.data.Link for the link with a rel ending in #publish.
272    """
273    return self.get_link(DOCS_PUBLISH_LINK_REL)
274
275  GetPublishLink = get_publish_link
276
277
278class RevisionFeed(gdata.data.GDFeed):
279  """A DocList Revision feed."""
280  entry = [Revision]