using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Text; namespace Online.Controllers { public class IptvOnline : BaseOnlineController { public IptvOnline() : base(AppInit.conf.IptvOnline) { } #region Bind [HttpGet] [AllowAnonymous] [Route("lite/iptvonline/bind")] public ActionResult Bind(string KEY, string ID) { string html = string.Empty; if (string.IsNullOrWhiteSpace(KEY) || string.IsNullOrWhiteSpace(ID)) { html = "Введите данные https://iptv.online/ru/dealers/api

   

"; } else { html = "Добавьте в init.conf

\"IptvOnline\": {
  \"enable\": true,
  \"token\": \"" + $"{ID}:{KEY}" + "\"
}"; } return ContentTo(html); } #endregion [HttpGet] [Route("lite/iptvonline")] async public Task Index(string imdb_id, long kinopoisk_id, string title, string original_title, int serial = -1, int s = -1, bool rjson = false) { if (await IsRequestBlocked(rch: false)) return badInitMsg; if (string.IsNullOrEmpty(init.token)) return OnError("token", statusCode: 401, gbcache: false); #region AUTH if (!hybridCache.TryGetValue($"iptvonline:auth:{init.token}", out string codeauth)) { var auth = await httpHydra.Post($"{init.host}/v1/api/auth", "", useDefaultHeaders: false, safety: true, addheaders: HeadersModel.Init( ("X-API-KEY", init.token.Split(":")[1]), ("X-API-ID", init.token.Split(":")[0]) )); if (auth == null) return OnError(refresh_proxy: true); string code = auth.Value("code"); if (string.IsNullOrEmpty(code)) return OnError(refresh_proxy: true); codeauth = code; hybridCache.Set($"iptvonline:auth:{init.token}", codeauth, DateTime.Now.AddHours(2)); } #endregion var data = await search(codeauth, serial, imdb_id, kinopoisk_id, title, original_title); if (data == null) return OnError(); if (data.Value("message") != null) return ShowError(data.Value("message")); #region media string id = data.Value("id"); var cache = await InvokeCacheResult($"IptvOnline:{id}:{init.token}", 20, async e => { string uri = $"{init.host}/v1/api/media/{(serial == 1 ? "serials" : "movies")}/{id}/"; var root = await httpHydra.Get(uri, useDefaultHeaders: false, safety: true, addheaders: HeadersModel.Init( ("X-API-AUTH", codeauth), ("X-API-ID", init.token.Split(":")[0]) )); if (root == null || !root.ContainsKey("data")) return e.Fail("data", refresh_proxy: true); return e.Success(root["data"]); }); #endregion return await ContentTpl(cache, () => { if (cache.Value.Value("category") == "movie") { #region Фильм var mtpl = new MovieTpl(title, original_title, 1); string stream = HostStreamProxy(cache.Value["medias"].First.Value("url") + "#.m3u8"); string quality = cache.Value.Value("quality")?.ToString(); if (quality != null) quality += "p"; mtpl.Append(quality ?? title, stream, vast: init.vast); return mtpl; #endregion } else { #region Сериал if (s == -1) { string enc_title = HttpUtility.UrlEncode(title); string enc_original_title = HttpUtility.UrlEncode(original_title); string quality = cache.Value.Value("quality"); if (quality != null) quality += "p"; var tpl = new SeasonTpl(quality); foreach (var media in cache.Value["medias"]) { int season = media.Value("season"); string link = $"{host}/lite/iptvonline?rjson={rjson}&serial={serial}&kinopoisk_id={kinopoisk_id}&imdb_id={imdb_id}&title={enc_title}&original_title={enc_original_title}&s={season}"; tpl.Append($"{season} сезон", link, season); } return tpl; } else { var etpl = new EpisodeTpl(); string sArhc = s.ToString(); foreach (var episode in cache.Value["medias"].First(i => i.Value("season") == s).Value("episodes")) { string name = episode.Value("title"); string file = episode.Value("url") + "#.m3u8"; if (string.IsNullOrEmpty(file)) continue; string stream = HostStreamProxy(file); etpl.Append(name ?? $"{episode.Value("episode")} серия", title ?? original_title, sArhc, episode.Value("episode").ToString(), stream, vast: init.vast); } return etpl; } #endregion } }); } #region search async ValueTask search(string codeauth, int serial, string imdb_id, long kinopoisk_id, string title, string original_title) { string memKey = $"iptvonline:view:{kinopoisk_id}:{imdb_id}:{title}:{original_title}"; if (!hybridCache.TryGetValue(memKey, out JToken data)) { string stitle = StringConvert.SearchName(title); string sorigtitle = StringConvert.SearchName(original_title); async Task goSearch(string search) { if (string.IsNullOrEmpty(search)) return null; string uri = $"{init.host}/v1/api/media/{(serial == 1 ? "serials" : "movies")}"; var data = new System.Net.Http.StringContent(JsonConvert.SerializeObject(new { search }), Encoding.UTF8, "application/json"); var video = await Http.Get(uri, body: data, timeoutSeconds: init.GetHttpTimeout(), httpversion: init.GetHttpVersion(), proxy: proxy, useDefaultHeaders: false, headers: httpHeaders(init, HeadersModel.Init( ("X-API-AUTH", codeauth), ("X-API-ID", init.token.Split(":")[0]) ))); if (video == null) { proxyManager?.Refresh(); return null; } if (video.ContainsKey("message") && video.Value("message") == "No Subscribed By Media API") return video; if (!video.ContainsKey("data")) return null; foreach (var item in video["data"]) { if (kinopoisk_id > 0) { if (item.Value("kinopoisk") == kinopoisk_id) return item; } if (!string.IsNullOrEmpty(imdb_id)) { if ($"tt{item.Value("imdb")}" == imdb_id) return item; } } foreach (var item in video["data"]) { if (sorigtitle != null) { if (StringConvert.SearchName(item.Value("orig_title")) == sorigtitle) return item; } if (stitle != null) { if (StringConvert.SearchName(item.Value("ru_title")) == stitle) return item; } } return null; } data = await goSearch(original_title) ?? await goSearch(title); if (data == null) return null; proxyManager?.Success(); hybridCache.Set(memKey, data, cacheTime(30)); } return data; } #endregion } }