mirror of
https://github.com/IAmParadox27/jellyfin-plugin-media-bar.git
synced 2026-11-08 16:27:14 +01:00
Changed media bar to use the HTTP Request approach for file transformation. Much more stable
This commit is contained in:
1 parent
bf39865742
commit
78c87c70f6
5 files changed
+158
-71
No files matched your search
@@ -1,32 +1,57 @@
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using Jellyfin.Plugin.MediaBar.Model;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Jellyfin.Plugin.MediaBar.Controllers;
|
||||
|
||||
[Route("[controller]")]
|
||||
public class MediaBarController : ControllerBase
|
||||
namespace Jellyfin.Plugin.MediaBar.Controllers
|
||||
{
|
||||
[HttpGet("{file}")]
|
||||
public ActionResult GetFile([FromRoute] string file)
|
||||
[Route("[controller]")]
|
||||
public class MediaBarController : ControllerBase
|
||||
{
|
||||
Stream fileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Jellyfin.Plugin.MediaBar.Inject." + file);
|
||||
string fileContents = new StreamReader(fileStream).ReadToEnd();
|
||||
[HttpGet("{file}")]
|
||||
public ActionResult GetFile([FromRoute] string file)
|
||||
{
|
||||
Stream fileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Jellyfin.Plugin.MediaBar.Inject." + file)!;
|
||||
string fileContents = new StreamReader(fileStream).ReadToEnd();
|
||||
|
||||
string contentType = "text/plain";
|
||||
string contentType = "text/plain";
|
||||
|
||||
if (Path.GetExtension(file) == ".js")
|
||||
{
|
||||
contentType = "text/javascript";
|
||||
}
|
||||
else if (Path.GetExtension(file) == ".css")
|
||||
{
|
||||
contentType = "text/css";
|
||||
}
|
||||
else if (Path.GetExtension(file) == ".html")
|
||||
{
|
||||
contentType = "text/html";
|
||||
}
|
||||
if (Path.GetExtension(file) == ".js")
|
||||
{
|
||||
contentType = "text/javascript";
|
||||
}
|
||||
else if (Path.GetExtension(file) == ".css")
|
||||
{
|
||||
contentType = "text/css";
|
||||
}
|
||||
else if (Path.GetExtension(file) == ".html")
|
||||
{
|
||||
contentType = "text/html";
|
||||
}
|
||||
|
||||
return Content(fileContents, contentType);
|
||||
return Content(fileContents, contentType);
|
||||
}
|
||||
|
||||
[HttpPost("Patch/IndexHtml")]
|
||||
public ActionResult PatchIndexHtml([FromBody] PatchRequestPayload payload)
|
||||
{
|
||||
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(MediaBarPlugin).Namespace}.Inject.index.html")!;
|
||||
using TextReader reader = new StreamReader(stream);
|
||||
|
||||
string regex = Regex.Replace(payload.Contents!, "(</body>)", $"{reader.ReadToEnd()}$1");
|
||||
|
||||
return Content(regex, "text/html");
|
||||
}
|
||||
|
||||
[HttpPost("Patch/HomeHtmlChunk")]
|
||||
public ActionResult PatchHomeHtmlChunk([FromBody] PatchRequestPayload payload)
|
||||
{
|
||||
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(MediaBarPlugin).Namespace}.Inject.home-html.chunk.js")!;
|
||||
using TextReader reader = new StreamReader(stream);
|
||||
|
||||
string regex = Regex.Replace(payload.Contents!, "(id=\"homeTab\" data-index=\"0\">)", $"$1{reader.ReadToEnd()}");
|
||||
|
||||
return Content(regex, "text/html");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,16 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<Version>1.0.0</Version>
|
||||
<Version>2.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jellyfin.Plugin.FileTransformation" Version="1.2.2" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.10.5" />
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.10.5" />
|
||||
<PackageReference Include="Jellyfin.Common" Version="10.10.5" />
|
||||
<PackageReference Include="Jellyfin.Data" Version="10.10.5" />
|
||||
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -25,4 +30,7 @@
|
||||
<EmbeddedResource Include="Inject\slideshowpure.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="Exists('C:\ProgramData\Jellyfin\Server\plugins\MediaBar')">
|
||||
<Exec Command="xcopy $(OutDir) "C:\ProgramData\Jellyfin\Server\plugins\MediaBar" /y" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,56 +1,18 @@
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using Jellyfin.Plugin.FileTransformation.Controller;
|
||||
using Jellyfin.Plugin.FileTransformation.Infrastructure;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Jellyfin.Plugin.MediaBar;
|
||||
|
||||
public class MediaBarPlugin : BasePlugin<BasePluginConfiguration>
|
||||
namespace Jellyfin.Plugin.MediaBar
|
||||
{
|
||||
public override Guid Id => Guid.Parse("08f615ea-2107-4f04-89cc-091035f54448");
|
||||
public class MediaBarPlugin : BasePlugin<BasePluginConfiguration>
|
||||
{
|
||||
public override Guid Id => Guid.Parse("08f615ea-2107-4f04-89cc-091035f54448");
|
||||
|
||||
public override string Name => "Media Bar";
|
||||
public override string Name => "Media Bar";
|
||||
|
||||
public MediaBarPlugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer, IServiceProvider serviceProvider) : base(applicationPaths, xmlSerializer)
|
||||
{
|
||||
IWebFileTransformationWriteService webFileTransformationWriteService = serviceProvider.GetRequiredService<IWebFileTransformationWriteService>();
|
||||
|
||||
webFileTransformationWriteService.AddTransformation("index.html", IndexHtml_Transformation);
|
||||
webFileTransformationWriteService.AddTransformation("home-html\\.[a-zA-z0-9]+\\.chunk\\.js", HomeHtmlChunk_Transformation);
|
||||
}
|
||||
|
||||
private void IndexHtml_Transformation(string path, Stream contents)
|
||||
{
|
||||
Stream? stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"{GetType().Namespace}.Inject.index.html");
|
||||
using TextReader reader = new StreamReader(stream);
|
||||
|
||||
using var textReader = new StreamReader(contents, null, true, -1, true);
|
||||
var text = textReader.ReadToEnd();
|
||||
|
||||
var regex = Regex.Replace(text, "(</body>)", $"{reader.ReadToEnd()}$1");
|
||||
contents.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using var textWriter = new StreamWriter(contents, null, -1, true);
|
||||
textWriter.Write(regex);
|
||||
}
|
||||
|
||||
private void HomeHtmlChunk_Transformation(string path, Stream contents)
|
||||
{
|
||||
Stream? stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"{GetType().Namespace}.Inject.home-html.chunk.js");
|
||||
using TextReader reader = new StreamReader(stream);
|
||||
|
||||
using var textReader = new StreamReader(contents, null, true, -1, true);
|
||||
var text = textReader.ReadToEnd();
|
||||
|
||||
var regex = Regex.Replace(text, "(id=\"homeTab\" data-index=\"0\">)", $"$1{reader.ReadToEnd()}");
|
||||
contents.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using var textWriter = new StreamWriter(contents, null, -1, true);
|
||||
textWriter.Write(regex);
|
||||
public MediaBarPlugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer, IServiceProvider serviceProvider) : base(applicationPaths, xmlSerializer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.MediaBar.Model
|
||||
{
|
||||
public class PatchRequestPayload
|
||||
{
|
||||
[JsonPropertyName("contents")]
|
||||
public string? Contents { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using System.Net.Http.Headers;
|
||||
using System.Reflection;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Jellyfin.Plugin.MediaBar.Services
|
||||
{
|
||||
public class StartupService : IScheduledTask
|
||||
{
|
||||
public string Name => "MediaBar Startup";
|
||||
|
||||
public string Key => "Jellyfin.Plugin.MediaBar.Startup";
|
||||
|
||||
public string Description => "Startup Service for MediaBar";
|
||||
|
||||
public string Category => "Startup Services";
|
||||
|
||||
private readonly IServerApplicationHost m_serverApplicationHost;
|
||||
private readonly ILogger<MediaBarPlugin> m_logger;
|
||||
|
||||
public StartupService(IServerApplicationHost serverApplicationHost, ILogger<MediaBarPlugin> logger)
|
||||
{
|
||||
m_serverApplicationHost = serverApplicationHost;
|
||||
m_logger = logger;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
List<JObject> payloads = new List<JObject>();
|
||||
|
||||
{
|
||||
JObject payload = new JObject();
|
||||
payload.Add("id", "0dfac9d7-d898-4944-900b-1c1837707279");
|
||||
payload.Add("fileNamePattern", "index.html");
|
||||
payload.Add("tranformationEndpoint", "/MediaBar/Patch/IndexHtml");
|
||||
|
||||
payloads.Add(payload);
|
||||
}
|
||||
{
|
||||
JObject payload = new JObject();
|
||||
payload.Add("id", "e6d32b76-d54b-4946-b73e-c5c9c50575c9");
|
||||
payload.Add("fileNamePattern", "home-html\\.[a-zA-z0-9]+\\.chunk\\.js");
|
||||
payload.Add("tranformationEndpoint", "/MediaBar/Patch/HomeHtmlChunk");
|
||||
|
||||
payloads.Add(payload);
|
||||
}
|
||||
|
||||
string? publishedServerUrl = m_serverApplicationHost.GetType()
|
||||
.GetProperty("PublishedServerUrl", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(m_serverApplicationHost) as string;
|
||||
|
||||
foreach (JObject payload in payloads)
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
client.BaseAddress = new Uri(publishedServerUrl ?? $"http://localhost:{m_serverApplicationHost.HttpPort}");
|
||||
|
||||
try
|
||||
{
|
||||
await client.PostAsync("/FileTransformation/RegisterTransformation",
|
||||
new StringContent(payload.ToString(Formatting.None),
|
||||
MediaTypeHeaderValue.Parse("application/json")));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_logger.LogError(ex, $"Caught exception when attempting to register file transformation. Ensure you have `File Transformation` plugin installed on your server.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||
{
|
||||
yield return new TaskTriggerInfo()
|
||||
{
|
||||
Type = TaskTriggerInfo.TriggerStartup
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user