summaryrefslogtreecommitdiff
path: root/Api/ScriptInjector.cs
blob: d6b186579a7b24ed2d0537b351b499ac9e33ea7c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
namespace Jellyfin.Plugin.JCoverXtremePro.Api;

using System;
using System.IO;
using System.Text.RegularExpressions;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Configuration;
using Microsoft.Extensions.Logging;

/// <summary>
/// Utility for injecting a JavaScript script tag into the Jellyfin web frontend.
/// </summary>
public static class ScriptInjector
{
    public static void PerformInjection(
        IApplicationPaths applicationPaths,
        IServerConfigurationManager configurationManager
    )
    {
        var indexHtmlFilePath = Path.Combine(applicationPaths.WebPath, "index.html");
        if (!File.Exists(indexHtmlFilePath))
        {
            Plugin.Logger.LogWarning("Could not find index html file");
            return;
        }

        var html = File.ReadAllText(indexHtmlFilePath);
        var snippet = GetInjectedSnippet(GetHTTPBasePath(configurationManager));
        if (html.Contains(snippet, StringComparison.InvariantCulture))
        {
            Plugin.Logger.LogInformation("Not injecting existing HTML snippet.");
            return;
        }

        html = Regex.Replace(html, $"<script[^>]*guid=\"{Plugin.GUID}\"[^>]*></script>", string.Empty);
        var bodyEnd = html.LastIndexOf("</body>", StringComparison.InvariantCulture);
        if (bodyEnd < 0)
        {
            Plugin.Logger.LogError("Could not find end of body to inject script");
            return;
        }

        html = html.Insert(bodyEnd, snippet);
        try
        {
            File.WriteAllText(indexHtmlFilePath, html);
            Plugin.Logger.LogInformation("Injected index.html");
        }
        catch (Exception e)
        {
            Plugin.Logger.LogError(e, "Failed to write patched index.html");
        }
    }

    public static string GetHTTPBasePath(IServerConfigurationManager configurationManager)
    {
        var networkConfig = configurationManager.GetConfiguration("network");
        var configType = networkConfig.GetType();
        var baseUrlField = configType.GetProperty("BaseUrl");
        var baseUrl = baseUrlField!.GetValue(networkConfig)!.ToString()!.Trim('/');
        return baseUrl;
    }

    public static string GetScriptUrl(string basePath)
    {
        return basePath + "/JCoverXtremeProStatic/ClientScript";
    }

    public static string GetInjectedSnippet(string basePath)
    {
        return
            $"<script guid=\"{Plugin.GUID}\" plugin=\"{Plugin.Instance!.Name}\" src=\"{GetScriptUrl(basePath)}\" defer></script>";
    }
}