from org.maemo.hermes.engine.friend import Friend
+from org.maemo.hermes.engine.contact import Contact
import evolution
class Hermes:
# -----------------------------------------------------------------------
- def __init__(self, services, gui_progress):
- """Constructor. Passed a list of services, and a callback method
- which must implement the following API.
-
- progress(i, j) - the application is currently processing friend 'i' of
- 'j'. Should be used to provide the user a progress bar.
- """
+ def __init__(self, services, gui_progress=None):
+ """Constructor. Passed a list of services, and a
+ method which will be invoked with three arguments:
+ str Name of current step
+ int Current position
+ int Maximum value of position."""
+
# -- These fields are currently part of the API...
#
self.matched = []
self.unmatched = []
self.friends = {}
- self.addresses = None
+ self.address_book = None
# -- Other initialisation...
#
self._services = services
- self._progress = gui_progress
+ self._progress = gui_progress or (lambda msg, i, j: None)
# -----------------------------------------------------------------------
- def run(self, resync=False):
- """Load information on the authenticated user's friends. Synchronise Facebook
- profiles to contact database. If resync is false, no existing information
- will be overwritten."""
+ def run(self, overwrite_existing_fields=False):
+ self._progress("Reading contacts...", 1, 10000)
+
+ contacts = []
+ self.address_book = self._get_address_book()
+ for contact in self.address_book.get_all_contacts():
+ contacts.append(Contact(self.address_book, contact))
- class FakeContact():
- def get_name(self):
- return "Fredrik Wendt"
- def get_emails(self):
- return ["fredrik@wendt.se", "maemohermes@wendt.se"]
- def get_photo(self):
- return None
- self.matched = [FakeContact()]
-
-# self._sync_job = SyncJob(services, [FakeContact()], self.progress)
-# self._sync_job.run()
-# self._sync_job.get_unmatched_friends()
-# self._sync_job.get_updated_contacts()
-# self._sync_job.get_matched_contacts()
- pass
-
-
- # -----------------------------------------------------------------------
- def run_alt(self, overwrite_existing_fields=False):
- print "+++ Syncing contacts..."
- self.addresses = evolution.ebook.open_addressbook('default')
- print "+++ Contact store created..."
- contacts = self.addresses.get_all_contacts()
+ # work out progress bar info
+ total_contacts = len(contacts) * len(self._services)
+ total_ticks = 6 * total_contacts # Number of distinct loops below
# warm up
+ current_tick = 1
for service in self._services:
+ print "pre-process:", service.get_id()
for contact in contacts:
+ self._progress("Pre-processing contacts...", current_tick, total_ticks)
+ current_tick += 1
service.pre_process_contact(contact)
# fetch data
for service in self._services:
+ print "process_friends:", service.get_id()
+ self._progress("Reading friends...", current_tick, total_ticks)
+ current_tick += len(contacts)
service.process_friends()
# combine results into one friend
for contact in contacts:
result = Friend()
for service in self._services:
+ print "process_contact:", service.get_id()
+ self._progress("Processing contacts...", current_tick, total_ticks)
+ current_tick += 1
friend = service.process_contact(contact)
- if (friend):
- friend.decorate(result)
+ if friend:
+ contact.add_mapping(service.get_id())
+ friend.update_friend(result)
+
+ if result.get_name() is not None:
+ self.update_contact(result, overwrite_existing_fields)
+ else:
+ self.unmatched.append(contact)
- self.update_contact(friend, overwrite_existing_fields)
+ # give services a chance to create new contacts
+ for service in self._services:
+ print "create_contacts:", service.get_id()
+ to_create = service.get_friends_to_create_contacts_for()
+ tick_increment = len(contacts) / (len(to_create) or 1)
+ print tick_increment, to_create
+ for friend in to_create:
+ self._progress("Creating contacts...", current_tick, total_ticks)
+ current_tick += tick_increment
+ self.create_contact_from_friend(friend)
+
+ # finalisation
+ for service in self._services:
+ print "finalize:", service.get_id()
+ self._progress("Finalising...", current_tick, total_ticks)
+ current_tick += len(contacts)
+ service.finalise(self.updated, overwrite_existing_fields)
+
+ # commit changes
+ tick_increment = total_contacts / (len(self.updated) or 1)
+ print tick_increment, self.updated
+ for contact in self.updated:
+ print "committing changes to:", contact.get_name(), contact
+ self._progress("Saving changes...", current_tick, total_ticks)
+ current_tick += tick_increment
+ self.address_book.commit_contact(contact.get_econtact())
+
+ self._progress('Finished', 1, -1)
# -----------------------------------------------------------------------
"""Update the given contact with information from the given friend."""
print "updating contact ", contact, " with friend ", friend
+ self.updated.append(contact)
+ self.matched.append(contact)
+ if friend.get_source() is not None:
+ contact.add_mapping(friend.get_source())
+ # -----------------------------------------------------------------------
def create_contact_from_friend(self, friend):
- contact = evolution.ebook.EContact()
- contact.props.full_name = friend['name']
- contact.props.given_name = friend['first_name']
- contact.props.family_name = friend['last_name']
-
+ econtact = evolution.ebook.EContact()
+ econtact.props.full_name = friend['name']
+ econtact.props.given_name = friend['first_name']
+ econtact.props.family_name = friend['last_name']
+ contact = Contact(self.address_book, econtact)
+
+ self.address_book.add_contact(contact.get_econtact())
self.update_contact(contact, friend)
- self.addresses.add_contact(contact)
- self.updated.append(contact)
- self.addresses.commit_contact(contact)
-
print "Created [%s]" % (contact.get_name())
- self.matched.append(contact)
-
-
- def commit(self):
- self.store.close()
+
+
+ # -----------------------------------------------------------------------
+ def _get_address_book(self):
+ return evolution.ebook.open_addressbook('default')