2 """Encapsulate the data from a remote service.
4 Copyright (c) Fredrik Wendt <fredrik@wendt.se> 2010.
5 Released under the Artistic Licence."""
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 = {}
16 self._set(key, props[key])
18 def __getitem__(self, key):
19 return self._safe_get(key)
21 def __unicode__(self):
22 return self.__repr__()
25 return "Friend %s" % self.get_name()
27 # public accessors -----------------
29 def is_interesting(self):
30 """A friend is interesting if there's more info than URLs
32 return self._attributes.has_key('bday') or self._multi_attributes.has_key('phone')
34 def add_url(self, url):
36 if not isinstance(url, basestring):
38 raise Exception('Not valid to add non-string URLs')
41 def add_phone(self, phone):
43 self._add('phone', phone)
45 def get_birthday_date(self):
46 return self._safe_get('bday')
48 def get_contact(self):
49 return self._safe_get('contact')
52 return self._safe_get('fn')
57 def set_source(self, source):
60 def get_nickname(self):
61 return self._safe_get("nickname")
64 try: return self._multi_attributes['url']
68 try: return self._multi_attributes['phone']
71 def get_photo_url(self):
72 return self._safe_get('photo-url')
74 def has_birthday_date(self):
75 return self._has('bday')
78 for a in self._attributes:
80 for a in self._multi_attributes:
84 def set_name(self, name):
87 def set_nickname(self, nickname):
88 self._set('nickname', nickname)
90 def set_birthday_date(self, date):
91 self._set('bday', date)
93 def set_contact(self, contact):
94 self._set('contact', contact)
96 def set_photo_url(self, url):
97 self._set('photo-url', url)
99 def update_from_friend(self, other_friend, overwrite=False):
101 Overwrites any attributes in this friend, with attributes from other_friend
104 self._attributes.update(other_friend._attributes)
106 for key in other_friend._multi_attributes.keys():
107 for value in other_friend._multi_attributes[key]:
108 self._add(key, value)
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."""
115 def set_birthday(arg):
116 # Hackily assumes Facebook format (mm/d[/y])
117 date_str = arg.split('/')
119 return contact.set_birthday(int(date_str[1]),
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)
131 if self._multi_attributes.has_key('phone'):
132 for phone in self._multi_attributes['phone']:
133 updated += contact.add_phone(phone)
138 # private helpers -----------------------
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)
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]
154 def _if_defined(self, key, callback):
155 return self._attributes.has_key(key) and callback(self._attributes[key]) or False
158 return self._attributes.has_key(key) or self._multi_attributes.has_key(key)
160 def _safe_get(self, key):
161 try: return self._attributes[key]
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
169 print u"%s not setting %s to undefined value" % (self, key)