mirror of
https://github.com/C9Glax/tranga.git
synced 2025-09-10 11:58:19 +02:00
Fix merging of Manga
Fix ComickIo empty lists
This commit is contained in:
@@ -41,15 +41,7 @@ public class MangaController(MangaContext context) : Controller
|
||||
[ProducesResponseType<Manga[]>(Status200OK, "application/json")]
|
||||
public IActionResult GetManga([FromBody]string[] MangaIds)
|
||||
{
|
||||
Manga[] ret = context.Mangas.Where(m => MangaIds.Contains(m.Key))
|
||||
.Include(m => m.Library)
|
||||
.Include(m => m.Authors)
|
||||
.Include(m => m.MangaTags)
|
||||
.Include(m => m.Links)
|
||||
.Include(m => m.AltTitles)
|
||||
.Include(m => m.Chapters)
|
||||
.Include(m => m.MangaConnectorIds)
|
||||
.ToArray();
|
||||
Manga[] ret = context.MangaIncludeAll().Where(m => MangaIds.Contains(m.Key)).ToArray();
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
@@ -64,11 +56,8 @@ public class MangaController(MangaContext context) : Controller
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetManga(string MangaId)
|
||||
{
|
||||
if (context.Mangas.Find(MangaId) is not { } manga)
|
||||
if (context.MangaIncludeAll().FirstOrDefault(m => m.Key == MangaId) is not { } manga)
|
||||
return NotFound(nameof(MangaId));
|
||||
foreach (CollectionEntry collectionEntry in context.Entry(manga).Collections)
|
||||
collectionEntry.Load();
|
||||
context.Entry(manga).Navigation(nameof(Manga.Library)).Load();
|
||||
return Ok(manga);
|
||||
}
|
||||
|
||||
|
@@ -177,19 +177,19 @@ public class ComickIo : MangaConnector
|
||||
byte whatever = 0;
|
||||
List<AltTitle> altTitles = altTitlesArray?
|
||||
.Select(token => new AltTitle(token.Value<string>("lang")??whatever++.ToString(), token.Value<string>("title")!))
|
||||
.ToList()!;
|
||||
.ToList()??[];
|
||||
|
||||
JArray? authorsArray = json["authors"] as JArray;
|
||||
JArray? artistsArray = json["artists"] as JArray;
|
||||
List<Author> authors = authorsArray?.Concat(artistsArray!)
|
||||
.Select(token => new Author(token.Value<string>("name")!))
|
||||
.DistinctBy(a => a.Key)
|
||||
.ToList()!;
|
||||
.ToList()??[];
|
||||
|
||||
JArray? genreArray = json["comic"]?["md_comic_md_genres"] as JArray;
|
||||
List<MangaTag> tags = genreArray?
|
||||
.Select(token => new MangaTag(token["md_genres"]?.Value<string>("name")!))
|
||||
.ToList()!;
|
||||
.ToList()??[];
|
||||
|
||||
JArray? linksArray = json["comic"]?["links"] as JArray;
|
||||
List<Link> links = linksArray?
|
||||
@@ -221,7 +221,7 @@ public class ComickIo : MangaConnector
|
||||
_ => kv.Key
|
||||
};
|
||||
return new Link(key, fullUrl);
|
||||
}).ToList()!;
|
||||
}).ToList()??[];
|
||||
|
||||
if(hid is null)
|
||||
throw new Exception("hid is null");
|
||||
@@ -232,7 +232,9 @@ public class ComickIo : MangaConnector
|
||||
|
||||
Manga manga = new (name, description??"", coverUrl, status, authors, tags, links, altTitles,
|
||||
year: year, originalLanguage: originalLanguage);
|
||||
return (manga, new MangaConnectorId<Manga>(manga, this, hid, url));
|
||||
MangaConnectorId<Manga> mcId = new (manga, this, hid, url);
|
||||
manga.MangaConnectorIds.Add(mcId);
|
||||
return (manga, mcId);
|
||||
}
|
||||
|
||||
private List<(Chapter, MangaConnectorId<Chapter>)> ParseChapters(MangaConnectorId<Manga> mcIdManga, JArray chaptersArray)
|
||||
@@ -251,8 +253,9 @@ public class ComickIo : MangaConnector
|
||||
continue;
|
||||
|
||||
Chapter ch = new (mcIdManga.Obj, chapterNum, volumeNum, title);
|
||||
|
||||
chapters.Add((ch, new (ch, this, hid, url)));
|
||||
MangaConnectorId<Chapter> mcId = new(ch, this, hid, url);
|
||||
ch.MangaConnectorIds.Add(mcId);
|
||||
chapters.Add((ch, mcId));
|
||||
}
|
||||
return chapters;
|
||||
}
|
||||
|
@@ -313,9 +313,11 @@ public class MangaDex : MangaConnector
|
||||
string websiteUrl = $"https://mangadex.org/title/{id}";
|
||||
string coverUrl = $"https://uploads.mangadex.org/covers/{id}/{coverFileName}";
|
||||
|
||||
Manga manga = new Manga(name, description, coverUrl, releaseStatus, authors, tags, links,altTitles,
|
||||
Manga manga = new (name, description, coverUrl, releaseStatus, authors, tags, links,altTitles,
|
||||
null, 0f, year, originalLanguage);
|
||||
return (manga, new MangaConnectorId<Manga>(manga, this, id, websiteUrl));
|
||||
MangaConnectorId<Manga> mcId = new (manga, this, id, websiteUrl);
|
||||
manga.MangaConnectorIds.Add(mcId);
|
||||
return (manga, mcId);
|
||||
}
|
||||
|
||||
private (Chapter chapter, MangaConnectorId<Chapter> id) ParseChapterFromJToken(MangaConnectorId<Manga> mcIdManga, JToken jToken)
|
||||
@@ -334,6 +336,8 @@ public class MangaDex : MangaConnector
|
||||
|
||||
string websiteUrl = $"https://mangadex.org/chapter/{id}";
|
||||
Chapter chapter = new (mcIdManga.Obj, chapterStr, volumeNumber, title);
|
||||
return (chapter, new MangaConnectorId<Chapter>(chapter, this, id, websiteUrl));
|
||||
MangaConnectorId<Chapter> mcId = new(chapter, this, id, websiteUrl);
|
||||
chapter.MangaConnectorIds.Add(mcId);
|
||||
return (chapter, mcId);
|
||||
}
|
||||
}
|
@@ -39,6 +39,7 @@ public class Chapter : Identifiable, IComparable<Chapter>
|
||||
this.Title = title;
|
||||
this.FileName = GetArchiveFilePath();
|
||||
this.Downloaded = false;
|
||||
this.MangaConnectorIds = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -61,6 +61,7 @@ public class Manga : Identifiable
|
||||
this.Year = year;
|
||||
this.OriginalLanguage = originalLanguage;
|
||||
this.Chapters = [];
|
||||
this.MangaConnectorIds = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -8,7 +8,7 @@ namespace API.Schema.MangaContext;
|
||||
[PrimaryKey("Key")]
|
||||
public class MangaConnectorId<T> : Identifiable where T : Identifiable
|
||||
{
|
||||
[StringLength(64)] [Required] public string ObjId { get; private set; }
|
||||
[StringLength(64)] [Required] public string ObjId { get; internal set; }
|
||||
[JsonIgnore] public T Obj = null!;
|
||||
|
||||
[StringLength(32)] [Required] public string MangaConnectorName { get; private set; }
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using API.MangaConnectors;
|
||||
using API.Schema.MangaContext.MetadataFetchers;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Query;
|
||||
|
||||
namespace API.Schema.MangaContext;
|
||||
|
||||
@@ -102,4 +103,23 @@ public class MangaContext(DbContextOptions<MangaContext> options) : TrangaBaseCo
|
||||
.WithMany()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
|
||||
public Manga? FindMangaLike(Manga other)
|
||||
{
|
||||
if (MangaIncludeAll().FirstOrDefault(m => m.Key == other.Key) is { } f)
|
||||
return f;
|
||||
|
||||
return MangaIncludeAll()
|
||||
.FirstOrDefault(m => m.Links.Any(l => l.Key == other.Key) ||
|
||||
m.AltTitles.Any(t => other.AltTitles.Select(ot => ot.Title)
|
||||
.Any(s => s.Equals(t.Title))));
|
||||
}
|
||||
|
||||
public IIncludableQueryable<Manga, ICollection<MangaConnectorId<Manga>>> MangaIncludeAll() => Mangas.Include(m => m.Library)
|
||||
.Include(m => m.Authors)
|
||||
.Include(m => m.MangaTags)
|
||||
.Include(m => m.Links)
|
||||
.Include(m => m.AltTitles)
|
||||
.Include(m => m.Chapters)
|
||||
.Include(m => m.MangaConnectorIds);
|
||||
}
|
@@ -9,7 +9,7 @@ using API.Workers;
|
||||
using API.Workers.MaintenanceWorkers;
|
||||
using log4net;
|
||||
using log4net.Config;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace API;
|
||||
|
||||
@@ -162,30 +162,41 @@ public static class Tranga
|
||||
|
||||
internal static bool AddMangaToContext(Manga addManga, MangaConnectorId<Manga> addMcId, MangaContext context, [NotNullWhen(true)]out Manga? manga)
|
||||
{
|
||||
manga = context.Mangas.Find(addManga.Key) ?? addManga;
|
||||
MangaConnectorId<Manga> mcId = context.MangaConnectorToManga.Find(addMcId.Key) ?? addMcId;
|
||||
mcId.Obj = manga;
|
||||
|
||||
foreach (CollectionEntry collectionEntry in context.Entry(manga).Collections)
|
||||
collectionEntry.Load();
|
||||
context.Entry(manga).Navigation(nameof(Manga.Library)).Load();
|
||||
|
||||
IEnumerable<MangaTag> mergedTags = manga.MangaTags.Select(mt =>
|
||||
context.ChangeTracker.Clear();
|
||||
manga = context.FindMangaLike(addManga);
|
||||
if (manga is not null)
|
||||
{
|
||||
MangaTag? inDb = context.Tags.Find(mt.Tag);
|
||||
return inDb ?? mt;
|
||||
});
|
||||
manga.MangaTags = mergedTags.ToList();
|
||||
|
||||
IEnumerable<Author> mergedAuthors = manga.Authors.Select(ma =>
|
||||
foreach (MangaConnectorId<Manga> mcId in addManga.MangaConnectorIds)
|
||||
{
|
||||
mcId.Obj = manga;
|
||||
mcId.ObjId = manga.Key;
|
||||
}
|
||||
manga.MangaTags = manga.MangaTags.UnionBy(addManga.MangaTags, tag => tag.Tag).ToList();
|
||||
manga.Authors = manga.Authors.UnionBy(addManga.Authors, author => author.Key).ToList();
|
||||
manga.Links = manga.Links.UnionBy(addManga.Links, link => link.Key).ToList();
|
||||
manga.AltTitles = manga.AltTitles.UnionBy(addManga.AltTitles, altTitle => altTitle.Key).ToList();
|
||||
manga.Chapters = manga.Chapters.UnionBy(addManga.Chapters, chapter => chapter.Key).ToList();
|
||||
manga.MangaConnectorIds = manga.MangaConnectorIds.UnionBy(addManga.MangaConnectorIds, id => id.MangaConnectorName).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
Author? inDb = context.Authors.Find(ma.Key);
|
||||
return inDb ?? ma;
|
||||
});
|
||||
manga.Authors = mergedAuthors.ToList();
|
||||
manga = addManga;
|
||||
IEnumerable<MangaTag> mergedTags = manga.MangaTags.Select(mt =>
|
||||
{
|
||||
MangaTag? inDb = context.Tags.Find(mt.Tag);
|
||||
return inDb ?? mt;
|
||||
});
|
||||
manga.MangaTags = mergedTags.ToList();
|
||||
|
||||
if(context.MangaConnectorToManga.Find(addMcId.Key) is null)
|
||||
context.MangaConnectorToManga.Add(mcId);
|
||||
IEnumerable<Author> mergedAuthors = manga.Authors.Select(ma =>
|
||||
{
|
||||
Author? inDb = context.Authors.Find(ma.Key);
|
||||
return inDb ?? ma;
|
||||
});
|
||||
manga.Authors = mergedAuthors.ToList();
|
||||
|
||||
context.Mangas.Add(manga);
|
||||
}
|
||||
|
||||
if (context.Sync() is { success: false })
|
||||
return false;
|
||||
@@ -201,16 +212,19 @@ public static class Tranga
|
||||
|
||||
internal static bool AddChapterToContext(Chapter addChapter, MangaConnectorId<Chapter> addChId, MangaContext context, [NotNullWhen(true)] out Chapter? chapter)
|
||||
{
|
||||
chapter = context.Chapters.Find(addChapter.Key) ?? addChapter;
|
||||
MangaConnectorId<Chapter> chId = context.MangaConnectorToChapter.Find(addChId.Key) ?? addChId;
|
||||
chId.Obj = chapter;
|
||||
|
||||
foreach (CollectionEntry collectionEntry in context.Entry(chapter).Collections)
|
||||
collectionEntry.Load();
|
||||
context.Entry(chapter).Navigation(nameof(Chapter.ParentManga)).Load();
|
||||
|
||||
if(context.MangaConnectorToChapter.Find(chId.Key) is null)
|
||||
context.MangaConnectorToChapter.Add(chId);
|
||||
chapter = context.Chapters.Where(ch => ch.Key == addChapter.Key)
|
||||
.Include(ch => ch.ParentManga)
|
||||
.Include(ch => ch.MangaConnectorIds)
|
||||
.FirstOrDefault();
|
||||
if (chapter is not null)
|
||||
{
|
||||
chapter.MangaConnectorIds = chapter.MangaConnectorIds.UnionBy(addChapter.MangaConnectorIds, id => id.Key).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Chapters.Add(addChapter);
|
||||
chapter = addChapter;
|
||||
}
|
||||
|
||||
if (context.Sync() is { success: false })
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user