/// <summary>
        /// Checks the server for new, updated and deleted items and returns them.
        /// </summary>
        /// <returns>A collection with all new, updated and deleted items on serverside.</returns>
        public AppointmentSyncCollection GetUpdates()
        {
            AppointmentSyncCollection returnCollection   = new AppointmentSyncCollection();
            List <CalDavElement>      responseListCalDav = GetAllItemsFromServer();

            //Check for new and updated items
            foreach (var remoteitem in responseListCalDav)
            {
                String foundETag = _localStorage.FindEtag(remoteitem.Guid);
                if (foundETag == null)
                {
                    returnCollection.AddList.Add(CalDavElementToAppointmentItemConverter.Convert(remoteitem));
                    _localStorage.WriteEntry(remoteitem.Guid, remoteitem.ETag, remoteitem.Url);
                }
                else if (foundETag != remoteitem.ETag)
                {
                    returnCollection.UpdateList.Add(CalDavElementToAppointmentItemConverter.Convert(remoteitem));
                    _localStorage.EditETag(remoteitem.Guid, remoteitem.ETag);
                }
            }
            ;

            //Check for deleted items
            Boolean            deleted;
            OutlookAppointment deletedAppointment = new OutlookAppointment();
            List <String>      guidsToDelete      = new List <String>();

            foreach (var localitem in _localStorage.GetAll())
            {
                deleted = true;
                foreach (var remoteitem in responseListCalDav)
                {
                    if (remoteitem.Guid.Equals(localitem.Key))
                    {
                        deleted = false;
                    }
                }
                if (deleted)
                {
                    deletedAppointment.SyncID = localitem.Key;
                    returnCollection.DeleteList.Add(deletedAppointment);
                    guidsToDelete.Add(localitem.Key);
                }
            }
            foreach (var item in guidsToDelete)
            {
                _localStorage.DeleteEntry(item);
            }

            return(returnCollection);
        }
        /// <summary>
        /// Returns an AppointmentSyncCollection of the full calendar
        /// </summary>
        /// <returns>AppointmentSyncCollection, with all appointments as "add"</returns>
        public AppointmentSyncCollection GetInitialSync()
        {
            if (_customCalendar == null)
            {
                return(null);
            }
            AppointmentSyncCollection syncCollection = GetUpdates(DateTime.MinValue);

            // this is a request for a full inital sync, so there are no "updates" or "delete", but only "adds"
            syncCollection.AddList.AddRange(syncCollection.UpdateList);
            syncCollection.UpdateList.Clear();
            syncCollection.DeleteList.Clear();

            return(syncCollection);
        }
        /// <summary>
        /// Drops an existing database, creates a new one, fetches all ics elements from server,
        /// writes their etags, uids and urls to the database, converts the ics to Outlook Appointments
        /// and returns them.
        /// </summary>
        /// <returns>A collection of all appointments on serverside.</returns>
        public AppointmentSyncCollection GetInitialSync()
        {
            _localStorage.RebuildDatabase();

            AppointmentSyncCollection responseList       = new AppointmentSyncCollection();
            List <CalDavElement>      responseListCalDav = GetAllItemsFromServer();

            responseListCalDav.ForEach(delegate(CalDavElement element)
            {
                _localStorage.WriteEntry(element.Guid, element.ETag, element.Url);
                responseList.AddList.Add(CalDavElementToAppointmentItemConverter.Convert(element));
            });

            return(responseList);
        }
        /// <summary>
        /// Applies all the updates to the calendar
        /// </summary>
        /// <param name="syncItems"></param>
        /// <returns>null</returns>
        public Dictionary <string, string> DoUpdates(AppointmentSyncCollection syncItems)
        {
            if (syncItems == null || _customCalendar == null)
            {
                return(null);
            }

            // add new appointments
            if (syncItems.AddList != null)
            {
                foreach (OutlookAppointment appointment in syncItems.AddList)
                {
                    CreateAppointment(appointment);
                }
            }

            // update appointments
            if (syncItems.UpdateList != null)
            {
                foreach (OutlookAppointment appointment in syncItems.UpdateList)
                {
                    UpdateAppointment(appointment);
                }
            }

            // delete appointments
            if (syncItems.DeleteList != null)
            {
                foreach (OutlookAppointment appointment in syncItems.DeleteList)
                {
                    DeleteAppointment(appointment);
                }
            }

            Debug.WriteLine("CalendarHandler (DoUpdates): Added: " + syncItems.AddList.Count + " | Updated: " + syncItems.UpdateList.Count + " | Deleted: " + syncItems.DeleteList.Count);

            return(null);
        }
        /// <summary>
        /// Returns a AppointmentSyncCollection, with all updates since the specified timestamp
        /// </summary>
        /// <param name="timestamp"></param>
        /// <returns></returns>
        private AppointmentSyncCollection GetUpdates(DateTime timestamp)
        {
            if (_customCalendar == null)
            {
                return(null);
            }
            AppointmentSyncCollection syncCollection = new AppointmentSyncCollection();

            // Debug.WriteLine("CalendarHandler: TimeStamp -> " + timestamp);

            foreach (Outlook.AppointmentItem item in _customCalendar.Items)
            {
                Boolean updatedBySync = false;

                //Debug.WriteLine("CalendarHandler: Item (" + item.Subject + ") LastModificationTime -> " + item.LastModificationTime);

                // if the date from the SYNC_UPDATE is newer or as the LastModificationTime, the item was not updated by the user
                if (item.ItemProperties[ITEM_PROPERTY_SYNC_UPDATE] != null && DateTime.Parse(item.ItemProperties[ITEM_PROPERTY_SYNC_UPDATE].Value) >= item.LastModificationTime)
                {
                    updatedBySync = true;
                }

                //Debug.WriteLine("CalendarHandler: Item (" + item.Subject + ") SyncUpdate -> " + syncUpdate);
                //Debug.WriteLine("CalendarHandler: Item (" + item.Subject + ") wasUpdatedBySync -> " + wasUpdatedBySync);

                if (item.LastModificationTime >= timestamp && !updatedBySync)
                {
                    // ADDING
                    // if SyncID does not exist, it is not yet synced and needs to be added to the other calendar
                    if (item.ItemProperties[ITEM_PROPERTY_SYNC_ID] == null)
                    {
                        syncCollection.AddList.Add(new OutlookAppointment(item));

                        if (item.ItemProperties[ITEM_PROPERTY_GLOBAL_A_ID] == null)
                        {
                            // GAI (GlobalAppointmentID) needs to be added as item property, otherwise it cannot be found later
                            Outlook.ItemProperty newProp = item.ItemProperties.Add(ITEM_PROPERTY_GLOBAL_A_ID, Outlook.OlUserPropertyType.olText);
                            item.Save();
                            newProp.Value = item.GlobalAppointmentID;
                            item.Save();
                        }
                    }

                    // UPDATING
                    // if a SyncID exist, it is already synced and needs to be updated in the other calendar
                    else
                    {
                        syncCollection.UpdateList.Add(new OutlookAppointment(item));
                    }
                }
            }

            // DELETING
            foreach (String syncID in GetAppointmentsForDeleting())
            {
                OutlookAppointment item = new OutlookAppointment();
                item.SyncID = syncID;
                syncCollection.DeleteList.Add(item);
            }

            Debug.WriteLine("CalendarHandler (GetUpdates): Added: " + syncCollection.AddList.Count + " | Updated: " + syncCollection.UpdateList.Count + " | Deleted: " + syncCollection.DeleteList.Count);

            ResetDeleteStorage();
            SetSyncTime(DateTime.Now);

            return(syncCollection);
        }
        /// <summary>
        /// Writes the items added, updated and deleted in Outlook back to the server.
        /// </summary>
        /// <param name="syncItems">A collection with all new, updated and deleted items on Outlook side.</param>
        /// <returns>The servers SyncIDs for items newly added in Outlook as dictionary.</returns>
        public Dictionary <string, string> DoUpdates(AppointmentSyncCollection syncItems)
        {
            Dictionary <string, string> newSyncIds = new Dictionary <string, string>();

            //Delete items from server
            foreach (var deleteItem in syncItems.DeleteList)
            {
                if (_localStorage.FindUrl(deleteItem.SyncID) != null && !_localStorage.FindUrl(deleteItem.SyncID).Equals(""))
                {
                    try
                    {
                        this.QueryCaldavServer("DELETE", new WebHeaderCollection(), "", null, _localStorage.FindUrl(deleteItem.SyncID));
                    } catch (WebException e) {
                        Debug.WriteLine(e.Message);
                        MessageBox.Show("The following error occurred: " + e.Message);
                    }
                    _localStorage.DeleteEntry(deleteItem.SyncID);
                }
            }

            //Update items on server
            foreach (var updateItem in syncItems.UpdateList)
            {
                if (_localStorage.FindUrl(updateItem.SyncID) != null && !_localStorage.FindUrl(updateItem.SyncID).Equals(""))
                {
                    try
                    {
                        this.QueryCaldavServer("PUT", new WebHeaderCollection(), AppointmentItemXmlParser.Parse(updateItem), "text/calendar", _localStorage.FindUrl(updateItem.SyncID));
                    }
                    catch (WebException e)
                    {
                        Debug.WriteLine(e.Message);
                        MessageBox.Show("The following error occurred: " + e.Message);
                    }
                    _localStorage.EditETag(updateItem.SyncID, GetSingleItemFromServer(_localStorage.FindUrl(updateItem.SyncID)).ETag);
                }
            }

            //Add items to server
            foreach (var addItem in syncItems.AddList)
            {
                String guid = System.Guid.NewGuid().ToString();
                addItem.SyncID = guid;
                newSyncIds.Add(addItem.GlobalAppointmentID, guid);
                String url = guid + ".ics";
                try
                {
                    this.QueryCaldavServer("PUT", new WebHeaderCollection(), AppointmentItemXmlParser.Parse(addItem), "text/calendar", url);
                    string        url_corrected = CheckSlashAtEnd(new Uri(calendarUrl).PathAndQuery) + url;
                    CalDavElement newElement    = GetSingleItemFromServer(url_corrected);
                    _localStorage.WriteEntry(guid, newElement.ETag, newElement.Url);
                }
                catch (WebException e)
                {
                    Debug.WriteLine(e.Message);
                    MessageBox.Show("The following error occurred: " + e.Message);
                }
            }

            //Return the dictionary with the new SyncIDs
            return(newSyncIds);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Synchronizes both calendars.
        /// </summary>
        private void Synchronize()
        {
            Debug.WriteLine("----------------------------------");
            Debug.WriteLine("SyncService: Started Synchronize(" + DateTime.Now + ")");

            // checking if another sync is already running
            if (!_isRunning)
            {
                _isRunning = true;

                //Get changes since last snyc
                AppointmentSyncCollection _externalGetUpdates = _syncExternal.GetUpdates();
                AppointmentSyncCollection _outlookGetUpdates  = _syncOutlook.GetUpdates();

                //Find updating conflicts and solve them
                List <OutlookAppointment> deleteFromOutlookCollection  = new List <OutlookAppointment>();
                List <OutlookAppointment> deleteFromExternalCollection = new List <OutlookAppointment>();
                if (_outlookGetUpdates.UpdateList.Count > 0 && _externalGetUpdates.UpdateList.Count > 0)
                {
                    foreach (var itemOutlook in _outlookGetUpdates.UpdateList)
                    {
                        foreach (var itemExternal in _externalGetUpdates.UpdateList)
                        {
                            if (itemOutlook.SyncID.Equals(itemExternal.SyncID))
                            {
                                int comparison = DateTime.Compare(itemOutlook.LastModificationTime, itemExternal.LastModificationTime);
                                //Item was edited in Outlook prior to the external source or at the same time --> external wins
                                if (comparison <= 0)
                                {
                                    deleteFromOutlookCollection.Add(itemOutlook);
                                }
                                //Item was edited in Outlook after last modification on external source --> outlook wins
                                else
                                {
                                    deleteFromExternalCollection.Add(itemExternal);
                                }
                            }
                        }
                    }
                    foreach (var item in deleteFromExternalCollection)
                    {
                        _externalGetUpdates.UpdateList.Remove(item);
                    }
                    foreach (var item in deleteFromOutlookCollection)
                    {
                        _outlookGetUpdates.UpdateList.Remove(item);
                    }
                }


                //Write the changes to the destinations
                _syncOutlook.DoUpdates(_externalGetUpdates);
                //Debug.WriteLine("SyncService: Processed _syncOutlook.DoUpdates(_externalGetUpdates)");

                _syncOutlook.UpdateSyncIDs(_syncExternal.DoUpdates(_outlookGetUpdates));
                //Debug.WriteLine("SyncService: Processed _syncOutlook.UpdateSyncIDs()");

                _isRunning = false;
            }
            else
            {
                Debug.WriteLine("SyncService: Synchronize() not processed, it is already running");
            }

            Debug.WriteLine("SyncService: Finished Synchronize()");
        }