private void ClearSyncHistory(object parameter)
 {
     SyncDbUtils.DeleteSyncHistory();
     SyncHistoryList.Clear();
     // ReSharper disable once ExplicitCallerInfoArgument
     RaisePropertyChanged(nameof(SyncHistoryList));
 }
Ejemplo n.º 2
0
        public SyncStatusPageViewModel(INavigationService navigationService, IResourceLoader resourceLoader, DialogService dialogService)
        {
            ToastNotificationManager.History.RemoveGroup(ToastNotificationService.SYNCACTION);
            ToastNotificationManager.History.RemoveGroup(ToastNotificationService.SYNCONFLICTACTION);
            _navigationService = navigationService;
            _resourceLoader    = resourceLoader;
            _dialogService     = dialogService;

            FixConflictByLocalCommand  = new RelayCommand(FixConflictByLocal, CanExecuteFixConflict);
            FixConflictByRemoteCommand = new RelayCommand(FixConflictByRemote, CanExecuteFixConflict);
            ClearSyncHistoryCommand    = new RelayCommand(ClearSyncHistory);

            SyncHistoryList = new ObservableCollection <SyncHistory>();
            ConflictList    = new ObservableCollection <SyncInfoDetail>();
            ErrorList       = new ObservableCollection <SyncInfoDetail>();
            FolderSyncList  = new ObservableCollection <FolderSyncInfo>();

            List <SyncHistory> history = SyncDbUtils.GetSyncHistory();

            history.ForEach(x => SyncHistoryList.Add(x));

            List <SyncInfoDetail> conflicts = SyncDbUtils.GetConflicts();

            conflicts.ForEach(x => ConflictList.Add(x));

            List <SyncInfoDetail> errors = SyncDbUtils.GetErrors();

            errors.ForEach(x => ErrorList.Add(x));
            List <FolderSyncInfo> fsis = SyncDbUtils.GetAllFolderSyncInfos();

            fsis.ForEach(x => FolderSyncList.Add(x));
        }
        public SyncStatusPageViewModel(IResourceLoader resourceLoader, DialogService dialogService)
        {
            ToastNotificationManager.History.RemoveGroup(ToastNotificationService.SyncAction);
            ToastNotificationManager.History.RemoveGroup(ToastNotificationService.SyncConflictAction);
            _resourceLoader = resourceLoader;
            _dialogService  = dialogService;

            FixConflictByLocalCommand    = new RelayCommand(FixConflictByLocal, CanExecuteFixConflict);
            FixConflictByRemoteCommand   = new RelayCommand(FixConflictByRemote, CanExecuteFixConflict);
            FixConflictByKeepAsIsCommand = new RelayCommand(FixConflictByKeepAsIs, CanExecuteFixConflict);
            ClearSyncHistoryCommand      = new RelayCommand(ClearSyncHistory);
            CheckAllCommand   = new RelayCommand(CheckAll);
            UncheckAllCommand = new RelayCommand(UncheckAll);

            SyncHistoryList = new ObservableCollection <SyncHistory>();
            ConflictList    = new ObservableCollection <SyncInfoDetail>();
            ErrorList       = new ObservableCollection <SyncInfoDetail>();
            FolderSyncList  = new ObservableCollection <FolderSyncInfo>();

            var history = SyncDbUtils.GetSyncHistory();

            history.ForEach(x => SyncHistoryList.Add(x));

            var conflicts = SyncDbUtils.GetConflicts();

            conflicts.ForEach(x => ConflictList.Add(x));

            var errors = SyncDbUtils.GetErrors();

            errors.ForEach(x => ErrorList.Add(x));
            var fsis = SyncDbUtils.GetAllFolderSyncInfos();

            fsis.ForEach(x => FolderSyncList.Add(x));
        }
Ejemplo n.º 4
0
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var item = (ResourceInfo)value;

            if (SyncDbUtils.IsSynced(item))
            {
                return(ResourceLoader.GetForCurrentView().GetString(ResourceConstants.SynchronizeNow));
            }
            else
            {
                return(ResourceLoader.GetForCurrentView().GetString(ResourceConstants.SynchronizeStart));
            }
        }
Ejemplo n.º 5
0
        protected override Task OnSuspendingApplicationAsync()
        {
            var task = base.OnSuspendingApplicationAsync();
            // Stop Background Sync Tasks
            List <FolderSyncInfo> activeSyncs = SyncDbUtils.GetActiveSyncInfos();

            foreach (var fsi in activeSyncs)
            {
                ToastNotificationService.ShowSyncSuspendedNotification(fsi);
                SyncDbUtils.UnlockFolderSyncInfo(fsi);
            }
            return(task);
        }
Ejemplo n.º 6
0
        private void StopSynchronizeFolder(ResourceInfo resourceInfo)
        {
            if (resourceInfo == null)
            {
                return;
            }

            var syncInfo = SyncDbUtils.GetFolderSyncInfoByPath(resourceInfo.Path);

            if (syncInfo != null)
            {
                // If there exists an entry for this path - stop sync command has been triggered.
                SyncDbUtils.DeleteFolderSyncInfo(syncInfo);
                StartDirectoryListing(); // This is just to update the menu flyout - maybe there is a better way
            }
        }
        private async void FixConflictByKeepAsIs(object parameter)
        {
            var listView = parameter as ListView;

            if (listView == null)
            {
                return;
            }

            var selectedList = new List <SyncInfoDetail>();
            var usageHint    = false;

            foreach (SyncInfoDetail detail in listView.SelectedItems)
            {
                if (detail.ConflictType == ConflictType.BothChanged ||
                    detail.ConflictType == ConflictType.BothNew)
                {
                    detail.ConflictSolution = ConflictSolution.KeepAsIs;
                    SyncDbUtils.SaveSyncInfoDetail(detail);
                    selectedList.Add(detail);
                }
                else
                {
                    usageHint = true;
                }
            }

            selectedList.ForEach(x => ConflictList.Remove(x));
            if (!usageHint)
            {
                return;
            }
            var dialog = new ContentDialog
            {
                Title   = _resourceLoader.GetString("SyncKeepAsIsHintTitle"),
                Content = new TextBlock
                {
                    Text         = _resourceLoader.GetString("SyncKeepAsIsHintDesc"),
                    TextWrapping = TextWrapping.WrapWholeWords,
                    Margin       = new Thickness(0, 20, 0, 0)
                },
                PrimaryButtonText = _resourceLoader.GetString("OK")
            };
            await _dialogService.ShowAsync(dialog);
        }
Ejemplo n.º 8
0
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var item = DirectoryService.Instance.PathStack.Count > 0 ? DirectoryService.Instance.PathStack[DirectoryService.Instance.PathStack.Count - 1].ResourceInfo : null;

            if (item == null)
            {
                return(String.Empty);
            }

            if (SyncDbUtils.IsSynced(item))
            {
                return(ResourceLoader.GetForCurrentView().GetString(ResourceConstants.SynchronizeThisFolderNow));
            }
            else
            {
                return(ResourceLoader.GetForCurrentView().GetString(ResourceConstants.SynchronizeThisFolderStart));
            }
        }
Ejemplo n.º 9
0
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var invert = parameter != null;
            var item   = (ResourceInfo)value;

            if (item.ContentType == null || !item.ContentType.Equals("dav/directory"))
            {
                return(Visibility.Collapsed);
            }

            if (SyncDbUtils.IsSynced(item))
            {
                return(Visibility.Visible);
            }
            else
            {
                return(Visibility.Collapsed);
            }
        }
Ejemplo n.º 10
0
        private void FixConflictByRemote(object parameter)
        {
            var listView = parameter as ListView;

            if (listView == null)
            {
                return;
            }

            var selectedList = new List <SyncInfoDetail>();

            foreach (SyncInfoDetail detail in listView.SelectedItems)
            {
                detail.ConflictSolution = ConflictSolution.PreferRemote;
                SyncDbUtils.SaveSyncInfoDetail(detail);
                selectedList.Add(detail);
            }

            selectedList.ForEach(x => ConflictList.Remove(x));
        }
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var item = DirectoryService.Instance.PathStack.Count > 0 ? DirectoryService.Instance.PathStack[DirectoryService.Instance.PathStack.Count - 1].ResourceInfo : null;

            if (item == null)
            {
                return(false);
            }

            if (item.ContentType == null || !item.ContentType.Equals("dav/directory"))
            {
                return(false);
            }

            if (SyncDbUtils.IsSynced(item))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 12
0
        protected override Task OnSuspendingApplicationAsync()
        {
            var task = base.OnSuspendingApplicationAsync();
            // Stop Background Sync Tasks
            var activeSyncs = SyncDbUtils.GetActiveSyncInfos();

            if (SettingsLocal.PauseSyncInBackground)
            {
                foreach (var fsi in activeSyncs)
                {
                    ToastNotificationService.ShowSyncSuspendedNotification(fsi);
                    SyncDbUtils.UnlockFolderSyncInfo(fsi);
                }
            }
            else
            {
                foreach (var fsi in activeSyncs)
                {
                    ToastNotificationService.ShowSyncInBackgroundNotification(fsi);
                }
            }

            return(task);
        }
Ejemplo n.º 13
0
        public async Task <bool> StartSync()
        {
            if (!SyncDbUtils.LockFolderSyncInfo(folderSyncInfo))
            {
                return(false);
            }

            try
            {
                client = await ClientService.GetClient();

                if (client == null)
                {
                    // ERROR
                    throw new Exception("Error creating webdav client");
                }

                int changedCount = 0;
                List <SyncInfoDetail> oldList = SyncDbUtils.GetAllSyncInfoDetails(folderSyncInfo);
                Debug.WriteLine("Sid List before Sync: ");

                foreach (SyncInfoDetail detail in oldList)
                {
                    Debug.WriteLine("Detail: " + detail.ToString());
                }

                var sid        = SyncDbUtils.GetSyncInfoDetail(resourceInfo, folderSyncInfo);
                var errorCount = 0;

                try
                {
                    if (sid == null)
                    {
                        sid = new SyncInfoDetail(folderSyncInfo)
                        {
                            Path     = resourceInfo.Path,
                            FilePath = baseFolder.Path,
                        };

                        SyncDbUtils.SaveSyncInfoDetail(sid);
                    }
                    else
                    {
                        sidList.Remove(sid);
                        sid.Error = null;
                    }

                    changedCount = await SyncFolder(resourceInfo, baseFolder);

                    foreach (SyncInfoDetail detail in oldList)
                    {
                        if (!sidList.Contains(detail) && detail.FilePath.StartsWith(baseFolder.Path))
                        {
                            // The items left here must have been deleted both remotely and locally so the sid is obsolete.
                            SyncDbUtils.DeleteSyncInfoDetail(detail, false);
                            changedCount++;
                        }
                    }
                    errorCount = SyncDbUtils.GetErrorConflictCount(folderSyncInfo);
                }
                catch (Exception e)
                {
                    sid.Error = e.Message;
                    errorCount++;
                }

                SyncDbUtils.SaveSyncInfoDetail(sid);
                List <SyncInfoDetail> newSidList = SyncDbUtils.GetAllSyncInfoDetails(folderSyncInfo);
                Debug.WriteLine("Sid List after Sync: ");

                foreach (SyncInfoDetail detail in newSidList)
                {
                    Debug.WriteLine("Detail: " + detail.ToString());
                }

                ToastNotificationService.ShowSyncFinishedNotification(folderSyncInfo.Path, changedCount, errorCount);
                return(errorCount == 0);
            }
            finally
            {
                SyncDbUtils.UnlockFolderSyncInfo(folderSyncInfo);
            }
        }
Ejemplo n.º 14
0
 private void ClearSyncHistory(object parameter)
 {
     SyncDbUtils.DeleteSyncHistory();
     SyncHistoryList.Clear();
     RaisePropertyChanged(nameof(SyncHistoryList));
 }
        /// <summary>
        /// Folder Synchronization
        /// </summary>
        /// <param name="resourceInfo">webdav Resource to sync</param>
        /// <param name="folder">Target folder</param>
        private async Task <int> SyncFolder(ResourceInfo resourceInfo, StorageFolder folder)
        {
            var sid = SyncDbUtils.GetSyncInfoDetail(resourceInfo, _folderSyncInfo);

            sid.Error = null;
            var changesCount = 0;

            try
            {
                Debug.WriteLine("Sync folder " + resourceInfo.Path + ":" + folder.Path);
                var localFiles = await folder.GetFilesAsync();

                var localFolders = await folder.GetFoldersAsync();

                List <ResourceInfo> list = null;
                try
                {
                    list = await _client.List(resourceInfo.Path);
                }
                catch (ResponseError e)
                {
                    ResponseErrorHandlerService.HandleException(e);
                }

                var synced = new List <IStorageItem>();

                if (list != null && list.Count > 0)
                {
                    foreach (var subInfo in list)
                    {
                        if (subInfo.IsDirectory)
                        {
                            var localFoldersWithName = localFolders.Where(f => f.Name.Equals(subInfo.Name));
                            var subFolder            = localFoldersWithName.FirstOrDefault();
                            // Can localFoldersWithName be null?
                            if (subFolder == null)
                            {
                                var subSid = SyncDbUtils.GetSyncInfoDetail(subInfo, _folderSyncInfo);
                                if (subSid != null)
                                {
                                    Debug.WriteLine("Sync folder (delete remotely) " + subInfo.Path);
                                    if (await _client.Delete(subInfo.Path))
                                    {
                                        SyncDbUtils.DeleteSyncInfoDetail(subSid, true);
                                    }
                                    else
                                    {
                                        sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_DeleteFolderRemotely), subInfo.Path);
                                        // Error could be overridden by other errors
                                    }
                                }
                                else
                                {
                                    // Create sid and local folder
                                    Debug.WriteLine("Sync folder (create locally) " + subInfo.Path);
                                    subFolder = await folder.CreateFolderAsync(subInfo.Name);

                                    var syncInfoDetail = new SyncInfoDetail(_folderSyncInfo)
                                    {
                                        Path     = subInfo.Path,
                                        FilePath = subFolder.Path
                                    };

                                    SyncDbUtils.SaveSyncInfoDetail(syncInfoDetail);
                                    changesCount = changesCount + await SyncFolder(subInfo, subFolder);

                                    // syncTasks.Add(SyncFolder(subInfo, subFolder));
                                }
                            }
                            else
                            {
                                var subSid = SyncDbUtils.GetSyncInfoDetail(subInfo, _folderSyncInfo);
                                if (subSid == null)
                                {
                                    // Both new
                                    Debug.WriteLine("Sync folder (create both) " + subInfo.Path);

                                    var syncInfoDetail = new SyncInfoDetail(_folderSyncInfo)
                                    {
                                        Path     = subInfo.Path,
                                        FilePath = subFolder.Path
                                    };

                                    SyncDbUtils.SaveSyncInfoDetail(syncInfoDetail);
                                }
                                synced.Add(subFolder);
                                changesCount = changesCount + await SyncFolder(subInfo, subFolder);

                                // syncTasks.Add(SyncFolder(subInfo, subFolder));
                            }
                        }
                        else
                        {
                            var localFilessWithName = localFiles.Where(f => f.Name.Equals(subInfo.Name));
                            // Can localFilessWithName be null?
                            var subFile = localFilessWithName.FirstOrDefault();
                            if (subFile != null)
                            {
                                synced.Add(subFile);
                            }
                            changesCount = changesCount + await SyncFile(subInfo, subFile, resourceInfo, folder);

                            //syncTasks.Add(SyncFile(subInfo, subFile, info, folder));
                        }
                    }
                }
                foreach (var file in localFiles)
                {
                    if (!synced.Contains(file))
                    {
                        changesCount = changesCount + await SyncFile(null, file, resourceInfo, folder);

                        //syncTasks.Add(SyncFile(null, file, info, folder));
                    }
                }
                foreach (var localFolder in localFolders)
                {
                    if (synced.Contains(localFolder))
                    {
                        continue;
                    }
                    var subSid = SyncDbUtils.GetSyncInfoDetail(localFolder, _folderSyncInfo);
                    if (subSid != null)
                    {
                        // Delete all sids and local folder
                        Debug.WriteLine("Sync folder (delete locally) " + localFolder.Path);
                        await localFolder.DeleteAsync();

                        SyncDbUtils.DeleteSyncInfoDetail(subSid, true);
                    }
                    else
                    {
                        // Create sid and remotefolder
                        var newPath = resourceInfo.Path + localFolder.Name;
                        Debug.WriteLine("Sync folder (create remotely) " + newPath);

                        if (await _client.CreateDirectory(newPath))
                        {
                            var subInfo = await _client.GetResourceInfo(resourceInfo.Path, localFolder.Name);

                            var syncInfoDetail = new SyncInfoDetail(_folderSyncInfo)
                            {
                                Path     = subInfo.Path,
                                FilePath = localFolder.Path
                            };

                            SyncDbUtils.SaveSyncInfoDetail(syncInfoDetail);
                            changesCount = changesCount + await SyncFolder(subInfo, localFolder);

                            //syncTasks.Add(SyncFolder(subInfo, localFolder));
                        }
                        else
                        {
                            sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_CreateFolderRemotely), newPath);
                        }
                    }
                }
                //Task.WaitAll(syncTasks.ToArray());
            }
            catch (Exception e)
            {
                sid.Error = string.Format(_resourceLoader.GetString("UnexpectedException"), e.Message);
            }
            _sidList.Add(sid);
            SyncDbUtils.SaveSyncInfoDetail(sid);
            SyncDbUtils.SaveSyncHistory(sid);
            return(changesCount);
        }
        private async Task <int> SyncFile(ResourceInfo info, StorageFile file, ResourceInfo parent, StorageFolder parentFolder)
        {
            SyncInfoDetail sid     = null;
            var            changed = false;
            var            deleted = false;

            if (info != null)
            {
                sid = SyncDbUtils.GetSyncInfoDetail(info, _folderSyncInfo);
            }
            else if (file != null)
            {
                sid = SyncDbUtils.GetSyncInfoDetail(file, _folderSyncInfo);
            }
            if (sid == null)
            {
                sid = new SyncInfoDetail(_folderSyncInfo);
            }
            sid.Error        = null;
            sid.ConflictType = ConflictType.None;

            try
            {
                DateTimeOffset currentModified;
                if (file != null)
                {
                    var basicProperties = await file.GetBasicPropertiesAsync();

                    currentModified = basicProperties.DateModified;
                }

                if (sid.Path == null && sid.FilePath == null)
                {
                    if (file != null && info != null)
                    {
                        sid.Path         = info.Path + "/" + info.Name;
                        sid.FilePath     = file.Path;
                        sid.ConflictType = ConflictType.BothNew;
                        Debug.WriteLine("Sync file: Conflict (both new) " + info.Path + "/" + info.Name);
                    }
                    else if (file != null)
                    {
                        // Create sid and upload file
                        var newPath = parent.Path + file.Name;
                        Debug.WriteLine("Sync file (Upload)" + newPath);
                        sid.DateModified = currentModified;
                        sid.FilePath     = file.Path;
                        if (await UploadFile(file, newPath))
                        {
                            var newInfo = await _client.GetResourceInfo(parent.Path, file.Name);

                            sid.Path = newInfo.Path + "/" + newInfo.Name;
                            sid.ETag = newInfo.ETag;
                            changed  = true;
                        }
                        else
                        {
                            sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_UploadFile), file.Name);
                        }
                    }
                    else if (info != null)
                    {
                        // Create sid and download file
                        var localFile = await parentFolder.CreateFileAsync(info.Name);

                        Debug.WriteLine("Sync file (Download)" + localFile.Path);
                        if (await DownloadFile(localFile, info.Path + "/" + info.Name))
                        {
                            var basicProperties = await localFile.GetBasicPropertiesAsync();

                            currentModified  = basicProperties.DateModified;
                            sid.Path         = info.Path + "/" + info.Name;
                            sid.ETag         = info.ETag;
                            sid.DateModified = currentModified;
                            sid.FilePath     = localFile.Path;
                            changed          = true;
                        }
                        else
                        {
                            sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_DownloadFile), info.Name);
                        }
                    }
                }
                else
                {
                    if (info == null)
                    {
                        if (sid.DateModified != null && sid.DateModified.Value.Equals(currentModified))
                        {
                            Debug.WriteLine("Sync file (Delete locally) " + sid.Path);
                            // Remove sid and local file
                            if (file != null)
                            {
                                await file.DeleteAsync();
                            }
                            SyncDbUtils.DeleteSyncInfoDetail(sid, false);
                            changed = true;
                            deleted = true;
                        }
                        else
                        {
                            switch (sid.ConflictSolution)
                            {
                            case ConflictSolution.PreferLocal:
                                if (file != null)
                                {
                                    var newPath = parent.Path + file.Name;
                                    Debug.WriteLine("Sync file (Upload)" + newPath);
                                    sid.DateModified = currentModified;
                                    sid.FilePath     = file.Path;
                                    if (await UploadFile(file, newPath))
                                    {
                                        var newInfo = await _client.GetResourceInfo(parent.Path, file.Name);

                                        sid.Path             = newInfo.Path + "/" + newInfo.Name;
                                        sid.ETag             = newInfo.ETag;
                                        sid.ConflictSolution = ConflictSolution.None;
                                        changed = true;
                                    }
                                    else
                                    {
                                        sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_UploadFile), file.Name);
                                    }
                                }
                                break;

                            case ConflictSolution.PreferRemote:
                                Debug.WriteLine("Sync file (Delete locally) " + sid.Path);
                                // Remove sid and local file
                                if (file != null)
                                {
                                    await file.DeleteAsync();
                                }
                                SyncDbUtils.DeleteSyncInfoDetail(sid, false);
                                deleted = true;
                                changed = true;
                                break;

                            default:
                                Debug.WriteLine("Sync file: Conflict (Deleted remotely, but changed locally) " + sid.Path);
                                sid.ConflictType = ConflictType.RemoteDelLocalChange;
                                break;
                            }
                        }
                    }
                    else if (file == null)
                    {
                        if (sid.ETag == null || info.ETag.Equals(sid.ETag))
                        {
                            Debug.WriteLine("Sync file (Delete remotely) " + sid.Path);
                            // Remove sid and remote file
                            await _client.Delete(info.Path + "/" + info.Name);

                            SyncDbUtils.DeleteSyncInfoDetail(sid, false);
                            deleted = true;
                            changed = true;
                        }
                        else
                        {
                            switch (sid.ConflictSolution)
                            {
                            case ConflictSolution.PreferLocal:
                                Debug.WriteLine("Sync file (Delete remotely) " + sid.Path);
                                // Remove sid and remote file
                                await _client.Delete(info.Path + "/" + info.Name);

                                SyncDbUtils.DeleteSyncInfoDetail(sid, false);
                                deleted = true;
                                changed = true;
                                break;

                            case ConflictSolution.PreferRemote:
                                // Update local file
                                var localFile = await parentFolder.CreateFileAsync(info.Name);

                                Debug.WriteLine("Sync file (Download)" + localFile.Path);
                                if (await DownloadFile(localFile, info.Path + "/" + info.Name))
                                {
                                    var basicProperties = await localFile.GetBasicPropertiesAsync();

                                    currentModified      = basicProperties.DateModified;
                                    sid.ETag             = info.ETag;
                                    sid.DateModified     = currentModified;
                                    sid.ConflictSolution = ConflictSolution.None;
                                    changed = true;
                                }
                                else
                                {
                                    sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_DownloadFile), info.Name);
                                }
                                break;

                            default:
                                // Conflict
                                Debug.WriteLine("Sync file: Conflict (Deleted locally, but changed remotely) " + sid.Path);
                                sid.ConflictType = ConflictType.LocalDelRemoteChange;
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (currentModified.Equals(sid.DateModified))
                        {
                            if (!info.ETag.Equals(sid.ETag))
                            {
                                // Update local file
                                Debug.WriteLine("Sync file (update locally) " + info.Path + "/" + info.Name);
                                if (await DownloadFile(file, info.Path + "/" + info.Name))
                                {
                                    sid.ETag         = info.ETag;
                                    sid.DateModified = currentModified;
                                    changed          = true;
                                }
                                else
                                {
                                    sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_DownloadFile), info.Name);
                                }
                            }
                        }
                        else if (info.ETag.Equals(sid.ETag))
                        {
                            // update file on nextcloud
                            Debug.WriteLine("Sync file (update remotely) " + info.Path + "/" + info.Name);

                            if (await UploadFile(file, info.Path + "/" + info.Name))
                            {
                                var newInfo = await _client.GetResourceInfo(info.Path, info.Name);

                                sid.ETag         = newInfo.ETag;
                                sid.DateModified = currentModified;
                                changed          = true;
                            }
                            else
                            {
                                sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_UploadFile), info.Name);
                            }
                        }
                        else
                        {
                            switch (sid.ConflictSolution)
                            {
                            case ConflictSolution.PreferLocal:
                                // update file on nextcloud
                                Debug.WriteLine("Sync file (update remotely) " + info.Path + "/" + info.Name);

                                if (await UploadFile(file, info.Path + "/" + info.Name))
                                {
                                    var newInfo = await _client.GetResourceInfo(info.Path, info.Name);

                                    sid.ETag             = newInfo.ETag;
                                    sid.DateModified     = currentModified;
                                    sid.ConflictSolution = ConflictSolution.None;
                                    changed = true;
                                }
                                else
                                {
                                    sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_UploadFile), info.Name);
                                }
                                break;

                            case ConflictSolution.PreferRemote:
                                // Update local file
                                Debug.WriteLine("Sync file (update locally) " + info.Path + "/" + info.Name);
                                if (await DownloadFile(file, info.Path + "/" + info.Name))
                                {
                                    sid.ETag             = info.ETag;
                                    sid.DateModified     = currentModified;
                                    sid.ConflictSolution = ConflictSolution.None;
                                    changed = true;
                                }
                                else
                                {
                                    sid.Error = string.Format(_resourceLoader.GetString(ResourceConstants.SyncService_Error_DownloadFile), info.Name);
                                }
                                break;

                            case ConflictSolution.KeepAsIs:
                                sid.ETag             = info.ETag;
                                sid.DateModified     = currentModified;
                                sid.ConflictSolution = ConflictSolution.None;
                                break;

                            default:
                                // Conflict
                                if (sid.ETag == null && !sid.DateModified.HasValue)
                                {
                                    sid.ConflictType = ConflictType.BothNew;
                                    Debug.WriteLine("Sync file: Conflict (both new) " + info.Path + "/" + info.Name);
                                }
                                else
                                {
                                    Debug.WriteLine("Sync file: Conflict (Changed remotely and locally) " + sid.Path);
                                    sid.ConflictType = ConflictType.BothChanged;
                                }
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                // TODO: do not write only the raw exception message in the sid.Error.
                sid.Error = string.Format(_resourceLoader.GetString("UnexpectedException"), e.Message);
            }
            Debug.WriteLine("Synced file " + sid);
            _sidList.Add(sid);
            SyncDbUtils.SaveSyncHistory(sid);
            if (!deleted)
            {
                SyncDbUtils.SaveSyncInfoDetail(sid);
            }
            return(changed ? 1 : 0);
        }
        public async Task <bool> StartSync()
        {
            if (!SyncDbUtils.LockFolderSyncInfo(_folderSyncInfo))
            {
                return(false);
            }

            try
            {
                _client = await ClientService.GetClient();

                if (_client == null)
                {
                    // ERROR
                    throw new NullReferenceException(_resourceLoader.GetString(ResourceConstants.SyncService_Error_CannotCreateClient));
                }

                var changedCount = 0;
                var oldList      = SyncDbUtils.GetAllSyncInfoDetails(_folderSyncInfo);
                Debug.WriteLine("Sid List before Sync: ");

                foreach (var detail in oldList)
                {
                    Debug.WriteLine("Detail: " + detail);
                }

                var sid        = SyncDbUtils.GetSyncInfoDetail(_resourceInfo, _folderSyncInfo);
                var errorCount = 0;

                try
                {
                    if (sid == null)
                    {
                        sid = new SyncInfoDetail(_folderSyncInfo)
                        {
                            Path     = _resourceInfo.Path,
                            FilePath = _baseFolder.Path,
                        };

                        SyncDbUtils.SaveSyncInfoDetail(sid);
                    }
                    else
                    {
                        _sidList.Remove(sid);
                        sid.Error = null;
                    }

                    changedCount = await SyncFolder(_resourceInfo, _baseFolder);

                    foreach (var detail in oldList)
                    {
                        if (_sidList.Contains(detail) || !detail.FilePath.StartsWith(_baseFolder.Path))
                        {
                            continue;
                        }
                        // The items left here must have been deleted both remotely and locally so the sid is obsolete.
                        SyncDbUtils.DeleteSyncInfoDetail(detail, false);
                        changedCount++;
                    }
                    errorCount = SyncDbUtils.GetErrorConflictCount(_folderSyncInfo);
                }
                catch (Exception e)
                {
                    sid.Error = string.Format(_resourceLoader.GetString("UnexpectedException"), e.Message);
                    errorCount++;
                }

                SyncDbUtils.SaveSyncInfoDetail(sid);
                var newSidList = SyncDbUtils.GetAllSyncInfoDetails(_folderSyncInfo);
                Debug.WriteLine("Sid List after Sync: ");

                foreach (var detail in newSidList)
                {
                    Debug.WriteLine("Detail: " + detail);
                }

                ToastNotificationService.ShowSyncFinishedNotification(_folderSyncInfo.Path, changedCount, errorCount);
                return(errorCount == 0);
            }
            finally
            {
                SyncDbUtils.UnlockFolderSyncInfo(_folderSyncInfo);
            }
        }
Ejemplo n.º 18
0
        private async Task SychronizeFolder(ResourceInfo resourceInfo)
        {
            if (resourceInfo == null)
            {
                return;
            }

            var           syncInfo = SyncDbUtils.GetFolderSyncInfoByPath(resourceInfo.Path);
            StorageFolder folder;

            try
            {
                Task <ContentDialogResult> firstRunDialog = null;
                if (syncInfo == null)
                {
                    // try to Get parent or initialize
                    syncInfo = SyncDbUtils.GetFolderSyncInfoBySubPath(resourceInfo.Path);

                    if (syncInfo == null)
                    {
                        // Initial Sync
                        syncInfo = new FolderSyncInfo()
                        {
                            Path = resourceInfo.Path
                        };

                        var folderPicker = new FolderPicker()
                        {
                            SuggestedStartLocation = PickerLocationId.Desktop
                        };

                        folderPicker.FileTypeFilter.Add(".txt");
                        StorageFolder newFolder = await folderPicker.PickSingleFolderAsync();

                        if (newFolder == null)
                        {
                            return;
                        }

                        StorageApplicationPermissions.FutureAccessList.AddOrReplace(syncInfo.AccessListKey, newFolder);
                        IReadOnlyList <IStorageItem> subElements = await newFolder.GetItemsAsync();

                        NextcloudClient.NextcloudClient client = await ClientService.GetClient();

                        var remoteElements = await client.List(resourceInfo.Path);

                        if (subElements.Count > 0 && remoteElements.Count > 0)
                        {
                            var dialogNotEmpty = new ContentDialog
                            {
                                Title   = _resourceLoader.GetString("SyncFoldersNotEmptyWarning"),
                                Content = new TextBlock()
                                {
                                    Text         = _resourceLoader.GetString("SyncFoldersNotEmptyWarningDetail"),
                                    TextWrapping = TextWrapping.WrapWholeWords,
                                    Margin       = new Thickness(0, 20, 0, 0)
                                },
                                PrimaryButtonText   = _resourceLoader.GetString("OK"),
                                SecondaryButtonText = _resourceLoader.GetString("Cancel")
                            };

                            var dialogResult = await _dialogService.ShowAsync(dialogNotEmpty);

                            if (dialogResult != ContentDialogResult.Primary)
                            {
                                return;
                            }
                        }

                        folder = newFolder;
                        SyncDbUtils.SaveFolderSyncInfo(syncInfo);
                        StartDirectoryListing(); // This is just to update the menu flyout - maybe there is a better way

                        var dialog = new ContentDialog
                        {
                            Title   = _resourceLoader.GetString("SyncStarted"),
                            Content = new TextBlock()
                            {
                                Text         = _resourceLoader.GetString("SyncStartedDetail"),
                                TextWrapping = TextWrapping.WrapWholeWords,
                                Margin       = new Thickness(0, 20, 0, 0)
                            },
                            PrimaryButtonText = _resourceLoader.GetString("OK")
                        };
                        firstRunDialog = _dialogService.ShowAsync(dialog);
                    }
                    else
                    {
                        string        subPath    = resourceInfo.Path.Substring(syncInfo.Path.Length);
                        StorageFolder tempFolder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(syncInfo.AccessListKey);

                        foreach (string foldername in subPath.Split('/'))
                        {
                            if (foldername.Length > 0)
                            {
                                tempFolder = await tempFolder.GetFolderAsync(foldername);
                            }
                        }
                        folder = tempFolder;
                    }
                }
                else
                {
                    folder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(syncInfo.AccessListKey);

                    // TODO catch exceptions
                }

                SyncService service = new SyncService(folder, resourceInfo, syncInfo);
                await service.StartSync();

                if (firstRunDialog != null)
                {
                    await firstRunDialog;
                }
            }
            catch (Exception e)
            {
                // ERROR Maybe AccessList timed out.
                Debug.WriteLine(e.Message);
            }
        }
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var item = (ResourceInfo)value;

            return(item.ContentType.Equals("dav/directory") ? SyncDbUtils.IsSynced(item) ? "\uE8F7" : "\uE8B7" : "\uE8A5");
        }
Ejemplo n.º 20
0
        private async Task <int> SyncFile(ResourceInfo info, StorageFile file, ResourceInfo parent, StorageFolder parentFolder)
        {
            SyncInfoDetail sid     = null;
            bool           changed = false;
            bool           deleted = false;

            if (info != null)
            {
                sid = SyncDbUtils.GetSyncInfoDetail(info, folderSyncInfo);
            }
            else if (file != null)
            {
                sid = SyncDbUtils.GetSyncInfoDetail(file, folderSyncInfo);
            }
            if (sid == null)
            {
                sid = new SyncInfoDetail(folderSyncInfo);
            }
            sid.Error        = null;
            sid.ConflictType = ConflictType.NONE;

            try
            {
                DateTimeOffset currentModified;
                if (file != null)
                {
                    BasicProperties basicProperties = await file.GetBasicPropertiesAsync();

                    currentModified = basicProperties.DateModified;
                }

                if (sid.Path == null && sid.FilePath == null)
                {
                    if (file != null && info != null)
                    {
                        sid.Path         = info.Path + "/" + info.Name;
                        sid.FilePath     = file.Path;
                        sid.ConflictType = ConflictType.BOTHNEW;
                        Debug.WriteLine("Sync file: Conflict (both new) " + info.Path + "/" + info.Name);
                    }
                    else if (file != null)
                    {
                        // Create sid and upload file
                        string newPath = parent.Path + file.Name;
                        Debug.WriteLine("Sync file (Upload)" + newPath);
                        sid.DateModified = currentModified;
                        sid.FilePath     = file.Path;
                        if (await UploadFile(file, newPath))
                        {
                            ResourceInfo newInfo = await client.GetResourceInfo(parent.Path, file.Name);

                            sid.Path = newInfo.Path + "/" + newInfo.Name;
                            sid.ETag = newInfo.ETag;
                            changed  = true;
                        }
                        else
                        {
                            sid.Error = "Error while uploading File to nextcloud.";
                        }
                    }
                    else if (info != null)
                    {
                        // Create sid and download file
                        StorageFile localFile = await parentFolder.CreateFileAsync(info.Name);

                        Debug.WriteLine("Sync file (Download)" + localFile.Path);
                        if (await this.DownloadFile(localFile, info.Path + "/" + info.Name))
                        {
                            BasicProperties basicProperties = await localFile.GetBasicPropertiesAsync();

                            currentModified  = basicProperties.DateModified;
                            sid.Path         = info.Path + "/" + info.Name;
                            sid.ETag         = info.ETag;
                            sid.DateModified = currentModified;
                            sid.FilePath     = localFile.Path;
                            changed          = true;
                        }
                        else
                        {
                            sid.Error = "Error while downloading file from nextcloud";
                        }
                    }
                }
                else
                {
                    if (info == null)
                    {
                        if (sid.DateModified.Value.Equals(currentModified))
                        {
                            Debug.WriteLine("Sync file (Delete locally) " + sid.Path);
                            // Remove sid and local file
                            await file.DeleteAsync();

                            SyncDbUtils.DeleteSyncInfoDetail(sid, false);
                            changed = true;
                            deleted = true;
                        }
                        else
                        {
                            switch (sid.ConflictSolution)
                            {
                            case ConflictSolution.PREFER_LOCAL:
                                string newPath = parent.Path + file.Name;
                                Debug.WriteLine("Sync file (Upload)" + newPath);
                                sid.DateModified = currentModified;
                                sid.FilePath     = file.Path;
                                if (await UploadFile(file, newPath))
                                {
                                    ResourceInfo newInfo = await client.GetResourceInfo(parent.Path, file.Name);

                                    sid.Path             = newInfo.Path + "/" + newInfo.Name;
                                    sid.ETag             = newInfo.ETag;
                                    sid.ConflictSolution = ConflictSolution.NONE;
                                    changed = true;
                                }
                                else
                                {
                                    sid.Error = "Error while uploading File to nextcloud.";
                                }
                                break;

                            case ConflictSolution.PREFER_REMOTE:
                                Debug.WriteLine("Sync file (Delete locally) " + sid.Path);
                                // Remove sid and local file
                                await file.DeleteAsync();

                                SyncDbUtils.DeleteSyncInfoDetail(sid, false);
                                deleted = true;
                                changed = true;
                                break;

                            default:
                                Debug.WriteLine("Sync file: Conflict (Deleted remotely, but changed locally) " + sid.Path);
                                sid.ConflictType = ConflictType.REMOTEDEL_LOCALCHANGE;
                                break;
                            }
                        }
                    }
                    else if (file == null)
                    {
                        if (sid.ETag == null || info.ETag.Equals(sid.ETag))
                        {
                            Debug.WriteLine("Sync file (Delete remotely) " + sid.Path);
                            // Remove sid and remote file
                            await client.Delete(info.Path + "/" + info.Name);

                            SyncDbUtils.DeleteSyncInfoDetail(sid, false);
                            deleted = true;
                            changed = true;
                        }
                        else
                        {
                            switch (sid.ConflictSolution)
                            {
                            case ConflictSolution.PREFER_LOCAL:
                                Debug.WriteLine("Sync file (Delete remotely) " + sid.Path);
                                // Remove sid and remote file
                                await client.Delete(info.Path + "/" + info.Name);

                                SyncDbUtils.DeleteSyncInfoDetail(sid, false);
                                deleted = true;
                                changed = true;
                                break;

                            case ConflictSolution.PREFER_REMOTE:
                                // Update local file
                                StorageFile localFile = await parentFolder.CreateFileAsync(info.Name);

                                Debug.WriteLine("Sync file (Download)" + localFile.Path);
                                if (await this.DownloadFile(localFile, info.Path + "/" + info.Name))
                                {
                                    BasicProperties basicProperties = await localFile.GetBasicPropertiesAsync();

                                    currentModified      = basicProperties.DateModified;
                                    sid.ETag             = info.ETag;
                                    sid.DateModified     = currentModified;
                                    sid.ConflictSolution = ConflictSolution.NONE;
                                    changed = true;
                                }
                                else
                                {
                                    sid.Error = "Error while downloading file from nextcloud";
                                }
                                break;

                            default:
                                // Conflict
                                Debug.WriteLine("Sync file: Conflict (Deleted locally, but changed remotely) " + sid.Path);
                                sid.ConflictType = ConflictType.LOCALDEL_REMOTECHANGE;
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (currentModified.Equals(sid.DateModified))
                        {
                            if (!info.ETag.Equals(sid.ETag))
                            {
                                // Update local file
                                Debug.WriteLine("Sync file (update locally) " + info.Path + "/" + info.Name);
                                if (await this.DownloadFile(file, info.Path + "/" + info.Name))
                                {
                                    sid.ETag         = info.ETag;
                                    sid.DateModified = currentModified;
                                    changed          = true;
                                }
                                else
                                {
                                    sid.Error = "Error while downloading file from nextcloud";
                                }
                            }
                        }
                        else if (info.ETag.Equals(sid.ETag))
                        {
                            // update file on nextcloud
                            Debug.WriteLine("Sync file (update remotely) " + info.Path + "/" + info.Name);

                            if (await UploadFile(file, info.Path + "/" + info.Name))
                            {
                                ResourceInfo newInfo = await client.GetResourceInfo(info.Path, info.Name);

                                sid.ETag         = newInfo.ETag;
                                sid.DateModified = currentModified;
                                changed          = true;
                            }
                            else
                            {
                                sid.Error = "Error while uploading file to nextcloud";
                            }
                        }
                        else
                        {
                            switch (sid.ConflictSolution)
                            {
                            case ConflictSolution.PREFER_LOCAL:
                                // update file on nextcloud
                                Debug.WriteLine("Sync file (update remotely) " + info.Path + "/" + info.Name);

                                if (await UploadFile(file, info.Path + "/" + info.Name))
                                {
                                    ResourceInfo newInfo = await client.GetResourceInfo(info.Path, info.Name);

                                    sid.ETag             = newInfo.ETag;
                                    sid.DateModified     = currentModified;
                                    sid.ConflictSolution = ConflictSolution.NONE;
                                    changed = true;
                                }
                                else
                                {
                                    sid.Error = "Error while uploading file to nextcloud";
                                }
                                break;

                            case ConflictSolution.PREFER_REMOTE:
                                // Update local file
                                Debug.WriteLine("Sync file (update locally) " + info.Path + "/" + info.Name);
                                if (await this.DownloadFile(file, info.Path + "/" + info.Name))
                                {
                                    sid.ETag             = info.ETag;
                                    sid.DateModified     = currentModified;
                                    sid.ConflictSolution = ConflictSolution.NONE;
                                    changed = true;
                                }
                                else
                                {
                                    sid.Error = "Error while downloading file from nextcloud";
                                }
                                break;

                            default:
                                // Conflict
                                if (sid.ETag == null && !sid.DateModified.HasValue)
                                {
                                    sid.ConflictType = ConflictType.BOTHNEW;
                                    Debug.WriteLine("Sync file: Conflict (both new) " + info.Path + "/" + info.Name);
                                }
                                else
                                {
                                    Debug.WriteLine("Sync file: Conflict (Changed remotely and locally) " + sid.Path);
                                    sid.ConflictType = ConflictType.BOTH_CHANGED;
                                }
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                // TODO: do not write only the raw exception message in the sid.Error.
                sid.Error = e.Message;
            }
            Debug.WriteLine("Synced file " + sid.ToString());
            sidList.Add(sid);
            SyncDbUtils.SaveSyncHistory(sid);
            if (!deleted)
            {
                SyncDbUtils.SaveSyncInfoDetail(sid);
            }
            return(changed ? 1 : 0);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Folder Synchronization
        /// </summary>
        /// <param name="resourceInfo">webdav Resource to sync</param>
        /// <param name="folder">Target folder</param>
        private async Task <int> SyncFolder(ResourceInfo info, StorageFolder folder)
        {
            SyncInfoDetail sid = SyncDbUtils.GetSyncInfoDetail(info, folderSyncInfo);

            sid.Error = null;
            int changesCount = 0;

            try
            {
                Debug.WriteLine("Sync folder " + info.Path + ":" + folder.Path);
                IReadOnlyList <StorageFile> localFiles = await folder.GetFilesAsync();

                IReadOnlyList <StorageFolder> localFolders = await folder.GetFoldersAsync();

                List <ResourceInfo> list = null;
                try
                {
                    list = await client.List(info.Path);
                }
                catch (ResponseError e)
                {
                    ResponseErrorHandlerService.HandleException(e);
                }
                //List<Task> syncTasks = new List<Task>();
                List <IStorageItem> synced = new List <IStorageItem>();
                if (list != null && list.Count > 0)
                {
                    foreach (ResourceInfo subInfo in list)
                    {
                        if (subInfo.IsDirectory)
                        {
                            IEnumerable <StorageFolder> localFoldersWithName = localFolders.Where(f => f.Name.Equals(subInfo.Name));
                            StorageFolder subFolder = localFoldersWithName.FirstOrDefault();
                            // Can localFoldersWithName be null?
                            if (subFolder == null)
                            {
                                var subSid = SyncDbUtils.GetSyncInfoDetail(subInfo, folderSyncInfo);
                                if (subSid != null)
                                {
                                    Debug.WriteLine("Sync folder (delete remotely) " + subInfo.Path);
                                    if (await client.Delete(subInfo.Path))
                                    {
                                        SyncDbUtils.DeleteSyncInfoDetail(subSid, true);
                                    }
                                    else
                                    {
                                        sid.Error = "Deletion of " + subInfo.Path + " on nextcloud failed.";
                                        // Error could be overridden by other errors
                                    }
                                }
                                else
                                {
                                    // Create sid and local folder
                                    Debug.WriteLine("Sync folder (create locally) " + subInfo.Path);
                                    subFolder = await folder.CreateFolderAsync(subInfo.Name);

                                    SyncInfoDetail syncInfoDetail = new SyncInfoDetail(folderSyncInfo)
                                    {
                                        Path     = subInfo.Path,
                                        FilePath = subFolder.Path
                                    };

                                    SyncDbUtils.SaveSyncInfoDetail(syncInfoDetail);
                                    changesCount = changesCount + await SyncFolder(subInfo, subFolder);

                                    // syncTasks.Add(SyncFolder(subInfo, subFolder));
                                }
                            }
                            else
                            {
                                var subSid = SyncDbUtils.GetSyncInfoDetail(subInfo, folderSyncInfo);
                                if (subSid == null)
                                {
                                    // Both new
                                    Debug.WriteLine("Sync folder (create both) " + subInfo.Path);

                                    SyncInfoDetail syncInfoDetail = new SyncInfoDetail(folderSyncInfo)
                                    {
                                        Path     = subInfo.Path,
                                        FilePath = subFolder.Path
                                    };

                                    SyncDbUtils.SaveSyncInfoDetail(syncInfoDetail);
                                }
                                synced.Add(subFolder);
                                changesCount = changesCount + await SyncFolder(subInfo, subFolder);

                                // syncTasks.Add(SyncFolder(subInfo, subFolder));
                            }
                        }
                        else
                        {
                            IEnumerable <StorageFile> localFilessWithName = localFiles.Where(f => f.Name.Equals(subInfo.Name));
                            // Can localFilessWithName be null?
                            StorageFile subFile = localFilessWithName.FirstOrDefault();
                            if (subFile != null)
                            {
                                synced.Add(subFile);
                            }
                            changesCount = changesCount + await SyncFile(subInfo, subFile, info, folder);

                            //syncTasks.Add(SyncFile(subInfo, subFile, info, folder));
                        }
                    }
                }
                foreach (StorageFile file in localFiles)
                {
                    if (!synced.Contains(file))
                    {
                        changesCount = changesCount + await SyncFile(null, file, info, folder);

                        //syncTasks.Add(SyncFile(null, file, info, folder));
                    }
                }
                foreach (StorageFolder localFolder in localFolders)
                {
                    if (!synced.Contains(localFolder))
                    {
                        var subSid = SyncDbUtils.GetSyncInfoDetail(localFolder, folderSyncInfo);
                        if (subSid != null)
                        {
                            // Delete all sids and local folder
                            Debug.WriteLine("Sync folder (delete locally) " + localFolder.Path);
                            await localFolder.DeleteAsync();

                            SyncDbUtils.DeleteSyncInfoDetail(subSid, true);
                        }
                        else
                        {
                            // Create sid and remotefolder
                            string newPath = info.Path + localFolder.Name;
                            Debug.WriteLine("Sync folder (create remotely) " + newPath);

                            if (await client.CreateDirectory(newPath))
                            {
                                ResourceInfo subInfo = await client.GetResourceInfo(info.Path, localFolder.Name);

                                SyncInfoDetail syncInfoDetail = new SyncInfoDetail(folderSyncInfo)
                                {
                                    Path     = subInfo.Path,
                                    FilePath = localFolder.Path
                                };

                                SyncDbUtils.SaveSyncInfoDetail(syncInfoDetail);
                                changesCount = changesCount + await SyncFolder(subInfo, localFolder);

                                //syncTasks.Add(SyncFolder(subInfo, localFolder));
                            }
                            else
                            {
                                sid.Error = "Could not create directory on nextcloud: " + newPath;
                            }
                        }
                    }
                }
                //Task.WaitAll(syncTasks.ToArray());
            }
            catch (Exception e)
            {
                sid.Error = e.Message;
            }
            sidList.Add(sid);
            SyncDbUtils.SaveSyncInfoDetail(sid);
            SyncDbUtils.SaveSyncHistory(sid);
            return(changesCount);
        }