Пример #1
0
 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));
 }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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());
        }
Пример #6
0
        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");
            }
        }