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