mirror of
https://github.com/lampame/lampac-ukraine.git
synced 2026-06-17 12:08:54 +00:00
Compare commits
4 Commits
3ee62e24f6
...
0189cb929c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0189cb929c | ||
|
|
b6c9c748cd | ||
|
|
ddcbc3eae8 | ||
|
|
e695121444 |
@ -19,5 +19,12 @@ namespace LME.Uaflix.Models
|
||||
/// Перший елемент відповідає iframeUrl, наступні — додаткові плеєри (напр. з субтитрами)
|
||||
/// </summary>
|
||||
public List<string> zetvideoIframeUrls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Епізод позначено як «Прем'єра» (ще не вийшов) на сторінці сезону.
|
||||
/// У таких епізодів у vi-desc → vi-title зазначено "Прем'єра. ДД.ММ.РРРР".
|
||||
/// ProbeSeasonPlayer не робитиме зайвого HTTP-запиту для таких епізодів.
|
||||
/// </summary>
|
||||
public bool IsPremiere { get; set; }
|
||||
}
|
||||
}
|
||||
@ -361,6 +361,14 @@ namespace LME.Uaflix
|
||||
if (episode == null || string.IsNullOrWhiteSpace(episode.url))
|
||||
continue;
|
||||
|
||||
// Пропускаємо епізоди, позначені як «Прем'єра» — вони ще не вийшли,
|
||||
// робити зайвий HTTP-запит на сторінку епізоду не потрібно.
|
||||
if (episode.IsPremiere)
|
||||
{
|
||||
_onLog($"ProbeSeasonPlayer: Пропускаю епізод {episode.episode} — позначено як прем'єра");
|
||||
continue;
|
||||
}
|
||||
|
||||
var probed = await ProbeEpisodePlayer(episode.url);
|
||||
if (probed == null)
|
||||
continue;
|
||||
@ -425,6 +433,17 @@ namespace LME.Uaflix
|
||||
if (structure == null || string.IsNullOrWhiteSpace(playerType) || seasonEpisodes == null || seasonEpisodes.Count == 0)
|
||||
return;
|
||||
|
||||
// Відфільтровуємо епізоди, що ще не вийшли (позначені як «Прем'єра»)
|
||||
var availableEpisodes = seasonEpisodes.Where(e => !e.IsPremiere).ToList();
|
||||
int filteredCount = seasonEpisodes.Count - availableEpisodes.Count;
|
||||
if (filteredCount > 0)
|
||||
_onLog($"AddVodSeasonEpisodes: Відфільтровано {filteredCount} прем'єрних епізодів із сезону {season}");
|
||||
if (availableEpisodes.Count == 0)
|
||||
{
|
||||
_onLog($"AddVodSeasonEpisodes: Усі епізоди сезону {season} є прем'єрами, пропускаю");
|
||||
return;
|
||||
}
|
||||
|
||||
string displayName = playerType == "ashdi-vod" ? "Uaflix #3" : "Uaflix #2";
|
||||
if (!structure.Voices.ContainsKey(displayName))
|
||||
{
|
||||
@ -437,7 +456,7 @@ namespace LME.Uaflix
|
||||
};
|
||||
}
|
||||
|
||||
var episodes = seasonEpisodes
|
||||
var episodes = availableEpisodes
|
||||
.OrderBy(ep => ep.episode)
|
||||
.Select(ep => new EpisodeInfo
|
||||
{
|
||||
@ -1084,13 +1103,28 @@ namespace LME.Uaflix
|
||||
parsedEpisode = episodeFromUrl;
|
||||
}
|
||||
|
||||
episodes.Add(new EpisodeLinkInfo
|
||||
var episode = new EpisodeLinkInfo
|
||||
{
|
||||
url = episodeUrl,
|
||||
title = episodeNode.SelectSingleNode(".//div[@class='vi-rate']")?.InnerText.Trim() ?? $"Епізод {parsedEpisode}",
|
||||
season = parsedSeason,
|
||||
episode = parsedEpisode
|
||||
});
|
||||
};
|
||||
|
||||
// Перевірка на «Прем'єра» — епізод ще не вийшов, плеєра немає
|
||||
var viDesc = episodeNode.SelectSingleNode(".//div[contains(@class, 'vi-desc')]");
|
||||
if (viDesc != null)
|
||||
{
|
||||
var viTitle = viDesc.SelectSingleNode(".//div[contains(@class, 'vi-title')]");
|
||||
string descText = viTitle?.InnerText?.Trim() ?? string.Empty;
|
||||
if (descText.IndexOf("Прем'єра", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
episode.IsPremiere = true;
|
||||
_onLog($"ParseSeasonEpisodesFromHtml: Серія {parsedEpisode} позначена як прем'єра: '{descText}'");
|
||||
}
|
||||
}
|
||||
|
||||
episodes.Add(episode);
|
||||
|
||||
fallbackEpisode = Math.Max(fallbackEpisode, parsedEpisode + 1);
|
||||
}
|
||||
@ -1107,8 +1141,8 @@ namespace LME.Uaflix
|
||||
if (season < 0)
|
||||
return null;
|
||||
|
||||
// v2 — зміна кеш-ключа для інвалідації старих структур без multi-voice
|
||||
string memKey = $"lme_uaflix:season-structure-v2:{serialUrl}:{season}";
|
||||
// v3 — інвалідація старих структур, що містили прем'єрні серії
|
||||
string memKey = $"lme_uaflix:season-structure-v3:{serialUrl}:{season}";
|
||||
if (_hybridCache.TryGetValue(memKey, out SerialAggregatedStructure cached))
|
||||
{
|
||||
_onLog($"GetSeasonStructure: Using cached structure for season={season}, url={serialUrl}");
|
||||
@ -1175,13 +1209,24 @@ namespace LME.Uaflix
|
||||
}
|
||||
else if (seasonProbe.PlayerType == "ashdi-vod" || seasonProbe.PlayerType == "zetvideo-vod")
|
||||
{
|
||||
// Відфільтровуємо прем'єрні епізоди (ще не вийшли) перед додаванням у структуру
|
||||
var seasonAvailable = seasonEpisodes.Where(e => !e.IsPremiere).ToList();
|
||||
int filteredCount = seasonEpisodes.Count - seasonAvailable.Count;
|
||||
if (filteredCount > 0)
|
||||
_onLog($"GetSeasonStructure: Відфільтровано {filteredCount} прем'єрних епізодів із сезону {season}");
|
||||
if (seasonAvailable.Count == 0)
|
||||
{
|
||||
_onLog($"GetSeasonStructure: Усі епізоди сезону {season} є прем'єрами, повертаю null");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Створюємо базовий голос (перший плеєр)
|
||||
AddVodSeasonEpisodes(structure, seasonProbe.PlayerType, season, seasonEpisodes);
|
||||
AddVodSeasonEpisodes(structure, seasonProbe.PlayerType, season, seasonAvailable);
|
||||
|
||||
// Якщо є додаткові zetvideo плеєри — створюємо окремий голос для кожного
|
||||
if (seasonEpisodes != null && seasonEpisodes.Count > 0)
|
||||
if (seasonAvailable.Count > 0)
|
||||
{
|
||||
var firstEp = seasonEpisodes.FirstOrDefault(e => e.zetvideoIframeUrls != null && e.zetvideoIframeUrls.Count > 1);
|
||||
var firstEp = seasonAvailable.FirstOrDefault(e => e.zetvideoIframeUrls != null && e.zetvideoIframeUrls.Count > 1);
|
||||
if (firstEp != null)
|
||||
{
|
||||
// Додаткові плеєри починаються з індексу 1
|
||||
@ -1190,7 +1235,7 @@ namespace LME.Uaflix
|
||||
string extraVoiceName = GetZetvideoVoiceName(extraIdx);
|
||||
_onLog($"GetSeasonStructure: створюю додатковий голос '{extraVoiceName}' для zetvideo плеєра #{extraIdx + 1}");
|
||||
|
||||
var extraEpisodes = seasonEpisodes
|
||||
var extraEpisodes = seasonAvailable
|
||||
.OrderBy(ep => ep.episode)
|
||||
.Select(ep => new EpisodeInfo
|
||||
{
|
||||
@ -1955,13 +2000,28 @@ namespace LME.Uaflix
|
||||
var match = Regex.Match(episodeUrl, @"season-(\d+).*?episode-(\d+)");
|
||||
if (match.Success)
|
||||
{
|
||||
allEpisodes.Add(new EpisodeLinkInfo
|
||||
var ep = new EpisodeLinkInfo
|
||||
{
|
||||
url = episodeUrl,
|
||||
title = episodeNode.SelectSingleNode(".//div[@class='vi-rate']")?.InnerText.Trim() ?? $"Епізод {match.Groups[2].Value}",
|
||||
season = int.Parse(match.Groups[1].Value),
|
||||
episode = int.Parse(match.Groups[2].Value)
|
||||
});
|
||||
};
|
||||
|
||||
// Перевірка на «Прем'єра» — епізод ще не вийшов
|
||||
var viDesc = episodeNode.SelectSingleNode(".//div[contains(@class, 'vi-desc')]");
|
||||
if (viDesc != null)
|
||||
{
|
||||
var viTitle = viDesc.SelectSingleNode(".//div[contains(@class, 'vi-title')]");
|
||||
string descText = viTitle?.InnerText?.Trim() ?? string.Empty;
|
||||
if (descText.IndexOf("Прем'єра", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
ep.IsPremiere = true;
|
||||
_onLog($"GetPaginationInfo: Серія {ep.episode} позначена як прем'єра: '{descText}'");
|
||||
}
|
||||
}
|
||||
|
||||
allEpisodes.Add(ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user