Compare commits
4 Commits
10.10
...
jellyfin_s
Author | SHA1 | Date | |
---|---|---|---|
|
bf258c1efb | ||
|
886908c636 | ||
|
a8753a03a3 | ||
|
f20ccaed42 |
@ -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,21 +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>
|
||||
public bool AnalyzeMovies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of client to auto skip for.
|
||||
/// </summary>
|
||||
@ -299,4 +283,21 @@ 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;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether movies should be analyzed.
|
||||
/// </summary>
|
||||
public bool AnalyzeMovies { get; set; }
|
||||
}
|
||||
|
@ -55,13 +55,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer">
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="AnalyzeMovies" type="checkbox" is="emby-checkbox" />
|
||||
<span>Analyze Movies</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="AnalyzeSeasonZero" type="checkbox" is="emby-checkbox" />
|
||||
@ -73,22 +66,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>
|
||||
|
||||
@ -762,7 +739,6 @@
|
||||
var configurationFields = [
|
||||
// analysis
|
||||
"MaxParallelism",
|
||||
"SelectedLibraries",
|
||||
"ClientList",
|
||||
"AnalysisPercent",
|
||||
"AnalysisLengthLimit",
|
||||
@ -792,7 +768,22 @@
|
||||
"AutoSkipNotificationText",
|
||||
];
|
||||
|
||||
var booleanConfigurationFields = ["AutoDetectIntros", "AnalyzeMovies", "AnalyzeSeasonZero", "SelectAllLibraries", "UpdateMediaSegments", "RebuildMediaSegments", "ScanIntroduction", "ScanCredits", "ScanRecap", "ScanPreview", "CacheFingerprints", "PluginSkip", "AutoSkip", "SkipFirstEpisode", "PersistSkipButton", "SkipButtonEnabled"];
|
||||
var booleanConfigurationFields = [
|
||||
"AutoDetectIntros",
|
||||
"AnalyzeSeasonZero",
|
||||
"UpdateMediaSegments",
|
||||
"RebuildMediaSegments",
|
||||
"ScanIntroduction",
|
||||
"ScanCredits",
|
||||
"ScanRecap",
|
||||
"ScanPreview",
|
||||
"CacheFingerprints",
|
||||
"PluginSkip",
|
||||
"AutoSkip",
|
||||
"SkipFirstEpisode",
|
||||
"PersistSkipButton",
|
||||
"SkipButtonEnabled"
|
||||
];
|
||||
|
||||
// visualizer elements
|
||||
var analyzerActionsSection = document.querySelector("div#analyzerActionsSection");
|
||||
@ -823,15 +814,12 @@
|
||||
|
||||
var windowHashInterval = 0;
|
||||
|
||||
var analyzeMovies = document.getElementById("AnalyzeMovies");
|
||||
var pluginSkip = document.getElementById("PluginSkip");
|
||||
var serverSkipSettings = document.getElementById("ServerSkipSettings");
|
||||
var autoSkip = document.getElementById("AutoSkip");
|
||||
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");
|
||||
@ -863,16 +851,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)
|
||||
@ -911,13 +889,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");
|
||||
@ -949,16 +920,6 @@
|
||||
|
||||
pluginSkip.addEventListener("change", pluginSkipSettingChanged);
|
||||
|
||||
async function analyzeMoviesChanged() {
|
||||
if (analyzeMovies.checked) {
|
||||
movieCreditsDuration.style.display = "unset";
|
||||
} else {
|
||||
movieCreditsDuration.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
analyzeMovies.addEventListener("change", analyzeMoviesChanged);
|
||||
|
||||
// when the fingerprint visualizer opens, populate show names
|
||||
async function visualizerToggled() {
|
||||
if (!visualizer.open) {
|
||||
@ -1443,8 +1404,6 @@
|
||||
document.getElementById("warningMessage").style.display = "none";
|
||||
}
|
||||
|
||||
populateLibraries();
|
||||
selectAllLibrariesChanged();
|
||||
autoSkipChanged();
|
||||
persistSkipChanged();
|
||||
generateAutoSkipTypeList();
|
||||
|
@ -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);
|
||||
}
|
||||
@ -123,7 +127,7 @@ internal static class LegacyMigrations
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// If skip button is disabled and we can't access the file, just return silently
|
||||
// If skip button is disabled, and we can't access the file, just return silently
|
||||
if (!plugin.Configuration.SkipButtonEnabled)
|
||||
{
|
||||
logger.LogDebug("Skip button disabled and no permission to access index.html. Assuming its a fresh install.");
|
||||
@ -215,4 +219,67 @@ 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))
|
||||
{
|
||||
// append 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();
|
||||
}
|
||||
|
||||
if (!plugin.Configuration.AnalyzeMovies)
|
||||
{
|
||||
logger.LogInformation("Migration of your old Movie settings to Jellyfin");
|
||||
foreach (var folder in libraryManager.GetVirtualFolders())
|
||||
{
|
||||
if (folder.CollectionType is CollectionTypeOptions.movies or CollectionTypeOptions.mixed)
|
||||
{
|
||||
// only add if not already disabled
|
||||
if (!folder.LibraryOptions.DisabledMediaSegmentProviders.Contains(plugin.Name))
|
||||
{
|
||||
// append 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.AnalyzeMovies = true;
|
||||
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,9 +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>
|
||||
/// Gets all media items on the server.
|
||||
@ -48,9 +45,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 +90,6 @@ 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)
|
||||
{
|
||||
@ -153,12 +133,9 @@ namespace IntroSkipper.Manager
|
||||
QueueEpisode(episode);
|
||||
}
|
||||
else if (item is Movie movie)
|
||||
{
|
||||
if (_analyzeMovies)
|
||||
{
|
||||
QueueMovie(movie);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogDebug("Item {Name} is not an episode or movie", item.Name);
|
||||
|
@ -90,7 +90,7 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
|
||||
try
|
||||
{
|
||||
LegacyMigrations.MigrateAll(this, serverConfiguration, logger, applicationPaths);
|
||||
LegacyMigrations.MigrateAll(this, serverConfiguration, logger, applicationPaths, _libraryManager);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user