test 6
This commit is contained in:
@@ -1,24 +1,35 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
|
||||
namespace Jellyfin.Plugin.Seasonals;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the injection of the Seasonals script into the Jellyfin web interface.
|
||||
/// </summary>
|
||||
public class ScriptInjector
|
||||
{
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
private readonly ILogger<ScriptInjector> _logger;
|
||||
private const string ScriptTag = "<script src=\"/Seasonals/Resources/seasonals.js\"></script>";
|
||||
private const string ScriptTag = "<script src=\"Seasonals/Resources/seasonals.js\"></script>";
|
||||
private const string Marker = "</body>";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ScriptInjector"/> class.
|
||||
/// </summary>
|
||||
/// <param name="appPaths">The application paths.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public ScriptInjector(IApplicationPaths appPaths, ILogger<ScriptInjector> logger)
|
||||
{
|
||||
_appPaths = appPaths;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Injects the script tag into index.html if it's not already present.
|
||||
/// </summary>
|
||||
public void Inject()
|
||||
{
|
||||
try
|
||||
@@ -38,14 +49,15 @@ public class ScriptInjector
|
||||
}
|
||||
|
||||
var content = File.ReadAllText(indexPath);
|
||||
if (content.Contains(ScriptTag))
|
||||
if (content.Contains(ScriptTag, StringComparison.Ordinal))
|
||||
{
|
||||
_logger.LogInformation("Seasonals script already injected.");
|
||||
return;
|
||||
}
|
||||
|
||||
var newContent = content.Replace(Marker, $"{ScriptTag}\n{Marker}");
|
||||
if (newContent == content)
|
||||
// Insert before the closing body tag
|
||||
var newContent = content.Replace(Marker, $"{ScriptTag}\n{Marker}", StringComparison.Ordinal);
|
||||
if (string.Equals(newContent, content, StringComparison.Ordinal))
|
||||
{
|
||||
_logger.LogWarning("Could not find closing body tag in index.html. Script injection skipped.");
|
||||
return;
|
||||
@@ -60,20 +72,35 @@ public class ScriptInjector
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the script tag from index.html.
|
||||
/// </summary>
|
||||
public void Remove()
|
||||
{
|
||||
try
|
||||
{
|
||||
var webPath = GetWebPath();
|
||||
if (string.IsNullOrEmpty(webPath)) return;
|
||||
if (string.IsNullOrEmpty(webPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var indexPath = Path.Combine(webPath, "index.html");
|
||||
if (!File.Exists(indexPath)) return;
|
||||
if (!File.Exists(indexPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var content = File.ReadAllText(indexPath);
|
||||
if (!content.Contains(ScriptTag)) return;
|
||||
if (!content.Contains(ScriptTag, StringComparison.Ordinal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var newContent = content.Replace(ScriptTag, "").Replace($"{ScriptTag}\n", "");
|
||||
// Try to remove with newline first, then just the tag to ensure clean removal
|
||||
var newContent = content.Replace($"{ScriptTag}\n", "", StringComparison.Ordinal)
|
||||
.Replace(ScriptTag, "", StringComparison.Ordinal);
|
||||
|
||||
File.WriteAllText(indexPath, newContent);
|
||||
_logger.LogInformation("Successfully removed Seasonals script from index.html.");
|
||||
}
|
||||
@@ -83,37 +110,14 @@ public class ScriptInjector
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the path to the Jellyfin web interface directory.
|
||||
/// </summary>
|
||||
/// <returns>The path to the web directory, or null if not found.</returns>
|
||||
private string? GetWebPath()
|
||||
{
|
||||
// Try to find the web path using IApplicationPaths
|
||||
// Note: The property name might vary depending on the Jellyfin version,
|
||||
// but usually it's accessible via the configuration or standard paths.
|
||||
// For this plugin context, we'll try to rely on the standard path structure if IApplicationPaths doesn't expose it directly
|
||||
// or if we need to infer it.
|
||||
|
||||
// In many Jellyfin versions, appPaths.WebPath is the property.
|
||||
// However, since we are in a plugin, we might need to use reflection if the interface doesn't expose it in the reference assembly,
|
||||
// or just assume it's there.
|
||||
|
||||
// Let's try to use the property if it exists.
|
||||
// If the compilation fails, we will adjust.
|
||||
// For now, we assume 'WebPath' is available on IApplicationPaths implementation
|
||||
// but it might not be on the interface in the nuget package.
|
||||
|
||||
// Workaround: Check known locations if property is missing or use reflection.
|
||||
|
||||
// Attempt 1: Reflection to get WebPath property (safest if interface varies)
|
||||
var prop = _appPaths.GetType().GetProperty("WebPath");
|
||||
if (prop != null)
|
||||
{
|
||||
return prop.GetValue(_appPaths) as string;
|
||||
}
|
||||
|
||||
// Attempt 2: Guess based on ProgramDataPath (common in Windows)
|
||||
// Usually <ProgramData>/jellyfin/web or <InstallDir>/jellyfin-web
|
||||
|
||||
// Let's try to look relative to the application executable if possible, but that's hard from a plugin.
|
||||
|
||||
return null;
|
||||
// Use reflection to access WebPath property to ensure compatibility across different Jellyfin versions
|
||||
var prop = _appPaths.GetType().GetProperty("WebPath", BindingFlags.Instance | BindingFlags.Public);
|
||||
return prop?.GetValue(_appPaths) as string;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user