handle library selection by jellyfin
This commit is contained in:
parent
9fce12bdbb
commit
f20ccaed42
@ -1,7 +1,6 @@
|
|||||||
// Copyright (C) 2024 Intro-Skipper contributors <intro-skipper.org>
|
// Copyright (C) 2024 Intro-Skipper contributors <intro-skipper.org>
|
||||||
// SPDX-License-Identifier: GPL-3.0-only.
|
// SPDX-License-Identifier: GPL-3.0-only.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using IntroSkipper.Data;
|
using IntroSkipper.Data;
|
||||||
using MediaBrowser.Model.Plugins;
|
using MediaBrowser.Model.Plugins;
|
||||||
@ -22,16 +21,6 @@ public class PluginConfiguration : BasePluginConfiguration
|
|||||||
|
|
||||||
// ===== Analysis settings =====
|
// ===== 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>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether movies should be analyzed.
|
/// Gets or sets a value indicating whether movies should be analyzed.
|
||||||
/// </summary>
|
/// </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.
|
/// Gets or sets a value indicating whether the ManifestUrl is self-managed, e.g. for mainland China.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool OverrideManifestUrl { get; set; }
|
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;
|
||||||
}
|
}
|
||||||
|
@ -73,22 +73,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</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">
|
<details id="intro_reqs">
|
||||||
<summary>Modify Segment Parameters</summary>
|
<summary>Modify Segment Parameters</summary>
|
||||||
|
|
||||||
@ -763,7 +747,6 @@
|
|||||||
var configurationFields = [
|
var configurationFields = [
|
||||||
// analysis
|
// analysis
|
||||||
"MaxParallelism",
|
"MaxParallelism",
|
||||||
"SelectedLibraries",
|
|
||||||
"ClientList",
|
"ClientList",
|
||||||
"AnalysisPercent",
|
"AnalysisPercent",
|
||||||
"AnalysisLengthLimit",
|
"AnalysisLengthLimit",
|
||||||
@ -793,7 +776,23 @@
|
|||||||
"AutoSkipNotificationText",
|
"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
|
// visualizer elements
|
||||||
var analyzerActionsSection = document.querySelector("div#analyzerActionsSection");
|
var analyzerActionsSection = document.querySelector("div#analyzerActionsSection");
|
||||||
@ -831,8 +830,6 @@
|
|||||||
var skipButtonVisible = document.getElementById("SkipButtonEnabled");
|
var skipButtonVisible = document.getElementById("SkipButtonEnabled");
|
||||||
var skipButtonVisibleLabel = document.getElementById("SkipButtonVisibleLabel");
|
var skipButtonVisibleLabel = document.getElementById("SkipButtonVisibleLabel");
|
||||||
var skipButtonSettings = document.getElementById("SkipButtonSettings");
|
var skipButtonSettings = document.getElementById("SkipButtonSettings");
|
||||||
var selectAllLibraries = document.querySelector("input#SelectAllLibraries");
|
|
||||||
var librariesContainer = document.querySelector("div.folderAccessListContainer");
|
|
||||||
var skipFirstEpisode = document.getElementById("divSkipFirstEpisode");
|
var skipFirstEpisode = document.getElementById("divSkipFirstEpisode");
|
||||||
var secondsOfIntroStartToPlay = document.getElementById("divSecondsOfIntroStartToPlay");
|
var secondsOfIntroStartToPlay = document.getElementById("divSecondsOfIntroStartToPlay");
|
||||||
var autoSkipClientList = document.querySelector("div.AutoSkipClientListContainer");
|
var autoSkipClientList = document.querySelector("div.AutoSkipClientListContainer");
|
||||||
@ -864,16 +861,6 @@
|
|||||||
|
|
||||||
autoSkip.addEventListener("change", autoSkipChanged);
|
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) {
|
function updateList(textField, container) {
|
||||||
textField.value = Array.from(container.querySelectorAll('input[type="checkbox"]:checked'))
|
textField.value = Array.from(container.querySelectorAll('input[type="checkbox"]:checked'))
|
||||||
.map((checkbox) => checkbox.nextElementSibling.textContent)
|
.map((checkbox) => checkbox.nextElementSibling.textContent)
|
||||||
@ -912,13 +899,6 @@
|
|||||||
generateCheckboxList(types, "autoSkipTypeCheckboxes", "TypeList");
|
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 persistSkip = document.getElementById("PersistSkipButton");
|
||||||
var showAdjustment = document.querySelector("div#divShowPromptAdjustment");
|
var showAdjustment = document.querySelector("div#divShowPromptAdjustment");
|
||||||
var hideAdjustment = document.querySelector("div#divHidePromptAdjustment");
|
var hideAdjustment = document.querySelector("div#divHidePromptAdjustment");
|
||||||
@ -1444,8 +1424,6 @@
|
|||||||
document.getElementById("warningMessage").style.display = "none";
|
document.getElementById("warningMessage").style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
populateLibraries();
|
|
||||||
selectAllLibrariesChanged();
|
|
||||||
autoSkipChanged();
|
autoSkipChanged();
|
||||||
persistSkipChanged();
|
persistSkipChanged();
|
||||||
generateAutoSkipTypeList();
|
generateAutoSkipTypeList();
|
||||||
|
@ -10,6 +10,8 @@ using IntroSkipper.Data;
|
|||||||
using IntroSkipper.Db;
|
using IntroSkipper.Db;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Updates;
|
using MediaBrowser.Model.Updates;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
@ -21,7 +23,8 @@ internal static class LegacyMigrations
|
|||||||
Plugin plugin,
|
Plugin plugin,
|
||||||
IServerConfigurationManager serverConfiguration,
|
IServerConfigurationManager serverConfiguration,
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
IApplicationPaths applicationPaths)
|
IApplicationPaths applicationPaths,
|
||||||
|
ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
var pluginDirName = "introskipper";
|
var pluginDirName = "introskipper";
|
||||||
var introPath = Path.Join(applicationPaths.DataPath, pluginDirName, "intros.xml");
|
var introPath = Path.Join(applicationPaths.DataPath, pluginDirName, "intros.xml");
|
||||||
@ -32,6 +35,7 @@ internal static class LegacyMigrations
|
|||||||
|
|
||||||
MigrateConfig(plugin, applicationPaths.PluginConfigurationsPath, logger);
|
MigrateConfig(plugin, applicationPaths.PluginConfigurationsPath, logger);
|
||||||
MigrateRepoUrl(plugin, serverConfiguration, logger);
|
MigrateRepoUrl(plugin, serverConfiguration, logger);
|
||||||
|
MigrateSettingsToJellyfin(plugin, logger, libraryManager);
|
||||||
InjectSkipButton(plugin, applicationPaths.WebPath, logger);
|
InjectSkipButton(plugin, applicationPaths.WebPath, logger);
|
||||||
RestoreTimestamps(plugin.DbPath, introPath, creditsPath);
|
RestoreTimestamps(plugin.DbPath, introPath, creditsPath);
|
||||||
}
|
}
|
||||||
@ -215,4 +219,45 @@ internal static class LegacyMigrations
|
|||||||
File.Delete(introPath);
|
File.Delete(introPath);
|
||||||
File.Delete(creditsPath);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,6 @@ namespace IntroSkipper.Manager
|
|||||||
private readonly ILogger<QueueManager> _logger = logger;
|
private readonly ILogger<QueueManager> _logger = logger;
|
||||||
private readonly Dictionary<Guid, List<QueuedEpisode>> _queuedEpisodes = [];
|
private readonly Dictionary<Guid, List<QueuedEpisode>> _queuedEpisodes = [];
|
||||||
private double _analysisPercent;
|
private double _analysisPercent;
|
||||||
private List<string> _selectedLibraries = [];
|
|
||||||
private bool _selectAllLibraries;
|
|
||||||
private bool _analyzeMovies;
|
private bool _analyzeMovies;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -48,9 +46,9 @@ namespace IntroSkipper.Manager
|
|||||||
foreach (var folder in _libraryManager.GetVirtualFolders())
|
foreach (var folder in _libraryManager.GetVirtualFolders())
|
||||||
{
|
{
|
||||||
// If libraries have been selected for analysis, ensure this library was selected.
|
// 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,23 +91,8 @@ namespace IntroSkipper.Manager
|
|||||||
// Store the analysis percent
|
// Store the analysis percent
|
||||||
_analysisPercent = Convert.ToDouble(config.AnalysisPercent) / 100;
|
_analysisPercent = Convert.ToDouble(config.AnalysisPercent) / 100;
|
||||||
|
|
||||||
_selectAllLibraries = config.SelectAllLibraries;
|
|
||||||
|
|
||||||
_analyzeMovies = config.AnalyzeMovies;
|
_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 analysis settings have been changed from the default, log the modified settings.
|
||||||
if (config.AnalysisLengthLimit != 10 || config.AnalysisPercent != 25 || config.MinimumIntroDuration != 15)
|
if (config.AnalysisLengthLimit != 10 || config.AnalysisPercent != 25 || config.MinimumIntroDuration != 15)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +79,7 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LegacyMigrations.MigrateAll(this, serverConfiguration, logger, applicationPaths);
|
LegacyMigrations.MigrateAll(this, serverConfiguration, logger, applicationPaths, _libraryManager);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -79,8 +79,8 @@ public class BaseItemAnalyzerTask(
|
|||||||
int totalQueued = queue.Sum(kvp => kvp.Value.Count) * modes.Count;
|
int totalQueued = queue.Sum(kvp => kvp.Value.Count) * modes.Count;
|
||||||
if (totalQueued == 0)
|
if (totalQueued == 0)
|
||||||
{
|
{
|
||||||
throw new FingerprintException(
|
_logger.LogInformation("No libraries selected for analysis. To enable, check library configuration > Media Segment Providers.");
|
||||||
"No libraries selected for analysis. Please visit the plugin settings to configure.");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalProcessed = 0;
|
int totalProcessed = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user