/gdata/docs/data.py
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]