Some checks failed
release / build-release (push) Has been cancelled
- per-creator "All videos" folder (release order across sub-channels); sub-channel copies use cpost: ids and UserDataMirror keeps played/resume state in sync - SortNameUpdater forces release-order sort names so every client lists newest first by default - official Floatplane icon as channel image (Primary only — a channel Thumb hid video thumbnails in Continue Watching) and as 16:9 plugin thumbnail; one-time image replacement on upgrade - OAuth device-flow login (FloatplaneAuthService + settings UI); needs a Floatplane client id; Turnstile verified domain-bound so password login inside Jellyfin is impossible - generic install.sh (linuxserver / official image / native), thumb.png in package + manifest - README rewritten for a general audience, doc/usage.md with screenshots, 60 tests Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
57 lines
2.5 KiB
C#
57 lines
2.5 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// Registers the plugin's services. Found by Jellyfin through type scanning; needs a
|
|
/// parameterless constructor. In 10.10 <c>ChannelManager</c> takes <c>IEnumerable<IChannel></c>
|
|
/// from DI, so the channel must be registered here.
|
|
/// </summary>
|
|
public class PluginServiceRegistrator : IPluginServiceRegistrator
|
|
{
|
|
/// <summary>Named HttpClient for Floatplane API + CDN traffic.</summary>
|
|
public const string HttpClientName = "Floatplane";
|
|
|
|
/// <inheritdoc />
|
|
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<FloatplaneAuthService>();
|
|
serviceCollection.AddSingleton<FloatplaneApiClient>();
|
|
serviceCollection.AddSingleton<CatalogService>();
|
|
serviceCollection.AddSingleton<DeliveryResolver>();
|
|
|
|
// One instance: the status endpoint and the sync task must see the same caches
|
|
// as the channel Jellyfin serves from.
|
|
serviceCollection.AddSingleton<SortNameUpdater>();
|
|
serviceCollection.AddSingleton<FloatplaneChannel>();
|
|
serviceCollection.AddSingleton<IChannel>(sp => sp.GetRequiredService<FloatplaneChannel>());
|
|
|
|
// 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<UserDataMirror>();
|
|
}
|
|
}
|