PageRenderTime 66ms CodeModel.GetById 18ms app.highlight 42ms RepoModel.GetById 1ms app.codeStats 1ms

/gdata/contacts/data.py

http://radioappz.googlecode.com/
Python | 474 lines | 430 code | 18 blank | 26 comment | 0 complexity | 4ecc5f430f30e19d0268b4a65085dcc2 MD5 | raw file
  1#!/usr/bin/env python                                                   
  2#                                                                       
  3# Copyright (C) 2009 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"""Data model classes for parsing and generating XML for the Contacts API."""
 18
 19
 20__author__ = 'vinces1979@gmail.com (Vince Spicer)'
 21
 22
 23import atom.core
 24import gdata
 25import gdata.data
 26
 27
 28PHOTO_LINK_REL = 'http://schemas.google.com/contacts/2008/rel#photo'
 29PHOTO_EDIT_LINK_REL = 'http://schemas.google.com/contacts/2008/rel#edit-photo'
 30
 31EXTERNAL_ID_ORGANIZATION = 'organization'
 32
 33RELATION_MANAGER = 'manager'
 34
 35CONTACTS_NAMESPACE = 'http://schemas.google.com/contact/2008'
 36CONTACTS_TEMPLATE = '{%s}%%s' % CONTACTS_NAMESPACE
 37
 38
 39class BillingInformation(atom.core.XmlElement):
 40  """ 
 41  gContact:billingInformation
 42  Specifies billing information of the entity represented by the contact. The element cannot be repeated. 
 43  """
 44  
 45  _qname = CONTACTS_TEMPLATE % 'billingInformation'
 46
 47
 48class Birthday(atom.core.XmlElement):
 49  """ 
 50 Stores birthday date of the person represented by the contact. The element cannot be repeated. 
 51 """
 52  
 53  _qname = CONTACTS_TEMPLATE % 'birthday'
 54  when = 'when'
 55
 56
 57class CalendarLink(atom.core.XmlElement):
 58  """ 
 59  Storage for URL of the contact's calendar. The element can be repeated. 
 60  """
 61  
 62  _qname = CONTACTS_TEMPLATE % 'calendarLink'
 63  rel = 'rel'
 64  label = 'label'
 65  primary = 'primary'
 66  href = 'href'
 67
 68
 69class DirectoryServer(atom.core.XmlElement):
 70  """ 
 71  A directory server associated with this contact. 
 72  May not be repeated. 
 73  """
 74  
 75  _qname = CONTACTS_TEMPLATE % 'directoryServer'
 76
 77
 78class Event(atom.core.XmlElement):
 79  """
 80  These elements describe events associated with a contact. 
 81  They may be repeated
 82  """
 83  
 84  _qname = CONTACTS_TEMPLATE % 'event'
 85  label = 'label'
 86  rel = 'rel'
 87  when = gdata.data.When
 88
 89
 90class ExternalId(atom.core.XmlElement):
 91  """
 92   Describes an ID of the contact in an external system of some kind. 
 93  This element may be repeated. 
 94  """
 95  
 96  _qname = CONTACTS_TEMPLATE % 'externalId'
 97
 98
 99def ExternalIdFromString(xml_string):
100  return atom.core.parse(ExternalId, xml_string)
101
102
103class Gender(atom.core.XmlElement):
104  """ 
105  Specifies the gender of the person represented by the contact.
106  The element cannot be repeated. 
107  """
108  
109  _qname = CONTACTS_TEMPLATE % 'directoryServer'
110  value = 'value'
111
112
113class Hobby(atom.core.XmlElement):
114  """ 
115  Describes an ID of the contact in an external system of some kind. 
116  This element may be repeated. 
117  """
118  
119  _qname = CONTACTS_TEMPLATE % 'hobby'
120
121
122class Initials(atom.core.XmlElement):
123  """ Specifies the initials of the person represented by the contact. The 
124  element cannot be repeated. """
125  
126  _qname = CONTACTS_TEMPLATE % 'initials'
127
128
129class Jot(atom.core.XmlElement):
130  """ 
131  Storage for arbitrary pieces of information about the contact. Each jot 
132  has a type specified by the rel attribute and a text value. 
133  The element can be repeated. 
134  """
135  
136  _qname = CONTACTS_TEMPLATE % 'jot'
137  rel = 'rel'
138
139
140class Language(atom.core.XmlElement):
141  """ 
142 Specifies the preferred languages of the contact. 
143 The element can be repeated.
144
145  The language must be specified using one of two mutually exclusive methods: 
146  using the freeform @label attribute, or using the @code attribute, whose value 
147  must conform to the IETF BCP 47 specification.
148  """
149  
150  _qname = CONTACTS_TEMPLATE % 'language'
151  code = 'code'
152  label = 'label'
153
154
155class MaidenName(atom.core.XmlElement):
156  """ 
157  Specifies maiden name of the person represented by the contact. 
158  The element cannot be repeated.
159  """
160  
161  _qname = CONTACTS_TEMPLATE % 'maidenName'
162
163
164class Mileage(atom.core.XmlElement):
165  """ 
166  Specifies the mileage for the entity represented by the contact. 
167  Can be used for example to document distance needed for reimbursement 
168  purposes. The value is not interpreted. The element cannot be repeated.
169  """
170  
171  _qname = CONTACTS_TEMPLATE % 'mileage'
172
173
174class NickName(atom.core.XmlElement):
175  """
176  Specifies the nickname of the person represented by the contact. 
177  The element cannot be repeated.
178  """
179  
180  _qname = CONTACTS_TEMPLATE % 'nickname'
181
182
183class Occupation(atom.core.XmlElement):
184  """
185  Specifies the occupation/profession of the person specified by the contact. 
186  The element cannot be repeated.
187  """
188  
189  _qname = CONTACTS_TEMPLATE % 'occupation'
190
191
192class Priority(atom.core.XmlElement):
193  """ 
194  Classifies importance of the contact into 3 categories:
195    * Low
196    * Normal
197    * High
198
199  The priority element cannot be repeated. 
200  """
201
202  _qname = CONTACTS_TEMPLATE % 'priority'
203
204
205class Relation(atom.core.XmlElement):
206  """
207  This element describe another entity (usually a person) that is in a 
208  relation of some kind with the contact.
209  """
210
211  _qname = CONTACTS_TEMPLATE % 'relation'
212  rel = 'rel'
213  label = 'label'
214
215
216class Sensitivity(atom.core.XmlElement):
217  """
218  Classifies sensitivity of the contact into the following categories:
219    * Confidential
220    * Normal
221    * Personal
222    * Private
223
224  The sensitivity element cannot be repeated. 
225  """
226
227  _qname = CONTACTS_TEMPLATE % 'sensitivity'
228  rel = 'rel'
229
230
231class UserDefinedField(atom.core.XmlElement):
232  """
233  Represents an arbitrary key-value pair attached to the contact.
234  """
235
236  _qname = CONTACTS_TEMPLATE % 'userDefinedField'
237  key = 'key'
238  value = 'value'
239
240
241def UserDefinedFieldFromString(xml_string):
242  return atom.core.parse(UserDefinedField, xml_string)
243
244
245class Website(atom.core.XmlElement):
246  """
247  Describes websites associated with the contact, including links. 
248  May be repeated.
249  """
250
251  _qname = CONTACTS_TEMPLATE % 'website'
252  
253  href = 'href'
254  label = 'label'
255  primary = 'primary'
256  rel = 'rel'
257
258
259def WebsiteFromString(xml_string):
260  return atom.core.parse(Website, xml_string)
261
262
263class HouseName(atom.core.XmlElement):
264  """
265  Used in places where houses or buildings have names (and 
266  not necessarily numbers), eg. "The Pillars".
267  """
268  
269  _qname = CONTACTS_TEMPLATE % 'housename'
270
271
272class Street(atom.core.XmlElement):
273  """
274  Can be street, avenue, road, etc. This element also includes the house 
275  number and room/apartment/flat/floor number.
276  """
277  
278  _qname = CONTACTS_TEMPLATE % 'street'
279
280
281class POBox(atom.core.XmlElement):
282  """
283  Covers actual P.O. boxes, drawers, locked bags, etc. This is usually but not
284  always mutually exclusive with street
285  """
286  
287  _qname = CONTACTS_TEMPLATE % 'pobox'
288
289
290class Neighborhood(atom.core.XmlElement):
291  """
292  This is used to disambiguate a street address when a city contains more than
293  one street with the same name, or to specify a small place whose mail is
294  routed through a larger postal town. In China it could be a county or a 
295  minor city.
296  """
297  
298  _qname = CONTACTS_TEMPLATE % 'neighborhood'
299
300
301class City(atom.core.XmlElement):
302  """
303  Can be city, village, town, borough, etc. This is the postal town and not
304  necessarily the place of residence or place of business.
305  """
306  
307  _qname = CONTACTS_TEMPLATE % 'city'
308
309
310class SubRegion(atom.core.XmlElement):
311  """
312  Handles administrative districts such as U.S. or U.K. counties that are not
313   used for mail addressing purposes. Subregion is not intended for 
314   delivery addresses.
315  """
316
317  _qname = CONTACTS_TEMPLATE % 'subregion'
318
319
320class Region(atom.core.XmlElement):
321  """
322  A state, province, county (in Ireland), Land (in Germany), 
323  departement (in France), etc.
324  """
325
326  _qname = CONTACTS_TEMPLATE % 'region'
327  
328
329class PostalCode(atom.core.XmlElement):
330  """
331  Postal code. Usually country-wide, but sometimes specific to the 
332  city (e.g. "2" in "Dublin 2, Ireland" addresses).
333  """
334  
335  _qname = CONTACTS_TEMPLATE % 'postcode'
336
337
338class Country(atom.core.XmlElement):
339  """ The name or code of the country. """
340
341  _qname = CONTACTS_TEMPLATE % 'country'  
342
343
344class PersonEntry(gdata.data.BatchEntry):
345  """Represents a google contact"""
346
347  billing_information = BillingInformation
348  birthday = Birthday
349  calendar_link = [CalendarLink]
350  directory_server = DirectoryServer
351  event = [Event]
352  external_id = [ExternalId]
353  gender = Gender
354  hobby = [Hobby]
355  initals = Initials
356  jot = [Jot]
357  language= [Language]
358  maiden_name = MaidenName
359  mileage = Mileage
360  nickname = NickName
361  occupation = Occupation
362  priority = Priority
363  relation = [Relation]
364  sensitivity = Sensitivity
365  user_defined_field = [UserDefinedField]
366  website = [Website]
367  
368  name = gdata.data.Name
369  phone_number = [gdata.data.PhoneNumber]
370  organization = gdata.data.Organization
371  postal_address = [gdata.data.PostalAddress]
372  email = [gdata.data.Email]
373  im = [gdata.data.Im]
374  structured_postal_address = [gdata.data.StructuredPostalAddress]
375  extended_property = [gdata.data.ExtendedProperty]
376  
377
378class Deleted(atom.core.XmlElement):
379  """If present, indicates that this contact has been deleted."""
380  _qname = gdata.GDATA_TEMPLATE % 'deleted'
381
382
383class GroupMembershipInfo(atom.core.XmlElement):
384  """
385  Identifies the group to which the contact belongs or belonged.
386  The group is referenced by its id.
387  """
388
389  _qname = CONTACTS_TEMPLATE % 'groupMembershipInfo'
390
391  href = 'href'
392  deleted = 'deleted'
393
394
395class ContactEntry(PersonEntry):
396  """A Google Contacts flavor of an Atom Entry."""
397
398  deleted = Deleted
399  group_membership_info = [GroupMembershipInfo]
400  organization = gdata.data.Organization
401
402  def GetPhotoLink(self):
403    for a_link in self.link:
404      if a_link.rel == PHOTO_LINK_REL:
405        return a_link
406    return None
407
408  def GetPhotoEditLink(self):
409    for a_link in self.link:
410      if a_link.rel == PHOTO_EDIT_LINK_REL:
411        return a_link
412    return None
413
414
415class ContactsFeed(gdata.data.BatchFeed):
416  """A collection of Contacts."""
417  entry = [ContactEntry]
418
419
420class SystemGroup(atom.core.XmlElement):
421  """The contacts systemGroup element.
422  
423  When used within a contact group entry, indicates that the group in
424  question is one of the predefined system groups."""
425
426  _qname = CONTACTS_TEMPLATE % 'systemGroup'
427  id = 'id'
428
429
430class GroupEntry(gdata.data.BatchEntry):
431  """Represents a contact group."""
432  extended_property = [gdata.data.ExtendedProperty]
433  system_group = SystemGroup
434
435
436class GroupsFeed(gdata.data.BatchFeed):
437  """A Google contact groups feed flavor of an Atom Feed."""
438  entry = [GroupEntry]
439
440
441class ProfileEntry(PersonEntry):
442  """A Google Profiles flavor of an Atom Entry."""
443
444
445def ProfileEntryFromString(xml_string):
446  """Converts an XML string into a ProfileEntry object.
447
448  Args:
449    xml_string: string The XML describing a Profile entry.
450
451  Returns:
452    A ProfileEntry object corresponding to the given XML.
453  """
454  return atom.core.parse(ProfileEntry, xml_string)
455
456
457class ProfilesFeed(gdata.data.BatchFeed):
458  """A Google Profiles feed flavor of an Atom Feed."""
459  _qname = atom.data.ATOM_TEMPLATE % 'feed'
460  entry = [ProfileEntry]
461
462
463def ProfilesFeedFromString(xml_string):
464  """Converts an XML string into a ProfilesFeed object.
465
466  Args:
467    xml_string: string The XML describing a Profiles feed.
468
469  Returns:
470    A ProfilesFeed object corresponding to the given XML.
471  """
472  return atom.core.parse(ProfilesFeed, xml_string)
473
474