public Task <List <FileIndexItem> > Sync(string subPath, bool recursive = true, ISynchronize.SocketUpdateDelegate updateDelegate = null) { Console.WriteLine($"sync => {subPath}"); Inputs.Add(new Tuple <string, bool>(subPath, recursive)); Receive?.Invoke(this, subPath); return(Task.FromResult(_data)); }
/// <summary> /// Query the database and check if an single item has changed /// </summary> /// <param name="subPath">path</param> /// <param name="updateDelegate">realtime updates, can be null to ignore</param> /// <returns>updated item with status</returns> internal async Task <FileIndexItem> SingleFile(string subPath, ISynchronize.SocketUpdateDelegate updateDelegate = null) { // route with database check if (_appSettings.ApplicationType == AppSettings.StarskyAppType.WebController) { _logger.LogInformation($"[SingleFile/db] {subPath} " + Synchronize.DateTimeDebug()); } // Sidecar files are updated but ignored by the process await UpdateSidecarFile(subPath); // ignore all the 'wrong' files var statusItem = CheckForStatusNotOk(subPath); if (statusItem.Status != FileIndexItem.ExifStatus.Ok) { _logger.LogDebug($"[SingleFile/db] status {statusItem.Status} for {subPath} {Synchronize.DateTimeDebug()}"); return(statusItem); } // temp disable caching TimeSpan.FromSeconds(1) var dbItem = await _query.GetObjectByFilePathAsync(subPath); // // // when item does not exist in Database if (dbItem == null) { return(await NewItem(statusItem, subPath)); } // Cached values are not checked for performance reasons if (dbItem.Status == FileIndexItem.ExifStatus.OkAndSame) { _logger.LogDebug($"[SingleFile/db] OkAndSame {subPath} {Synchronize.DateTimeDebug()}"); return(dbItem); } var(isSame, updatedDbItem) = await SizeFileHashIsTheSame(dbItem); if (!isSame) { if (updateDelegate != null) { await updateDelegate(new List <FileIndexItem> { dbItem }); } return(await UpdateItem(dbItem, updatedDbItem.Size, subPath)); } // to avoid reSync updatedDbItem.Status = FileIndexItem.ExifStatus.OkAndSame; AddDeleteStatus(statusItem, FileIndexItem.ExifStatus.DeletedAndSame); _logger.LogInformation($"[SingleFile/db] Same: {updatedDbItem.Status} for: {updatedDbItem.FilePath}"); return(updatedDbItem); }
/// <summary> /// For Checking single items without querying the database /// </summary> /// <param name="subPath">path</param> /// <param name="dbItem">current item, can be null</param> /// <param name="updateDelegate">push updates realtime to the user and avoid waiting</param> /// <returns>updated item with status</returns> internal async Task <FileIndexItem> SingleFile(string subPath, FileIndexItem dbItem, ISynchronize.SocketUpdateDelegate updateDelegate = null) { // when item does not exist in db if (dbItem == null) { return(await SingleFile(subPath)); } // Route without database check if (_appSettings.ApplicationType == AppSettings.StarskyAppType.WebController) { _logger.LogInformation($"[SingleFile/no-db] {subPath} - {DateTime.UtcNow.ToShortTimeString()}"); } // Sidecar files are updated but ignored by the process await UpdateSidecarFile(subPath); var statusItem = CheckForStatusNotOk(subPath); if (statusItem.Status != FileIndexItem.ExifStatus.Ok) { _logger.LogInformation($"[SingleFile/no-db] status {statusItem.Status} for {subPath}"); return(statusItem); } var(isSame, updatedDbItem) = await SizeFileHashIsTheSame(dbItem); if (!isSame) { if (updateDelegate != null) { new Thread(() => updateDelegate(new List <FileIndexItem> { dbItem })).Start(); } return(await UpdateItem(dbItem, updatedDbItem.Size, subPath)); } // to avoid reSync updatedDbItem.Status = FileIndexItem.ExifStatus.OkAndSame; AddDeleteStatus(statusItem, FileIndexItem.ExifStatus.DeletedAndSame); return(updatedDbItem); }
public async Task <List <FileIndexItem> > Folder(string inputSubPath, ISynchronize.SocketUpdateDelegate updateDelegate = null) { var subPaths = new List <string> { inputSubPath }; subPaths.AddRange(_subPathStorage.GetDirectoryRecursive(inputSubPath)); var allResults = new List <FileIndexItem>(); // Loop trough all folders recursive foreach (var subPath in subPaths) { // get only direct child files and folders and NOT recursive var fileIndexItems = await _query.GetAllObjectsAsync(subPath); fileIndexItems = await _duplicate.RemoveDuplicateAsync(fileIndexItems); // And check files within this folder var pathsOnDisk = _subPathStorage.GetAllFilesInDirectory(subPath) .Where(ExtensionRolesHelper.IsExtensionSyncSupported).ToList(); var indexItems = await LoopOverFolder(fileIndexItems, pathsOnDisk, updateDelegate); allResults.AddRange(indexItems); var dirItems = (await CheckIfFolderExistOnDisk(fileIndexItems)) .Where(p => p != null).ToList(); if (dirItems.Any()) { allResults.AddRange(dirItems); } } // // remove the duplicates from a large list of folders var folderList = await _query.GetObjectsByFilePathQueryAsync(subPaths); folderList = await _duplicate.RemoveDuplicateAsync(folderList); await CompareFolderListAndFixMissingFolders(subPaths, folderList); allResults.Add(await AddParentFolder(inputSubPath)); return(allResults); }
private async Task <List <FileIndexItem> > LoopOverFolder(IReadOnlyCollection <FileIndexItem> fileIndexItems, IReadOnlyCollection <string> pathsOnDisk, ISynchronize.SocketUpdateDelegate updateDelegate) { var fileIndexItemsOnlyFiles = fileIndexItems .Where(p => p.IsDirectory == false).ToList(); var pathsToUpdateInDatabase = PathsToUpdateInDatabase(fileIndexItemsOnlyFiles, pathsOnDisk); if (!pathsToUpdateInDatabase.Any()) { return(new List <FileIndexItem>()); } var result = await pathsToUpdateInDatabase .ForEachAsync(async subPathInFiles => { var query = new QueryFactory(_setupDatabaseTypes, _query, _memoryCache, _appSettings, _logger).Query(); var dbItem = await new SyncSingleFile(_appSettings, query, _subPathStorage, _logger).SingleFile(subPathInFiles, fileIndexItems.FirstOrDefault(p => p.FilePath == subPathInFiles), updateDelegate); if (dbItem.Status == FileIndexItem.ExifStatus.NotFoundSourceMissing) { await new SyncRemove(_appSettings, _setupDatabaseTypes, query, _memoryCache, _logger) .Remove(subPathInFiles); } _console.Write(dbItem.Status == FileIndexItem.ExifStatus .NotFoundSourceMissing ? "≠" : "•"); // only used in Parallelism loop await query.DisposeAsync(); return(dbItem); }, _appSettings.MaxDegreesOfParallelism); return(result == null ? new List <FileIndexItem>() : result.ToList()); }
public async Task <List <FileIndexItem> > Sync(string subPath, bool recursive = true, ISynchronize.SocketUpdateDelegate updateDelegate = null) { // Prefix / for database subPath = PathHelper.PrefixDbSlash(subPath); if (subPath != "/") { subPath = PathHelper.RemoveLatestSlash(subPath); } if (FilterCommonTempFiles.Filter(subPath) || _syncIgnoreCheck.Filter(subPath)) { return(FilterCommonTempFiles.DefaultOperationNotSupported(subPath)); } _console.WriteLine($"[Synchronize] Sync {subPath} {DateTimeDebug()}"); // ReSharper disable once ConvertSwitchStatementToSwitchExpression switch (_subPathStorage.IsFolderOrFile(subPath)) { case FolderOrFileModel.FolderOrFileTypeList.Folder: return(await _syncFolder.Folder(subPath, updateDelegate)); case FolderOrFileModel.FolderOrFileTypeList.File: var item = await _syncSingleFile.SingleFile(subPath, updateDelegate); return(new List <FileIndexItem> { item }); case FolderOrFileModel.FolderOrFileTypeList.Deleted: return(await _syncRemove.Remove(subPath)); default: throw new AggregateException("enum is not valid"); } }