-import org.maemo.hermes.engine.service
-
-import twitter
from org.maemo.hermes.engine.names import canonical
+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."""
-
- self._gui = gui_callback
- self._username = username
- self._password = password
+ def __init__(self, service_id, twitterApi):
+ org.maemo.hermes.engine.service.Service.__init__(self, service_id)
+
+ self._twitter = twitterApi
- self._friends = None
+ self._friends_by_name = {}
self._friends_by_url = {}
+ self._friends_by_contact = {}
+ self._friends = []
+ self._known_urls = set()
+
+
+ # -----------------------------------------------------------------------
+ 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 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 = {'name': tweeter.name, 'pic': tweeter.profile_image_url,
- 'birthday_date': None, 'profile_url': url,
- 'homepage': tweeter.url, 'account': 'twitter'}
- if friend['pic'].find('/default_profile') > -1:
- friend['pic'] = None
+ 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 process_contact(self, contact, overwrite = False, friend = None):
- """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()
-
- matched_friend = None
- for url in contact.get_urls():
- if url in self._friends_by_url:
- matched_friend = self._friends_by_url[url]
- break
-
- if not matched_friend:
- for id in contact.get_identifiers():
- if id in self._friends:
- matched_friend = self._friends[id]
- break
-
- if matched_friend:
- print contact.get_name(), " -> ", matched_friend['profile_url']
- else:
- print contact.get_name(), " no match to Twitter with ", contact.get_identifiers()
-
+ def process_contact(self, contact):
+ if self._friends_by_contact.has_key(contact) or \
+ self._match_contact_to_friend_by_urls(contact) or \
+ self._match_contact_to_friend_by_identifiers(contact):
+ return self._get_friend_by_contact(contact)
+
+ return None
# -----------------------------------------------------------------------
- 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 _get_friend_by_contact(self, contact):
+ return self._friends_by_contact[contact]
+
+
+ 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)
+ 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]
+ self._register_match(contact, matched_friend)
+ return True
+
+ return False
+
+
+ def _register_match(self, contact, friend):
+ friend.set_contact(contact)
+ self._friends_by_contact[contact] = friend
+ self._friends.remove(friend)
+