Compare commits

..

3 Commits

Author SHA1 Message Date
Felix
a45e26537a docs(readme): update module references with LME prefix and repository URL
- Add Ukrainian note explaining LME prefix usage
- Update all module names in lists and examples to include LME prefix
- Change repository URL to lampac-ukraine organization
- Modify Docker volume path and YAML config accordingly
- Remove APN support section
- Add log to .gitignore
2026-04-12 10:23:39 +03:00
Felix
2cb90e15a9 refactor(modules): prefix namespaces and identifiers with LME 2026-04-12 10:20:44 +03:00
Felix
581b3438a5 refactor(modules): prefix namespaces and identifiers with LME
- Updated namespaces across all online modules to include LME prefix (e.g., AnimeON -> LME.AnimeON)
- Changed routes from /lite/plugin to /lite/lme.plugin
- Prefixed cache keys with lme. (e.g., jacktor: -> lme.jacktor:)
- Updated module settings names and init calls to LME.Plugin
- Bumped version numbers and updated manifest files with LME-prefixed class names
- Replaced OnError calls to use lme.plugin identifiers
- Modified log messages to include lme.plugin prefix for consistency
2026-04-12 09:29:49 +03:00
126 changed files with 498 additions and 469 deletions

3
.gitignore vendored
View File

@ -15,4 +15,5 @@ AGENTS.md
bin bin
obj obj
.vscode/settings.json .vscode/settings.json
.qwen .qwen
log

View File

@ -1,3 +0,0 @@
{
"enable": true
}

View File

@ -1,3 +0,0 @@
{
"enable": true
}

View File

@ -1,3 +0,0 @@
{
"enable": true
}

View File

@ -1,3 +0,0 @@
{
"enable": true
}

View File

@ -9,10 +9,10 @@ using System.Linq;
using System.Text; using System.Text;
using System.Net; using System.Net;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using AnimeON.Models; using LME.AnimeON.Models;
using Shared.Engine; using Shared.Engine;
namespace AnimeON namespace LME.AnimeON
{ {
public class AnimeONInvoke public class AnimeONInvoke
{ {

View File

@ -8,14 +8,14 @@ using System.Web;
using System.Linq; using System.Linq;
using Shared; using Shared;
using Shared.Models.Templates; using Shared.Models.Templates;
using AnimeON.Models; using LME.AnimeON.Models;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Text; using System.Text;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using Shared.Models; using Shared.Models;
using HtmlAgilityPack; using HtmlAgilityPack;
namespace AnimeON.Controllers namespace LME.AnimeON.Controllers
{ {
public class Controller : BaseOnlineController public class Controller : BaseOnlineController
{ {
@ -27,7 +27,7 @@ namespace AnimeON.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/animeon")] [Route("lite/lme.animeon")]
async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, bool checksearch = false) async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, bool checksearch = false)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -42,13 +42,13 @@ namespace AnimeON.Controllers
if (checksearch) if (checksearch)
{ {
if (!IsCheckOnlineSearchEnabled()) if (!IsCheckOnlineSearchEnabled())
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
var checkSeasons = await invoke.Search(imdb_id, kinopoisk_id, title, original_title, year, serial); var checkSeasons = await invoke.Search(imdb_id, kinopoisk_id, title, original_title, year, serial);
if (checkSeasons != null && checkSeasons.Count > 0) if (checkSeasons != null && checkSeasons.Count > 0)
return Content("data-json=", "text/plain; charset=utf-8"); return Content("data-json=", "text/plain; charset=utf-8");
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
} }
OnLog($"AnimeON Index: title={title}, original_title={original_title}, serial={serial}, s={s}, t={t}, year={year}, imdb_id={imdb_id}, kp={kinopoisk_id}"); OnLog($"AnimeON Index: title={title}, original_title={original_title}, serial={serial}, s={s}, t={t}, year={year}, imdb_id={imdb_id}, kp={kinopoisk_id}");
@ -56,7 +56,7 @@ namespace AnimeON.Controllers
var seasons = await invoke.Search(imdb_id, kinopoisk_id, title, original_title, year, serial); var seasons = await invoke.Search(imdb_id, kinopoisk_id, title, original_title, year, serial);
OnLog($"AnimeON: search results = {seasons?.Count ?? 0}"); OnLog($"AnimeON: search results = {seasons?.Count ?? 0}");
if (seasons == null || seasons.Count == 0) if (seasons == null || seasons.Count == 0)
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
// [Refactoring] Використовується агрегована структура (AggregateSerialStructure) — попередній збір allOptions не потрібний // [Refactoring] Використовується агрегована структура (AggregateSerialStructure) — попередній збір allOptions не потрібний
@ -82,7 +82,7 @@ namespace AnimeON.Controllers
foreach (var item in seasonItems) foreach (var item in seasonItems)
{ {
string seasonName = item.SeasonNumber.ToString(); string seasonName = item.SeasonNumber.ToString();
string link = $"{host}/lite/animeon?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={item.SeasonNumber}"; string link = $"{host}/lite/lme.animeon?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={item.SeasonNumber}";
season_tpl.Append(seasonName, link, seasonName); season_tpl.Append(seasonName, link, seasonName);
} }
OnLog($"AnimeON: return seasons count={seasonItems.Count}"); OnLog($"AnimeON: return seasons count={seasonItems.Count}");
@ -107,13 +107,13 @@ namespace AnimeON.Controllers
selected = new { Anime = seasons[s], Index = s, SeasonNumber = seasons[s].Season > 0 ? seasons[s].Season : s + 1 }; selected = new { Anime = seasons[s], Index = s, SeasonNumber = seasons[s].Season > 0 ? seasons[s].Season : s + 1 };
if (selected == null) if (selected == null)
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
var selectedAnime = selected.Anime; var selectedAnime = selected.Anime;
int selectedSeasonNumber = selected.SeasonNumber; int selectedSeasonNumber = selected.SeasonNumber;
var structure = await invoke.AggregateSerialStructure(selectedAnime.Id, selectedSeasonNumber); var structure = await invoke.AggregateSerialStructure(selectedAnime.Id, selectedSeasonNumber);
if (structure == null || !structure.Voices.Any()) if (structure == null || !structure.Voices.Any())
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
OnLog($"AnimeON: voices found = {structure.Voices.Count}"); OnLog($"AnimeON: voices found = {structure.Voices.Count}");
var voiceItems = structure.Voices var voiceItems = structure.Voices
@ -136,14 +136,14 @@ namespace AnimeON.Controllers
var voice_tpl = new VoiceTpl(); var voice_tpl = new VoiceTpl();
foreach (var voice in voiceItems) foreach (var voice in voiceItems)
{ {
string voiceLink = $"{host}/lite/animeon?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={s}&t={HttpUtility.UrlEncode(voice.Key)}"; string voiceLink = $"{host}/lite/lme.animeon?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={s}&t={HttpUtility.UrlEncode(voice.Key)}";
bool isActive = voice.Key == t; bool isActive = voice.Key == t;
voice_tpl.Append(voice.Display, isActive, voiceLink); voice_tpl.Append(voice.Display, isActive, voiceLink);
} }
// Перевірка вибраної озвучки // Перевірка вибраної озвучки
if (!structure.Voices.ContainsKey(t)) if (!structure.Voices.ContainsKey(t))
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
var episode_tpl = new EpisodeTpl(); var episode_tpl = new EpisodeTpl();
var selectedVoiceInfo = structure.Voices[t]; var selectedVoiceInfo = structure.Voices[t];
@ -180,7 +180,7 @@ namespace AnimeON.Controllers
if (string.IsNullOrEmpty(streamLink) && ep.EpisodeId > 0) if (string.IsNullOrEmpty(streamLink) && ep.EpisodeId > 0)
{ {
string callUrl = $"{host}/lite/animeon/play?episode_id={ep.EpisodeId}&serial=1"; string callUrl = $"{host}/lite/lme.animeon/play?episode_id={ep.EpisodeId}&serial=1";
episode_tpl.Append(episodeName, title ?? original_title, seasonStr, episodeStr, accsArgs(callUrl), "call"); episode_tpl.Append(episodeName, title ?? original_title, seasonStr, episodeStr, accsArgs(callUrl), "call");
continue; continue;
} }
@ -190,7 +190,7 @@ namespace AnimeON.Controllers
if (needsResolve || streamLink.Contains("moonanime.art") || streamLink.Contains("ashdi.vip/vod")) if (needsResolve || streamLink.Contains("moonanime.art") || streamLink.Contains("ashdi.vip/vod"))
{ {
string callUrl = $"{host}/lite/animeon/play?url={HttpUtility.UrlEncode(streamLink)}&serial=1"; string callUrl = $"{host}/lite/lme.animeon/play?url={HttpUtility.UrlEncode(streamLink)}&serial=1";
episode_tpl.Append(episodeName, title ?? original_title, seasonStr, episodeStr, accsArgs(callUrl), "call"); episode_tpl.Append(episodeName, title ?? original_title, seasonStr, episodeStr, accsArgs(callUrl), "call");
} }
else else
@ -213,12 +213,12 @@ namespace AnimeON.Controllers
{ {
var firstAnime = seasons.FirstOrDefault(); var firstAnime = seasons.FirstOrDefault();
if (firstAnime == null) if (firstAnime == null)
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
var fundubs = await invoke.GetFundubs(firstAnime.Id); var fundubs = await invoke.GetFundubs(firstAnime.Id);
OnLog($"AnimeON: movie fundubs count = {fundubs?.Count ?? 0}"); OnLog($"AnimeON: movie fundubs count = {fundubs?.Count ?? 0}");
if (fundubs == null || fundubs.Count == 0) if (fundubs == null || fundubs.Count == 0)
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
var tpl = new MovieTpl(title, original_title); var tpl = new MovieTpl(title, original_title);
@ -252,7 +252,7 @@ namespace AnimeON.Controllers
foreach (var ashdiStream in ashdiStreams) foreach (var ashdiStream in ashdiStreams)
{ {
string optionName = $"{translationName} {ashdiStream.title}"; string optionName = $"{translationName} {ashdiStream.title}";
string callUrl = $"{host}/lite/animeon/play?url={HttpUtility.UrlEncode(ashdiStream.link)}"; string callUrl = $"{host}/lite/lme.animeon/play?url={HttpUtility.UrlEncode(ashdiStream.link)}";
tpl.Append(optionName, accsArgs(callUrl), "call"); tpl.Append(optionName, accsArgs(callUrl), "call");
} }
continue; continue;
@ -261,7 +261,7 @@ namespace AnimeON.Controllers
if (needsResolve || streamLink.Contains("moonanime.art/iframe/") || streamLink.Contains("ashdi.vip/vod")) if (needsResolve || streamLink.Contains("moonanime.art/iframe/") || streamLink.Contains("ashdi.vip/vod"))
{ {
string callUrl = $"{host}/lite/animeon/play?url={HttpUtility.UrlEncode(streamLink)}"; string callUrl = $"{host}/lite/lme.animeon/play?url={HttpUtility.UrlEncode(streamLink)}";
tpl.Append(translationName, accsArgs(callUrl), "call"); tpl.Append(translationName, accsArgs(callUrl), "call");
} }
else else
@ -273,7 +273,7 @@ namespace AnimeON.Controllers
// Якщо не зібрали жодної опції — повертаємо помилку // Якщо не зібрали жодної опції — повертаємо помилку
if (tpl.data == null || tpl.data.Count == 0) if (tpl.data == null || tpl.data.Count == 0)
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
OnLog("AnimeON: return movie options"); OnLog("AnimeON: return movie options");
return rjson ? Content(tpl.ToJson(), "application/json; charset=utf-8") : Content(tpl.ToHtml(), "text/html; charset=utf-8"); return rjson ? Content(tpl.ToJson(), "application/json; charset=utf-8") : Content(tpl.ToHtml(), "text/html; charset=utf-8");
@ -374,7 +374,7 @@ namespace AnimeON.Controllers
return null; return null;
} }
[HttpGet("lite/animeon/play")] [HttpGet("lite/lme.animeon/play")]
public async Task<ActionResult> Play(string url, int episode_id = 0, string title = null, int serial = 0) public async Task<ActionResult> Play(string url, int episode_id = 0, string title = null, int serial = 0)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -400,13 +400,13 @@ namespace AnimeON.Controllers
else else
{ {
OnLog("AnimeON Play: empty url"); OnLog("AnimeON Play: empty url");
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
} }
if (string.IsNullOrEmpty(streamLink)) if (string.IsNullOrEmpty(streamLink))
{ {
OnLog("AnimeON Play: cannot extract stream"); OnLog("AnimeON Play: cannot extract stream");
return OnError("animeon", refresh_proxy: true); return OnError("lme.animeon", refresh_proxy: true);
} }
List<HeadersModel> streamHeaders = null; List<HeadersModel> streamHeaders = null;

View File

@ -22,11 +22,11 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AnimeON namespace LME.AnimeON
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 4.0; public static double Version => 4.1;
public static OnlinesSettings AnimeON; public static OnlinesSettings AnimeON;
public static bool ApnHostProvided; public static bool ApnHostProvided;
@ -45,7 +45,7 @@ namespace AnimeON
{ {
AnimeON = new OnlinesSettings("AnimeON", "https://animeon.club", streamproxy: false, useproxy: false) AnimeON = new OnlinesSettings("LME.AnimeON", "https://animeon.club", streamproxy: false, useproxy: false)
{ {
displayname = "AnimeON", displayname = "AnimeON",
displayindex = 0, displayindex = 0,
@ -64,7 +64,7 @@ namespace AnimeON
["ashdi"] = ApnHelper.DefaultHost ["ashdi"] = ApnHelper.DefaultHost
}; };
var conf = ModuleInvoke.Init("AnimeON", defaults) ?? defaults; var conf = ModuleInvoke.Init("LME.AnimeON", defaults) ?? defaults;
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost); bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf); MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf);
conf.Remove("magic_apn"); conf.Remove("magic_apn");
@ -85,7 +85,7 @@ namespace AnimeON
} }
// Виводити "уточнити пошук" // Виводити "уточнити пошук"
RegisterWithSearch("animeon"); RegisterWithSearch("lme.animeon");
} }
private static void RegisterWithSearch(string plugin) private static void RegisterWithSearch(string plugin)

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace AnimeON.Models namespace LME.AnimeON.Models
{ {
/// <summary> Aggregated structure for AnimeON serial content to match Lampac standard navigation.</summary> /// <summary> Aggregated structure for AnimeON serial content to match Lampac standard navigation.</summary>
public class AnimeONAggregatedStructure public class AnimeONAggregatedStructure

View File

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace AnimeON.Models namespace LME.AnimeON.Models
{ {
public class EmbedModel public class EmbedModel
{ {

View File

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace AnimeON.Models namespace LME.AnimeON.Models
{ {
public class SearchResponseModel public class SearchResponseModel
{ {

View File

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace AnimeON.Models namespace LME.AnimeON.Models
{ {
public class Serial public class Serial
{ {

View File

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace AnimeON.Models namespace LME.AnimeON.Models
{ {
public class Voice public class Voice
{ {

View File

@ -6,7 +6,7 @@ using Shared.Models.Module.Interfaces;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AnimeON namespace LME.AnimeON
{ {
public class OnlineApi : IModuleOnline public class OnlineApi : IModuleOnline
{ {
@ -30,7 +30,7 @@ namespace AnimeON
if (UpdateService.IsDisconnected()) if (UpdateService.IsDisconnected())
init.overridehost = null; init.overridehost = null;
online.Add(new ModuleOnlineItem(init, "animeon")); online.Add(new ModuleOnlineItem(init, "lme.animeon"));
} }
return online; return online;

View File

@ -0,0 +1,6 @@
{
"enable": true,
"version": 3,
"initspace": "LME.AnimeON.ModInit",
"online": "LME.AnimeON.OnlineApi"
}

View File

@ -5,14 +5,14 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
using Bamboo.Models; using LME.Bamboo.Models;
using HtmlAgilityPack; using HtmlAgilityPack;
using Shared; using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models; using Shared.Models;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
namespace Bamboo namespace LME.Bamboo
{ {
public class BambooInvoke public class BambooInvoke
{ {

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
using Bamboo.Models; using LME.Bamboo.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Shared; using Shared;
using Shared.Engine; using Shared.Engine;
@ -11,7 +11,7 @@ using Shared.Models;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using Shared.Models.Templates; using Shared.Models.Templates;
namespace Bamboo.Controllers namespace LME.Bamboo.Controllers
{ {
public class Controller : BaseOnlineController public class Controller : BaseOnlineController
{ {
@ -23,7 +23,7 @@ namespace Bamboo.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/bamboo")] [Route("lite/lme.bamboo")]
async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, string href = null, bool checksearch = false) async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, string href = null, bool checksearch = false)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -37,13 +37,13 @@ namespace Bamboo.Controllers
if (checksearch) if (checksearch)
{ {
if (!IsCheckOnlineSearchEnabled()) if (!IsCheckOnlineSearchEnabled())
return OnError("bamboo", refresh_proxy: true); return OnError("lme.bamboo", refresh_proxy: true);
var searchResults = await invoke.Search(title, original_title); var searchResults = await invoke.Search(title, original_title);
if (searchResults != null && searchResults.Count > 0) if (searchResults != null && searchResults.Count > 0)
return Content("data-json=", "text/plain; charset=utf-8"); return Content("data-json=", "text/plain; charset=utf-8");
return OnError("bamboo", refresh_proxy: true); return OnError("lme.bamboo", refresh_proxy: true);
} }
string itemUrl = href; string itemUrl = href;
@ -51,14 +51,14 @@ namespace Bamboo.Controllers
{ {
var searchResults = await invoke.Search(title, original_title); var searchResults = await invoke.Search(title, original_title);
if (searchResults == null || searchResults.Count == 0) if (searchResults == null || searchResults.Count == 0)
return OnError("bamboo", refresh_proxy: true); return OnError("lme.bamboo", refresh_proxy: true);
if (searchResults.Count > 1) if (searchResults.Count > 1)
{ {
var similar_tpl = new SimilarTpl(searchResults.Count); var similar_tpl = new SimilarTpl(searchResults.Count);
foreach (var res in searchResults) foreach (var res in searchResults)
{ {
string link = $"{host}/lite/bamboo?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(res.Url)}"; string link = $"{host}/lite/lme.bamboo?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(res.Url)}";
similar_tpl.Append(res.Title, string.Empty, string.Empty, link, res.Poster); similar_tpl.Append(res.Title, string.Empty, string.Empty, link, res.Poster);
} }
@ -72,7 +72,7 @@ namespace Bamboo.Controllers
{ {
var series = await invoke.GetSeriesEpisodes(itemUrl); var series = await invoke.GetSeriesEpisodes(itemUrl);
if (series == null || (series.Sub.Count == 0 && series.Dub.Count == 0)) if (series == null || (series.Sub.Count == 0 && series.Dub.Count == 0))
return OnError("bamboo", refresh_proxy: true); return OnError("lme.bamboo", refresh_proxy: true);
var voice_tpl = new VoiceTpl(); var voice_tpl = new VoiceTpl();
var episode_tpl = new EpisodeTpl(); var episode_tpl = new EpisodeTpl();
@ -88,13 +88,13 @@ namespace Bamboo.Controllers
foreach (var voice in availableVoices) foreach (var voice in availableVoices)
{ {
string voiceLink = $"{host}/lite/bamboo?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&t={voice.key}&href={HttpUtility.UrlEncode(itemUrl)}"; string voiceLink = $"{host}/lite/lme.bamboo?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&t={voice.key}&href={HttpUtility.UrlEncode(itemUrl)}";
voice_tpl.Append(voice.name, voice.key == t, voiceLink); voice_tpl.Append(voice.name, voice.key == t, voiceLink);
} }
var selected = availableVoices.FirstOrDefault(v => v.key == t); var selected = availableVoices.FirstOrDefault(v => v.key == t);
if (selected.episodes == null || selected.episodes.Count == 0) if (selected.episodes == null || selected.episodes.Count == 0)
return OnError("bamboo", refresh_proxy: true); return OnError("lme.bamboo", refresh_proxy: true);
int index = 1; int index = 1;
foreach (var ep in selected.episodes.OrderBy(e => e.Episode ?? int.MaxValue)) foreach (var ep in selected.episodes.OrderBy(e => e.Episode ?? int.MaxValue))
@ -116,7 +116,7 @@ namespace Bamboo.Controllers
{ {
var streams = await invoke.GetMovieStreams(itemUrl); var streams = await invoke.GetMovieStreams(itemUrl);
if (streams == null || streams.Count == 0) if (streams == null || streams.Count == 0)
return OnError("bamboo", refresh_proxy: true); return OnError("lme.bamboo", refresh_proxy: true);
var movie_tpl = new MovieTpl(title, original_title); var movie_tpl = new MovieTpl(title, original_title);
for (int i = 0; i < streams.Count; i++) for (int i = 0; i < streams.Count; i++)

View File

@ -21,11 +21,11 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Bamboo namespace LME.Bamboo
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 4.0; public static double Version => 4.1;
public static OnlinesSettings Bamboo; public static OnlinesSettings Bamboo;
public static bool ApnHostProvided; public static bool ApnHostProvided;
@ -43,7 +43,7 @@ namespace Bamboo
{ {
Bamboo = new OnlinesSettings("Bamboo", "https://bambooua.com", streamproxy: false, useproxy: false) Bamboo = new OnlinesSettings("LME.Bamboo", "https://bambooua.com", streamproxy: false, useproxy: false)
{ {
displayname = "BambooUA", displayname = "BambooUA",
displayindex = 0, displayindex = 0,
@ -57,7 +57,7 @@ namespace Bamboo
}; };
var defaults = JObject.FromObject(Bamboo); var defaults = JObject.FromObject(Bamboo);
defaults["enabled"] = true; defaults["enabled"] = true;
var conf = ModuleInvoke.Init("Bamboo", defaults); var conf = ModuleInvoke.Init("LME.Bamboo", defaults);
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost); bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
conf.Remove("apn"); conf.Remove("apn");
conf.Remove("apn_host"); conf.Remove("apn_host");
@ -76,7 +76,7 @@ namespace Bamboo
} }
// Виводити "уточнити пошук" // Виводити "уточнити пошук"
RegisterWithSearch("bamboo"); RegisterWithSearch("lme.bamboo");
} }
private static void RegisterWithSearch(string plugin) private static void RegisterWithSearch(string plugin)

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Bamboo.Models namespace LME.Bamboo.Models
{ {
public class SearchResult public class SearchResult
{ {

View File

@ -6,7 +6,7 @@ using Shared.Models.Module.Interfaces;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Bamboo namespace LME.Bamboo
{ {
public class OnlineApi : IModuleOnline public class OnlineApi : IModuleOnline
{ {
@ -33,7 +33,7 @@ namespace Bamboo
if (UpdateService.IsDisconnected()) if (UpdateService.IsDisconnected())
init.overridehost = null; init.overridehost = null;
online.Add(new ModuleOnlineItem(init, "bamboo")); online.Add(new ModuleOnlineItem(init, "lme.bamboo"));
} }
return online; return online;

6
LME.Bamboo/manifest.json Normal file
View File

@ -0,0 +1,6 @@
{
"enable": true,
"version": 3,
"initspace": "LME.Bamboo.ModInit",
"online": "LME.Bamboo.OnlineApi"
}

View File

@ -1,4 +1,4 @@
using JackTor.Models; using LME.JackTor.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Shared; using Shared;
using Shared.Models; using Shared.Models;
@ -14,7 +14,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
namespace JackTor.Controllers namespace LME.JackTor.Controllers
{ {
public class Controller : BaseOnlineController<JackTorSettings> public class Controller : BaseOnlineController<JackTorSettings>
{ {
@ -26,7 +26,7 @@ namespace JackTor.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/jacktor")] [Route("lite/lme.jacktor")]
async public Task<ActionResult> Index( async public Task<ActionResult> Index(
long id, long id,
string imdb_id, string imdb_id,
@ -57,20 +57,20 @@ namespace JackTor.Controllers
if (checksearch) if (checksearch)
{ {
if (!IsCheckOnlineSearchEnabled()) if (!IsCheckOnlineSearchEnabled())
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
var check = await invoke.Search(title, original_title, year, serial, original_language); var check = await invoke.Search(title, original_title, year, serial, original_language);
if (check.Count > 0) if (check.Count > 0)
return Content("data-json=", "text/plain; charset=utf-8"); return Content("data-json=", "text/plain; charset=utf-8");
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
} }
var torrents = await invoke.Search(title, original_title, year, serial, original_language); var torrents = await invoke.Search(title, original_title, year, serial, original_language);
if (torrents == null || torrents.Count == 0) if (torrents == null || torrents.Count == 0)
{ {
string debugInfo = $"title={title}\noriginal_title={original_title}\nyear={year}\nserial={serial}\njackett={MaskSensitiveUrl(init.jackett)}\nmin_sid={init.min_sid}\nmin_peers={init.min_peers}"; string debugInfo = $"title={title}\noriginal_title={original_title}\nyear={year}\nserial={serial}\njackett={MaskSensitiveUrl(init.jackett)}\nmin_sid={init.min_sid}\nmin_peers={init.min_peers}";
return OnError("jacktor", refresh_proxy: true, weblog: debugInfo); return OnError("lme.jacktor", refresh_proxy: true, weblog: debugInfo);
} }
if (serial == 1) if (serial == 1)
@ -97,7 +97,7 @@ namespace JackTor.Controllers
{ {
seasonTpl.Append( seasonTpl.Append(
$"{season} сезон", $"{season} сезон",
$"{host}/lite/jacktor?rjson={rjson}&title={enTitle}&original_title={enOriginal}&year={year}&original_language={original_language}&serial=1&s={season}", $"{host}/lite/lme.jacktor?rjson={rjson}&title={enTitle}&original_title={enOriginal}&year={year}&original_language={original_language}&serial=1&s={season}",
season); season);
} }
@ -126,7 +126,7 @@ namespace JackTor.Controllers
: $"{seasonLabel} • {torrent.Voice}"; : $"{seasonLabel} • {torrent.Voice}";
string qualityInfo = $"{torrent.Tracker} / {torrent.QualityLabel} / {torrent.MediaInfo} / ↑{torrent.Seeders}"; string qualityInfo = $"{torrent.Tracker} / {torrent.QualityLabel} / {torrent.MediaInfo} / ↑{torrent.Seeders}";
string releaseLink = accsArgs($"{host}/lite/jacktor/serial/{torrent.Rid}?rjson={rjson}&title={enTitle}&original_title={enOriginal}&s={targetSeason}"); string releaseLink = accsArgs($"{host}/lite/lme.jacktor/serial/{torrent.Rid}?rjson={rjson}&title={enTitle}&original_title={enOriginal}&s={targetSeason}");
similarTpl.Append(releaseName, null, qualityInfo, releaseLink); similarTpl.Append(releaseName, null, qualityInfo, releaseLink);
} }
@ -146,7 +146,7 @@ namespace JackTor.Controllers
: torrent.Voice; : torrent.Voice;
string voiceName = $"{torrent.QualityLabel} / {torrent.MediaInfo} / ↑{torrent.Seeders}"; string voiceName = $"{torrent.QualityLabel} / {torrent.MediaInfo} / ↑{torrent.Seeders}";
string streamLink = accsArgs($"{host}/lite/jacktor/s{torrent.Rid}"); string streamLink = accsArgs($"{host}/lite/lme.jacktor/s{torrent.Rid}");
movieTpl.Append( movieTpl.Append(
voice, voice,
@ -162,7 +162,7 @@ namespace JackTor.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/jacktor/serial/{rid}")] [Route("lite/lme.jacktor/serial/{rid}")]
async public ValueTask<ActionResult> Serial(string rid, string account_email, string title, string original_title, int s = 1, bool rjson = false) async public ValueTask<ActionResult> Serial(string rid, string account_email, string title, string original_title, int s = 1, bool rjson = false)
{ {
var init = loadKit(ModInit.Settings); var init = loadKit(ModInit.Settings);
@ -174,9 +174,9 @@ namespace JackTor.Controllers
var invoke = new JackTorInvoke(init, hybridCache, OnLog, proxyManager); var invoke = new JackTorInvoke(init, hybridCache, OnLog, proxyManager);
if (!invoke.TryGetSource(rid, out JackTorSourceCache source)) if (!invoke.TryGetSource(rid, out JackTorSourceCache source))
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
string memKey = $"jacktor:serial:{rid}"; string memKey = $"lme.jacktor:serial:{rid}";
return await InvkSemaphore(memKey, null, async () => return await InvkSemaphore(memKey, null, async () =>
{ {
@ -184,7 +184,7 @@ namespace JackTor.Controllers
{ {
var ts = ResolveProbeTorrentServer(init, account_email); var ts = ResolveProbeTorrentServer(init, account_email);
if (string.IsNullOrWhiteSpace(ts.host)) if (string.IsNullOrWhiteSpace(ts.host))
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
string hashResponse = await httpHydra.Post( string hashResponse = await httpHydra.Post(
$"{ts.host}/torrents", $"{ts.host}/torrents",
@ -194,7 +194,7 @@ namespace JackTor.Controllers
string hash = ExtractHash(hashResponse); string hash = ExtractHash(hashResponse);
if (string.IsNullOrWhiteSpace(hash)) if (string.IsNullOrWhiteSpace(hash))
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
Stat stat = null; Stat stat = null;
DateTime deadline = DateTime.Now.AddSeconds(20); DateTime deadline = DateTime.Now.AddSeconds(20);
@ -213,7 +213,7 @@ namespace JackTor.Controllers
if (DateTime.Now > deadline) if (DateTime.Now > deadline)
{ {
_ = httpHydra.Post($"{ts.host}/torrents", BuildRemovePayload(hash), statusCodeOK: false, newheaders: ts.headers); _ = httpHydra.Post($"{ts.host}/torrents", BuildRemovePayload(hash), statusCodeOK: false, newheaders: ts.headers);
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
} }
await Task.Delay(250); await Task.Delay(250);
@ -226,7 +226,7 @@ namespace JackTor.Controllers
} }
if (fileStats == null || fileStats.Length == 0) if (fileStats == null || fileStats.Length == 0)
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
var episodeTpl = new EpisodeTpl(); var episodeTpl = new EpisodeTpl();
int appended = 0; int appended = 0;
@ -241,13 +241,13 @@ namespace JackTor.Controllers
title ?? original_title, title ?? original_title,
s.ToString(), s.ToString(),
file.Id.ToString(), file.Id.ToString(),
accsArgs($"{host}/lite/jacktor/s{rid}?tsid={file.Id}")); accsArgs($"{host}/lite/lme.jacktor/s{rid}?tsid={file.Id}"));
appended++; appended++;
} }
if (appended == 0) if (appended == 0)
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
return rjson return rjson
? Content(episodeTpl.ToJson(), "application/json; charset=utf-8") ? Content(episodeTpl.ToJson(), "application/json; charset=utf-8")
@ -256,7 +256,7 @@ namespace JackTor.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/jacktor/s{rid}")] [Route("lite/lme.jacktor/s{rid}")]
async public ValueTask<ActionResult> Stream(string rid, int tsid = -1, string account_email = null) async public ValueTask<ActionResult> Stream(string rid, int tsid = -1, string account_email = null)
{ {
var init = loadKit(ModInit.Settings); var init = loadKit(ModInit.Settings);
@ -268,14 +268,14 @@ namespace JackTor.Controllers
var invoke = new JackTorInvoke(init, hybridCache, OnLog, proxyManager); var invoke = new JackTorInvoke(init, hybridCache, OnLog, proxyManager);
if (!invoke.TryGetSource(rid, out JackTorSourceCache source)) if (!invoke.TryGetSource(rid, out JackTorSourceCache source))
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
int index = tsid != -1 ? tsid : 1; int index = tsid != -1 ? tsid : 1;
string country = requestInfo.Country; string country = requestInfo.Country;
async ValueTask<ActionResult> AuthStream(string tsHost, string login, string passwd, string uhost = null, Dictionary<string, string> addheaders = null) async ValueTask<ActionResult> AuthStream(string tsHost, string login, string passwd, string uhost = null, Dictionary<string, string> addheaders = null)
{ {
string memKey = $"jacktor:auth_stream:{rid}:{uhost ?? tsHost}"; string memKey = $"lme.jacktor:auth_stream:{rid}:{uhost ?? tsHost}";
if (!hybridCache.TryGetValue(memKey, out string hash)) if (!hybridCache.TryGetValue(memKey, out string hash))
{ {
login = (login ?? string.Empty).Replace("{account_email}", account_email ?? string.Empty); login = (login ?? string.Empty).Replace("{account_email}", account_email ?? string.Empty);
@ -291,7 +291,7 @@ namespace JackTor.Controllers
hash = ExtractHash(response); hash = ExtractHash(response);
if (string.IsNullOrWhiteSpace(hash)) if (string.IsNullOrWhiteSpace(hash))
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
hybridCache.Set(memKey, hash, DateTime.Now.AddMinutes(1)); hybridCache.Set(memKey, hash, DateTime.Now.AddMinutes(1));
} }
@ -315,7 +315,7 @@ namespace JackTor.Controllers
if (init.auth_torrs != null && init.auth_torrs.Count > 0) if (init.auth_torrs != null && init.auth_torrs.Count > 0)
{ {
string tsKey = $"jacktor:ts2:{rid}:{requestInfo.IP}"; string tsKey = $"lme.jacktor:ts2:{rid}:{requestInfo.IP}";
if (!hybridCache.TryGetValue(tsKey, out PidTorAuthTS ts)) if (!hybridCache.TryGetValue(tsKey, out PidTorAuthTS ts))
{ {
var servers = init.auth_torrs.Where(i => i.enable).ToList(); var servers = init.auth_torrs.Where(i => i.enable).ToList();
@ -328,7 +328,7 @@ namespace JackTor.Controllers
} }
if (servers.Count == 0) if (servers.Count == 0)
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
ts = servers[Random.Shared.Next(0, servers.Count)]; ts = servers[Random.Shared.Next(0, servers.Count)];
hybridCache.Set(tsKey, ts, DateTime.Now.AddHours(4)); hybridCache.Set(tsKey, ts, DateTime.Now.AddHours(4));
@ -341,9 +341,9 @@ namespace JackTor.Controllers
if (init.base_auth != null && init.base_auth.enable) if (init.base_auth != null && init.base_auth.enable)
{ {
if (init.torrs == null || init.torrs.Length == 0) if (init.torrs == null || init.torrs.Length == 0)
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
string tsKey = $"jacktor:ts3:{rid}:{requestInfo.IP}"; string tsKey = $"lme.jacktor:ts3:{rid}:{requestInfo.IP}";
if (!hybridCache.TryGetValue(tsKey, out string tsHost)) if (!hybridCache.TryGetValue(tsKey, out string tsHost))
{ {
tsHost = init.torrs[Random.Shared.Next(0, init.torrs.Length)]; tsHost = init.torrs[Random.Shared.Next(0, init.torrs.Length)];
@ -354,9 +354,9 @@ namespace JackTor.Controllers
} }
if (init.torrs == null || init.torrs.Length == 0) if (init.torrs == null || init.torrs.Length == 0)
return OnError("jacktor", refresh_proxy: true); return OnError("lme.jacktor", refresh_proxy: true);
string key = $"jacktor:ts4:{rid}:{requestInfo.IP}"; string key = $"lme.jacktor:ts4:{rid}:{requestInfo.IP}";
if (!hybridCache.TryGetValue(key, out string torrentHost)) if (!hybridCache.TryGetValue(key, out string torrentHost))
{ {
torrentHost = init.torrs[Random.Shared.Next(0, init.torrs.Length)]; torrentHost = init.torrs[Random.Shared.Next(0, init.torrs.Length)];

View File

@ -1,4 +1,4 @@
using JackTor.Models; using LME.JackTor.Models;
using Shared.Models; using Shared.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -10,7 +10,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
namespace JackTor namespace LME.JackTor
{ {
public class JackTorInvoke public class JackTorInvoke
{ {
@ -45,7 +45,7 @@ namespace JackTor
public async Task<List<JackTorParsedResult>> Search(string title, string originalTitle, int year, int serial, string originalLanguage) public async Task<List<JackTorParsedResult>> Search(string title, string originalTitle, int year, int serial, string originalLanguage)
{ {
string memKey = $"jacktor:search:{serial}:{year}:{(title ?? string.Empty).Trim().ToLowerInvariant()}:{(originalTitle ?? string.Empty).Trim().ToLowerInvariant()}"; string memKey = $"lme.jacktor:search:{serial}:{year}:{(title ?? string.Empty).Trim().ToLowerInvariant()}:{(originalTitle ?? string.Empty).Trim().ToLowerInvariant()}";
if (_hybridCache.TryGetValue(memKey, out List<JackTorParsedResult> cached)) if (_hybridCache.TryGetValue(memKey, out List<JackTorParsedResult> cached))
return cached; return cached;
@ -83,7 +83,7 @@ namespace JackTor
public bool TryGetSource(string rid, out JackTorSourceCache source) public bool TryGetSource(string rid, out JackTorSourceCache source)
{ {
return _hybridCache.TryGetValue($"jacktor:source:{rid}", out source); return _hybridCache.TryGetValue($"lme.jacktor:source:{rid}", out source);
} }
private async Task<List<JackettResult>> SearchRaw(string query, int categoryId) private async Task<List<JackettResult>> SearchRaw(string query, int categoryId)
@ -731,7 +731,7 @@ namespace JackTor
Seasons = item.Seasons Seasons = item.Seasons
}; };
_hybridCache.Set($"jacktor:source:{item.Rid}", cacheItem, expires); _hybridCache.Set($"lme.jacktor:source:{item.Rid}", cacheItem, expires);
} }
} }
} }

View File

@ -1,4 +1,4 @@
using JackTor.Models; using LME.JackTor.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Shared; using Shared;
@ -13,11 +13,11 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace JackTor namespace LME.JackTor
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 2.0; public static double Version => 2.1;
public static JackTorSettings JackTor; public static JackTorSettings JackTor;
@ -32,7 +32,7 @@ namespace JackTor
/// </summary> /// </summary>
public void Loaded(InitspaceModel initspace) public void Loaded(InitspaceModel initspace)
{ {
JackTor = new JackTorSettings("JackTor", "http://127.0.0.1:9117", streamproxy: false, useproxy: false) JackTor = new JackTorSettings("LME.JackTor", "http://127.0.0.1:9117", streamproxy: false, useproxy: false)
{ {
displayname = "JackTor", displayname = "JackTor",
displayindex = 0, displayindex = 0,
@ -68,7 +68,7 @@ namespace JackTor
var defaults = JObject.FromObject(JackTor); var defaults = JObject.FromObject(JackTor);
defaults["enabled"] = true; defaults["enabled"] = true;
var conf = ModuleInvoke.Init("JackTor", defaults) ?? defaults; var conf = ModuleInvoke.Init("LME.JackTor", defaults) ?? defaults;
JackTor = conf.ToObject<JackTorSettings>(); JackTor = conf.ToObject<JackTorSettings>();
if (string.IsNullOrWhiteSpace(JackTor.jackett)) if (string.IsNullOrWhiteSpace(JackTor.jackett))
@ -78,7 +78,7 @@ namespace JackTor
JackTor.host = JackTor.jackett; JackTor.host = JackTor.jackett;
// Показувати «уточнити пошук». // Показувати «уточнити пошук».
RegisterWithSearch("jacktor"); RegisterWithSearch("lme.jacktor");
} }
private static void RegisterWithSearch(string plugin) private static void RegisterWithSearch(string plugin)

View File

@ -2,7 +2,7 @@ using Shared.Models.Online.Settings;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace JackTor.Models namespace LME.JackTor.Models
{ {
public class JackTorSettings : OnlinesSettings, ICloneable public class JackTorSettings : OnlinesSettings, ICloneable
{ {

View File

@ -6,7 +6,7 @@ using Shared.Models.Module.Interfaces;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace JackTor namespace LME.JackTor
{ {
public class OnlineApi : IModuleOnline public class OnlineApi : IModuleOnline
{ {
@ -26,7 +26,7 @@ namespace JackTor
if (UpdateService.IsDisconnected()) if (UpdateService.IsDisconnected())
init.overridehost = null; init.overridehost = null;
online.Add(new ModuleOnlineItem(init, "jacktor")); online.Add(new ModuleOnlineItem(init, "lme.jacktor"));
} }
return online; return online;

View File

@ -0,0 +1,6 @@
{
"enable": true,
"version": 3,
"initspace": "LME.JackTor.ModInit",
"online": "LME.JackTor.OnlineApi"
}

View File

@ -3,14 +3,14 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
using KlonFUN.Models; using LME.KlonFUN.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Shared; using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using Shared.Models.Templates; using Shared.Models.Templates;
namespace KlonFUN.Controllers namespace LME.KlonFUN.Controllers
{ {
public class Controller : BaseOnlineController public class Controller : BaseOnlineController
{ {
@ -22,7 +22,7 @@ namespace KlonFUN.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/klonfun")] [Route("lite/lme.klonfun")]
async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, string href = null, bool checksearch = false) async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, string href = null, bool checksearch = false)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -38,13 +38,13 @@ namespace KlonFUN.Controllers
if (checksearch) if (checksearch)
{ {
if (!IsCheckOnlineSearchEnabled()) if (!IsCheckOnlineSearchEnabled())
return OnError("klonfun", refresh_proxy: true); return OnError("lme.klonfun", refresh_proxy: true);
var checkResults = await invoke.Search(imdb_id, title, original_title); var checkResults = await invoke.Search(imdb_id, title, original_title);
if (checkResults != null && checkResults.Count > 0) if (checkResults != null && checkResults.Count > 0)
return Content("data-json=", "text/plain; charset=utf-8"); return Content("data-json=", "text/plain; charset=utf-8");
return OnError("klonfun", refresh_proxy: true); return OnError("lme.klonfun", refresh_proxy: true);
} }
string itemUrl = href; string itemUrl = href;
@ -52,14 +52,14 @@ namespace KlonFUN.Controllers
{ {
var searchResults = await invoke.Search(imdb_id, title, original_title); var searchResults = await invoke.Search(imdb_id, title, original_title);
if (searchResults == null || searchResults.Count == 0) if (searchResults == null || searchResults.Count == 0)
return OnError("klonfun", refresh_proxy: true); return OnError("lme.klonfun", refresh_proxy: true);
if (searchResults.Count > 1) if (searchResults.Count > 1)
{ {
var similarTpl = new SimilarTpl(searchResults.Count); var similarTpl = new SimilarTpl(searchResults.Count);
foreach (SearchResult result in searchResults) foreach (SearchResult result in searchResults)
{ {
string link = $"{host}/lite/klonfun?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(result.Url)}"; string link = $"{host}/lite/lme.klonfun?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(result.Url)}";
similarTpl.Append(result.Title, result.Year > 0 ? result.Year.ToString() : string.Empty, string.Empty, link, result.Poster); similarTpl.Append(result.Title, result.Year > 0 ? result.Year.ToString() : string.Empty, string.Empty, link, result.Poster);
} }
@ -75,7 +75,7 @@ namespace KlonFUN.Controllers
if (item == null || string.IsNullOrWhiteSpace(item.PlayerUrl)) if (item == null || string.IsNullOrWhiteSpace(item.PlayerUrl))
{ {
OnLog($"KlonFUN: не знайдено iframe-плеєр для {itemUrl}"); OnLog($"KlonFUN: не знайдено iframe-плеєр для {itemUrl}");
return OnError("klonfun", refresh_proxy: true); return OnError("lme.klonfun", refresh_proxy: true);
} }
string contentTitle = !string.IsNullOrWhiteSpace(title) ? title : item.Title; string contentTitle = !string.IsNullOrWhiteSpace(title) ? title : item.Title;
@ -89,7 +89,7 @@ namespace KlonFUN.Controllers
{ {
var serialStructure = await invoke.GetSerialStructure(item.PlayerUrl); var serialStructure = await invoke.GetSerialStructure(item.PlayerUrl);
if (serialStructure == null || serialStructure.Voices.Count == 0) if (serialStructure == null || serialStructure.Voices.Count == 0)
return OnError("klonfun", refresh_proxy: true); return OnError("lme.klonfun", refresh_proxy: true);
if (s == -1) if (s == -1)
{ {
@ -120,12 +120,12 @@ namespace KlonFUN.Controllers
} }
if (seasons.Count == 0) if (seasons.Count == 0)
return OnError("klonfun", refresh_proxy: true); return OnError("lme.klonfun", refresh_proxy: true);
var seasonTpl = new SeasonTpl(seasons.Count); var seasonTpl = new SeasonTpl(seasons.Count);
foreach (int seasonNumber in seasons) foreach (int seasonNumber in seasons)
{ {
string link = $"{host}/lite/klonfun?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={seasonNumber}&href={HttpUtility.UrlEncode(itemUrl)}"; string link = $"{host}/lite/lme.klonfun?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={seasonNumber}&href={HttpUtility.UrlEncode(itemUrl)}";
if (!string.IsNullOrWhiteSpace(t)) if (!string.IsNullOrWhiteSpace(t))
link += $"&t={HttpUtility.UrlEncode(t)}"; link += $"&t={HttpUtility.UrlEncode(t)}";
@ -142,7 +142,7 @@ namespace KlonFUN.Controllers
.ToList(); .ToList();
if (voicesForSeason.Count == 0) if (voicesForSeason.Count == 0)
return OnError("klonfun", refresh_proxy: true); return OnError("lme.klonfun", refresh_proxy: true);
var selectedVoiceForSeason = voicesForSeason var selectedVoiceForSeason = voicesForSeason
.FirstOrDefault(v => !string.IsNullOrWhiteSpace(t) && v.Key.Equals(t, StringComparison.OrdinalIgnoreCase)) .FirstOrDefault(v => !string.IsNullOrWhiteSpace(t) && v.Key.Equals(t, StringComparison.OrdinalIgnoreCase))
@ -151,12 +151,12 @@ namespace KlonFUN.Controllers
var voiceTpl = new VoiceTpl(voicesForSeason.Count); var voiceTpl = new VoiceTpl(voicesForSeason.Count);
foreach (var voice in voicesForSeason) foreach (var voice in voicesForSeason)
{ {
string voiceLink = $"{host}/lite/klonfun?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={s}&t={HttpUtility.UrlEncode(voice.Key)}&href={HttpUtility.UrlEncode(itemUrl)}"; string voiceLink = $"{host}/lite/lme.klonfun?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={s}&t={HttpUtility.UrlEncode(voice.Key)}&href={HttpUtility.UrlEncode(itemUrl)}";
voiceTpl.Append(voice.DisplayName, voice.Key.Equals(selectedVoiceForSeason.Key, StringComparison.OrdinalIgnoreCase), voiceLink); voiceTpl.Append(voice.DisplayName, voice.Key.Equals(selectedVoiceForSeason.Key, StringComparison.OrdinalIgnoreCase), voiceLink);
} }
if (!selectedVoiceForSeason.Seasons.TryGetValue(s, out List<SerialEpisode> episodes) || episodes.Count == 0) if (!selectedVoiceForSeason.Seasons.TryGetValue(s, out List<SerialEpisode> episodes) || episodes.Count == 0)
return OnError("klonfun", refresh_proxy: true); return OnError("lme.klonfun", refresh_proxy: true);
var episodeTpl = new EpisodeTpl(episodes.Count); var episodeTpl = new EpisodeTpl(episodes.Count);
foreach (SerialEpisode episode in episodes.OrderBy(e => e.Number)) foreach (SerialEpisode episode in episodes.OrderBy(e => e.Number))
@ -179,7 +179,7 @@ namespace KlonFUN.Controllers
{ {
var streams = await invoke.GetMovieStreams(item.PlayerUrl); var streams = await invoke.GetMovieStreams(item.PlayerUrl);
if (streams == null || streams.Count == 0) if (streams == null || streams.Count == 0)
return OnError("klonfun", refresh_proxy: true); return OnError("lme.klonfun", refresh_proxy: true);
var movieTpl = new MovieTpl(contentTitle, contentOriginalTitle, streams.Count); var movieTpl = new MovieTpl(contentTitle, contentOriginalTitle, streams.Count);
for (int i = 0; i < streams.Count; i++) for (int i = 0; i < streams.Count; i++)

View File

@ -6,7 +6,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
using HtmlAgilityPack; using HtmlAgilityPack;
using KlonFUN.Models; using LME.KlonFUN.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Shared; using Shared;
@ -14,7 +14,7 @@ using Shared.Engine;
using Shared.Models; using Shared.Models;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
namespace KlonFUN namespace LME.KlonFUN
{ {
public class KlonFUNInvoke public class KlonFUNInvoke
{ {

View File

@ -16,11 +16,11 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Shared.Models.Events; using Shared.Models.Events;
namespace KlonFUN namespace LME.KlonFUN
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 2.0; public static double Version => 2.1;
public static ModuleConfig KlonFUN; public static ModuleConfig KlonFUN;
public static bool ApnHostProvided; public static bool ApnHostProvided;
@ -41,12 +41,12 @@ namespace KlonFUN
EventListener.UpdateInitFile += UpdateConfig; EventListener.UpdateInitFile += UpdateConfig;
// Додаємо підтримку "уточнити пошук". // Додаємо підтримку "уточнити пошук".
RegisterWithSearch("klonfun"); RegisterWithSearch("lme.klonfun");
} }
private void UpdateConfig() private void UpdateConfig()
{ {
KlonFUN = new ModuleConfig("KlonFUN", "https://klon.fun", streamproxy: false, useproxy: false) KlonFUN = new ModuleConfig("LME.KlonFUN", "https://klon.fun", streamproxy: false, useproxy: false)
{ {
displayname = "KlonFUN", displayname = "KlonFUN",
displayindex = 0, displayindex = 0,
@ -66,7 +66,7 @@ namespace KlonFUN
["ashdi"] = ApnHelper.DefaultHost ["ashdi"] = ApnHelper.DefaultHost
}; };
var conf = ModuleInvoke.Init("KlonFUN", defaults) ?? defaults; var conf = ModuleInvoke.Init("LME.KlonFUN", defaults) ?? defaults;
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost); bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf); MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf);
conf.Remove("magic_apn"); conf.Remove("magic_apn");

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace KlonFUN.Models namespace LME.KlonFUN.Models
{ {
public class SearchResult public class SearchResult
{ {

View File

@ -1,6 +1,6 @@
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
namespace KlonFUN namespace LME.KlonFUN
{ {
public class MagicApnSettings public class MagicApnSettings
{ {

View File

@ -6,7 +6,7 @@ using Shared.Models.Module.Interfaces;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace KlonFUN namespace LME.KlonFUN
{ {
public class OnlineApi : IModuleOnline public class OnlineApi : IModuleOnline
{ {
@ -26,7 +26,7 @@ namespace KlonFUN
if (UpdateService.IsDisconnected()) if (UpdateService.IsDisconnected())
init.overridehost = null; init.overridehost = null;
online.Add(new ModuleOnlineItem(init, "klonfun")); online.Add(new ModuleOnlineItem(init, "lme.klonfun"));
} }
return online; return online;

View File

@ -0,0 +1,5 @@
{
"enable": true,
"initspace": "LME.KlonFUN.ModInit",
"online": "LME.KlonFUN.OnlineApi"
}

View File

@ -9,11 +9,11 @@ using Shared;
using Shared.Models.Templates; using Shared.Models.Templates;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using Shared.Models; using Shared.Models;
using Makhno.Models; using LME.Makhno.Models;
namespace Makhno namespace LME.Makhno
{ {
[Route("lite/makhno")] [Route("lite/lme.makhno")]
public class MakhnoController : BaseOnlineController public class MakhnoController : BaseOnlineController
{ {
private readonly ProxyManager proxyManager; private readonly ProxyManager proxyManager;
@ -42,7 +42,7 @@ namespace Makhno
TryEnableMagicApn(init); TryEnableMagicApn(init);
Initialization(init); Initialization(init);
OnLog($"Makhno: {title} (serial={serial}, s={s}, season={season}, t={t})"); OnLog($"lme.makhno: {title} (serial={serial}, s={s}, season={season}, t={t})");
var invoke = new MakhnoInvoke(init, hybridCache, OnLog, proxyManager, httpHydra); var invoke = new MakhnoInvoke(init, hybridCache, OnLog, proxyManager, httpHydra);
@ -75,14 +75,14 @@ namespace Makhno
if (resolved == null || string.IsNullOrEmpty(resolved.PlayUrl)) if (resolved == null || string.IsNullOrEmpty(resolved.PlayUrl))
return OnError(); return OnError();
var playerData = await InvokeCache<PlayerData>($"makhno:player:{resolved.PlayUrl}", TimeSpan.FromMinutes(10), async () => var playerData = await InvokeCache<PlayerData>($"lme.makhno:player:{resolved.PlayUrl}", TimeSpan.FromMinutes(10), async () =>
{ {
return await invoke.GetPlayerData(resolved.PlayUrl); return await invoke.GetPlayerData(resolved.PlayUrl);
}); });
if (playerData?.Voices == null || !playerData.Voices.Any()) if (playerData?.Voices == null || !playerData.Voices.Any())
{ {
OnLog("Makhno Play: no voices parsed"); OnLog("lme.makhno Play: no voices parsed");
return OnError(); return OnError();
} }
@ -99,7 +99,7 @@ namespace Makhno
{ {
if (episode.Id == episodeId && !string.IsNullOrEmpty(episode.File)) if (episode.Id == episodeId && !string.IsNullOrEmpty(episode.File))
{ {
OnLog($"Makhno Play: Found episode {episode.Title}, stream: {episode.File}"); OnLog($"lme.makhno Play: Found episode {episode.Title}, stream: {episode.File}");
string streamUrl = BuildStreamUrl(init, episode.File); string streamUrl = BuildStreamUrl(init, episode.File);
string episodeTitle = $"{title ?? original_title} - {episode.Title}"; string episodeTitle = $"{title ?? original_title} - {episode.Title}";
@ -111,7 +111,7 @@ namespace Makhno
} }
} }
OnLog("Makhno Play: Episode not found"); OnLog("lme.makhno Play: Episode not found");
return OnError(); return OnError();
} }
@ -127,21 +127,21 @@ namespace Makhno
TryEnableMagicApn(init); TryEnableMagicApn(init);
Initialization(init); Initialization(init);
OnLog($"Makhno PlayMovie: {title} ({year}) play={play}"); OnLog($"lme.makhno PlayMovie: {title} ({year}) play={play}");
var invoke = new MakhnoInvoke(init, hybridCache, OnLog, proxyManager, httpHydra); var invoke = new MakhnoInvoke(init, hybridCache, OnLog, proxyManager, httpHydra);
var resolved = await ResolvePlaySource(imdb_id, serial: 0, invoke); var resolved = await ResolvePlaySource(imdb_id, serial: 0, invoke);
if (resolved == null || string.IsNullOrEmpty(resolved.PlayUrl)) if (resolved == null || string.IsNullOrEmpty(resolved.PlayUrl))
return OnError(); return OnError();
var playerData = await InvokeCache<PlayerData>($"makhno:player:{resolved.PlayUrl}", TimeSpan.FromMinutes(10), async () => var playerData = await InvokeCache<PlayerData>($"lme.makhno:player:{resolved.PlayUrl}", TimeSpan.FromMinutes(10), async () =>
{ {
return await invoke.GetPlayerData(resolved.PlayUrl); return await invoke.GetPlayerData(resolved.PlayUrl);
}); });
if (playerData?.File == null) if (playerData?.File == null)
{ {
OnLog("Makhno PlayMovie: no file parsed"); OnLog("lme.makhno PlayMovie: no file parsed");
return OnError(); return OnError();
} }
@ -156,7 +156,7 @@ namespace Makhno
private async Task<ActionResult> HandleMovie(string playUrl, string imdb_id, string title, string original_title, int year, bool rjson, MakhnoInvoke invoke) private async Task<ActionResult> HandleMovie(string playUrl, string imdb_id, string title, string original_title, int year, bool rjson, MakhnoInvoke invoke)
{ {
var init = ModInit.Makhno; var init = ModInit.Makhno;
var playerData = await InvokeCache<PlayerData>($"makhno:player:{playUrl}", TimeSpan.FromMinutes(10), async () => var playerData = await InvokeCache<PlayerData>($"lme.makhno:player:{playUrl}", TimeSpan.FromMinutes(10), async () =>
{ {
return await invoke.GetPlayerData(playUrl); return await invoke.GetPlayerData(playUrl);
}); });
@ -177,7 +177,7 @@ namespace Makhno
if (movieStreams.Count == 0) if (movieStreams.Count == 0)
{ {
OnLog("Makhno HandleMovie: no file parsed"); OnLog("lme.makhno HandleMovie: no file parsed");
return OnError(); return OnError();
} }
@ -200,14 +200,14 @@ namespace Makhno
{ {
var init = ModInit.Makhno; var init = ModInit.Makhno;
var playerData = await InvokeCache<PlayerData>($"makhno:player:{playUrl}", TimeSpan.FromMinutes(10), async () => var playerData = await InvokeCache<PlayerData>($"lme.makhno:player:{playUrl}", TimeSpan.FromMinutes(10), async () =>
{ {
return await invoke.GetPlayerData(playUrl); return await invoke.GetPlayerData(playUrl);
}); });
if (playerData?.Voices == null || !playerData.Voices.Any()) if (playerData?.Voices == null || !playerData.Voices.Any())
{ {
OnLog("Makhno HandleSerial: no voices parsed"); OnLog("lme.makhno HandleSerial: no voices parsed");
return OnError(); return OnError();
} }
@ -270,7 +270,7 @@ namespace Makhno
string voiceParam = seasonVoiceIndex.HasValue ? $"&t={seasonVoiceIndex.Value}" : string.Empty; string voiceParam = seasonVoiceIndex.HasValue ? $"&t={seasonVoiceIndex.Value}" : string.Empty;
string seasonName = seasonItem.HasValue ? seasonItem.Value.Season?.Title ?? $"Сезон {seasonNumber}" : $"Сезон {seasonNumber}"; string seasonName = seasonItem.HasValue ? seasonItem.Value.Season?.Title ?? $"Сезон {seasonNumber}" : $"Сезон {seasonNumber}";
string link = $"{host}/lite/makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season={seasonNumber}{voiceParam}"; string link = $"{host}/lite/lme.makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season={seasonNumber}{voiceParam}";
season_tpl.Append(seasonName, link, seasonNumber.ToString()); season_tpl.Append(seasonName, link, seasonNumber.ToString());
} }
@ -340,7 +340,7 @@ namespace Makhno
string voiceParam = seasonVoiceIndexForTpl.HasValue ? $"&t={seasonVoiceIndexForTpl.Value}" : string.Empty; string voiceParam = seasonVoiceIndexForTpl.HasValue ? $"&t={seasonVoiceIndexForTpl.Value}" : string.Empty;
string seasonName = seasonItem.HasValue ? seasonItem.Value.Season?.Title ?? $"Сезон {seasonNumber}" : $"Сезон {seasonNumber}"; string seasonName = seasonItem.HasValue ? seasonItem.Value.Season?.Title ?? $"Сезон {seasonNumber}" : $"Сезон {seasonNumber}";
string link = $"{host}/lite/makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season={seasonNumber}{voiceParam}"; string link = $"{host}/lite/lme.makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season={seasonNumber}{voiceParam}";
seasonTplForVoice.Append(seasonName, link, seasonNumber.ToString()); seasonTplForVoice.Append(seasonName, link, seasonNumber.ToString());
} }
@ -357,11 +357,11 @@ namespace Makhno
bool sameSeasonSet = seasonsForVoice.Select(s => s.Number).ToHashSet().SetEquals(selectedVoiceSeasonSet); bool sameSeasonSet = seasonsForVoice.Select(s => s.Number).ToHashSet().SetEquals(selectedVoiceSeasonSet);
if (hasRequestedSeason && sameSeasonSet) if (hasRequestedSeason && sameSeasonSet)
{ {
voiceLink = $"{host}/lite/makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season={requestedSeason}&t={i}"; voiceLink = $"{host}/lite/lme.makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season={requestedSeason}&t={i}";
} }
else else
{ {
voiceLink = $"{host}/lite/makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season=-1&t={i}"; voiceLink = $"{host}/lite/lme.makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season=-1&t={i}";
} }
bool isActive = selectedVoice == i.ToString(); bool isActive = selectedVoice == i.ToString();
@ -377,7 +377,7 @@ namespace Makhno
bool hasRequestedSeason = seasonsForVoice.Any(s => s.Number == requestedSeason); bool hasRequestedSeason = seasonsForVoice.Any(s => s.Number == requestedSeason);
if (!hasRequestedSeason) if (!hasRequestedSeason)
{ {
string redirectUrl = $"{host}/lite/makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season=-1&t={voiceIndex}"; string redirectUrl = $"{host}/lite/lme.makhno?imdb_id={imdb_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&season=-1&t={voiceIndex}";
return UpdateService.Validate(Redirect(redirectUrl)); return UpdateService.Validate(Redirect(redirectUrl));
} }
@ -448,7 +448,7 @@ namespace Makhno
if (string.IsNullOrWhiteSpace(imdbId)) if (string.IsNullOrWhiteSpace(imdbId))
return null; return null;
string cacheKey = $"makhno:wormhole:{imdbId}"; string cacheKey = $"lme.makhno:wormhole:{imdbId}";
string playUrl = await InvokeCache<string>(cacheKey, TimeSpan.FromMinutes(5), async () => string playUrl = await InvokeCache<string>(cacheKey, TimeSpan.FromMinutes(5), async () =>
{ {
return await invoke.GetWormholePlay(imdbId); return await invoke.GetWormholePlay(imdbId);
@ -530,7 +530,7 @@ namespace Makhno
return; return;
ApnHelper.ApplyInitConf(true, ModInit.MagicApnAshdiHost, init); ApnHelper.ApplyInitConf(true, ModInit.MagicApnAshdiHost, init);
OnLog($"Makhno: увімкнено magic_apn для Ashdi (player={player ?? "unknown"})."); OnLog($"lme.makhno: увімкнено magic_apn для Ashdi (player={player ?? "unknown"}).");
} }
private class ResolveResult private class ResolveResult

View File

@ -10,9 +10,9 @@ using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models; using Shared.Models;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using Makhno.Models; using LME.Makhno.Models;
namespace Makhno namespace LME.Makhno
{ {
public class MakhnoInvoke public class MakhnoInvoke
{ {
@ -57,7 +57,7 @@ namespace Makhno
} }
catch (Exception ex) catch (Exception ex)
{ {
_onLog($"Makhno wormhole error: {ex.Message}"); _onLog($"lme.makhno wormhole error: {ex.Message}");
return null; return null;
} }
} }
@ -84,7 +84,7 @@ namespace Makhno
if (ApnHelper.IsAshdiUrl(sourceUrl) && ApnHelper.IsEnabled(_init) && string.IsNullOrWhiteSpace(_init.webcorshost)) if (ApnHelper.IsAshdiUrl(sourceUrl) && ApnHelper.IsEnabled(_init) && string.IsNullOrWhiteSpace(_init.webcorshost))
requestUrl = ApnHelper.WrapUrl(_init, sourceUrl); requestUrl = ApnHelper.WrapUrl(_init, sourceUrl);
_onLog($"Makhno getting player data from: {requestUrl}"); _onLog($"lme.makhno getting player data from: {requestUrl}");
var response = await HttpGet(requestUrl, headers); var response = await HttpGet(requestUrl, headers);
if (string.IsNullOrEmpty(response)) if (string.IsNullOrEmpty(response))
@ -133,14 +133,14 @@ namespace Makhno
string jsonData = ExtractPlayerJson(html); string jsonData = ExtractPlayerJson(html);
if (jsonData == null) if (jsonData == null)
_onLog("Makhno ParsePlayerData: file array not found"); _onLog("lme.makhno ParsePlayerData: file array not found");
else else
_onLog($"Makhno ParsePlayerData: file array length={jsonData.Length}"); _onLog($"lme.makhno ParsePlayerData: file array length={jsonData.Length}");
if (!string.IsNullOrEmpty(jsonData)) if (!string.IsNullOrEmpty(jsonData))
{ {
var voices = ParseVoicesJson(jsonData); var voices = ParseVoicesJson(jsonData);
var movies = ParseMovieVariantsJson(jsonData); var movies = ParseMovieVariantsJson(jsonData);
_onLog($"Makhno ParsePlayerData: voices={voices?.Count ?? 0}"); _onLog($"lme.makhno ParsePlayerData: voices={voices?.Count ?? 0}");
return new PlayerData return new PlayerData
{ {
File = movies.FirstOrDefault()?.File, File = movies.FirstOrDefault()?.File,
@ -153,7 +153,7 @@ namespace Makhno
var m3u8Match = Regex.Match(html, @"(https?://[^""'\s>]+\.m3u8[^""'\s>]*)", RegexOptions.IgnoreCase); var m3u8Match = Regex.Match(html, @"(https?://[^""'\s>]+\.m3u8[^""'\s>]*)", RegexOptions.IgnoreCase);
if (m3u8Match.Success) if (m3u8Match.Success)
{ {
_onLog("Makhno ParsePlayerData: fallback m3u8 match"); _onLog("lme.makhno ParsePlayerData: fallback m3u8 match");
return new PlayerData return new PlayerData
{ {
File = m3u8Match.Groups[1].Value, File = m3u8Match.Groups[1].Value,
@ -174,7 +174,7 @@ namespace Makhno
var sourceMatch = Regex.Match(html, @"<source[^>]*src=[""']([^""']+)[""']", RegexOptions.IgnoreCase); var sourceMatch = Regex.Match(html, @"<source[^>]*src=[""']([^""']+)[""']", RegexOptions.IgnoreCase);
if (sourceMatch.Success) if (sourceMatch.Success)
{ {
_onLog("Makhno ParsePlayerData: fallback source match"); _onLog("lme.makhno ParsePlayerData: fallback source match");
return new PlayerData return new PlayerData
{ {
File = sourceMatch.Groups[1].Value, File = sourceMatch.Groups[1].Value,
@ -196,7 +196,7 @@ namespace Makhno
} }
catch (Exception ex) catch (Exception ex)
{ {
_onLog($"Makhno ParsePlayerData error: {ex.Message}"); _onLog($"lme.makhno ParsePlayerData error: {ex.Message}");
return null; return null;
} }
} }
@ -263,7 +263,7 @@ namespace Makhno
} }
catch (Exception ex) catch (Exception ex)
{ {
_onLog($"Makhno ParseVoicesJson error: {ex.Message}"); _onLog($"lme.makhno ParseVoicesJson error: {ex.Message}");
return new List<Voice>(); return new List<Voice>();
} }
} }
@ -298,7 +298,7 @@ namespace Makhno
} }
catch (Exception ex) catch (Exception ex)
{ {
_onLog($"Makhno ParseMovieVariantsJson error: {ex.Message}"); _onLog($"lme.makhno ParseMovieVariantsJson error: {ex.Message}");
return new List<MovieVariant>(); return new List<MovieVariant>();
} }
} }

View File

@ -20,11 +20,11 @@ using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Makhno namespace LME.Makhno
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 3.0; public static double Version => 3.1;
public static OnlinesSettings Makhno; public static OnlinesSettings Makhno;
public static bool ApnHostProvided; public static bool ApnHostProvided;
@ -41,7 +41,7 @@ namespace Makhno
/// </summary> /// </summary>
public void Loaded(InitspaceModel initspace) public void Loaded(InitspaceModel initspace)
{ {
Makhno = new OnlinesSettings("Makhno", "https://wh.lme.isroot.in", streamproxy: false, useproxy: false) Makhno = new OnlinesSettings("LME.Makhno", "https://wh.lme.isroot.in", streamproxy: false, useproxy: false)
{ {
displayname = "Махно", displayname = "Махно",
displayindex = 0, displayindex = 0,
@ -60,7 +60,7 @@ namespace Makhno
["ashdi"] = ApnHelper.DefaultHost ["ashdi"] = ApnHelper.DefaultHost
}; };
var conf = ModuleInvoke.Init("Makhno", defaults) ?? defaults; var conf = ModuleInvoke.Init("LME.Makhno", defaults) ?? defaults;
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost); bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf); MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf);
conf.Remove("magic_apn"); conf.Remove("magic_apn");
@ -84,7 +84,7 @@ namespace Makhno
} }
// Виводити "уточнити пошук" // Виводити "уточнити пошук"
RegisterWithSearch("makhno"); RegisterWithSearch("lme.makhno");
} }
private static void RegisterWithSearch(string plugin) private static void RegisterWithSearch(string plugin)

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Makhno.Models namespace LME.Makhno.Models
{ {
public class PlayerData public class PlayerData
{ {

View File

@ -6,7 +6,7 @@ using Shared.Models.Module.Interfaces;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Makhno namespace LME.Makhno
{ {
public class OnlineApi : IModuleOnline public class OnlineApi : IModuleOnline
{ {
@ -15,7 +15,7 @@ namespace Makhno
long.TryParse(args.id, out long tmdbid); long.TryParse(args.id, out long tmdbid);
return Events(host, tmdbid, args.imdb_id, args.kinopoisk_id, args.title, args.original_title, args.original_language, args.year, args.source, args.serial, args.account_email); return Events(host, tmdbid, args.imdb_id, args.kinopoisk_id, args.title, args.original_title, args.original_language, args.year, args.source, args.serial, args.account_email);
} }
private static List<ModuleOnlineItem> Events(string host, long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email) private static List<ModuleOnlineItem> Events(string host, long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email)
{ {
var online = new List<ModuleOnlineItem>(); var online = new List<ModuleOnlineItem>();
@ -26,7 +26,7 @@ namespace Makhno
if (UpdateService.IsDisconnected()) if (UpdateService.IsDisconnected())
init.overridehost = null; init.overridehost = null;
online.Add(new ModuleOnlineItem(init, "makhno")); online.Add(new ModuleOnlineItem(init, "lme.makhno"));
} }
return online; return online;

5
LME.Makhno/manifest.json Normal file
View File

@ -0,0 +1,5 @@
{
"enable": true,
"initspace": "LME.Makhno.ModInit",
"online": "LME.Makhno.OnlineApi"
}

View File

@ -4,14 +4,14 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Mikai.Models; using LME.Mikai.Models;
using Shared; using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models; using Shared.Models;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using Shared.Models.Templates; using Shared.Models.Templates;
namespace Mikai.Controllers namespace LME.Mikai.Controllers
{ {
public class Controller : BaseOnlineController public class Controller : BaseOnlineController
{ {
@ -23,7 +23,7 @@ namespace Mikai.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/mikai")] [Route("lite/lme.mikai")]
public async Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, bool checksearch = false) public async Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, bool checksearch = false)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -38,34 +38,34 @@ namespace Mikai.Controllers
if (checksearch) if (checksearch)
{ {
if (!IsCheckOnlineSearchEnabled()) if (!IsCheckOnlineSearchEnabled())
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
var checkResults = await invoke.Search(title, original_title, year); var checkResults = await invoke.Search(title, original_title, year);
if (checkResults != null && checkResults.Count > 0) if (checkResults != null && checkResults.Count > 0)
return Content("data-json=", "text/plain; charset=utf-8"); return Content("data-json=", "text/plain; charset=utf-8");
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
} }
OnLog($"Mikai Index: title={title}, original_title={original_title}, serial={serial}, s={s}, t={t}, year={year}"); OnLog($"Mikai Index: title={title}, original_title={original_title}, serial={serial}, s={s}, t={t}, year={year}");
var searchResults = await invoke.Search(title, original_title, year); var searchResults = await invoke.Search(title, original_title, year);
if (searchResults == null || searchResults.Count == 0) if (searchResults == null || searchResults.Count == 0)
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
var selected = searchResults.FirstOrDefault(); var selected = searchResults.FirstOrDefault();
if (selected == null) if (selected == null)
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
var details = await invoke.GetDetails(selected.Id); var details = await invoke.GetDetails(selected.Id);
if (details == null || details.Players == null || details.Players.Count == 0) if (details == null || details.Players == null || details.Players.Count == 0)
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
bool isSerial = serial == 1 || (serial == -1 && !string.Equals(details.Format, "movie", StringComparison.OrdinalIgnoreCase)); bool isSerial = serial == 1 || (serial == -1 && !string.Equals(details.Format, "movie", StringComparison.OrdinalIgnoreCase));
var seasonDetails = await CollectSeasonDetails(details, invoke); var seasonDetails = await CollectSeasonDetails(details, invoke);
var voices = BuildVoices(seasonDetails); var voices = BuildVoices(seasonDetails);
if (voices.Count == 0) if (voices.Count == 0)
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
string displayTitle = title ?? details.Details?.Names?.Name ?? original_title; string displayTitle = title ?? details.Details?.Names?.Name ?? original_title;
@ -82,14 +82,14 @@ namespace Mikai.Controllers
.ToList(); .ToList();
if (seasonNumbers.Count == 0) if (seasonNumbers.Count == 0)
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
if (s == -1) if (s == -1)
{ {
var seasonTpl = new SeasonTpl(seasonNumbers.Count); var seasonTpl = new SeasonTpl(seasonNumbers.Count);
foreach (var seasonNumber in seasonNumbers) foreach (var seasonNumber in seasonNumbers)
{ {
string link = $"{host}/lite/mikai?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={seasonNumber}"; string link = $"{host}/lite/lme.mikai?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={seasonNumber}";
if (restrictByVoice) if (restrictByVoice)
link += $"&t={HttpUtility.UrlEncode(t)}"; link += $"&t={HttpUtility.UrlEncode(t)}";
seasonTpl.Append($"{seasonNumber}", link, seasonNumber.ToString()); seasonTpl.Append($"{seasonNumber}", link, seasonNumber.ToString());
@ -105,7 +105,7 @@ namespace Mikai.Controllers
.ToList(); .ToList();
if (!voicesForSeason.Any()) if (!voicesForSeason.Any())
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
if (string.IsNullOrEmpty(t)) if (string.IsNullOrEmpty(t))
t = voicesForSeason[0].Key; t = voicesForSeason[0].Key;
@ -119,7 +119,7 @@ namespace Mikai.Controllers
{ {
var targetSeasonSet = GetSeasonSet(voice.Value); var targetSeasonSet = GetSeasonSet(voice.Value);
bool sameSeasonSet = targetSeasonSet.SetEquals(selectedSeasonSet); bool sameSeasonSet = targetSeasonSet.SetEquals(selectedSeasonSet);
string voiceLink = $"{host}/lite/mikai?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1"; string voiceLink = $"{host}/lite/lme.mikai?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1";
if (sameSeasonSet) if (sameSeasonSet)
voiceLink += $"&s={s}&t={HttpUtility.UrlEncode(voice.Key)}"; voiceLink += $"&s={s}&t={HttpUtility.UrlEncode(voice.Key)}";
else else
@ -129,7 +129,7 @@ namespace Mikai.Controllers
if (!voices.ContainsKey(t) || !voices[t].Seasons.ContainsKey(s)) if (!voices.ContainsKey(t) || !voices[t].Seasons.ContainsKey(s))
{ {
string redirectUrl = $"{host}/lite/mikai?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s=-1&t={HttpUtility.UrlEncode(t)}"; string redirectUrl = $"{host}/lite/lme.mikai?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s=-1&t={HttpUtility.UrlEncode(t)}";
return Redirect(redirectUrl); return Redirect(redirectUrl);
} }
@ -144,7 +144,7 @@ namespace Mikai.Controllers
if (NeedsResolve(voices[t].ProviderName, streamLink)) if (NeedsResolve(voices[t].ProviderName, streamLink))
{ {
string callUrl = $"{host}/lite/mikai/play?url={HttpUtility.UrlEncode(streamLink)}&title={HttpUtility.UrlEncode(displayTitle)}&serial=1"; string callUrl = $"{host}/lite/lme.mikai/play?url={HttpUtility.UrlEncode(streamLink)}&title={HttpUtility.UrlEncode(displayTitle)}&serial=1";
episodeTpl.Append(episodeName, displayTitle, s.ToString(), ep.Number.ToString(), accsArgs(callUrl), "call"); episodeTpl.Append(episodeName, displayTitle, s.ToString(), ep.Number.ToString(), accsArgs(callUrl), "call");
} }
else else
@ -178,14 +178,14 @@ namespace Mikai.Controllers
foreach (var ashdiStream in ashdiStreams) foreach (var ashdiStream in ashdiStreams)
{ {
string optionName = $"{voice.DisplayName} {ashdiStream.title}"; string optionName = $"{voice.DisplayName} {ashdiStream.title}";
string ashdiCallUrl = $"{host}/lite/mikai/play?url={HttpUtility.UrlEncode(ashdiStream.link)}&title={HttpUtility.UrlEncode(displayTitle)}"; string ashdiCallUrl = $"{host}/lite/lme.mikai/play?url={HttpUtility.UrlEncode(ashdiStream.link)}&title={HttpUtility.UrlEncode(displayTitle)}";
movieTpl.Append(optionName, accsArgs(ashdiCallUrl), "call"); movieTpl.Append(optionName, accsArgs(ashdiCallUrl), "call");
} }
continue; continue;
} }
} }
string callUrl = $"{host}/lite/mikai/play?url={HttpUtility.UrlEncode(episode.Url)}&title={HttpUtility.UrlEncode(displayTitle)}"; string callUrl = $"{host}/lite/lme.mikai/play?url={HttpUtility.UrlEncode(episode.Url)}&title={HttpUtility.UrlEncode(displayTitle)}";
movieTpl.Append(voice.DisplayName, accsArgs(callUrl), "call"); movieTpl.Append(voice.DisplayName, accsArgs(callUrl), "call");
} }
else else
@ -196,14 +196,14 @@ namespace Mikai.Controllers
} }
if (movieTpl.data == null || movieTpl.data.Count == 0) if (movieTpl.data == null || movieTpl.data.Count == 0)
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
return rjson return rjson
? Content(movieTpl.ToJson(), "application/json; charset=utf-8") ? Content(movieTpl.ToJson(), "application/json; charset=utf-8")
: Content(movieTpl.ToHtml(), "text/html; charset=utf-8"); : Content(movieTpl.ToHtml(), "text/html; charset=utf-8");
} }
[HttpGet("lite/mikai/play")] [HttpGet("lite/lme.mikai/play")]
public async Task<ActionResult> Play(string url, string title = null, int serial = 0) public async Task<ActionResult> Play(string url, string title = null, int serial = 0)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -214,14 +214,14 @@ namespace Mikai.Controllers
TryEnableMagicApn(init); TryEnableMagicApn(init);
if (string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
var invoke = new MikaiInvoke(init, hybridCache, OnLog, _proxyManager, httpHydra); var invoke = new MikaiInvoke(init, hybridCache, OnLog, _proxyManager, httpHydra);
OnLog($"Mikai Play: url={url}, serial={serial}"); OnLog($"Mikai Play: url={url}, serial={serial}");
string streamLink = await invoke.ResolveVideoUrl(url, serial == 1); string streamLink = await invoke.ResolveVideoUrl(url, serial == 1);
if (string.IsNullOrEmpty(streamLink)) if (string.IsNullOrEmpty(streamLink))
return OnError("mikai", refresh_proxy: true); return OnError("lme.mikai", refresh_proxy: true);
List<HeadersModel> streamHeaders = null; List<HeadersModel> streamHeaders = null;
bool forceProxy = false; bool forceProxy = false;

View File

@ -6,13 +6,13 @@ using System.Threading.Tasks;
using System.Web; using System.Web;
using System.Net; using System.Net;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Mikai.Models; using LME.Mikai.Models;
using Shared; using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models; using Shared.Models;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
namespace Mikai namespace LME.Mikai
{ {
public class MikaiInvoke public class MikaiInvoke
{ {

View File

@ -21,11 +21,11 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Mikai namespace LME.Mikai
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 4.0; public static double Version => 4.1;
public static OnlinesSettings Mikai; public static OnlinesSettings Mikai;
public static bool ApnHostProvided; public static bool ApnHostProvided;
@ -42,9 +42,9 @@ namespace Mikai
/// </summary> /// </summary>
public void Loaded(InitspaceModel initspace) public void Loaded(InitspaceModel initspace)
{ {
Mikai = new OnlinesSettings("Mikai", "https://mikai.me", streamproxy: false, useproxy: false)
Mikai = new OnlinesSettings("LME.Mikai", "https://mikai.me", streamproxy: false, useproxy: false)
{ {
displayname = "Mikai", displayname = "Mikai",
displayindex = 0, displayindex = 0,
@ -65,7 +65,7 @@ namespace Mikai
["ashdi"] = ApnHelper.DefaultHost ["ashdi"] = ApnHelper.DefaultHost
}; };
var conf = ModuleInvoke.Init("Mikai", defaults) ?? defaults; var conf = ModuleInvoke.Init("LME.Mikai", defaults) ?? defaults;
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost); bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf); MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf);
conf.Remove("magic_apn"); conf.Remove("magic_apn");
@ -86,7 +86,7 @@ namespace Mikai
} }
// Виводити "уточнити пошук" // Виводити "уточнити пошук"
RegisterWithSearch("mikai"); RegisterWithSearch("lme.mikai");
} }
private static void RegisterWithSearch(string plugin) private static void RegisterWithSearch(string plugin)

View File

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Mikai.Models namespace LME.Mikai.Models
{ {
public class SearchResponse public class SearchResponse
{ {

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Mikai.Models namespace LME.Mikai.Models
{ {
public class MikaiVoiceInfo public class MikaiVoiceInfo
{ {

View File

@ -6,7 +6,7 @@ using Shared.Models.Module.Interfaces;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Mikai namespace LME.Mikai
{ {
public class OnlineApi : IModuleOnline public class OnlineApi : IModuleOnline
{ {
@ -30,7 +30,7 @@ namespace Mikai
if (UpdateService.IsDisconnected()) if (UpdateService.IsDisconnected())
init.overridehost = null; init.overridehost = null;
online.Add(new ModuleOnlineItem(init, "mikai")); online.Add(new ModuleOnlineItem(init, "lme.mikai"));
} }
return online; return online;

6
LME.Mikai/manifest.json Normal file
View File

@ -0,0 +1,6 @@
{
"enable": true,
"version": 3,
"initspace": "LME.Mikai.ModInit",
"online": "LME.Mikai.OnlineApi"
}

View File

@ -1,5 +1,5 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NMoonAnime.Models; using LME.NMoonAnime.Models;
using Shared; using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models; using Shared.Models;
@ -13,7 +13,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
namespace NMoonAnime.Controllers namespace LME.NMoonAnime.Controllers
{ {
public class Controller : BaseOnlineController public class Controller : BaseOnlineController
{ {
@ -25,7 +25,7 @@ namespace NMoonAnime.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/nmoonanime")] [Route("lite/lme.nmoonanime")]
public async Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string mal_id, string t, int s = -1, bool rjson = false, bool checksearch = false) public async Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string mal_id, string t, int s = -1, bool rjson = false, bool checksearch = false)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -40,20 +40,20 @@ namespace NMoonAnime.Controllers
if (checksearch) if (checksearch)
{ {
if (!IsCheckOnlineSearchEnabled()) if (!IsCheckOnlineSearchEnabled())
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
var checkResults = await invoke.Search(imdb_id, effectiveMalId, title, year); var checkResults = await invoke.Search(imdb_id, effectiveMalId, title, year);
if (checkResults != null && checkResults.Count > 0) if (checkResults != null && checkResults.Count > 0)
return Content("data-json=", "text/plain; charset=utf-8"); return Content("data-json=", "text/plain; charset=utf-8");
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
} }
OnLog($"NMoonAnime: назва={title}, source={source}, imdb={imdb_id}, kinopoisk_id(як mal_id)={kinopoisk_id}, mal_id_ефективний={effectiveMalId}, рік={year}, серіал={serial}, сезон={s}, озвучка={t}"); OnLog($"NMoonAnime: назва={title}, source={source}, imdb={imdb_id}, kinopoisk_id(як mal_id)={kinopoisk_id}, mal_id_ефективний={effectiveMalId}, рік={year}, серіал={serial}, сезон={s}, озвучка={t}");
var seasons = await invoke.Search(imdb_id, effectiveMalId, title, year); var seasons = await invoke.Search(imdb_id, effectiveMalId, title, year);
if (seasons == null || seasons.Count == 0) if (seasons == null || seasons.Count == 0)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
bool isSeries = serial == 1; bool isSeries = serial == 1;
NMoonAnimeSeasonContent firstSeasonData = null; NMoonAnimeSeasonContent firstSeasonData = null;
@ -62,7 +62,7 @@ namespace NMoonAnime.Controllers
{ {
firstSeasonData = await invoke.GetSeasonContent(seasons[0]); firstSeasonData = await invoke.GetSeasonContent(seasons[0]);
if (firstSeasonData == null || firstSeasonData.Voices.Count == 0) if (firstSeasonData == null || firstSeasonData.Voices.Count == 0)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
isSeries = firstSeasonData.IsSeries; isSeries = firstSeasonData.IsSeries;
} }
@ -75,7 +75,7 @@ namespace NMoonAnime.Controllers
return await RenderMovie(invoke, seasons, title, original_title, firstSeasonData, rjson); return await RenderMovie(invoke, seasons, title, original_title, firstSeasonData, rjson);
} }
[HttpGet("lite/nmoonanime/play")] [HttpGet("lite/lme.nmoonanime/play")]
public async Task<ActionResult> Play(string file, string title = null) public async Task<ActionResult> Play(string file, string title = null)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -85,12 +85,12 @@ namespace NMoonAnime.Controllers
return Forbid(); return Forbid();
if (string.IsNullOrWhiteSpace(file)) if (string.IsNullOrWhiteSpace(file))
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
var invoke = new NMoonAnimeInvoke(init, hybridCache, OnLog, proxyManager, httpHydra); var invoke = new NMoonAnimeInvoke(init, hybridCache, OnLog, proxyManager, httpHydra);
var streams = invoke.ParseStreams(file); var streams = invoke.ParseStreams(file);
if (streams == null || streams.Count == 0) if (streams == null || streams.Count == 0)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
if (streams.Count == 1) if (streams.Count == 1)
{ {
@ -107,7 +107,7 @@ namespace NMoonAnime.Controllers
} }
if (!streamQuality.Any()) if (!streamQuality.Any())
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
var first = streamQuality.Firts(); var first = streamQuality.Firts();
string json = VideoTpl.ToJson("play", first.link, title ?? string.Empty, streamquality: streamQuality); string json = VideoTpl.ToJson("play", first.link, title ?? string.Empty, streamquality: streamQuality);
@ -133,7 +133,7 @@ namespace NMoonAnime.Controllers
.ToList(); .ToList();
if (orderedSeasons.Count == 0) if (orderedSeasons.Count == 0)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
if (selectedSeason == -1) if (selectedSeason == -1)
{ {
@ -154,14 +154,14 @@ namespace NMoonAnime.Controllers
var currentSeason = orderedSeasons.FirstOrDefault(s => s.SeasonNumber == selectedSeason) ?? orderedSeasons[0]; var currentSeason = orderedSeasons.FirstOrDefault(s => s.SeasonNumber == selectedSeason) ?? orderedSeasons[0];
var seasonData = await invoke.GetSeasonContent(currentSeason); var seasonData = await invoke.GetSeasonContent(currentSeason);
if (seasonData == null) if (seasonData == null)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
var voices = seasonData.Voices var voices = seasonData.Voices
.Where(v => v != null && v.Episodes != null && v.Episodes.Count > 0) .Where(v => v != null && v.Episodes != null && v.Episodes.Count > 0)
.ToList(); .ToList();
if (voices.Count == 0) if (voices.Count == 0)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
int activeVoiceIndex = ParseVoiceIndex(selectedVoice, voices.Count); int activeVoiceIndex = ParseVoiceIndex(selectedVoice, voices.Count);
var voiceTpl = new VoiceTpl(voices.Count); var voiceTpl = new VoiceTpl(voices.Count);
@ -180,7 +180,7 @@ namespace NMoonAnime.Controllers
.ToList(); .ToList();
if (episodes.Count == 0) if (episodes.Count == 0)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
string displayTitle = !string.IsNullOrWhiteSpace(title) string displayTitle = !string.IsNullOrWhiteSpace(title)
? title ? title
@ -193,7 +193,7 @@ namespace NMoonAnime.Controllers
{ {
int episodeNumber = episode.Number <= 0 ? 1 : episode.Number; int episodeNumber = episode.Number <= 0 ? 1 : episode.Number;
string episodeName = string.IsNullOrWhiteSpace(episode.Name) ? $"Епізод {episodeNumber}" : episode.Name; string episodeName = string.IsNullOrWhiteSpace(episode.Name) ? $"Епізод {episodeNumber}" : episode.Name;
string callUrl = $"{host}/lite/nmoonanime/play?file={HttpUtility.UrlEncode(episode.File)}&title={HttpUtility.UrlEncode(displayTitle)}"; string callUrl = $"{host}/lite/lme.nmoonanime/play?file={HttpUtility.UrlEncode(episode.File)}&title={HttpUtility.UrlEncode(displayTitle)}";
episodeTpl.Append(episodeName, displayTitle, currentSeason.SeasonNumber.ToString(), episodeNumber.ToString(), accsArgs(callUrl), "call"); episodeTpl.Append(episodeName, displayTitle, currentSeason.SeasonNumber.ToString(), episodeNumber.ToString(), accsArgs(callUrl), "call");
} }
@ -218,14 +218,14 @@ namespace NMoonAnime.Controllers
.FirstOrDefault(); .FirstOrDefault();
if (currentSeason == null) if (currentSeason == null)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
NMoonAnimeSeasonContent seasonData = firstSeasonData; NMoonAnimeSeasonContent seasonData = firstSeasonData;
if (seasonData == null || !string.Equals(seasonData.Url, currentSeason.Url, StringComparison.OrdinalIgnoreCase)) if (seasonData == null || !string.Equals(seasonData.Url, currentSeason.Url, StringComparison.OrdinalIgnoreCase))
seasonData = await invoke.GetSeasonContent(currentSeason); seasonData = await invoke.GetSeasonContent(currentSeason);
if (seasonData == null || seasonData.Voices.Count == 0) if (seasonData == null || seasonData.Voices.Count == 0)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
string displayTitle = !string.IsNullOrWhiteSpace(title) string displayTitle = !string.IsNullOrWhiteSpace(title)
? title ? title
@ -249,13 +249,13 @@ namespace NMoonAnime.Controllers
continue; continue;
string voiceName = string.IsNullOrWhiteSpace(voice.Name) ? $"Озвучка {fallbackIndex}" : voice.Name; string voiceName = string.IsNullOrWhiteSpace(voice.Name) ? $"Озвучка {fallbackIndex}" : voice.Name;
string callUrl = $"{host}/lite/nmoonanime/play?file={HttpUtility.UrlEncode(file)}&title={HttpUtility.UrlEncode(displayTitle)}"; string callUrl = $"{host}/lite/lme.nmoonanime/play?file={HttpUtility.UrlEncode(file)}&title={HttpUtility.UrlEncode(displayTitle)}";
movieTpl.Append(voiceName, accsArgs(callUrl), "call"); movieTpl.Append(voiceName, accsArgs(callUrl), "call");
fallbackIndex++; fallbackIndex++;
} }
if (movieTpl.IsEmpty) if (movieTpl.IsEmpty)
return OnError("nmoonanime", refresh_proxy: true); return OnError("lme.nmoonanime", refresh_proxy: true);
return rjson return rjson
? Content(movieTpl.ToJson(), "application/json; charset=utf-8") ? Content(movieTpl.ToJson(), "application/json; charset=utf-8")
@ -265,7 +265,7 @@ namespace NMoonAnime.Controllers
private string BuildIndexUrl(string imdbId, long kinopoiskId, string title, string originalTitle, int year, int serial, string malId, int season, string voice) private string BuildIndexUrl(string imdbId, long kinopoiskId, string title, string originalTitle, int year, int serial, string malId, int season, string voice)
{ {
var url = new StringBuilder(); var url = new StringBuilder();
url.Append($"{host}/lite/nmoonanime?imdb_id={HttpUtility.UrlEncode(imdbId)}"); url.Append($"{host}/lite/lme.nmoonanime?imdb_id={HttpUtility.UrlEncode(imdbId)}");
url.Append($"&kinopoisk_id={kinopoiskId}"); url.Append($"&kinopoisk_id={kinopoiskId}");
url.Append($"&title={HttpUtility.UrlEncode(title)}"); url.Append($"&title={HttpUtility.UrlEncode(title)}");
url.Append($"&original_title={HttpUtility.UrlEncode(originalTitle)}"); url.Append($"&original_title={HttpUtility.UrlEncode(originalTitle)}");

View File

@ -15,11 +15,11 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NMoonAnime namespace LME.NMoonAnime
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 2.0; public static double Version => 2.1;
public static OnlinesSettings NMoonAnime; public static OnlinesSettings NMoonAnime;
@ -36,7 +36,7 @@ namespace NMoonAnime
/// </summary> /// </summary>
public void Loaded(InitspaceModel initspace) public void Loaded(InitspaceModel initspace)
{ {
NMoonAnime = new OnlinesSettings("NMoonAnime", "https://moonanime.art", "https://apx.lme.isroot.in", streamproxy: false, useproxy: false) NMoonAnime = new OnlinesSettings("LME.NMoonAnime", "https://moonanime.art", "https://apx.lme.isroot.in", streamproxy: false, useproxy: false)
{ {
displayname = "New MoonAnime", displayname = "New MoonAnime",
displayindex = 0, displayindex = 0,
@ -51,7 +51,7 @@ namespace NMoonAnime
var defaults = JObject.FromObject(NMoonAnime); var defaults = JObject.FromObject(NMoonAnime);
defaults["enabled"] = true; defaults["enabled"] = true;
var conf = ModuleInvoke.Init("NMoonAnime", defaults) ?? JObject.FromObject(NMoonAnime); var conf = ModuleInvoke.Init("LME.NMoonAnime", defaults) ?? JObject.FromObject(NMoonAnime);
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost); bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
conf.Remove("apn"); conf.Remove("apn");
conf.Remove("apn_host"); conf.Remove("apn_host");
@ -71,7 +71,7 @@ namespace NMoonAnime
NMoonAnime.apn = null; NMoonAnime.apn = null;
} }
RegisterWithSearch("nmoonanime"); RegisterWithSearch("lme.nmoonanime");
} }
private static void RegisterWithSearch(string plugin) private static void RegisterWithSearch(string plugin)

View File

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace NMoonAnime.Models namespace LME.NMoonAnime.Models
{ {
public class NMoonAnimeSearchResponse public class NMoonAnimeSearchResponse
{ {

View File

@ -1,4 +1,4 @@
using NMoonAnime.Models; using LME.NMoonAnime.Models;
using Shared; using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models; using Shared.Models;
@ -14,7 +14,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
namespace NMoonAnime namespace LME.NMoonAnime
{ {
public class NMoonAnimeInvoke public class NMoonAnimeInvoke
{ {

View File

@ -6,7 +6,7 @@ using Shared.Models.Module.Interfaces;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NMoonAnime namespace LME.NMoonAnime
{ {
public class OnlineApi : IModuleOnline public class OnlineApi : IModuleOnline
{ {
@ -30,7 +30,7 @@ namespace NMoonAnime
if (UpdateService.IsDisconnected()) if (UpdateService.IsDisconnected())
init.overridehost = null; init.overridehost = null;
online.Add(new ModuleOnlineItem(init, "nmoonanime")); online.Add(new ModuleOnlineItem(init, "lme.nmoonanime"));
} }
return online; return online;

View File

@ -0,0 +1,6 @@
{
"enable": true,
"version": 3,
"initspace": "LME.NMoonAnime.ModInit",
"online": "LME.NMoonAnime.OnlineApi"
}

View File

@ -10,9 +10,9 @@ using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using Shared.Models.Templates; using Shared.Models.Templates;
using StarLight.Models; using LME.StarLight.Models;
namespace StarLight.Controllers namespace LME.StarLight.Controllers
{ {
public class Controller : BaseOnlineController public class Controller : BaseOnlineController
{ {
@ -24,7 +24,7 @@ namespace StarLight.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/starlight")] [Route("lite/lme.starlight")]
async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, int s = -1, bool rjson = false, string href = null, bool checksearch = false) async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, int s = -1, bool rjson = false, string href = null, bool checksearch = false)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -38,13 +38,13 @@ namespace StarLight.Controllers
if (checksearch) if (checksearch)
{ {
if (!IsCheckOnlineSearchEnabled()) if (!IsCheckOnlineSearchEnabled())
return OnError("starlight", refresh_proxy: true); return OnError("lme.starlight", refresh_proxy: true);
var searchResults = await invoke.Search(title, original_title); var searchResults = await invoke.Search(title, original_title);
if (searchResults != null && searchResults.Count > 0) if (searchResults != null && searchResults.Count > 0)
return Content("data-json=", "text/plain; charset=utf-8"); return Content("data-json=", "text/plain; charset=utf-8");
return OnError("starlight", refresh_proxy: true); return OnError("lme.starlight", refresh_proxy: true);
} }
string itemUrl = href; string itemUrl = href;
@ -52,14 +52,14 @@ namespace StarLight.Controllers
{ {
var searchResults = await invoke.Search(title, original_title); var searchResults = await invoke.Search(title, original_title);
if (searchResults == null || searchResults.Count == 0) if (searchResults == null || searchResults.Count == 0)
return OnError("starlight", refresh_proxy: true); return OnError("lme.starlight", refresh_proxy: true);
if (searchResults.Count > 1) if (searchResults.Count > 1)
{ {
var similar_tpl = new SimilarTpl(searchResults.Count); var similar_tpl = new SimilarTpl(searchResults.Count);
foreach (var res in searchResults) foreach (var res in searchResults)
{ {
string link = $"{host}/lite/starlight?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(res.Href)}"; string link = $"{host}/lite/lme.starlight?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(res.Href)}";
similar_tpl.Append(res.Title, string.Empty, string.Empty, link, string.Empty); similar_tpl.Append(res.Title, string.Empty, string.Empty, link, string.Empty);
} }
@ -71,7 +71,7 @@ namespace StarLight.Controllers
var project = await invoke.GetProject(itemUrl); var project = await invoke.GetProject(itemUrl);
if (project == null) if (project == null)
return OnError("starlight", refresh_proxy: true); return OnError("lme.starlight", refresh_proxy: true);
if (serial == 1 && project.Seasons.Count > 0) if (serial == 1 && project.Seasons.Count > 0)
{ {
@ -82,7 +82,7 @@ namespace StarLight.Controllers
{ {
var seasonInfo = project.Seasons[i]; var seasonInfo = project.Seasons[i];
string seasonName = string.IsNullOrEmpty(seasonInfo.Title) ? $"Сезон {i + 1}" : seasonInfo.Title; string seasonName = string.IsNullOrEmpty(seasonInfo.Title) ? $"Сезон {i + 1}" : seasonInfo.Title;
string link = $"{host}/lite/starlight?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={i}&href={HttpUtility.UrlEncode(itemUrl)}"; string link = $"{host}/lite/lme.starlight?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={i}&href={HttpUtility.UrlEncode(itemUrl)}";
season_tpl.Append(seasonName, link, i.ToString()); season_tpl.Append(seasonName, link, i.ToString());
} }
@ -90,13 +90,13 @@ namespace StarLight.Controllers
} }
if (s < 0 || s >= project.Seasons.Count) if (s < 0 || s >= project.Seasons.Count)
return OnError("starlight", refresh_proxy: true); return OnError("lme.starlight", refresh_proxy: true);
var season = project.Seasons[s]; var season = project.Seasons[s];
string seasonSlug = season.Slug; string seasonSlug = season.Slug;
var episodes = invoke.GetEpisodes(project, seasonSlug); var episodes = invoke.GetEpisodes(project, seasonSlug);
if (episodes == null || episodes.Count == 0) if (episodes == null || episodes.Count == 0)
return OnError("starlight", refresh_proxy: true); return OnError("lme.starlight", refresh_proxy: true);
var episode_tpl = new EpisodeTpl(); var episode_tpl = new EpisodeTpl();
int index = 1; int index = 1;
@ -114,7 +114,7 @@ namespace StarLight.Controllers
continue; continue;
string episodeName = string.IsNullOrEmpty(ep.Title) ? $"Епізод {index}" : ep.Title; string episodeName = string.IsNullOrEmpty(ep.Title) ? $"Епізод {index}" : ep.Title;
string callUrl = $"{host}/lite/starlight/play?hash={HttpUtility.UrlEncode(ep.Hash)}&title={HttpUtility.UrlEncode(title ?? original_title)}"; string callUrl = $"{host}/lite/lme.starlight/play?hash={HttpUtility.UrlEncode(ep.Hash)}&title={HttpUtility.UrlEncode(title ?? original_title)}";
episode_tpl.Append(episodeName, title ?? original_title, seasonNumber, index.ToString("D2"), accsArgs(callUrl), "call"); episode_tpl.Append(episodeName, title ?? original_title, seasonNumber, index.ToString("D2"), accsArgs(callUrl), "call");
index++; index++;
} }
@ -128,9 +128,9 @@ namespace StarLight.Controllers
hash = project.Episodes.FirstOrDefault(e => !string.IsNullOrEmpty(e.Hash))?.Hash; hash = project.Episodes.FirstOrDefault(e => !string.IsNullOrEmpty(e.Hash))?.Hash;
if (string.IsNullOrEmpty(hash)) if (string.IsNullOrEmpty(hash))
return OnError("starlight", refresh_proxy: true); return OnError("lme.starlight", refresh_proxy: true);
string callUrl = $"{host}/lite/starlight/play?hash={HttpUtility.UrlEncode(hash)}&title={HttpUtility.UrlEncode(title ?? original_title)}"; string callUrl = $"{host}/lite/lme.starlight/play?hash={HttpUtility.UrlEncode(hash)}&title={HttpUtility.UrlEncode(title ?? original_title)}";
var movie_tpl = new MovieTpl(title, original_title, 1); var movie_tpl = new MovieTpl(title, original_title, 1);
movie_tpl.Append(string.IsNullOrEmpty(title) ? "StarLight" : title, accsArgs(callUrl), "call"); movie_tpl.Append(string.IsNullOrEmpty(title) ? "StarLight" : title, accsArgs(callUrl), "call");
@ -139,13 +139,13 @@ namespace StarLight.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/starlight/play")] [Route("lite/lme.starlight/play")]
async public Task<ActionResult> Play(string hash, string title) async public Task<ActionResult> Play(string hash, string title)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
if (string.IsNullOrEmpty(hash)) if (string.IsNullOrEmpty(hash))
return OnError("starlight", refresh_proxy: true); return OnError("lme.starlight", refresh_proxy: true);
var init = loadKit(ModInit.StarLight); var init = loadKit(ModInit.StarLight);
if (!init.enable) if (!init.enable)
@ -154,7 +154,7 @@ namespace StarLight.Controllers
var invoke = new StarLightInvoke(init, hybridCache, OnLog, proxyManager, httpHydra); var invoke = new StarLightInvoke(init, hybridCache, OnLog, proxyManager, httpHydra);
var result = await invoke.ResolveStream(hash); var result = await invoke.ResolveStream(hash);
if (result == null || string.IsNullOrEmpty(result.Stream)) if (result == null || string.IsNullOrEmpty(result.Stream))
return OnError("starlight", refresh_proxy: true); return OnError("lme.starlight", refresh_proxy: true);
string videoTitle = title ?? result.Name ?? ""; string videoTitle = title ?? result.Name ?? "";

View File

@ -21,11 +21,11 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace StarLight namespace LME.StarLight
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 4.0; public static double Version => 4.1;
public static OnlinesSettings StarLight; public static OnlinesSettings StarLight;
public static bool ApnHostProvided; public static bool ApnHostProvided;
@ -41,9 +41,9 @@ namespace StarLight
/// </summary> /// </summary>
public void Loaded(InitspaceModel initspace) public void Loaded(InitspaceModel initspace)
{ {
StarLight = new OnlinesSettings("StarLight", "https://tp-back.starlight.digital", streamproxy: false, useproxy: false)
StarLight = new OnlinesSettings("LME.StarLight", "https://tp-back.starlight.digital", streamproxy: false, useproxy: false)
{ {
displayname = "StarLight", displayname = "StarLight",
displayindex = 0, displayindex = 0,
@ -57,7 +57,7 @@ namespace StarLight
}; };
var defaults = JObject.FromObject(StarLight); var defaults = JObject.FromObject(StarLight);
defaults["enabled"] = true; defaults["enabled"] = true;
var conf = ModuleInvoke.Init("StarLight", defaults); var conf = ModuleInvoke.Init("LME.StarLight", defaults);
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost); bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
conf.Remove("apn"); conf.Remove("apn");
conf.Remove("apn_host"); conf.Remove("apn_host");
@ -76,7 +76,7 @@ namespace StarLight
} }
// Виводити "уточнити пошук" // Виводити "уточнити пошук"
RegisterWithSearch("starlight"); RegisterWithSearch("lme.starlight");
} }
private static void RegisterWithSearch(string plugin) private static void RegisterWithSearch(string plugin)

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace StarLight.Models namespace LME.StarLight.Models
{ {
public class SearchResult public class SearchResult
{ {

View File

@ -7,7 +7,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace StarLight namespace LME.StarLight
{ {
public class OnlineApi : IModuleOnline public class OnlineApi : IModuleOnline
{ {
@ -30,7 +30,7 @@ namespace StarLight
if (UpdateService.IsDisconnected()) if (UpdateService.IsDisconnected())
init.overridehost = null; init.overridehost = null;
online.Add(new ModuleOnlineItem(init, "starlight")); online.Add(new ModuleOnlineItem(init, "lme.starlight"));
} }
return online; return online;

View File

@ -11,9 +11,9 @@ using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models; using Shared.Models;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using StarLight.Models; using LME.StarLight.Models;
namespace StarLight namespace LME.StarLight
{ {
public class StarLightInvoke public class StarLightInvoke
{ {

View File

@ -0,0 +1,6 @@
{
"enable": true,
"version": 3,
"initspace": "LME.StarLight.ModInit",
"online": "LME.StarLight.OnlineApi"
}

View File

@ -9,9 +9,9 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
using UafilmME.Models; using LME.UafilmME.Models;
namespace UafilmME.Controllers namespace LME.UafilmME.Controllers
{ {
public class Controller : BaseOnlineController public class Controller : BaseOnlineController
{ {
@ -23,7 +23,7 @@ namespace UafilmME.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/uafilmme")] [Route("lite/lme.uafilmme")]
async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, string href = null, bool checksearch = false) async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, bool rjson = false, string href = null, bool checksearch = false)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -37,13 +37,13 @@ namespace UafilmME.Controllers
if (checksearch) if (checksearch)
{ {
if (!IsCheckOnlineSearchEnabled()) if (!IsCheckOnlineSearchEnabled())
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
var searchResults = await invoke.Search(title, original_title, year); var searchResults = await invoke.Search(title, original_title, year);
if (searchResults != null && searchResults.Count > 0) if (searchResults != null && searchResults.Count > 0)
return Content("data-json=", "text/plain; charset=utf-8"); return Content("data-json=", "text/plain; charset=utf-8");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
long titleId = 0; long titleId = 0;
@ -54,8 +54,8 @@ namespace UafilmME.Controllers
var searchResults = await invoke.Search(title, original_title, year); var searchResults = await invoke.Search(title, original_title, year);
if (searchResults == null || searchResults.Count == 0) if (searchResults == null || searchResults.Count == 0)
{ {
OnLog("UafilmME: пошук нічого не повернув."); OnLog("lme.uafilmme: пошук нічого не повернув.");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
var best = invoke.SelectBestSearchResult(searchResults, id, imdb_id, title, original_title, year, serial); var best = invoke.SelectBestSearchResult(searchResults, id, imdb_id, title, original_title, year, serial);
@ -72,11 +72,11 @@ namespace UafilmME.Controllers
{ {
string details = item.IsSeries ? "Серіал" : "Фільм"; string details = item.IsSeries ? "Серіал" : "Фільм";
string itemYear = item.Year > 1900 ? item.Year.ToString() : string.Empty; string itemYear = item.Year > 1900 ? item.Year.ToString() : string.Empty;
string link = $"{host}/lite/uafilmme?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={item.Id}"; string link = $"{host}/lite/lme.uafilmme?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={item.Id}";
similarTpl.Append(item.Name, itemYear, details, link, item.Poster); similarTpl.Append(item.Name, itemYear, details, link, item.Poster);
} }
OnLog($"UafilmME: кілька схожих збігів, повертаю SimilarTpl ({ordered.Count})."); OnLog($"lme.uafilmme: кілька схожих збігів, повертаю SimilarTpl ({ordered.Count}).");
return rjson return rjson
? Content(similarTpl.ToJson(), "application/json; charset=utf-8") ? Content(similarTpl.ToJson(), "application/json; charset=utf-8")
: Content(similarTpl.ToHtml(), "text/html; charset=utf-8"); : Content(similarTpl.ToHtml(), "text/html; charset=utf-8");
@ -87,8 +87,8 @@ namespace UafilmME.Controllers
if (titleId <= 0) if (titleId <= 0)
{ {
OnLog("UafilmME: не вдалося визначити title_id."); OnLog("lme.uafilmme: не вдалося визначити title_id.");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
if (serial == 1) if (serial == 1)
@ -98,8 +98,8 @@ namespace UafilmME.Controllers
var seasons = await invoke.GetAllSeasons(titleId); var seasons = await invoke.GetAllSeasons(titleId);
if (seasons == null || seasons.Count == 0) if (seasons == null || seasons.Count == 0)
{ {
OnLog($"UafilmME: сезони не знайдено для title_id={titleId}."); OnLog($"lme.uafilmme: сезони не знайдено для title_id={titleId}.");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
var seasonTpl = new SeasonTpl(seasons.Count); var seasonTpl = new SeasonTpl(seasons.Count);
@ -109,7 +109,7 @@ namespace UafilmME.Controllers
? $"Сезон {season.Number} ({season.EpisodesCount} еп.)" ? $"Сезон {season.Number} ({season.EpisodesCount} еп.)"
: $"Сезон {season.Number}"; : $"Сезон {season.Number}";
string link = $"{host}/lite/uafilmme?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={season.Number}&href={titleId}"; string link = $"{host}/lite/lme.uafilmme?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={season.Number}&href={titleId}";
seasonTpl.Append(seasonName, link, season.Number.ToString()); seasonTpl.Append(seasonName, link, season.Number.ToString());
} }
@ -120,15 +120,15 @@ namespace UafilmME.Controllers
if (s <= 0) if (s <= 0)
{ {
OnLog($"UafilmME: некоректний номер сезону s={s}."); OnLog($"lme.uafilmme: некоректний номер сезону s={s}.");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
var episodes = await invoke.GetSeasonEpisodes(titleId, s); var episodes = await invoke.GetSeasonEpisodes(titleId, s);
if (episodes == null || episodes.Count == 0) if (episodes == null || episodes.Count == 0)
{ {
OnLog($"UafilmME: епізоди не знайдено для title_id={titleId}, season={s}."); OnLog($"lme.uafilmme: епізоди не знайдено для title_id={titleId}, season={s}.");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
var episodeTpl = new EpisodeTpl(); var episodeTpl = new EpisodeTpl();
@ -145,7 +145,7 @@ namespace UafilmME.Controllers
? episode.Name ? episode.Name
: $"Епізод {episodeNumber}"; : $"Епізод {episodeNumber}";
string callUrl = $"{host}/lite/uafilmme/play?video_id={episode.PrimaryVideoId}&title_id={titleId}&s={s}&e={episodeNumber}&title={HttpUtility.UrlEncode(title ?? original_title)}"; string callUrl = $"{host}/lite/lme.uafilmme/play?video_id={episode.PrimaryVideoId}&title_id={titleId}&s={s}&e={episodeNumber}&title={HttpUtility.UrlEncode(title ?? original_title)}";
episodeTpl.Append(episodeName, title ?? original_title, s.ToString(), episodeNumber.ToString("D2"), accsArgs(callUrl), "call"); episodeTpl.Append(episodeName, title ?? original_title, s.ToString(), episodeNumber.ToString("D2"), accsArgs(callUrl), "call");
fallbackEpisodeNumber = Math.Max(fallbackEpisodeNumber, episodeNumber + 1); fallbackEpisodeNumber = Math.Max(fallbackEpisodeNumber, episodeNumber + 1);
@ -154,8 +154,8 @@ namespace UafilmME.Controllers
if (appended == 0) if (appended == 0)
{ {
OnLog($"UafilmME: у сезоні {s} немає епізодів з playable video_id."); OnLog($"lme.uafilmme: у сезоні {s} немає епізодів з playable video_id.");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
return rjson return rjson
@ -167,8 +167,8 @@ namespace UafilmME.Controllers
var videos = await invoke.GetMovieVideos(titleId); var videos = await invoke.GetMovieVideos(titleId);
if (videos == null || videos.Count == 0) if (videos == null || videos.Count == 0)
{ {
OnLog($"UafilmME: не знайдено відео для фільму title_id={titleId}."); OnLog($"lme.uafilmme: не знайдено відео для фільму title_id={titleId}.");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
var movieTpl = new MovieTpl(title, original_title, videos.Count); var movieTpl = new MovieTpl(title, original_title, videos.Count);
@ -176,7 +176,7 @@ namespace UafilmME.Controllers
foreach (var video in videos) foreach (var video in videos)
{ {
string label = BuildVideoLabel(video, index); string label = BuildVideoLabel(video, index);
string callUrl = $"{host}/lite/uafilmme/play?video_id={video.Id}&title_id={titleId}&title={HttpUtility.UrlEncode(title ?? original_title)}"; string callUrl = $"{host}/lite/lme.uafilmme/play?video_id={video.Id}&title_id={titleId}&title={HttpUtility.UrlEncode(title ?? original_title)}";
movieTpl.Append(label, accsArgs(callUrl), "call"); movieTpl.Append(label, accsArgs(callUrl), "call");
index++; index++;
} }
@ -188,13 +188,13 @@ namespace UafilmME.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/uafilmme/play")] [Route("lite/lme.uafilmme/play")]
async public Task<ActionResult> Play(long video_id, long title_id = 0, int s = 0, int e = 0, string title = null) async public Task<ActionResult> Play(long video_id, long title_id = 0, int s = 0, int e = 0, string title = null)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
if (video_id <= 0) if (video_id <= 0)
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
var init = loadKit(ModInit.UafilmME); var init = loadKit(ModInit.UafilmME);
if (!init.enable) if (!init.enable)
@ -205,8 +205,8 @@ namespace UafilmME.Controllers
var videos = invoke.CollectPlayableVideos(watch); var videos = invoke.CollectPlayableVideos(watch);
if (videos == null || videos.Count == 0) if (videos == null || videos.Count == 0)
{ {
OnLog($"UafilmME Play: watch/{video_id} не повернув playable stream."); OnLog($"lme.uafilmme Play: watch/{video_id} не повернув playable stream.");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
var headers = new List<HeadersModel>() var headers = new List<HeadersModel>()
@ -229,8 +229,8 @@ namespace UafilmME.Controllers
var first = streamQuality.Firts(); var first = streamQuality.Firts();
if (string.IsNullOrWhiteSpace(first.link)) if (string.IsNullOrWhiteSpace(first.link))
{ {
OnLog($"UafilmME Play: не вдалося зібрати streamquality для video_id={video_id}."); OnLog($"lme.uafilmme Play: не вдалося зібрати streamquality для video_id={video_id}.");
return OnError("uafilmme", refresh_proxy: true); return OnError("lme.uafilmme", refresh_proxy: true);
} }
string videoTitle = !string.IsNullOrWhiteSpace(title) string videoTitle = !string.IsNullOrWhiteSpace(title)

View File

@ -15,11 +15,11 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace UafilmME namespace LME.UafilmME
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 1.0; public static double Version => 1.1;
public static OnlinesSettings UafilmME; public static OnlinesSettings UafilmME;
public static bool ApnHostProvided; public static bool ApnHostProvided;
@ -35,7 +35,7 @@ namespace UafilmME
/// </summary> /// </summary>
public void Loaded(InitspaceModel initspace) public void Loaded(InitspaceModel initspace)
{ {
UafilmME = new OnlinesSettings("UafilmME", "https://uafilm.me", streamproxy: false, useproxy: false) UafilmME = new OnlinesSettings("LME.UafilmME", "https://uafilm.me", streamproxy: false, useproxy: false)
{ {
displayname = "UAFilmME", displayname = "UAFilmME",
displayindex = 0, displayindex = 0,
@ -50,7 +50,7 @@ namespace UafilmME
var defaults = JObject.FromObject(UafilmME); var defaults = JObject.FromObject(UafilmME);
defaults["enabled"] = true; defaults["enabled"] = true;
var conf = ModuleInvoke.Init("UafilmME", defaults); var conf = ModuleInvoke.Init("LME.UafilmME", defaults);
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost); bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
conf.Remove("apn"); conf.Remove("apn");
conf.Remove("apn_host"); conf.Remove("apn_host");
@ -69,7 +69,7 @@ namespace UafilmME
UafilmME.apn = null; UafilmME.apn = null;
} }
RegisterWithSearch("uafilmme"); RegisterWithSearch("lme.uafilmme");
} }
private static void RegisterWithSearch(string plugin) private static void RegisterWithSearch(string plugin)

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace UafilmME.Models namespace LME.UafilmME.Models
{ {
public class UafilmSearchItem public class UafilmSearchItem
{ {

View File

@ -4,7 +4,7 @@ using Shared.Models.Module;
using Shared.Models.Module.Interfaces; using Shared.Models.Module.Interfaces;
using System.Collections.Generic; using System.Collections.Generic;
namespace UafilmME namespace LME.UafilmME
{ {
public class OnlineApi : IModuleOnline public class OnlineApi : IModuleOnline
{ {
@ -24,7 +24,7 @@ namespace UafilmME
if (UpdateService.IsDisconnected()) if (UpdateService.IsDisconnected())
init.overridehost = null; init.overridehost = null;
online.Add(new ModuleOnlineItem(init, "uafilmme")); online.Add(new ModuleOnlineItem(init, "lme.uafilmme"));
} }
return online; return online;

View File

@ -10,9 +10,9 @@ using Shared;
using Shared.Engine; using Shared.Engine;
using Shared.Models; using Shared.Models;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using UafilmME.Models; using LME.UafilmME.Models;
namespace UafilmME namespace LME.UafilmME
{ {
public class UafilmMEInvoke public class UafilmMEInvoke
{ {

View File

@ -0,0 +1,6 @@
{
"enable": true,
"version": 3,
"initspace": "LME.UafilmME.ModInit",
"online": "LME.UafilmME.OnlineApi"
}

View File

@ -13,9 +13,9 @@ using System.Text.RegularExpressions;
using System.Text; using System.Text;
using Shared.Models.Online.Settings; using Shared.Models.Online.Settings;
using Shared.Models; using Shared.Models;
using Uaflix.Models; using LME.Uaflix.Models;
namespace Uaflix.Controllers namespace LME.Uaflix.Controllers
{ {
public class Controller : BaseOnlineController<UaflixSettings> public class Controller : BaseOnlineController<UaflixSettings>
@ -28,7 +28,7 @@ namespace Uaflix.Controllers
} }
[HttpGet] [HttpGet]
[Route("lite/uaflix")] [Route("lite/lme.uaflix")]
async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, int e = -1, bool play = false, bool rjson = false, string href = null, bool checksearch = false) async public Task<ActionResult> Index(long id, string imdb_id, long kinopoisk_id, string title, string original_title, string original_language, int year, string source, int serial, string account_email, string t, int s = -1, int e = -1, bool play = false, bool rjson = false, string href = null, bool checksearch = false)
{ {
await UpdateService.ConnectAsync(host); await UpdateService.ConnectAsync(host);
@ -38,10 +38,10 @@ namespace Uaflix.Controllers
var init = this.init; var init = this.init;
TryEnableMagicApn(init); TryEnableMagicApn(init);
OnLog($"=== UAFLIX INDEX START ==="); OnLog($"lme.uaflix: === UAFLIX INDEX START ===");
OnLog($"Uaflix Index: title={title}, serial={serial}, s={s}, play={play}, href={href}, checksearch={checksearch}"); OnLog($"lme.uaflix: Index: title={title}, serial={serial}, s={s}, play={play}, href={href}, checksearch={checksearch}");
OnLog($"Uaflix Index: kinopoisk_id={kinopoisk_id}, imdb_id={imdb_id}, id={id}"); OnLog($"lme.uaflix: Index: kinopoisk_id={kinopoisk_id}, imdb_id={imdb_id}, id={id}");
OnLog($"Uaflix Index: year={year}, source={source}, t={t}, e={e}, rjson={rjson}"); OnLog($"lme.uaflix: Index: year={year}, source={source}, t={t}, e={e}, rjson={rjson}");
var auth = new UaflixAuth(init, memoryCache, OnLog, proxyManager); var auth = new UaflixAuth(init, memoryCache, OnLog, proxyManager);
var invoke = new UaflixInvoke(init, hybridCache, OnLog, proxyManager, auth, httpHydra); var invoke = new UaflixInvoke(init, hybridCache, OnLog, proxyManager, auth, httpHydra);
@ -50,7 +50,7 @@ namespace Uaflix.Controllers
if (checksearch) if (checksearch)
{ {
if (!IsCheckOnlineSearchEnabled()) if (!IsCheckOnlineSearchEnabled())
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
try try
{ {
@ -64,13 +64,13 @@ namespace Uaflix.Controllers
OnLog("checksearch: Контент не знайдено"); OnLog("checksearch: Контент не знайдено");
OnLog("=== RETURN: checksearch OnError ==="); OnLog("=== RETURN: checksearch OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
catch (Exception ex) catch (Exception ex)
{ {
OnLog($"checksearch: помилка - {ex.Message}"); OnLog($"checksearch: помилка - {ex.Message}");
OnLog("=== RETURN: checksearch exception OnError ==="); OnLog("=== RETURN: checksearch exception OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
} }
@ -81,7 +81,7 @@ namespace Uaflix.Controllers
if (string.IsNullOrWhiteSpace(urlToParse)) if (string.IsNullOrWhiteSpace(urlToParse))
{ {
OnLog("=== RETURN: play missing url OnError ==="); OnLog("=== RETURN: play missing url OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
var playResult = await invoke.ParseEpisode(urlToParse); var playResult = await invoke.ParseEpisode(urlToParse);
@ -92,7 +92,7 @@ namespace Uaflix.Controllers
} }
OnLog("=== RETURN: play no streams ==="); OnLog("=== RETURN: play no streams ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
// Якщо є episode_url але немає play=true, це виклик для отримання інформації про стрім (для method: 'call') // Якщо є episode_url але немає play=true, це виклик для отримання інформації про стрім (для method: 'call')
@ -110,7 +110,7 @@ namespace Uaflix.Controllers
} }
OnLog("=== RETURN: call method no streams ==="); OnLog("=== RETURN: call method no streams ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
string filmUrl = href; string filmUrl = href;
@ -122,7 +122,7 @@ namespace Uaflix.Controllers
{ {
OnLog("No search results found"); OnLog("No search results found");
OnLog("=== RETURN: no search results OnError ==="); OnLog("=== RETURN: no search results OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
var selectedResult = invoke.SelectBestSearchResult(searchResults, title, original_title, year); var selectedResult = invoke.SelectBestSearchResult(searchResults, title, original_title, year);
@ -143,7 +143,7 @@ namespace Uaflix.Controllers
var similar_tpl = new SimilarTpl(orderedResults.Count); var similar_tpl = new SimilarTpl(orderedResults.Count);
foreach (var res in orderedResults) foreach (var res in orderedResults)
{ {
string link = $"{host}/lite/uaflix?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(res.Url)}"; string link = $"{host}/lite/lme.uaflix?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&href={HttpUtility.UrlEncode(res.Url)}";
string y = res.Year > 0 ? res.Year.ToString() : string.Empty; string y = res.Year > 0 ? res.Year.ToString() : string.Empty;
string details = res.Category switch string details = res.Category switch
{ {
@ -176,13 +176,13 @@ namespace Uaflix.Controllers
{ {
OnLog("No seasons found in season index"); OnLog("No seasons found in season index");
OnLog("=== RETURN: no seasons OnError ==="); OnLog("=== RETURN: no seasons OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
var season_tpl = new SeasonTpl(seasons.Count); var season_tpl = new SeasonTpl(seasons.Count);
foreach (int season in seasons) foreach (int season in seasons)
{ {
string link = $"{host}/lite/uaflix?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={season}&href={HttpUtility.UrlEncode(filmUrl)}"; string link = $"{host}/lite/lme.uaflix?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&s={season}&href={HttpUtility.UrlEncode(filmUrl)}";
if (!string.IsNullOrWhiteSpace(t)) if (!string.IsNullOrWhiteSpace(t))
link += $"&t={HttpUtility.UrlEncode(t)}"; link += $"&t={HttpUtility.UrlEncode(t)}";
@ -204,7 +204,7 @@ namespace Uaflix.Controllers
{ {
OnLog($"No voices found for season {s}"); OnLog($"No voices found for season {s}");
OnLog("=== RETURN: no voices for season OnError ==="); OnLog("=== RETURN: no voices for season OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
var voicesForSeason = structure.Voices var voicesForSeason = structure.Voices
.Select(v => new { DisplayName = v.Key, Info = v.Value }) .Select(v => new { DisplayName = v.Key, Info = v.Value })
@ -214,7 +214,7 @@ namespace Uaflix.Controllers
{ {
OnLog($"No voices found for season {s}"); OnLog($"No voices found for season {s}");
OnLog("=== RETURN: no voices for season OnError ==="); OnLog("=== RETURN: no voices for season OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
// Автоматично вибираємо першу озвучку якщо не вказана // Автоматично вибираємо першу озвучку якщо не вказана
@ -237,7 +237,7 @@ namespace Uaflix.Controllers
{ {
OnLog($"Season {s} not found for selected voice and fallback voice missing"); OnLog($"Season {s} not found for selected voice and fallback voice missing");
OnLog("=== RETURN: season not found for voice OnError ==="); OnLog("=== RETURN: season not found for voice OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
t = fallbackVoice.DisplayName; t = fallbackVoice.DisplayName;
@ -249,7 +249,7 @@ namespace Uaflix.Controllers
var voice_tpl = new VoiceTpl(); var voice_tpl = new VoiceTpl();
foreach (var voice in voicesForSeason) foreach (var voice in voicesForSeason)
{ {
string voiceLink = $"{host}/lite/uaflix?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&href={HttpUtility.UrlEncode(filmUrl)}"; string voiceLink = $"{host}/lite/lme.uaflix?imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial=1&href={HttpUtility.UrlEncode(filmUrl)}";
voiceLink += $"&s={s}&t={HttpUtility.UrlEncode(voice.DisplayName)}"; voiceLink += $"&s={s}&t={HttpUtility.UrlEncode(voice.DisplayName)}";
bool isActive = voice.DisplayName == t; bool isActive = voice.DisplayName == t;
@ -276,7 +276,7 @@ namespace Uaflix.Controllers
{ {
// Для zetvideo-vod та ashdi-vod використовуємо URL епізоду для виклику // Для zetvideo-vod та ashdi-vod використовуємо URL епізоду для виклику
// Потрібно передати URL епізоду в інший параметр, щоб не плутати з play=true // Потрібно передати URL епізоду в інший параметр, щоб не плутати з play=true
string callUrl = $"{host}/lite/uaflix?episode_url={HttpUtility.UrlEncode(ep.File)}&imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&s={s}&e={ep.Number}"; string callUrl = $"{host}/lite/lme.uaflix?episode_url={HttpUtility.UrlEncode(ep.File)}&imdb_id={imdb_id}&kinopoisk_id={kinopoisk_id}&title={HttpUtility.UrlEncode(title)}&original_title={HttpUtility.UrlEncode(original_title)}&year={year}&serial={serial}&s={s}&e={ep.Number}";
episode_tpl.Append( episode_tpl.Append(
name: episodeTitle, name: episodeTitle,
title: title, title: title,
@ -307,7 +307,7 @@ namespace Uaflix.Controllers
{ {
OnLog($"No valid episodes after filtering for season {s}, voice {t}"); OnLog($"No valid episodes after filtering for season {s}, voice {t}");
OnLog("=== RETURN: no valid episodes OnError ==="); OnLog("=== RETURN: no valid episodes OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
OnLog($"Created EpisodeTpl with {appendedEpisodes} episodes"); OnLog($"Created EpisodeTpl with {appendedEpisodes} episodes");
@ -329,7 +329,7 @@ namespace Uaflix.Controllers
// Fallback: якщо жоден з умов не виконався // Fallback: якщо жоден з умов не виконався
OnLog($"Fallback: s={s}, t={t}"); OnLog($"Fallback: s={s}, t={t}");
OnLog("=== RETURN: fallback OnError ==="); OnLog("=== RETURN: fallback OnError ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
else // Фільм else // Фільм
{ {
@ -337,7 +337,7 @@ namespace Uaflix.Controllers
if (playResult?.streams == null || playResult.streams.Count == 0) if (playResult?.streams == null || playResult.streams.Count == 0)
{ {
OnLog("=== RETURN: movie no streams ==="); OnLog("=== RETURN: movie no streams ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
var tpl = new MovieTpl(title, original_title, playResult.streams.Count); var tpl = new MovieTpl(title, original_title, playResult.streams.Count);
@ -358,7 +358,7 @@ namespace Uaflix.Controllers
if (tpl.data == null || tpl.data.Count == 0) if (tpl.data == null || tpl.data.Count == 0)
{ {
OnLog("=== RETURN: movie template empty ==="); OnLog("=== RETURN: movie template empty ===");
return OnError("uaflix", refresh_proxy: true); return OnError("lme.uaflix", refresh_proxy: true);
} }
OnLog("=== RETURN: movie template ==="); OnLog("=== RETURN: movie template ===");
@ -401,7 +401,7 @@ namespace Uaflix.Controllers
return; return;
ApnHelper.ApplyInitConf(true, ModInit.MagicApnAshdiHost, init); ApnHelper.ApplyInitConf(true, ModInit.MagicApnAshdiHost, init);
OnLog($"Uaflix: увімкнено magic_apn для Ashdi (player={player ?? "unknown"})."); OnLog($"lme.uaflix: увімкнено magic_apn для Ashdi (player={player ?? "unknown"}).");
} }
private static string StripLampacArgs(string url) private static string StripLampacArgs(string url)

View File

@ -13,13 +13,13 @@ using System.Security.Authentication;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Uaflix.Models; using LME.Uaflix.Models;
namespace Uaflix namespace LME.Uaflix
{ {
public class ModInit : IModuleLoaded public class ModInit : IModuleLoaded
{ {
public static double Version => 5.1; public static double Version => 5.2;
public static UaflixSettings UaFlix; public static UaflixSettings UaFlix;
@ -37,7 +37,7 @@ namespace Uaflix
/// </summary> /// </summary>
public void Loaded(InitspaceModel initspace) public void Loaded(InitspaceModel initspace)
{ {
UaFlix = new UaflixSettings("Uaflix", "https://uafix.net", streamproxy: false, useproxy: false) UaFlix = new UaflixSettings("LME.Uaflix", "https://uafix.net", streamproxy: false, useproxy: false)
{ {
displayname = "UaFlix", displayname = "UaFlix",
group = 0, group = 0,
@ -62,7 +62,7 @@ namespace Uaflix
["ashdi"] = ApnHelper.DefaultHost ["ashdi"] = ApnHelper.DefaultHost
}; };
var conf = ModuleInvoke.Init("Uaflix", defaults) ?? defaults; var conf = ModuleInvoke.Init("LME.Uaflix", defaults) ?? defaults;
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost); bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf); MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf);
conf.Remove("magic_apn"); conf.Remove("magic_apn");
@ -85,7 +85,7 @@ namespace Uaflix
} }
// Показувати «уточнити пошук». // Показувати «уточнити пошук».
RegisterWithSearch("uaflix"); RegisterWithSearch("lme.uaflix");
} }
private static void RegisterWithSearch(string plugin) private static void RegisterWithSearch(string plugin)

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Uaflix.Models namespace LME.Uaflix.Models
{ {
public class EpisodeLinkInfo public class EpisodeLinkInfo
{ {

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Uaflix.Models namespace LME.Uaflix.Models
{ {
/// <summary> /// <summary>
/// Модель для зберігання інформації про фільм /// Модель для зберігання інформації про фільм

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Uaflix.Models namespace LME.Uaflix.Models
{ {
public class PaginationInfo public class PaginationInfo
{ {

View File

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Shared.Models.Templates; using Shared.Models.Templates;
namespace Uaflix.Models namespace LME.Uaflix.Models
{ {
public class PlayResult public class PlayResult
{ {

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Uaflix.Models namespace LME.Uaflix.Models
{ {
public class SearchResult public class SearchResult
{ {

Some files were not shown because too many files have changed in this diff Show More