lampac/Online/Controllers/IptvOnline.cs
2026-02-07 00:18:50 +03:00

234 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 = "Введите данные <a href='https://iptv.online/ru/dealers/api' target=_blank>https://iptv.online/ru/dealers/api</a> <br> <br><form method=\"get\" action=\"/lite/iptvonline/bind\"><input type=\"text\" name=\"KEY\" placeholder=\"X-API-KEY\"> &nbsp; &nbsp; <input type=\"text\" name=\"ID\" placeholder=\"X-API-ID\"><br><br><button>Авторизоваться</button></form> ";
}
else
{
html = "Добавьте в init.conf<br><br>\"IptvOnline\": {<br>&nbsp;&nbsp;\"enable\": true,<br>&nbsp;&nbsp;\"token\": \"" + $"{ID}:{KEY}" + "\"<br>}";
}
return ContentTo(html);
}
#endregion
[HttpGet]
[Route("lite/iptvonline")]
async public Task<ActionResult> 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<JObject>($"{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<string>("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<string>("message") != null)
return ShowError(data.Value<string>("message"));
#region media
string id = data.Value<string>("id");
var cache = await InvokeCacheResult<JToken>($"IptvOnline:{id}:{init.token}", 20, async e =>
{
string uri = $"{init.host}/v1/api/media/{(serial == 1 ? "serials" : "movies")}/{id}/";
var root = await httpHydra.Get<JObject>(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<string>("category") == "movie")
{
#region Фильм
var mtpl = new MovieTpl(title, original_title, 1);
string stream = HostStreamProxy(cache.Value["medias"].First.Value<string>("url") + "#.m3u8");
string quality = cache.Value.Value<int?>("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<string>("quality");
if (quality != null)
quality += "p";
var tpl = new SeasonTpl(quality);
foreach (var media in cache.Value["medias"])
{
int season = media.Value<int>("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<int>("season") == s).Value<JArray>("episodes"))
{
string name = episode.Value<string>("title");
string file = episode.Value<string>("url") + "#.m3u8";
if (string.IsNullOrEmpty(file))
continue;
string stream = HostStreamProxy(file);
etpl.Append(name ?? $"{episode.Value<int>("episode")} серия", title ?? original_title, sArhc, episode.Value<int>("episode").ToString(), stream, vast: init.vast);
}
return etpl;
}
#endregion
}
});
}
#region search
async ValueTask<JToken> 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<JToken> 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<JObject>(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<string>("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<long?>("kinopoisk") == kinopoisk_id)
return item;
}
if (!string.IsNullOrEmpty(imdb_id))
{
if ($"tt{item.Value<long?>("imdb")}" == imdb_id)
return item;
}
}
foreach (var item in video["data"])
{
if (sorigtitle != null)
{
if (StringConvert.SearchName(item.Value<string>("orig_title")) == sorigtitle)
return item;
}
if (stitle != null)
{
if (StringConvert.SearchName(item.Value<string>("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
}
}