Port to Jellyfin 10.11 (net9.0, IHostedService)

IServerEntryPoint was removed in favor of IHostedService; migrated
PlaybackScrobbler and updated PluginServiceRegistrator accordingly
(RegisterServices now takes IServerApplicationHost, AnilistApi moved
to a singleton so the hosted service can depend on it). Bumped
TargetFramework to net9.0 and targetAbi to 10.11.0.0.

Also fixed Endpoints.cs, which referenced an "DefaultAuthorization"
authorization policy that no longer resolves for plugin controllers
on 10.11, causing every API call to 500 instead of 401'ing when
unauthenticated. Verified end-to-end against a live 10.11.11 server:
plugin loads, OAuth re-auth works, and a real scrobble to Anilist
succeeded.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 23:10:40 +02:00
parent d5147340a8
commit c17d62fc62
5 changed files with 25 additions and 33 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ namespace Jellyfin.Plugin.AnilistSync.API
/// Anilist endpoints.
/// </summary>
[ApiController]
[Authorize(Policy = "DefaultAuthorization")]
[Authorize]
[Route("AnilistSync")]
public class Endpoints : ControllerBase
{
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<FileVersion>2.0.0.0</FileVersion>
<TargetFramework>net9.0</TargetFramework>
<AssemblyVersion>2.1.0.0</AssemblyVersion>
<FileVersion>2.1.0.0</FileVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<nullable>enable</nullable>
@@ -11,12 +11,12 @@
<ItemGroup>
<PackageReference Include="Jellyfin.Controller" Version="10.*-*" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.*" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.11" />
</ItemGroup>
<!-- Code Analyzers-->
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3" PrivateAssets="All" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" PrivateAssets="All" />
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
</ItemGroup>
@@ -1,5 +1,7 @@
using Jellyfin.Plugin.AnilistSync.API;
using MediaBrowser.Common.Plugins;
using Jellyfin.Plugin.AnilistSync.Services;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Plugins;
using Microsoft.Extensions.DependencyInjection;
namespace Jellyfin.Plugin.AnilistSync
@@ -8,9 +10,10 @@ namespace Jellyfin.Plugin.AnilistSync
public class PluginServiceRegistrator : IPluginServiceRegistrator
{
/// <inheritdoc />
public void RegisterServices(IServiceCollection serviceCollection)
public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost)
{
serviceCollection.AddScoped<AnilistApi>();
serviceCollection.AddSingleton<AnilistApi>();
serviceCollection.AddHostedService<PlaybackScrobbler>();
}
}
}
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using Jellyfin.Plugin.AnilistSync.API;
@@ -10,8 +11,8 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Model.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Plugin.AnilistSync.Services
@@ -19,7 +20,7 @@ namespace Jellyfin.Plugin.AnilistSync.Services
/// <summary>
/// Playback progress scrobbler.
/// </summary>
public class PlaybackScrobbler : IServerEntryPoint
public class PlaybackScrobbler : IHostedService
{
private readonly ISessionManager _sessionManager; // Needed to set up the startPlayBack and endPlayBack functions
private readonly ILogger<PlaybackScrobbler> _logger;
@@ -43,7 +44,7 @@ namespace Jellyfin.Plugin.AnilistSync.Services
}
/// <inheritdoc/>
public Task RunAsync()
public Task StartAsync(CancellationToken cancellationToken)
{
_sessionManager.PlaybackProgress += OnPlaybackProgress;
_sessionManager.PlaybackStopped += OnPlaybackStopped;
@@ -51,23 +52,11 @@ namespace Jellyfin.Plugin.AnilistSync.Services
}
/// <inheritdoc/>
public void Dispose()
public Task StopAsync(CancellationToken cancellationToken)
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Dispose.
/// </summary>
/// <param name="disposing">Dispoe all resources.</param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_sessionManager.PlaybackProgress -= OnPlaybackProgress;
_sessionManager.PlaybackStopped -= OnPlaybackStopped;
}
_sessionManager.PlaybackProgress -= OnPlaybackProgress;
_sessionManager.PlaybackStopped -= OnPlaybackStopped;
return Task.CompletedTask;
}
// UserConfig config,
@@ -169,7 +158,7 @@ namespace Jellyfin.Plugin.AnilistSync.Services
string? anilistId = GetAnilistId(eventArgs);
if (anilistId == null)
{
_logger.LogDebug("Cannot Scrobble {ItemName}, unknown AniList Id.");
_logger.LogDebug("Cannot Scrobble {ItemName}, unknown AniList Id.", eventArgs.MediaInfo.Name);
return;
}
+4 -4
View File
@@ -1,15 +1,15 @@
---
name: "AnilistSync"
guid: "18c2a8ea-afa0-4a0b-aa94-072b492ab80b"
version: "2.0.0.0"
targetAbi: "10.8.0.0"
version: "2.1.0.0"
targetAbi: "10.11.0.0"
owner: "ARufenach"
overview: "Scrobble to Anilist"
description: >
Jellyfin plugin to scrobble to Anilist
category: "General"
framework: "net6.0"
framework: "net9.0"
artifacts:
- "Jellyfin.Plugin.AnilistSync.dll"
changelog: >
Added support for jellyfin 10.8.0
Added support for Jellyfin 10.11 (migrated IServerEntryPoint to IHostedService, net9.0)