MAL Interest Stacks (#2932)
This commit is contained in:
parent
29eb65c783
commit
b23300b1a4
61 changed files with 4104 additions and 382 deletions
3025
API/Data/Migrations/20240503120147_SmartCollectionFields.Designer.cs
generated
Normal file
3025
API/Data/Migrations/20240503120147_SmartCollectionFields.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
39
API/Data/Migrations/20240503120147_SmartCollectionFields.cs
Normal file
39
API/Data/Migrations/20240503120147_SmartCollectionFields.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace API.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class SmartCollectionFields : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "MissingSeriesFromSource",
|
||||
table: "AppUserCollection",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "TotalSourceCount",
|
||||
table: "AppUserCollection",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MissingSeriesFromSource",
|
||||
table: "AppUserCollection");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TotalSourceCount",
|
||||
table: "AppUserCollection");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -224,6 +224,9 @@ namespace API.Data.Migrations
|
|||
b.Property<DateTime>("LastSyncUtc")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MissingSeriesFromSource")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedTitle")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -242,6 +245,9 @@ namespace API.Data.Migrations
|
|||
b.Property<string>("Title")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("TotalSourceCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AppUserId");
|
||||
|
|
|
@ -9,6 +9,7 @@ using API.Entities.Enums;
|
|||
using API.Extensions;
|
||||
using API.Extensions.QueryExtensions;
|
||||
using API.Extensions.QueryExtensions.Filtering;
|
||||
using API.Services.Plus;
|
||||
using AutoMapper;
|
||||
using AutoMapper.QueryableExtensions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
@ -57,6 +58,7 @@ public interface ICollectionTagRepository
|
|||
Task<IList<AppUserCollection>> GetCollectionsForUserAsync(int userId, CollectionIncludes includes = CollectionIncludes.None);
|
||||
Task UpdateCollectionAgeRating(AppUserCollection tag);
|
||||
Task<IEnumerable<AppUserCollection>> GetCollectionsByIds(IEnumerable<int> tags, CollectionIncludes includes = CollectionIncludes.None);
|
||||
Task<IList<AppUserCollection>> GetAllCollectionsForSyncing(DateTime expirationTime);
|
||||
}
|
||||
public class CollectionTagRepository : ICollectionTagRepository
|
||||
{
|
||||
|
@ -207,6 +209,16 @@ public class CollectionTagRepository : ICollectionTagRepository
|
|||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<AppUserCollection>> GetAllCollectionsForSyncing(DateTime expirationTime)
|
||||
{
|
||||
return await _context.AppUserCollection
|
||||
.Where(c => c.Source == ScrobbleProvider.Mal)
|
||||
.Where(c => c.LastSyncUtc <= expirationTime)
|
||||
.Include(c => c.Items)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
public async Task<AppUserCollection?> GetCollectionAsync(int tagId, CollectionIncludes includes = CollectionIncludes.None)
|
||||
{
|
||||
|
|
|
@ -73,6 +73,7 @@ public interface ISeriesRepository
|
|||
void Update(Series series);
|
||||
void Remove(Series series);
|
||||
void Remove(IEnumerable<Series> series);
|
||||
void Detach(Series series);
|
||||
Task<bool> DoesSeriesNameExistInLibrary(string name, int libraryId, MangaFormat format);
|
||||
/// <summary>
|
||||
/// Adds user information like progress, ratings, etc
|
||||
|
@ -96,7 +97,7 @@ public interface ISeriesRepository
|
|||
Task<SeriesDto?> GetSeriesDtoByIdAsync(int seriesId, int userId);
|
||||
Task<Series?> GetSeriesByIdAsync(int seriesId, SeriesIncludes includes = SeriesIncludes.Volumes | SeriesIncludes.Metadata);
|
||||
Task<IList<SeriesDto>> GetSeriesDtoByIdsAsync(IEnumerable<int> seriesIds, AppUser user);
|
||||
Task<IList<Series>> GetSeriesByIdsAsync(IList<int> seriesIds);
|
||||
Task<IList<Series>> GetSeriesByIdsAsync(IList<int> seriesIds, bool fullSeries = true);
|
||||
Task<int[]> GetChapterIdsForSeriesAsync(IList<int> seriesIds);
|
||||
Task<IDictionary<int, IList<int>>> GetChapterIdWithSeriesIdForSeriesAsync(int[] seriesIds);
|
||||
/// <summary>
|
||||
|
@ -138,6 +139,7 @@ public interface ISeriesRepository
|
|||
Task<IEnumerable<Series>> GetAllSeriesByNameAsync(IList<string> normalizedNames,
|
||||
int userId, SeriesIncludes includes = SeriesIncludes.None);
|
||||
Task<Series?> GetFullSeriesByAnyName(string seriesName, string localizedName, int libraryId, MangaFormat format, bool withFullIncludes = true);
|
||||
Task<Series?> GetSeriesByAnyName(string seriesName, string localizedName, IList<MangaFormat> formats, int userId);
|
||||
public Task<IList<Series>> GetAllSeriesByAnyName(string seriesName, string localizedName, int libraryId,
|
||||
MangaFormat format);
|
||||
Task<IList<Series>> RemoveSeriesNotInList(IList<ParsedSeries> seenSeries, int libraryId);
|
||||
|
@ -204,6 +206,11 @@ public class SeriesRepository : ISeriesRepository
|
|||
_context.Series.RemoveRange(series);
|
||||
}
|
||||
|
||||
public void Detach(Series series)
|
||||
{
|
||||
_context.Entry(series).State = EntityState.Detached;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a series name and format exists already in a library
|
||||
/// </summary>
|
||||
|
@ -531,15 +538,19 @@ public class SeriesRepository : ISeriesRepository
|
|||
/// Returns Full Series including all external links
|
||||
/// </summary>
|
||||
/// <param name="seriesIds"></param>
|
||||
/// <param name="fullSeries">Include all the includes or just the Series</param>
|
||||
/// <returns></returns>
|
||||
public async Task<IList<Series>> GetSeriesByIdsAsync(IList<int> seriesIds)
|
||||
public async Task<IList<Series>> GetSeriesByIdsAsync(IList<int> seriesIds, bool fullSeries = true)
|
||||
{
|
||||
return await _context.Series
|
||||
.Include(s => s.Volumes)
|
||||
var query = _context.Series
|
||||
.Where(s => seriesIds.Contains(s.Id))
|
||||
.AsSplitQuery();
|
||||
|
||||
if (!fullSeries) return await query.ToListAsync();
|
||||
|
||||
return await query.Include(s => s.Volumes)
|
||||
.Include(s => s.Relations)
|
||||
.Include(s => s.Metadata)
|
||||
.ThenInclude(m => m.CollectionTags)
|
||||
|
||||
|
||||
.Include(s => s.ExternalSeriesMetadata)
|
||||
|
||||
|
@ -549,9 +560,6 @@ public class SeriesRepository : ISeriesRepository
|
|||
.ThenInclude(e => e.ExternalReviews)
|
||||
.Include(s => s.ExternalSeriesMetadata)
|
||||
.ThenInclude(e => e.ExternalRecommendations)
|
||||
|
||||
.Where(s => seriesIds.Contains(s.Id))
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
|
@ -1670,6 +1678,26 @@ public class SeriesRepository : ISeriesRepository
|
|||
#nullable enable
|
||||
}
|
||||
|
||||
public async Task<Series?> GetSeriesByAnyName(string seriesName, string localizedName, IList<MangaFormat> formats, int userId)
|
||||
{
|
||||
var libraryIds = GetLibraryIdsForUser(userId);
|
||||
var normalizedSeries = seriesName.ToNormalized();
|
||||
var normalizedLocalized = localizedName.ToNormalized();
|
||||
return await _context.Series
|
||||
.Where(s => libraryIds.Contains(s.LibraryId))
|
||||
.Where(s => formats.Contains(s.Format))
|
||||
.Where(s =>
|
||||
s.NormalizedName.Equals(normalizedSeries)
|
||||
|| s.NormalizedName.Equals(normalizedLocalized)
|
||||
|
||||
|| s.NormalizedLocalizedName.Equals(normalizedSeries)
|
||||
|| (!string.IsNullOrEmpty(normalizedLocalized) && s.NormalizedLocalizedName.Equals(normalizedLocalized))
|
||||
|
||||
|| (s.OriginalName != null && s.OriginalName.Equals(seriesName))
|
||||
)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<Series>> GetAllSeriesByAnyName(string seriesName, string localizedName, int libraryId,
|
||||
MangaFormat format)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue