using System; using System.Collections.Generic; using System.Linq; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; using LME.UAKino.Models; using HtmlAgilityPack; using Shared; using Shared.Engine; using Shared.Models; using Shared.Models.Online.Settings; namespace LME.UAKino { public class UAKinoInvoke { private readonly OnlinesSettings _init; private readonly IHybridCache _hybridCache; private readonly Action _onLog; private readonly ProxyManager _proxyManager; private readonly HttpHydra _httpHydra; public UAKinoInvoke(OnlinesSettings init, IHybridCache hybridCache, Action onLog, ProxyManager proxyManager, HttpHydra httpHydra = null) { _init = init; _hybridCache = hybridCache; _onLog = onLog; _proxyManager = proxyManager; _httpHydra = httpHydra; } public async Task> Search(string title, string original_title, int year, string imdb_id) { string query = BuildSearchQuery(title, original_title, imdb_id); if (string.IsNullOrEmpty(query)) return null; string memKey = $"UAKino:search:{query}"; if (_hybridCache.TryGetValue(memKey, out List cached)) return cached; try { _onLog?.Invoke($"UAKino search: {query}"); string url = $"{_init.host}/engine/lazydev/dle_search/ajax.php"; string body = $"story={HttpUtility.UrlEncode(query)}&thisUrl=/ua/"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.3 Safari/605.1.15"), new HeadersModel("Referer", $"{_init.host}/ua/"), new HeadersModel("X-Requested-With", "XMLHttpRequest"), new HeadersModel("Origin", _init.host), new HeadersModel("Accept", "*/*"), new HeadersModel("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") }; string json = await Http.Post(_init.cors(url), body, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(json)) return null; using var jsonDoc = JsonDocument.Parse(json); if (!jsonDoc.RootElement.TryGetProperty("content", out JsonElement contentElem)) return null; string html = contentElem.GetString(); if (string.IsNullOrEmpty(html)) return null; var htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(html); var rawItems = ParseRawItems(htmlDoc); var results = GroupByShow(rawItems); if (results.Count > 0) _hybridCache.Set(memKey, results, cacheTime(20)); return results; } catch (Exception ex) { _onLog?.Invoke($"UAKino search error: {ex.Message}"); return null; } } /// /// Отримати плейлист (озвучки + епізоди) за news_id /// public async Task> GetPlaylist(string newsId) { if (string.IsNullOrEmpty(newsId)) return null; string memKey = $"UAKino:playlist:{newsId}"; if (_hybridCache.TryGetValue(memKey, out List cached)) return cached; try { _onLog?.Invoke($"UAKino playlist: {newsId}"); string url = $"{_init.host}/engine/ajax/playlists.php?news_id={newsId}&xfield=playlist"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.3 Safari/605.1.15"), new HeadersModel("Referer", $"{_init.host}/{newsId}-"), new HeadersModel("X-Requested-With", "XMLHttpRequest"), new HeadersModel("Accept", "application/json, text/javascript, */*; q=0.01") }; string json = await HttpGet(url, headers); if (string.IsNullOrEmpty(json)) return null; using var jsonDoc = JsonDocument.Parse(json); if (!jsonDoc.RootElement.TryGetProperty("response", out JsonElement responseElem)) return null; string html = responseElem.GetString(); if (string.IsNullOrEmpty(html)) return null; var voices = ParsePlaylistHtml(html); if (voices.Count > 0) _hybridCache.Set(memKey, voices, cacheTime(30)); return voices; } catch (Exception ex) { _onLog?.Invoke($"UAKino playlist error: {ex.Message}"); return null; } } /// /// Fallback: отримати стрім з HTML сторінки фільму коли playlist API недоступний /// Парсить <link itemprop="video" value="..."> або <iframe id="pre" src="..."> /// public async Task GetPageFallbackUrl(string pageUrl) { if (string.IsNullOrEmpty(pageUrl)) return null; try { _onLog?.Invoke($"UAKino page fallback: {pageUrl}"); var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.3 Safari/605.1.15"), new HeadersModel("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"), new HeadersModel("Referer", _init.host) }; string html = await HttpGet(pageUrl, headers); if (string.IsNullOrEmpty(html)) return null; var doc = new HtmlDocument(); doc.LoadHtml(html); // Спершу пробуємо var linkTag = doc.DocumentNode.SelectSingleNode("//link[@itemprop='video']"); if (linkTag != null) { string value = linkTag.GetAttributeValue("value", ""); if (!string.IsNullOrEmpty(value)) return NormalizeUrl(value); } // Fallback до