mirror of
https://github.com/lampame/lampac-ukraine.git
synced 2026-06-17 12:08:54 +00:00
refactor(uakino): restructure search results into grouped season entries
Replace flat search result handling with a grouped model where each show contains a list of season entries, enabling deterministic serial flow for single-show and multi-season matches. Update controller logic to branch serial/movie processing against grouped results, add explicit season selection handling, and reuse selected season URLs on follow-up requests. Adjust search parsing to collect raw items, filter non-content entries, and group by normalized show identity before caching, removing early year-based filtering from cached returns.
This commit is contained in:
parent
317cb6292c
commit
a54bc0e435
@ -51,30 +51,46 @@ namespace LME.UAKino.Controllers
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(itemUrl))
|
if (string.IsNullOrEmpty(itemUrl))
|
||||||
{
|
{
|
||||||
|
// === ПЕРШИЙ ЗАПИТ: пошук ===
|
||||||
var searchResults = await invoke.Search(title, original_title, year, imdb_id);
|
var searchResults = await invoke.Search(title, original_title, year, imdb_id);
|
||||||
if (searchResults == null || searchResults.Count == 0)
|
if (searchResults == null || searchResults.Count == 0)
|
||||||
return OnError("lme_uakino", refresh_proxy: true);
|
return OnError("lme_uakino", refresh_proxy: true);
|
||||||
|
|
||||||
// Якщо кілька результатів — дозволяємо обрати
|
if (serial == 1)
|
||||||
if (searchResults.Count > 1)
|
|
||||||
{
|
{
|
||||||
var similar_tpl = new SimilarTpl(searchResults.Count);
|
// Серіал
|
||||||
foreach (var res in searchResults)
|
if (searchResults.Count == 1)
|
||||||
{
|
{
|
||||||
string link = $"{host}/lite/lme_uakino?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(res.Url)}";
|
var sr = searchResults[0];
|
||||||
similar_tpl.Append(res.Title, res.Year?.ToString() ?? "", res.OriginalTitle ?? "", link, res.Poster);
|
if (sr.Seasons.Count > 1 && s == -1)
|
||||||
|
{
|
||||||
|
// Кілька сезонів — показуємо SeasonTpl для вибору
|
||||||
|
return HandleSeasonSelection(sr, id, imdb_id, kinopoisk_id, title, original_title, year, rjson);
|
||||||
|
}
|
||||||
|
// Один сезон — використовуємо його
|
||||||
|
itemUrl = sr.Seasons[0].Url;
|
||||||
|
newsId = sr.Seasons[0].NewsId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Кілька різних шоу — обирає
|
||||||
|
return ShowSimilarTpl(searchResults, id, imdb_id, kinopoisk_id, title, original_title, year, serial, rjson);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rjson
|
|
||||||
? Content(similar_tpl.ToJson(), "application/json; charset=utf-8")
|
|
||||||
: Content(similar_tpl.ToHtml(), "text/html; charset=utf-8");
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
itemUrl = searchResults[0].Url;
|
{
|
||||||
newsId = searchResults[0].NewsId;
|
// Фільм
|
||||||
|
if (searchResults.Count > 1)
|
||||||
|
{
|
||||||
|
return ShowSimilarTpl(searchResults, id, imdb_id, kinopoisk_id, title, original_title, year, serial, rjson);
|
||||||
|
}
|
||||||
|
itemUrl = searchResults[0].Seasons[0].Url;
|
||||||
|
newsId = searchResults[0].Seasons[0].NewsId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Повторний запит (з селектора сезонів або озвучок)
|
||||||
newsId = UAKinoInvoke.ExtractNewsId(itemUrl);
|
newsId = UAKinoInvoke.ExtractNewsId(itemUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +103,7 @@ namespace LME.UAKino.Controllers
|
|||||||
|
|
||||||
if (serial == 1)
|
if (serial == 1)
|
||||||
{
|
{
|
||||||
return HandleSerial(init, voices, title, original_title, year, imdb_id, kinopoisk_id, itemUrl, t, rjson);
|
return HandleSerial(init, voices, title, original_title, imdb_id, kinopoisk_id, itemUrl, s, t, rjson);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -95,7 +111,40 @@ namespace LME.UAKino.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ActionResult HandleSerial(OnlinesSettings init, List<VoiceGroup> voices, string title, string original_title, int year, string imdb_id, long kinopoisk_id, string itemUrl, string t, bool rjson)
|
/// <summary>Вибір сезону для багатосезонного серіалу</summary>
|
||||||
|
private ActionResult HandleSeasonSelection(SearchResult sr, long id, string imdb_id, long kinopoisk_id, string title, string original_title, int year, bool rjson)
|
||||||
|
{
|
||||||
|
var season_tpl = new SeasonTpl(sr.Seasons.Count);
|
||||||
|
foreach (var season in sr.Seasons)
|
||||||
|
{
|
||||||
|
string link = $"{host}/lite/lme_uakino?id={id}&imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={season.SeasonNumber}&href={HttpUtility.UrlEncode(season.Url)}";
|
||||||
|
season_tpl.Append($"Сезон {season.SeasonNumber}", link, season.SeasonNumber.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return rjson
|
||||||
|
? Content(season_tpl.ToJson(), "application/json; charset=utf-8")
|
||||||
|
: Content(season_tpl.ToHtml(), "text/html; charset=utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Вибір між різними шоу/фільмами</summary>
|
||||||
|
private ActionResult ShowSimilarTpl(List<SearchResult> searchResults, long id, string imdb_id, long kinopoisk_id, string title, string original_title, int year, int serial, bool rjson)
|
||||||
|
{
|
||||||
|
var similar_tpl = new SimilarTpl(searchResults.Count);
|
||||||
|
foreach (var res in searchResults)
|
||||||
|
{
|
||||||
|
string seasonUrl = res.Seasons.Count > 0 ? res.Seasons[0].Url : "";
|
||||||
|
string yearStr = res.Seasons.Count > 0 ? (res.Seasons[0].Year?.ToString() ?? "") : (res.Year?.ToString() ?? "");
|
||||||
|
string link = $"{host}/lite/lme_uakino?id={id}&imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(seasonUrl)}";
|
||||||
|
similar_tpl.Append(res.Title, yearStr, res.OriginalTitle ?? "", link, res.Poster);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rjson
|
||||||
|
? Content(similar_tpl.ToJson(), "application/json; charset=utf-8")
|
||||||
|
: Content(similar_tpl.ToHtml(), "text/html; charset=utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Серіал: озвучки + епізоди</summary>
|
||||||
|
private ActionResult HandleSerial(OnlinesSettings init, List<VoiceGroup> voices, string title, string original_title, string imdb_id, long kinopoisk_id, string itemUrl, int s, string t, bool rjson)
|
||||||
{
|
{
|
||||||
var voice_tpl = new VoiceTpl();
|
var voice_tpl = new VoiceTpl();
|
||||||
var episode_tpl = new EpisodeTpl();
|
var episode_tpl = new EpisodeTpl();
|
||||||
@ -105,7 +154,7 @@ namespace LME.UAKino.Controllers
|
|||||||
|
|
||||||
foreach (var voice in voices)
|
foreach (var voice in voices)
|
||||||
{
|
{
|
||||||
string voiceLink = $"{host}/lite/lme_uakino?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&t={voice.DataId}&href={HttpUtility.UrlEncode(itemUrl)}";
|
string voiceLink = $"{host}/lite/lme_uakino?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&serial=1&s={s}&t={voice.DataId}&href={HttpUtility.UrlEncode(itemUrl)}";
|
||||||
voice_tpl.Append(voice.Name, voice.DataId == t, voiceLink);
|
voice_tpl.Append(voice.Name, voice.DataId == t, voiceLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +177,7 @@ namespace LME.UAKino.Controllers
|
|||||||
: Content(episode_tpl.ToHtml(), "text/html; charset=utf-8");
|
: Content(episode_tpl.ToHtml(), "text/html; charset=utf-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Фільм: список стрімів</summary>
|
||||||
private ActionResult HandleMovie(OnlinesSettings init, List<VoiceGroup> voices, string title, string original_title, bool rjson)
|
private ActionResult HandleMovie(OnlinesSettings init, List<VoiceGroup> voices, string title, string original_title, bool rjson)
|
||||||
{
|
{
|
||||||
var movie_tpl = new MovieTpl(title, original_title);
|
var movie_tpl = new MovieTpl(title, original_title);
|
||||||
|
|||||||
@ -6,10 +6,19 @@ namespace LME.UAKino.Models
|
|||||||
{
|
{
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string OriginalTitle { get; set; }
|
public string OriginalTitle { get; set; }
|
||||||
public string Url { get; set; }
|
|
||||||
public string Poster { get; set; }
|
public string Poster { get; set; }
|
||||||
|
/// <summary>Сезони серіалу. Для фільмів — один елемент без SeasonNumber</summary>
|
||||||
|
public List<SeasonEntry> Seasons { get; set; } = new();
|
||||||
|
/// <summary>Рік фільму (тільки для не-сезонних результатів)</summary>
|
||||||
public int? Year { get; set; }
|
public int? Year { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SeasonEntry
|
||||||
|
{
|
||||||
|
public int SeasonNumber { get; set; }
|
||||||
public string NewsId { get; set; }
|
public string NewsId { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public int? Year { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VoiceGroup
|
public class VoiceGroup
|
||||||
|
|||||||
@ -39,7 +39,7 @@ namespace LME.UAKino
|
|||||||
|
|
||||||
string memKey = $"UAKino:search:{query}";
|
string memKey = $"UAKino:search:{query}";
|
||||||
if (_hybridCache.TryGetValue(memKey, out List<SearchResult> cached))
|
if (_hybridCache.TryGetValue(memKey, out List<SearchResult> cached))
|
||||||
return FilterByYear(cached, year);
|
return cached;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -73,11 +73,13 @@ namespace LME.UAKino
|
|||||||
var htmlDoc = new HtmlDocument();
|
var htmlDoc = new HtmlDocument();
|
||||||
htmlDoc.LoadHtml(html);
|
htmlDoc.LoadHtml(html);
|
||||||
|
|
||||||
var results = ParseSearchResults(htmlDoc);
|
var rawItems = ParseRawItems(htmlDoc);
|
||||||
|
var results = GroupByShow(rawItems);
|
||||||
|
|
||||||
if (results.Count > 0)
|
if (results.Count > 0)
|
||||||
_hybridCache.Set(memKey, results, cacheTime(20));
|
_hybridCache.Set(memKey, results, cacheTime(20));
|
||||||
|
|
||||||
return FilterByYear(results, year);
|
return results;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -152,12 +154,25 @@ namespace LME.UAKino
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SearchResult> ParseSearchResults(HtmlDocument doc)
|
// ===================== Парсинг результатів пошуку =====================
|
||||||
|
|
||||||
|
/// <summary>Сирий елемент з HTML пошуку, до групування</summary>
|
||||||
|
private class RawSearchItem
|
||||||
{
|
{
|
||||||
var results = new List<SearchResult>();
|
public string Title { get; set; }
|
||||||
|
public string OriginalTitle { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public string Poster { get; set; }
|
||||||
|
public int? Year { get; set; }
|
||||||
|
public string NewsId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<RawSearchItem> ParseRawItems(HtmlDocument doc)
|
||||||
|
{
|
||||||
|
var items = new List<RawSearchItem>();
|
||||||
var nodes = doc.DocumentNode.SelectNodes("//a[@class='search-result-link']");
|
var nodes = doc.DocumentNode.SelectNodes("//a[@class='search-result-link']");
|
||||||
if (nodes == null)
|
if (nodes == null)
|
||||||
return results;
|
return items;
|
||||||
|
|
||||||
foreach (var node in nodes)
|
foreach (var node in nodes)
|
||||||
{
|
{
|
||||||
@ -186,9 +201,13 @@ namespace LME.UAKino
|
|||||||
year = parsedYear;
|
year = parsedYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Фільтр: пропускаємо новини/трейлери — без року та без оригінальної назви
|
||||||
|
if (!IsRealContent(title, origTitle, year))
|
||||||
|
continue;
|
||||||
|
|
||||||
string newsId = ExtractNewsId(href);
|
string newsId = ExtractNewsId(href);
|
||||||
|
|
||||||
results.Add(new SearchResult
|
items.Add(new RawSearchItem
|
||||||
{
|
{
|
||||||
Title = title,
|
Title = title,
|
||||||
OriginalTitle = origTitle,
|
OriginalTitle = origTitle,
|
||||||
@ -204,9 +223,121 @@ namespace LME.UAKino
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Фільтр: реальний контент (не новина/трейлер)</summary>
|
||||||
|
private static bool IsRealContent(string title, string origTitle, int? year)
|
||||||
|
{
|
||||||
|
// Є рік — контент
|
||||||
|
if (year.HasValue)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Є оригінальна назва — контент
|
||||||
|
if (!string.IsNullOrEmpty(origTitle))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Дуже довга назва без року — скоріше новина
|
||||||
|
if (!string.IsNullOrEmpty(title) && title.Length > 50)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Групування сирих елементів по назві шоу. Кожна група = один SearchResult зі списком сезонів</summary>
|
||||||
|
private List<SearchResult> GroupByShow(List<RawSearchItem> rawItems)
|
||||||
|
{
|
||||||
|
if (rawItems.Count == 0)
|
||||||
|
return new List<SearchResult>();
|
||||||
|
|
||||||
|
var groups = new Dictionary<string, List<RawSearchItem>>();
|
||||||
|
|
||||||
|
foreach (var item in rawItems)
|
||||||
|
{
|
||||||
|
string cleanTitle = CleanShowTitle(item.Title);
|
||||||
|
string key = $"{cleanTitle.ToLowerInvariant()}|{(item.OriginalTitle ?? "").ToLowerInvariant()}";
|
||||||
|
|
||||||
|
if (!groups.ContainsKey(key))
|
||||||
|
groups[key] = new List<RawSearchItem>();
|
||||||
|
|
||||||
|
groups[key].Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
var results = new List<SearchResult>();
|
||||||
|
|
||||||
|
foreach (var kvp in groups)
|
||||||
|
{
|
||||||
|
var items = kvp.Value;
|
||||||
|
var first = items[0];
|
||||||
|
string showTitle = CleanShowTitle(first.Title);
|
||||||
|
|
||||||
|
var sr = new SearchResult
|
||||||
|
{
|
||||||
|
Title = showTitle,
|
||||||
|
OriginalTitle = first.OriginalTitle,
|
||||||
|
Poster = first.Poster
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
int? seasonNum = ExtractSeasonNumber(item.Title);
|
||||||
|
if (seasonNum.HasValue)
|
||||||
|
{
|
||||||
|
sr.Seasons.Add(new SeasonEntry
|
||||||
|
{
|
||||||
|
SeasonNumber = seasonNum.Value,
|
||||||
|
NewsId = item.NewsId,
|
||||||
|
Url = item.Url,
|
||||||
|
Year = item.Year
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Фільм або контент без сезону
|
||||||
|
sr.Seasons.Add(new SeasonEntry
|
||||||
|
{
|
||||||
|
SeasonNumber = 1,
|
||||||
|
NewsId = item.NewsId,
|
||||||
|
Url = item.Url,
|
||||||
|
Year = item.Year
|
||||||
|
});
|
||||||
|
sr.Year = item.Year;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сортуємо сезони за номером
|
||||||
|
sr.Seasons = sr.Seasons.OrderBy(s => s.SeasonNumber).ToList();
|
||||||
|
|
||||||
|
results.Add(sr);
|
||||||
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Витягти чисту назву шоу (без "N сезон" суфіксу)</summary>
|
||||||
|
private static string CleanShowTitle(string title)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(title))
|
||||||
|
return title;
|
||||||
|
|
||||||
|
return Regex.Replace(title, @"\s*\d+\s*сезон\s*$", "", RegexOptions.IgnoreCase).Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Витягти номер сезону з назви</summary>
|
||||||
|
private static int? ExtractSeasonNumber(string title)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(title))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var match = Regex.Match(title, @"(\d+)\s*сезон", RegexOptions.IgnoreCase);
|
||||||
|
if (match.Success && int.TryParse(match.Groups[1].Value, out int num))
|
||||||
|
return num;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================== Парсинг плейлиста =====================
|
||||||
|
|
||||||
private List<VoiceGroup> ParsePlaylistHtml(string html)
|
private List<VoiceGroup> ParsePlaylistHtml(string html)
|
||||||
{
|
{
|
||||||
var voices = new List<VoiceGroup>();
|
var voices = new List<VoiceGroup>();
|
||||||
@ -217,7 +348,6 @@ namespace LME.UAKino
|
|||||||
var playerDiv = doc.DocumentNode.SelectSingleNode("//div[@class='playlists-player']");
|
var playerDiv = doc.DocumentNode.SelectSingleNode("//div[@class='playlists-player']");
|
||||||
if (playerDiv == null)
|
if (playerDiv == null)
|
||||||
{
|
{
|
||||||
// спроба знайти епізоди без обгортки playlists-player
|
|
||||||
return ParseEpisodesFlat(doc.DocumentNode);
|
return ParseEpisodesFlat(doc.DocumentNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +359,6 @@ namespace LME.UAKino
|
|||||||
{
|
{
|
||||||
string dataId = li.GetAttributeValue("data-id", "");
|
string dataId = li.GetAttributeValue("data-id", "");
|
||||||
string text = CleanText(li.InnerText);
|
string text = CleanText(li.InnerText);
|
||||||
// Прибираємо "(X-Y)" з кінця назви озвучки
|
|
||||||
string voiceName = Regex.Replace(text, @"\s*\(\d+[\d,\s-]*\)\s*$", "").Trim();
|
string voiceName = Regex.Replace(text, @"\s*\(\d+[\d,\s-]*\)\s*$", "").Trim();
|
||||||
if (string.IsNullOrEmpty(voiceName))
|
if (string.IsNullOrEmpty(voiceName))
|
||||||
voiceName = text;
|
voiceName = text;
|
||||||
@ -257,19 +386,15 @@ namespace LME.UAKino
|
|||||||
string voiceAttr = li.GetAttributeValue("data-voice", "");
|
string voiceAttr = li.GetAttributeValue("data-voice", "");
|
||||||
string text = CleanText(li.InnerText);
|
string text = CleanText(li.InnerText);
|
||||||
|
|
||||||
// Визначаємо до якого voice групи належить
|
|
||||||
VoiceGroup targetVoice = null;
|
VoiceGroup targetVoice = null;
|
||||||
|
|
||||||
// Спершу за data-id
|
|
||||||
if (!string.IsNullOrEmpty(dataId))
|
if (!string.IsNullOrEmpty(dataId))
|
||||||
targetVoice = voices.FirstOrDefault(v => v.DataId == dataId);
|
targetVoice = voices.FirstOrDefault(v => v.DataId == dataId);
|
||||||
|
|
||||||
// Якщо не знайшли, то за data-voice (назвою)
|
|
||||||
if (targetVoice == null && !string.IsNullOrEmpty(voiceAttr))
|
if (targetVoice == null && !string.IsNullOrEmpty(voiceAttr))
|
||||||
targetVoice = voices.FirstOrDefault(v =>
|
targetVoice = voices.FirstOrDefault(v =>
|
||||||
v.Name.Equals(voiceAttr, StringComparison.OrdinalIgnoreCase));
|
v.Name.Equals(voiceAttr, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
// Якщо досі не знайшли, беремо перший голос
|
|
||||||
targetVoice ??= voices.FirstOrDefault();
|
targetVoice ??= voices.FirstOrDefault();
|
||||||
|
|
||||||
int? epNum = ExtractEpisodeNumber(text);
|
int? epNum = ExtractEpisodeNumber(text);
|
||||||
@ -289,9 +414,6 @@ namespace LME.UAKino
|
|||||||
return voices;
|
return voices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Парсинг коли немає структури playlists-player (наприклад для фільмів)
|
|
||||||
/// </summary>
|
|
||||||
private List<VoiceGroup> ParseEpisodesFlat(HtmlNode scope)
|
private List<VoiceGroup> ParseEpisodesFlat(HtmlNode scope)
|
||||||
{
|
{
|
||||||
var voices = new List<VoiceGroup>();
|
var voices = new List<VoiceGroup>();
|
||||||
@ -309,7 +431,6 @@ namespace LME.UAKino
|
|||||||
foreach (var li in items)
|
foreach (var li in items)
|
||||||
{
|
{
|
||||||
string fileUrl = li.GetAttributeValue("data-file", "");
|
string fileUrl = li.GetAttributeValue("data-file", "");
|
||||||
string voiceAttr = li.GetAttributeValue("data-voice", "");
|
|
||||||
string text = CleanText(li.InnerText);
|
string text = CleanText(li.InnerText);
|
||||||
int? epNum = ExtractEpisodeNumber(text);
|
int? epNum = ExtractEpisodeNumber(text);
|
||||||
|
|
||||||
@ -327,6 +448,8 @@ namespace LME.UAKino
|
|||||||
return voices;
|
return voices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===================== Допоміжні методи =====================
|
||||||
|
|
||||||
private static string BuildSearchQuery(string title, string original_title, string imdb_id)
|
private static string BuildSearchQuery(string title, string original_title, string imdb_id)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(imdb_id) && imdb_id.StartsWith("tt"))
|
if (!string.IsNullOrEmpty(imdb_id) && imdb_id.StartsWith("tt"))
|
||||||
@ -341,18 +464,6 @@ namespace LME.UAKino
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<SearchResult> FilterByYear(List<SearchResult> results, int year)
|
|
||||||
{
|
|
||||||
if (results == null || results.Count <= 1 || year <= 0)
|
|
||||||
return results;
|
|
||||||
|
|
||||||
var yearMatch = results.Where(r => r.Year == year).ToList();
|
|
||||||
if (yearMatch.Count > 0)
|
|
||||||
return yearMatch;
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string NormalizeUrl(string url)
|
private string NormalizeUrl(string url)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(url))
|
if (string.IsNullOrEmpty(url))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user