using System; using System.Net.Http; using Jellyfin.Plugin.Floatplane.Api; using Jellyfin.Plugin.Floatplane.Channel; using Jellyfin.Plugin.Floatplane.Playback; using MediaBrowser.Controller; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Plugins; using Microsoft.Extensions.DependencyInjection; namespace Jellyfin.Plugin.Floatplane; /// /// Registers the plugin's services. Found by Jellyfin through type scanning; needs a /// parameterless constructor. In 10.10 ChannelManager takes IEnumerable<IChannel> /// from DI, so the channel must be registered here. /// public class PluginServiceRegistrator : IPluginServiceRegistrator { /// Named HttpClient for Floatplane API + CDN traffic. public const string HttpClientName = "Floatplane"; /// public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost) { serviceCollection .AddHttpClient(HttpClientName, client => { client.Timeout = TimeSpan.FromSeconds(60); client.DefaultRequestHeaders.UserAgent.ParseAdd(Plugin.UserAgent); }) .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { // The session cookie is attached per request; no cookie jar, no redirects // (a 302 from the CDN would otherwise be followed with the cookie attached). UseCookies = false, AllowAutoRedirect = false, AutomaticDecompression = System.Net.DecompressionMethods.All }); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); // One instance: the status endpoint and the sync task must see the same caches // as the channel Jellyfin serves from. serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(sp => sp.GetRequiredService()); // The same post appears under "All videos" and under its sub-channel (Jellyfin // allows one parent per item id); this keeps watched/resume state in sync. serviceCollection.AddHostedService(); } }