handle library selection by jellyfin

This commit is contained in:
Kilian von Pflugk 2024-11-24 17:53:07 +01:00
parent 9fce12bdbb
commit f20ccaed42
6 changed files with 80 additions and 73 deletions

View File

@ -1,7 +1,6 @@
// Copyright (C) 2024 Intro-Skipper contributors <intro-skipper.org>
// SPDX-License-Identifier: GPL-3.0-only.
using System.Collections.Generic;
using System.Diagnostics;
using IntroSkipper.Data;
using MediaBrowser.Model.Plugins;
@ -22,16 +21,6 @@ public class PluginConfiguration : BasePluginConfiguration
// ===== Analysis settings =====
/// <summary>
/// Gets or sets the comma separated list of library names to analyze.
/// </summary>
public string SelectedLibraries { get; set; } = string.Empty;
/// <summary>
/// Gets or sets a value indicating whether all libraries should be analyzed.
/// </summary>
public bool SelectAllLibraries { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether movies should be analyzed.
/// </summary>
@ -299,4 +288,16 @@ public class PluginConfiguration : BasePluginConfiguration
/// Gets or sets a value indicating whether the ManifestUrl is self-managed, e.g. for mainland China.
/// </summary>
public bool OverrideManifestUrl { get; set; }
// ===== Deprecated =====
/// <summary>
/// Gets or sets the comma separated list of library names to analyze.
/// </summary>
public string SelectedLibraries { get; set; } = string.Empty;
/// <summary>
/// Gets or sets a value indicating whether all libraries should be analyzed.
/// </summary>
public bool SelectAllLibraries { get; set; } = true;
}

View File

@ -73,22 +73,6 @@
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="SelectAllLibraries" type="checkbox" is="emby-checkbox" />
<span>Enable analysis for all libraries containing television episodes</span>
</label>
<div class="folderAccessListContainer">
<div class="folderAccess">
<h3 class="checkboxListLabel">Limit analysis to the following libraries</h3>
<div class="checkboxList paperList" style="padding: 0.5em 1em" id="libraryCheckboxes"></div>
</div>
<label class="inputLabel" for="SelectedLibraries"></label>
<input id="SelectedLibraries" type="hidden" is="emby-input" />
</div>
</div>
<details id="intro_reqs">
<summary>Modify Segment Parameters</summary>
@ -763,7 +747,6 @@
var configurationFields = [
// analysis
"MaxParallelism",
"SelectedLibraries",
"ClientList",
"AnalysisPercent",
"AnalysisLengthLimit",
@ -793,7 +776,23 @@
"AutoSkipNotificationText",
];
var booleanConfigurationFields = ["AutoDetectIntros", "AnalyzeMovies", "AnalyzeSeasonZero", "SelectAllLibraries", "UpdateMediaSegments", "RebuildMediaSegments", "ScanIntroduction", "ScanCredits", "ScanRecap", "ScanPreview", "CacheFingerprints", "PluginSkip", "AutoSkip", "SkipFirstEpisode", "PersistSkipButton", "SkipButtonEnabled"];
var booleanConfigurationFields = [
"AutoDetectIntros",
"AnalyzeMovies",
"AnalyzeSeasonZero",
"UpdateMediaSegments",
"RebuildMediaSegments",
"ScanIntroduction",
"ScanCredits",
"ScanRecap",
"ScanPreview",
"CacheFingerprints",
"PluginSkip",
"AutoSkip",
"SkipFirstEpisode",
"PersistSkipButton",
"SkipButtonEnabled"
];
// visualizer elements
var analyzerActionsSection = document.querySelector("div#analyzerActionsSection");
@ -831,8 +830,6 @@
var skipButtonVisible = document.getElementById("SkipButtonEnabled");
var skipButtonVisibleLabel = document.getElementById("SkipButtonVisibleLabel");
var skipButtonSettings = document.getElementById("SkipButtonSettings");
var selectAllLibraries = document.querySelector("input#SelectAllLibraries");
var librariesContainer = document.querySelector("div.folderAccessListContainer");
var skipFirstEpisode = document.getElementById("divSkipFirstEpisode");
var secondsOfIntroStartToPlay = document.getElementById("divSecondsOfIntroStartToPlay");
var autoSkipClientList = document.querySelector("div.AutoSkipClientListContainer");
@ -864,16 +861,6 @@
autoSkip.addEventListener("change", autoSkipChanged);
function selectAllLibrariesChanged() {
if (selectAllLibraries.checked) {
librariesContainer.style.display = "none";
} else {
librariesContainer.style.display = "unset";
}
}
selectAllLibraries.addEventListener("change", selectAllLibrariesChanged);
function updateList(textField, container) {
textField.value = Array.from(container.querySelectorAll('input[type="checkbox"]:checked'))
.map((checkbox) => checkbox.nextElementSibling.textContent)
@ -912,13 +899,6 @@
generateCheckboxList(types, "autoSkipTypeCheckboxes", "TypeList");
}
async function populateLibraries() {
const response = await getJson("Library/VirtualFolders");
const tvLibraries = response.filter((item) => item.CollectionType === undefined || item.CollectionType === "tvshows" || item.CollectionType === "movies");
const libraryNames = tvLibraries.map((lib) => lib.Name || "Unnamed Library");
generateCheckboxList(libraryNames, "libraryCheckboxes", "SelectedLibraries");
}
var persistSkip = document.getElementById("PersistSkipButton");
var showAdjustment = document.querySelector("div#divShowPromptAdjustment");
var hideAdjustment = document.querySelector("div#divHidePromptAdjustment");
@ -1444,8 +1424,6 @@
document.getElementById("warningMessage").style.display = "none";
}
populateLibraries();
selectAllLibrariesChanged();
autoSkipChanged();
persistSkipChanged();
generateAutoSkipTypeList();

View File

@ -10,6 +10,8 @@ using IntroSkipper.Data;
using IntroSkipper.Db;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Updates;
using Microsoft.Extensions.Logging;
@ -21,7 +23,8 @@ internal static class LegacyMigrations
Plugin plugin,
IServerConfigurationManager serverConfiguration,
ILogger logger,
IApplicationPaths applicationPaths)
IApplicationPaths applicationPaths,
ILibraryManager libraryManager)
{
var pluginDirName = "introskipper";
var introPath = Path.Join(applicationPaths.DataPath, pluginDirName, "intros.xml");
@ -32,6 +35,7 @@ internal static class LegacyMigrations
MigrateConfig(plugin, applicationPaths.PluginConfigurationsPath, logger);
MigrateRepoUrl(plugin, serverConfiguration, logger);
MigrateSettingsToJellyfin(plugin, logger, libraryManager);
InjectSkipButton(plugin, applicationPaths.WebPath, logger);
RestoreTimestamps(plugin.DbPath, introPath, creditsPath);
}
@ -215,4 +219,45 @@ internal static class LegacyMigrations
File.Delete(introPath);
File.Delete(creditsPath);
}
private static void MigrateSettingsToJellyfin(Plugin plugin, ILogger logger, ILibraryManager libraryManager)
{
try
{
if (!plugin.Configuration.SelectAllLibraries)
{
logger.LogInformation("Migration of your old library settings to Jellyfin");
List<string> selectedLibraries = [.. plugin.Configuration.SelectedLibraries.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)];
foreach (var folder in libraryManager.GetVirtualFolders())
{
if (!selectedLibraries.Contains(folder.Name) && folder.CollectionType is CollectionTypeOptions.tvshows or CollectionTypeOptions.movies or CollectionTypeOptions.mixed)
{
// only add if not already disabled
if (!folder.LibraryOptions.DisabledMediaSegmentProviders.Contains(plugin.Name))
{
// ppend in case there other disabled media segment providers
folder.LibraryOptions.DisabledMediaSegmentProviders = [.. folder.LibraryOptions.DisabledMediaSegmentProviders, plugin.Name];
logger.LogInformation("Disable Media Segment Provider <{Name}> for Library <{Name}>", plugin.Name, folder.Name);
}
}
}
// reset to default
plugin.Configuration.SelectAllLibraries = true;
plugin.Configuration.SelectedLibraries = string.Empty;
plugin.SaveConfiguration();
}
}
catch (Exception ex)
{
logger.LogWarning("The migration of your old library settings to Jellyfin has failed: {Exception}", ex);
}
finally
{
// reset to default
plugin.Configuration.SelectAllLibraries = true;
plugin.Configuration.SelectedLibraries = string.Empty;
plugin.SaveConfiguration();
}
}
}

View File

@ -30,8 +30,6 @@ namespace IntroSkipper.Manager
private readonly ILogger<QueueManager> _logger = logger;
private readonly Dictionary<Guid, List<QueuedEpisode>> _queuedEpisodes = [];
private double _analysisPercent;
private List<string> _selectedLibraries = [];
private bool _selectAllLibraries;
private bool _analyzeMovies;
/// <summary>
@ -48,9 +46,9 @@ namespace IntroSkipper.Manager
foreach (var folder in _libraryManager.GetVirtualFolders())
{
// If libraries have been selected for analysis, ensure this library was selected.
if (!_selectAllLibraries && !_selectedLibraries.Contains(folder.Name))
if (folder.LibraryOptions.DisabledMediaSegmentProviders.Contains(Plugin.Instance.Name))
{
_logger.LogDebug("Not analyzing library \"{Name}\": not selected by user", folder.Name);
_logger.LogDebug("Not analyzing library \"{Name}\": Intro Skipper is disabled in library settings. To enable, check library configuration > Media Segment Providers", folder.Name);
continue;
}
@ -93,23 +91,8 @@ namespace IntroSkipper.Manager
// Store the analysis percent
_analysisPercent = Convert.ToDouble(config.AnalysisPercent) / 100;
_selectAllLibraries = config.SelectAllLibraries;
_analyzeMovies = config.AnalyzeMovies;
if (!_selectAllLibraries)
{
// Get the list of library names which have been selected for analysis, ignoring whitespace and empty entries.
_selectedLibraries = [.. config.SelectedLibraries.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)];
// If any libraries have been selected for analysis, log their names.
_logger.LogInformation("Limiting analysis to the following libraries: {Selected}", _selectedLibraries);
}
else
{
_logger.LogDebug("Not limiting analysis by library name");
}
// If analysis settings have been changed from the default, log the modified settings.
if (config.AnalysisLengthLimit != 10 || config.AnalysisPercent != 25 || config.MinimumIntroDuration != 15)
{

View File

@ -79,7 +79,7 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
try
{
LegacyMigrations.MigrateAll(this, serverConfiguration, logger, applicationPaths);
LegacyMigrations.MigrateAll(this, serverConfiguration, logger, applicationPaths, _libraryManager);
}
catch (Exception ex)
{

View File

@ -79,8 +79,8 @@ public class BaseItemAnalyzerTask(
int totalQueued = queue.Sum(kvp => kvp.Value.Count) * modes.Count;
if (totalQueued == 0)
{
throw new FingerprintException(
"No libraries selected for analysis. Please visit the plugin settings to configure.");
_logger.LogInformation("No libraries selected for analysis. To enable, check library configuration > Media Segment Providers.");
return;
}
int totalProcessed = 0;