From c8fabe999e7b95a121cf9f09934b31ce8a99e0dd Mon Sep 17 00:00:00 2001 From: azures04 Date: Mon, 26 Jan 2026 23:20:34 +0100 Subject: [PATCH] Initial commit with packager implementation Add AzuresPackager project with .gitignore, solution and project files, core Packager.cs implementation, and sample source files. Implements basic package creation, extraction, and file handling using SharpCompress. --- .gitignore | 59 ++++++++++++++++++++++ AzuresPackager.csproj | 14 ++++++ AzuresPackager.sln | 24 +++++++++ Packager.cs | 112 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 .gitignore create mode 100644 AzuresPackager.csproj create mode 100644 AzuresPackager.sln create mode 100644 Packager.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..06f9cf6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ +## A streamlined .gitignore for modern .NET projects +## including temporary files, build results, and +## files generated by popular .NET tools. If you are +## developing with Visual Studio, the VS .gitignore +## https://github.com/github/gitignore/blob/main/VisualStudio.gitignore +## has more thorough IDE-specific entries. +## +## Get latest from https://github.com/github/gitignore/blob/main/Dotnet.gitignore + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg + +# dotenv environment variables file +.env + +# Others +~$* +*~ +CodeCoverage/ + +# MSBuild Binary and Structured Log +*.binlog + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +temp \ No newline at end of file diff --git a/AzuresPackager.csproj b/AzuresPackager.csproj new file mode 100644 index 0000000..84109e2 --- /dev/null +++ b/AzuresPackager.csproj @@ -0,0 +1,14 @@ + + + net8.0 + true + AzuresPackager + 1.0.0 + azures04 + https://gitea.azures.fr/Azures04/AzuresPackager + + + + + + \ No newline at end of file diff --git a/AzuresPackager.sln b/AzuresPackager.sln new file mode 100644 index 0000000..52ed38b --- /dev/null +++ b/AzuresPackager.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzuresPackager", "AzuresPackager.csproj", "{B853400F-35B5-924D-72A5-D2AEEF025774}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B853400F-35B5-924D-72A5-D2AEEF025774}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B853400F-35B5-924D-72A5-D2AEEF025774}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B853400F-35B5-924D-72A5-D2AEEF025774}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B853400F-35B5-924D-72A5-D2AEEF025774}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AA88177B-51D0-44C0-AFA0-1B34161C75E1} + EndGlobalSection +EndGlobal diff --git a/Packager.cs b/Packager.cs new file mode 100644 index 0000000..02fa6f9 --- /dev/null +++ b/Packager.cs @@ -0,0 +1,112 @@ +using System.IO; +using System.Text; +using SharpCompress.Archives; +using SharpCompress.Common; +using SharpCompress.Writers; +using System.Collections.Generic; +using System.Linq; +using System; + +namespace AzuresPackager; + +public class AzuresPackage : IDisposable { + private readonly byte[] _data; + private readonly byte _key; + + public AzuresPackage(string filePath, byte key) { + _key = key; + _data = File.ReadAllBytes(filePath); + Decode(); + } + + private void Decode() { + for (int i = 0; i < _data.Length; i++) { + _data[i] = (byte)(_data[i] ^ _key); + } + } + + public List ListEntries() { + using var ms = new MemoryStream(_data); + using var archive = ArchiveFactory.Open(ms); + return archive.Entries.Select(e => e.Key!).ToList(); + } + + public string GetFileContent(string internalPath) { + using var ms = new MemoryStream(_data); + using var archive = ArchiveFactory.Open(ms); + var entry = archive.Entries.FirstOrDefault(e => e.Key == internalPath); + + if (entry == null || entry.IsDirectory) return string.Empty; + + using var entryStream = entry.OpenEntryStream(); + using var reader = new StreamReader(entryStream, Encoding.UTF8); + return reader.ReadToEnd(); + } + + public byte[] GetFileBytes(string internalPath) { + using var ms = new MemoryStream(_data); + using var archive = ArchiveFactory.Open(ms); + var entry = archive.Entries.FirstOrDefault(e => e.Key == internalPath); + + if (entry == null) return Array.Empty(); + + using var entryStream = entry.OpenEntryStream(); + using var outMs = new MemoryStream(); + entryStream.CopyTo(outMs); + return outMs.ToArray(); + } + + public void Unpack(string targetDirectory) { + if (!Directory.Exists(targetDirectory)) Directory.CreateDirectory(targetDirectory); + + using var ms = new MemoryStream(_data); + using var archive = ArchiveFactory.Open(ms); + foreach (var entry in archive.Entries.Where(e => !e.IsDirectory)) { + entry.WriteToDirectory(targetDirectory, new ExtractionOptions { + ExtractFullPath = true, + Overwrite = true + }); + } + } + + public void Dispose() { + Array.Clear(_data, 0, _data.Length); + } +} + +public static class Packager { + public static void Pack(string sourceFolder, string outputPath, byte key) { + using var memoryStream = new MemoryStream(); + var writerOptions = new WriterOptions(CompressionType.LZMA); + + using (var writer = WriterFactory.Open(memoryStream, ArchiveType.Zip, writerOptions)) { + writer.WriteAll(sourceFolder, "*", SearchOption.AllDirectories); + } + + byte[] data = memoryStream.ToArray(); + + for (int i = 0; i < data.Length; i++) { + data[i] = (byte)(data[i] ^ key); + } + + File.WriteAllBytes(outputPath, data); + } +} + +public static class MimeHelper { + public static string GetMimeType(string path) { + string extension = Path.GetExtension(path).ToLower(); + return extension switch + { + ".html" or ".htm" => "text/html", + ".css" => "text/css", + ".js" => "text/javascript", + ".png" => "image/png", + ".jpg" or ".jpeg" => "image/jpeg", + ".svg" => "image/svg+xml", + ".woff2" => "font/woff2", + ".json" => "application/json", + _ => "application/octet-stream", + }; + } +} \ No newline at end of file