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