예제 #1
0
        public DeleteResolution ResolveDelete(OutlookContactInfo outlookContact)
        {
            string name = ContactMatch.GetName(outlookContact);

            _form.Text = "Google Contact deleted";
            _form.messageLabel.Text =
                "Google Contact \"" + name +
                "\" doesn't exist anymore. Do you want to delete it also on Outlook side?";

            _form.OutlookItemTextBox.Text = string.Empty;
            _form.GoogleItemTextBox.Text  = string.Empty;
            Outlook.ContactItem item = outlookContact.GetOriginalItemFromOutlook();
            try
            {
                _form.OutlookItemTextBox.Text = ContactMatch.GetSummary(item);
            }
            finally
            {
                if (item != null)
                {
                    Marshal.ReleaseComObject(item);
                    item = null;
                }
            }

            _form.keepOutlook.Text = "Keep Outlook";
            _form.keepGoogle.Text  = "Delete Outlook";
            _form.skip.Enabled     = false;

            return(ResolveDeletedGoogle());
        }
예제 #2
0
        public static string GetName(OutlookContactInfo outlookContact)
        {
            string name = outlookContact.FileAs;
            if (string.IsNullOrEmpty(name))
                name = outlookContact.FullName;
            if (string.IsNullOrEmpty(name))
                name = outlookContact.Company;
            if (string.IsNullOrEmpty(name))
                name = outlookContact.Email1Address;

            return name;
        }
예제 #3
0
        public ConflictResolution ResolveDuplicate(OutlookContactInfo outlookContact, List <Contact> googleContacts, out Contact googleContact)
        {
            string name = ContactMatch.GetName(outlookContact);

            _form.messageLabel.Text =
                "There are multiple Google Contacts (" + googleContacts.Count + ") matching unique properties for Outlook Contact \"" + name +
                "\". Please choose from the combobox below the Google Contact you would like to match with Outlook and if you want to keep the Google or Outlook properties of the selected contact.";


            _form.OutlookItemTextBox.Text = string.Empty;
            _form.GoogleItemTextBox.Text  = string.Empty;

            Microsoft.Office.Interop.Outlook.ContactItem item = outlookContact.GetOriginalItemFromOutlook();
            try
            {
                _form.OutlookItemTextBox.Text = ContactMatch.GetSummary(item);
            }
            finally
            {
                if (item != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(item);
                    item = null;
                }
            }



            _form.GoogleComboBox.DataSource = googleContacts;
            _form.GoogleComboBox.Visible    = true;
            _form.AllCheckBox.Visible       = false;
            _form.skip.Text = "Keep both";


            ConflictResolution res = Resolve();

            googleContact = _form.GoogleComboBox.SelectedItem as Contact;

            return(res);
        }
예제 #4
0
        /// <summary>
        /// Updates Google contact from Outlook (but without groups/categories)
        /// </summary>
        public static void UpdateContact(Outlook.ContactItem master, Contact slave, bool useFileAs)
        {
            //// if no email or number, contact will be updated at each sync
            //if (string.IsNullOrEmpty(master.Email1Address) && string.IsNullOrEmpty(master.PrimaryTelephoneNumber))
            //{
            //    if (slave.Emails.Count > 0)
            //    {
            //        Logger.Log("Outlook Contact '" + master.FullNameAndCompany + "' has neither email address nor phone number. Setting email address of Google contact: " + slave.Emails[0].Address, EventType.Warning);
            //        master.Email1Address = slave.Emails[0].Address;
            //    }
            //    else
            //    {
            //        Logger.Log("Outlook Contact '" + master.FullNameAndCompany + "' has neither email address nor phone number. Cannot merge with Google contact: " + slave.Summary, EventType.Error);
            //        return;
            //    }
            //}

            //TODO: convert to merge as opposed to replace

            #region Title/FileAs

            slave.Title = null;
            if (useFileAs)
            {
                if (!string.IsNullOrEmpty(master.FileAs))
                {
                    slave.Title = master.FileAs;
                }
                else if (!string.IsNullOrEmpty(master.FullName))
                {
                    slave.Title = master.FullName;
                }
                else if (!string.IsNullOrEmpty(master.CompanyName))
                {
                    slave.Title = master.CompanyName;
                }
                else if (!string.IsNullOrEmpty(master.Email1Address))
                {
                    slave.Title = master.Email1Address;
                }
            }

            #endregion Title/FileAs

            #region Name
            Name name = new Name();

            name.NamePrefix     = master.Title;
            name.GivenName      = master.FirstName;
            name.AdditionalName = master.MiddleName;
            name.FamilyName     = master.LastName;
            name.NameSuffix     = master.Suffix;

            //Use the Google's full name to save a unique identifier. When saving the FullName, it always overwrites the Google Title
            if (!string.IsNullOrEmpty(master.FullName)) //Only if master.FullName has a value, i.e. not only a company or email contact
            {
                if (useFileAs)
                {
                    name.FullName = master.FileAs;
                }
                else
                {
                    name.FullName = OutlookContactInfo.GetTitleFirstLastAndSuffix(master);
                    if (!string.IsNullOrEmpty(name.FullName))
                    {
                        name.FullName = name.FullName.Trim().Replace("  ", " ");
                    }
                }
            }

            slave.Name = name;
            #endregion Name

            #region Birthday
            try
            {
                if (master.Birthday.Equals(outlookDateNone)) //earlier also || master.Birthday.Year < 1900
                {
                    slave.ContactEntry.Birthday = null;
                }
                else
                {
                    slave.ContactEntry.Birthday = master.Birthday.ToString("yyyy-MM-dd");
                }
            }
            catch (Exception ex)
            {
                Logger.Log("Birthday couldn't be updated from Outlook to Google for '" + master.FileAs + "': " + ex.Message, EventType.Error);
            }
            #endregion Birthday

            slave.ContactEntry.Nickname = master.NickName;
            slave.Location = master.OfficeLocation;
            //Categories are synced separately in Syncronizer.OverwriteContactGroups: slave.Categories = master.Categories;
            slave.ContactEntry.Initials = master.Initials;
            slave.Languages.Clear();
            if (!string.IsNullOrEmpty(master.Language))
            {
                foreach (string language in master.Language.Split(';'))
                {
                    Language googleLanguage = new Language();
                    googleLanguage.Label = language;
                    slave.Languages.Add(googleLanguage);
                }
            }

            SetEmails(master, slave);

            SetAddresses(master, slave);

            SetPhoneNumbers(master, slave);

            SetCompanies(master, slave);

            SetIMs(master, slave);

            #region anniversary
            //First remove anniversary
            foreach (Event ev in slave.ContactEntry.Events)
            {
                if (ev.Relation != null && ev.Relation.Equals(relAnniversary))
                {
                    slave.ContactEntry.Events.Remove(ev);
                    break;
                }
            }
            try
            {
                //Then add it again if existing
                if (!master.Anniversary.Equals(outlookDateNone)) //earlier also || master.Birthday.Year < 1900
                {
                    Event ev = new Event();
                    ev.Relation       = relAnniversary;
                    ev.When           = new When();
                    ev.When.AllDay    = true;
                    ev.When.StartTime = master.Anniversary.Date;
                    slave.ContactEntry.Events.Add(ev);
                }
            }
            catch (Exception ex)
            {
                Logger.Log("Anniversary couldn't be updated from Outlook to Google for '" + master.FileAs + "': " + ex.Message, EventType.Error);
            }
            #endregion anniversary

            #region relations (spouse, child, manager and assistant)
            //First remove spouse, child, manager and assistant
            for (int i = slave.ContactEntry.Relations.Count - 1; i >= 0; i--)
            {
                Relation rel = slave.ContactEntry.Relations[i];
                if (rel.Rel != null && (rel.Rel.Equals(relSpouse) || rel.Rel.Equals(relChild) || rel.Rel.Equals(relManager) || rel.Rel.Equals(relAssistant)))
                {
                    slave.ContactEntry.Relations.RemoveAt(i);
                }
            }
            //Then add spouse again if existing
            if (!string.IsNullOrEmpty(master.Spouse))
            {
                Relation rel = new Relation();
                rel.Rel   = relSpouse;
                rel.Value = master.Spouse;
                slave.ContactEntry.Relations.Add(rel);
            }
            //Then add children again if existing
            if (!string.IsNullOrEmpty(master.Children))
            {
                Relation rel = new Relation();
                rel.Rel   = relChild;
                rel.Value = master.Children;
                slave.ContactEntry.Relations.Add(rel);
            }
            //Then add manager again if existing
            if (!string.IsNullOrEmpty(master.ManagerName))
            {
                Relation rel = new Relation();
                rel.Rel   = relManager;
                rel.Value = master.ManagerName;
                slave.ContactEntry.Relations.Add(rel);
            }
            //Then add assistant again if existing
            if (!string.IsNullOrEmpty(master.AssistantName))
            {
                Relation rel = new Relation();
                rel.Rel   = relAssistant;
                rel.Value = master.AssistantName;
                slave.ContactEntry.Relations.Add(rel);
            }
            #endregion relations (spouse, child, manager and assistant)

            #region HomePage
            slave.ContactEntry.Websites.Clear();
            //Just copy the first URL, because Outlook only has 1
            if (!string.IsNullOrEmpty(master.WebPage))
            {
                Website url = new Website();
                url.Href    = master.WebPage;
                url.Rel     = relHomePage;
                url.Primary = true;
                slave.ContactEntry.Websites.Add(url);
            }
            #endregion HomePage

            //CH - Fixed error with invalid xml being sent to google... This may need to be added to everything
            //slave.Content = String.Format("<![CDATA[{0}]]>", master.Body);
            //floriwan: Maybe better to just escape the XML instead of putting it in CDATA, because this causes a CDATA added to all my contacts
            if (!string.IsNullOrEmpty(master.Body))
            {
                slave.Content = System.Security.SecurityElement.Escape(master.Body);
            }
            else
            {
                slave.Content = null;
            }
        }
예제 #5
0
 //public Contact LastGoogleContact;
 public ContactMatch(OutlookContactInfo outlookContact, Contact googleContact)
 {
     AddOutlookContact(outlookContact);
     AddGoogleContact(googleContact);
 }
예제 #6
0
        /// <summary>
        /// Matches outlook and google contact by a) google id b) properties.
        /// </summary>
        /// <param name="sync">Syncronizer instance</param>
        /// <param name="duplicatesFound">Exception returned, if duplicates have been found (null else)</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 List<ContactMatch> MatchContacts(Synchronizer sync, out DuplicateDataException duplicatesFound)
        {
            Logger.Log("Matching Outlook and Google contacts...", EventType.Information);
            var result = new List<ContactMatch>();

            var duplicateGoogleMatches = string.Empty;
            var duplicateOutlookContacts = string.Empty;
            sync.GoogleContactDuplicates = new Collection<ContactMatch>();
            sync.OutlookContactDuplicates = new Collection<ContactMatch>();

            var skippedOutlookIds = new List<string>();

            //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)
            var outlookContactsWithoutOutlookGoogleId = new Collection<OutlookContactInfo>();
            #region Match first all outlookContacts by sync id
            for (int i = 1; i <= sync.OutlookContacts.Count; i++)
            {
                Outlook.ContactItem olc = null;
                try
                {
                    olc = sync.OutlookContacts[i] as Outlook.ContactItem;
                    if (olc == null)
                    {
                        Logger.Log("Empty Outlook contact found (maybe distribution list). Skipping", EventType.Warning);
                        sync.SkippedCount++;
                        sync.SkippedCountNotMatches++;
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    //this is needed because some contacts throw exceptions
                    Logger.Log("Accessing Outlook contact threw and exception. Skipping: " + ex.Message, EventType.Warning);
                    sync.SkippedCount++;
                    sync.SkippedCountNotMatches++;
                    continue;
                }

                try
                {

                    // sometimes contacts throw Exception when accessing their properties, so we give it a controlled try first.
                    try
                    {
                        string email1Address = olc.Email1Address;
                    }
                    catch (Exception ex)
                    {
                        string message = string.Format("Can't access contact details for outlook contact, got {0} - '{1}'. Skipping", ex.GetType().ToString(), ex.Message);
                        try
                        {
                            message = string.Format("{0} {1}.", message, olc.FileAs);
                            //remember skippedOutlookIds to later not delete them if found on Google side
                            skippedOutlookIds.Add(string.Copy(olc.EntryID));

                        }
                        catch
                        {
                            //e.g. if olc.FileAs also fails, ignore, because messge already set
                            //message = null;
                        }

                        //if (olc != null && message != null) // it's useless to say "we couldn't access some contacts properties
                        //{
                        Logger.Log(message, EventType.Warning);
                        //}
                        sync.SkippedCount++;
                        sync.SkippedCountNotMatches++;
                        continue;
                    }

                    if (!IsContactValid(olc))
                    {
                        Logger.Log(string.Format("Invalid outlook contact ({0}). Skipping", olc.FileAs), EventType.Warning);
                        skippedOutlookIds.Add(string.Copy(olc.EntryID));
                        sync.SkippedCount++;
                        sync.SkippedCountNotMatches++;
                        continue;
                    }

                    if (olc.Body != null && olc.Body.Length > 62000)
                    {
                        // notes field too large
                        Logger.Log(string.Format("Skipping outlook contact ({0}). Reduce the notes field to a maximum of 62.000 characters.", olc.FileAs), EventType.Warning);
                        skippedOutlookIds.Add(string.Copy(olc.EntryID));
                        sync.SkippedCount++;
                        sync.SkippedCountNotMatches++;
                        continue;
                    }

                    if (NotificationReceived != null)
                        NotificationReceived(String.Format("Matching contact {0} of {1} by id: {2} ...", i, sync.OutlookContacts.Count, olc.FileAs));

                    // Create our own info object to go into collections/lists, so we can free the Outlook objects and not run out of resources / exceed policy limits.
                    var olci = new OutlookContactInfo(olc, sync);

                    //try to match this contact to one of google contacts
                    Outlook.UserProperties userProperties = olc.UserProperties;
                    Outlook.UserProperty idProp = userProperties[sync.OutlookPropertyNameId];
                    try
                    {
                        if (idProp != null)
                        {
                            string googleContactId = string.Copy((string)idProp.Value);
                            Contact foundContact = sync.GetGoogleContactById(googleContactId);
                            var match = new ContactMatch(olci, null);

                            //Check first, that this is not a duplicate
                            //e.g. by copying an existing Outlook contact
                            //or by Outlook checked this as duplicate, but the user selected "Add new"
                            Collection<OutlookContactInfo> duplicates = sync.OutlookContactByProperty(sync.OutlookPropertyNameId, googleContactId);
                            if (duplicates.Count > 1)
                            {
                                foreach (OutlookContactInfo duplicate in duplicates)
                                {
                                    if (!string.IsNullOrEmpty(googleContactId))
                                    {
                                        Logger.Log("Duplicate Outlook contact found, resetting match and trying to match again: " + duplicate.FileAs, EventType.Warning);
                                        Outlook.ContactItem item = duplicate.GetOriginalItemFromOutlook();
                                        try
                                        {
                                            ContactPropertiesUtils.ResetOutlookGoogleContactId(sync, item);
                                            item.Save();
                                        }
                                        finally
                                        {
                                            if (item != null)
                                            {
                                                Marshal.ReleaseComObject(item);
                                                item = null;
                                            }
                                        }
                                    }
                                }

                                if (foundContact != null && !foundContact.Deleted)
                                {
                                    ContactPropertiesUtils.ResetGoogleOutlookContactId(sync.SyncProfile, foundContact);
                                }

                                outlookContactsWithoutOutlookGoogleId.Add(olci);
                            }
                            else
                            {

                                if (foundContact != null && !foundContact.Deleted)
                                {
                                    //we found a match by google id, that is not deleted yet
                                    match.AddGoogleContact(foundContact);
                                    result.Add(match);
                                    //Remove the contact from the list to not sync it twice
                                    sync.GoogleContacts.Remove(foundContact);
                                }
                                else
                                {
                                    outlookContactsWithoutOutlookGoogleId.Add(olci);
                                }
                            }
                        }
                        else
                            outlookContactsWithoutOutlookGoogleId.Add(olci);
                    }
                    finally
                    {
                        if (idProp != null)
                            Marshal.ReleaseComObject(idProp);
                        Marshal.ReleaseComObject(userProperties);
                    }
                }

                finally
                {
                    Marshal.ReleaseComObject(olc);
                    olc = null;
                }

            }
            #endregion
            #region Match the remaining contacts by properties

            for (int i = 0; i < outlookContactsWithoutOutlookGoogleId.Count; i++)
            {
                OutlookContactInfo olci = outlookContactsWithoutOutlookGoogleId[i];

                if (NotificationReceived != null)
                    NotificationReceived(String.Format("Matching contact {0} of {1} by unique properties: {2} ...", i + 1, outlookContactsWithoutOutlookGoogleId.Count, olci.FileAs));

                //no match found by id => match by common properties
                //create a default match pair with just outlook contact.
                var match = new ContactMatch(olci, null);

                //foreach google contact try to match and create a match pair if found some match(es)
                for (int j=sync.GoogleContacts.Count-1;j>=0;j--)
                {
                    Contact entry = sync.GoogleContacts[j];
                    if (entry.Deleted)
                        continue;

                    // only match if there is either an email or telephone or else
                    // a matching google contact will be created at each sync
                    //1. try to match by FileAs
                    //1.1 try to match by FullName
                    //2. try to match by primary email
                    //3. try to match by mobile phone number, don't match by home or business bumbers, because several people may share the same home or business number
                    //4. try to math Company, if Google Title is null, i.e. the contact doesn't have a name and title, only a company
                    string entryTitleFirstLastAndSuffix = OutlookContactInfo.GetTitleFirstLastAndSuffix(entry);
                    if (!string.IsNullOrEmpty(olci.FileAs) && !string.IsNullOrEmpty(entry.Title) && olci.FileAs.Equals(entry.Title.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||  //Replace twice to not replace a \r\n by \r\r\n. This is necessary because \r\n are saved as \n only to google
                        !string.IsNullOrEmpty(olci.FileAs) && !string.IsNullOrEmpty(entry.Name.FullName) && olci.FileAs.Equals(entry.Name.FullName.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
                        !string.IsNullOrEmpty(olci.FullName) && !string.IsNullOrEmpty(entry.Name.FullName) && olci.FullName.Equals(entry.Name.FullName.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
                        !string.IsNullOrEmpty(olci.TitleFirstLastAndSuffix) && !string.IsNullOrEmpty(entryTitleFirstLastAndSuffix) && olci.TitleFirstLastAndSuffix.Equals(entryTitleFirstLastAndSuffix.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
                        !string.IsNullOrEmpty(olci.Email1Address) && entry.Emails.Count > 0 && olci.Email1Address.Equals(entry.Emails[0].Address, StringComparison.InvariantCultureIgnoreCase) ||
                        //!string.IsNullOrEmpty(olci.Email2Address) && FindEmail(olci.Email2Address, entry.Emails) != null ||
                        //!string.IsNullOrEmpty(olci.Email3Address) && FindEmail(olci.Email3Address, entry.Emails) != null ||
                        olci.MobileTelephoneNumber != null && FindPhone(olci.MobileTelephoneNumber, entry.Phonenumbers) != null ||
                        !string.IsNullOrEmpty(olci.FileAs) && string.IsNullOrEmpty(entry.Title) && entry.Organizations.Count > 0 && olci.FileAs.Equals(entry.Organizations[0].Name, StringComparison.InvariantCultureIgnoreCase)
                        )
                    {
                        match.AddGoogleContact(entry);
                        sync.GoogleContacts.Remove(entry);
                    }

                }

                #region find duplicates not needed now
                //if (match.GoogleContact == null && match.OutlookContact != null)
                //{//If GoogleContact, we have to expect a conflict because of Google insert of duplicates
                //    foreach (Contact entry in sync.GoogleContacts)
                //    {
                //        if (!string.IsNullOrEmpty(olc.FullName) && olc.FullName.Equals(entry.Title, StringComparison.InvariantCultureIgnoreCase) ||
                //         !string.IsNullOrEmpty(olc.FileAs) && olc.FileAs.Equals(entry.Title, StringComparison.InvariantCultureIgnoreCase) ||
                //         !string.IsNullOrEmpty(olc.Email1Address) && FindEmail(olc.Email1Address, entry.Emails) != null ||
                //         !string.IsNullOrEmpty(olc.Email2Address) && FindEmail(olc.Email1Address, entry.Emails) != null ||
                //         !string.IsNullOrEmpty(olc.Email3Address) && FindEmail(olc.Email1Address, entry.Emails) != null ||
                //         olc.MobileTelephoneNumber != null && FindPhone(olc.MobileTelephoneNumber, entry.Phonenumbers) != null
                //         )
                //    }
                //// check for each email 1,2 and 3 if a duplicate exists with same email, because Google doesn't like inserting new contacts with same email
                //Collection<Outlook.ContactItem> duplicates1 = new Collection<Outlook.ContactItem>();
                //Collection<Outlook.ContactItem> duplicates2 = new Collection<Outlook.ContactItem>();
                //Collection<Outlook.ContactItem> duplicates3 = new Collection<Outlook.ContactItem>();
                //if (!string.IsNullOrEmpty(olc.Email1Address))
                //    duplicates1 = sync.OutlookContactByEmail(olc.Email1Address);

                //if (!string.IsNullOrEmpty(olc.Email2Address))
                //    duplicates2 = sync.OutlookContactByEmail(olc.Email2Address);

                //if (!string.IsNullOrEmpty(olc.Email3Address))
                //    duplicates3 = sync.OutlookContactByEmail(olc.Email3Address);

                //if (duplicates1.Count > 1 || duplicates2.Count > 1 || duplicates3.Count > 1)
                //{
                //    if (string.IsNullOrEmpty(duplicatesEmailList))
                //        duplicatesEmailList = "Outlook contacts with the same email have been found and cannot be synchronized. Please delete duplicates of:";

                //    if (duplicates1.Count > 1)
                //        foreach (Outlook.ContactItem duplicate in duplicates1)
                //        {
                //            string str = olc.FileAs + " (" + olc.Email1Address + ")";
                //            if (!duplicatesEmailList.Contains(str))
                //                duplicatesEmailList += Environment.NewLine + str;
                //        }
                //    if (duplicates2.Count > 1)
                //        foreach (Outlook.ContactItem duplicate in duplicates2)
                //        {
                //            string str = olc.FileAs + " (" + olc.Email2Address + ")";
                //            if (!duplicatesEmailList.Contains(str))
                //                duplicatesEmailList += Environment.NewLine + str;
                //        }
                //    if (duplicates3.Count > 1)
                //        foreach (Outlook.ContactItem duplicate in duplicates3)
                //        {
                //            string str = olc.FileAs + " (" + olc.Email3Address + ")";
                //            if (!duplicatesEmailList.Contains(str))
                //                duplicatesEmailList += Environment.NewLine + str;
                //        }
                //    continue;
                //}
                //else if (!string.IsNullOrEmpty(olc.Email1Address))
                //{
                //    ContactMatch dup = result.Find(delegate(ContactMatch match)
                //    {
                //        return match.OutlookContact != null && match.OutlookContact.Email1Address == olc.Email1Address;
                //    });
                //    if (dup != null)
                //    {
                //        Logger.Log(string.Format("Duplicate contact found by Email1Address ({0}). Skipping", olc.FileAs), EventType.Information);
                //        continue;
                //    }
                //}

                //// check for unique mobile phone, because this sync tool uses the also the mobile phone to identify matches between Google and Outlook
                //Collection<Outlook.ContactItem> duplicatesMobile = new Collection<Outlook.ContactItem>();
                //if (!string.IsNullOrEmpty(olc.MobileTelephoneNumber))
                //    duplicatesMobile = sync.OutlookContactByProperty("MobileTelephoneNumber", olc.MobileTelephoneNumber);

                //if (duplicatesMobile.Count > 1)
                //{
                //    if (string.IsNullOrEmpty(duplicatesMobileList))
                //        duplicatesMobileList = "Outlook contacts with the same mobile phone have been found and cannot be synchronized. Please delete duplicates of:";

                //    foreach (Outlook.ContactItem duplicate in duplicatesMobile)
                //    {
                //        sync.OutlookContactDuplicates.Add(olc);
                //        string str = olc.FileAs + " (" + olc.MobileTelephoneNumber + ")";
                //        if (!duplicatesMobileList.Contains(str))
                //            duplicatesMobileList += Environment.NewLine + str;
                //    }
                //    continue;
                //}
                //else if (!string.IsNullOrEmpty(olc.MobileTelephoneNumber))
                //{
                //    ContactMatch dup = result.Find(delegate(ContactMatch match)
                //    {
                //        return match.OutlookContact != null && match.OutlookContact.MobileTelephoneNumber == olc.MobileTelephoneNumber;
                //    });
                //    if (dup != null)
                //    {
                //        Logger.Log(string.Format("Duplicate contact found by MobileTelephoneNumber ({0}). Skipping", olc.FileAs), EventType.Information);
                //        continue;
                //    }
                //}

                #endregion

                if (match.AllGoogleContactMatches == null || match.AllGoogleContactMatches.Count == 0)
                {
                    //Check, if this Outlook contact has a match in the google duplicates
                    bool duplicateFound = false;
                    foreach (ContactMatch duplicate in sync.GoogleContactDuplicates)
                    {
                        string entryTitleFirstLastAndSuffix = OutlookContactInfo.GetTitleFirstLastAndSuffix(duplicate.AllGoogleContactMatches[0]);
                        if (duplicate.AllGoogleContactMatches.Count > 0 &&
                            (!string.IsNullOrEmpty(olci.FileAs) && !string.IsNullOrEmpty(duplicate.AllGoogleContactMatches[0].Title) && olci.FileAs.Equals(duplicate.AllGoogleContactMatches[0].Title.Replace("\r\n", "\n").Replace("\n","\r\n"), StringComparison.InvariantCultureIgnoreCase) ||  //Replace twice to not replace a \r\n by \r\r\n. This is necessary because \r\n are saved as \n only to google
                             !string.IsNullOrEmpty(olci.FileAs) && !string.IsNullOrEmpty(duplicate.AllGoogleContactMatches[0].Name.FullName) && olci.FileAs.Equals(duplicate.AllGoogleContactMatches[0].Name.FullName.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
                             !string.IsNullOrEmpty(olci.FullName) && !string.IsNullOrEmpty(duplicate.AllGoogleContactMatches[0].Name.FullName) && olci.FullName.Equals(duplicate.AllGoogleContactMatches[0].Name.FullName.Replace("\r\n", "\n").Replace("\n","\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
                             !string.IsNullOrEmpty(olci.TitleFirstLastAndSuffix) && !string.IsNullOrEmpty(entryTitleFirstLastAndSuffix) && olci.TitleFirstLastAndSuffix.Equals(entryTitleFirstLastAndSuffix.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
                             !string.IsNullOrEmpty(olci.Email1Address) && duplicate.AllGoogleContactMatches[0].Emails.Count > 0 && olci.Email1Address.Equals(duplicate.AllGoogleContactMatches[0].Emails[0].Address, StringComparison.InvariantCultureIgnoreCase) ||
                             //!string.IsNullOrEmpty(olci.Email2Address) && FindEmail(olci.Email2Address, duplicate.AllGoogleContactMatches[0].Emails) != null ||
                             //!string.IsNullOrEmpty(olci.Email3Address) && FindEmail(olci.Email3Address, duplicate.AllGoogleContactMatches[0].Emails) != null ||
                             olci.MobileTelephoneNumber != null && FindPhone(olci.MobileTelephoneNumber, duplicate.AllGoogleContactMatches[0].Phonenumbers) != null ||
                             !string.IsNullOrEmpty(olci.FileAs) && string.IsNullOrEmpty(duplicate.AllGoogleContactMatches[0].Title) && duplicate.AllGoogleContactMatches[0].Organizations.Count > 0 && olci.FileAs.Equals(duplicate.AllGoogleContactMatches[0].Organizations[0].Name, StringComparison.InvariantCultureIgnoreCase)
                            ) ||
                            !string.IsNullOrEmpty(olci.FileAs) && olci.FileAs.Equals(duplicate.OutlookContact.FileAs, StringComparison.InvariantCultureIgnoreCase) ||
                            !string.IsNullOrEmpty(olci.FullName) && olci.FullName.Equals(duplicate.OutlookContact.FullName, StringComparison.InvariantCultureIgnoreCase) ||
                            !string.IsNullOrEmpty(olci.TitleFirstLastAndSuffix) && olci.TitleFirstLastAndSuffix.Equals(duplicate.OutlookContact.TitleFirstLastAndSuffix, StringComparison.InvariantCultureIgnoreCase) ||
                            !string.IsNullOrEmpty(olci.Email1Address) && olci.Email1Address.Equals(duplicate.OutlookContact.Email1Address, StringComparison.InvariantCultureIgnoreCase) ||
                            //                                              olci.Email1Address.Equals(duplicate.OutlookContact.Email2Address, StringComparison.InvariantCultureIgnoreCase) ||
                            //                                              olci.Email1Address.Equals(duplicate.OutlookContact.Email3Address, StringComparison.InvariantCultureIgnoreCase)
                            //                                              ) ||
                            //!string.IsNullOrEmpty(olci.Email2Address) && (olci.Email2Address.Equals(duplicate.OutlookContact.Email1Address, StringComparison.InvariantCultureIgnoreCase) ||
                            //                                              olci.Email2Address.Equals(duplicate.OutlookContact.Email2Address, StringComparison.InvariantCultureIgnoreCase) ||
                            //                                              olci.Email2Address.Equals(duplicate.OutlookContact.Email3Address, StringComparison.InvariantCultureIgnoreCase)
                            //                                              ) ||
                            //!string.IsNullOrEmpty(olci.Email3Address) && (olci.Email3Address.Equals(duplicate.OutlookContact.Email1Address, StringComparison.InvariantCultureIgnoreCase) ||
                            //                                              olci.Email3Address.Equals(duplicate.OutlookContact.Email2Address, StringComparison.InvariantCultureIgnoreCase) ||
                            //                                              olci.Email3Address.Equals(duplicate.OutlookContact.Email3Address, StringComparison.InvariantCultureIgnoreCase)
                            //                                              ) ||
                            olci.MobileTelephoneNumber != null && olci.MobileTelephoneNumber.Equals(duplicate.OutlookContact.MobileTelephoneNumber) ||
                            !string.IsNullOrEmpty(olci.FileAs) && string.IsNullOrEmpty(duplicate.GoogleContact.Title) && duplicate.GoogleContact.Organizations.Count > 0 && olci.FileAs.Equals(duplicate.GoogleContact.Organizations[0].Name, StringComparison.InvariantCultureIgnoreCase)
                           )
                        {
                            duplicateFound = true;
                            duplicate.AddOutlookContact(olci);
                            sync.OutlookContactDuplicates.Add(match);
                            if (string.IsNullOrEmpty(duplicateOutlookContacts))
                                duplicateOutlookContacts = "Outlook contact found that has been already identified as duplicate Google contact (either same email, Mobile or FullName) and cannot be synchronized. Please delete or resolve duplicates of:";

                            string str = olci.FileAs + " (" + olci.Email1Address + ", " + olci.MobileTelephoneNumber + ")";
                            if (!duplicateOutlookContacts.Contains(str))
                                duplicateOutlookContacts += Environment.NewLine + str;

                            break;
                        }
                    }

                    if (!duplicateFound)
                        Logger.Log(string.Format("No match found for outlook contact ({0}) => {1}", olci.FileAs, (olci.UserProperties.GoogleContactId != null?"Delete from Outlook":"Add to Google")), EventType.Information);
                }
                else
                {
                    //Remember Google duplicates to later react to it when resetting matches or syncing
                    //ResetMatches: Also reset the duplicates
                    //Sync: Skip duplicates (don't sync duplicates to be fail safe)
                    if (match.AllGoogleContactMatches.Count > 1)
                    {
                        sync.GoogleContactDuplicates.Add(match);
                        foreach (Contact entry in match.AllGoogleContactMatches)
                        {
                            //Create message for duplicatesFound exception
                            if (string.IsNullOrEmpty(duplicateGoogleMatches))
                                duplicateGoogleMatches = "Outlook contacts matching with multiple Google contacts have been found (either same email, Mobile, FullName or company) and cannot be synchronized. Please delete or resolve duplicates of:";

                            string str = olci.FileAs + " (" + olci.Email1Address + ", " + olci.MobileTelephoneNumber + ")";
                            if (!duplicateGoogleMatches.Contains(str))
                                duplicateGoogleMatches += Environment.NewLine + str;
                        }
                    }

                }

                result.Add(match);
            }
            #endregion

            if (!string.IsNullOrEmpty(duplicateGoogleMatches) || !string.IsNullOrEmpty(duplicateOutlookContacts))
                duplicatesFound = new DuplicateDataException(duplicateGoogleMatches + Environment.NewLine + Environment.NewLine + duplicateOutlookContacts);
            else
                duplicatesFound = null;

            //return result;

            //for each google contact that's left (they will be nonmatched) create a new match pair without outlook contact.
            for (int i=0; i< sync.GoogleContacts.Count;i++)
            {
               Contact entry = sync.GoogleContacts[i];
               if (NotificationReceived != null)
                    NotificationReceived(String.Format("Adding new Google contact {0} of {1} by unique properties: {2} ...", i+1, sync.GoogleContacts.Count, entry.Title));

                // only match if there is either an email or mobile phone or a name or a company
                // otherwise a matching google contact will be created at each sync
                bool mobileExists = false;
                foreach (PhoneNumber phone in entry.Phonenumbers)
                {
                    if (phone.Rel == ContactsRelationships.IsMobile)
                    {
                        mobileExists = true;
                        break;
                    }
                }

                string googleOutlookId = ContactPropertiesUtils.GetGoogleOutlookContactId(sync.SyncProfile, entry);
                if (!String.IsNullOrEmpty(googleOutlookId) && skippedOutlookIds.Contains(googleOutlookId))
                {
                    Logger.Log("Skipped GoogleContact because Outlook contact couldn't be matched because of previous problem (see log): " + entry.Title, EventType.Warning);
                }
                else if (entry.Emails.Count == 0 && !mobileExists && string.IsNullOrEmpty(entry.Title) && (entry.Organizations.Count == 0 || string.IsNullOrEmpty(entry.Organizations[0].Name)))
                {
                    // no telephone and email

                    //ToDo: For now I use the ResolveDelete function, because it is almost the same, maybe we introduce a separate function for this ans also include DeleteGoogleAlways checkbox
                    var r = new ConflictResolver();
                    DeleteResolution res = r.ResolveDelete(entry);
                    if (res == DeleteResolution.DeleteGoogle || res == DeleteResolution.DeleteGoogleAlways)
                    {
                        ContactPropertiesUtils.SetGoogleOutlookContactId(sync.SyncProfile, entry, "-1"); //just set a dummy Id to delete this entry later on
                        sync.SaveContact(new ContactMatch(null, entry));
                    }
                    else
                    {
                        sync.SkippedCount++;
                        sync.SkippedCountNotMatches++;

                        Logger.Log("Skipped GoogleContact because no unique property found (Email1 or mobile or name or company):" + ContactMatch.GetSummary(entry), EventType.Warning);
                    }

                }
                else
                {
                    Logger.Log(string.Format("No match found for Google contact ({0}) => {1}", entry.Title, (!string.IsNullOrEmpty(googleOutlookId) ? "Delete from Google" : "Add to Outlook")), EventType.Information);
                    var match = new ContactMatch(null, entry);
                    result.Add(match);
                }
            }
            return result;
        }
예제 #7
0
        public void AddOutlookContact(OutlookContactInfo outlookContact)
        {
            if (outlookContact == null)
                return;
            //throw new ArgumentNullException("outlookContact must not be null.");

            if (OutlookContact == null)
                OutlookContact = outlookContact;

            //this to avoid searching the entire collection.
            //if last contact it what we are trying to add the we have already added it earlier
            //if (LastGoogleContact == googleContact)
            //    return;

            if (!AllOutlookContactMatches.Contains(outlookContact))
                AllOutlookContactMatches.Add(outlookContact);

            //LastGoogleContact = googleContact;
        }
예제 #8
0
        public ConflictResolution ResolveDuplicate(OutlookContactInfo outlookContact, List<Contact> googleContacts, out Contact googleContact)
        {
            string name = ContactMatch.GetName(outlookContact);

            _form.messageLabel.Text =
                     "There are multiple Google Contacts (" + googleContacts.Count + ") matching unique properties for Outlook Contact \"" + name +
                     "\". Please choose from the combobox below the Google Contact you would like to match with Outlook and if you want to keep the Google or Outlook properties of the selected contact.";

            _form.OutlookItemTextBox.Text = string.Empty;
            _form.GoogleItemTextBox.Text = string.Empty;

            Microsoft.Office.Interop.Outlook.ContactItem item = outlookContact.GetOriginalItemFromOutlook();
            try
            {
                _form.OutlookItemTextBox.Text = ContactMatch.GetSummary(item);
            }
            finally
            {
                if (item != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(item);
                    item = null;
                }
            }

            _form.GoogleComboBox.DataSource = googleContacts;
            _form.GoogleComboBox.Visible = true;
            _form.AllCheckBox.Visible = false;
            _form.skip.Text = "Keep both";

            ConflictResolution res = Resolve();
            googleContact = _form.GoogleComboBox.SelectedItem as Contact;

            return res;
        }
예제 #9
0
        public DeleteResolution ResolveDelete(OutlookContactInfo outlookContact)
        {
            string name = ContactMatch.GetName(outlookContact);

            _form.Text = "Google Contact deleted";
            _form.messageLabel.Text =
                "Google Contact \"" + name +
                "\" doesn't exist anymore. Do you want to delete it also on Outlook side?";

            _form.OutlookItemTextBox.Text = string.Empty;
            _form.GoogleItemTextBox.Text = string.Empty;
            Microsoft.Office.Interop.Outlook.ContactItem item = outlookContact.GetOriginalItemFromOutlook();
            try
            {
                _form.OutlookItemTextBox.Text = ContactMatch.GetSummary(item);
            }
            finally
            {
                if (item != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(item);
                    item = null;
                }
            }

            _form.keepOutlook.Text = "Keep Outlook";
            _form.keepGoogle.Text = "Delete Outlook";
            _form.skip.Enabled = false;

            return ResolveDeletedGoogle();
        }