Esempio n. 1
0
        public async Task <IActionResult> GetPathTree([FromBody] PathTreeRequestDto request, [FromQuery] bool keepOrder,
                                                      CancellationToken cancellationToken)
        {
            var response        = new PathTreeResponseDto();
            var directoryHelper = new DirectoryHelper();

            Task <IEnumerable <FileExplorerEntry> > entriesTask = null;

            if (request.RequestEntries)
            {
                entriesTask = keepOrder
                    ? directoryHelper.GetEntriesKeepOrder(request.Path, cancellationToken)
                    : directoryHelper.GetEntries(request.Path, cancellationToken);
            }

            if (request.RequestedDirectories?.Count > 0)
            {
                var pathDirectories = PathHelper.GetPathDirectories(request.Path).ToList();
                var directories     = new ConcurrentDictionary <int, List <DirectoryEntry> >();

                await TaskCombinators.ThrottledAsync(request.RequestedDirectories, async (i, token) =>
                {
                    var directoryPath = pathDirectories[i];
                    directories.TryAdd(i,
                                       (await directoryHelper.GetDirectoryEntries(directoryPath, cancellationToken)).ToList());
                }, CancellationToken.None);

                response.Directories = directories;
            }

            if (entriesTask != null)
            {
                response.Entries = (await entriesTask).ToList();
            }

            return(Ok(response));
        }
Esempio n. 2
0
        public async Task <PathContent> FetchPath(string path, bool ignoreEntriesCache, bool ignorePathCache,
                                                  CancellationToken token)
        {
            if (PathHelper.ContainsEnvironmentVariables(path))
            {
                path = await FileSystemResource.ExpandEnvironmentVariables(path, _restClient);
            }

            path = NormalizePath(path);
            var request = new PathTreeRequestDto {
                Path = path, RequestedDirectories = new List <int>()
            };

            if (ignoreEntriesCache || !TryGetCachedDirectory(path, out var cachedDirectory) ||
                cachedDirectory.DirectoriesOnly)
            {
                request.RequestEntries = true;
            }

            var parts = PathHelper.GetPathDirectories(path).ToList();

            for (var i = 0; i < parts.Count; i++)
            {
                var partPath = parts[i];

                if (ignorePathCache || !TryGetCachedDirectory(partPath, out _))
                {
                    request.RequestedDirectories.Add(i);
                }
            }

            PathTreeResponseDto queryResponse = null;

            if (request.RequestEntries || request.RequestedDirectories.Any())
            {
                queryResponse = await FileExplorerResource.GetPathTree(request,
                                                                       DirectoryHelper.IsComputerDirectory(path), token, _restClient);
            }

            parts.Add(path);

            DirectoryEntry directory       = null;
            var            pathDirectories = new List <DirectoryEntry>();
            IReadOnlyList <FileExplorerEntry> directoryEntries = null;

            for (var i = 0; i < parts.Count; i++)
            {
                var directoryPath = parts[i];

                if (directory == null)
                {
                    if (TryGetCachedDirectory(directoryPath, out cachedDirectory))
                    {
                        directory = cachedDirectory.Directory;
                    }
                    else
                    {
                        directory = _computerDirectory.Entries.OfType <DirectoryEntry>()
                                    .FirstOrDefault(x => string.Equals(x.Path, directoryPath, PathStringComparison));
                    }
                }

                if (directory == null) //Special folders like trash can etc.
                {
                    directory = await FileSystemResource.GetDirectoryEntry(directoryPath, _restClient);

                    directory.Migrate();
                }

                if (request.RequestEntries && i == parts.Count - 1)
                {
                    // ReSharper disable once PossibleNullReferenceException
                    directoryEntries = queryResponse.Entries;
                    foreach (var entry in directoryEntries)
                    {
                        entry.Migrate(directory);
                    }

                    AddToCache(directory, directoryEntries, false);
                }
                else if (queryResponse?.Directories != null && queryResponse.Directories.TryGetValue(i, out var subDirectories))
                {
                    directoryEntries = subDirectories;

                    foreach (var directoryEntry in directoryEntries)
                    {
                        directoryEntry.Migrate(directory);
                    }

                    AddToCache(directory, directoryEntries, true);
                }
                else
                {
                    directoryEntries = _localCache[NormalizePath(directoryPath)].Entries.ToList();
                }

                pathDirectories.Add(directory);

                //if we are not at the very last part (so there is a child directory)
                if (i < parts.Count - 1)
                {
                    var normalizedPath = NormalizePath(parts[i + 1]); //path of the child directory
                    var nextDirectory  = directoryEntries.OfType <DirectoryEntry>().FirstOrDefault(x =>
                                                                                                   string.Equals(normalizedPath, NormalizePath(x.Path), PathStringComparison));

                    if (nextDirectory == null)
                    {
                        nextDirectory = new DirectoryEntry
                        {
                            HasSubFolder = true,
                            Parent       = directory,
                            Name         = GetDirectoryName(normalizedPath)
                        };
                        directoryEntries = directoryEntries.Concat(new[] { nextDirectory }).ToList();

                        //update cache
                        var key      = NormalizePath(directoryPath);
                        var oldCache = _localCache[key];
                        _localCache[key] = new CachedDirectory(oldCache.Directory, oldCache.DirectoriesOnly,
                                                               directoryEntries);
                    }

                    directory = nextDirectory;
                }
            }

            return(new PathContent(directory, directoryEntries, pathDirectories));
        }