mirror of
https://github.com/Kareadita/Kavita.git
synced 2026-05-13 11:02:18 -04:00
Text View, View & Filter All Annotations, and More OPDS Love (#4062)
Co-authored-by: Amelia <77553571+Fesaa@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.DTOs.Filtering.v2;
|
||||
using API.DTOs.Reader;
|
||||
using API.Entities;
|
||||
using Kavita.Common;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace API.Extensions.QueryExtensions.Filtering;
|
||||
|
||||
public static class AnnotationFilter
|
||||
{
|
||||
|
||||
public static IQueryable<AppUserAnnotation> IsOwnedBy(this IQueryable<AppUserAnnotation> queryable, bool condition,
|
||||
FilterComparison comparison, IList<int> ownerIds)
|
||||
{
|
||||
if (ownerIds.Count == 0 || !condition) return queryable;
|
||||
|
||||
return comparison switch
|
||||
{
|
||||
FilterComparison.Equal => queryable.Where(a => a.AppUserId == ownerIds[0]),
|
||||
FilterComparison.Contains => queryable.Where(a => ownerIds.Contains(a.AppUserId)),
|
||||
FilterComparison.NotContains => queryable.Where(a => !ownerIds.Contains(a.AppUserId)),
|
||||
FilterComparison.NotEqual => queryable.Where(a => a.AppUserId != ownerIds[0]),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null),
|
||||
};
|
||||
}
|
||||
|
||||
public static IQueryable<AppUserAnnotation> IsInLibrary(this IQueryable<AppUserAnnotation> queryable, bool condition,
|
||||
FilterComparison comparison, IList<int> libraryIds)
|
||||
{
|
||||
if (libraryIds.Count == 0 || !condition) return queryable;
|
||||
|
||||
return comparison switch
|
||||
{
|
||||
FilterComparison.Equal => queryable.Where(a => a.Series.LibraryId == libraryIds[0]),
|
||||
FilterComparison.Contains => queryable.Where(a => libraryIds.Contains(a.Series.LibraryId)),
|
||||
FilterComparison.NotContains => queryable.Where(a => !libraryIds.Contains(a.Series.LibraryId)),
|
||||
FilterComparison.NotEqual => queryable.Where(a => a.Series.LibraryId != libraryIds[0]),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null),
|
||||
};
|
||||
}
|
||||
|
||||
public static IQueryable<AppUserAnnotation> IsUsingHighlights(this IQueryable<AppUserAnnotation> queryable, bool condition,
|
||||
FilterComparison comparison, IList<int> highlightSlotIdxs)
|
||||
{
|
||||
if (highlightSlotIdxs.Count == 0 || !condition) return queryable;
|
||||
|
||||
return comparison switch
|
||||
{
|
||||
FilterComparison.Equal => queryable.Where(a => a.SelectedSlotIndex== highlightSlotIdxs[0]),
|
||||
FilterComparison.Contains => queryable.Where(a => highlightSlotIdxs.Contains(a.SelectedSlotIndex)),
|
||||
FilterComparison.NotContains => queryable.Where(a => !highlightSlotIdxs.Contains(a.SelectedSlotIndex)),
|
||||
FilterComparison.NotEqual => queryable.Where(a => a.SelectedSlotIndex != highlightSlotIdxs[0]),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null),
|
||||
};
|
||||
}
|
||||
|
||||
public static IQueryable<AppUserAnnotation> HasSelected(this IQueryable<AppUserAnnotation> queryable, bool condition,
|
||||
FilterComparison comparison, string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || !condition) return queryable;
|
||||
|
||||
return comparison switch
|
||||
{
|
||||
FilterComparison.Equal => queryable.Where(a => a.SelectedText == value),
|
||||
FilterComparison.NotEqual => queryable.Where(a => a.SelectedText != value),
|
||||
FilterComparison.BeginsWith => queryable.Where(a => EF.Functions.Like(a.SelectedText, $"{value}%")),
|
||||
FilterComparison.EndsWith => queryable.Where(a => EF.Functions.Like(a.SelectedText, $"%{value}")),
|
||||
FilterComparison.Matches => queryable.Where(a => EF.Functions.Like(a.SelectedText, $"%{value}%")),
|
||||
FilterComparison.GreaterThan or
|
||||
FilterComparison.GreaterThanEqual or
|
||||
FilterComparison.LessThan or
|
||||
FilterComparison.LessThanEqual or
|
||||
FilterComparison.Contains or
|
||||
FilterComparison.MustContains or
|
||||
FilterComparison.NotContains or
|
||||
FilterComparison.IsBefore or
|
||||
FilterComparison.IsAfter or
|
||||
FilterComparison.IsInLast or
|
||||
FilterComparison.IsNotInLast or
|
||||
FilterComparison.IsEmpty => throw new KavitaException($"{comparison} is not applicable for Annotation.SelectedText"),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null),
|
||||
};
|
||||
}
|
||||
|
||||
public static IQueryable<AppUserAnnotation> HasCommented(this IQueryable<AppUserAnnotation> queryable, bool condition,
|
||||
FilterComparison comparison, string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || !condition) return queryable;
|
||||
|
||||
return comparison switch
|
||||
{
|
||||
FilterComparison.Equal => queryable.Where(a => a.CommentPlainText == value),
|
||||
FilterComparison.NotEqual => queryable.Where(a => a.CommentPlainText != value),
|
||||
FilterComparison.BeginsWith => queryable.Where(a => EF.Functions.Like(a.CommentPlainText, $"{value}%")),
|
||||
FilterComparison.EndsWith => queryable.Where(a => EF.Functions.Like(a.CommentPlainText, $"%{value}")),
|
||||
FilterComparison.Matches => queryable.Where(a => EF.Functions.Like(a.CommentPlainText, $"%{value}%")),
|
||||
FilterComparison.GreaterThan or
|
||||
FilterComparison.GreaterThanEqual or
|
||||
FilterComparison.LessThan or
|
||||
FilterComparison.LessThanEqual or
|
||||
FilterComparison.Contains or
|
||||
FilterComparison.MustContains or
|
||||
FilterComparison.NotContains or
|
||||
FilterComparison.IsBefore or
|
||||
FilterComparison.IsAfter or
|
||||
FilterComparison.IsInLast or
|
||||
FilterComparison.IsNotInLast or
|
||||
FilterComparison.IsEmpty => throw new KavitaException($"{comparison} is not applicable for Annotation.CommentPlainText"),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -925,5 +925,21 @@ public static class SeriesFilter
|
||||
}
|
||||
}
|
||||
|
||||
public static IQueryable<Series> HasFileSize(this IQueryable<Series> queryable, bool condition,
|
||||
FilterComparison comparison, float fileSize)
|
||||
{
|
||||
if (fileSize == 0f || !condition) return queryable;
|
||||
|
||||
return comparison switch
|
||||
{
|
||||
FilterComparison.Equal => queryable.Where(s => s.Volumes.Sum(v => v.Chapters.Sum(c => c.Files.Sum(f => f.Bytes))) == fileSize),
|
||||
FilterComparison.LessThan => queryable.Where(s => s.Volumes.Sum(v => v.Chapters.Sum(c => c.Files.Sum(f => f.Bytes))) < fileSize),
|
||||
FilterComparison.LessThanEqual => queryable.Where(s => s.Volumes.Sum(v => v.Chapters.Sum(c => c.Files.Sum(f => f.Bytes))) <= fileSize),
|
||||
FilterComparison.GreaterThan => queryable.Where(s => s.Volumes.Sum(v => v.Chapters.Sum(c => c.Files.Sum(f => f.Bytes))) > fileSize),
|
||||
FilterComparison.GreaterThanEqual => queryable.Where(s => s.Volumes.Sum(v => v.Chapters.Sum(c => c.Files.Sum(f => f.Bytes))) >= fileSize),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(comparison), comparison, "Filter Comparison is not supported"),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
||||
using API.Data.Misc;
|
||||
using API.Data.Repositories;
|
||||
using API.DTOs;
|
||||
using API.DTOs.Annotations;
|
||||
using API.DTOs.Filtering;
|
||||
using API.DTOs.KavitaPlus.Manage;
|
||||
using API.DTOs.Metadata.Browse;
|
||||
@@ -291,10 +292,29 @@ public static class QueryableExtensions
|
||||
PersonSortField.SeriesCount => query.OrderByDescending(p => p.SeriesMetadataPeople.Count),
|
||||
PersonSortField.ChapterCount when sort.IsAscending => query.OrderBy(p => p.ChapterPeople.Count),
|
||||
PersonSortField.ChapterCount => query.OrderByDescending(p => p.ChapterPeople.Count),
|
||||
_ => query.OrderBy(p => p.Name)
|
||||
_ => query.OrderBy(p => p.Name),
|
||||
};
|
||||
}
|
||||
|
||||
public static IQueryable<AppUserAnnotation> SortBy(this IQueryable<AppUserAnnotation> query, AnnotationSortOptions? sort)
|
||||
{
|
||||
if (sort == null)
|
||||
{
|
||||
return query.OrderBy(a => a.CreatedUtc);
|
||||
}
|
||||
|
||||
return sort.SortField switch
|
||||
{
|
||||
AnnotationSortField.Owner when sort.IsAscending => query.OrderBy(a => a.AppUser.UserName),
|
||||
AnnotationSortField.Owner => query.OrderByDescending(a => a.AppUser.UserName),
|
||||
AnnotationSortField.Created when sort.IsAscending => query.OrderBy(a => a.CreatedUtc),
|
||||
AnnotationSortField.Created => query.OrderByDescending(a => a.CreatedUtc),
|
||||
AnnotationSortField.LastModified when sort.IsAscending => query.OrderBy(a => a.LastModifiedUtc),
|
||||
AnnotationSortField.LastModified => query.OrderByDescending(a => a.LastModifiedUtc),
|
||||
AnnotationSortField.Color when sort.IsAscending => query.OrderBy(a => a.SelectedSlotIndex),
|
||||
AnnotationSortField.Color => query.OrderByDescending(a => a.SelectedSlotIndex),
|
||||
_ => query.OrderBy(a => a.CreatedUtc),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -325,4 +345,35 @@ public static class QueryableExtensions
|
||||
_ => query
|
||||
};
|
||||
}
|
||||
|
||||
public static IQueryable<FullAnnotationDto> SelectFullAnnotation(this IQueryable<AppUserAnnotation> query)
|
||||
{
|
||||
return query.Select(a => new FullAnnotationDto
|
||||
{
|
||||
Id = a.Id,
|
||||
UserId = a.AppUserId,
|
||||
SelectedText = a.SelectedText,
|
||||
Comment = a.Comment,
|
||||
CommentHtml = a.CommentHtml,
|
||||
CommentPlainText = a.CommentPlainText,
|
||||
Context = a.Context,
|
||||
ChapterTitle = a.ChapterTitle,
|
||||
PageNumber = a.PageNumber,
|
||||
SelectedSlotIndex = a.SelectedSlotIndex,
|
||||
ContainsSpoiler = a.ContainsSpoiler,
|
||||
CreatedUtc = a.CreatedUtc,
|
||||
LastModifiedUtc = a.LastModifiedUtc,
|
||||
LibraryId = a.LibraryId,
|
||||
LibraryName = a.Chapter.Volume.Series.Library.Name,
|
||||
SeriesId = a.SeriesId,
|
||||
SeriesName = a.Chapter.Volume.Series.Name,
|
||||
VolumeId = a.VolumeId,
|
||||
VolumeName = a.Chapter.Volume.Name,
|
||||
ChapterId = a.ChapterId,
|
||||
})
|
||||
.OrderBy(a => a.SeriesId)
|
||||
.ThenBy(a => a.VolumeId)
|
||||
.ThenBy(a => a.ChapterId)
|
||||
.ThenBy(a => a.PageNumber);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user