using Newtonsoft.Json.Linq; using Shared.Models; using Shared.Models.Base; using Shared.Models.Online.Filmix; using Shared.Models.Online.FilmixTV; using Shared.Models.Templates; using System.Text.Json; using System.Web; namespace Shared.Engine.Online { public class FilmixTVInvoke { #region FilmixTVInvoke string host; string apihost; List bearer; HttpHydra httpHydra; Func onstreamfile; Func onlog; Action requesterror; bool rjson; public FilmixTVInvoke(string host, string apihost, List bearer, HttpHydra httpHydra, Func onstreamfile, Func onlog = null, Action requesterror = null, bool rjson = false) { this.host = host != null ? $"{host}/" : null; this.apihost = apihost; this.bearer = bearer; this.httpHydra = httpHydra; this.onstreamfile = onstreamfile; this.onlog = onlog; this.requesterror = requesterror; this.rjson = rjson; } #endregion #region Search async public Task Search(string title, string original_title, int clarification, int year, bool similar) { if (string.IsNullOrWhiteSpace(title ?? original_title)) return null; string uri = $"{apihost}/api-fx/list?search={HttpUtility.UrlEncode(clarification == 1 ? title : (original_title ?? title))}&limit=48"; onlog?.Invoke(uri); var root = await httpHydra.Get(uri, addheaders: bearer, safety: true); if (root == null || !root.ContainsKey("items")) return await Search2(title, original_title, year, clarification); List items = null; try { items = root["items"].ToObject>(); } catch { } if (items == null || items.Count == 0) return await Search2(title, original_title, year, clarification); var ids = new List(items.Count); var stpl = new SimilarTpl(items.Count); string enc_title = HttpUtility.UrlEncode(title); string enc_original_title = HttpUtility.UrlEncode(original_title); string stitle = StringConvert.SearchName(title); string sorigtitle = StringConvert.SearchName(original_title); foreach (var item in items) { if (item == null) continue; string name = !string.IsNullOrEmpty(item.title) && !string.IsNullOrEmpty(item.original_name) ? $"{item.title} / {item.original_name}" : (item.title ?? item.original_name); stpl.Append(name, item.year.ToString(), string.Empty, host + $"lite/filmixtv?postid={item.id}&title={enc_title}&original_title={enc_original_title}", PosterApi.Size(item.poster)); if ((!string.IsNullOrEmpty(stitle) && StringConvert.SearchName(item.title) == stitle) || (!string.IsNullOrEmpty(sorigtitle) && StringConvert.SearchName(item.original_name) == sorigtitle)) { if (item.year == year) ids.Add(item.id); } } if (ids.Count == 1 && !similar) return new SearchResult() { id = ids[0] }; return new SearchResult() { similars = stpl }; } #endregion #region Search2 async Task Search2(string title, string original_title, int year, int clarification) { var result = await gosearch(clarification == 1 ? original_title : title); if (result == null) result = await gosearch(clarification == 1 ? title : original_title); if (result == null) return null; var ids = new List(result.Count); var stpl = new SimilarTpl(result.Count); string enc_title = HttpUtility.UrlEncode(title); string enc_original_title = HttpUtility.UrlEncode(original_title); string stitle = StringConvert.SearchName(title); string sorigtitle = StringConvert.SearchName(original_title); foreach (var item in result) { if (item == null) continue; string name = !string.IsNullOrEmpty(item.title) && !string.IsNullOrEmpty(item.original_title) ? $"{item.title} / {item.original_title}" : (item.title ?? item.original_title); stpl.Append(name, item.year.ToString(), string.Empty, host + $"lite/filmixtv?postid={item.id}&title={enc_title}&original_title={enc_original_title}", PosterApi.Size(item.poster)); if ((!string.IsNullOrEmpty(stitle) && StringConvert.SearchName(item.title) == stitle) || (!string.IsNullOrEmpty(sorigtitle) && StringConvert.SearchName(item.original_title) == sorigtitle)) { if (item.year == year) ids.Add(item.id); } } if (ids.Count == 1) return new SearchResult() { id = ids[0] }; return new SearchResult() { similars = stpl }; } async Task> gosearch(string story) { if (string.IsNullOrEmpty(story)) return null; string uri = $"{AppInit.conf.Filmix.corsHost()}/api/v2/search?story={HttpUtility.UrlEncode(story)}&user_dev_apk=2.0.1&user_dev_id=&user_dev_name=Xiaomi&user_dev_os=11&user_dev_token=&user_dev_vendor=Xiaomi"; var root = await httpHydra.Get>(uri, addheaders: bearer, safety: true); if (root == null || root.Count == 0) return null; return root; } #endregion #region Post public Models.Online.FilmixTV.RootObject Post(string json) { if (string.IsNullOrWhiteSpace(json)) { requesterror?.Invoke(); return null; } try { var rootMs = new Models.Online.FilmixTV.RootObject(); if (JsonDocument.Parse(json).RootElement.ValueKind == JsonValueKind.Array) { rootMs.Movies = JsonSerializer.Deserialize(json); } else { rootMs.SerialVoice = JsonSerializer.Deserialize>>(json); } return rootMs; } catch { return null; } } #endregion #region Tpl public ITplResult Tpl(Models.Online.FilmixTV.RootObject root, bool pro, int postid, string title, string original_title, int t, int? s, VastConf vast = null) { if (root == null) return default; #region Сериал if (root.SerialVoice != null) { string enc_title = HttpUtility.UrlEncode(title); string enc_original_title = HttpUtility.UrlEncode(original_title); if (s == null) { #region Сезоны var maxQuality = root.SerialVoice.SelectMany(i => i.Value) .SelectMany(season => season.Value.episodes) .SelectMany(episode => episode.Value.files) .Max(file => file.quality); var tpl = new SeasonTpl($"{maxQuality}p"); var temp = new HashSet(); foreach (var translation in root.SerialVoice) { foreach (var season in translation.Value) { if (temp.Contains(season.Value.season)) continue; temp.Add(season.Value.season); var link = $"{host}lite/filmixtv?rjson={rjson}&postid={postid}&title={enc_title}&original_title={enc_original_title}&s={season.Value.season}"; tpl.Append($"{season.Value.season} сезон", link, season.Value.season); } } return tpl; #endregion } else { #region Перевод int indexTranslate = 0; var vtpl = new VoiceTpl(); foreach (var translation in root.SerialVoice) { foreach (var season in translation.Value) { if (season.Value.season == s) { string link = host + $"lite/filmixtv?rjson={rjson}&postid={postid}&title={enc_title}&original_title={enc_original_title}&s={s}&t={indexTranslate}"; bool active = t == indexTranslate; if (t == -1) t = indexTranslate; vtpl.Append(translation.Key, active, link); } } indexTranslate++; } #endregion var selectedSeason = root.SerialVoice.ElementAt(t).Value.FirstOrDefault(x => x.Value.season == s); if (selectedSeason.Value.episodes == null) return default; var etpl = new EpisodeTpl(vtpl, selectedSeason.Value.episodes.Count); foreach (var episode in selectedSeason.Value.episodes) { var streamquality = new StreamQualityTpl(); var sortedFiles = episode.Value.files .Where(file => pro || file.quality <= 720) .OrderByDescending(file => file.quality); foreach (var file in sortedFiles) streamquality.Append(onstreamfile.Invoke(file.url), $"{file.quality}p"); if (!streamquality.Any()) continue; etpl.Append($"{episode.Key.TrimStart('e')} серия", title ?? original_title, selectedSeason.Value.season.ToString(), episode.Key.TrimStart('e'), streamquality.Firts().link, streamquality: streamquality, vast: vast); } return etpl; } } #endregion #region Фильм else if (root.Movies != null) { var mtpl = new MovieTpl(title, original_title, root.Movies.Length); foreach (var item in root.Movies) { var streamquality = new StreamQualityTpl(); foreach (var file in item.files) { if (!pro) { if (pro && file.quality > 480) continue; if (file.quality > 720) continue; } streamquality.Append(onstreamfile.Invoke(file.url), $"{file.quality}p"); } if (!streamquality.Any()) continue; mtpl.Append(item.voiceover, streamquality.Firts().link, streamquality: streamquality, vast: vast); } return mtpl; } #endregion return default; } #endregion } }