mirror of
https://github.com/C9Glax/tranga.git
synced 2025-07-02 08:54:16 +02:00
Merge branch 'Jikan' into JobQueue-Sortable
# Conflicts: # API/Schema/Contexts/PgsqlContext.cs
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
using API.Schema.Jobs;
|
||||
using API.Schema.MangaConnectors;
|
||||
using API.Schema.MetadataFetchers;
|
||||
using log4net;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
@ -17,6 +18,7 @@ public class PgsqlContext(DbContextOptions<PgsqlContext> options) : DbContext(op
|
||||
public DbSet<MangaTag> Tags { get; set; }
|
||||
public DbSet<MangaConnectorId<Manga>> MangaConnectorToManga { get; set; }
|
||||
public DbSet<MangaConnectorId<Chapter>> MangaConnectorToChapter { get; set; }
|
||||
public DbSet<MetadataEntry> MetadataEntries { get; set; }
|
||||
private ILog Log => LogManager.GetLogger(GetType());
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
@ -216,5 +218,18 @@ public class PgsqlContext(DbContextOptions<PgsqlContext> options) : DbContext(op
|
||||
modelBuilder.Entity<Manga>()
|
||||
.Navigation(m => m.Library)
|
||||
.EnableLazyLoading();
|
||||
|
||||
modelBuilder.Entity<MetadataFetcher>()
|
||||
.HasDiscriminator<string>(nameof(MetadataEntry))
|
||||
.HasValue<MyAnimeList>(nameof(MyAnimeList));
|
||||
//MetadataEntry
|
||||
modelBuilder.Entity<MetadataEntry>()
|
||||
.HasOne<Manga>(entry => entry.Manga)
|
||||
.WithMany()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
modelBuilder.Entity<MetadataEntry>()
|
||||
.HasOne<MetadataFetcher>(entry => entry.MetadataFetcher)
|
||||
.WithMany()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
35
API/Schema/MetadataFetchers/MetadataEntry.cs
Normal file
35
API/Schema/MetadataFetchers/MetadataEntry.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace API.Schema.MetadataFetchers;
|
||||
|
||||
[PrimaryKey("MetadataFetcherName", "Identifier")]
|
||||
public class MetadataEntry
|
||||
{
|
||||
[JsonIgnore]
|
||||
public Manga Manga { get; init; } = null!;
|
||||
public string MangaId { get; init; }
|
||||
[JsonIgnore]
|
||||
public MetadataFetcher MetadataFetcher { get; init; } = null!;
|
||||
public string MetadataFetcherName { get; init; }
|
||||
public string Identifier { get; init; }
|
||||
|
||||
public MetadataEntry(MetadataFetcher fetcher, Manga manga, string identifier)
|
||||
{
|
||||
this.Manga = manga;
|
||||
this.MangaId = manga.Key;
|
||||
this.MetadataFetcher = fetcher;
|
||||
this.MetadataFetcherName = fetcher.MetadataFetcherName;
|
||||
this.Identifier = identifier;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EFCORE only!!!!
|
||||
/// </summary>
|
||||
internal MetadataEntry(string mangaId, string identifier, string metadataFetcherName)
|
||||
{
|
||||
this.MangaId = mangaId;
|
||||
this.Identifier = identifier;
|
||||
this.MetadataFetcherName = metadataFetcherName;
|
||||
}
|
||||
}
|
37
API/Schema/MetadataFetchers/MetadataFetcher.cs
Normal file
37
API/Schema/MetadataFetchers/MetadataFetcher.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using API.Schema.Contexts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace API.Schema.MetadataFetchers;
|
||||
|
||||
[PrimaryKey("MetadataFetcherName")]
|
||||
public abstract class MetadataFetcher
|
||||
{
|
||||
// ReSharper disable once EntityFramework.ModelValidation.UnlimitedStringLength
|
||||
public string MetadataFetcherName { get; init; }
|
||||
|
||||
protected MetadataFetcher()
|
||||
{
|
||||
this.MetadataFetcherName = this.GetType().Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EFCORE ONLY!!!
|
||||
/// </summary>
|
||||
internal MetadataFetcher(string metadataFetcherName)
|
||||
{
|
||||
this.MetadataFetcherName = metadataFetcherName;
|
||||
}
|
||||
|
||||
internal MetadataEntry CreateMetadataEntry(Manga manga, string identifier) =>
|
||||
new (this, manga, identifier);
|
||||
|
||||
public abstract MetadataSearchResult[] SearchMetadataEntry(Manga manga);
|
||||
|
||||
public abstract MetadataSearchResult[] SearchMetadataEntry(string searchTerm);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the Manga linked in the MetadataEntry
|
||||
/// </summary>
|
||||
public abstract void UpdateMetadata(MetadataEntry metadataEntry, PgsqlContext dbContext);
|
||||
}
|
3
API/Schema/MetadataFetchers/MetadataSearchResult.cs
Normal file
3
API/Schema/MetadataFetchers/MetadataSearchResult.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace API.Schema.MetadataFetchers;
|
||||
|
||||
public record MetadataSearchResult(string Identifier, string Name, string Url, string? Description = null, string? CoverUrl = null);
|
79
API/Schema/MetadataFetchers/MyAnimeList.cs
Normal file
79
API/Schema/MetadataFetchers/MyAnimeList.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using API.Schema.Contexts;
|
||||
using JikanDotNet;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace API.Schema.MetadataFetchers;
|
||||
|
||||
public class MyAnimeList : MetadataFetcher
|
||||
{
|
||||
private static readonly Jikan Jikan = new ();
|
||||
private static readonly Regex GetIdFromUrl = new(@"https?:\/\/myanimelist\.net\/manga\/([0-9]+)\/?.*");
|
||||
|
||||
public override MetadataSearchResult[] SearchMetadataEntry(Manga manga)
|
||||
{
|
||||
if (manga.Links.Any(link => link.LinkProvider.Equals("MyAnimeList", StringComparison.InvariantCultureIgnoreCase)))
|
||||
{
|
||||
string url = manga.Links.First(link => link.LinkProvider.Equals("MyAnimeList", StringComparison.InvariantCultureIgnoreCase)).LinkUrl;
|
||||
Match m = GetIdFromUrl.Match(url);
|
||||
if (m.Success && m.Groups[1].Success)
|
||||
{
|
||||
long id = long.Parse(m.Groups[1].Value);
|
||||
JikanDotNet.Manga data = Jikan.GetMangaAsync(id).Result.Data;
|
||||
return [new MetadataSearchResult(id.ToString(), data.Titles.First().Title, data.Url, data.Synopsis)];
|
||||
}
|
||||
}
|
||||
|
||||
return SearchMetadataEntry(manga.Name);
|
||||
}
|
||||
|
||||
public override MetadataSearchResult[] SearchMetadataEntry(string searchTerm)
|
||||
{
|
||||
|
||||
ICollection<JikanDotNet.Manga> resultData = Jikan.SearchMangaAsync(searchTerm).Result.Data;
|
||||
if (resultData.Count < 1)
|
||||
return [];
|
||||
return resultData.Select(data =>
|
||||
new MetadataSearchResult(data.MalId.ToString(), data.Titles.First().Title, data.Url, data.Synopsis))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the Manga linked in the MetadataEntry
|
||||
/// </summary>
|
||||
/// <param name="metadataEntry"></param>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <exception cref="FormatException"></exception>
|
||||
/// <exception cref="DbUpdateException"></exception>
|
||||
public override void UpdateMetadata(MetadataEntry metadataEntry, PgsqlContext dbContext)
|
||||
{
|
||||
Manga dbManga = dbContext.Mangas.Find(metadataEntry.MangaId)!;
|
||||
MangaFull resultData;
|
||||
try
|
||||
{
|
||||
long id = long.Parse(metadataEntry.Identifier);
|
||||
resultData = Jikan.GetMangaFullDataAsync(id).Result.Data;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FormatException("ID was not in correct format");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dbManga.Name = resultData.Titles.First().Title;
|
||||
dbManga.Description = resultData.Synopsis;
|
||||
dbManga.AltTitles.Clear();
|
||||
dbManga.AltTitles = resultData.Titles.Select(t => new AltTitle(t.Type, t.Title)).ToList();
|
||||
dbManga.Authors.Clear();
|
||||
dbManga.Authors = resultData.Authors.Select(a => new Author(a.Name)).ToList();
|
||||
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
catch (DbUpdateException e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user