diff --git a/OakArchive/OakArchive.csproj b/OakArchive/OakArchive.csproj
index 7c977dc..9f0707a 100644
--- a/OakArchive/OakArchive.csproj
+++ b/OakArchive/OakArchive.csproj
@@ -14,6 +14,7 @@
+
@@ -28,13 +29,7 @@
-
-
-
-
-
-
-
+
diff --git a/OakArchive/Program.cs b/OakArchive/Program.cs
index 0ece349..e76c8b1 100644
--- a/OakArchive/Program.cs
+++ b/OakArchive/Program.cs
@@ -1,21 +1,67 @@
+using Microsoft.EntityFrameworkCore;
+using OakArchive.Database;
+using OakArchive.Services;
+
namespace OakArchive;
public class Program
{
- public static void Main(string[] args)
+ public static async Task Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
- // Add services to the container.
builder.Services.AddControllers();
+ builder.Services.AddDbContext(options =>
+ options.UseNpgsql(builder.Configuration["DefaultConnection"]));
+
+
+ builder.Services.AddMemoryCache(); // Registriert das native IMemoryCache von Microsoft
+ builder.Services.AddSingleton();
+
+ builder.Services.AddHttpClient(client =>
+ {
+ client.BaseAddress = new Uri("https://api.tcgdex.net/v2/");
+ client.DefaultRequestHeaders.Add("Accept", "application/json");
+ });
+
+ builder.Services.AddScoped();
+
var app = builder.Build();
- // Configure the HTTP request pipeline.
+ app.Lifetime.ApplicationStarted.Register(async () =>
+ {
+ // Da ApplicationStarted synchron registriert, machen wir hier einen neuen asynchronen Scope auf
+ using var scope = app.Services.CreateScope();
+ try
+ {
+ var context = scope.ServiceProvider.GetRequiredService();
+
+ Console.WriteLine("[INFO] Prüfe auf ausstehende Datenbank-Migrationen...");
+
+ // Führt alle ausstehenden Migrationen auf der PostgreSQL-Datenbank aus.
+ // Falls die Datenbank noch gar nicht existiert, wird sie hier automatisch erstellt!
+ await context.Database.MigrateAsync();
+
+ var updater = scope.ServiceProvider.GetRequiredService();
+
+ Console.WriteLine("[INFO] === Starte TCGdex Test-Sync im Hintergrund ===");
+
+ var result = await updater.SyncBaseDataFromTcgDex();
+
+ Console.WriteLine($"[INFO] === Test-Sync beendet! Neue Daten geladen: {result} ===");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[FEHLER] !!! Fehler beim Test-Sync: {ex.Message} !!!");
+ Console.WriteLine(ex.StackTrace);
+ }
+ });
app.UseAuthorization();
+ app.UseStaticFiles();
app.MapControllers();
diff --git a/OakArchive/Util/PerceptualHashHelper.cs b/OakArchive/Util/PerceptualHashHelper.cs
new file mode 100644
index 0000000..604ce8c
--- /dev/null
+++ b/OakArchive/Util/PerceptualHashHelper.cs
@@ -0,0 +1,47 @@
+using CoenM.ImageHash.HashAlgorithms;
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
+
+namespace OakArchive.Util;
+
+public class PerceptualHashHelper
+{
+ private static readonly PerceptualHash _perceptualHash = new();
+
+ private const int TargetWidth = 600;
+ private const int TargetHeight = 840;
+ private const int Margin = 15;
+
+ public static ulong GenerateHash(byte[] rawImage)
+ {
+ using var image = Image.Load(rawImage);
+
+ image.Mutate(x => x.Resize(TargetWidth, TargetHeight));
+
+ return _perceptualHash.Hash(image);
+ }
+
+ public static ulong GenerateHashWithMargin(byte[] rawImage)
+ {
+ using var image = Image.Load(rawImage);
+
+ const int maxContentWidth = TargetWidth - (2 * Margin);
+ const int maxContentHeight = TargetHeight - (2 * Margin);
+
+ image.Mutate(x => x.Resize(new ResizeOptions
+ {
+ Size = new Size(maxContentWidth, maxContentHeight),
+ Mode = ResizeMode.Max
+ }));
+
+ using var canvas = new Image(TargetWidth, TargetHeight, Color.Black);
+
+ var posX = (TargetWidth - image.Width) / 2;
+ var posY = (TargetHeight - image.Height) / 2;
+
+ canvas.Mutate(x => x.DrawImage(image, new Point(posX, posY), 1f));
+
+ return _perceptualHash.Hash(canvas);
+ }
+}
\ No newline at end of file
diff --git a/compose.yaml b/compose.yaml
index d4c7bd8..7cdb608 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -4,13 +4,12 @@
build:
context: .
dockerfile: OakArchive/Dockerfile
- # Falls die DB in einer anderen Datei ist, nimm depends_on raus,
- # da Compose nur Services innerhalb derselben Datei überwachen kann.
networks:
- postgres-network
environment:
- # WICHTIG: Host muss der 'container_name' oder 'service_name' der DB sein
- - CONNECTION_STRING=Host=OmniDB;Database=oak_db;Username=admin;Password=${DB_PASSWORD}
+ - DefaultConnection=Host=OmniDB;Database=oak_db;Username=admin;Password=${DB_PASSWORD}
+ volumes:
+ - C:\Users\larsh\Documents\docker\oakarchive\Cards:/app/Cards
networks:
postgres-network: