Files
Explorer-Workbench/src/Explorer.FileOperations/FileOperationService.cs

152 lines
5.9 KiB
C#

using Explorer.Contracts;
using Explorer.Domain;
using Explorer.Domain.Abstractions;
namespace Explorer.FileOperations;
public sealed class FileOperationService
{
private readonly ITransferHost _queue;
private readonly IShellFileOperations _shell;
private readonly IFileSystemEnumerator _enumerator;
public FileOperationService(ITransferHost queue, IShellFileOperations shell, IFileSystemEnumerator enumerator)
{
_queue = queue;
_shell = shell;
_enumerator = enumerator;
}
public void Open(IReadOnlyList<string> paths)
{
foreach (var path in paths)
{
_shell.Open(path);
}
}
public Task CopyAsync(IReadOnlyList<string> sources, string destinationDirectory, CancellationToken cancellationToken = default)
=> _queue.EnqueueCopyAsync(sources, destinationDirectory, cancellationToken);
public Task MoveAsync(IReadOnlyList<string> sources, string destinationDirectory, CancellationToken cancellationToken = default)
=> _queue.EnqueueMoveAsync(sources, destinationDirectory, cancellationToken);
public Task DeleteAsync(IReadOnlyList<string> paths, bool permanent = false, CancellationToken cancellationToken = default)
=> _queue.EnqueueDeleteAsync(paths, permanent, cancellationToken);
public Task CreateShortcutsAsync(IReadOnlyList<string> sources, string destinationDirectory, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
foreach (var source in sources)
{
var dest = UniqueShortcutPath(destinationDirectory, PathRules.GetFileName(source));
if (!_shell.CreateShortcut(source, dest, out var error) && error is not null)
{
throw new IOException(error);
}
}
return Task.CompletedTask;
}
private static string UniqueShortcutPath(string directory, string sourceName)
{
var stem = sourceName + " - Shortcut";
var dest = Path.Combine(directory, stem + ".lnk");
var i = 2;
while (File.Exists(PathRules.ToExtended(dest)) || Directory.Exists(PathRules.ToExtended(dest)))
{
dest = Path.Combine(directory, $"{stem} ({i++}).lnk");
}
return dest;
}
public Task EnqueueRenameAsync(string path, string newName, CancellationToken cancellationToken = default)
=> _queue.EnqueueRenameAsync(path, newName, cancellationToken);
public async Task EnqueueRenameAsync(IReadOnlyList<(string Path, string NewName)> items, CancellationToken cancellationToken = default)
{
foreach (var (path, newName) in items)
{
await _queue.EnqueueRenameAsync(path, newName, cancellationToken).ConfigureAwait(false);
}
}
public Task EmptyRecycleBinAsync(CancellationToken cancellationToken = default)
=> _queue.EnqueueEmptyRecycleBinAsync(cancellationToken);
public Task ExtractAsync(string archivePath, string destinationDirectory, CancellationToken cancellationToken = default)
=> _queue.EnqueueExtractAsync(archivePath, destinationDirectory, cancellationToken);
public Task CompressAsync(IReadOnlyList<string> sources, string archivePath, CancellationToken cancellationToken = default)
=> _queue.EnqueueCompressAsync(sources, archivePath, cancellationToken);
public Task AddToArchiveAsync(string archivePath, IReadOnlyList<string> sources, CancellationToken cancellationToken = default)
=> _queue.EnqueueAddToArchiveAsync(archivePath, sources, cancellationToken);
public Task VerifyArchiveAsync(string archivePath, CancellationToken cancellationToken = default)
=> _queue.EnqueueVerifyArchiveAsync(archivePath, cancellationToken);
public Task ConvertAsync(string sourcePath, string destinationPath, ConversionKind kind, CancellationToken cancellationToken = default)
=> _queue.EnqueueConvertAsync(sourcePath, destinationPath, kind, cancellationToken);
public async Task ConvertAsync(IReadOnlyList<PlannedOperation> operations, CancellationToken cancellationToken = default)
{
foreach (var op in operations.Where(o => o.Op == TransferOp.Convert && o.DestinationPath is not null))
{
var kind = Enum.TryParse<ConversionKind>(op.NewName, true, out var parsed)
? parsed
: ConversionFormats.Infer(op.SourcePath, op.DestinationPath!);
await _queue.EnqueueConvertAsync(op.SourcePath, op.DestinationPath!, kind, cancellationToken).ConfigureAwait(false);
}
}
public static string UniqueArchivePath(string directory, string stem, string extension)
{
extension = extension.Trim().TrimStart('.');
var dest = Path.Combine(directory, stem + "." + extension);
var i = 2;
while (File.Exists(PathRules.ToExtended(dest)) || Directory.Exists(PathRules.ToExtended(dest)))
{
dest = Path.Combine(directory, $"{stem} ({i++}).{extension}");
}
return dest;
}
public void Rename(string path, string newName)
{
var parent = PathRules.Parent(path);
var dest = Path.Combine(parent, newName);
var src = PathRules.ToExtended(path);
var dst = PathRules.ToExtended(dest);
if (Directory.Exists(src))
{
Directory.Move(src, dst);
}
else
{
File.Move(src, dst);
}
}
public string NewFolder(string parent)
{
var baseName = "New folder";
var name = baseName;
var i = 2;
var dest = Path.Combine(parent, name);
while (Directory.Exists(PathRules.ToExtended(dest)) || File.Exists(PathRules.ToExtended(dest)))
{
name = $"{baseName} ({i++})";
dest = Path.Combine(parent, name);
}
Directory.CreateDirectory(PathRules.ToExtended(dest));
return dest;
}
public FileSystemItem? GetItem(string path) => _enumerator.GetItem(path);
}