Expand integration coverage and fix settings UI

This commit is contained in:
ajp_anton
2026-07-21 00:42:44 +00:00
parent 25088ce91d
commit 094d5ad9f0
26 changed files with 1665 additions and 66 deletions
@@ -1,4 +1,7 @@
using System.Text.Json.Nodes;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Plugin.Multilang.Services;
@@ -6,20 +9,27 @@ namespace Jellyfin.Plugin.Multilang.Services;
public sealed class ItemsProxyPrecacheService
{
private static readonly TimeSpan IdleThreshold = TimeSpan.FromMinutes(30);
private readonly IServerApplicationHost _applicationHost;
private readonly IConfigurationManager _configurationManager;
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<ItemsProxyPrecacheService> _logger;
private readonly object _lock = new();
private readonly Dictionary<string, DateTimeOffset> _lastSeen = new(StringComparer.Ordinal);
private readonly HashSet<string> _pendingUsers = new(StringComparer.Ordinal);
public ItemsProxyPrecacheService(IHttpClientFactory httpClientFactory, ILogger<ItemsProxyPrecacheService> logger)
public ItemsProxyPrecacheService(
IServerApplicationHost applicationHost,
IConfigurationManager configurationManager,
IHttpClientFactory httpClientFactory,
ILogger<ItemsProxyPrecacheService> logger)
{
_applicationHost = applicationHost;
_configurationManager = configurationManager;
_httpClientFactory = httpClientFactory;
_logger = logger;
}
public void ObserveUserActivity(
Uri baseUri,
string userId,
string token,
string clientLocale,
@@ -38,11 +48,10 @@ public sealed class ItemsProxyPrecacheService
return;
}
_ = PrecacheAsync(baseUri, userId, token, clientLocale, precacheMovieLibraries, precacheTvShowLibraries);
_ = PrecacheAsync(userId, token, clientLocale, precacheMovieLibraries, precacheTvShowLibraries);
}
private async Task PrecacheAsync(
Uri baseUri,
string userId,
string token,
string clientLocale,
@@ -51,6 +60,8 @@ public sealed class ItemsProxyPrecacheService
{
try
{
var port = _configurationManager.GetNetworkConfiguration().InternalHttpPort;
var baseUri = new Uri(_applicationHost.GetLocalApiUrl("127.0.0.1", "http", port).TrimEnd('/') + "/");
var views = await GetJsonAsync(new Uri(baseUri, $"Users/{userId}/Views"), token).ConfigureAwait(false);
var items = views["Items"]?.AsArray() ?? [];
var targets = items
@@ -82,26 +82,25 @@ public static class ItemsProxySorting
public static string[] GetSortArticles(
SortArticleCatalog articleCatalog,
IEnumerable<SortArticleEntry> configuredArticles,
IReadOnlyList<SortArticleEntry> configuredArticles,
string? titleLanguage,
bool ignoreArticles = true)
{
if (!ignoreArticles)
return [];
var configured = configuredArticles.ToArray();
var always = configured
var always = configuredArticles
.Where(e => e.AlwaysApply == true)
.SelectMany(e => SplitArticles(e.Articles));
return always
.Concat(GetLanguageArticles(articleCatalog, configured, titleLanguage))
.Concat(GetLanguageArticles(articleCatalog, configuredArticles, titleLanguage))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToArray();
}
private static string[] GetLanguageArticles(
SortArticleCatalog articleCatalog,
SortArticleEntry[] configured,
IReadOnlyList<SortArticleEntry> configured,
string? titleLanguage)
{
var language = (titleLanguage ?? string.Empty).Trim();
@@ -84,6 +84,7 @@ public sealed class ItemsProxyTransformer
? ApplyRules(items, ids, rules, controls.ClientLocale, factsByItem)
: new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var jellyfinTitleLanguages = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var sortArticlesByLanguage = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
ItemsProxySorting.Apply(root, controls, sortCulture, item =>
{
@@ -91,7 +92,13 @@ public sealed class ItemsProxyTransformer
var language = itemId is not null && titleLanguages.TryGetValue(itemId, out var translatedLanguage)
? translatedLanguage
: ResolveJellyfinTitleLanguage(itemId, config, jellyfinTitleLanguages);
return ItemsProxySorting.GetSortArticles(_articleCatalog, config.ArticleEntries, language, config.IgnoreArticlesWhenSorting);
if (!sortArticlesByLanguage.TryGetValue(language, out var articles))
{
articles = ItemsProxySorting.GetSortArticles(_articleCatalog, config.ArticleEntries, language, config.IgnoreArticlesWhenSorting);
sortArticlesByLanguage[language] = articles;
}
return articles;
});
return new ItemsProxyTransformResult(root.ToJsonString(new JsonSerializerOptions { WriteIndented = false }), ids);
}