From 2f29be6222835d3d4e9b001a7d595f5e0ba72761 Mon Sep 17 00:00:00 2001 From: PurpleCreativity Date: Wed, 17 Jun 2026 22:40:18 +0200 Subject: [PATCH] Better argument handling, make output-dir optional --- Program.cs | 56 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/Program.cs b/Program.cs index 675566d..d17f40f 100644 --- a/Program.cs +++ b/Program.cs @@ -7,9 +7,9 @@ namespace WSiPBookDownloader; internal class BookMissingException : Exception { - public int BookId { get; } + public uint BookId { get; } - public BookMissingException(int bookId) + public BookMissingException(uint bookId) : base($"Book with ID {bookId} does not exist.") { BookId = bookId; @@ -45,28 +45,46 @@ internal class Program static async Task Main(string[] args) { - if (args.Length < 2 || args.Length > 4) + var onlyCovers = args.Any(arg => arg.Equals("--only-covers", StringComparison.OrdinalIgnoreCase)); + + var outputDirectory = Directory.GetCurrentDirectory(); + var outputDirectoryIndex = Array.FindIndex(args, arg => arg.Equals("--output-dir", StringComparison.OrdinalIgnoreCase)); + if (outputDirectoryIndex > -1) { - Log("Usage: [outputDirectory] [startBookId] [endBookId] [--only-covers]", ConsoleColor.DarkRed); - return; + if (outputDirectoryIndex + 1 >= args.Length) + { + Log("--output-dir requires a value.", ConsoleColor.DarkRed); + return; + } + + outputDirectory = args[outputDirectoryIndex + 1]; + + if (!Directory.Exists(outputDirectory)) + { + Log($"Output directory \"{outputDirectory}\" does not exist.", ConsoleColor.DarkRed); + return; + } } - var outputDirectory = args[0]; - if (!Path.Exists(outputDirectory)) - { - Log($"Output directory \"{outputDirectory}\" does not exist.", ConsoleColor.DarkRed); - return; - } + var positionalArgs = args + .Except( + [ + "--only-covers", + "--output-dir", + outputDirectory + ], StringComparer.OrdinalIgnoreCase) + .ToArray(); - var startBookId = int.Parse(args[1]); - var endBookId = (args.Length >= 3 && int.TryParse(args[2], out var parsedEndBookId)) - ? parsedEndBookId + var startBookId = int.Parse(positionalArgs[0]); + var endBookId = positionalArgs.Length > 1 + ? int.Parse(positionalArgs[1]) : startBookId; - var onlyCovers = args.FirstOrDefault(arg => arg.Equals("--only-covers", StringComparison.OrdinalIgnoreCase)) != null; - var bookIds = Enumerable.Range(startBookId, endBookId - startBookId + 1); + var bookIds = Enumerable.Range(startBookId, endBookId - startBookId + 1).Select(bookId => (uint)bookId); var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = onlyCovers ? 100 : 10 }; + Log($"Output directory: \"{outputDirectory}\""); + await Parallel.ForEachAsync(bookIds, parallelOptions, async (bookId, cancellationToken) => { var outputPath = Path.Combine(outputDirectory, $"{bookId}.pdf"); @@ -104,7 +122,7 @@ internal class Program }); } - private static async Task DownloadBookCoverJpg(int bookId, string outputDir, CancellationToken cancellationToken = default) + private static async Task DownloadBookCoverJpg(uint bookId, string outputDir, CancellationToken cancellationToken = default) { var outputPath = Path.Combine(outputDir, $"{bookId}.jpg"); if (File.Exists(outputPath)) @@ -126,7 +144,7 @@ internal class Program Debug.WriteLine($"Downloaded cover for book {bookId}"); } - private static async Task DownloadBookJpg(int bookId, string outputDir, CancellationToken cancellationToken = default) + private static async Task DownloadBookJpg(uint bookId, string outputDir, CancellationToken cancellationToken = default) { var currentPage = 1; while (true) @@ -163,7 +181,7 @@ internal class Program } } - private static void BuildPdf(int bookId, string jpgDir, string outputPath) + private static void BuildPdf(uint bookId, string jpgDir, string outputPath) { var pages = Directory.GetFiles(jpgDir, "*.jpg") .OrderBy(file => int.Parse(Path.GetFileNameWithoutExtension(file)))