public void SaveContacts(ContactMatchList contacts) { foreach (ContactMatch match in contacts) { try { SaveContact(match); } catch (Exception ex) { if (ErrorEncountered != null) { Debug.WriteLine(String.Format("Error Saving Contact: {0}", ex.Message)); Debug.WriteLine("Stack Trace:"); Debug.WriteLine(ex.StackTrace); ErrorEncountered("Error", ex.Message, EventType.Error); } else { throw; } } } }
public void Load() { LoadOutlookContacts(); LoadGoogleContacts(); LoadGoogleGroups(); try { _matches = ContactsMatcher.MatchContacts(this); } catch (DuplicateDataException ex) { Logger.Log(ex.Message, EventType.Error); if (DuplicatesFound != null) { DuplicatesFound("Outlook duplicates found", ex.Message, EventType.Error); } } }
/// <summary> /// Matches outlook and google contact by a) google id b) properties. /// </summary> /// <param name="outlookContacts"></param> /// <param name="googleContacts"></param> /// <returns>Returns a list of match pairs (outlook contact + google contact) for all contact. Those that weren't matche will have it's peer set to null</returns> public static ContactMatchList MatchContacts(Syncronizer sync) { ContactMatchList result = new ContactMatchList(Math.Max(sync.OutlookContacts.Count, sync.GoogleContacts.Capacity)); int googleContactsMatched = 0; bool listingDuplicates = false; string duplicatesList = ""; //for each outlook contact try to get google contact id from user properties //if no match - try to match by properties //if no match - create a new match pair without google contact. //foreach (Outlook._ContactItem olc in outlookContacts) for (int i = 1; i <= sync.OutlookContacts.Count; i++) { try { if (!(sync.OutlookContacts[i] is Outlook.ContactItem)) { continue; } } catch (Exception ex) { //this is needed because some contacts throw exceptions continue; } Outlook.ContactItem olc = sync.OutlookContacts[i] as Outlook.ContactItem; // check if a duplicate Collection <Outlook.ContactItem> duplicates; if (!string.IsNullOrEmpty(olc.Email1Address)) { duplicates = sync.OutlookContactByEmail(olc.Email1Address); if (duplicates.Count > 1) { if (!listingDuplicates) { duplicatesList = "Outlook contacts with the same email have been found. Please delete duplicates of:"; listingDuplicates = true; } string str = olc.FileAs + " (" + olc.Email1Address + ")"; if (!duplicatesList.Contains(str)) { duplicatesList += Environment.NewLine + str; } continue; } else { ContactMatch dup = result.Find(delegate(ContactMatch match) { return(match.OutlookContact != null && match.OutlookContact.Email1Address == olc.Email1Address); }); if (dup != null) { if (sync.Logger != null) { sync.Logger.Log(string.Format("Duplicate contact found ({0}). Skipping", olc.FileAs), EventType.Information); } continue; } } } //if (duplicates.Count != 1) //{ // // if this is the first item in the duplicates // // collection, then proceed, otherwise skip. // int index = sync.IndexOf(duplicates, olc); //duplicates.IndexOf(olc); // if (index == -1) // throw new Exception("Did not find self in duplicates"); // if (index != 0) // continue; //} if (!IsContactValid(olc)) { if (sync.Logger != null) { sync.Logger.Log(string.Format("Invalid outlook contact ({0}). Skipping", olc.FileAs), EventType.Warning); } continue; } // only match if there is either an email or telephone or else // a matching google contact will be created at each sync if (olc.Email1Address != null || olc.Email2Address != null || olc.Email3Address != null || olc.PrimaryTelephoneNumber != null || olc.HomeTelephoneNumber != null || olc.MobileTelephoneNumber != null || olc.BusinessTelephoneNumber != null ) { //create a default match pair with just outlook contact. ContactMatch match = new ContactMatch(olc, null); #region Match by google id //try to match this contact to one of google contacts. Outlook.UserProperty idProp = olc.UserProperties[sync.OutlookPropertyNameId]; if (idProp != null) { AtomId id = new AtomId((string)idProp.Value); ContactEntry foundContact = sync.GoogleContacts.FindById(id) as ContactEntry; if (foundContact != null && foundContact.Deleted) { //google contact was deleted, but outlook contact is still referencing it. idProp.Value = ""; //TODO: delete outlook contact too? } if (foundContact == null) { //google contact not found. delete property. idProp.Value = ""; } else if (foundContact != null) { //we found a match by google id match.AddGoogleContact(foundContact); } } #endregion if (match.GoogleContact == null) { //no match found. match by common properties #region Match by properties //foreach google contac try to match and create a match pair if found some match(es) foreach (ContactEntry entry in sync.GoogleContacts) { //Console.WriteLine(" - "+entry.Title.Text); if (entry.Deleted) { continue; } //1. try to match by name if (!string.IsNullOrEmpty(olc.FullName) && olc.FullName.Equals(entry.Title.Text, StringComparison.InvariantCultureIgnoreCase)) { match.AddGoogleContact(entry); continue; } //1.1 try to match by file as if (!string.IsNullOrEmpty(olc.FileAs) && olc.FileAs.Equals(entry.Title.Text, StringComparison.InvariantCultureIgnoreCase)) { match.AddGoogleContact(entry); continue; } //2. try to match by emails if (FindEmail(olc.Email1Address, entry.Emails) != null) { match.AddGoogleContact(entry); continue; } if (FindEmail(olc.Email2Address, entry.Emails) != null) { match.AddGoogleContact(entry); continue; } if (FindEmail(olc.Email3Address, entry.Emails) != null) { match.AddGoogleContact(entry); continue; } #region Phone numbers //3. try to match by phone numbers if (FindPhone(olc.MobileTelephoneNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); continue; } //don't match by home or business bumbers, because several people may share the saem home or business number continue; //if (FindPhone(olc.PrimaryTelephoneNumber, entry.Phonenumbers) != null) //{ // match.AddGoogleContact(entry); // continue; //} if (FindPhone(olc.HomeTelephoneNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); continue; } if (FindPhone(olc.BusinessTelephoneNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); continue; } if (FindPhone(olc.BusinessFaxNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); //continue; } if (FindPhone(olc.HomeFaxNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); //continue; } if (FindPhone(olc.PagerNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); //continue; } if (FindPhone(olc.RadioTelephoneNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); //continue; } if (FindPhone(olc.OtherTelephoneNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); //continue; } if (FindPhone(olc.CarTelephoneNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); //continue; } if (FindPhone(olc.Business2TelephoneNumber, entry.Phonenumbers) != null) { match.AddGoogleContact(entry); //continue; } #endregion } #endregion } //check if a match was found. if (match.AllGoogleContactMatches.Count > 0) { googleContactsMatched += match.AllGoogleContactMatches.Count; //remove google contact from the list so it's not matched twice. foreach (ContactEntry contact in match.AllGoogleContactMatches) { sync.GoogleContacts.Remove(contact); } } else { if (sync.Logger != null) { sync.Logger.Log(string.Format("No match found for outlook contact ({0})", olc.FileAs), EventType.Information); } } result.Add(match); } else { // no telephone and email if (sync.Logger != null) { sync.Logger.Log(string.Format("Skipping outlook contact ({0})", olc.FileAs), EventType.Warning); } } } if (listingDuplicates) { throw new DuplicateDataException(duplicatesList); } //return result; if (sync.SyncOption != SyncOption.OutlookToGoogleOnly) { //for each google contact that's left (they will be nonmatched) create a new match pair without outlook contact. foreach (ContactEntry entry in sync.GoogleContacts) { // only match if there is either an email or telephone or else // a matching google contact will be created at each sync if (entry.Emails.Count != 0 || entry.Phonenumbers.Count != 0) { ContactMatch match = new ContactMatch(null, entry);; result.Add(match); } else { // no telephone and email } } } return(result); }