Skip to content

Commit

Permalink
feat: add per library structure type respect preferred image setting
Browse files Browse the repository at this point in the history
  • Loading branch information
revam committed Dec 6, 2024
1 parent ea2078e commit 70eb8e2
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 15 deletions.
17 changes: 15 additions & 2 deletions Shokofin/Configuration/PluginConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
Expand Down Expand Up @@ -204,6 +205,14 @@ public DescriptionProvider[] ThirdPartyIdProviderList {
/// </summary>
public ImageType[] AddImageLanguageCodeForMovies { get; set; }

/// <summary>
/// This isn't used anymore, but is kept for upgrading the config in a
/// backwards compatible manner.
/// TODO: REMOVE THIS IN 6.0
/// </summary>
[JsonIgnore]
public bool? RespectPreferredImage { get; set; }

/// <summary>
/// Respect the preferred image flag sent from server when selecting the
/// correct image to use for the library. Setting this will also set the
Expand All @@ -212,7 +221,7 @@ public DescriptionProvider[] ThirdPartyIdProviderList {
/// <see cref="AddImageLanguageCodeForMovies"/> are enabled, thus ensuring
/// it is always selected for the library.
/// </summary>
public bool RespectPreferredImage { get; set; }
public SeriesStructureType[] RespectPreferredImagePerStructureType { get; set; }

#endregion

Expand Down Expand Up @@ -663,7 +672,11 @@ public PluginConfiguration() {
AddImageLanguageCode = null;
AddImageLanguageCodeForShows = [];
AddImageLanguageCodeForMovies = [];
RespectPreferredImage = true;
RespectPreferredImage = null;
RespectPreferredImagePerStructureType = [
SeriesStructureType.AniDB_Anime,
SeriesStructureType.Shoko_Groups,
];

VFS_Enabled = true;
VFS_Threads = 4;
Expand Down
4 changes: 2 additions & 2 deletions Shokofin/Pages/Scripts/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ function applyFormToConfig(form, config) {
config.SynopsisRemoveSummary = form.querySelector("#CleanupAniDBDescriptions").checked;
config.AddImageLanguageCodeForShows = retrieveCheckboxList(form, "AddImageLanguageCodeForShows");
config.AddImageLanguageCodeForMovies = retrieveCheckboxList(form, "AddImageLanguageCodeForMovies");
config.RespectPreferredImage = form.querySelector("#RespectPreferredImage").checked;
config.RespectPreferredImagePerStructureType = retrieveCheckboxList(form, "RespectPreferredImagePerStructureType");
config.HideUnverifiedTags = form.querySelector("#HideUnverifiedTags").checked;
config.TagSources = retrieveCheckboxList(form, "TagSources").join(", ");
config.TagIncludeFilters = retrieveCheckboxList(form, "TagIncludeFilters").join(", ");
Expand Down Expand Up @@ -532,7 +532,7 @@ async function applyConfigToForm(form, config) {
);
renderCheckboxList(form, "AddImageLanguageCodeForShows", config.AddImageLanguageCodeForShows);
renderCheckboxList(form, "AddImageLanguageCodeForMovies", config.AddImageLanguageCodeForMovies);
form.querySelector("#RespectPreferredImage").checked = config.RespectPreferredImage;
renderCheckboxList(form, "RespectPreferredImagePerStructureType", config.RespectPreferredImagePerStructureType.map(s => s.trim()).filter(s => s));
form.querySelector("#HideUnverifiedTags").checked = config.HideUnverifiedTags;
renderCheckboxList(form, "TagSources", config.TagSources.split(",").map(s => s.trim()).filter(s => s));
renderCheckboxList(form, "TagIncludeFilters", config.TagIncludeFilters.split(",").map(s => s.trim()).filter(s => s));
Expand Down
38 changes: 32 additions & 6 deletions Shokofin/Pages/Settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -1104,12 +1104,38 @@ <h3 class="listItemBodyText">Logos</h3>
</div>
<div class="fieldDescription">Add the language code to image metadata for movie libraries provided to Jellyfin, which it can use to prioritize images based on a library's configured metadata language. If a library has no language set, Jellyfin will prioritize English labeled images if this option is set, and will otherwise use the first available image.</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription expert-only">
<label class="emby-checkbox-label">
<input is="emby-checkbox" type="checkbox" id="RespectPreferredImage" />
<span>Respect Preferred Image</span>
</label>
<div class="fieldDescription checkboxFieldDescription">Respect the preferred image flag sent from server when selecting the correct image to use for the library. Setting this will also set the language code to the preferred language code for the library if "Add Language Code" is enabled, thus ensuring it is always selected for the library.</div>
<div id="RespectPreferredImagePerStructureType" is="checkbox-list" class="expert-only" style="margin-bottom: 2em;">
<h3 class="checkboxListLabel">Respect Preferred Image</h3>
<div class="checkboxList paperList checkboxList-paperList">
<div class="listItem">
<label class="listItemCheckboxContainer">
<input is="emby-checkbox" type="checkbox" data-option="AniDB_Anime">
<span></span>
</label>
<div class="listItemBody">
<h3 class="listItemBodyText">AniDB Anime Structure</h3>
</div>
</div>
<div class="listItem">
<label class="listItemCheckboxContainer">
<input is="emby-checkbox" type="checkbox" data-option="Shoko_Groups">
<span></span>
</label>
<div class="listItemBody">
<h3 class="listItemBodyText">Shoko Group Structure</h3>
</div>
</div>
<div class="listItem">
<label class="listItemCheckboxContainer">
<input is="emby-checkbox" type="checkbox" data-option="TMDB_SeriesAndMovies">
<span></span>
</label>
<div class="listItemBody">
<h3 class="listItemBodyText">TheMovieDb Shows &amp; Movies Structure</h3>
</div>
</div>
</div>
<div class="fieldDescription">Respect the preferred image flag sent from server when selecting the correct image to use for the entity. Setting this will also set the language code to the preferred language code for the entity if "Add Language Code" is enabled, thus ensuring it is always selected for the given entity.</div>
</div>
<button is="emby-button" type="submit" name="settings" class="raised button-submit block emby-button">
<span>Save</span>
Expand Down
7 changes: 7 additions & 0 deletions Shokofin/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,13 @@ public void FixupConfiguration(PluginConfiguration config) {
config.AddImageLanguageCode = null;
changed = true;
}
if (config.RespectPreferredImage.HasValue) {
config.RespectPreferredImagePerStructureType = config.RespectPreferredImage.Value
? [SeriesStructureType.AniDB_Anime, SeriesStructureType.Shoko_Groups]
: [];
config.RespectPreferredImage = null;
changed = true;
}

if (changed)
SaveConfiguration(config);
Expand Down
14 changes: 9 additions & 5 deletions Shokofin/Providers/ImageProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, Cancell
var list = new List<RemoteImageInfo>();
var metadataLanguage = item.GetPreferredMetadataLanguage();
var baseKind = item.GetBaseItemKind();
var sortPreferred = Plugin.Instance.Configuration.RespectPreferredImage;
var trackerId = Plugin.Instance.Tracker.Add($"Providing images for {baseKind} \"{item.Name}\". (Path=\"{item.Path}\")");
try {
switch (item) {
case Episode episode: {
var (fileInfo, _, _) = await _apiManager.GetFileInfoByPath(episode.Path).ConfigureAwait(false);
if (fileInfo is not { EpisodeList.Count: > 0 })
var (fileInfo, seasonInfo, _) = await _apiManager.GetFileInfoByPath(episode.Path).ConfigureAwait(false);
if (fileInfo is not { EpisodeList.Count: > 0 } || seasonInfo is null)
break;

var episodeInfo = fileInfo.EpisodeList[0].Episode;
var sortPreferred = Plugin.Instance.Configuration.RespectPreferredImagePerStructureType.Contains(seasonInfo.StructureType);
if (await episodeInfo.GetImages(cancellationToken).ConfigureAwait(false) is { } episodeImages)
AddImagesForEpisode(ref list, episodeImages, metadataLanguage, sortPreferred);

Expand All @@ -46,6 +46,7 @@ public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, Cancell
if (_lookup.TryGetSeasonIdFor(series, out var seasonId)) {
if (await _apiManager.GetShowInfoBySeasonId(seasonId).ConfigureAwait(false) is { } showInfo) {
var images = await showInfo.GetImages(cancellationToken).ConfigureAwait(false);
var sortPreferred = Plugin.Instance.Configuration.RespectPreferredImagePerStructureType.Contains(showInfo.DefaultSeason.StructureType);
AddImagesForSeries(ref list, images, metadataLanguage, sortPreferred);
sortPreferred = false;

Expand All @@ -71,17 +72,19 @@ public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, Cancell
break;

var seriesImages = await seasonInfo.GetImages(cancellationToken).ConfigureAwait(false);
var sortPreferred = Plugin.Instance.Configuration.RespectPreferredImagePerStructureType.Contains(seasonInfo.StructureType);
AddImagesForSeries(ref list, seriesImages, metadataLanguage, sortPreferred);
_logger.LogInformation("Getting {Count} images for season {SeasonNumber} in {SeriesName} (Season={SeasonId},Language={MetadataLanguage})", list.Count, season.IndexNumber, season.SeriesName, seasonId, metadataLanguage);
}
break;
}
case Movie movie: {
var (fileInfo, _, _) = await _apiManager.GetFileInfoByPath(movie.Path).ConfigureAwait(false);
if (fileInfo is not { EpisodeList.Count: > 0 })
var (fileInfo, seasonInfo, _) = await _apiManager.GetFileInfoByPath(movie.Path).ConfigureAwait(false);
if (fileInfo is not { EpisodeList.Count: > 0 } || seasonInfo is null)
break;

var episodeInfo = fileInfo.EpisodeList[0].Episode;
var sortPreferred = Plugin.Instance.Configuration.RespectPreferredImagePerStructureType.Contains(seasonInfo.StructureType);
if (await episodeInfo.GetImages(cancellationToken).ConfigureAwait(false) is { } episodeImages)
AddImagesForSeries(ref list, episodeImages, metadataLanguage, sortPreferred, BaseItemKind.Movie);

Expand All @@ -97,6 +100,7 @@ await _apiManager.GetCollectionInfo(collectionId).ConfigureAwait(false) is { } c

if (!string.IsNullOrEmpty(seasonId) && await _apiManager.GetShowInfoBySeasonId(seasonId).ConfigureAwait(false) is { } showInfo) {
var showImages = await showInfo.GetImages(cancellationToken).ConfigureAwait(false);
var sortPreferred = Plugin.Instance.Configuration.RespectPreferredImagePerStructureType.Contains(showInfo.DefaultSeason.StructureType);
AddImagesForSeries(ref list, showImages, metadataLanguage, sortPreferred);
}

Expand Down

0 comments on commit 70eb8e2

Please sign in to comment.