diff --git a/API/Controllers/DTOs/Chapter.cs b/API/Controllers/DTOs/Chapter.cs
index f9eae85..2d20a8a 100644
--- a/API/Controllers/DTOs/Chapter.cs
+++ b/API/Controllers/DTOs/Chapter.cs
@@ -6,7 +6,7 @@ namespace API.Controllers.DTOs;
///
/// DTO
///
-public sealed record Chapter(string Key, string MangaId, int? Volume, string ChapterNumber, string? Title, IEnumerable MangaConnectorIds, bool Downloaded, string FileName) : Identifiable(Key)
+public sealed record Chapter(string Key, string MangaId, int? Volume, string ChapterNumber, string? Title, IEnumerable MangaConnectorIds, bool Downloaded, string? FileName) : Identifiable(Key)
{
///
/// Identifier of the Manga this Chapter belongs to
@@ -53,7 +53,6 @@ public sealed record Chapter(string Key, string MangaId, int? Volume, string Cha
///
/// Filename of the archive
///
- [Required]
[Description("Filename of the archive")]
- public string FileName { get; init; } = FileName;
+ public string? FileName { get; init; } = FileName;
}
\ No newline at end of file
diff --git a/API/Migrations/Manga/20251008220207_Chapter_Filename_is_set_own_download.Designer.cs b/API/Migrations/Manga/20251008220207_Chapter_Filename_is_set_own_download.Designer.cs
new file mode 100644
index 0000000..9631089
--- /dev/null
+++ b/API/Migrations/Manga/20251008220207_Chapter_Filename_is_set_own_download.Designer.cs
@@ -0,0 +1,541 @@
+//
+using API.Schema.MangaContext;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace API.Migrations.Manga
+{
+ [DbContext(typeof(MangaContext))]
+ [Migration("20251008220207_Chapter_Filename_is_set_own_download")]
+ partial class Chapter_Filename_is_set_own_download
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "9.0.9")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("API.MangaConnectors.MangaConnector", b =>
+ {
+ b.Property("Name")
+ .HasMaxLength(32)
+ .HasColumnType("character varying(32)");
+
+ b.PrimitiveCollection("BaseUris")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("text[]");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("IconUrl")
+ .IsRequired()
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)");
+
+ b.PrimitiveCollection("SupportedLanguages")
+ .IsRequired()
+ .HasMaxLength(8)
+ .HasColumnType("text[]");
+
+ b.HasKey("Name");
+
+ b.ToTable("MangaConnector");
+
+ b.HasDiscriminator("Name").HasValue("MangaConnector");
+
+ b.UseTphMappingStrategy();
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.Author", b =>
+ {
+ b.Property("Key")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("AuthorName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)");
+
+ b.HasKey("Key");
+
+ b.ToTable("Authors");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.Chapter", b =>
+ {
+ b.Property("Key")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("ChapterNumber")
+ .IsRequired()
+ .HasMaxLength(10)
+ .HasColumnType("character varying(10)");
+
+ b.Property("Downloaded")
+ .HasColumnType("boolean");
+
+ b.Property("FileName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("ParentMangaId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("Title")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("VolumeNumber")
+ .HasColumnType("integer");
+
+ b.HasKey("Key");
+
+ b.HasIndex("ParentMangaId");
+
+ b.ToTable("Chapters");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.FileLibrary", b =>
+ {
+ b.Property("Key")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("BasePath")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("LibraryName")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
+
+ b.HasKey("Key");
+
+ b.ToTable("FileLibraries");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.Manga", b =>
+ {
+ b.Property("Key")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("CoverFileNameInCache")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
+
+ b.Property("CoverUrl")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DirectoryName")
+ .IsRequired()
+ .HasMaxLength(1024)
+ .HasColumnType("character varying(1024)");
+
+ b.Property("IgnoreChaptersBefore")
+ .HasColumnType("real");
+
+ b.Property("LibraryId")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
+
+ b.Property("OriginalLanguage")
+ .HasMaxLength(8)
+ .HasColumnType("character varying(8)");
+
+ b.Property("ReleaseStatus")
+ .HasColumnType("smallint");
+
+ b.Property("Year")
+ .HasColumnType("bigint");
+
+ b.HasKey("Key");
+
+ b.HasIndex("LibraryId");
+
+ b.ToTable("Mangas");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId", b =>
+ {
+ b.Property("Key")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("IdOnConnectorSite")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("MangaConnectorName")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("character varying(32)");
+
+ b.Property("ObjId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("UseForDownload")
+ .HasColumnType("boolean");
+
+ b.Property("WebsiteUrl")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
+
+ b.HasKey("Key");
+
+ b.HasIndex("ObjId");
+
+ b.ToTable("MangaConnectorToChapter");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId", b =>
+ {
+ b.Property("Key")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("IdOnConnectorSite")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("MangaConnectorName")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("character varying(32)");
+
+ b.Property("ObjId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("UseForDownload")
+ .HasColumnType("boolean");
+
+ b.Property("WebsiteUrl")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
+
+ b.HasKey("Key");
+
+ b.HasIndex("ObjId");
+
+ b.ToTable("MangaConnectorToManga");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.MangaTag", b =>
+ {
+ b.Property("Tag")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.HasKey("Tag");
+
+ b.ToTable("Tags");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.MetadataFetchers.MetadataEntry", b =>
+ {
+ b.Property("MetadataFetcherName")
+ .HasColumnType("text");
+
+ b.Property("Identifier")
+ .HasColumnType("text");
+
+ b.Property("MangaId")
+ .IsRequired()
+ .HasColumnType("character varying(64)");
+
+ b.HasKey("MetadataFetcherName", "Identifier");
+
+ b.HasIndex("MangaId");
+
+ b.ToTable("MetadataEntries");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.MetadataFetchers.MetadataFetcher", b =>
+ {
+ b.Property("Name")
+ .HasColumnType("text");
+
+ b.Property("MetadataEntry")
+ .IsRequired()
+ .HasMaxLength(21)
+ .HasColumnType("character varying(21)");
+
+ b.HasKey("Name");
+
+ b.ToTable("MetadataFetcher");
+
+ b.HasDiscriminator("MetadataEntry").HasValue("MetadataFetcher");
+
+ b.UseTphMappingStrategy();
+ });
+
+ modelBuilder.Entity("AuthorToManga", b =>
+ {
+ b.Property("AuthorIds")
+ .HasColumnType("character varying(64)");
+
+ b.Property("MangaIds")
+ .HasColumnType("character varying(64)");
+
+ b.HasKey("AuthorIds", "MangaIds");
+
+ b.HasIndex("MangaIds");
+
+ b.ToTable("AuthorToManga");
+ });
+
+ modelBuilder.Entity("MangaTagToManga", b =>
+ {
+ b.Property("MangaTagIds")
+ .HasColumnType("character varying(64)");
+
+ b.Property("MangaIds")
+ .HasColumnType("character varying(64)");
+
+ b.HasKey("MangaTagIds", "MangaIds");
+
+ b.HasIndex("MangaIds");
+
+ b.ToTable("MangaTagToManga");
+ });
+
+ modelBuilder.Entity("API.MangaConnectors.Global", b =>
+ {
+ b.HasBaseType("API.MangaConnectors.MangaConnector");
+
+ b.HasDiscriminator().HasValue("Global");
+ });
+
+ modelBuilder.Entity("API.MangaConnectors.MangaDex", b =>
+ {
+ b.HasBaseType("API.MangaConnectors.MangaConnector");
+
+ b.HasDiscriminator().HasValue("MangaDex");
+ });
+
+ modelBuilder.Entity("API.MangaConnectors.MangaPark", b =>
+ {
+ b.HasBaseType("API.MangaConnectors.MangaConnector");
+
+ b.HasDiscriminator().HasValue("MangaPark");
+ });
+
+ modelBuilder.Entity("API.MangaConnectors.Mangaworld", b =>
+ {
+ b.HasBaseType("API.MangaConnectors.MangaConnector");
+
+ b.HasDiscriminator().HasValue("Mangaworld");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.MetadataFetchers.MyAnimeList", b =>
+ {
+ b.HasBaseType("API.Schema.MangaContext.MetadataFetchers.MetadataFetcher");
+
+ b.HasDiscriminator().HasValue("MyAnimeList");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.Chapter", b =>
+ {
+ b.HasOne("API.Schema.MangaContext.Manga", "ParentManga")
+ .WithMany("Chapters")
+ .HasForeignKey("ParentMangaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("ParentManga");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.Manga", b =>
+ {
+ b.HasOne("API.Schema.MangaContext.FileLibrary", "Library")
+ .WithMany()
+ .HasForeignKey("LibraryId")
+ .OnDelete(DeleteBehavior.SetNull);
+
+ b.OwnsMany("API.Schema.MangaContext.AltTitle", "AltTitles", b1 =>
+ {
+ b1.Property("Key")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b1.Property("Language")
+ .IsRequired()
+ .HasMaxLength(8)
+ .HasColumnType("character varying(8)");
+
+ b1.Property("MangaKey")
+ .IsRequired()
+ .HasColumnType("character varying(64)");
+
+ b1.Property("Title")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b1.HasKey("Key");
+
+ b1.HasIndex("MangaKey");
+
+ b1.ToTable("AltTitle");
+
+ b1.WithOwner()
+ .HasForeignKey("MangaKey");
+ });
+
+ b.OwnsMany("API.Schema.MangaContext.Link", "Links", b1 =>
+ {
+ b1.Property("Key")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b1.Property("LinkProvider")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b1.Property("LinkUrl")
+ .IsRequired()
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)");
+
+ b1.Property("MangaKey")
+ .IsRequired()
+ .HasColumnType("character varying(64)");
+
+ b1.HasKey("Key");
+
+ b1.HasIndex("MangaKey");
+
+ b1.ToTable("Link");
+
+ b1.WithOwner()
+ .HasForeignKey("MangaKey");
+ });
+
+ b.Navigation("AltTitles");
+
+ b.Navigation("Library");
+
+ b.Navigation("Links");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId", b =>
+ {
+ b.HasOne("API.Schema.MangaContext.Chapter", "Obj")
+ .WithMany("MangaConnectorIds")
+ .HasForeignKey("ObjId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Obj");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId", b =>
+ {
+ b.HasOne("API.Schema.MangaContext.Manga", "Obj")
+ .WithMany("MangaConnectorIds")
+ .HasForeignKey("ObjId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Obj");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.MetadataFetchers.MetadataEntry", b =>
+ {
+ b.HasOne("API.Schema.MangaContext.Manga", "Manga")
+ .WithMany()
+ .HasForeignKey("MangaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("API.Schema.MangaContext.MetadataFetchers.MetadataFetcher", "MetadataFetcher")
+ .WithMany()
+ .HasForeignKey("MetadataFetcherName")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Manga");
+
+ b.Navigation("MetadataFetcher");
+ });
+
+ modelBuilder.Entity("AuthorToManga", b =>
+ {
+ b.HasOne("API.Schema.MangaContext.Author", null)
+ .WithMany()
+ .HasForeignKey("AuthorIds")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("API.Schema.MangaContext.Manga", null)
+ .WithMany()
+ .HasForeignKey("MangaIds")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("MangaTagToManga", b =>
+ {
+ b.HasOne("API.Schema.MangaContext.Manga", null)
+ .WithMany()
+ .HasForeignKey("MangaIds")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("API.Schema.MangaContext.MangaTag", null)
+ .WithMany()
+ .HasForeignKey("MangaTagIds")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.Chapter", b =>
+ {
+ b.Navigation("MangaConnectorIds");
+ });
+
+ modelBuilder.Entity("API.Schema.MangaContext.Manga", b =>
+ {
+ b.Navigation("Chapters");
+
+ b.Navigation("MangaConnectorIds");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/API/Migrations/Manga/20251008220207_Chapter_Filename_is_set_own_download.cs b/API/Migrations/Manga/20251008220207_Chapter_Filename_is_set_own_download.cs
new file mode 100644
index 0000000..6d6aa06
--- /dev/null
+++ b/API/Migrations/Manga/20251008220207_Chapter_Filename_is_set_own_download.cs
@@ -0,0 +1,40 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace API.Migrations.Manga
+{
+ ///
+ public partial class Chapter_Filename_is_set_own_download : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "FileName",
+ table: "Chapters",
+ type: "character varying(256)",
+ maxLength: 256,
+ nullable: true,
+ oldClrType: typeof(string),
+ oldType: "character varying(256)",
+ oldMaxLength: 256);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "FileName",
+ table: "Chapters",
+ type: "character varying(256)",
+ maxLength: 256,
+ nullable: false,
+ defaultValue: "",
+ oldClrType: typeof(string),
+ oldType: "character varying(256)",
+ oldMaxLength: 256,
+ oldNullable: true);
+ }
+ }
+}
diff --git a/API/Migrations/Manga/MangaContextModelSnapshot.cs b/API/Migrations/Manga/MangaContextModelSnapshot.cs
index aded9d6..ec904a7 100644
--- a/API/Migrations/Manga/MangaContextModelSnapshot.cs
+++ b/API/Migrations/Manga/MangaContextModelSnapshot.cs
@@ -16,7 +16,7 @@ namespace API.Migrations.Manga
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "9.0.8")
+ .HasAnnotation("ProductVersion", "9.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
@@ -85,7 +85,6 @@ namespace API.Migrations.Manga
.HasColumnType("boolean");
b.Property("FileName")
- .IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)");
@@ -331,13 +330,6 @@ namespace API.Migrations.Manga
b.ToTable("MangaTagToManga");
});
- modelBuilder.Entity("API.MangaConnectors.ComickIo", b =>
- {
- b.HasBaseType("API.MangaConnectors.MangaConnector");
-
- b.HasDiscriminator().HasValue("ComickIo");
- });
-
modelBuilder.Entity("API.MangaConnectors.Global", b =>
{
b.HasBaseType("API.MangaConnectors.MangaConnector");
@@ -352,6 +344,20 @@ namespace API.Migrations.Manga
b.HasDiscriminator().HasValue("MangaDex");
});
+ modelBuilder.Entity("API.MangaConnectors.MangaPark", b =>
+ {
+ b.HasBaseType("API.MangaConnectors.MangaConnector");
+
+ b.HasDiscriminator().HasValue("MangaPark");
+ });
+
+ modelBuilder.Entity("API.MangaConnectors.Mangaworld", b =>
+ {
+ b.HasBaseType("API.MangaConnectors.MangaConnector");
+
+ b.HasDiscriminator().HasValue("Mangaworld");
+ });
+
modelBuilder.Entity("API.Schema.MangaContext.MetadataFetchers.MyAnimeList", b =>
{
b.HasBaseType("API.Schema.MangaContext.MetadataFetchers.MetadataFetcher");
diff --git a/API/Schema/MangaContext/Chapter.cs b/API/Schema/MangaContext/Chapter.cs
index 0c0c80c..6be5d88 100644
--- a/API/Schema/MangaContext/Chapter.cs
+++ b/API/Schema/MangaContext/Chapter.cs
@@ -22,7 +22,7 @@ public class Chapter : Identifiable, IComparable
[StringLength(256)] public string? Title { get; private set; }
- [StringLength(256)] public string FileName { get; private set; }
+ [StringLength(256)] public string? FileName { get; private set; }
public bool Downloaded { get; internal set; }
@@ -43,7 +43,6 @@ public class Chapter : Identifiable, IComparable
this.MangaConnectorIds = [];
this.VolumeNumber = volumeNumber;
this.Title = title;
- this.FileName = GetArchiveFilePath().CleanNameForWindows();
this.Downloaded = false;
this.MangaConnectorIds = [];
}
@@ -51,7 +50,7 @@ public class Chapter : Identifiable, IComparable
///
/// EF ONLY!!!
///
- internal Chapter(string key, int? volumeNumber, string chapterNumber, string? title, string fileName, bool downloaded)
+ internal Chapter(string key, int? volumeNumber, string chapterNumber, string? title, string? fileName, bool downloaded)
: base(key)
{
this.VolumeNumber = volumeNumber;
@@ -91,6 +90,8 @@ public class Chapter : Identifiable, IComparable
if (chapter.ParentManga.Library is null)
return false;
+ if (chapter.FileName is null)
+ return false;
this.Downloaded = File.Exists(chapter.FullArchiveFilePath);
await context.Sync(token??CancellationToken.None, GetType(), $"CheckDownloaded {this} {this.Downloaded}");
@@ -169,7 +170,7 @@ public class Chapter : Identifiable, IComparable
{
try
{
- return Path.Join(ParentManga.FullDirectoryPath, FileName);
+ return Path.Join(ParentManga.FullDirectoryPath, this.FileName is null ? GetArchiveFilePath() : FileName);
}
catch (Exception)
{
diff --git a/API/Workers/MoveMangaLibraryWorker.cs b/API/Workers/MoveMangaLibraryWorker.cs
index 815ab94..bab52d0 100644
--- a/API/Workers/MoveMangaLibraryWorker.cs
+++ b/API/Workers/MoveMangaLibraryWorker.cs
@@ -17,20 +17,12 @@ public class MoveMangaLibraryWorker(Manga manga, FileLibrary toLibrary, IEnumera
// Get Manga (with and Library)
if (await DbContext.Mangas
.Include(m => m.Library)
+ .Include(m => m.Chapters)
.FirstOrDefaultAsync(m => m.Key == MangaId, CancellationToken) is not { } manga)
{
Log.Error("Could not find Manga.");
return [];
}
-
- if (await DbContext.Chapters
- .Include(ch => ch.ParentManga).ThenInclude(m => m.Library)
- .Where(ch => ch.ParentMangaId == MangaId)
- .ToListAsync(CancellationToken) is not { } chapters)
- {
- Log.Error("Could not find chapters.");
- return [];
- }
// Get new Library
if (await DbContext.FileLibraries.FirstOrDefaultAsync(l => l.Key == LibraryId, CancellationToken) is not { } toLibrary)
@@ -40,7 +32,7 @@ public class MoveMangaLibraryWorker(Manga manga, FileLibrary toLibrary, IEnumera
}
// Save old Path (to later move chapters)
- Dictionary oldPath = manga.Chapters.ToDictionary(c => c.Key, c => c.FullArchiveFilePath).Where(kv => kv.Value is not null).ToDictionary(x => x.Key, x => x.Value)!;
+ Dictionary oldPath = manga.Chapters.Where(c => c.FileName != null).ToDictionary(c => c.Key, c => c.FullArchiveFilePath)!;
// Set new Path
manga.Library = toLibrary;
@@ -48,7 +40,7 @@ public class MoveMangaLibraryWorker(Manga manga, FileLibrary toLibrary, IEnumera
return [];
// Create Jobs to move chapters from old to new Path
- return manga.Chapters.Select(c => new MoveFileOrFolderWorker(c.FullArchiveFilePath, oldPath[c.Key])).ToArray();
+ return oldPath.Select(kv => new MoveFileOrFolderWorker(manga.Chapters.First(ch => ch.Key == kv.Key).FullArchiveFilePath!, kv.Value)).ToArray();
}
public override string ToString() => $"{base.ToString()} {MangaId} {LibraryId}";
diff --git a/API/openapi/API_v2.json b/API/openapi/API_v2.json
index d725b20..866ca40 100644
--- a/API/openapi/API_v2.json
+++ b/API/openapi/API_v2.json
@@ -3406,7 +3406,6 @@
"required": [
"chapterNumber",
"downloaded",
- "fileName",
"key",
"mangaConnectorIds",
"mangaId",
@@ -3447,9 +3446,9 @@
"description": "Ids of the Manga on MangaConnectors"
},
"fileName": {
- "minLength": 1,
"type": "string",
- "description": "Filename of the archive"
+ "description": "Filename of the archive",
+ "nullable": true
},
"key": {
"maxLength": 64,