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
}
}