Add support for creating contacts from "interesting" friends on LinkedIn. Completes...
[hermes] / package / src / org / maemo / hermes / engine / friend.py
1 class Friend():
2     """Encapsulate the data from a remote service.
3     
4        Copyright (c) Fredrik Wendt <fredrik@wendt.se> 2010.
5        Released under the Artistic Licence."""
6
7     
8     def __init__(self, name=None, source=None, props=None):
9         """ source is source service, such as LinkedIn """
10         self._attributes = {};
11         if name: self._set('fn', name)
12         self._multi_attributes = {}
13         self._source = source
14         if props:
15             for key in props:
16                 self._set(key, props[key])
17         
18     def __getitem__(self, key):
19         return self._safe_get(key)
20                               
21     def __unicode__(self):
22         return self.__repr__()
23     
24     def __repr__(self):
25         return "Friend %s" % self.get_name()
26     
27     # public accessors -----------------
28         
29     def is_interesting(self):
30         """A friend is interesting if there's more info than URLs
31            and photos."""
32         return self._attributes.has_key('bday') or self._multi_attributes.has_key('phone')
33
34     def add_url(self, url):
35         if url:
36             if not isinstance(url, basestring):
37                 print url
38                 raise Exception('Not valid to add non-string URLs')
39             self._add('url', url)
40     
41     def add_phone(self, phone):
42         if phone:
43             self._add('phone', phone)
44         
45     def get_birthday_date(self):
46         return self._safe_get('bday')
47     
48     def get_contact(self):
49         return self._safe_get('contact')
50     
51     def get_name(self):
52         return self._safe_get('fn')
53     
54     def get_source(self):
55         return self._source
56     
57     def set_source(self, source):
58         self._source = source
59     
60     def get_nickname(self):
61         return self._safe_get("nickname")
62     
63     def get_urls(self):
64         try: return self._multi_attributes['url'] 
65         except: return []
66     
67     def get_phones(self):
68         try: return self._multi_attributes['phone'] 
69         except: return []
70         
71     def get_photo_url(self):
72         return self._safe_get('photo-url')
73     
74     def has_birthday_date(self):
75         return self._has('bday')
76     
77     def is_empty(self):
78         for a in self._attributes:
79             return False
80         for a in self._multi_attributes:
81             return False
82         return True
83     
84     def set_name(self, name):
85         self._set('fn', name)
86     
87     def set_nickname(self, nickname):
88         self._set('nickname', nickname)
89         
90     def set_birthday_date(self, date):
91         self._set('bday', date)
92         
93     def set_contact(self, contact):
94         self._set('contact', contact)
95         
96     def set_photo_url(self, url):
97         self._set('photo-url', url)
98     
99     def update_from_friend(self, other_friend, overwrite=False):
100         """
101         Overwrites any attributes in this friend, with attributes from other_friend
102         """
103         
104         self._attributes.update(other_friend._attributes)
105         
106         for key in other_friend._multi_attributes.keys():
107             for value in other_friend._multi_attributes[key]:
108                 self._add(key, value)
109      
110     def update_contact(self, contact, overwrite=False):
111         """Updates the contact with information from this object,
112            without overwriting unless overwrite is set to True.
113            Returns flag indicating if anything *was* changed."""
114         
115         def set_birthday(arg):
116             # Hackily assumes Facebook format (mm/d[/y])
117             date_str = arg.split('/')
118             date_str.append('0')
119             return contact.set_birthday(int(date_str[1]),
120                                         int(date_str[0]),
121                                         int(date_str[2]))
122
123         updated = False
124         if overwrite or contact.get_photo() is None:    updated += self._if_defined('photo-url', contact.set_photo)
125         if overwrite or contact.get_nickname() is None: updated += self._if_defined('nickname', contact.set_nickname)
126         if overwrite or contact.get_birthday() is None: updated += self._if_defined('bday', set_birthday)
127         if self._multi_attributes.has_key('url'):
128             for url in self._multi_attributes['url']:
129                 updated += contact.add_url(url)
130
131         if self._multi_attributes.has_key('phone'):
132             for phone in self._multi_attributes['phone']:
133                 updated += contact.add_phone(phone)
134                 
135         return updated
136
137
138     # private helpers -----------------------
139     #
140     def _add(self, key, value):
141         if value is not None:
142             if not self._multi_attributes.has_key(key):
143                 self._multi_attributes[key] = []
144 #            print "%s ADD %s to %s" % (self, key, value)
145             self._multi_attributes[key].append(value)
146     
147     def _contains(self, key, value):
148         if self._attributes.has_key(key):
149             return value == self._attributes[key]
150         if self._multi_attributes.has_key(key):
151             return value in self._multi_attributes[key]
152         return False
153     
154     def _if_defined(self, key, callback):
155         return self._attributes.has_key(key) and callback(self._attributes[key]) or False
156     
157     def _has(self, key):
158         return self._attributes.has_key(key) or self._multi_attributes.has_key(key)
159     
160     def _safe_get(self, key):
161         try: return self._attributes[key]
162         except: return None
163         
164     def _set(self, key, value):
165         if value is not None:
166             print u"%s SET %s to %s" % (self, key, value)
167             self._attributes[key] = value
168         else:
169             print u"%s not setting %s to undefined value" % (self, key)
170