From fd54bcc9213d0d1e0426e9ecc0e9aec6d6d33628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Sat, 29 Jan 2022 23:26:42 +0100 Subject: [PATCH] feat(data): add cli for database migration and extraction of nos files --- .../Commands/ExtractNosFileCommand.cs | 63 +++++++++++++++ .../Commands/MigrateDatabaseCommand.cs | 63 +++++++++++++++ .../NosSmooth.Data.CLI.csproj | 11 +++ Data/NosSmooth.Data.CLI/Program.cs | 76 +++++++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 Data/NosSmooth.Data.CLI/Commands/ExtractNosFileCommand.cs create mode 100644 Data/NosSmooth.Data.CLI/Commands/MigrateDatabaseCommand.cs create mode 100644 Data/NosSmooth.Data.CLI/Program.cs diff --git a/Data/NosSmooth.Data.CLI/Commands/ExtractNosFileCommand.cs b/Data/NosSmooth.Data.CLI/Commands/ExtractNosFileCommand.cs new file mode 100644 index 0000000000000000000000000000000000000000..ac472f7dbd0fab7dc35d9873ad0cfb0e61d183e5 --- /dev/null +++ b/Data/NosSmooth.Data.CLI/Commands/ExtractNosFileCommand.cs @@ -0,0 +1,63 @@ +// +// ExtractNosFileCommand.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Net; +using System.Text; +using NosSmooth.Data.NOSFiles.Files; +using NosSmooth.Data.NOSFiles.Readers; +using Remora.Commands.Attributes; +using Remora.Commands.Groups; +using Remora.Results; + +namespace NosSmooth.Data.CLI.Commands; + +/// +/// A command to extract files from a NosTale archive. +/// +public class ExtractNosFileCommand : CommandGroup +{ + private readonly FileReader _reader; + + /// + /// Initializes a new instance of the class. + /// + /// The file reader. + public ExtractNosFileCommand(FileReader reader) + { + _reader = reader; + } + + /// + /// Handles extract command. + /// + /// The input nos archive. + /// The output directory to put the extracted files to. + /// A result that may or may not have succeeded.. + [Command("extract")] + public async Task HandleExtract + ( + string inputFile, + [Option('o', "option")] + string outputDirectory = "out" + ) + { + Directory.CreateDirectory(outputDirectory); + + var readResult = _reader.ReadFileSystemFile(inputFile); + if (!readResult.IsSuccess) + { + return Result.FromError(readResult); + } + + foreach (var file in readResult.Entity.Content.Files) + { + var outputPath = Path.Combine(outputDirectory, file.Path); + await File.WriteAllBytesAsync(outputPath, file.Content, CancellationToken); + } + + return Result.FromSuccess(); + } +} \ No newline at end of file diff --git a/Data/NosSmooth.Data.CLI/Commands/MigrateDatabaseCommand.cs b/Data/NosSmooth.Data.CLI/Commands/MigrateDatabaseCommand.cs new file mode 100644 index 0000000000000000000000000000000000000000..066f204c988751ca29ad9ec33cdecf0a9906a847 --- /dev/null +++ b/Data/NosSmooth.Data.CLI/Commands/MigrateDatabaseCommand.cs @@ -0,0 +1,63 @@ +// +// MigrateDatabaseCommand.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.Data.Abstractions.Language; +using NosSmooth.Data.Database; +using NosSmooth.Data.NOSFiles; +using Remora.Commands.Attributes; +using Remora.Commands.Groups; +using Remora.Results; + +namespace NosSmooth.Data.CLI.Commands; + +/// +/// Create a database from nos files. +/// +public class MigrateDatabaseCommand : CommandGroup +{ + private readonly DatabaseMigrator _migrator; + private readonly NostaleDataParser _parser; + + /// + /// Initializes a new instance of the class. + /// + /// The database migrator. + /// The data parser. + public MigrateDatabaseCommand(DatabaseMigrator migrator, NostaleDataParser parser) + { + _migrator = migrator; + _parser = parser; + } + + /// + /// Migrate the database using nos files. + /// + /// The directory with nostale data files. + /// A representing the asynchronous operation. + [Command("migrate")] + public async Task HandleMigrate(string nostaleDataPath) + { + var parsingResult = _parser.ParseFiles + ( + nostaleDataPath, + Language.Cz, + Language.De, + Language.Uk, + Language.Es, + Language.Fr, + Language.It, + Language.Pl, + Language.Ru, + Language.Tr + ); + if (!parsingResult.IsSuccess) + { + return Result.FromError(parsingResult); + } + + return await _migrator.Migrate(parsingResult.Entity); + } +} \ No newline at end of file diff --git a/Data/NosSmooth.Data.CLI/NosSmooth.Data.CLI.csproj b/Data/NosSmooth.Data.CLI/NosSmooth.Data.CLI.csproj index c10fffa497f41d7e9f68803add150a868aab2f6e..f35ecb2f50a620a98db08f83636156f8aabc521e 100644 --- a/Data/NosSmooth.Data.CLI/NosSmooth.Data.CLI.csproj +++ b/Data/NosSmooth.Data.CLI/NosSmooth.Data.CLI.csproj @@ -7,4 +7,15 @@ Exe + + + + + + + + + + + diff --git a/Data/NosSmooth.Data.CLI/Program.cs b/Data/NosSmooth.Data.CLI/Program.cs new file mode 100644 index 0000000000000000000000000000000000000000..69e0ad8868628e016ca31a263725d3754f9b7059 --- /dev/null +++ b/Data/NosSmooth.Data.CLI/Program.cs @@ -0,0 +1,76 @@ +// +// Program.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Extensions.DependencyInjection; +using NosSmooth.Data.CLI.Commands; +using NosSmooth.Data.Database.Extensions; +using NosSmooth.Data.NOSFiles.Extensions; +using NosSmooth.Data.NOSFiles.Files; +using NosSmooth.Data.NOSFiles.Readers; +using NosSmooth.Data.NOSFiles.Readers.Types; +using Remora.Commands.Extensions; +using Remora.Commands.Services; +using Remora.Results; + +namespace NosSmooth.Data.CLI; + +/// +/// Entrypoint class. +/// +public class Program +{ + /// + /// Entrypoint method. + /// + /// The arguments. + /// A representing the asynchronous operation. + public static async Task Main(string[] arguments) + { + var services = CreateServices(); + var commandService = services.GetRequiredService(); + var preparedCommandResult = await commandService.TryPrepareCommandAsync(string.Join(' ', arguments), services); + if (!preparedCommandResult.IsSuccess) + { + Console.Error.WriteLine($"There was an error, {preparedCommandResult.Error.Message}"); + return; + } + + if (preparedCommandResult.Entity is null) + { + Console.Error.WriteLine("You must enter a command such ast list or inject."); + return; + } + + var executionResult = await commandService.TryExecuteAsync(preparedCommandResult.Entity, services); + if (!executionResult.Entity.IsSuccess) + { + switch (executionResult.Entity.Error) + { + case ExceptionError exc: + Console.Error.WriteLine($"There was an exception, {exc.Exception.Message}"); + break; + default: + Console.Error.WriteLine($"There was an error, {executionResult.Entity.Error!.Message}"); + break; + } + } + } + + private static IServiceProvider CreateServices() + { + var collection = new ServiceCollection(); + + collection + .AddNostaleDataParsing() + .AddNostaleDatabaseMigrator() + .AddCommands() + .AddCommandTree() + .WithCommandGroup() + .WithCommandGroup(); + + return collection.BuildServiceProvider(); + } +} \ No newline at end of file