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)); }
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); }