public static void SyncContact(ContactMatch match, Syncronizer sync) { if (match.GoogleContact == null && match.OutlookContact != null) { //no google contact //TODO: check SyncOption //TODO: found that when a contacts doesn't have anything other that the name - it's not returned in the google contacts list. Outlook.UserProperty idProp = match.OutlookContact.UserProperties[sync.OutlookPropertyNameId]; if (idProp != null && (string)idProp.Value != "") { AtomId id = new AtomId((string)idProp.Value); ContactEntry matchingGoogleContact = sync.GoogleContacts.FindById(id) as ContactEntry; if (matchingGoogleContact == null) { //TODO: make sure that outlook contacts don't get deleted when deleting corresponding google contact when testing. //solution: use ResetMatching() method to unlink this relation //sync.ResetMatches(); return; } } //create a Google contact from Outlook contact match.GoogleContact = new ContactEntry(); ContactSync.UpdateContact(match.OutlookContact, match.GoogleContact); sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact); } else if (match.OutlookContact == null && match.GoogleContact != null) { // no outlook contact string outlookId = ContactPropertiesUtils.GetGoogleOutlookContactId(sync.SyncProfile, match.GoogleContact); if (outlookId != null) { //TODO: make sure that google contacts don't get deleted when deleting corresponding outlook contact when testing. //solution: use ResetMatching() method to unlink this relation //sync.ResetMatches(); return; } //TODO: check SyncOption //create a Outlook contact from Google contact match.OutlookContact = sync.OutlookApplication.CreateItem(Outlook.OlItemType.olContactItem) as Outlook.ContactItem; ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact); sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact); } else if (match.OutlookContact != null && match.GoogleContact != null) { //merge contact details //TODO: check if there are multiple matches if (match.AllGoogleContactMatches.Count > 1) { //loop from 2-nd item for (int m = 1; m < match.AllGoogleContactMatches.Count; m++) { ContactEntry entry = match.AllGoogleContactMatches[m]; try { Outlook.ContactItem item = sync.OutlookContacts.Find("[" + sync.OutlookPropertyNameId + "] = \"" + entry.Id.Uri.Content + "\"") as Outlook.ContactItem; //Outlook.ContactItem item = sync.OutlookContacts.Find("[myTest] = \"value\"") as Outlook.ContactItem; if (item != null) { //do something } } catch (Exception) { //TODO: should not get here. } } //TODO: add info to Outlook contact from extra Google contacts before deleting extra Google contacts. for (int m = 1; m < match.AllGoogleContactMatches.Count; m++) { match.AllGoogleContactMatches[m].Delete(); } } //determine if this contact pair were syncronized //DateTime? lastUpdated = GetOutlookPropertyValueDateTime(match.OutlookContact, sync.OutlookPropertyNameUpdated); DateTime?lastSynced = GetOutlookPropertyValueDateTime(match.OutlookContact, sync.OutlookPropertyNameSynced); if (lastSynced.HasValue) { //contact pair was syncronysed before. //determine if google contact was updated since last sync //lastSynced is stored without seconds. take that into account. DateTime lastUpdatedOutlook = match.OutlookContact.LastModificationTime.AddSeconds(-match.OutlookContact.LastModificationTime.Second); DateTime lastUpdatedGoogle = match.GoogleContact.Updated.AddSeconds(-match.GoogleContact.Updated.Second); //check if both outlok and google contacts where updated sync last sync if (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds >= TimeTolerance && lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds >= TimeTolerance) { //both contacts were updated. //options: 1) ignore 2) loose one based on SyncOption //throw new Exception("Both contacts were updated!"); switch (sync.SyncOption) { case SyncOption.MergeOutlookWins: //overwrite google contact ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact); sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact); break; case SyncOption.MergeGoogleWins: //overwrite outlook contact ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact); sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact); break; case SyncOption.MergePrompt: //promp for sync option ConflictResolver r = new ConflictResolver(); ConflictResolution res = r.Resolve(match.OutlookContact, match.GoogleContact); switch (res) { case ConflictResolution.Cancel: break; case ConflictResolution.OutlookWins: //TODO: what about categories/groups? ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact); sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact); break; case ConflictResolution.GoogleWins: //TODO: what about categories/groups? ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact); sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact); break; default: break; } break; case SyncOption.GoogleToOutlookOnly: ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact); sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact); break; case SyncOption.OutlookToGoogleOnly: ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact); sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact); break; } return; } //check if outlook contact was updated (with X second tolerance) if (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds >= TimeTolerance) { //outlook contact was changed //merge contacts. if (sync.SyncOption != SyncOption.GoogleToOutlookOnly) { //TODO: use UpdateContact instead? ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact); sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact); //at the moment use outlook as "master" source of contacts - in the event of a conflict google contact will be overwritten. //TODO: control conflict resolution by SyncOption return; } } //check if google contact was updated (with X second tolerance) if (lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds >= TimeTolerance) { //google contact was updated //update outlook contact if (sync.SyncOption != SyncOption.OutlookToGoogleOnly) { ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact); sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact); } } } else { //contacts were never synced. //merge contacts. switch (sync.SyncOption) { case SyncOption.MergeOutlookWins: //overwrite google contact ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact); sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact); break; case SyncOption.MergeGoogleWins: //overwrite outlook contact ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact); sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact); break; case SyncOption.MergePrompt: //promp for sync option ConflictResolver r = new ConflictResolver(); ConflictResolution res = r.Resolve(match.OutlookContact, match.GoogleContact); switch (res) { case ConflictResolution.Cancel: break; case ConflictResolution.OutlookWins: ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact); sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact); break; case ConflictResolution.GoogleWins: ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact); sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact); break; default: break; } break; case SyncOption.GoogleToOutlookOnly: ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact); sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact); break; case SyncOption.OutlookToGoogleOnly: ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact); sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact); break; } } } else { throw new ArgumentNullException("ContactMatch has all peers null."); } }
public void SaveContact(ContactMatch match) { if (match.GoogleContact != null && match.OutlookContact != null) { //bool googleChanged, outlookChanged; //SaveContactGroups(match, out googleChanged, out outlookChanged); if (match.GoogleContact.IsDirty() || !match.OutlookContact.Saved) { _syncedCount++; } if (match.GoogleContact.IsDirty())// || googleChanged) { //google contact was modified. save. SaveGoogleContact(match); if (Logger != null) { Logger.Log("Saved Google contact: \"" + match.GoogleContact.Title.Text + "\"", EventType.Information); } } if (!match.OutlookContact.Saved)// || outlookChanged) { match.OutlookContact.Save(); ContactPropertiesUtils.SetGoogleOutlookContactId(SyncProfile, match.GoogleContact, match.OutlookContact); ContactEntry updatedEntry = match.GoogleContact.Update() as ContactEntry; match.GoogleContact = updatedEntry; ContactPropertiesUtils.SetOutlookGoogleContactId(this, match.OutlookContact, match.GoogleContact); match.OutlookContact.Save(); if (Logger != null) { Logger.Log("Saved Outlook contact: \"" + match.OutlookContact.FileAs + "\"", EventType.Information); } //TODO: this will cause the google contact to be updated on next run because Outlook's contact will be marked as saved later that Google's contact. } // save photos SaveContactPhotos(match); } else if (match.GoogleContact == null && match.OutlookContact != null) { if (ContactPropertiesUtils.GetOutlookGoogleContactId(this, match.OutlookContact) != null && _syncDelete) { _deletedCount++; string name = match.OutlookContact.FileAs; // peer google contact was deleted, delete outlook contact match.OutlookContact.Delete(); if (Logger != null) { Logger.Log("Deleted Outlook contact: \"" + name + "\"", EventType.Information); } } } else if (match.GoogleContact != null && match.OutlookContact == null) { if (ContactPropertiesUtils.GetGoogleOutlookContactId(SyncProfile, match.GoogleContact) != null && _syncDelete) { _deletedCount++; // peer outlook contact was deleted, delete google contact match.GoogleContact.Delete(); if (Logger != null) { Logger.Log("Deleted Google contact: \"" + match.GoogleContact.Title.Text + "\"", EventType.Information); } } } else { //TODO: ignore for now: throw new ArgumentNullException("To save contacts both ContactMatch peers must be present."); if (Logger != null) { Logger.Log("Both Google and Outlook contact: \"" + match.GoogleContact.Title.Text + "\" have been changed! Not implemented yet.", EventType.Warning); } } }