Repository navigation
Expand file tree
/
Copy pathPlugin.cs
More file actions
167 lines (150 loc) · 6.18 KB
/
Copy pathPlugin.cs
File metadata and controls
167 lines (150 loc) · 6.18 KB
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
using Gelato.Config;
using Gelato.ScheduledTasks;
using Gelato.Services;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.Plugins;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
namespace Gelato;
public class GelatoPlugin : BasePlugin<PluginConfiguration>, IHasWebPages
{
private readonly ILogger<GelatoPlugin> _log;
private readonly GelatoManager _manager;
private readonly GelatoStremioProviderFactory _stremioFactory;
private readonly GelatoCache _cache;
private readonly ITaskManager _taskManager;
public PalcoCacheService PalcoCache { get; } // Migrated Palco Cache Service
public GelatoPlugin(
IApplicationPaths applicationPaths,
GelatoManager manager,
IXmlSerializer xmlSerializer,
ILogger<GelatoPlugin> log,
GelatoStremioProviderFactory stremioFactory,
PalcoCacheService palcoCache,
ITaskManager taskManager,
GelatoCache cache
)
: base(applicationPaths, xmlSerializer)
{
Instance = this;
_log = log;
_manager = manager;
_stremioFactory = stremioFactory;
PalcoCache = palcoCache;
_taskManager = taskManager;
_cache = cache;
}
public static GelatoPlugin? Instance { get; private set; }
/// <summary>
/// The User-Agent Gelato sends to addons and RemuxDB: <c>Gelato/<version></c>.
/// </summary>
public static string UserAgent { get; } =
$"Gelato/{typeof(GelatoPlugin).Assembly.GetName().Version?.ToString() ?? "0"}";
// Event fired when the plugin configuration is updated via UpdateConfiguration
public static new event Action<PluginConfiguration>? ConfigurationChanged;
public override string Name => "Gelato";
public override Guid Id => Guid.Parse("94EA4E14-8163-4989-96FE-0A2094BC2D6A");
public override string Description =>
"Gelato brings AIOStreams (Stremio addons) into Jellyfin. Search results and imported catalogs show up as regular movies and series, and streams are resolved when you press play and proxied through Jellyfin.";
private static readonly string[] PageFiles =
[
"gelato.css",
"gelato-common.js",
"gelato-settings.js",
"gelato-setup.js",
];
/// <inheritdoc />
public IEnumerable<PluginPageInfo> GetPages()
{
var prefix = GetType().Namespace;
yield return new PluginPageInfo
{
Name = "config",
EnableInMainMenu = true,
MenuIcon = "movie",
EmbeddedResourcePath = prefix + ".Config.config.html",
};
// The page's style and scripts, which config.html and its scripts load by these names.
foreach (var file in PageFiles)
{
yield return new PluginPageInfo
{
Name = file,
EmbeddedResourcePath = prefix + ".Config." + file,
};
}
}
public override void UpdateConfiguration(BasePluginConfiguration configuration)
{
var cfg = (PluginConfiguration)configuration;
var treesChanged = Configuration.ExtendLocalSeriesTrees != cfg.ExtendLocalSeriesTrees;
base.UpdateConfiguration(cfg);
// Everything that came from the old configuration or the addon as it was: a changed
// setting takes effect with the next request, and the Catalogs tab's Refresh (a save of
// the unchanged configuration) reads the manifest again.
_cache.Invalidate(cfg);
// A changed movie or series path can be the folder items without one were waiting for.
_manager.AdoptParkedSoon();
// The task adds the missing seasons and episodes to local series, or removes them once
// the setting is off. Jellyfin starts it now when idle; a run in progress read the old
// value, so it runs once more after that one (its queue holds a task once).
if (treesChanged)
{
_log.LogInformation(
"Extending local series trees turned {State}, queueing the series tree sync",
cfg.ExtendLocalSeriesTrees ? "on" : "off"
);
_taskManager.QueueScheduledTask<SyncSeriesTreesTask>();
}
// Notify subscribers that configuration changed
try
{
ConfigurationChanged?.Invoke(cfg);
}
catch (Exception ex)
{
_log.LogWarning(ex, "Error while invoking ConfigurationChanged event");
}
}
public PluginConfiguration GetConfig(Guid userId)
{
try
{
var cfg = _cache.UserConfig(
userId,
_ =>
{
var built = Instance?.Configuration;
if (userId != Guid.Empty)
{
var userConfig = Instance?.Configuration.UserConfigs.FirstOrDefault(u =>
u.UserId == userId
);
built =
userConfig?.ApplyOverrides(Instance?.Configuration)
?? Instance?.Configuration;
}
built.Stremio = _stremioFactory.Create(built);
return built;
}
);
// Resolved on every call rather than once with the cached entry. The libraries
// backing these paths are usually added after Gelato is first configured, and a
// null cached from before they existed would never recover on its own — the
// symptom being imports that quietly do nothing until the server is restarted.
// GelatoManager memoizes the underlying lookup, so this stays cheap.
cfg.MovieFolder = _manager.TryGetMovieFolder(cfg);
cfg.SeriesFolder = _manager.TryGetSeriesFolder(cfg);
// Seeds the catalogs' folders too, so one can be added to a library right away.
_manager.GetCatalogFolders(cfg);
return cfg;
}
catch (Exception ex)
{
_log.LogWarning(ex, "Error getting config");
return new PluginConfiguration();
}
}
}