1 from org.maemo.hermes.engine.friend import Friend
2 from org.maemo.hermes.engine.contact import Contact
6 """Encapsulate the process of syncing online friends' information with the
7 Evolution contacts' database. This should be used as follows:
9 * Initialise, passing in a GUI callback.
11 * Retrieve information on changes effected.
12 * Call update_contact to enact manual mapping.
14 Copyright (c) Andrew Flegg <andrew@bleb.org> 2010.
15 Released under the Artistic Licence."""
18 # -----------------------------------------------------------------------
19 def __init__(self, services, gui_progress=None):
20 """Constructor. Passed a list of services, and a
21 method which will be invoked with three arguments:
22 str Name of current step
24 int Maximum value of position."""
27 # -- These fields are currently part of the API...
33 self.address_book = None
35 # -- Other initialisation...
37 self._services = services
38 self._progress = gui_progress or (lambda msg, i, j: None)
41 # -----------------------------------------------------------------------
42 def run(self, overwrite_existing_fields=False):
43 self._progress("Reading contacts...", 1, 10000)
46 self.address_book = self._get_address_book()
47 for econtact in self.address_book.get_all_contacts():
48 contacts.append(self._create_contact_wrapper(econtact))
50 # work out progress bar info
51 total_contacts = len(contacts) * len(self._services)
52 total_ticks = 6 * total_contacts # Number of distinct loops below
56 for service in self._services:
57 print "pre-process:", service.get_id()
58 for contact in contacts:
59 self._progress("Pre-processing contacts...", current_tick, total_ticks)
61 service.pre_process_contact(contact)
64 for service in self._services:
65 print "process_friends:", service.get_id()
66 self._progress("Reading friends...", current_tick, total_ticks)
67 current_tick += len(contacts)
68 service.process_friends()
70 # combine results into one friend
71 for contact in contacts:
73 for service in self._services:
74 print "process_contact:", service.get_id()
75 self._progress("Processing contacts...", current_tick, total_ticks)
77 friend = service.process_contact(contact)
79 contact.add_mapping(service.get_id())
80 result.update_from_friend(friend)
82 if result.get_name() is not None:
83 self.update_contact(contact, result, overwrite_existing_fields)
85 self.unmatched.append(contact)
87 # give services a chance to create new contacts
88 for service in self._services:
89 print "create_contacts:", service.get_id()
90 to_create = service.get_friends_to_create_contacts_for()
91 tick_increment = len(contacts) / (len(to_create) or 1)
92 print tick_increment, to_create
93 for friend in to_create:
94 friend.set_source(service.get_id())
95 self._progress("Creating contacts...", current_tick, total_ticks)
96 current_tick += tick_increment
97 self.create_contact_from_friend(friend)
100 for service in self._services:
101 print "finalize:", service.get_id()
102 self._progress("Finalising...", current_tick, total_ticks)
103 current_tick += len(contacts)
104 service.finalise(self.updated, overwrite_existing_fields)
105 for friend in service.get_unmatched_friends():
106 friend.set_source(service.get_id())
107 key = unicode(friend.get_name()).encode('trans') + "_" + service.get_id()
108 self.friends[key] = friend
111 tick_increment = total_contacts / (len(self.updated) or 1)
112 print tick_increment, self.updated
113 for contact in self.updated:
114 print "committing changes to:", contact.get_name(), contact
115 self._progress("Saving changes...", current_tick, total_ticks)
116 current_tick += tick_increment
117 self.address_book.commit_contact(contact.get_econtact())
119 self._progress('Finished', 1, -1)
122 # -----------------------------------------------------------------------
123 def update_contact(self, contact, friend, resync=False, commit=False):
124 """Update the given contact with information from the given friend."""
126 print "updating contact ", contact, " with friend ", friend
127 if friend.update_contact(contact, resync):
128 self.updated.append(contact)
130 self.address_book.commit_contact(contact.get_econtact())
132 self.matched.append(contact)
133 if friend.get_source() is not None:
134 contact.add_mapping(friend.get_source())
137 # -----------------------------------------------------------------------
138 def create_contact_from_friend(self, friend):
139 econtact = self._create_empty_contact(friend)
140 contact = self._create_contact_wrapper(econtact)
142 self.address_book.add_contact(contact.get_econtact())
143 self.update_contact(contact, friend)
145 print "Created [%s]" % (contact.get_name())
148 # -----------------------------------------------------------------------
149 def _get_address_book(self):
150 return evolution.ebook.open_addressbook('default')
152 # -----------------------------------------------------------------------
153 def _create_empty_contact(self, friend):
154 econtact = evolution.ebook.EContact()
155 econtact.props.given_name = friend['first_name']
156 econtact.props.family_name = friend['last_name']
157 econtact.props.full_name = friend.get_name()
160 # -----------------------------------------------------------------------
161 def _create_contact_wrapper(self, econtact):
162 return Contact(self.address_book, econtact)