IsEmpty Filter and other small fixes (#3142)

Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
This commit is contained in:
Joe Milazzo 2024-09-13 15:15:01 -07:00 committed by GitHub
parent e574caf7eb
commit 07a36176de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
96 changed files with 1361 additions and 1135 deletions

View file

@ -43,6 +43,7 @@ public static class SeriesFilter
case FilterComparison.IsAfter:
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.IsEmpty:
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
}
@ -71,6 +72,8 @@ public static class SeriesFilter
return queryable.Where(s => s.Metadata.ReleaseYear >= DateTime.Now.Year - (int) releaseYear);
case FilterComparison.IsNotInLast:
return queryable.Where(s => s.Metadata.ReleaseYear < DateTime.Now.Year - (int) releaseYear);
case FilterComparison.IsEmpty:
return queryable.Where(s => s.Metadata.ReleaseYear == 0);
case FilterComparison.Matches:
case FilterComparison.Contains:
case FilterComparison.NotContains:
@ -86,14 +89,20 @@ public static class SeriesFilter
public static IQueryable<Series> HasRating(this IQueryable<Series> queryable, bool condition,
FilterComparison comparison, int rating, int userId)
FilterComparison comparison, float rating, int userId)
{
if (rating < 0 || !condition || userId <= 0) return queryable;
// Users see rating as %, so they are likely to pass 10%. We need to turn that into the underlying float encoding
if (rating.IsNot(0f))
{
rating /= 100f;
}
switch (comparison)
{
case FilterComparison.Equal:
return queryable.Where(s => s.Ratings.Any(r => Math.Abs(r.Rating - rating) < FloatingPointTolerance && r.AppUserId == userId));
return queryable.Where(s => s.Ratings.Any(r => Math.Abs(r.Rating - rating) <= FloatingPointTolerance && r.AppUserId == userId));
case FilterComparison.GreaterThan:
return queryable.Where(s => s.Ratings.Any(r => r.Rating > rating && r.AppUserId == userId));
case FilterComparison.GreaterThanEqual:
@ -102,10 +111,13 @@ public static class SeriesFilter
return queryable.Where(s => s.Ratings.Any(r => r.Rating < rating && r.AppUserId == userId));
case FilterComparison.LessThanEqual:
return queryable.Where(s => s.Ratings.Any(r => r.Rating <= rating && r.AppUserId == userId));
case FilterComparison.NotEqual:
return queryable.Where(s => s.Ratings.Any(r => Math.Abs(r.Rating - rating) >= FloatingPointTolerance && r.AppUserId == userId));
case FilterComparison.IsEmpty:
return queryable.Where(s => s.Ratings.All(r => r.AppUserId != userId));
case FilterComparison.Contains:
case FilterComparison.Matches:
case FilterComparison.NotContains:
case FilterComparison.NotEqual:
case FilterComparison.BeginsWith:
case FilterComparison.EndsWith:
case FilterComparison.IsBefore:
@ -124,7 +136,7 @@ public static class SeriesFilter
{
if (!condition || ratings.Count == 0) return queryable;
var firstRating = ratings.First();
var firstRating = ratings[0];
switch (comparison)
{
case FilterComparison.Equal:
@ -151,6 +163,7 @@ public static class SeriesFilter
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.MustContains:
case FilterComparison.IsEmpty:
throw new KavitaException($"{comparison} not applicable for Series.AgeRating");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
@ -185,6 +198,7 @@ public static class SeriesFilter
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.MustContains:
case FilterComparison.IsEmpty:
throw new KavitaException($"{comparison} not applicable for Series.AverageReadTime");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
@ -196,7 +210,7 @@ public static class SeriesFilter
{
if (!condition || pubStatues.Count == 0) return queryable;
var firstStatus = pubStatues.First();
var firstStatus = pubStatues[0];
switch (comparison)
{
case FilterComparison.Equal:
@ -219,6 +233,7 @@ public static class SeriesFilter
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.Matches:
case FilterComparison.IsEmpty:
throw new KavitaException($"{comparison} not applicable for Series.PublicationStatus");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
@ -269,6 +284,7 @@ public static class SeriesFilter
case FilterComparison.NotEqual:
subQuery = subQuery.Where(s => Math.Abs(s.Percentage - readProgress) > FloatingPointTolerance);
break;
case FilterComparison.IsEmpty:
case FilterComparison.Matches:
case FilterComparison.Contains:
case FilterComparison.NotContains:
@ -293,6 +309,7 @@ public static class SeriesFilter
{
if (!condition) return queryable;
var subQuery = queryable
.Where(s => s.ExternalSeriesMetadata != null)
.Include(s => s.ExternalSeriesMetadata)
@ -334,6 +351,7 @@ public static class SeriesFilter
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.MustContains:
case FilterComparison.IsEmpty:
throw new KavitaException($"{comparison} not applicable for Series.AverageRating");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
@ -393,6 +411,7 @@ public static class SeriesFilter
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.MustContains:
case FilterComparison.IsEmpty:
throw new KavitaException($"{comparison} not applicable for Series.ReadProgress");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
@ -424,6 +443,8 @@ public static class SeriesFilter
queries.AddRange(tags.Select(gId => queryable.Where(s => s.Metadata.Tags.Any(p => p.Id == gId))));
return queries.Aggregate((q1, q2) => q1.Intersect(q2));
case FilterComparison.IsEmpty:
return queryable.Where(s => s.Metadata.Tags == null || s.Metadata.Tags.Count == 0);
case FilterComparison.GreaterThan:
case FilterComparison.GreaterThanEqual:
case FilterComparison.LessThan:
@ -442,6 +463,48 @@ public static class SeriesFilter
}
public static IQueryable<Series> HasPeople(this IQueryable<Series> queryable, bool condition,
FilterComparison comparison, IList<int> people, PersonRole role)
{
if (!condition || (comparison != FilterComparison.IsEmpty && people.Count == 0)) return queryable;
switch (comparison)
{
case FilterComparison.Equal:
case FilterComparison.Contains:
return queryable.Where(s => s.Metadata.People.Any(p => people.Contains(p.Id)));
case FilterComparison.NotEqual:
case FilterComparison.NotContains:
return queryable.Where(s => s.Metadata.People.All(t => !people.Contains(t.Id)));
case FilterComparison.MustContains:
// Deconstruct and do a Union of a bunch of where statements since this doesn't translate
var queries = new List<IQueryable<Series>>()
{
queryable
};
queries.AddRange(people.Select(gId => queryable.Where(s => s.Metadata.People.Any(p => p.Id == gId))));
return queries.Aggregate((q1, q2) => q1.Intersect(q2));
case FilterComparison.IsEmpty:
// Check if there are no people with specific roles (e.g., Writer, Penciller, etc.)
return queryable.Where(s => !s.Metadata.People.Any(p => p.Role == role));
case FilterComparison.GreaterThan:
case FilterComparison.GreaterThanEqual:
case FilterComparison.LessThan:
case FilterComparison.LessThanEqual:
case FilterComparison.BeginsWith:
case FilterComparison.EndsWith:
case FilterComparison.IsBefore:
case FilterComparison.IsAfter:
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.Matches:
throw new KavitaException($"{comparison} not applicable for Series.People");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
}
}
public static IQueryable<Series> HasPeopleLegacy(this IQueryable<Series> queryable, bool condition,
FilterComparison comparison, IList<int> people)
{
if (!condition || people.Count == 0) return queryable;
@ -463,6 +526,7 @@ public static class SeriesFilter
queries.AddRange(people.Select(gId => queryable.Where(s => s.Metadata.People.Any(p => p.Id == gId))));
return queries.Aggregate((q1, q2) => q1.Intersect(q2));
case FilterComparison.IsEmpty:
case FilterComparison.GreaterThan:
case FilterComparison.GreaterThanEqual:
case FilterComparison.LessThan:
@ -502,6 +566,8 @@ public static class SeriesFilter
queries.AddRange(genres.Select(gId => queryable.Where(s => s.Metadata.Genres.Any(p => p.Id == gId))));
return queries.Aggregate((q1, q2) => q1.Intersect(q2));
case FilterComparison.IsEmpty:
return queryable.Where(s => s.Metadata.Genres.Count == 0);
case FilterComparison.GreaterThan:
case FilterComparison.GreaterThanEqual:
case FilterComparison.LessThan:
@ -544,6 +610,7 @@ public static class SeriesFilter
case FilterComparison.IsAfter:
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.IsEmpty:
throw new KavitaException($"{comparison} not applicable for Series.Format");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null);
@ -573,6 +640,8 @@ public static class SeriesFilter
queries.AddRange(collectionSeries.Select(gId => queryable.Where(s => collectionSeries.Any(p => p == s.Id))));
return queries.Aggregate((q1, q2) => q1.Intersect(q2));
case FilterComparison.IsEmpty:
return queryable.Where(s => collectionSeries.All(c => c != s.Id));
case FilterComparison.GreaterThan:
case FilterComparison.GreaterThanEqual:
case FilterComparison.LessThan:
@ -633,6 +702,7 @@ public static class SeriesFilter
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.MustContains:
case FilterComparison.IsEmpty:
throw new KavitaException($"{comparison} not applicable for Series.Name");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, "Filter Comparison is not supported");
@ -656,6 +726,8 @@ public static class SeriesFilter
return queryable.Where(s => EF.Functions.Like(s.Metadata.Summary, $"%{queryString}%"));
case FilterComparison.NotEqual:
return queryable.Where(s => s.Metadata.Summary != queryString);
case FilterComparison.IsEmpty:
return queryable.Where(s => string.IsNullOrEmpty(s.Metadata.Summary));
case FilterComparison.NotContains:
case FilterComparison.GreaterThan:
case FilterComparison.GreaterThanEqual:
@ -703,6 +775,7 @@ public static class SeriesFilter
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.MustContains:
case FilterComparison.IsEmpty:
throw new KavitaException($"{comparison} not applicable for Series.FolderPath");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, "Filter Comparison is not supported");
@ -779,6 +852,7 @@ public static class SeriesFilter
case FilterComparison.IsInLast:
case FilterComparison.IsNotInLast:
case FilterComparison.MustContains:
case FilterComparison.IsEmpty:
throw new KavitaException($"{comparison} not applicable for Series.FolderPath");
default:
throw new ArgumentOutOfRangeException(nameof(comparison), comparison, "Filter Comparison is not supported");