1 import org.maemo.hermes.engine.service
3 from org.maemo.hermes.engine.names import canonical
5 class Service(org.maemo.hermes.engine.service.Service):
6 """Facebook backend for Hermes.
8 Copyright (c) Andrew Flegg <andrew@bleb.org> 2010.
9 Copyright (c) Fredrik Wendt <fredrik@wendt.se> 2010.
10 Released under the Artistic Licence."""
12 attrs = ['uid', 'name', 'pic_big', 'birthday_date', 'profile_url', 'first_name', 'last_name', 'website']
14 # -----------------------------------------------------------------------
15 def __init__(self, facebook, autocreate = False, gui_callback = None):
16 """Initialise the Facebook service, finding Facebook API keys in gconf and
17 having a gui_callback available."""
19 self._gui = gui_callback
20 self._autocreate = autocreate
23 self._friends_by_id = {}
24 self._friends_by_url = {}
25 self._friends_by_contact = {}
26 self._contacts_by_friend = {}
27 self._friends_without_contact = set()
28 self._known_urls = set()
31 # -----------------------------------------------------------------------
36 # -----------------------------------------------------------------------
37 def get_friends(self):
38 return self._contacts_by_friend.keys()
41 def get_contacts_with_match(self):
42 return self._friends_by_contact
44 def get_unmatched_friends(self):
45 return self._friends_by_id.values()
47 # -----------------------------------------------------------------------
48 def pre_process_contact(self, contact):
49 """Registers URLs of all previous mappings, and makes sure that any Friends with those
50 URLs don't get match by name."""
51 for url in contact.get_urls():
52 self._known_urls.add(url)
55 # -----------------------------------------------------------------------
56 def process_friends(self):
58 def if_defined(data, key, callback):
59 if key in data and data[key]:
62 friends_data = self._get_friends_data()
63 for data in friends_data:
64 key = canonical(data['name']) # FIXME: deal with name collision
65 friend = self._create_friend(data['name'])
67 if 'profile_url' not in data:
68 data['profile_url'] = "http://www.facebook.com/profile.php?id=" + str(data['uid'])
70 if_defined(data, 'website', friend.add_url)
71 if_defined(data, 'profile_url', friend.add_url)
72 if_defined(data, 'birthday_date', friend.set_birthday_date)
74 if_defined(data, 'pic_big', friend.set_photo_url)
76 if friend.has_birthday_date(): # FIXME: remove this, either you want to add your contacts or not?
77 self._friends_without_contact.add(friend)
78 url = data['profile_url']
79 self._friends_by_url[url] = friend
81 if url not in self._known_urls:
82 self._friends_by_id[key] = friend
84 # -----------------------------------------------------------------------
85 def process_contact(self, contact):
86 if self._friends_by_contact.has_key(contact):
90 # we might get a hit if the friend has setup a URL with another service,
91 # such as putting the id link to Facebook on the Twitter account's profile
92 for url in contact.get_urls():
93 if url in self._friends_by_url:
94 matched_friend = self._friends_by_url[url]
95 self._register_match(contact, matched_friend)
96 print contact.get_name(), " -> match by url -> ", matched_friend
99 if not matched_friend:
100 for id in contact.get_identifiers():
101 if id in self._friends_by_id:
102 matched_friend = self._friends_by_id.pop(id)
103 self._register_match(contact, matched_friend)
104 print contact.get_name(), " -> match by name -> ", matched_friend
108 # -----------------------------------------------------------------------
109 def _register_match(self, contact, friend):
110 self._friends_without_contact.discard(friend)
111 self._friends_by_contact[contact] = friend
112 self._contacts_by_friend[friend] = contact
114 # -----------------------------------------------------------------------
115 def _get_friends_data(self):
116 """Returns a list of dicts, where each dict represents a friend/contact"""
118 return self.fb.users.getInfo(self.fb.friends.get(), Service.attrs)