Send better data to Kavita+ related to AltNames and Year.

Fixed a localization issue which prevented issue count showing on Series Match Result.
This commit is contained in:
Joseph Milazzo 2025-05-11 10:04:52 -05:00
parent 66f78aa859
commit 519cf60fc8
4 changed files with 32 additions and 7 deletions

View file

@ -200,6 +200,9 @@ public class ExternalMetadataService : IExternalMetadataService
/// <summary> /// <summary>
/// Returns the match results for a Series from UI Flow /// Returns the match results for a Series from UI Flow
/// </summary> /// </summary>
/// <remarks>
/// Will extract alternative names like Localized name, year will send as ReleaseYear but fallback to Comic Vine syntax if applicable
/// </remarks>
/// <param name="dto"></param> /// <param name="dto"></param>
/// <returns></returns> /// <returns></returns>
public async Task<IList<ExternalSeriesMatchDto>> MatchSeries(MatchSeriesDto dto) public async Task<IList<ExternalSeriesMatchDto>> MatchSeries(MatchSeriesDto dto)
@ -212,19 +215,22 @@ public class ExternalMetadataService : IExternalMetadataService
var potentialAnilistId = ScrobblingService.ExtractId<int?>(dto.Query, ScrobblingService.AniListWeblinkWebsite); var potentialAnilistId = ScrobblingService.ExtractId<int?>(dto.Query, ScrobblingService.AniListWeblinkWebsite);
var potentialMalId = ScrobblingService.ExtractId<long?>(dto.Query, ScrobblingService.MalWeblinkWebsite); var potentialMalId = ScrobblingService.ExtractId<long?>(dto.Query, ScrobblingService.MalWeblinkWebsite);
List<string> altNames = [series.LocalizedName, series.OriginalName]; var format = series.Library.Type.ConvertToPlusMediaFormat(series.Format);
if (potentialAnilistId == null && potentialMalId == null && !string.IsNullOrEmpty(dto.Query)) var otherNames = ExtractAlternativeNames(dto, series);
var year = series.Metadata.ReleaseYear;
if (year == 0 && format == PlusMediaFormat.Comic)
{ {
altNames.Add(dto.Query); year = int.Parse(Parser.ParseYear(series.Name));
} }
var matchRequest = new MatchSeriesRequestDto() var matchRequest = new MatchSeriesRequestDto()
{ {
Format = series.Library.Type.ConvertToPlusMediaFormat(series.Format), Format = format,
Query = dto.Query, Query = dto.Query,
SeriesName = series.Name, SeriesName = series.Name,
AlternativeNames = altNames.Where(s => !string.IsNullOrEmpty(s)).ToList(), AlternativeNames = otherNames,
Year = series.Metadata.ReleaseYear, Year = year,
AniListId = potentialAnilistId ?? ScrobblingService.GetAniListId(series), AniListId = potentialAnilistId ?? ScrobblingService.GetAniListId(series),
MalId = potentialMalId ?? ScrobblingService.GetMalId(series) MalId = potentialMalId ?? ScrobblingService.GetMalId(series)
}; };
@ -254,6 +260,18 @@ public class ExternalMetadataService : IExternalMetadataService
return ArraySegment<ExternalSeriesMatchDto>.Empty; return ArraySegment<ExternalSeriesMatchDto>.Empty;
} }
private static List<string> ExtractAlternativeNames(MatchSeriesDto dto, Series series)
{
List<string> altNames = [series.LocalizedName, series.OriginalName];
// if (potentialAnilistId == null && potentialMalId == null && !string.IsNullOrEmpty(dto.Query))
// {
// altNames.Add(dto.Query);
// }
var otherNames = altNames.Where(s => !string.IsNullOrEmpty(s)).Distinct().ToList();
return otherNames;
}
/// <summary> /// <summary>
/// Retrieves Metadata about a Recommended External Series /// Retrieves Metadata about a Recommended External Series

View file

@ -1159,6 +1159,12 @@ public static partial class Parser
return !string.IsNullOrEmpty(name) && SeriesAndYearRegex.IsMatch(name); return !string.IsNullOrEmpty(name) && SeriesAndYearRegex.IsMatch(name);
} }
/// <summary>
/// Parse a Year from a Comic Series: Series Name (YEAR)
/// </summary>
/// <example>Harley Quinn (2024) returns 2024</example>
/// <param name="name"></param>
/// <returns></returns>
public static string ParseYear(string? name) public static string ParseYear(string? name)
{ {
if (string.IsNullOrEmpty(name)) return string.Empty; if (string.IsNullOrEmpty(name)) return string.Empty;

View file

@ -33,10 +33,10 @@
} @else { } @else {
<div class="d-flex pt-3 justify-content-between"> <div class="d-flex pt-3 justify-content-between">
@if ((item.series.volumes || 0) > 0 || (item.series.chapters || 0) > 0) { @if ((item.series.volumes || 0) > 0 || (item.series.chapters || 0) > 0) {
<span class="me-1">{{t('volume-count', {num: item.series.volumes})}}</span>
@if (item.series.plusMediaFormat === PlusMediaFormat.Comic) { @if (item.series.plusMediaFormat === PlusMediaFormat.Comic) {
<span class="me-1">{{t('issue-count', {num: item.series.chapters})}}</span> <span class="me-1">{{t('issue-count', {num: item.series.chapters})}}</span>
} @else { } @else {
<span class="me-1">{{t('volume-count', {num: item.series.volumes})}}</span>
<span class="me-1">{{t('chapter-count', {num: item.series.chapters})}}</span> <span class="me-1">{{t('chapter-count', {num: item.series.chapters})}}</span>
} }
} @else { } @else {

View file

@ -2911,6 +2911,7 @@
"author-count": "{{num}} Authors", "author-count": "{{num}} Authors",
"item-count": "{{num}} Items", "item-count": "{{num}} Items",
"chapter-count": "{{num}} Chapters", "chapter-count": "{{num}} Chapters",
"issue-count": "{{num}} Issues",
"no-data": "No Data", "no-data": "No Data",
"book-num": "Book", "book-num": "Book",