PageRenderTime 69ms CodeModel.GetById 2ms app.highlight 58ms RepoModel.GetById 1ms app.codeStats 0ms

/gdata/calendar/__init__.py

http://radioappz.googlecode.com/
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)