feat(animeon): enhance search for serials and improve voice display

Add serial parameter to Search method to enable enhanced search logic for
series content. When serial flag is set, perform additional search using
English title to find more results. Improve voice selection by properly
handling display names with fallbacks to key or default label.
This commit is contained in:
baliasnyifeliks 2026-02-01 18:05:28 +02:00
parent ff320a97f9
commit 3576932089
2 changed files with 37 additions and 8 deletions

View File

@ -35,7 +35,7 @@ namespace AnimeON
return ApnHelper.WrapUrl(_init, url); return ApnHelper.WrapUrl(_init, url);
} }
public async Task<List<SearchModel>> Search(string imdb_id, long kinopoisk_id, string title, string original_title, int year) public async Task<List<SearchModel>> Search(string imdb_id, long kinopoisk_id, string title, string original_title, int year, int serial)
{ {
string memKey = $"AnimeON:search:{kinopoisk_id}:{imdb_id}"; string memKey = $"AnimeON:search:{kinopoisk_id}:{imdb_id}";
if (_hybridCache.TryGetValue(memKey, out List<SearchModel> res)) if (_hybridCache.TryGetValue(memKey, out List<SearchModel> res))
@ -44,7 +44,7 @@ namespace AnimeON
try try
{ {
var headers = new List<HeadersModel>() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; var headers = new List<HeadersModel>() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) };
async Task<List<SearchModel>> FindAnime(string query) async Task<List<SearchModel>> FindAnime(string query)
{ {
if (string.IsNullOrEmpty(query)) if (string.IsNullOrEmpty(query))
@ -64,7 +64,24 @@ namespace AnimeON
var searchResults = await FindAnime(title) ?? await FindAnime(original_title); var searchResults = await FindAnime(title) ?? await FindAnime(original_title);
if (searchResults == null) if (searchResults == null)
return null; return null;
if (serial == 1 && searchResults.Count > 0)
{
string fallbackTitleEn = searchResults.FirstOrDefault()?.TitleEn;
if (!string.IsNullOrWhiteSpace(fallbackTitleEn))
{
var extraResults = await FindAnime(fallbackTitleEn);
if (extraResults != null && extraResults.Count > 0)
{
searchResults = searchResults
.Concat(extraResults)
.GroupBy(a => a.Id)
.Select(g => g.First())
.ToList();
}
}
}
if (!string.IsNullOrEmpty(imdb_id)) if (!string.IsNullOrEmpty(imdb_id))
{ {
var seasons = searchResults.Where(a => a.ImdbId == imdb_id).ToList(); var seasons = searchResults.Where(a => a.ImdbId == imdb_id).ToList();
@ -74,7 +91,7 @@ namespace AnimeON
return seasons; return seasons;
} }
} }
// Fallback to first result if no imdb match // Fallback to first result if no imdb match
var firstResult = searchResults.FirstOrDefault(); var firstResult = searchResults.FirstOrDefault();
if (firstResult != null) if (firstResult != null)

View File

@ -39,7 +39,7 @@ namespace AnimeON.Controllers
var invoke = new AnimeONInvoke(init, hybridCache, OnLog, proxyManager); var invoke = new AnimeONInvoke(init, hybridCache, OnLog, proxyManager);
OnLog($"AnimeON Index: title={title}, original_title={original_title}, serial={serial}, s={s}, t={t}, year={year}, imdb_id={imdb_id}, kp={kinopoisk_id}"); OnLog($"AnimeON Index: title={title}, original_title={original_title}, serial={serial}, s={s}, t={t}, year={year}, imdb_id={imdb_id}, kp={kinopoisk_id}");
var seasons = await invoke.Search(imdb_id, kinopoisk_id, title, original_title, year); var seasons = await invoke.Search(imdb_id, kinopoisk_id, title, original_title, year, serial);
OnLog($"AnimeON: search results = {seasons?.Count ?? 0}"); OnLog($"AnimeON: search results = {seasons?.Count ?? 0}");
if (seasons == null || seasons.Count == 0) if (seasons == null || seasons.Count == 0)
return OnError("animeon", proxyManager); return OnError("animeon", proxyManager);
@ -102,17 +102,29 @@ namespace AnimeON.Controllers
return OnError("animeon", proxyManager); return OnError("animeon", proxyManager);
OnLog($"AnimeON: voices found = {structure.Voices.Count}"); OnLog($"AnimeON: voices found = {structure.Voices.Count}");
var voiceItems = structure.Voices
.Select(v =>
{
string display = v.Value?.DisplayName;
if (string.IsNullOrWhiteSpace(display))
display = v.Key;
if (string.IsNullOrWhiteSpace(display))
display = "Озвучка";
return new { Key = v.Key, Display = display };
})
.ToList();
// Автовибір першої озвучки якщо t не задано // Автовибір першої озвучки якщо t не задано
if (string.IsNullOrEmpty(t)) if (string.IsNullOrEmpty(t))
t = structure.Voices.Keys.First(); t = voiceItems.First().Key;
// Формуємо список озвучок // Формуємо список озвучок
var voice_tpl = new VoiceTpl(); var voice_tpl = new VoiceTpl();
foreach (var voice in structure.Voices) foreach (var voice in voiceItems)
{ {
string voiceLink = $"{host}/animeon?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={s}&t={HttpUtility.UrlEncode(voice.Key)}"; string voiceLink = $"{host}/animeon?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={s}&t={HttpUtility.UrlEncode(voice.Key)}";
bool isActive = voice.Key == t; bool isActive = voice.Key == t;
voice_tpl.Append(voice.Key, isActive, voiceLink); voice_tpl.Append(voice.Display, isActive, voiceLink);
} }
// Перевірка вибраної озвучки // Перевірка вибраної озвучки