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 <noreply@anthropic.com>
This commit is contained in:
2026-02-05 23:20:25 -05:00
parent a281f7f1e7
commit 00a0b3e14f

View File

@@ -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<DiscordArchiveContext>();
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<IRelationalDatabaseCreator>()!;
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<JsonImportService>();
var archiveService = scope.ServiceProvider.GetRequiredService<ArchiveService>();
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);
}
}
}