Merge pull request #37 from That-One-Nerd/more-compression-options
Update main with some new compression formats.
This commit is contained in:
commit
51f58e6e82
@ -1,9 +1,13 @@
|
||||
global using Nerd_STF.Mathematics;
|
||||
global using SharpCompress.Archives.Rar;
|
||||
global using SharpCompress.Archives.SevenZip;
|
||||
global using SharpCompress.Readers;
|
||||
global using SrcMod.Shell;
|
||||
global using SrcMod.Shell.Modules.ObjectModels;
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Diagnostics;
|
||||
global using System.Formats.Tar;
|
||||
global using System.IO;
|
||||
global using System.IO.Compression;
|
||||
global using System.Linq;
|
||||
|
||||
@ -1,14 +1,24 @@
|
||||
namespace SrcMod.Shell.Modules;
|
||||
|
||||
// Some things that can be extracted can't be compressed by SharpCompress.
|
||||
// In the future I might replace it with my own, but that'll take a *really*
|
||||
// long time and I'm already planning to do that for the valve compression formats,
|
||||
// so I'll seethe for now.
|
||||
[Module("compress")]
|
||||
public static class CompressionModule
|
||||
{
|
||||
[Command("zip")]
|
||||
public static void CompressZip(string source, string? destination = null,
|
||||
[Command("gz")]
|
||||
[Command("gzip")]
|
||||
public static void CompressGZip(string source, string? destination = null,
|
||||
CompressionLevel level = CompressionLevel.Optimal)
|
||||
{
|
||||
destination ??= Path.Combine(Path.GetDirectoryName(Path.GetFullPath(source))!,
|
||||
$"{Path.GetFileNameWithoutExtension(source)}.zip");
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source),
|
||||
name = Path.GetFileName(full),
|
||||
folder = Program.Shell!.WorkingDirectory;
|
||||
destination ??= $"{folder}\\{name}.gz";
|
||||
}
|
||||
|
||||
string absSource = Path.GetFullPath(source),
|
||||
localDest = Path.GetRelativePath(Program.Shell!.WorkingDirectory, destination);
|
||||
@ -19,8 +29,109 @@ public static class CompressionModule
|
||||
string message = $"Compressing file at \"{source}\" into \"{localDest}\"...";
|
||||
Write(message);
|
||||
|
||||
Stream writer = new FileStream(destination, FileMode.CreateNew);
|
||||
FileStream writer = new(localDest, FileMode.CreateNew),
|
||||
reader = new(absSource, FileMode.Open);
|
||||
GZipStream gzip = new(writer, level);
|
||||
|
||||
reader.CopyTo(gzip);
|
||||
|
||||
gzip.Close();
|
||||
reader.Close();
|
||||
writer.Close();
|
||||
|
||||
Console.CursorLeft = 0;
|
||||
Console.CursorTop -= (message.Length / Console.BufferWidth) + 1;
|
||||
Write(new string(' ', message.Length), newLine: false);
|
||||
}
|
||||
else if (Directory.Exists(source)) throw new("The GZip format can only compress 1 file.");
|
||||
else throw new("No file located at \"source\"");
|
||||
}
|
||||
|
||||
[Command("tar")]
|
||||
[Command("tarball")]
|
||||
public static void CompressTar(string source, string? destination = null)
|
||||
{
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source),
|
||||
name = Path.GetFileNameWithoutExtension(full),
|
||||
folder = Program.Shell!.WorkingDirectory;
|
||||
destination ??= $"{folder}\\{name}.tar";
|
||||
}
|
||||
|
||||
string absSource = Path.GetFullPath(source),
|
||||
localDest = Path.GetRelativePath(Program.Shell!.WorkingDirectory, destination);
|
||||
|
||||
if (File.Exists(source)) throw new("The Tar format cannot compress a single file.");
|
||||
else if (Directory.Exists(source))
|
||||
{
|
||||
if (File.Exists(destination)) throw new($"File already exists at \"{localDest}\"");
|
||||
|
||||
Write($"Compressing folder at \"{source}\" into \"{localDest}\"...");
|
||||
|
||||
FileStream writer = new(destination, FileMode.CreateNew);
|
||||
TarFile.CreateFromDirectory(absSource, writer, false);
|
||||
|
||||
writer.Close();
|
||||
|
||||
Console.CursorLeft = 0;
|
||||
Write(new string(' ', Console.BufferWidth), newLine: false);
|
||||
Console.SetCursorPosition(0, Console.CursorTop - 1);
|
||||
Write(new string(' ', Console.BufferWidth), newLine: false);
|
||||
}
|
||||
else throw new("No file or directory located at \"source\"");
|
||||
}
|
||||
|
||||
// Rar can't be compressed.
|
||||
|
||||
[Command("targz")]
|
||||
[Command("tar.gz")]
|
||||
[Command("tar-gz")]
|
||||
public static void CompressTarGzip(string source, string? destination = null,
|
||||
CompressionLevel level = CompressionLevel.Optimal)
|
||||
{
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source),
|
||||
name = Path.GetFileNameWithoutExtension(full),
|
||||
folder = Program.Shell!.WorkingDirectory;
|
||||
destination ??= $"{folder}\\{name}.tar.gz";
|
||||
}
|
||||
|
||||
string firstDest = Path.GetFileNameWithoutExtension(destination);
|
||||
|
||||
CompressTar(source, firstDest);
|
||||
CompressGZip(firstDest, destination, level);
|
||||
File.Delete(firstDest);
|
||||
|
||||
Console.CursorLeft = 0;
|
||||
Console.CursorTop--;
|
||||
}
|
||||
|
||||
[Command("zip")]
|
||||
public static void CompressZip(string source, string? destination = null,
|
||||
CompressionLevel level = CompressionLevel.Optimal, string comment = "")
|
||||
{
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source),
|
||||
name = Path.GetFileNameWithoutExtension(full),
|
||||
folder = Program.Shell!.WorkingDirectory;
|
||||
destination ??= $"{folder}\\{name}.zip";
|
||||
}
|
||||
|
||||
string absSource = Path.GetFullPath(source),
|
||||
localDest = Path.GetRelativePath(Program.Shell!.WorkingDirectory, destination);
|
||||
|
||||
if (File.Exists(source))
|
||||
{
|
||||
if (File.Exists(destination)) throw new($"File already exists at \"{localDest}\"");
|
||||
string message = $"Compressing file at \"{source}\" into \"{localDest}\"...";
|
||||
Write(message);
|
||||
|
||||
FileStream writer = new(destination, FileMode.CreateNew);
|
||||
ZipArchive archive = new(writer, ZipArchiveMode.Create);
|
||||
if (!string.IsNullOrWhiteSpace(comment)) archive.Comment = comment;
|
||||
|
||||
archive.CreateEntryFromFile(absSource, Path.GetFileName(absSource), level);
|
||||
|
||||
@ -37,18 +148,40 @@ public static class CompressionModule
|
||||
|
||||
Write($"Compressing folder at \"{source}\" into \"{localDest}\"...");
|
||||
|
||||
Stream writer = new FileStream(destination, FileMode.CreateNew);
|
||||
FileStream writer = new(destination, FileMode.CreateNew);
|
||||
ZipArchive archive = new(writer, ZipArchiveMode.Create);
|
||||
if (!string.IsNullOrWhiteSpace(comment)) archive.Comment = comment;
|
||||
|
||||
List<string> files = new(GetAllFiles(absSource)),
|
||||
relative = new();
|
||||
foreach (string f in files) relative.Add(Path.GetRelativePath(absSource, f));
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
{
|
||||
string f = files[i];
|
||||
if (f.Trim().ToLower() == destination.Trim().ToLower())
|
||||
{
|
||||
files.RemoveAt(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
relative.Add(Path.GetRelativePath(absSource, f));
|
||||
}
|
||||
|
||||
int failed = 0;
|
||||
|
||||
LoadingBarStart();
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
{
|
||||
archive.CreateEntryFromFile(files[i], relative[i], level);
|
||||
LoadingBarSet((i + 1) / (float)files.Count, ConsoleColor.DarkGreen);
|
||||
bool failedThisTime = false;
|
||||
try
|
||||
{
|
||||
archive.CreateEntryFromFile(files[i], relative[i], level);
|
||||
}
|
||||
catch
|
||||
{
|
||||
failedThisTime = true;
|
||||
failed++;
|
||||
}
|
||||
LoadingBarSet((i + 1) / (float)files.Count, failedThisTime ? ConsoleColor.Red : ConsoleColor.DarkGreen); ;
|
||||
Console.CursorLeft = 0;
|
||||
string message = $"{relative[i]}";
|
||||
int remainder = Console.BufferWidth - message.Length;
|
||||
@ -67,6 +200,13 @@ public static class CompressionModule
|
||||
Write(new string(' ', Console.BufferWidth), newLine: false);
|
||||
Console.SetCursorPosition(0, Console.CursorTop - 2);
|
||||
Write(new string(' ', Console.BufferWidth), newLine: false);
|
||||
|
||||
if (failed > 0)
|
||||
{
|
||||
Console.CursorLeft = 0;
|
||||
Write($"{failed} file{(failed == 1 ? " has" : "s have")} been ignored due to an error.",
|
||||
ConsoleColor.DarkYellow);
|
||||
}
|
||||
}
|
||||
else throw new("No file or directory located at \"source\"");
|
||||
|
||||
@ -91,4 +231,6 @@ public static class CompressionModule
|
||||
name = $"Compressed a file or folder into a zip archive located at \"{destination}\""
|
||||
});
|
||||
}
|
||||
|
||||
// 7z can't be compressed.
|
||||
}
|
||||
|
||||
182
SrcMod/Shell/Modules/ExtractionModule.cs
Normal file
182
SrcMod/Shell/Modules/ExtractionModule.cs
Normal file
@ -0,0 +1,182 @@
|
||||
namespace SrcMod.Shell.Modules;
|
||||
|
||||
[Module("extract")]
|
||||
public static class ExtractionModule
|
||||
{
|
||||
[Command("gz")]
|
||||
[Command("gzip")]
|
||||
public static void ExtractGZip(string source, string? destination = null)
|
||||
{
|
||||
if (!File.Exists(source)) throw new($"No file exists at \"{source}\".");
|
||||
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source);
|
||||
string folder = Program.Shell!.WorkingDirectory;
|
||||
string name = Path.GetFileNameWithoutExtension(full);
|
||||
|
||||
destination = $"{folder}\\{name}";
|
||||
}
|
||||
|
||||
string absSource = Path.GetFullPath(source),
|
||||
localDest = Path.GetRelativePath(Program.Shell!.WorkingDirectory, destination);
|
||||
|
||||
if (File.Exists(destination)) throw new($"File already exists at \"{destination}\".");
|
||||
string message = $"Extracting file at \"{source}\" into \"{localDest}\"...";
|
||||
Write(message);
|
||||
|
||||
FileStream writer = new(destination, FileMode.CreateNew),
|
||||
reader = new(absSource, FileMode.Open);
|
||||
GZipStream gzip = new(reader, CompressionMode.Decompress);
|
||||
|
||||
gzip.CopyTo(writer);
|
||||
|
||||
gzip.Close();
|
||||
reader.Close();
|
||||
writer.Close();
|
||||
|
||||
Console.CursorLeft = 0;
|
||||
Console.CursorTop -= (message.Length / Console.BufferWidth) + 1;
|
||||
Write(new string(' ', message.Length), newLine: false);
|
||||
}
|
||||
|
||||
[Command("rar")]
|
||||
public static void ExtractRar(string source, string? destination = null)
|
||||
{
|
||||
if (!File.Exists(source)) throw new($"No file exists at \"{source}\".");
|
||||
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source);
|
||||
string folder = Program.Shell!.WorkingDirectory;
|
||||
string name = Path.GetFileNameWithoutExtension(full);
|
||||
|
||||
destination = $"{folder}\\{name}";
|
||||
}
|
||||
|
||||
if (!Directory.Exists(destination)) Directory.CreateDirectory(destination);
|
||||
|
||||
FileStream reader = new(source, FileMode.Open);
|
||||
RarArchive rar = RarArchive.Open(reader);
|
||||
|
||||
IReader data = rar.ExtractAllEntries();
|
||||
data.WriteAllToDirectory(destination, new()
|
||||
{
|
||||
ExtractFullPath = true,
|
||||
Overwrite = true,
|
||||
PreserveFileTime = true
|
||||
});
|
||||
|
||||
rar.Dispose();
|
||||
reader.Dispose();
|
||||
}
|
||||
|
||||
[Command("tar")]
|
||||
[Command("tarball")]
|
||||
public static void ExtractTar(string source, string? destination = null)
|
||||
{
|
||||
if (!File.Exists(source)) throw new($"No file exists at \"{source}\".");
|
||||
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source);
|
||||
string folder = Program.Shell!.WorkingDirectory;
|
||||
string name = Path.GetFileNameWithoutExtension(full);
|
||||
|
||||
destination = $"{folder}\\{name}";
|
||||
}
|
||||
|
||||
if (!Directory.Exists(destination)) Directory.CreateDirectory(destination);
|
||||
|
||||
FileStream reader = new(source, FileMode.Open);
|
||||
TarFile.ExtractToDirectory(reader, Path.GetFileName(destination), true);
|
||||
|
||||
reader.Dispose();
|
||||
}
|
||||
|
||||
[Command("targz")]
|
||||
[Command("tar.gz")]
|
||||
[Command("tar-gz")]
|
||||
public static void ExtractTarGz(string source, string? destination = null)
|
||||
{
|
||||
if (!File.Exists(source)) throw new($"No file exists at \"{source}\".");
|
||||
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source);
|
||||
string folder = Program.Shell!.WorkingDirectory;
|
||||
string name = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(full));
|
||||
|
||||
destination = $"{folder}\\{name}";
|
||||
}
|
||||
|
||||
string absSource = Path.GetFullPath(source),
|
||||
temp = Path.Combine(Path.GetDirectoryName(absSource)!, Path.GetFileNameWithoutExtension(absSource));
|
||||
|
||||
ExtractGZip(source, temp);
|
||||
ExtractTar(temp, destination);
|
||||
|
||||
File.Delete(temp);
|
||||
}
|
||||
|
||||
[Command("zip")]
|
||||
public static void ExtractZip(string source, string? destination = null)
|
||||
{
|
||||
if (!File.Exists(source)) throw new($"No file exists at \"{source}\".");
|
||||
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source);
|
||||
string folder = Program.Shell!.WorkingDirectory;
|
||||
string name = Path.GetFileNameWithoutExtension(full);
|
||||
|
||||
destination = $"{folder}\\{name}";
|
||||
}
|
||||
|
||||
if (!Directory.Exists(destination)) Directory.CreateDirectory(destination);
|
||||
|
||||
FileStream reader = new(source, FileMode.Open);
|
||||
ZipArchive zip = new(reader, ZipArchiveMode.Read);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(zip.Comment)) Write(zip.Comment);
|
||||
|
||||
zip.ExtractToDirectory(destination, true);
|
||||
|
||||
zip.Dispose();
|
||||
reader.Dispose();
|
||||
}
|
||||
|
||||
[Command("7z")]
|
||||
[Command("7zip")]
|
||||
[Command("sevenzip")]
|
||||
public static void Extract7Zip(string source, string? destination = null)
|
||||
{
|
||||
if (!File.Exists(source)) throw new($"No file exists at \"{source}\".");
|
||||
|
||||
if (destination is null)
|
||||
{
|
||||
string full = Path.GetFullPath(source);
|
||||
string folder = Program.Shell!.WorkingDirectory;
|
||||
string name = Path.GetFileNameWithoutExtension(full);
|
||||
|
||||
destination = $"{folder}\\{name}";
|
||||
}
|
||||
|
||||
if (!Directory.Exists(destination)) Directory.CreateDirectory(destination);
|
||||
|
||||
FileStream reader = new(source, FileMode.Open);
|
||||
SevenZipArchive zip = SevenZipArchive.Open(reader);
|
||||
|
||||
IReader data = zip.ExtractAllEntries();
|
||||
data.WriteAllToDirectory(destination, new()
|
||||
{
|
||||
ExtractFullPath = true,
|
||||
Overwrite = true,
|
||||
PreserveAttributes = true,
|
||||
PreserveFileTime = true
|
||||
});
|
||||
|
||||
zip.Dispose();
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,7 @@ public class Shell
|
||||
{
|
||||
public const string Author = "That_One_Nerd";
|
||||
public const string Name = "SrcMod";
|
||||
public const string Version = "Alpha 0.2.2";
|
||||
public const string Version = "Alpha 0.3.0";
|
||||
|
||||
public readonly string? ShellDirectory;
|
||||
|
||||
@ -170,10 +170,13 @@ public class Shell
|
||||
if (command.NameId.Trim().ToLower() != commandName) continue;
|
||||
int start = module.NameIsPrefix ? 2 : 1;
|
||||
string[] args = parts.GetRange(start, parts.Count - start).ToArray();
|
||||
|
||||
|
||||
#if RELEASE
|
||||
try
|
||||
{
|
||||
#endif
|
||||
command.Invoke(args);
|
||||
#if RELEASE
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
@ -185,6 +188,7 @@ public class Shell
|
||||
Write($"[ERROR] {ex.Message}", ConsoleColor.Red);
|
||||
if (LoadingBarEnabled) LoadingBarEnd();
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Nerd_STF" Version="2.3.2" />
|
||||
<PackageReference Include="SharpCompress" Version="0.33.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user