-import org.maemo.hermes.engine.service
-
-import twitter
from org.maemo.hermes.engine.names import canonical
-from org.maemo.hermes.engine.friend import Friend
+import org.maemo.hermes.engine.service
class Service(org.maemo.hermes.engine.service.Service):
"""Twitter backend for Hermes.
Copyright (c) Andrew Flegg <andrew@bleb.org> 2010.
+ Copyright (c) Fredrik Wendt <fredrik@wendt.se> 2010.
Released under the Artistic Licence."""
# -----------------------------------------------------------------------
- def __init__(self, username, password, gui_callback = None):
- """Initialise the Twitter service, using the given credentials and
- having a gui_callback available."""
+ def __init__(self, twitterApi):
+ self._twitter = twitterApi
- self._gui = gui_callback
- self._username = username
- self._password = password
-
- self._friends = None
+ self._friends_by_name = {}
self._friends_by_url = {}
self._friends_by_contact = {}
+ self._friends = []
+ self._known_urls = set()
# -----------------------------------------------------------------------
# -----------------------------------------------------------------------
- def get_friends(self):
- """Return a list of friends from this service, or 'None' if manual mapping
- is not supported."""
-
- if self._friends:
- return self._friends.values()
-
- self._friends = {}
-
- api = twitter.Api(username=self._username, password=self._password)
- for tweeter in api.GetFriends():
- key = canonical(tweeter.name)
- url = 'http://twitter.com/%s' % (tweeter.screen_name)
- friend = Friend(tweeter.name)
+ def pre_process_contact(self, contact):
+ """Registers URLs of all previous mappings, and makes sure that any Friends with those
+ URLs don't get match by name."""
+ for url in contact.get_urls():
+ self._known_urls.add(url)
+
+
+ # -----------------------------------------------------------------------
+ def process_friends(self):
+ for tweeter in self._get_tweeters():
+ key = canonical(tweeter.name)
+ url = 'http://twitter.com/%s' % (tweeter.screen_name)
+ friend = self._create_friend(tweeter.name)
friend.set_nickname(tweeter.screen_name)
friend.add_url(url)
friend.add_url(tweeter.url)
if '/default_profile' not in tweeter.profile_image_url:
friend.set_photo_url(tweeter.profile_image_url)
- self._friends[key] = friend
+ self._friends.append(friend)
self._friends_by_url[url] = friend
-
- return self._friends.values()
+ if url not in self._known_urls:
+ self._friends_by_name[key] = friend
# -----------------------------------------------------------------------
- def pre_process_contact(self, contact):
- if not self._friends:
- self.get_friends()
-
- for url in contact.get_urls():
- if url in self._friends_by_url:
- matched_friend = self._friends_by_url[url]
- self._friends_by_contact[contact] = matched_friend
-
-
- # -----------------------------------------------------------------------
- def process_contact(self, contact, friend):
- """Called for each contact in the address book. Any friends linked to
- from the contact should have their matching updated. The backend should
- enrich the contact with any meta-data it can; and return 'True' if any
- information was updated. If 'friend' is provided, the information should
- be retrieved from friend. This will be one of the entries from
- 'get_friends' when manual mapping is being done."""
-
- if not self._friends:
- self.get_friends()
-
+ def process_contact(self, contact):
if self._friends_by_contact.has_key(contact):
- friend.update(self._friends_by_contact[contact])
return
- for id in contact.get_identifiers():
- if id in self._friends:
- matched_friend = self._friends[id]
- print contact.get_name(), " -> ", matched_friend
- if matched_friend in self._friends_by_contact.values():
- print "COLLISSION avoided for %s" % friend
- else:
- print "Match found %s" % friend
- self._friends_by_contact[contact] = matched_friend
- friend.update(matched_friend)
-
+ if self._match_contact_to_friend_by_urls(contact):
+ return
+
+ self._match_contact_to_friend_by_identifiers(contact)
# -----------------------------------------------------------------------
- def finalise(self, updated, overwrite = False):
- """Once all contacts have been processed, allows for any tidy-up/additional
- enrichment. If any contacts are updated at this stage, 'updated' should
- be added to."""
-
+ def finalise(self, updated, overwrite=False):
pass
+
+
+ # -----------------------------------------------------------------------
+ def get_contacts_with_match(self):
+ return self._friends_by_contact
+
+
+ # -----------------------------------------------------------------------
+ def get_unmatched_friends(self):
+ return self._friends
+
+
+ # -----------------------------------------------------------------------
+ def _get_tweeters(self):
+ return self._twitter.GetFriends()
+
+
+ def _match_contact_to_friend_by_urls(self, contact):
+ for url in contact.get_urls():
+ if url in self._friends_by_url:
+ matched_friend = self._friends_by_url[url]
+ self._register_match(contact, matched_friend)
+ print contact.get_name(), " -> url -> ", matched_friend
+ return True
+
+ return False
+
+
+ def _match_contact_to_friend_by_identifiers(self, contact):
+ for id in contact.get_identifiers():
+ if id in self._friends_by_name:
+ matched_friend = self._friends_by_name[id]
+ print contact.get_name(), " -> name -> ", matched_friend
+ self._register_match(contact, matched_friend)
+ return True
+
+ return False
+
+
+ def _register_match(self, contact, friend):
+ self._friends_by_contact[contact] = friend
+ self._friends.remove(friend)
+