Filtering Bugfixes (#1220)

* Cleaned up random strings and unified them in one place.

* Implemented the ability to disable typeaheads

* Refactored disable state to disable controls on filter

* Fixed an overflow regression on title

* Updated ComicInfo DTO which had some bad properties on it

* Cleaned up some code around disabled typeaheads/filters

* Fixed typeaheads causing resets to state and mucking up filter presets

* Fixed state not refreshing between page loads

* Fixed a bad parsing for My Charms Are Wasted on Kuroiwa Medaka - Ch. 37.5 - Volume Extras

* Cleanup within the metadata filter to reuse logic and minimize extra loops.

* Fixed a timing issue with typeahead and first load for people

* Fixed a bug in Publication Status for a given library, which would fail due to not performing some of the query in memory. Removed a custom index on Series table that wasn't used and potentially caused constraint issues.

* Added a wiki link for stats collections

* Security bump

* Fixed the regex
This commit is contained in:
Joseph Milazzo 2022-04-16 18:29:11 -05:00 committed by GitHub
parent e3aa9abf55
commit e630e0b2c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 1856 additions and 291 deletions

View file

@ -99,12 +99,12 @@ public class MetadataController : BaseApiController
/// <param name="libraryIds">String separated libraryIds or null for all publication status</param>
/// <returns></returns>
[HttpGet("publication-status")]
public async Task<ActionResult<IList<AgeRatingDto>>> GetAllPublicationStatus(string? libraryIds)
public ActionResult<IList<AgeRatingDto>> GetAllPublicationStatus(string? libraryIds)
{
var ids = libraryIds?.Split(",").Select(int.Parse).ToList();
if (ids != null && ids.Count > 0)
if (ids is {Count: > 0})
{
return Ok(await _unitOfWork.SeriesRepository.GetAllPublicationStatusesDtosForLibrariesAsync(ids));
return Ok(_unitOfWork.SeriesRepository.GetAllPublicationStatusesDtosForLibrariesAsync(ids));
}
return Ok(Enum.GetValues<PublicationStatus>().Select(t => new PublicationStatusDto()

View file

@ -47,11 +47,11 @@ namespace API.Data.Metadata
/// </summary>
public float UserRating { get; set; }
public string AlternateSeries { get; set; } = string.Empty;
public string StoryArc { get; set; } = string.Empty;
public string SeriesGroup { get; set; } = string.Empty;
public string AlternativeSeries { get; set; } = string.Empty;
public string AlternativeNumber { get; set; } = string.Empty;
public string AlternateNumber { get; set; } = string.Empty;
public int AlternateCount { get; set; } = 0;
public string AlternateSeries { get; set; } = string.Empty;
/// <summary>
/// This is Epub only: calibre:title_sort

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,25 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace API.Data.Migrations
{
public partial class RemoveCustomIndex : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_Series_Name_NormalizedName_LocalizedName_LibraryId_Format",
table: "Series");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateIndex(
name: "IX_Series_Name_NormalizedName_LocalizedName_LibraryId_Format",
table: "Series",
columns: new[] { "Name", "NormalizedName", "LocalizedName", "LibraryId", "Format" },
unique: true);
}
}
}

View file

@ -744,9 +744,6 @@ namespace API.Data.Migrations
b.HasIndex("LibraryId");
b.HasIndex("Name", "NormalizedName", "LocalizedName", "LibraryId", "Format")
.IsUnique();
b.ToTable("Series");
});

View file

@ -94,7 +94,7 @@ public interface ISeriesRepository
Task<IList<SeriesMetadata>> GetSeriesMetadataForIdsAsync(IEnumerable<int> seriesIds);
Task<IList<AgeRatingDto>> GetAllAgeRatingsDtosForLibrariesAsync(List<int> libraryIds);
Task<IList<LanguageDto>> GetAllLanguagesForLibrariesAsync(List<int> libraryIds);
Task<IList<PublicationStatusDto>> GetAllPublicationStatusesDtosForLibrariesAsync(List<int> libraryIds);
IEnumerable<PublicationStatusDto> GetAllPublicationStatusesDtosForLibrariesAsync(List<int> libraryIds);
Task<IEnumerable<GroupedSeriesDto>> GetRecentlyUpdatedSeries(int userId, int pageSize = 30);
}
@ -884,19 +884,19 @@ public class SeriesRepository : ISeriesRepository
.ToList();
}
public async Task<IList<PublicationStatusDto>> GetAllPublicationStatusesDtosForLibrariesAsync(List<int> libraryIds)
public IEnumerable<PublicationStatusDto> GetAllPublicationStatusesDtosForLibrariesAsync(List<int> libraryIds)
{
return await _context.Series
return _context.Series
.Where(s => libraryIds.Contains(s.LibraryId))
.Select(s => s.Metadata.PublicationStatus)
.Distinct()
.AsEnumerable()
.Select(s => new PublicationStatusDto()
{
Value = s,
Title = s.ToDescription()
})
.OrderBy(s => s.Title)
.ToListAsync();
.OrderBy(s => s.Title);
}

View file

@ -3,78 +3,75 @@ using System.Collections.Generic;
using API.Entities.Enums;
using API.Entities.Interfaces;
using API.Entities.Metadata;
using Microsoft.EntityFrameworkCore;
namespace API.Entities
namespace API.Entities;
public class Series : IEntityDate
{
[Index(nameof(Name), nameof(NormalizedName), nameof(LocalizedName), nameof(LibraryId), nameof(Format), IsUnique = true)]
public class Series : IEntityDate
{
public int Id { get; set; }
/// <summary>
/// The UI visible Name of the Series. This may or may not be the same as the OriginalName
/// </summary>
public string Name { get; set; }
/// <summary>
/// Used internally for name matching. <see cref="Parser.Parser.Normalize"/>
/// </summary>
public string NormalizedName { get; set; }
/// <summary>
/// The name used to sort the Series. By default, will be the same as Name.
/// </summary>
public string SortName { get; set; }
/// <summary>
/// Name in original language (Japanese for Manga). By default, will be same as Name.
/// </summary>
public string LocalizedName { get; set; }
/// <summary>
/// Original Name on disk. Not exposed to UI.
/// </summary>
public string OriginalName { get; set; }
/// <summary>
/// Time of creation
/// </summary>
public DateTime Created { get; set; }
/// <summary>
/// Whenever a modification occurs. Ie) New volumes, removed volumes, title update, etc
/// </summary>
public DateTime LastModified { get; set; }
/// <summary>
/// Absolute path to the (managed) image file
/// </summary>
/// <remarks>The file is managed internally to Kavita's APPDIR</remarks>
public string CoverImage { get; set; }
/// <summary>
/// Denotes if the CoverImage has been overridden by the user. If so, it will not be updated during normal scan operations.
/// </summary>
public bool CoverImageLocked { get; set; }
/// <summary>
/// Sum of all Volume page counts
/// </summary>
public int Pages { get; set; }
public int Id { get; set; }
/// <summary>
/// The UI visible Name of the Series. This may or may not be the same as the OriginalName
/// </summary>
public string Name { get; set; }
/// <summary>
/// Used internally for name matching. <see cref="Parser.Parser.Normalize"/>
/// </summary>
public string NormalizedName { get; set; }
/// <summary>
/// The name used to sort the Series. By default, will be the same as Name.
/// </summary>
public string SortName { get; set; }
/// <summary>
/// Name in original language (Japanese for Manga). By default, will be same as Name.
/// </summary>
public string LocalizedName { get; set; }
/// <summary>
/// Original Name on disk. Not exposed to UI.
/// </summary>
public string OriginalName { get; set; }
/// <summary>
/// Time of creation
/// </summary>
public DateTime Created { get; set; }
/// <summary>
/// Whenever a modification occurs. Ie) New volumes, removed volumes, title update, etc
/// </summary>
public DateTime LastModified { get; set; }
/// <summary>
/// Absolute path to the (managed) image file
/// </summary>
/// <remarks>The file is managed internally to Kavita's APPDIR</remarks>
public string CoverImage { get; set; }
/// <summary>
/// Denotes if the CoverImage has been overridden by the user. If so, it will not be updated during normal scan operations.
/// </summary>
public bool CoverImageLocked { get; set; }
/// <summary>
/// Sum of all Volume page counts
/// </summary>
public int Pages { get; set; }
/// <summary>
/// The type of all the files attached to this series
/// </summary>
public MangaFormat Format { get; set; } = MangaFormat.Unknown;
/// <summary>
/// The type of all the files attached to this series
/// </summary>
public MangaFormat Format { get; set; } = MangaFormat.Unknown;
public bool NameLocked { get; set; }
public bool SortNameLocked { get; set; }
public bool LocalizedNameLocked { get; set; }
public bool NameLocked { get; set; }
public bool SortNameLocked { get; set; }
public bool LocalizedNameLocked { get; set; }
/// <summary>
/// When a Chapter was last added onto the Series
/// </summary>
public DateTime LastChapterAdded { get; set; }
/// <summary>
/// When a Chapter was last added onto the Series
/// </summary>
public DateTime LastChapterAdded { get; set; }
public SeriesMetadata Metadata { get; set; }
public ICollection<AppUserRating> Ratings { get; set; } = new List<AppUserRating>();
public ICollection<AppUserProgress> Progress { get; set; } = new List<AppUserProgress>();
public SeriesMetadata Metadata { get; set; }
public ICollection<AppUserRating> Ratings { get; set; } = new List<AppUserRating>();
public ICollection<AppUserProgress> Progress { get; set; } = new List<AppUserProgress>();
// Relationships
public List<Volume> Volumes { get; set; }
public Library Library { get; set; }
public int LibraryId { get; set; }
// Relationships
public List<Volume> Volumes { get; set; }
public Library Library { get; set; }
public int LibraryId { get; set; }
}
}

View file

@ -132,9 +132,9 @@ namespace API.Parser
new Regex(
@"(?<Series>.*)(?:, Chapter )(?<Chapter>\d+)",
MatchOptions, RegexTimeout),
// Please Go Home, Akutsu-San! - Chapter 038.5 - Volume Announcement.cbz
// Please Go Home, Akutsu-San! - Chapter 038.5 - Volume Announcement.cbz, My Charms Are Wasted on Kuroiwa Medaka - Ch. 37.5 - Volume Extras
new Regex(
@"(?<Series>.*)(\s|_|-)(?!Vol)(\s|_|-)(?:Chapter)(\s|_|-)(?<Chapter>\d+)",
@"(?<Series>.+?)(\s|_|-)(?!Vol)(\s|_|-)((?:Chapter)|(?:Ch\.))(\s|_|-)(?<Chapter>\d+)",
MatchOptions, RegexTimeout),
// [dmntsf.net] One Piece - Digital Colored Comics Vol. 20 Ch. 177 - 30 Million vs 81 Million.cbz
new Regex(