mirror of
https://github.com/C9Glax/tranga.git
synced 2025-10-17 10:50:45 +02:00
Fix Actions that can have related chapters and manga
This commit is contained in:
@@ -69,7 +69,7 @@ public class ActionsController(ActionsContext context) : Controller
|
||||
[ProducesResponseType(Status500InternalServerError)]
|
||||
public async Task<Results<Ok<IEnumerable<ActionRecord>>, InternalServerError>> GetActionsRelatedToManga(string MangaId)
|
||||
{
|
||||
if(await context.Actions.FromSqlInterpolated($"""SELECT * FROM public."Actions" WHERE "MangaId" = {MangaId}""").ToListAsync() is not { } actions)
|
||||
if(await context.Actions.FromSqlInterpolated($"""SELECT * FROM public."Actions" WHERE "MangaId" = {MangaId}""").ToListAsync(HttpContext.RequestAborted) is not { } actions)
|
||||
return TypedResults.InternalServerError();
|
||||
|
||||
return TypedResults.Ok(actions.Select(a => new ActionRecord(a)));
|
||||
@@ -85,7 +85,7 @@ public class ActionsController(ActionsContext context) : Controller
|
||||
[ProducesResponseType(Status500InternalServerError)]
|
||||
public async Task<Results<Ok<IEnumerable<ActionRecord>>, InternalServerError>> GetActionsRelatedToChapter(string ChapterId)
|
||||
{
|
||||
if(await context.Actions.FromSqlInterpolated($"""SELECT * FROM public."Actions" WHERE "ChapterId" = {ChapterId}""").ToListAsync() is not { } actions)
|
||||
if(await context.Actions.FromSqlInterpolated($"""SELECT * FROM public."Actions" WHERE "ChapterId" = {ChapterId}""").ToListAsync(HttpContext.RequestAborted) is not { } actions)
|
||||
return TypedResults.InternalServerError();
|
||||
|
||||
return TypedResults.Ok(actions.Select(a => new ActionRecord(a)));
|
||||
|
@@ -11,8 +11,8 @@ public sealed record ActionRecord : Identifiable
|
||||
{
|
||||
Action = actionRecord.Action;
|
||||
PerformedAt = actionRecord.PerformedAt;
|
||||
MangaId = actionRecord is ActionWithMangaRecord m ? m.MangaId : null;
|
||||
ChapterId = actionRecord is ActionWithChapterRecord c ? c.ChapterId : null;
|
||||
MangaId = actionRecord is IActionWithMangaRecord m ? m.MangaId : null;
|
||||
ChapterId = actionRecord is IActionWithChapterRecord c ? c.ChapterId : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -28,13 +28,13 @@ public sealed record ActionRecord : Identifiable
|
||||
public DateTime PerformedAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// MangaId if Record is <see cref="ActionWithMangaRecord"/>
|
||||
/// MangaId if Record is <see cref="IActionWithMangaRecord"/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? MangaId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// ChapterId if Record is <see cref="ActionWithMangaRecord"/>
|
||||
/// ChapterId if Record is <see cref="IActionWithMangaRecord"/>
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? ChapterId { get; init; }
|
||||
|
@@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
namespace API.Migrations.Actions
|
||||
{
|
||||
[DbContext(typeof(ActionsContext))]
|
||||
[Migration("20251016170924_Actions")]
|
||||
[Migration("20251016182526_Actions")]
|
||||
partial class Actions
|
||||
{
|
||||
/// <inheritdoc />
|
||||
@@ -53,8 +53,14 @@ namespace API.Migrations.Actions
|
||||
|
||||
b.Property<string>("ChapterId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("ChapterId");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue(1);
|
||||
});
|
||||
@@ -66,8 +72,8 @@ namespace API.Migrations.Actions
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue(2);
|
||||
});
|
||||
@@ -84,8 +90,8 @@ namespace API.Migrations.Actions
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue(3);
|
||||
});
|
||||
@@ -119,8 +125,8 @@ namespace API.Migrations.Actions
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue(5);
|
||||
});
|
||||
@@ -132,8 +138,8 @@ namespace API.Migrations.Actions
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.Property<string>("MetadataFetcher")
|
||||
.IsRequired()
|
@@ -18,8 +18,8 @@ namespace API.Migrations.Actions
|
||||
Key = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
|
||||
Action = table.Column<int>(type: "integer", maxLength: 128, nullable: false),
|
||||
PerformedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ChapterId = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
||||
MangaId = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
||||
ChapterId = table.Column<string>(type: "text", nullable: true),
|
||||
MangaId = table.Column<string>(type: "text", nullable: true),
|
||||
Filename = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||
From = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
||||
To = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
@@ -50,8 +50,14 @@ namespace API.Migrations.Actions
|
||||
|
||||
b.Property<string>("ChapterId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("ChapterId");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue(1);
|
||||
});
|
||||
@@ -63,8 +69,8 @@ namespace API.Migrations.Actions
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue(2);
|
||||
});
|
||||
@@ -81,8 +87,8 @@ namespace API.Migrations.Actions
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue(3);
|
||||
});
|
||||
@@ -116,8 +122,8 @@ namespace API.Migrations.Actions
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue(5);
|
||||
});
|
||||
@@ -129,8 +135,8 @@ namespace API.Migrations.Actions
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnUpdateSometimes()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("MangaId");
|
||||
|
||||
b.Property<string>("MetadataFetcher")
|
||||
.IsRequired()
|
||||
|
@@ -3,7 +3,9 @@ using API.Schema.MangaContext;
|
||||
|
||||
namespace API.Schema.ActionsContext.Actions;
|
||||
|
||||
public sealed class ChapterDownloadedActionRecord(ActionsEnum action, DateTime performedAt, string chapterId) : ActionWithChapterRecord(action, performedAt, chapterId)
|
||||
public sealed class ChapterDownloadedActionRecord(ActionsEnum action, DateTime performedAt, string mangaId, string chapterId) : ActionRecord(action, performedAt), IActionWithChapterRecord, IActionWithMangaRecord
|
||||
{
|
||||
public ChapterDownloadedActionRecord(Chapter chapter) : this(ActionsEnum.ChapterDownloaded, DateTime.UtcNow, chapter.Key) { }
|
||||
public ChapterDownloadedActionRecord(Manga manga, Chapter chapter) : this(ActionsEnum.ChapterDownloaded, DateTime.UtcNow, manga.Key, chapter.Key) { }
|
||||
public string ChapterId { get; init; } = chapterId;
|
||||
public string MangaId { get; init; } = mangaId;
|
||||
}
|
@@ -4,9 +4,9 @@ using API.Schema.MangaContext;
|
||||
namespace API.Schema.ActionsContext.Actions;
|
||||
|
||||
public sealed class ChaptersRetrievedActionRecord(ActionsEnum action, DateTime performedAt, string mangaId)
|
||||
: ActionWithMangaRecord(action, performedAt, mangaId)
|
||||
: ActionRecord(action, performedAt), IActionWithMangaRecord
|
||||
{
|
||||
public ChaptersRetrievedActionRecord(Manga manga) : this(ActionsEnum.ChaptersRetrieved, DateTime.UtcNow, manga.Key) { }
|
||||
|
||||
public const string ChaptersRetrievedAction = "Manga.ChaptersRetrieved";
|
||||
public string MangaId { get; init; } = mangaId;
|
||||
}
|
@@ -5,7 +5,7 @@ using API.Schema.MangaContext;
|
||||
namespace API.Schema.ActionsContext.Actions;
|
||||
|
||||
public sealed class CoverDownloadedActionRecord(ActionsEnum action, DateTime performedAt, string mangaId, string filename)
|
||||
: ActionWithMangaRecord(action, performedAt, mangaId)
|
||||
: ActionRecord(action, performedAt), IActionWithMangaRecord
|
||||
{
|
||||
public CoverDownloadedActionRecord(Manga manga, string filename) : this(ActionsEnum.CoverDownloaded, DateTime.UtcNow, manga.Key, filename) { }
|
||||
|
||||
@@ -14,4 +14,6 @@ public sealed class CoverDownloadedActionRecord(ActionsEnum action, DateTime per
|
||||
/// </summary>
|
||||
[StringLength(1024)]
|
||||
public string Filename { get; init; } = filename;
|
||||
|
||||
public string MangaId { get; init; } = mangaId;
|
||||
}
|
@@ -1,15 +1,12 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using API.Schema.MangaContext;
|
||||
|
||||
namespace API.Schema.ActionsContext.Actions.Generic;
|
||||
|
||||
public abstract class ActionWithChapterRecord(ActionsEnum action, DateTime performedAt, string chapterId) : ActionRecord(action, performedAt)
|
||||
public interface IActionWithChapterRecord
|
||||
{
|
||||
protected ActionWithChapterRecord(ActionsEnum action, DateTime performedAt, Chapter chapter) : this(action, performedAt, chapter.Key) { }
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Schema.MangaContext.Manga"/> for which the cover was downloaded
|
||||
/// </summary>
|
||||
[StringLength(64)]
|
||||
public string ChapterId { get; init; } = chapterId;
|
||||
public string ChapterId { get; init; }
|
||||
}
|
@@ -1,15 +1,12 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using API.Schema.MangaContext;
|
||||
|
||||
namespace API.Schema.ActionsContext.Actions.Generic;
|
||||
|
||||
public abstract class ActionWithMangaRecord(ActionsEnum action, DateTime performedAt, string mangaId) : ActionRecord(action, performedAt)
|
||||
public interface IActionWithMangaRecord
|
||||
{
|
||||
protected ActionWithMangaRecord(ActionsEnum action, DateTime performedAt, Manga manga) : this(action, performedAt, manga.Key) { }
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Schema.MangaContext.Manga"/> for which the cover was downloaded
|
||||
/// </summary>
|
||||
[StringLength(64)]
|
||||
public string MangaId { get; init; } = mangaId;
|
||||
public string MangaId { get; init; }
|
||||
}
|
@@ -4,7 +4,8 @@ using API.Schema.MangaContext;
|
||||
|
||||
namespace API.Schema.ActionsContext.Actions;
|
||||
|
||||
public sealed class LibraryMovedActionRecord(ActionsEnum action, DateTime performedAt, string mangaId, string fileLibraryId) : ActionWithMangaRecord(action, performedAt, mangaId)
|
||||
public sealed class LibraryMovedActionRecord(ActionsEnum action, DateTime performedAt, string mangaId, string fileLibraryId)
|
||||
: ActionRecord(action, performedAt), IActionWithMangaRecord
|
||||
{
|
||||
public LibraryMovedActionRecord(Manga manga, FileLibrary library) : this(ActionsEnum.LibraryMoved, DateTime.UtcNow, manga.Key, library.Key) { }
|
||||
|
||||
@@ -13,4 +14,6 @@ public sealed class LibraryMovedActionRecord(ActionsEnum action, DateTime perfor
|
||||
/// </summary>
|
||||
[StringLength(64)]
|
||||
public string FileLibraryId { get; init; } = fileLibraryId;
|
||||
|
||||
public string MangaId { get; init; } = mangaId;
|
||||
}
|
@@ -6,7 +6,7 @@ using API.Schema.MangaContext.MetadataFetchers;
|
||||
namespace API.Schema.ActionsContext.Actions;
|
||||
|
||||
public sealed class MetadataUpdatedActionRecord(ActionsEnum action, DateTime performedAt, string mangaId, string metadataFetcher)
|
||||
: ActionWithMangaRecord(action, performedAt, mangaId)
|
||||
: ActionRecord(action, performedAt), IActionWithMangaRecord
|
||||
{
|
||||
public MetadataUpdatedActionRecord(Manga manga, MetadataFetcher fetcher) : this(ActionsEnum.MetadataUpdated, DateTime.UtcNow, manga.Key, fetcher.Name) { }
|
||||
|
||||
@@ -15,4 +15,6 @@ public sealed class MetadataUpdatedActionRecord(ActionsEnum action, DateTime per
|
||||
/// </summary>
|
||||
[StringLength(1024)]
|
||||
public string MetadataFetcher { get; init; } = metadataFetcher;
|
||||
|
||||
public string MangaId { get; init; } = mangaId;
|
||||
}
|
@@ -19,5 +19,16 @@ public class ActionsContext(DbContextOptions<ActionsContext> options) : TrangaBa
|
||||
.HasValue<DataMovedActionRecord>(ActionsEnum.DataMoved)
|
||||
.HasValue<LibraryMovedActionRecord>(ActionsEnum.LibraryMoved)
|
||||
.HasValue<StartupActionRecord>(ActionsEnum.Startup);
|
||||
|
||||
modelBuilder.Entity<ChapterDownloadedActionRecord>().Property(a => a.MangaId).HasColumnName("MangaId");
|
||||
modelBuilder.Entity<ChapterDownloadedActionRecord>().Property(a => a.ChapterId).HasColumnName("ChapterId");
|
||||
|
||||
modelBuilder.Entity<CoverDownloadedActionRecord>().Property(a => a.MangaId).HasColumnName("MangaId");
|
||||
|
||||
modelBuilder.Entity<ChaptersRetrievedActionRecord>().Property(a => a.MangaId).HasColumnName("MangaId");
|
||||
|
||||
modelBuilder.Entity<MetadataUpdatedActionRecord>().Property(a => a.MangaId).HasColumnName("MangaId");
|
||||
|
||||
modelBuilder.Entity<LibraryMovedActionRecord>().Property(a => a.MangaId).HasColumnName("MangaId");
|
||||
}
|
||||
}
|
@@ -192,7 +192,7 @@ public class DownloadChapterFromMangaconnectorWorker(MangaConnectorId<Chapter> c
|
||||
|
||||
Log.Debug($"Downloaded chapter {chapter}.");
|
||||
|
||||
ActionsContext.Actions.Add(new ChapterDownloadedActionRecord(chapter));
|
||||
ActionsContext.Actions.Add(new ChapterDownloadedActionRecord(chapter.ParentManga, chapter));
|
||||
if(await ActionsContext.Sync(CancellationToken, GetType(), "Download complete") is { success: false } actionsContextException)
|
||||
Log.Error($"Failed to save database changes: {actionsContextException.exceptionMessage}");
|
||||
|
||||
|
@@ -3277,12 +3277,12 @@
|
||||
},
|
||||
"mangaId": {
|
||||
"type": "string",
|
||||
"description": "MangaId if Record is API.Schema.ActionsContext.Actions.Generic.ActionWithMangaRecord",
|
||||
"description": "MangaId if Record is API.Schema.ActionsContext.Actions.Generic.IActionWithMangaRecord",
|
||||
"nullable": true
|
||||
},
|
||||
"chapterId": {
|
||||
"type": "string",
|
||||
"description": "ChapterId if Record is API.Schema.ActionsContext.Actions.Generic.ActionWithMangaRecord",
|
||||
"description": "ChapterId if Record is API.Schema.ActionsContext.Actions.Generic.IActionWithMangaRecord",
|
||||
"nullable": true
|
||||
},
|
||||
"key": {
|
||||
|
Reference in New Issue
Block a user