예제 #1
0
        /// <summary>
        /// Config Datei wird eingelesen und für für jedes Postfach werden die Jahrestage und Geburtstage überprüft und syncroniesiert.
        /// Danach werden die Kontakte Syncronisiert.
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Config config = ReadConfig();

            ExchangeSync.writeLog("##################################################################");

            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();

            foreach (var m in config.mailboxes)
            {
                ExchangeSync.writeLog("---------- " + m.smtpAdresse.ToUpper() + " ----------");
                ExchangeService service = ExchangeConnect(config.username, config.password, config.domain, m.smtpAdresse, config.exUri);

                if (m.birthday || m.anniversary)
                {
                    ExchangeSync.writeLog("---------- SyncRun Start - Appointment ----------");
                    Stopwatch sWatch = new Stopwatch();
                    sWatch.Start();

                    var BASync = new AppointmentSync(service, m.smtpAdresse);

                    // Aktiviren wenn alle Termine gelöscht werden sollen
                    //BASync.runDelete();

                    if (m.birthday)
                    {
                        BASync.runBirthdaySync();
                    }
                    if (m.anniversary)
                    {
                        BASync.runAnniversarySync();
                    }

                    sWatch.Stop();
                    ExchangeSync.writeLog("---------- SyncRun End - " + stopWatch.Elapsed + " ----------");
                }

                if (m.folder.Count > 0 && m.folder[0] != "")
                {
                    foreach (var f in m.folder)
                    {
                        var SyncRun = new ExchangeSync(service, m.smtpAdresse, f);
                        SyncRun.writePublicIdInExProp();
                        bool changes = SyncRun.Sync();

                        if (changes)
                        {
                            MatchingList.Create(service, m.smtpAdresse, f);
                            ExchangeSync.writeLog("Matching List created: " + m.smtpAdresse + " - " + f);
                        }
                    }
                }
            }

            stopWatch.Stop();
            ExchangeSync.writeLog("Complete Sync - Time: " + stopWatch.Elapsed);
        }
예제 #2
0
        /// <summary>
        /// <h2>Hauptfunktion</h2>
        /// Hier werden die SyncStates der einzelnen Ordner verglichen und verarbeitet.
        /// Das alles wird umspannt von einer Stopuhr um im Log eine Ausgabe zu haben wie viel Zeit für jeden SyncRun gebraucht wird.
        /// <h3>LOCAL SYNC</h3>
        /// Zuerst wird der Kontakt Ordner im Postfach bearbeitet.
        /// Dazu wird der gespeicherte SyncStatus vom letzten Durchgang gelesen und mit dem aktuellen Status verglichen.
        /// In einer Schleife wird dann über jede erfasste änderung gegangen und in verschiedenen if Abfragen verarbeitet.
        /// Da die SyncStatus Abfrage nur 512 Änderungen zurückgibt, muss die Schleife so lange wiederholt werden bis es keine Änderungen mehr gibt.
        /// <ul>
        /// <li>Create : Kontakt wird wieder gelöscht</li>
        /// <li>Update : Werden aktuell ignoriert da der ChacheModus von Outlook auch immer wieder Änderungen vornimmt.</li>
        /// <li>Delete : Vom gelöschten Kontakt wird das public Pendant in der MatchingListe gesucht. Danach wird der Kontakt aus dem öffentlichen Ordner wieder kopiert.</li>
        /// </ul>
        /// <h3>PUBLIC SYNC</h3>
        /// Als Zweites wird der öffentliche Ordner bearbeitet.
        /// <i>siehe LOCAL SYNC</i>
        /// <ul>
        /// <li>Create : Kontakt wird in das Postfach kopiert.</li>
        /// <li>Update : Kontakt wird in der MatchingListe gesucht. Pendant im Postfach wird gelöscht und aus dem öffentlichen Ordner wieder kopiert.</li>
        /// <li>Delete : Kontakt wird in der MatchingListe gesucht. Pendant wird im Postfach gesucht und gelöscht. Es wird mit dem AppointmentSync der Jahrestag und Geburtstag aus dem Kalender gelöscht.</li>
        /// </ul>
        /// <h3>GET AND SET LOCAL SYNC</h3>
        /// Hier wird noch mal über die Änderungen im Postfach Ordner gegangen aber nichts bearbeitet. Nach der Schleife wird der neue SyncStatus für das Postfach geschrieben.
        /// Das muss im nach dem PUBLIC SYNC nochmal passieren das dur den PUBLIC SYNC änderungen am Postfach Ordner vorgenommen werden können.
        /// </summary>
        /// <returns>Gibt zurück ob min. eine Änderung gemacht worden ist</returns>
        public bool Sync()
        {
            var changeValue = false;

            if (service != null)
            {
                var PublicContactFolder = getPublicFolder();

                writeLog("---------- SyncRun Start - " + ContactFolderName + " ----------");
                Stopwatch stopWatch = new Stopwatch();
                stopWatch.Start();

                #region LOCAL SYNC
                bool isEndOfChanges = false;
                var  localSyncState = getSyncState(false, SMTPAdresse); // Ist null falls Initialer SyncRun

                var MailboxContactFolder = getMailboxFolder(localSyncState == null);

                //makeChangeKey(SMTPAdresse, MailboxContactFolder.Id, "Anfang"); // DEBUG
                do
                {
                    ChangeCollection <ItemChange> icc_mailbox = service.SyncFolderItems(MailboxContactFolder.Id, PropertySet.FirstClassProperties, null, 512, SyncFolderItemsScope.NormalItems, localSyncState);

                    if (icc_mailbox.Count != 0)
                    {
                        changeValue = true;
                        var c = 0;
                        var u = 0;
                        var d = 0;
                        //writeLog(SMTPAdresse + " - " + icc_mailbox.Count + " changes in own mailbox folder");

                        foreach (ItemChange ic_mailbox in icc_mailbox)
                        {
                            Console.WriteLine(ic_mailbox.ChangeType);
                            try
                            {
                                //changeKeys += ic_mailbox.ChangeType + "_" + ic_mailbox.Item.Subject + "_" + ic_mailbox.ItemId.ChangeKey + System.Environment.NewLine; //DEBUG
                            }
                            catch (Exception) {}


                            if (ic_mailbox.ChangeType == ChangeType.Create)
                            {
                                c++;
                                try
                                {
                                    Contact contacts = Contact.Bind(service, ic_mailbox.ItemId);
                                    //writeLog(contacts.Subject + " - Create");
                                    contacts.Delete(DeleteMode.HardDelete);
                                }
                                catch (Exception ex)
                                {
                                    writeLog("ERROR: LocalSync Create: " + ex.Message);
                                }


                                //Console.WriteLine(SMTPAdresse + " - LocalChange " + contacts.Subject + " was created locally and removed automatically");
                            }
                            else if (ic_mailbox.ChangeType == ChangeType.Update)
                            {
                                u++;
                                // Wird nicht benutzt da der ChacheModus von Outlook die ChangeKeys ändert und damit ca alle 30min ein InitialerSync stattfindet
                                // Evtl eigenen Hash über Felder sobalt die Kontakte aus SAP kommen alternativ anderes Feld mit dem letzten Änderungsdatum.
                                // Lokale Änderungen würden sowieso nicht zurück in den Öffentlichen Ordner geschrieben, sondern nur mit den Daten von dort ersetzt werden.
                                // Damit werden lokale Änderungen (z.B Name, Tel ... ) vom Benutzer nicht mehr berücksichtigt, sondern nur noch Create und Delete.

                                //try
                                //{
                                //    Contact contacts = Contact.Bind(service, ic_mailbox.ItemId);
                                //    //writeLog(contacts.Subject + " - Update");

                                //    contacts.Delete(DeleteMode.HardDelete);

                                //    var MailboxId = ic_mailbox.ItemId.UniqueId;
                                //    List<Matching> matchingList = MatchingList.GetList(SMTPAdresse, ContactFolderName);
                                //    Matching result = matchingList.Find(x => x.MailboxId == MailboxId);

                                //    Contact PublicContacts = Contact.Bind(service, result.PublicId);
                                //    PublicContacts.Copy(MailboxContactFolder.Id);
                                //}
                                //catch (Exception ex)
                                //{
                                //    writeLog("ERROR: LocalSync Update: " + ex.Message);
                                //}
                            }
                            else if (ic_mailbox.ChangeType == ChangeType.Delete)
                            {
                                d++;
                                var MailboxId = ic_mailbox.ItemId.UniqueId;

                                try
                                {
                                    List <Matching> matchingList = MatchingList.GetList(SMTPAdresse, ContactFolderName);
                                    Matching        result       = matchingList.Find(x => x.MailboxId == MailboxId);

                                    if (result == null)
                                    {
                                        writeLog("ERROR: No match in MatchingList for: " + MailboxId);
                                    }
                                    else
                                    {
                                        Contact contacts = Contact.Bind(service, result.PublicId);
                                        //writeLog(contacts.Subject + " - Delete");
                                        contacts.Copy(MailboxContactFolder.Id);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    writeLog("ERROR: LocalSync Delete: " + ex.Message);
                                }
                            }
                        }

                        writeLog(SMTPAdresse + " - " + icc_mailbox.Count + " changes (" + c + " created, " + u + " updated, " + d + " deleted) in own mailbox folder");
                        writeLog("LOCAL UPDATES ARE IGNORED!");
                    }

                    localSyncState = icc_mailbox.SyncState;

                    if (!icc_mailbox.MoreChangesAvailable)
                    {
                        isEndOfChanges = true;
                    }
                } while (!isEndOfChanges);

                // DEBUG
                //Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
                //File.WriteAllText(binaryPath + @"\changeKeys\ChangeKeys_" + ContactFolderName + SMTPAdresse + "_" + unixTimestamp, changeKeys);

                writeSyncState(localSyncState, false, SMTPAdresse);
                #endregion

                #region PUBLIC SYNC
                bool isEndOfChangesPublic = false;
                var  sSyncState           = getSyncState(true, SMTPAdresse);
                var  index = 0;

                do
                {
                    ChangeCollection <ItemChange> icc = service.SyncFolderItems(PublicContactFolder.Id, PropertySet.FirstClassProperties, null, 512, SyncFolderItemsScope.NormalItems, sSyncState);

                    if (icc.Count == 0)
                    {
                        writeLog(SMTPAdresse + " - There are no item changes to synchronize.");
                    }
                    else
                    {
                        var c = 0;
                        var u = 0;
                        var d = 0;
                        changeValue = true;
                        //writeLog(SMTPAdresse + " - " + icc.Count + " changes in public folder");

                        foreach (ItemChange ic in icc)
                        {
                            if (ic.ChangeType == ChangeType.Create)
                            {
                                c++;
                                try
                                {
                                    Contact contacts = Contact.Bind(service, ic.ItemId);
                                    contacts.Copy(MailboxContactFolder.Id);
                                }
                                catch (Exception ex)
                                {
                                    writeLog("ERROR: ExchangeSync.cs - 152: " + ic.Item.Subject + " - " + ex.Message);
                                }
                            }
                            else if (ic.ChangeType == ChangeType.Update)
                            {
                                u++;
                                try
                                {
                                    List <Matching> matchingList = MatchingList.GetList(SMTPAdresse, ContactFolderName);
                                    Matching        result       = matchingList.Find(x => x.PublicId == ic.ItemId.UniqueId);

                                    Contact LocalContact = Contact.Bind(service, result.MailboxId);
                                    LocalContact.Delete(DeleteMode.HardDelete);

                                    Contact PublicContact = Contact.Bind(service, ic.ItemId);
                                    PublicContact.Copy(MailboxContactFolder.Id);
                                }
                                catch (Exception ex)
                                {
                                    writeLog("ExchangeSync.cs - 265: " + ic.Item.Subject + " - " + ex.Message);
                                }

                                //Console.WriteLine(SMTPAdresse + " - " + index + " - PublicChange " + contacts.Subject + " was updated in public and updated in the mailbox");
                            }
                            else if (ic.ChangeType == ChangeType.Delete)
                            {
                                d++;
                                var PublicId = ic.ItemId.UniqueId;



                                List <Matching> matchingList = MatchingList.GetList(SMTPAdresse, ContactFolderName);

                                if (matchingList != null)
                                {
                                    try
                                    {
                                        Matching result = matchingList.Find(x => x.PublicId == PublicId);

                                        // Löscht nur die Geburtstage und Jahrestage bei Arges Intern Kontakten
                                        if (ContactFolderName == "Arges Intern")
                                        {
                                            var BASync = new AppointmentSync(service, SMTPAdresse);
                                            BASync.deleteName(result.Subject);
                                        }

                                        Contact contacts = Contact.Bind(service, result.MailboxId);
                                        contacts.Delete(DeleteMode.HardDelete);
                                    }
                                    catch (Exception ex)
                                    {
                                        writeLog("ERROR: ExchangeSync.cs - 187: " + ex.Message);
                                    }
                                }
                                else
                                {
                                    writeLog(SMTPAdresse + " - Mailbox MatchingListe konnte nicht geladen werden");
                                }


                                //Contact contacts = Contact.Bind(service, ic.ItemId);

                                //SearchFilter.IsEqualTo filter2 = new SearchFilter.IsEqualTo(ItemSchema.Subject, contacts.Subject);
                                //FindItemsResults<Item> findResults = service.FindItems(MailboxContactFolder.Id, filter2, new ItemView(1));
                                //foreach (Contact item in findResults.Items)
                                //{
                                //    item.Delete(DeleteMode.HardDelete);
                                //}
                            }

                            //var OutputText = index + " - " + ic.ChangeType.ToString() + " - ";
                            //if (ic.Item != null) { OutputText += ic.Item.Subject; }
                            //Console.WriteLine(OutputText);

                            if (index % 50 == 0)
                            {
                                Console.WriteLine("SyncIndex: " + index);
                            }

                            index++;
                        }

                        writeLog(SMTPAdresse + " - " + icc.Count + " changes (" + c + " created, " + u + " updated, " + d + " deleted) in public folder");
                    }

                    sSyncState = icc.SyncState;

                    if (!icc.MoreChangesAvailable)
                    {
                        isEndOfChangesPublic = true;
                    }
                } while (!isEndOfChangesPublic);

                writeSyncState(sSyncState, true, SMTPAdresse);
                #endregion

                #region GET AND SET LOCAL SYNC
                bool isEndOfChangesLocal = false;
                var  sSyncStateLocal     = getSyncState(false, SMTPAdresse);

                do
                {
                    ChangeCollection <ItemChange> icc_mailbox2 = service.SyncFolderItems(MailboxContactFolder.Id, PropertySet.FirstClassProperties, null, 512, SyncFolderItemsScope.NormalItems, sSyncStateLocal);
                    sSyncStateLocal = icc_mailbox2.SyncState;

                    if (!icc_mailbox2.MoreChangesAvailable)
                    {
                        isEndOfChangesLocal = true;
                    }
                } while (!isEndOfChangesLocal);



                writeSyncState(sSyncStateLocal, false, SMTPAdresse);

                //writeSyncState(localSyncState, false, SMTPAdresse);
                #endregion


                //makeChangeKey(SMTPAdresse, MailboxContactFolder.Id, "Ende"); // DEBUG

                stopWatch.Stop();
                writeLog("---------- SyncRun End - " + stopWatch.Elapsed + " ----------");
            }
            return(changeValue);
        }