/gdata/sites/data.py
Python | 376 lines | 233 code | 90 blank | 53 comment | 15 complexity | f3ef95a271557e879f97092ef4e5e755 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 Sites Data API.""" 18 19__author__ = 'e.bidelman (Eric Bidelman)' 20 21 22import atom.core 23import atom.data 24import gdata.acl.data 25import gdata.data 26 27# XML Namespaces used in Google Sites entities. 28SITES_NAMESPACE = 'http://schemas.google.com/sites/2008' 29SITES_TEMPLATE = '{http://schemas.google.com/sites/2008}%s' 30SPREADSHEETS_NAMESPACE = 'http://schemas.google.com/spreadsheets/2006' 31SPREADSHEETS_TEMPLATE = '{http://schemas.google.com/spreadsheets/2006}%s' 32DC_TERMS_TEMPLATE = '{http://purl.org/dc/terms}%s' 33THR_TERMS_TEMPLATE = '{http://purl.org/syndication/thread/1.0}%s' 34XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml' 35XHTML_TEMPLATE = '{http://www.w3.org/1999/xhtml}%s' 36 37SITES_PARENT_LINK_REL = SITES_NAMESPACE + '#parent' 38SITES_REVISION_LINK_REL = SITES_NAMESPACE + '#revision' 39SITES_SOURCE_LINK_REL = SITES_NAMESPACE + '#source' 40 41SITES_KIND_SCHEME = 'http://schemas.google.com/g/2005#kind' 42ANNOUNCEMENT_KIND_TERM = SITES_NAMESPACE + '#announcement' 43ANNOUNCEMENT_PAGE_KIND_TERM = SITES_NAMESPACE + '#announcementspage' 44ATTACHMENT_KIND_TERM = SITES_NAMESPACE + '#attachment' 45COMMENT_KIND_TERM = SITES_NAMESPACE + '#comment' 46FILECABINET_KIND_TERM = SITES_NAMESPACE + '#filecabinet' 47LISTITEM_KIND_TERM = SITES_NAMESPACE + '#listitem' 48LISTPAGE_KIND_TERM = SITES_NAMESPACE + '#listpage' 49WEBPAGE_KIND_TERM = SITES_NAMESPACE + '#webpage' 50WEBATTACHMENT_KIND_TERM = SITES_NAMESPACE + '#webattachment' 51FOLDER_KIND_TERM = SITES_NAMESPACE + '#folder' 52 53SUPPORT_KINDS = [ 54 'announcement', 'announcementspage', 'attachment', 'comment', 'filecabinet', 55 'listitem', 'listpage', 'webpage', 'webattachment' 56 ] 57 58 59class Revision(atom.core.XmlElement): 60 """Google Sites <sites:revision>.""" 61 _qname = SITES_TEMPLATE % 'revision' 62 63 64class PageName(atom.core.XmlElement): 65 """Google Sites <sites:pageName>.""" 66 _qname = SITES_TEMPLATE % 'pageName' 67 68 69class SiteName(atom.core.XmlElement): 70 """Google Sites <sites:siteName>.""" 71 _qname = SITES_TEMPLATE % 'siteName' 72 73 74class Theme(atom.core.XmlElement): 75 """Google Sites <sites:theme>.""" 76 _qname = SITES_TEMPLATE % 'theme' 77 78 79class Deleted(atom.core.XmlElement): 80 """Google Sites <gd:deleted>.""" 81 _qname = gdata.data.GDATA_TEMPLATE % 'deleted' 82 83 84class Publisher(atom.core.XmlElement): 85 """Google Sites <dc:pulisher>.""" 86 _qname = DC_TERMS_TEMPLATE % 'publisher' 87 88 89class Worksheet(atom.core.XmlElement): 90 """Google Sites List Page <gs:worksheet>.""" 91 92 _qname = SPREADSHEETS_TEMPLATE % 'worksheet' 93 name = 'name' 94 95 96class Header(atom.core.XmlElement): 97 """Google Sites List Page <gs:header>.""" 98 99 _qname = SPREADSHEETS_TEMPLATE % 'header' 100 row = 'row' 101 102 103class Column(atom.core.XmlElement): 104 """Google Sites List Page <gs:column>.""" 105 106 _qname = SPREADSHEETS_TEMPLATE % 'column' 107 index = 'index' 108 name = 'name' 109 110 111class Data(atom.core.XmlElement): 112 """Google Sites List Page <gs:data>.""" 113 114 _qname = SPREADSHEETS_TEMPLATE % 'data' 115 startRow = 'startRow' 116 column = [Column] 117 118 119class Field(atom.core.XmlElement): 120 """Google Sites List Item <gs:field>.""" 121 122 _qname = SPREADSHEETS_TEMPLATE % 'field' 123 index = 'index' 124 name = 'name' 125 126 127class InReplyTo(atom.core.XmlElement): 128 """Google Sites List Item <thr:in-reply-to>.""" 129 130 _qname = THR_TERMS_TEMPLATE % 'in-reply-to' 131 href = 'href' 132 ref = 'ref' 133 source = 'source' 134 type = 'type' 135 136 137class Content(atom.data.Content): 138 """Google Sites version of <atom:content> that encapsulates XHTML.""" 139 140 def __init__(self, html=None, type=None, **kwargs): 141 if type is None and html: 142 type = 'xhtml' 143 super(Content, self).__init__(type=type, **kwargs) 144 if html is not None: 145 self.html = html 146 147 def _get_html(self): 148 if self.children: 149 return self.children[0] 150 else: 151 return '' 152 153 def _set_html(self, html): 154 if not html: 155 self.children = [] 156 return 157 158 if type(html) == str: 159 html = atom.core.parse(html) 160 if not html.namespace: 161 html.namespace = XHTML_NAMESPACE 162 163 self.children = [html] 164 165 html = property(_get_html, _set_html) 166 167 168class Summary(atom.data.Summary): 169 """Google Sites version of <atom:summary>.""" 170 171 def __init__(self, html=None, type=None, text=None, **kwargs): 172 if type is None and html: 173 type = 'xhtml' 174 175 super(Summary, self).__init__(type=type, text=text, **kwargs) 176 if html is not None: 177 self.html = html 178 179 def _get_html(self): 180 if self.children: 181 return self.children[0] 182 else: 183 return '' 184 185 def _set_html(self, html): 186 if not html: 187 self.children = [] 188 return 189 190 if type(html) == str: 191 html = atom.core.parse(html) 192 if not html.namespace: 193 html.namespace = XHTML_NAMESPACE 194 195 self.children = [html] 196 197 html = property(_get_html, _set_html) 198 199 200class BaseSiteEntry(gdata.data.GDEntry): 201 """Google Sites Entry.""" 202 203 def __init__(self, kind=None, **kwargs): 204 super(BaseSiteEntry, self).__init__(**kwargs) 205 if kind is not None: 206 self.category.append( 207 atom.data.Category(scheme=SITES_KIND_SCHEME, 208 term='%s#%s' % (SITES_NAMESPACE, kind), 209 label=kind)) 210 211 def __find_category_scheme(self, scheme): 212 for category in self.category: 213 if category.scheme == scheme: 214 return category 215 return None 216 217 def kind(self): 218 kind = self.__find_category_scheme(SITES_KIND_SCHEME) 219 if kind is not None: 220 return kind.term[len(SITES_NAMESPACE) + 1:] 221 else: 222 return None 223 224 Kind = kind 225 226 def get_node_id(self): 227 return self.id.text[self.id.text.rfind('/') + 1:] 228 229 GetNodeId = get_node_id 230 231 def find_parent_link(self): 232 return self.find_url(SITES_PARENT_LINK_REL) 233 234 FindParentLink = find_parent_link 235 236 def is_deleted(self): 237 return self.deleted is not None 238 239 IsDeleted = is_deleted 240 241 242class ContentEntry(BaseSiteEntry): 243 """Google Sites Content Entry.""" 244 content = Content 245 deleted = Deleted 246 publisher = Publisher 247 in_reply_to = InReplyTo 248 worksheet = Worksheet 249 header = Header 250 data = Data 251 field = [Field] 252 revision = Revision 253 page_name = PageName 254 feed_link = gdata.data.FeedLink 255 256 def find_revison_link(self): 257 return self.find_url(SITES_REVISION_LINK_REL) 258 259 FindRevisionLink = find_revison_link 260 261 262class ContentFeed(gdata.data.GDFeed): 263 """Google Sites Content Feed. 264 265 The Content feed is a feed containing the current, editable site content. 266 """ 267 entry = [ContentEntry] 268 269 def __get_entry_type(self, kind): 270 matches = [] 271 for entry in self.entry: 272 if entry.Kind() == kind: 273 matches.append(entry) 274 return matches 275 276 def get_announcements(self): 277 return self.__get_entry_type('announcement') 278 279 GetAnnouncements = get_announcements 280 281 def get_announcement_pages(self): 282 return self.__get_entry_type('announcementspage') 283 284 GetAnnouncementPages = get_announcement_pages 285 286 def get_attachments(self): 287 return self.__get_entry_type('attachment') 288 289 GetAttachments = get_attachments 290 291 def get_comments(self): 292 return self.__get_entry_type('comment') 293 294 GetComments = get_comments 295 296 def get_file_cabinets(self): 297 return self.__get_entry_type('filecabinet') 298 299 GetFileCabinets = get_file_cabinets 300 301 def get_list_items(self): 302 return self.__get_entry_type('listitem') 303 304 GetListItems = get_list_items 305 306 def get_list_pages(self): 307 return self.__get_entry_type('listpage') 308 309 GetListPages = get_list_pages 310 311 def get_webpages(self): 312 return self.__get_entry_type('webpage') 313 314 GetWebpages = get_webpages 315 316 def get_webattachments(self): 317 return self.__get_entry_type('webattachment') 318 319 GetWebattachments = get_webattachments 320 321 322class ActivityEntry(BaseSiteEntry): 323 """Google Sites Activity Entry.""" 324 summary = Summary 325 326 327class ActivityFeed(gdata.data.GDFeed): 328 """Google Sites Activity Feed. 329 330 The Activity feed is a feed containing recent Site activity. 331 """ 332 entry = [ActivityEntry] 333 334 335class RevisionEntry(BaseSiteEntry): 336 """Google Sites Revision Entry.""" 337 content = Content 338 339 340class RevisionFeed(gdata.data.GDFeed): 341 """Google Sites Revision Feed. 342 343 The Activity feed is a feed containing recent Site activity. 344 """ 345 entry = [RevisionEntry] 346 347 348class SiteEntry(gdata.data.GDEntry): 349 """Google Sites Site Feed Entry.""" 350 site_name = SiteName 351 theme = Theme 352 353 def find_source_link(self): 354 return self.find_url(SITES_SOURCE_LINK_REL) 355 356 FindSourceLink = find_source_link 357 358 359class SiteFeed(gdata.data.GDFeed): 360 """Google Sites Site Feed. 361 362 The Site feed can be used to list a user's sites and create new sites. 363 """ 364 entry = [SiteEntry] 365 366 367class AclEntry(gdata.acl.data.AclEntry): 368 """Google Sites ACL Entry.""" 369 370 371class AclFeed(gdata.acl.data.AclFeed): 372 """Google Sites ACL Feed. 373 374 The ACL feed can be used to modify the sharing permissions of a Site. 375 """ 376 entry = [AclEntry]