public async Task <FolderOperationResult> CopyFolderAsync(
            string path,
            string destinationPath,
            DuplicateEntryHandling dupeEntryHandling = DuplicateEntryHandling.Skip,
            CancellationToken cancelToken            = default)
        {
            Guard.NotEmpty(path, nameof(path));
            Guard.NotEmpty(destinationPath, nameof(destinationPath));

            path = FolderService.NormalizePath(path);
            ValidateFolderPath(path, "CopyFolder", nameof(path));

            destinationPath = FolderService.NormalizePath(destinationPath);
            if (destinationPath.EnsureEndsWith("/").StartsWith(path.EnsureEndsWith("/")))
            {
                throw new ArgumentException(T("Admin.Media.Exception.DescendantFolder", destinationPath, path), nameof(destinationPath));
            }

            var node = _folderService.GetNodeByPath(path);

            if (node == null)
            {
                throw _exceptionFactory.FolderNotFound(path);
            }

            if (node.Value.IsAlbum)
            {
                throw new NotSupportedException(T("Admin.Media.Exception.CopyRootAlbum", node.Value.Name));
            }

            using (var scope = new DbContextScope(_db, autoDetectChanges: false, deferCommit: true))
            {
                destinationPath += "/" + node.Value.Name;
                var dupeFiles = new List <DuplicateFileInfo>();

                // >>>> Do the heavy stuff
                var folder = await InternalCopyFolder(scope, node, destinationPath, dupeEntryHandling, dupeFiles, cancelToken);

                var result = new FolderOperationResult
                {
                    Operation = "copy",
                    DuplicateEntryHandling = dupeEntryHandling,
                    Folder         = folder,
                    DuplicateFiles = dupeFiles
                };

                return(result);
            }
        }
        public async Task <FolderDeleteResult> DeleteFolderAsync(
            string path,
            FileHandling fileHandling     = FileHandling.SoftDelete,
            CancellationToken cancelToken = default)
        {
            Guard.NotEmpty(path, nameof(path));

            path = FolderService.NormalizePath(path);
            ValidateFolderPath(path, "DeleteFolder", nameof(path));

            var root = _folderService.GetNodeByPath(path);

            if (root == null)
            {
                throw _exceptionFactory.FolderNotFound(path);
            }

            // Collect all affected subfolders also
            var allNodes = root.FlattenNodes(true).Reverse().ToArray();
            var result   = new FolderDeleteResult();

            using (var scope = new DbContextScope(_db, autoDetectChanges: false, deferCommit: true))
            {
                // Delete all from DB
                foreach (var node in allNodes)
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        break;
                    }

                    var folder = await _db.MediaFolders.FindByIdAsync(node.Value.Id);

                    if (folder != null)
                    {
                        await InternalDeleteFolder(scope, folder, node, root, result, fileHandling, cancelToken);
                    }
                }
            }

            return(result);
        }
Exemple #3
0
 public string CombinePaths(params string[] paths)
 {
     return(FolderService.NormalizePath(Path.Combine(paths), false));
 }
        public async Task <MediaFolderInfo> MoveFolderAsync(string path, string destinationPath)
        {
            Guard.NotEmpty(path, nameof(path));
            Guard.NotEmpty(destinationPath, nameof(destinationPath));

            path = FolderService.NormalizePath(path);
            ValidateFolderPath(path, "MoveFolder", nameof(path));

            var node = _folderService.GetNodeByPath(path);

            if (node == null)
            {
                throw _exceptionFactory.FolderNotFound(path);
            }

            if (node.Value.IsAlbum)
            {
                throw new NotSupportedException(T("Admin.Media.Exception.AlterRootAlbum", node.Value.Name));
            }

            var folder = await _db.MediaFolders.FindByIdAsync(node.Value.Id);

            if (folder == null)
            {
                throw _exceptionFactory.FolderNotFound(path);
            }

            ValidateFolderPath(destinationPath, "MoveFolder", nameof(destinationPath));

            // Destination must not exist
            if (FolderExists(destinationPath))
            {
                throw new ArgumentException(T("Admin.Media.Exception.DuplicateFolder", destinationPath));
            }

            var destParent = FolderService.NormalizePath(Path.GetDirectoryName(destinationPath));

            // Get destination parent
            var destParentNode = _folderService.GetNodeByPath(destParent);

            if (destParentNode == null)
            {
                throw _exceptionFactory.FolderNotFound(destinationPath);
            }

            // Cannot move outside source album
            if (!_folderService.AreInSameAlbum(folder.Id, destParentNode.Value.Id))
            {
                throw _exceptionFactory.NotSameAlbum(node.Value.Path, destParent);
            }

            if (destParentNode.IsDescendantOfOrSelf(node))
            {
                throw new ArgumentException(T("Admin.Media.Exception.DescendantFolder", destinationPath, node.Value.Path));
            }

            // Set new values
            folder.ParentId = destParentNode.Value.Id;
            folder.Name     = Path.GetFileName(destinationPath);

            // Commit
            await _db.SaveChangesAsync();

            return(new MediaFolderInfo(_folderService.GetNodeById(folder.Id)));
        }
        public async Task <MediaFolderInfo> CreateFolderAsync(string path)
        {
            Guard.NotEmpty(path, nameof(path));

            path = FolderService.NormalizePath(path, false);
            ValidateFolderPath(path, "CreateFolder", nameof(path));

            var dupe = _folderService.GetNodeByPath(path);

            if (dupe != null)
            {
                throw _exceptionFactory.DuplicateFolder(path, dupe.Value);
            }

            var  sep         = "/";
            var  folderNames = path.Split(new[] { sep }, StringSplitOptions.RemoveEmptyEntries);
            bool flag        = false;
            int  folderId    = 0;

            path = string.Empty;

            for (int i = 0; i < folderNames.Length; i++)
            {
                var folderName = MediaHelper.NormalizeFolderName(folderNames[i]);
                path += (i > 0 ? sep : string.Empty) + folderName;

                if (!flag)
                {
                    // Find the last existing node in path trail
                    var currentNode = _folderService.GetNodeByPath(path)?.Value;
                    if (currentNode != null)
                    {
                        folderId = currentNode.Id;
                    }
                    else
                    {
                        if (i == 0)
                        {
                            throw new NotSupportedException(T("Admin.Media.Exception.TopLevelAlbum", path));
                        }
                        flag = true;
                    }
                }

                if (flag)
                {
                    using (new DbContextScope(_db, deferCommit: false))
                    {
                        var mediaFolder = new MediaFolder {
                            Name = folderName, ParentId = folderId
                        };
                        _db.MediaFolders.Add(mediaFolder);
                        await _db.SaveChangesAsync();

                        folderId = mediaFolder.Id;
                    }
                }
            }

            return(new MediaFolderInfo(_folderService.GetNodeById(folderId)));
        }