~cmiller/+junk/notify-friends-contacts

« back to all changes in this revision

Viewing changes to contact_data.py

  • Committer: Chad MILLER
  • Date: 2010-07-03 23:18:35 UTC
  • mfrom: (2.1.2 contacts_sync)
  • Revision ID: cmiller@hypatia-20100703231835-jqd5pmqcrlfb3avg
Merge Mandel's ui code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import logging
 
2
 
 
3
logger = logging.getLogger("contact_data")
 
4
 
 
5
def get_instance(cls, data):
 
6
    """
 
7
    @type cls: Class
 
8
    @param cls: The class of the object to instantiate.
 
9
    @type data: dict
 
10
    @param data: A dictiornary with the data of the object to desirialize.
 
11
 
 
12
    Method that takes a class and return a new instance with the passed
 
13
    data in athe given dictionary.
 
14
    """
 
15
    # create an instance using the class
 
16
    instance = cls()
 
17
    for attribute in cls._attributes:
 
18
        if attribute in data:
 
19
            setattr(instance, attribute, data[attribute])
 
20
    return instance
 
21
 
 
22
def get_dictionary(instance):
 
23
    """
 
24
    """
 
25
    data = {}
 
26
    for attribute in type(instance)._attributes:
 
27
        current_data = getattr(instance, attribute)
 
28
        if current_data and attribute != "id":
 
29
            data[attribute] = current_data
 
30
    return data
 
31
 
 
32
class ContactData(object):
 
33
    """
 
34
    Represents the bas class that should be extended of contact data that
 
35
    can be added to a contact.
 
36
    """
 
37
 
 
38
    def __init__(self, description=None):
 
39
        self.description = description
 
40
 
 
41
    def __cmp__(self, other):
 
42
        if isinstance(other, type(self)):
 
43
            for current_attribute in self._attributes:
 
44
                first_value = getattr(self, current_attribute)
 
45
                second_value = getattr(other, current_attribute)
 
46
                if not first_value == second_value:
 
47
                    return cmp(first_value, second_value)
 
48
            return 0
 
49
        else:
 
50
            raise TypeError("{0} {1} cannot be compared".format(
 
51
                str(type(self)), str(type(other))))
 
52
 
 
53
    def __eq__(self, other):
 
54
        if isinstance(other, type(self)):
 
55
            return cmp(self, other) == 0
 
56
        raise TypeError("{0} {1} cannot be compared".format(
 
57
                str(type(self)), str(type(other))))
 
58
 
 
59
    def __hash__(self):
 
60
        result = 0
 
61
        for current_attribute in self._attributes:
 
62
            result += hash(getattr(self, current_attribute))
 
63
        return result
 
64
 
 
65
    # private methods
 
66
 
 
67
    def _get_description(self):
 
68
        # test if the class has a description enum
 
69
        if type(self)._description_enum is not None:
 
70
            if hasattr(self, "_description"):
 
71
                return self._description
 
72
            return None
 
73
        else:
 
74
            raise AttributeError(
 
75
                "The class {0} does not support descriptions.".format(
 
76
                    type(self)))
 
77
 
 
78
    def _set_description(self, value):
 
79
        # test if the class has a description enum
 
80
        if type(self)._description_enum is not None:
 
81
            if value in type(self)._description_enum or value is None:
 
82
                self._description = value
 
83
            else:
 
84
                raise ValueError("Wrong description provided {0}".format(
 
85
                    value))
 
86
        else:
 
87
            raise AttributeError(
 
88
                "The class {0} does not support descriptions.".format(
 
89
                    type(self)))
 
90
 
 
91
    def _attributes(self):
 
92
        """
 
93
        Returns the accepted attributes of the class.
 
94
        """
 
95
        return type(self)._attributes
 
96
 
 
97
    # properties
 
98
    description = property(_get_description, _set_description)
 
99
 
 
100
################################################################################
 
101
########################### Address implementation #############################
 
102
################################################################################
 
103
 
 
104
WORK_ADDRESS = "work"
 
105
HOME_ADDRESS = "home"
 
106
OTHER_ADDRESS = "other"
 
107
 
 
108
ADDRESS_DESCRIPTIONS = (WORK_ADDRESS,
 
109
    HOME_ADDRESS,
 
110
    OTHER_ADDRESS,)
 
111
 
 
112
class Address(ContactData):
 
113
    """
 
114
    Represents an address in the system. An address will have the required
 
115
    information to send packages etc...
 
116
    """
 
117
 
 
118
    _attributes = ("country",
 
119
                   "state",
 
120
                   "city",
 
121
                   "postalcode",
 
122
                   "street",
 
123
                   "description",)
 
124
 
 
125
    _description_enum = ADDRESS_DESCRIPTIONS
 
126
 
 
127
    def __init__(self, country=None, state=None, city=None, postalcode=None,
 
128
        street=None, description=None):
 
129
        """
 
130
        @type country: string
 
131
        @type state: string
 
132
        @type city: string
 
133
        @type postalcode: string
 
134
        @type street: string
 
135
        @type description: string
 
136
        @param country: Country where the address can be found.
 
137
        @param state: State where the address can be found.
 
138
        @param city: City where the addrss can be found
 
139
        @param postalcode: The postcalcode of the address.
 
140
        @param street: The actual address
 
141
        @param description: Description that gives more information about the
 
142
        address.
 
143
 
 
144
        Creates a new address that can be added to a user.
 
145
        """
 
146
        ContactData.__init__(self, description=description)
 
147
        self.country = country
 
148
        self.state = state
 
149
        self.city = city
 
150
        self.postalcode = postalcode
 
151
        self.street = street
 
152
 
 
153
    def __str__(self):
 
154
        return "{0} {1} {2} {3}".format(
 
155
            self.country, self.state, self.city, self.street)
 
156
 
 
157
###############################################################################
 
158
########################### Email address implementation ######################
 
159
###############################################################################
 
160
 
 
161
WORK_EMAIL_ADDRESS = "work"
 
162
HOME_EMAIL_ADDRESS = "home"
 
163
OTHER_EMAIL_ADDRESS = "other"
 
164
 
 
165
EMAIL_ADDRESS_DESCRIPTIONS = (WORK_EMAIL_ADDRESS,
 
166
    HOME_EMAIL_ADDRESS,
 
167
    OTHER_EMAIL_ADDRESS,)
 
168
 
 
169
class EmailAddress(ContactData):
 
170
    """
 
171
    Represents an emial address in the api.
 
172
    """
 
173
 
 
174
    _attributes = ("address", "description",)
 
175
 
 
176
    _description_enum = EMAIL_ADDRESS_DESCRIPTIONS
 
177
 
 
178
    def __init__(self, address=None, description=None):
 
179
        """
 
180
        @type address: string
 
181
        @param address: The string that represents the address
 
182
        @type description: string
 
183
        @param description: A nice description about the address.
 
184
 
 
185
        Creates a new address that can be used in the API.
 
186
        """
 
187
        ContactData.__init__(self, description=description)
 
188
        self.address = address
 
189
 
 
190
    def __str__(self):
 
191
        return self.address
 
192
 
 
193
###############################################################################
 
194
######################### Instant messenger implementation ####################
 
195
###############################################################################
 
196
 
 
197
AIM_PROTOCOL = "aim"
 
198
GADU_GADU_PROTOCOL = "gadu-gadu"
 
199
GROUPWISE_PROTOCOL = "groupwise"
 
200
ICQ_PROTOCOL = "icq"
 
201
IRC_PROTOCOL = "irc"
 
202
JABBER_PROTOCOL = "jabber"
 
203
MSN_PROTOCOL = "msn"
 
204
SKYPE_PROTOCOL = "skype"
 
205
YAHOO_PROTOCOL = "yahoo"
 
206
 
 
207
IM_ADDRESS_PROTOCOLS = (AIM_PROTOCOL,
 
208
    GADU_GADU_PROTOCOL,
 
209
    GROUPWISE_PROTOCOL,
 
210
    ICQ_PROTOCOL,
 
211
    IRC_PROTOCOL,
 
212
    JABBER_PROTOCOL,
 
213
    MSN_PROTOCOL,
 
214
    SKYPE_PROTOCOL,
 
215
    YAHOO_PROTOCOL,)
 
216
 
 
217
class InstantMessenger(ContactData):
 
218
    """
 
219
    This class represents an instant messenger account that a contact can have.
 
220
    """
 
221
 
 
222
    _attributes = ("address", "description", )
 
223
 
 
224
    _description_enum = IM_ADDRESS_PROTOCOLS
 
225
 
 
226
    def __init__(self, address=None, protocol=None, description=None):
 
227
        """
 
228
        @type user_name: string
 
229
        @param user_name: The user name in the m protocol.
 
230
        @type protocol: Protocol
 
231
        @param protocol: The protocol used by the im.
 
232
        Creates a new instant messenger to be used by the contact.
 
233
        """
 
234
        ContactData.__init__(self, description=protocol)
 
235
        self.address = address
 
236
        self._text_description = description
 
237
 
 
238
    def _get_text_description(self):
 
239
        return self._text_description
 
240
 
 
241
    def _set_text_description(self, value):
 
242
        self._text_description = value
 
243
 
 
244
    # properties
 
245
 
 
246
    # rebind the description since the instant messenger uses it in a diff
 
247
    # manner
 
248
    description = property(_get_text_description, _set_text_description)
 
249
    protocol = property(ContactData._get_description,
 
250
        ContactData._set_description)
 
251
 
 
252
###############################################################################
 
253
######################## Telephone Number implementation ######################
 
254
###############################################################################
 
255
 
 
256
HOME_PHONE_NUMBER = "home"
 
257
MOBILE_PHONE_NUMBER = "mobile"
 
258
HOME_FAX_NUMBER = "home fax"
 
259
WORK_PHONE_NUMBER = "work"
 
260
CAR_PHONE_NUMBER = "car"
 
261
PAGER_PHONE_NUMBER = "pager"
 
262
WORK_FAX_PHONE_NUMBER = "work fax"
 
263
ASSISTANT_PHONE_NUMBER = "assistant"
 
264
CALLBACK_PHONE_NUMBER = "callback"
 
265
COMPANY_PHONE_NUMBER = "company"
 
266
OTHER_PHONE_NUMBER = "other"
 
267
OTHER_FAX_PHONE_NUMBER = "other fax"
 
268
PRIMARY_PHONE_NUMBER = "primary"
 
269
TELEX_PHONE_NUMBER = "telex"
 
270
 
 
271
PHONE_NUMBER_DESCRIPTIONS = (HOME_PHONE_NUMBER,
 
272
    MOBILE_PHONE_NUMBER,
 
273
    HOME_FAX_NUMBER,
 
274
    WORK_PHONE_NUMBER,
 
275
    CAR_PHONE_NUMBER,
 
276
    PAGER_PHONE_NUMBER,
 
277
    WORK_FAX_PHONE_NUMBER,
 
278
    ASSISTANT_PHONE_NUMBER,
 
279
    CALLBACK_PHONE_NUMBER,
 
280
    COMPANY_PHONE_NUMBER,
 
281
    OTHER_PHONE_NUMBER,
 
282
    OTHER_FAX_PHONE_NUMBER,
 
283
    PRIMARY_PHONE_NUMBER,
 
284
    TELEX_PHONE_NUMBER, )
 
285
 
 
286
class TelephoneNumber(ContactData):
 
287
    """
 
288
    Represents a telephone in the address book.
 
289
    """
 
290
 
 
291
    _attributes = ("number", "description", )
 
292
 
 
293
    _description_enum = PHONE_NUMBER_DESCRIPTIONS
 
294
 
 
295
    def __init__(self, number=None, description=None):
 
296
        """
 
297
        Creates a new number to be used in the system.
 
298
        """
 
299
        ContactData.__init__(self, description=description)
 
300
        self.number = number
 
301
 
 
302
###############################################################################
 
303
############################ Url implementation ###############################
 
304
###############################################################################
 
305
 
 
306
HOME_PAGE_URL = "home page"
 
307
BLOG_URL = "blog"
 
308
URL_DESCRIPTIONS = (HOME_PAGE_URL, BLOG_URL, )
 
309
 
 
310
class Url(ContactData):
 
311
    """
 
312
    Represents a url in the system that can be added in API.
 
313
    """
 
314
 
 
315
    _attributes = ("url", "description", )
 
316
 
 
317
    _description_enum = URL_DESCRIPTIONS
 
318
 
 
319
    def __init__(self, url=None, description=None):
 
320
        """
 
321
        @type url: string
 
322
        @param url: The url of the webage.
 
323
        @type description: string
 
324
        @param description: A useful description about the webpage/url
 
325
 
 
326
        Creates a new instance of the object.
 
327
        """
 
328
        ContactData.__init__(self, description=description)
 
329
        self.url = url