using System; using System.IO; using System.Threading; using System.Threading.Tasks; using Humanizer; namespace Artemis.Core { /// /// Represents a plugin prerequisite action that copies a folder /// public class CopyFolderAction : PluginPrerequisiteAction { /// /// Creates a new instance of a copy folder action /// /// The name of the action /// The source folder to copy /// The target folder to copy to (will be created if needed) public CopyFolderAction(string name, string source, string target) : base(name) { Source = source; Target = target; } /// /// Gets the source directory /// public string Source { get; } /// /// Gets or sets the target directory /// public string Target { get; } /// public override async Task Execute(CancellationToken cancellationToken) { DirectoryInfo source = new(Source); DirectoryInfo target = new(Target); if (!source.Exists) throw new ArtemisCoreException($"The source directory at '{source}' was not found."); int filesCopied = 0; FileInfo[] files = source.GetFiles("*", SearchOption.AllDirectories); foreach (FileInfo fileInfo in files) { string outputPath = fileInfo.FullName.Replace(source.FullName, target.FullName); string outputDir = Path.GetDirectoryName(outputPath)!; Utilities.CreateAccessibleDirectory(outputDir); void SubProgressOnProgressReported(object? sender, EventArgs e) { if (SubProgress.ProgressPerSecond != 0) Status = $"Copying {fileInfo.Name} - {SubProgress.ProgressPerSecond.Bytes().Humanize("#.##")}/sec"; else Status = $"Copying {fileInfo.Name}"; } Progress.Report((filesCopied, files.Length)); SubProgress.ProgressReported += SubProgressOnProgressReported; await using FileStream sourceStream = fileInfo.OpenRead(); await using FileStream destinationStream = File.Create(outputPath); await sourceStream.CopyToAsync(fileInfo.Length, destinationStream, SubProgress, cancellationToken); filesCopied++; SubProgress.ProgressReported -= SubProgressOnProgressReported; } Progress.Report((filesCopied, files.Length)); Status = $"Finished copying {filesCopied} file(s)"; } } }