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:
@@ -1,6 +1,8 @@
|
|||||||
using DiscordArchiveManager.Data;
|
using DiscordArchiveManager.Data;
|
||||||
using DiscordArchiveManager.Services;
|
using DiscordArchiveManager.Services;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
@@ -32,11 +34,23 @@ var inputDirectory = config["Paths:InputDirectory"] ?? "/app/input";
|
|||||||
var archiveDirectory = config["Paths:ArchiveDirectory"] ?? "/app/archive";
|
var archiveDirectory = config["Paths:ArchiveDirectory"] ?? "/app/archive";
|
||||||
var imageDirectory = config["Paths:ImageDirectory"] ?? "/app/images";
|
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("Discord Archive Manager starting...");
|
||||||
logger.LogInformation("Input directory: {Path}", inputDirectory);
|
logger.LogInformation("Input directory: {Path}", inputDirectory);
|
||||||
logger.LogInformation("Archive directory: {Path}", archiveDirectory);
|
logger.LogInformation("Archive directory: {Path}", archiveDirectory);
|
||||||
logger.LogInformation("Image directory: {Path}", imageDirectory);
|
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
|
// Ensure directories exist
|
||||||
Directory.CreateDirectory(inputDirectory);
|
Directory.CreateDirectory(inputDirectory);
|
||||||
Directory.CreateDirectory(archiveDirectory);
|
Directory.CreateDirectory(archiveDirectory);
|
||||||
@@ -46,54 +60,84 @@ Directory.CreateDirectory(imageDirectory);
|
|||||||
using (var scope = host.Services.CreateScope())
|
using (var scope = host.Services.CreateScope())
|
||||||
{
|
{
|
||||||
var context = scope.ServiceProvider.GetRequiredService<DiscordArchiveContext>();
|
var context = scope.ServiceProvider.GetRequiredService<DiscordArchiveContext>();
|
||||||
logger.LogInformation("Ensuring database exists and applying migrations...");
|
logger.LogInformation("Ensuring database schema exists...");
|
||||||
await context.Database.EnsureCreatedAsync();
|
|
||||||
|
// 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.");
|
logger.LogInformation("Database ready.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process files
|
// Process files or reprocess reactions
|
||||||
using (var scope = host.Services.CreateScope())
|
using (var scope = host.Services.CreateScope())
|
||||||
{
|
{
|
||||||
var importService = scope.ServiceProvider.GetRequiredService<JsonImportService>();
|
var importService = scope.ServiceProvider.GetRequiredService<JsonImportService>();
|
||||||
var archiveService = scope.ServiceProvider.GetRequiredService<ArchiveService>();
|
var archiveService = scope.ServiceProvider.GetRequiredService<ArchiveService>();
|
||||||
|
|
||||||
var files = archiveService.GetExportFiles(inputDirectory).ToList();
|
if (reimport)
|
||||||
|
|
||||||
if (files.Count == 0)
|
|
||||||
{
|
{
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
logger.LogInformation("Found {Count} JSON files to process.", files.Count);
|
var files = archiveService.GetExportFiles(inputDirectory).ToList();
|
||||||
|
|
||||||
var successCount = 0;
|
if (files.Count == 0)
|
||||||
var skipCount = 0;
|
|
||||||
var errorCount = 0;
|
|
||||||
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
{
|
||||||
try
|
logger.LogInformation("No JSON files found in input directory.");
|
||||||
{
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogInformation("Found {Count} JSON files to process.", files.Count);
|
||||||
|
|
||||||
logger.LogInformation("Processing complete. Processed: {Success}, Skipped: {Skip}, Errors: {Error}",
|
var successCount = 0;
|
||||||
successCount, skipCount, errorCount);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user