lampac-talks f843f04fd4 chore: initial commit 154.3
Signed-off-by: lampac-talks <lampac-talks@users.noreply.github.com>
2026-01-30 16:23:09 +03:00

259 lines
9.1 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 Shared.Engine.RxEnumerate;
using Shared.Models;
using Shared.Models.Base;
using Shared.Models.Online.FanCDN;
using Shared.Models.Templates;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Web;
namespace Shared.Engine.Online
{
public struct FanCDNInvoke
{
#region FanCDNInvoke
string host;
string apihost;
HttpHydra httpHydra;
Func<string, Task<string>> onget;
Func<string, string> onstreamfile;
public FanCDNInvoke(string host, string apihost, HttpHydra httpHydra, Func<string, Task<string>> onget, Func<string, string> onstreamfile)
{
this.host = host != null ? $"{host}/" : null; this.apihost = apihost;
this.onget = onget;
this.httpHydra = httpHydra;
this.onstreamfile = onstreamfile;
}
#endregion
#region EmbedSearch
async public Task<EmbedModel> EmbedSearch(string title, string original_title, int year, int serial)
{
if (serial == 1)
{
return null;
}
else
{
if (string.IsNullOrEmpty(title) || year == 0)
return null;
string search = await onget($"{apihost}/?do=search&subaction=search&story={HttpUtility.UrlEncode(title)}");
if (string.IsNullOrEmpty(search))
return null;
string href = null;
var rx = Rx.Split("item-search-serial", search);
foreach (var row in rx.Rows())
{
var item_search = Rx.Split("item-search-serial", row.Span);
if (item_search.Count == 0)
continue;
string info = item_search[0].ToString();
if (!string.IsNullOrEmpty(info) && (info.Contains($"({year - 1}") || info.Contains($"({year}") || info.Contains($"({year + 1}")))
{
string _info = StringConvert.SearchName(info);
if (_info.Contains(StringConvert.SearchName(title)) || (!string.IsNullOrEmpty(original_title) && _info.Contains(StringConvert.SearchName(original_title))))
{
href = Regex.Match(info, "<a href=\"(https?://[^\"]+\\.html)\"").Groups[1].Value;
break;
}
}
}
if (string.IsNullOrEmpty(href))
return null;
string html = await onget(href);
if (string.IsNullOrEmpty(html))
return null;
string iframe_url = null;
foreach (Match match in Regex.Matches(html, "(https?://fancdn\\.[^\"\n\r\t ]+)\""))
{
string cdn = match.Groups[1].Value;
if (cdn.Contains("kinopoisk=") && cdn.Contains("key="))
iframe_url = cdn;
}
if (string.IsNullOrEmpty(iframe_url))
return null;
return await Embed(iframe_url);
}
}
#endregion
#region EmbedToken
async public Task<EmbedModel> EmbedToken(long kinopoisk_id, string token)
{
if (kinopoisk_id == 0)
return null;
return await Embed($"https://fancdn.net/iframe/?kinopoisk={kinopoisk_id}&key={token}");
}
#endregion
#region EmbedFilms
async public Task<EmbedModel> EmbedFilms(string host, long kinopoisk_id)
{
if (kinopoisk_id == 0)
return null;
string iframe_url = $"{host}/films.php?kp={kinopoisk_id}";
var movies = await httpHydra.Get<Episode[]>(iframe_url);
if (movies == null || movies.Length == 0)
return null;
return new EmbedModel() { movies = movies };
}
#endregion
#region Embed
async public Task<EmbedModel> Embed(string iframe_url)
{
if (string.IsNullOrEmpty(iframe_url))
return null;
string iframe = await onget(iframe_url);
if (string.IsNullOrEmpty(iframe))
return null;
iframe = Regex.Replace(iframe, "[\n\r\t]+", "").Replace("var ", "\n");
string playlist = Regex.Match(iframe, "playlist ?= ?(\\[[^\n\r]+\\]);").Groups[1].Value;
if (string.IsNullOrEmpty(playlist))
return null;
try
{
if (iframe.Contains("\"folder\""))
{
var serial = JsonSerializer.Deserialize<Voice[]>(playlist);
if (serial == null || serial.Length == 0)
return null;
return new EmbedModel() { serial = serial };
}
else
{
var movies = JsonSerializer.Deserialize<Episode[]>(playlist);
if (movies == null || movies.Length == 0)
return null;
return new EmbedModel() { movies = movies };
}
}
catch { }
return null;
}
#endregion
#region Html
public ITplResult Tpl(EmbedModel root, string imdb_id, long kinopoisk_id, string title, string original_title, int t = -1, int s = -1, bool rjson = false, VastConf vast = null, List<HeadersModel> headers = null)
{
if (root == null)
return default;
if (root.movies != null)
{
var mtpl = new MovieTpl(title, original_title, root.movies.Length);
foreach (var m in root.movies)
{
if (string.IsNullOrEmpty(m.file))
continue;
#region subtitle
var subtitles = new SubtitleTpl();
if (!string.IsNullOrEmpty(m.subtitles))
{
// [rus]rus1.srt,[eng]eng2.srt,[eng]eng3.srt
var match = new Regex("\\[([^\\]]+)\\]([^\\,]+)").Match(m.subtitles);
while (match.Success)
{
string srt = m.file.Replace("/hls.m3u8", "/") + match.Groups[2].Value;
subtitles.Append(match.Groups[1].Value, onstreamfile.Invoke(srt));
match = match.NextMatch();
}
}
#endregion
mtpl.Append(m.title, onstreamfile.Invoke(m.file), subtitles: subtitles, vast: vast, headers: headers);
}
return mtpl;
}
else
{
#region Сериал
string enc_title = HttpUtility.UrlEncode(title);
string enc_original_title = HttpUtility.UrlEncode(original_title);
if (s == -1)
{
#region Сезоны
var tpl = new SeasonTpl();
var hash = new HashSet<int>(20);
foreach (var voice in root.serial.OrderBy(i => i.seasons))
{
if (hash.Contains(voice.seasons))
continue;
hash.Add(voice.seasons);
string link = host + $"lite/fancdn?rjson={rjson}&imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={enc_title}&original_title={enc_original_title}&s={voice.seasons}";
tpl.Append($"{voice.seasons} сезон", link, voice.seasons);
}
return tpl;
#endregion
}
else
{
#region Перевод
var vtpl = new VoiceTpl();
foreach (var voice in root.serial)
{
if (s != voice.seasons)
continue;
if (t == -1)
t = voice.id;
string link = host + $"lite/fancdn?rjson={rjson}&imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={enc_title}&original_title={enc_original_title}&s={s}&t={voice.id}";
bool active = t == voice.id;
vtpl.Append(voice.title, active, link);
}
#endregion
var episodes = root.serial.First(i => i.id == t).folder[s.ToString()].folder;
var etpl = new EpisodeTpl(vtpl, episodes.Count);
string sArhc = s.ToString();
foreach (var episode in episodes)
etpl.Append($"{episode.Key} серия", title ?? original_title, sArhc, episode.Key, onstreamfile.Invoke(episode.Value.file), vast: vast, headers: headers);
return etpl;
}
#endregion
}
}
#endregion
}
}