/gdata/calendar/__init__.py
Python | 1044 lines | 793 code | 168 blank | 83 comment | 71 complexity | aebdd96ddb094b4b7061eb56909b042a MD5 | raw file
1#!/usr/bin/python 2# 3# Copyright (C) 2006 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"""Contains extensions to ElementWrapper objects used with Google Calendar.""" 19 20 21__author__ = 'api.vli (Vivian Li), api.rboyd (Ryan Boyd)' 22 23 24try: 25 from xml.etree import cElementTree as ElementTree 26except ImportError: 27 try: 28 import cElementTree as ElementTree 29 except ImportError: 30 try: 31 from xml.etree import ElementTree 32 except ImportError: 33 from elementtree import ElementTree 34import atom 35import gdata 36 37 38# XML namespaces which are often used in Google Calendar entities. 39GCAL_NAMESPACE = 'http://schemas.google.com/gCal/2005' 40GCAL_TEMPLATE = '{http://schemas.google.com/gCal/2005}%s' 41WEB_CONTENT_LINK_REL = '%s/%s' % (GCAL_NAMESPACE, 'webContent') 42GACL_NAMESPACE = gdata.GACL_NAMESPACE 43GACL_TEMPLATE = gdata.GACL_TEMPLATE 44 45 46 47class ValueAttributeContainer(atom.AtomBase): 48 """A parent class for all Calendar classes which have a value attribute. 49 50 Children include Color, AccessLevel, Hidden 51 """ 52 53 _children = atom.AtomBase._children.copy() 54 _attributes = atom.AtomBase._attributes.copy() 55 _attributes['value'] = 'value' 56 57 def __init__(self, value=None, extension_elements=None, 58 extension_attributes=None, text=None): 59 self.value = value 60 self.text = text 61 self.extension_elements = extension_elements or [] 62 self.extension_attributes = extension_attributes or {} 63 64class Color(ValueAttributeContainer): 65 """The Google Calendar color element""" 66 67 _tag = 'color' 68 _namespace = GCAL_NAMESPACE 69 _children = ValueAttributeContainer._children.copy() 70 _attributes = ValueAttributeContainer._attributes.copy() 71 72 73 74class AccessLevel(ValueAttributeContainer): 75 """The Google Calendar accesslevel element""" 76 77 _tag = 'accesslevel' 78 _namespace = GCAL_NAMESPACE 79 _children = ValueAttributeContainer._children.copy() 80 _attributes = ValueAttributeContainer._attributes.copy() 81 82 83class Hidden(ValueAttributeContainer): 84 """The Google Calendar hidden element""" 85 86 _tag = 'hidden' 87 _namespace = GCAL_NAMESPACE 88 _children = ValueAttributeContainer._children.copy() 89 _attributes = ValueAttributeContainer._attributes.copy() 90 91 92class Selected(ValueAttributeContainer): 93 """The Google Calendar selected element""" 94 95 _tag = 'selected' 96 _namespace = GCAL_NAMESPACE 97 _children = ValueAttributeContainer._children.copy() 98 _attributes = ValueAttributeContainer._attributes.copy() 99 100 101class Timezone(ValueAttributeContainer): 102 """The Google Calendar timezone element""" 103 104 _tag = 'timezone' 105 _namespace = GCAL_NAMESPACE 106 _children = ValueAttributeContainer._children.copy() 107 _attributes = ValueAttributeContainer._attributes.copy() 108 109 110class Where(atom.AtomBase): 111 """The Google Calendar Where element""" 112 113 _tag = 'where' 114 _namespace = gdata.GDATA_NAMESPACE 115 _children = atom.AtomBase._children.copy() 116 _attributes = atom.AtomBase._attributes.copy() 117 _attributes['valueString'] = 'value_string' 118 119 def __init__(self, value_string=None, extension_elements=None, 120 extension_attributes=None, text=None): 121 self.value_string = value_string 122 self.text = text 123 self.extension_elements = extension_elements or [] 124 self.extension_attributes = extension_attributes or {} 125 126 127class CalendarListEntry(gdata.GDataEntry, gdata.LinkFinder): 128 """A Google Calendar meta Entry flavor of an Atom Entry """ 129 130 _tag = gdata.GDataEntry._tag 131 _namespace = gdata.GDataEntry._namespace 132 _children = gdata.GDataEntry._children.copy() 133 _attributes = gdata.GDataEntry._attributes.copy() 134 _children['{%s}color' % GCAL_NAMESPACE] = ('color', Color) 135 _children['{%s}accesslevel' % GCAL_NAMESPACE] = ('access_level', 136 AccessLevel) 137 _children['{%s}hidden' % GCAL_NAMESPACE] = ('hidden', Hidden) 138 _children['{%s}selected' % GCAL_NAMESPACE] = ('selected', Selected) 139 _children['{%s}timezone' % GCAL_NAMESPACE] = ('timezone', Timezone) 140 _children['{%s}where' % gdata.GDATA_NAMESPACE] = ('where', Where) 141 142 def __init__(self, author=None, category=None, content=None, 143 atom_id=None, link=None, published=None, 144 title=None, updated=None, 145 color=None, access_level=None, hidden=None, timezone=None, 146 selected=None, 147 where=None, 148 extension_elements=None, extension_attributes=None, text=None): 149 gdata.GDataEntry.__init__(self, author=author, category=category, 150 content=content, atom_id=atom_id, link=link, 151 published=published, title=title, 152 updated=updated, text=None) 153 154 self.color = color 155 self.access_level = access_level 156 self.hidden = hidden 157 self.selected = selected 158 self.timezone = timezone 159 self.where = where 160 161 162class CalendarListFeed(gdata.GDataFeed, gdata.LinkFinder): 163 """A Google Calendar meta feed flavor of an Atom Feed""" 164 165 _tag = gdata.GDataFeed._tag 166 _namespace = gdata.GDataFeed._namespace 167 _children = gdata.GDataFeed._children.copy() 168 _attributes = gdata.GDataFeed._attributes.copy() 169 _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [CalendarListEntry]) 170 171 172class Scope(atom.AtomBase): 173 """The Google ACL scope element""" 174 175 _tag = 'scope' 176 _namespace = GACL_NAMESPACE 177 _children = atom.AtomBase._children.copy() 178 _attributes = atom.AtomBase._attributes.copy() 179 _attributes['value'] = 'value' 180 _attributes['type'] = 'type' 181 182 def __init__(self, extension_elements=None, value=None, scope_type=None, 183 extension_attributes=None, text=None): 184 self.value = value 185 self.type = scope_type 186 self.text = text 187 self.extension_elements = extension_elements or [] 188 self.extension_attributes = extension_attributes or {} 189 190 191class Role(ValueAttributeContainer): 192 """The Google Calendar timezone element""" 193 194 _tag = 'role' 195 _namespace = GACL_NAMESPACE 196 _children = ValueAttributeContainer._children.copy() 197 _attributes = ValueAttributeContainer._attributes.copy() 198 199 200class CalendarAclEntry(gdata.GDataEntry, gdata.LinkFinder): 201 """A Google Calendar ACL Entry flavor of an Atom Entry """ 202 203 _tag = gdata.GDataEntry._tag 204 _namespace = gdata.GDataEntry._namespace 205 _children = gdata.GDataEntry._children.copy() 206 _attributes = gdata.GDataEntry._attributes.copy() 207 _children['{%s}scope' % GACL_NAMESPACE] = ('scope', Scope) 208 _children['{%s}role' % GACL_NAMESPACE] = ('role', Role) 209 210 def __init__(self, author=None, category=None, content=None, 211 atom_id=None, link=None, published=None, 212 title=None, updated=None, 213 scope=None, role=None, 214 extension_elements=None, extension_attributes=None, text=None): 215 gdata.GDataEntry.__init__(self, author=author, category=category, 216 content=content, atom_id=atom_id, link=link, 217 published=published, title=title, 218 updated=updated, text=None) 219 self.scope = scope 220 self.role = role 221 222 223class CalendarAclFeed(gdata.GDataFeed, gdata.LinkFinder): 224 """A Google Calendar ACL feed flavor of an Atom Feed""" 225 226 _tag = gdata.GDataFeed._tag 227 _namespace = gdata.GDataFeed._namespace 228 _children = gdata.GDataFeed._children.copy() 229 _attributes = gdata.GDataFeed._attributes.copy() 230 _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [CalendarAclEntry]) 231 232 233class CalendarEventCommentEntry(gdata.GDataEntry, gdata.LinkFinder): 234 """A Google Calendar event comments entry flavor of an Atom Entry""" 235 236 _tag = gdata.GDataEntry._tag 237 _namespace = gdata.GDataEntry._namespace 238 _children = gdata.GDataEntry._children.copy() 239 _attributes = gdata.GDataEntry._attributes.copy() 240 241 242class CalendarEventCommentFeed(gdata.GDataFeed, gdata.LinkFinder): 243 """A Google Calendar event comments feed flavor of an Atom Feed""" 244 245 _tag = gdata.GDataFeed._tag 246 _namespace = gdata.GDataFeed._namespace 247 _children = gdata.GDataFeed._children.copy() 248 _attributes = gdata.GDataFeed._attributes.copy() 249 _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', 250 [CalendarEventCommentEntry]) 251 252 253class ExtendedProperty(gdata.ExtendedProperty): 254 """A transparent subclass of gdata.ExtendedProperty added to this module 255 for backwards compatibility.""" 256 257 258class Reminder(atom.AtomBase): 259 """The Google Calendar reminder element""" 260 261 _tag = 'reminder' 262 _namespace = gdata.GDATA_NAMESPACE 263 _children = atom.AtomBase._children.copy() 264 _attributes = atom.AtomBase._attributes.copy() 265 _attributes['absoluteTime'] = 'absolute_time' 266 _attributes['days'] = 'days' 267 _attributes['hours'] = 'hours' 268 _attributes['minutes'] = 'minutes' 269 _attributes['method'] = 'method' 270 271 def __init__(self, absolute_time=None, 272 days=None, hours=None, minutes=None, method=None, 273 extension_elements=None, 274 extension_attributes=None, text=None): 275 self.absolute_time = absolute_time 276 if days is not None: 277 self.days = str(days) 278 else: 279 self.days = None 280 if hours is not None: 281 self.hours = str(hours) 282 else: 283 self.hours = None 284 if minutes is not None: 285 self.minutes = str(minutes) 286 else: 287 self.minutes = None 288 self.method = method 289 self.text = text 290 self.extension_elements = extension_elements or [] 291 self.extension_attributes = extension_attributes or {} 292 293 294class When(atom.AtomBase): 295 """The Google Calendar When element""" 296 297 _tag = 'when' 298 _namespace = gdata.GDATA_NAMESPACE 299 _children = atom.AtomBase._children.copy() 300 _attributes = atom.AtomBase._attributes.copy() 301 _children['{%s}reminder' % gdata.GDATA_NAMESPACE] = ('reminder', [Reminder]) 302 _attributes['startTime'] = 'start_time' 303 _attributes['endTime'] = 'end_time' 304 305 def __init__(self, start_time=None, end_time=None, reminder=None, 306 extension_elements=None, extension_attributes=None, text=None): 307 self.start_time = start_time 308 self.end_time = end_time 309 self.reminder = reminder or [] 310 self.text = text 311 self.extension_elements = extension_elements or [] 312 self.extension_attributes = extension_attributes or {} 313 314 315class Recurrence(atom.AtomBase): 316 """The Google Calendar Recurrence element""" 317 318 _tag = 'recurrence' 319 _namespace = gdata.GDATA_NAMESPACE 320 _children = atom.AtomBase._children.copy() 321 _attributes = atom.AtomBase._attributes.copy() 322 323 324class UriEnumElement(atom.AtomBase): 325 326 _children = atom.AtomBase._children.copy() 327 _attributes = atom.AtomBase._attributes.copy() 328 329 def __init__(self, tag, enum_map, attrib_name='value', 330 extension_elements=None, extension_attributes=None, text=None): 331 self.tag=tag 332 self.enum_map=enum_map 333 self.attrib_name=attrib_name 334 self.value=None 335 self.text=text 336 self.extension_elements = extension_elements or [] 337 self.extension_attributes = extension_attributes or {} 338 339 def findKey(self, value): 340 res=[item[0] for item in self.enum_map.items() if item[1] == value] 341 if res is None or len(res) == 0: 342 return None 343 return res[0] 344 345 def _ConvertElementAttributeToMember(self, attribute, value): 346 # Special logic to use the enum_map to set the value of the object's value member. 347 if attribute == self.attrib_name and value != '': 348 self.value = self.enum_map[value] 349 return 350 # Find the attribute in this class's list of attributes. 351 if self.__class__._attributes.has_key(attribute): 352 # Find the member of this class which corresponds to the XML attribute 353 # (lookup in current_class._attributes) and set this member to the 354 # desired value (using self.__dict__). 355 setattr(self, self.__class__._attributes[attribute], value) 356 else: 357 # The current class doesn't map this attribute, so try to parent class. 358 atom.ExtensionContainer._ConvertElementAttributeToMember(self, 359 attribute, 360 value) 361 362 def _AddMembersToElementTree(self, tree): 363 # Convert the members of this class which are XML child nodes. 364 # This uses the class's _children dictionary to find the members which 365 # should become XML child nodes. 366 member_node_names = [values[0] for tag, values in 367 self.__class__._children.iteritems()] 368 for member_name in member_node_names: 369 member = getattr(self, member_name) 370 if member is None: 371 pass 372 elif isinstance(member, list): 373 for instance in member: 374 instance._BecomeChildElement(tree) 375 else: 376 member._BecomeChildElement(tree) 377 # Special logic to set the desired XML attribute. 378 key = self.findKey(self.value) 379 if key is not None: 380 tree.attrib[self.attrib_name]=key 381 # Convert the members of this class which are XML attributes. 382 for xml_attribute, member_name in self.__class__._attributes.iteritems(): 383 member = getattr(self, member_name) 384 if member is not None: 385 tree.attrib[xml_attribute] = member 386 # Lastly, call the parent's _AddMembersToElementTree to get any 387 # extension elements. 388 atom.ExtensionContainer._AddMembersToElementTree(self, tree) 389 390 391 392class AttendeeStatus(UriEnumElement): 393 """The Google Calendar attendeeStatus element""" 394 395 _tag = 'attendeeStatus' 396 _namespace = gdata.GDATA_NAMESPACE 397 _children = UriEnumElement._children.copy() 398 _attributes = UriEnumElement._attributes.copy() 399 400 attendee_enum = { 401 'http://schemas.google.com/g/2005#event.accepted' : 'ACCEPTED', 402 'http://schemas.google.com/g/2005#event.declined' : 'DECLINED', 403 'http://schemas.google.com/g/2005#event.invited' : 'INVITED', 404 'http://schemas.google.com/g/2005#event.tentative' : 'TENTATIVE'} 405 406 def __init__(self, extension_elements=None, 407 extension_attributes=None, text=None): 408 UriEnumElement.__init__(self, 'attendeeStatus', AttendeeStatus.attendee_enum, 409 extension_elements=extension_elements, 410 extension_attributes=extension_attributes, 411 text=text) 412 413 414class AttendeeType(UriEnumElement): 415 """The Google Calendar attendeeType element""" 416 417 _tag = 'attendeeType' 418 _namespace = gdata.GDATA_NAMESPACE 419 _children = UriEnumElement._children.copy() 420 _attributes = UriEnumElement._attributes.copy() 421 422 attendee_type_enum = { 423 'http://schemas.google.com/g/2005#event.optional' : 'OPTIONAL', 424 'http://schemas.google.com/g/2005#event.required' : 'REQUIRED' } 425 426 def __init__(self, extension_elements=None, 427 extension_attributes=None, text=None): 428 UriEnumElement.__init__(self, 'attendeeType', 429 AttendeeType.attendee_type_enum, 430 extension_elements=extension_elements, 431 extension_attributes=extension_attributes,text=text) 432 433 434class Visibility(UriEnumElement): 435 """The Google Calendar Visibility element""" 436 437 _tag = 'visibility' 438 _namespace = gdata.GDATA_NAMESPACE 439 _children = UriEnumElement._children.copy() 440 _attributes = UriEnumElement._attributes.copy() 441 442 visibility_enum = { 443 'http://schemas.google.com/g/2005#event.confidential' : 'CONFIDENTIAL', 444 'http://schemas.google.com/g/2005#event.default' : 'DEFAULT', 445 'http://schemas.google.com/g/2005#event.private' : 'PRIVATE', 446 'http://schemas.google.com/g/2005#event.public' : 'PUBLIC' } 447 448 def __init__(self, extension_elements=None, 449 extension_attributes=None, text=None): 450 UriEnumElement.__init__(self, 'visibility', Visibility.visibility_enum, 451 extension_elements=extension_elements, 452 extension_attributes=extension_attributes, 453 text=text) 454 455 456class Transparency(UriEnumElement): 457 """The Google Calendar Transparency element""" 458 459 _tag = 'transparency' 460 _namespace = gdata.GDATA_NAMESPACE 461 _children = UriEnumElement._children.copy() 462 _attributes = UriEnumElement._attributes.copy() 463 464 transparency_enum = { 465 'http://schemas.google.com/g/2005#event.opaque' : 'OPAQUE', 466 'http://schemas.google.com/g/2005#event.transparent' : 'TRANSPARENT' } 467 468 def __init__(self, extension_elements=None, 469 extension_attributes=None, text=None): 470 UriEnumElement.__init__(self, tag='transparency', 471 enum_map=Transparency.transparency_enum, 472 extension_elements=extension_elements, 473 extension_attributes=extension_attributes, 474 text=text) 475 476 477class Comments(atom.AtomBase): 478 """The Google Calendar comments element""" 479 480 _tag = 'comments' 481 _namespace = gdata.GDATA_NAMESPACE 482 _children = atom.AtomBase._children.copy() 483 _attributes = atom.AtomBase._attributes.copy() 484 _children['{%s}feedLink' % gdata.GDATA_NAMESPACE] = ('feed_link', 485 gdata.FeedLink) 486 _attributes['rel'] = 'rel' 487 488 def __init__(self, rel=None, feed_link=None, extension_elements=None, 489 extension_attributes=None, text=None): 490 self.rel = rel 491 self.feed_link = feed_link 492 self.text = text 493 self.extension_elements = extension_elements or [] 494 self.extension_attributes = extension_attributes or {} 495 496 497class EventStatus(UriEnumElement): 498 """The Google Calendar eventStatus element""" 499 500 _tag = 'eventStatus' 501 _namespace = gdata.GDATA_NAMESPACE 502 _children = UriEnumElement._children.copy() 503 _attributes = UriEnumElement._attributes.copy() 504 505 status_enum = { 'http://schemas.google.com/g/2005#event.canceled' : 'CANCELED', 506 'http://schemas.google.com/g/2005#event.confirmed' : 'CONFIRMED', 507 'http://schemas.google.com/g/2005#event.tentative' : 'TENTATIVE'} 508 509 def __init__(self, extension_elements=None, 510 extension_attributes=None, text=None): 511 UriEnumElement.__init__(self, tag='eventStatus', 512 enum_map=EventStatus.status_enum, 513 extension_elements=extension_elements, 514 extension_attributes=extension_attributes, 515 text=text) 516 517 518class Who(UriEnumElement): 519 """The Google Calendar Who element""" 520 521 _tag = 'who' 522 _namespace = gdata.GDATA_NAMESPACE 523 _children = UriEnumElement._children.copy() 524 _attributes = UriEnumElement._attributes.copy() 525 _children['{%s}attendeeStatus' % gdata.GDATA_NAMESPACE] = ( 526 'attendee_status', AttendeeStatus) 527 _children['{%s}attendeeType' % gdata.GDATA_NAMESPACE] = ('attendee_type', 528 AttendeeType) 529 _attributes['valueString'] = 'name' 530 _attributes['email'] = 'email' 531 532 relEnum = { 'http://schemas.google.com/g/2005#event.attendee' : 'ATTENDEE', 533 'http://schemas.google.com/g/2005#event.organizer' : 'ORGANIZER', 534 'http://schemas.google.com/g/2005#event.performer' : 'PERFORMER', 535 'http://schemas.google.com/g/2005#event.speaker' : 'SPEAKER', 536 'http://schemas.google.com/g/2005#message.bcc' : 'BCC', 537 'http://schemas.google.com/g/2005#message.cc' : 'CC', 538 'http://schemas.google.com/g/2005#message.from' : 'FROM', 539 'http://schemas.google.com/g/2005#message.reply-to' : 'REPLY_TO', 540 'http://schemas.google.com/g/2005#message.to' : 'TO' } 541 542 def __init__(self, name=None, email=None, attendee_status=None, 543 attendee_type=None, rel=None, extension_elements=None, 544 extension_attributes=None, text=None): 545 UriEnumElement.__init__(self, 'who', Who.relEnum, attrib_name='rel', 546 extension_elements=extension_elements, 547 extension_attributes=extension_attributes, 548 text=text) 549 self.name = name 550 self.email = email 551 self.attendee_status = attendee_status 552 self.attendee_type = attendee_type 553 self.rel = rel 554 555 556class OriginalEvent(atom.AtomBase): 557 """The Google Calendar OriginalEvent element""" 558 559 _tag = 'originalEvent' 560 _namespace = gdata.GDATA_NAMESPACE 561 _children = atom.AtomBase._children.copy() 562 _attributes = atom.AtomBase._attributes.copy() 563 # TODO: The when tag used to map to a EntryLink, make sure it should really be a When. 564 _children['{%s}when' % gdata.GDATA_NAMESPACE] = ('when', When) 565 _attributes['id'] = 'id' 566 _attributes['href'] = 'href' 567 568 def __init__(self, id=None, href=None, when=None, 569 extension_elements=None, extension_attributes=None, text=None): 570 self.id = id 571 self.href = href 572 self.when = when 573 self.text = text 574 self.extension_elements = extension_elements or [] 575 self.extension_attributes = extension_attributes or {} 576 577 578def GetCalendarEventEntryClass(): 579 return CalendarEventEntry 580 581 582# This class is not completely defined here, because of a circular reference 583# in which CalendarEventEntryLink and CalendarEventEntry refer to one another. 584class CalendarEventEntryLink(gdata.EntryLink): 585 """An entryLink which contains a calendar event entry 586 587 Within an event's recurranceExceptions, an entry link 588 points to a calendar event entry. This class exists 589 to capture the calendar specific extensions in the entry. 590 """ 591 592 _tag = 'entryLink' 593 _namespace = gdata.GDATA_NAMESPACE 594 _children = gdata.EntryLink._children.copy() 595 _attributes = gdata.EntryLink._attributes.copy() 596 # The CalendarEventEntryLink should like CalendarEventEntry as a child but 597 # that class hasn't been defined yet, so we will wait until after defining 598 # CalendarEventEntry to list it in _children. 599 600 601class RecurrenceException(atom.AtomBase): 602 """The Google Calendar RecurrenceException element""" 603 604 _tag = 'recurrenceException' 605 _namespace = gdata.GDATA_NAMESPACE 606 _children = atom.AtomBase._children.copy() 607 _attributes = atom.AtomBase._attributes.copy() 608 _children['{%s}entryLink' % gdata.GDATA_NAMESPACE] = ('entry_link', 609 CalendarEventEntryLink) 610 _children['{%s}originalEvent' % gdata.GDATA_NAMESPACE] = ('original_event', 611 OriginalEvent) 612 _attributes['specialized'] = 'specialized' 613 614 def __init__(self, specialized=None, entry_link=None, 615 original_event=None, extension_elements=None, 616 extension_attributes=None, text=None): 617 self.specialized = specialized 618 self.entry_link = entry_link 619 self.original_event = original_event 620 self.text = text 621 self.extension_elements = extension_elements or [] 622 self.extension_attributes = extension_attributes or {} 623 624 625class SendEventNotifications(atom.AtomBase): 626 """The Google Calendar sendEventNotifications element""" 627 628 _tag = 'sendEventNotifications' 629 _namespace = GCAL_NAMESPACE 630 _children = atom.AtomBase._children.copy() 631 _attributes = atom.AtomBase._attributes.copy() 632 _attributes['value'] = 'value' 633 634 def __init__(self, extension_elements=None, 635 value=None, extension_attributes=None, text=None): 636 self.value = value 637 self.text = text 638 self.extension_elements = extension_elements or [] 639 self.extension_attributes = extension_attributes or {} 640 641 642class QuickAdd(atom.AtomBase): 643 """The Google Calendar quickadd element""" 644 645 _tag = 'quickadd' 646 _namespace = GCAL_NAMESPACE 647 _children = atom.AtomBase._children.copy() 648 _attributes = atom.AtomBase._attributes.copy() 649 _attributes['value'] = 'value' 650 651 def __init__(self, extension_elements=None, 652 value=None, extension_attributes=None, text=None): 653 self.value = value 654 self.text = text 655 self.extension_elements = extension_elements or [] 656 self.extension_attributes = extension_attributes or {} 657 658 def _TransferToElementTree(self, element_tree): 659 if self.value: 660 element_tree.attrib['value'] = self.value 661 element_tree.tag = GCAL_TEMPLATE % 'quickadd' 662 atom.AtomBase._TransferToElementTree(self, element_tree) 663 return element_tree 664 665 def _TakeAttributeFromElementTree(self, attribute, element_tree): 666 if attribute == 'value': 667 self.value = element_tree.attrib[attribute] 668 del element_tree.attrib[attribute] 669 else: 670 atom.AtomBase._TakeAttributeFromElementTree(self, attribute, 671 element_tree) 672 673 674class SyncEvent(atom.AtomBase): 675 _tag = 'syncEvent' 676 _namespace = GCAL_NAMESPACE 677 _children = atom.AtomBase._children.copy() 678 _attributes = atom.AtomBase._attributes.copy() 679 _attributes['value'] = 'value' 680 681 def __init__(self, value='false', extension_elements=None, 682 extension_attributes=None, text=None): 683 self.value = value 684 self.text = text 685 self.extension_elements = extension_elements or [] 686 self.extension_attributes = extension_attributes or {} 687 688 689class UID(atom.AtomBase): 690 _tag = 'uid' 691 _namespace = GCAL_NAMESPACE 692 _children = atom.AtomBase._children.copy() 693 _attributes = atom.AtomBase._attributes.copy() 694 _attributes['value'] = 'value' 695 696 def __init__(self, value=None, extension_elements=None, 697 extension_attributes=None, text=None): 698 self.value = value 699 self.text = text 700 self.extension_elements = extension_elements or [] 701 self.extension_attributes = extension_attributes or {} 702 703 704class Sequence(atom.AtomBase): 705 _tag = 'sequence' 706 _namespace = GCAL_NAMESPACE 707 _children = atom.AtomBase._children.copy() 708 _attributes = atom.AtomBase._attributes.copy() 709 _attributes['value'] = 'value' 710 711 def __init__(self, value=None, extension_elements=None, 712 extension_attributes=None, text=None): 713 self.value = value 714 self.text = text 715 self.extension_elements = extension_elements or [] 716 self.extension_attributes = extension_attributes or {} 717 718 719class WebContentGadgetPref(atom.AtomBase): 720 721 _tag = 'webContentGadgetPref' 722 _namespace = GCAL_NAMESPACE 723 _children = atom.AtomBase._children.copy() 724 _attributes = atom.AtomBase._attributes.copy() 725 _attributes['name'] = 'name' 726 _attributes['value'] = 'value' 727 728 """The Google Calendar Web Content Gadget Preferences element""" 729 730 def __init__(self, name=None, value=None, extension_elements=None, 731 extension_attributes=None, text=None): 732 self.name = name 733 self.value = value 734 self.text = text 735 self.extension_elements = extension_elements or [] 736 self.extension_attributes = extension_attributes or {} 737 738 739class WebContent(atom.AtomBase): 740 741 _tag = 'webContent' 742 _namespace = GCAL_NAMESPACE 743 _children = atom.AtomBase._children.copy() 744 _attributes = atom.AtomBase._attributes.copy() 745 _children['{%s}webContentGadgetPref' % GCAL_NAMESPACE] = ('gadget_pref', 746 [WebContentGadgetPref]) 747 _attributes['url'] = 'url' 748 _attributes['width'] = 'width' 749 _attributes['height'] = 'height' 750 751 def __init__(self, url=None, width=None, height=None, text=None, 752 gadget_pref=None, extension_elements=None, extension_attributes=None): 753 self.url = url 754 self.width = width 755 self.height = height 756 self.text = text 757 self.gadget_pref = gadget_pref or [] 758 self.extension_elements = extension_elements or [] 759 self.extension_attributes = extension_attributes or {} 760 761 762class WebContentLink(atom.Link): 763 764 _tag = 'link' 765 _namespace = atom.ATOM_NAMESPACE 766 _children = atom.Link._children.copy() 767 _attributes = atom.Link._attributes.copy() 768 _children['{%s}webContent' % GCAL_NAMESPACE] = ('web_content', WebContent) 769 770 def __init__(self, title=None, href=None, link_type=None, 771 web_content=None): 772 atom.Link.__init__(self, rel=WEB_CONTENT_LINK_REL, title=title, href=href, 773 link_type=link_type) 774 self.web_content = web_content 775 776 777class GuestsCanInviteOthers(atom.AtomBase): 778 """Indicates whether event attendees may invite others to the event. 779 780 This element may only be changed by the organizer of the event. If not 781 included as part of the event entry, this element will default to true 782 during a POST request, and will inherit its previous value during a PUT 783 request. 784 """ 785 _tag = 'guestsCanInviteOthers' 786 _namespace = GCAL_NAMESPACE 787 _attributes = atom.AtomBase._attributes.copy() 788 _attributes['value'] = 'value' 789 790 def __init__(self, value='true', *args, **kwargs): 791 atom.AtomBase.__init__(self, *args, **kwargs) 792 self.value = value 793 794 795class GuestsCanSeeGuests(atom.AtomBase): 796 """Indicates whether attendees can see other people invited to the event. 797 798 The organizer always sees all attendees. Guests always see themselves. This 799 property affects what attendees see in the event's guest list via both the 800 Calendar UI and API feeds. 801 802 This element may only be changed by the organizer of the event. 803 804 If not included as part of the event entry, this element will default to 805 true during a POST request, and will inherit its previous value during a 806 PUT request. 807 """ 808 _tag = 'guestsCanSeeGuests' 809 _namespace = GCAL_NAMESPACE 810 _attributes = atom.AtomBase._attributes.copy() 811 _attributes['value'] = 'value' 812 813 def __init__(self, value='true', *args, **kwargs): 814 atom.AtomBase.__init__(self, *args, **kwargs) 815 self.value = value 816 817 818class GuestsCanModify(atom.AtomBase): 819 """Indicates whether event attendees may modify the original event. 820 821 If yes, changes are visible to organizer and other attendees. Otherwise, 822 any changes made by attendees will be restricted to that attendee's 823 calendar. 824 825 This element may only be changed by the organizer of the event, and may 826 be set to 'true' only if both gCal:guestsCanInviteOthers and 827 gCal:guestsCanSeeGuests are set to true in the same PUT/POST request. 828 Otherwise, request fails with HTTP error code 400 (Bad Request). 829 830 If not included as part of the event entry, this element will default to 831 false during a POST request, and will inherit its previous value during a 832 PUT request.""" 833 _tag = 'guestsCanModify' 834 _namespace = GCAL_NAMESPACE 835 _attributes = atom.AtomBase._attributes.copy() 836 _attributes['value'] = 'value' 837 838 def __init__(self, value='false', *args, **kwargs): 839 atom.AtomBase.__init__(self, *args, **kwargs) 840 self.value = value 841 842 843 844class CalendarEventEntry(gdata.BatchEntry): 845 """A Google Calendar flavor of an Atom Entry """ 846 847 _tag = gdata.BatchEntry._tag 848 _namespace = gdata.BatchEntry._namespace 849 _children = gdata.BatchEntry._children.copy() 850 _attributes = gdata.BatchEntry._attributes.copy() 851 # This class also contains WebContentLinks but converting those members 852 # is handled in a special version of _ConvertElementTreeToMember. 853 _children['{%s}where' % gdata.GDATA_NAMESPACE] = ('where', [Where]) 854 _children['{%s}when' % gdata.GDATA_NAMESPACE] = ('when', [When]) 855 _children['{%s}who' % gdata.GDATA_NAMESPACE] = ('who', [Who]) 856 _children['{%s}extendedProperty' % gdata.GDATA_NAMESPACE] = ( 857 'extended_property', [ExtendedProperty]) 858 _children['{%s}visibility' % gdata.GDATA_NAMESPACE] = ('visibility', 859 Visibility) 860 _children['{%s}transparency' % gdata.GDATA_NAMESPACE] = ('transparency', 861 Transparency) 862 _children['{%s}eventStatus' % gdata.GDATA_NAMESPACE] = ('event_status', 863 EventStatus) 864 _children['{%s}recurrence' % gdata.GDATA_NAMESPACE] = ('recurrence', 865 Recurrence) 866 _children['{%s}recurrenceException' % gdata.GDATA_NAMESPACE] = ( 867 'recurrence_exception', [RecurrenceException]) 868 _children['{%s}sendEventNotifications' % GCAL_NAMESPACE] = ( 869 'send_event_notifications', SendEventNotifications) 870 _children['{%s}quickadd' % GCAL_NAMESPACE] = ('quick_add', QuickAdd) 871 _children['{%s}comments' % gdata.GDATA_NAMESPACE] = ('comments', Comments) 872 _children['{%s}originalEvent' % gdata.GDATA_NAMESPACE] = ('original_event', 873 OriginalEvent) 874 _children['{%s}sequence' % GCAL_NAMESPACE] = ('sequence', Sequence) 875 _children['{%s}reminder' % gdata.GDATA_NAMESPACE] = ('reminder', [Reminder]) 876 _children['{%s}syncEvent' % GCAL_NAMESPACE] = ('sync_event', SyncEvent) 877 _children['{%s}uid' % GCAL_NAMESPACE] = ('uid', UID) 878 _children['{%s}guestsCanInviteOthers' % GCAL_NAMESPACE] = ( 879 'guests_can_invite_others', GuestsCanInviteOthers) 880 _children['{%s}guestsCanModify' % GCAL_NAMESPACE] = ( 881 'guests_can_modify', GuestsCanModify) 882 _children['{%s}guestsCanSeeGuests' % GCAL_NAMESPACE] = ( 883 'guests_can_see_guests', GuestsCanSeeGuests) 884 885 def __init__(self, author=None, category=None, content=None, 886 atom_id=None, link=None, published=None, 887 title=None, updated=None, 888 transparency=None, comments=None, event_status=None, 889 send_event_notifications=None, visibility=None, 890 recurrence=None, recurrence_exception=None, 891 where=None, when=None, who=None, quick_add=None, 892 extended_property=None, original_event=None, 893 batch_operation=None, batch_id=None, batch_status=None, 894 sequence=None, reminder=None, sync_event=None, uid=None, 895 guests_can_invite_others=None, guests_can_modify=None, 896 guests_can_see_guests=None, 897 extension_elements=None, extension_attributes=None, text=None): 898 899 gdata.BatchEntry.__init__(self, author=author, category=category, 900 content=content, 901 atom_id=atom_id, link=link, published=published, 902 batch_operation=batch_operation, batch_id=batch_id, 903 batch_status=batch_status, 904 title=title, updated=updated) 905 906 self.transparency = transparency 907 self.comments = comments 908 self.event_status = event_status 909 self.send_event_notifications = send_event_notifications 910 self.visibility = visibility 911 self.recurrence = recurrence 912 self.recurrence_exception = recurrence_exception or [] 913 self.where = where or [] 914 self.when = when or [] 915 self.who = who or [] 916 self.quick_add = quick_add 917 self.extended_property = extended_property or [] 918 self.original_event = original_event 919 self.sequence = sequence 920 self.reminder = reminder or [] 921 self.sync_event = sync_event 922 self.uid = uid 923 self.text = text 924 self.guests_can_invite_others = guests_can_invite_others 925 self.guests_can_modify = guests_can_modify 926 self.guests_can_see_guests = guests_can_see_guests 927 self.extension_elements = extension_elements or [] 928 self.extension_attributes = extension_attributes or {} 929 930 # We needed to add special logic to _ConvertElementTreeToMember because we 931 # want to make links with a rel of WEB_CONTENT_LINK_REL into a 932 # WebContentLink 933 def _ConvertElementTreeToMember(self, child_tree): 934 # Special logic to handle Web Content links 935 if (child_tree.tag == '{%s}link' % atom.ATOM_NAMESPACE and 936 child_tree.attrib['rel'] == WEB_CONTENT_LINK_REL): 937 if self.link is None: 938 self.link = [] 939 self.link.append(atom._CreateClassFromElementTree(WebContentLink, 940 child_tree)) 941 return 942 # Find the element's tag in this class's list of child members 943 if self.__class__._children.has_key(child_tree.tag): 944 member_name = self.__class__._children[child_tree.tag][0] 945 member_class = self.__class__._children[child_tree.tag][1] 946 # If the class member is supposed to contain a list, make sure the 947 # matching member is set to a list, then append the new member 948 # instance to the list. 949 if isinstance(member_class, list): 950 if getattr(self, member_name) is None: 951 setattr(self, member_name, []) 952 getattr(self, member_name).append(atom._CreateClassFromElementTree( 953 member_class[0], child_tree)) 954 else: 955 setattr(self, member_name, 956 atom._CreateClassFromElementTree(member_class, child_tree)) 957 else: 958 atom.ExtensionContainer._ConvertElementTreeToMember(self, child_tree) 959 960 961 def GetWebContentLink(self): 962 """Finds the first link with rel set to WEB_CONTENT_REL 963 964 Returns: 965 A gdata.calendar.WebContentLink or none if none of the links had rel 966 equal to WEB_CONTENT_REL 967 """ 968 969 for a_link in self.link: 970 if a_link.rel == WEB_CONTENT_LINK_REL: 971 return a_link 972 return None 973 974 975def CalendarEventEntryFromString(xml_string): 976 return atom.CreateClassFromXMLString(CalendarEventEntry, xml_string) 977 978 979def CalendarEventCommentEntryFromString(xml_string): 980 return atom.CreateClassFromXMLString(CalendarEventCommentEntry, xml_string) 981 982 983CalendarEventEntryLink._children = {'{%s}entry' % atom.ATOM_NAMESPACE: 984 ('entry', CalendarEventEntry)} 985 986 987def CalendarEventEntryLinkFromString(xml_string): 988 return atom.CreateClassFromXMLString(CalendarEventEntryLink, xml_string) 989 990 991class CalendarEventFeed(gdata.BatchFeed, gdata.LinkFinder): 992 """A Google Calendar event feed flavor of an Atom Feed""" 993 994 _tag = gdata.BatchFeed._tag 995 _namespace = gdata.BatchFeed._namespace 996 _children = gdata.BatchFeed._children.copy() 997 _attributes = gdata.BatchFeed._attributes.copy() 998 _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', 999 [CalendarEventEntry]) 1000 _children['{%s}timezone' % GCAL_NAMESPACE] = ('timezone', Timezone) 1001 1002 def __init__(self, author=None, category=None, contributor=None, 1003 generator=None, icon=None, atom_id=None, link=None, logo=None, 1004 rights=None, subtitle=None, title=None, updated=None, entry=None, 1005 total_results=None, start_index=None, items_per_page=None, 1006 interrupted=None, timezone=None, 1007 extension_elements=None, extension_attributes=None, text=None): 1008 gdata.BatchFeed.__init__(self, author=author, category=category, 1009 contributor=contributor, generator=generator, 1010 icon=icon, atom_id=atom_id, link=link, 1011 logo=logo, rights=rights, subtitle=subtitle, 1012 title=title, updated=updated, entry=entry, 1013 total_results=total_results, 1014 start_index=start_index, 1015 items_per_page=items_per_page, 1016 interrupted=interrupted, 1017 extension_elements=extension_elements, 1018 extension_attributes=extension_attributes, 1019 text=text) 1020 self.timezone = timezone 1021 1022 1023def CalendarListEntryFromString(xml_string): 1024 return atom.CreateClassFromXMLString(CalendarListEntry, xml_string) 1025 1026 1027def CalendarAclEntryFromString(xml_string): 1028 return atom.CreateClassFromXMLString(CalendarAclEntry, xml_string) 1029 1030 1031def CalendarListFeedFromString(xml_string): 1032 return atom.CreateClassFromXMLString(CalendarListFeed, xml_string) 1033 1034 1035def CalendarAclFeedFromString(xml_string): 1036 return atom.CreateClassFromXMLString(CalendarAclFeed, xml_string) 1037 1038 1039def CalendarEventFeedFromString(xml_string): 1040 return atom.CreateClassFromXMLString(CalendarEventFeed, xml_string) 1041 1042 1043def CalendarEventCommentFeedFromString(xml_string): 1044 return atom.CreateClassFromXMLString(CalendarEventCommentFeed, xml_string)