using System;
using System.IO;
using System.IO.Compression;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Artemis.Core
{
///
/// Represents a plugin prerequisite action that extracts a ZIP file
///
public class ExtractArchiveAction : PluginPrerequisiteAction
{
///
/// Creates a new instance of .
///
/// The name of the action
/// The ZIP file to extract
/// The folder into which to extract the file
public ExtractArchiveAction(string name, string fileName, string target) : base(name)
{
FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
Target = target ?? throw new ArgumentNullException(nameof(target));
ShowProgressBar = true;
}
///
/// Gets the file to extract
///
public string FileName { get; }
///
/// Gets the folder into which to extract the file
///
public string Target { get; }
///
public override async Task Execute(CancellationToken cancellationToken)
{
using HttpClient client = new();
ShowSubProgressBar = true;
Status = $"Extracting {FileName}";
Utilities.CreateAccessibleDirectory(Target);
await using (FileStream fileStream = new(FileName, FileMode.Open))
{
ZipArchive archive = new(fileStream);
long count = 0;
foreach (ZipArchiveEntry entry in archive.Entries)
{
await using Stream unzippedEntryStream = entry.Open();
Progress.Report((count, archive.Entries.Count));
if (entry.Length > 0)
{
string path = Path.Combine(Target, entry.FullName);
CreateDirectoryForFile(path);
await using Stream extractStream = new FileStream(path, FileMode.OpenOrCreate);
await unzippedEntryStream.CopyToAsync(entry.Length, extractStream, SubProgress, cancellationToken);
}
count++;
}
}
Progress.Report((1, 1));
ShowSubProgressBar = false;
Status = "Finished extracting";
}
private static void CreateDirectoryForFile(string path)
{
string? directory = Path.GetDirectoryName(path);
if (directory == null)
throw new ArtemisCoreException($"Failed to get directory from path {path}");
Utilities.CreateAccessibleDirectory(directory);
}
}
}