From 00a0b3e14f046c8526c692f1b9896cdee5d2dfe3 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Thu, 5 Feb 2026 23:20:25 -0500 Subject: [PATCH] Add --reimport and --reprocess-reactions CLI modes Add flags to reimport all data from archived files or selectively reprocess reactions. Also replace EnsureCreatedAsync with explicit database/table existence checks for safer initialization. Co-Authored-By: Claude Opus 4.6 --- src/DiscordArchiveManager/Program.cs | 108 +++++++++++++++++++-------- 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/src/DiscordArchiveManager/Program.cs b/src/DiscordArchiveManager/Program.cs index b7e606c..54a3457 100644 --- a/src/DiscordArchiveManager/Program.cs +++ b/src/DiscordArchiveManager/Program.cs @@ -1,6 +1,8 @@ using DiscordArchiveManager.Data; using DiscordArchiveManager.Services; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -32,11 +34,23 @@ var inputDirectory = config["Paths:InputDirectory"] ?? "/app/input"; var archiveDirectory = config["Paths:ArchiveDirectory"] ?? "/app/archive"; var imageDirectory = config["Paths:ImageDirectory"] ?? "/app/images"; +var reprocessReactions = args.Contains("--reprocess-reactions"); +var reimport = args.Contains("--reimport"); + logger.LogInformation("Discord Archive Manager starting..."); logger.LogInformation("Input directory: {Path}", inputDirectory); logger.LogInformation("Archive directory: {Path}", archiveDirectory); logger.LogInformation("Image directory: {Path}", imageDirectory); +if (reimport) +{ + logger.LogInformation("Mode: Reimport all data from archive"); +} +else if (reprocessReactions) +{ + logger.LogInformation("Mode: Reprocess reactions from archive"); +} + // Ensure directories exist Directory.CreateDirectory(inputDirectory); Directory.CreateDirectory(archiveDirectory); @@ -46,54 +60,84 @@ Directory.CreateDirectory(imageDirectory); using (var scope = host.Services.CreateScope()) { var context = scope.ServiceProvider.GetRequiredService(); - logger.LogInformation("Ensuring database exists and applying migrations..."); - await context.Database.EnsureCreatedAsync(); + logger.LogInformation("Ensuring database schema exists..."); + + // Get the database creator for more control + var creator = context.GetService()!; + + if (!await creator.ExistsAsync()) + { + logger.LogError("Database does not exist. Please create it first."); + return; + } + + if (!await creator.HasTablesAsync()) + { + logger.LogInformation("Creating database tables..."); + await creator.CreateTablesAsync(); + } + logger.LogInformation("Database ready."); } -// Process files +// Process files or reprocess reactions using (var scope = host.Services.CreateScope()) { var importService = scope.ServiceProvider.GetRequiredService(); var archiveService = scope.ServiceProvider.GetRequiredService(); - var files = archiveService.GetExportFiles(inputDirectory).ToList(); - - if (files.Count == 0) + if (reimport) { - logger.LogInformation("No JSON files found in input directory."); + logger.LogInformation("Reimporting all data from archived files..."); + var (success, errors) = await importService.ReimportFromArchiveAsync(archiveDirectory, imageDirectory); + logger.LogInformation("Reimport complete. Imported: {Success}, Errors: {Errors}", success, errors); + } + else if (reprocessReactions) + { + logger.LogInformation("Reprocessing reactions from archived files..."); + var added = await importService.ReprocessReactionsAsync(archiveDirectory); + logger.LogInformation("Reprocessing complete. Added {Count} reactions.", added); } else { - logger.LogInformation("Found {Count} JSON files to process.", files.Count); + var files = archiveService.GetExportFiles(inputDirectory).ToList(); - var successCount = 0; - var skipCount = 0; - var errorCount = 0; - - foreach (var file in files) + if (files.Count == 0) { - try - { - var processed = await importService.ProcessFileAsync(file, imageDirectory, archiveDirectory); - if (processed) - { - successCount++; - } - else - { - skipCount++; - } - } - catch (Exception ex) - { - logger.LogError(ex, "Failed to process file: {Path}", file); - errorCount++; - } + logger.LogInformation("No JSON files found in input directory."); } + else + { + logger.LogInformation("Found {Count} JSON files to process.", files.Count); - logger.LogInformation("Processing complete. Processed: {Success}, Skipped: {Skip}, Errors: {Error}", - successCount, skipCount, errorCount); + var successCount = 0; + var skipCount = 0; + var errorCount = 0; + + foreach (var file in files) + { + try + { + var processed = await importService.ProcessFileAsync(file, imageDirectory, archiveDirectory); + if (processed) + { + successCount++; + } + else + { + skipCount++; + } + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to process file: {Path}", file); + errorCount++; + } + } + + logger.LogInformation("Processing complete. Processed: {Success}, Skipped: {Skip}, Errors: {Error}", + successCount, skipCount, errorCount); + } } }