Esempio n. 1
0
        internal void ResetErrorFlag(Guid?id = null)
        {
            var store = new MetadataStore(SyncConfiguration.LocalFolder);

            if (id == null)
            {
                foreach (var item in store.Items.Where(p => p.HasError).Select(p => p.Id).ToArray())
                {
                    store.Delete(item);
                }
            }
            else
            {
                store.Delete(id.Value);
            }

            store.Save();

            OnPropertyChanged(nameof(ItemsWithErrors));
        }
Esempio n. 2
0
        private int SyncMetadataStore(bool doNotSave, ConflictHandling conflictHandling, out bool moreChangesFound, bool rescanLocalFiles = true)
        {
            var sumWatch = Stopwatch.StartNew();

            var correlationId = Guid.NewGuid();

            //reset item status for all items except the ones with errors
            _metadataStore.Items.Where(p => p.Status != ItemStatus.Conflict).ToList().ForEach(p => { p.Status = ItemStatus.Unchanged; p.HasError = false; });

            var watch = Stopwatch.StartNew();

            var remoteFileList = _sharePointManager.GetChangedFiles(_metadataStore, (percent, currentFile) =>
            {
                OnSyncProgress(percent, ProgressStatus.Analyzing, $"Processing remote changes... '{currentFile}'");
            });

            watch.Stop();

            var syncToRemote = (_configuration.Direction == SyncDirection.LocalToRemote || _configuration.Direction == SyncDirection.Both);
            var syncToLocal  = _configuration.Direction == SyncDirection.RemoteToLocal || _configuration.Direction == SyncDirection.Both;

            var searchOption = SearchOption.AllDirectories;

            if (rescanLocalFiles)
            {
                OnSyncProgress(0, ProgressStatus.Analyzing, "Processing local changes");

                #region Iterate local files/folders

                watch = Stopwatch.StartNew();

                Parallel.ForEach(Directory.EnumerateDirectories(_localFolder, "*", searchOption), localFolder =>
                {
                    if (!syncToRemote)
                    {
                        return;
                    }

                    if (!_configuration.ShouldFileSync(localFolder))
                    {
                        return;
                    }

                    if (File.GetAttributes(localFolder).HasFlag(FileAttributes.Hidden))
                    {
                        return;
                    }

                    if (Path.GetDirectoryName(localFolder) == MetadataStore.STOREFOLDER)
                    {
                        return;
                    }

                    var item = _metadataStore.GetByFileName(localFolder);
                    if (item == null)
                    {
                        _metadataStore.Add(new MetadataItem(localFolder, ItemType.Folder));
                    }
                    else
                    {
                        item.UpdateWithLocalInfo(conflictHandling, correlationId);
                        if (item.Status == ItemStatus.Conflict)
                        {
                            item.Status = OnItemConflict(item);
                        }
                    }
                });

                watch.Stop();
                watch = Stopwatch.StartNew();

                // update store for local files
                Parallel.ForEach(Directory.EnumerateFiles(_localFolder, "*.*", searchOption), localFile =>
                                 //foreach (var localFile in Directory.EnumerateFiles(_localFolder, "*.*", searchOption))
                {
                    if (!syncToRemote)
                    {
                        return;
                    }

                    if (!_configuration.ShouldFileSync(localFile))
                    {
                        return;
                    }

                    var localExtension = Path.GetExtension(localFile);
                    if (localExtension == ".spsync")
                    {
                        return;
                    }

                    if (File.GetAttributes(localFile).HasFlag(FileAttributes.Hidden))
                    {
                        return;
                    }

                    if (Directory.GetParent(localFile).Name == MetadataStore.STOREFOLDER)
                    {
                        return;
                    }

                    var item = _metadataStore.GetByFileName(localFile);
                    if (item == null)
                    {
                        _metadataStore.Add(new MetadataItem(localFile, ItemType.File));
                    }
                    else
                    {
                        item.UpdateWithLocalInfo(conflictHandling, correlationId);
                        if (item.Status == ItemStatus.Conflict)
                        {
                            item.Status = OnItemConflict(item);
                        }
                    }
                });

                watch.Stop();

                #endregion
            }

            #region Iterate remote files/folders

            // update store for remote files/folders
            foreach (var remoteItem in remoteFileList)
            {
                if (!syncToLocal)
                {
                    continue;
                }

                var localFile = new DirectoryInfo(Path.Combine(_localFolder, remoteItem.FullFileName)).FullName;

                if (!_configuration.ShouldFileSync(localFile))
                {
                    continue;
                }

                string fn = localFile;
                if (remoteItem.Type == ItemType.Folder)
                {
                    fn = Path.Combine(localFile, remoteItem.Name);
                }

                var item = _metadataStore.GetByItemId(remoteItem.Id);
                if (remoteItem.ChangeType == Microsoft.SharePoint.Client.ChangeType.Add)
                {
                    // new
                    if (item == null)
                    {
                        _metadataStore.Add(new MetadataItem(remoteItem.Id, remoteItem.ETag, remoteItem.Name, Path.GetDirectoryName(localFile), remoteItem.LastModified, remoteItem.Type));
                    }
                    // remote and local change
                    else
                    {
                        item.UpdateWithRemoteInfo(remoteItem.Id, remoteItem.ETag, remoteItem.LastModified, conflictHandling, correlationId);
                        if (item.Status == ItemStatus.Conflict)
                        {
                            item.Status = OnItemConflict(item);
                        }
                    }
                }
                if (remoteItem.ChangeType == Microsoft.SharePoint.Client.ChangeType.DeleteObject)
                {
                    if (item != null)
                    {
                        item.Status = ItemStatus.DeletedRemote;
                    }
                }
                if (remoteItem.ChangeType == Microsoft.SharePoint.Client.ChangeType.Rename)
                {
                    if (item == null)
                    {
                        _metadataStore.Add(new MetadataItem(remoteItem.Id, remoteItem.ETag, remoteItem.Name, Path.GetDirectoryName(localFile), remoteItem.LastModified, remoteItem.Type));
                    }
                    else
                    {
                        if (item.Name != remoteItem.Name)
                        {
                            item.NewNameAfterRename = remoteItem.Name;
                            item.Status             = ItemStatus.RenamedRemote;

                            if (item.Type == ItemType.Folder)
                            {
                                foreach (var itemInFolder in _metadataStore.Items.Where(p => p.LocalFile.Contains(item.LocalFile)))
                                {
                                    if (itemInFolder.Id == item.Id)
                                    {
                                        continue;
                                    }
                                    var newFolder = _localFolder + remoteItem.FullFileName.Substring(1);
                                    itemInFolder.LocalFolder = itemInFolder.LocalFolder.Replace(item.LocalFile, newFolder);
                                    itemInFolder.HasError    = true;
                                }
                            }
                        }
                        else
                        {
                            item.Status = ItemStatus.Unchanged;
                        }
                    }
                }
                if (remoteItem.ChangeType == Microsoft.SharePoint.Client.ChangeType.Update)
                {
                    // new
                    if (item == null)
                    {
                        _metadataStore.Add(new MetadataItem(remoteItem.Id, remoteItem.ETag, remoteItem.Name, Path.GetDirectoryName(localFile), remoteItem.LastModified, remoteItem.Type));
                    }
                    else
                    {
                        item.UpdateWithRemoteInfo(remoteItem.Id, remoteItem.ETag, remoteItem.LastModified, conflictHandling, correlationId);
                        if (item.Status == ItemStatus.Conflict)
                        {
                            item.Status = OnItemConflict(item);
                        }
                    }
                }
            }

            #endregion

            #region Check for deleted files/folders

            var itemsToDelete = new List <Guid>();

            // update store: files
            foreach (var item in _metadataStore.Items.Where(p => p.Status == ItemStatus.Unchanged && p.Type == ItemType.File && !p.HasError))
            {
                var path = item.LocalFile;

                if (!_configuration.ShouldFileSync(path))
                {
                    continue;
                }

                if (!File.Exists(path) && !File.Exists(path + ".spsync"))
                {
                    item.Status = ItemStatus.DeletedLocal;
                }
                //if (remoteFileList.Count(p => p.Id == item.SharePointId) < 1)
                //{
                //    if (item.Status == ItemStatus.DeletedLocal)
                //    {
                //        itemsToDelete.Add(item.Id);
                //    }
                //    item.Status = ItemStatus.DeletedRemote;
                //}
            }

            // update store: folders
            foreach (var item in _metadataStore.Items.Where(p => p.Status == ItemStatus.Unchanged && p.Type == ItemType.Folder && !p.HasError))
            {
                var relFile = item.LocalFile.Replace(_localFolder, string.Empty).TrimStart('.', '\\');
                var path    = item.LocalFile;

                if (!_configuration.ShouldFileSync(path))
                {
                    continue;
                }

                if (!Directory.Exists(path))
                {
                    item.Status = ItemStatus.DeletedLocal;

                    // delete all dependend items
                    _metadataStore.Items.Where(p => p.LocalFolder == item.LocalFile).ToList().ForEach(p => { if (!itemsToDelete.Contains(p.Id))
                                                                                                             {
                                                                                                                 itemsToDelete.Add(p.Id);
                                                                                                             }
                                                                                                      });
                }
                //if (remoteFileList.Count(p => p.FullFileName.Replace(_localFolder, string.Empty).TrimStart('.', '\\') + p.Name == relFile) < 1)
                //{
                //    if (item.Status == ItemStatus.DeletedLocal)
                //    {
                //        if (!itemsToDelete.Contains(item.Id))
                //            itemsToDelete.Add(item.Id);
                //    }
                //    item.Status = ItemStatus.DeletedRemote;
                //}
            }

            #endregion

            itemsToDelete.ForEach(p => _metadataStore.Delete(p));

            var countChanged = _metadataStore.Items.Count(p => p.Status != ItemStatus.Unchanged);

            _metadataStore.Items.Where(p => p.Status != ItemStatus.Unchanged).ToList().ForEach(p =>
            {
                Logger.LogDebug(correlationId, p.Id, "(Result) Item Name={0}, Status={1}, HasError={2}, LastError={3}", p.Name, p.Status, p.HasError, p.LastError);
            });

            // reset error flag
            //_metadataStore.Items.Where(p => p.HasError && p.Status != ItemStatus.Unchanged).ToList().ForEach(p => p.HasError = false);

            if (!doNotSave)
            {
                _metadataStore.Save();
            }

            sumWatch.Stop();

            moreChangesFound = remoteFileList.Count > 0;

            return(countChanged);
        }