Skip to content

Commit

Permalink
release(major): Version 5.0.0
Browse files Browse the repository at this point in the history
So apparently Jellyfin 10.10 was released. Didn't notice because there hasn't been an announcement in their discord server yet, but here we are.

 # Highlights

Here are some of the key features and improvements since the last stable release (4.2.2):

 ## Breaking Changes

- **Removed TvDB usage throughout the plugin, except for the TvDB IDs.** (1083a0c)

- **Dropped support for Shoko Server below version 5.0.0** (13fc638)

- **Enabled 'Attach VFS to Libraries' (_an advanced setting_) by default for new installs.** (dfdb115)

- **Removed the episode namespace migration scheduled task since the method we used to get all user data for a user is removed in 10.10**. Let this be your warning to migrate your user data **before** updating to 10.10 if needed. (a51d760)

 ## Bug Fixes

- Fixed the usage of user data for Jellyfin 10.10. (0361e83)

- Fixed the usage of `SetProviderId` for Jellyfin 10.10. (23c7575)

- Simplify multi resolver code now that Jellyfin 10.10 is out. (80d2758)

 ## Repository Changes

- Update to Jellyfin 10.10. (3dff389)

For the full list of changes, please check out the [complete changelog](v4.2.2...v5.0.0) here on GitHub.
  • Loading branch information
revam committed Oct 27, 2024
2 parents 4d9f055 + 3dff389 commit e7ac1ef
Show file tree
Hide file tree
Showing 20 changed files with 76 additions and 362 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ compatible with what.
| `2.x.x` | `10.8` | `4.1.2` |
| `3.x.x` | `10.8` | `4.2.0` |
| `4.0.0``4.1.1` | `10.9` | `4.2.2` |
| `4.2.0``4.x.x` | `10.9` | `4.2.2``5.0.0` |
| `dev` | `10.9` | `dev` |
| `4.2.0``4.2.2` | `10.9` | `4.2.2``5.0.0` |
| `5.x.x` | `10.10` | `5.0.0` |
| `dev` | `10.10` | `dev` |

### Official Repository

Expand Down
3 changes: 0 additions & 3 deletions Shokofin/API/Info/EpisodeInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ public class EpisodeInfo

public Episode.AniDB AniDB;

public Episode.TvDB? TvDB;

public EpisodeInfo(Episode episode)
{
Id = episode.IDs.Shoko.ToString();
ExtraType = Ordering.GetExtraType(episode.AniDBEntity);
Shoko = episode;
AniDB = episode.AniDBEntity;
TvDB = episode.TvDBEntityList?.FirstOrDefault();
}
}
3 changes: 0 additions & 3 deletions Shokofin/API/Info/SeasonInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ public class SeasonInfo

public readonly Series.AniDBWithDate AniDB;

public readonly Series.TvDB? TvDB;

public readonly SeriesType Type;

/// <summary>
Expand Down Expand Up @@ -254,7 +252,6 @@ public SeasonInfo(Series series, SeriesType? customType, IEnumerable<string> ext
ExtraIds = extraIds.ToArray();
Shoko = series;
AniDB = series.AniDBEntity;
TvDB = series.TvDBEntityList.FirstOrDefault();
Type = type;
EarliestImportedAt = earliestImportedAt;
LastImportedAt = lastImportedAt;
Expand Down
30 changes: 1 addition & 29 deletions Shokofin/API/Models/Episode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class Episode
{
/// <summary>
/// All identifiers related to the episode entry, e.g. the Shoko, AniDB,
/// TvDB, etc.
/// TMDB, etc.
/// </summary>
public EpisodeIDs IDs { get; set; } = new();

Expand Down Expand Up @@ -47,13 +47,6 @@ public class Episode
[JsonPropertyName("AniDB")]
public AniDB AniDBEntity { get; set; } = new();

/// <summary>
/// The <see cref="Episode.TvDB"/> entries, if <see cref="DataSource.TvDB"/>
/// is included in the data to add.
/// </summary>
[JsonPropertyName("TvDB")]
public List<TvDB> TvDBEntityList { get; set; } = [];

/// <summary>
/// File cross-references for the episode.
/// </summary>
Expand Down Expand Up @@ -83,32 +76,11 @@ public class AniDB
public Rating Rating { get; set; } = new();
}

public class TvDB
{
[JsonPropertyName("Season")]
public int SeasonNumber { get; set; }

[JsonPropertyName("Number")]
public int EpisodeNumber { get; set; }

public string Description { get; set; } = string.Empty;

public int? AirsAfterSeason { get; set; }

public int? AirsBeforeSeason { get; set; }

public int? AirsBeforeEpisode { get; set; }

public Image Thumbnail { get; set; } = new();
}

public class EpisodeIDs : IDs
{
public int ParentSeries { get; set; }

public int AniDB { get; set; }

public List<int> TvDB { get; set; } = [];
}
}

Expand Down
5 changes: 3 additions & 2 deletions Shokofin/API/Models/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Shokofin.API.Models;
public class Image
{
/// <summary>
/// AniDB, TvDB, TMDB, etc.
/// AniDB, TMDB, etc.
/// </summary>
public ImageSource Source { get; set; } = ImageSource.AniDB;

Expand Down Expand Up @@ -90,7 +90,8 @@ public enum ImageSource
AniDB = 1,

/// <summary>
///
/// Deprecated, but kept until the next major release for backwards compatibility.
/// TODO: REMOVE THIS IN 6.0
/// </summary>
TvDB = 2,

Expand Down
13 changes: 1 addition & 12 deletions Shokofin/API/Models/Series.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class Series

/// <summary>
/// All identifiers related to the series entry, e.g. the Shoko, AniDB,
/// TvDB, etc.
/// TMDB, etc.
/// </summary>
public SeriesIDs IDs { get; set; } = new();

Expand All @@ -45,12 +45,6 @@ public class Series
[JsonPropertyName("AniDB")]
public AniDBWithDate AniDBEntity { get; set; } = new();

/// <summary>
/// The TvDB entries, if any.
/// </summary>
[JsonPropertyName("TvDB")]
public List<TvDB> TvDBEntityList { get; set; }= [];

public SeriesSizes Sizes { get; set; } = new();

/// <summary>
Expand Down Expand Up @@ -191,11 +185,6 @@ public DateTime? EndDate
}
}

public class TvDB
{
public string Description { get; set; } = string.Empty;
}

public class SeriesIDs : IDs
{
public int ParentGroup { get; set; } = 0;
Expand Down
2 changes: 1 addition & 1 deletion Shokofin/API/Models/Title.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class Title
public bool IsDefault { get; set; }

/// <summary>
/// AniDB, TvDB, AniList, etc.
/// AniDB, TMDB, AniList, etc.
/// </summary>
public string Source { get; set; } = "Unknown";
}
Expand Down
81 changes: 16 additions & 65 deletions Shokofin/API/ShokoAPIClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,6 @@ public class ShokoAPIClient : IDisposable

private readonly ILogger<ShokoAPIClient> Logger;

private static ComponentVersion? ServerVersion =>
Plugin.Instance.Configuration.ServerVersion;

private static readonly DateTime EpisodeSeriesParentAddedDate = DateTime.Parse("2023-04-17T00:00:00.000Z");

private static bool UseEpisodeGetSeriesEndpoint =>
ServerVersion != null && ((ServerVersion.ReleaseChannel == ReleaseChannel.Stable && ServerVersion.Version == new Version("4.2.2.0")) || (ServerVersion.ReleaseDate.HasValue && ServerVersion.ReleaseDate.Value < EpisodeSeriesParentAddedDate));

private static readonly DateTime StableCutOffDate = DateTime.Parse("2023-12-16T00:00:00.000Z");

private static bool UseOlderSeriesAndFileEndpoints =>
ServerVersion != null && ((ServerVersion.ReleaseChannel == ReleaseChannel.Stable && ServerVersion.Version == new Version("4.2.2.0")) || (ServerVersion.ReleaseDate.HasValue && ServerVersion.ReleaseDate.Value < StableCutOffDate));

private static readonly DateTime ImportFolderCutOffDate = DateTime.Parse("2024-03-28T00:00:00.000Z");

private static bool UseOlderImportFolderFileEndpoints =>
ServerVersion != null && ((ServerVersion.ReleaseChannel == ReleaseChannel.Stable && ServerVersion.Version == new Version("4.2.2.0")) || (ServerVersion.ReleaseDate.HasValue && ServerVersion.ReleaseDate.Value < ImportFolderCutOffDate));

public static bool AllowEpisodeImages =>
ServerVersion is { } serverVersion && serverVersion.Version > new Version("4.2.2.0");

private readonly GuardedMemoryCache _cache;

public ShokoAPIClient(ILogger<ShokoAPIClient> logger)
Expand Down Expand Up @@ -270,9 +249,6 @@ public Task<HttpResponseMessage> GetImageAsync(ImageSource imageSource, ImageTyp

public Task<File> GetFile(string id)
{
if (UseOlderSeriesAndFileEndpoints)
return Get<File>($"/api/v3/File/{id}?includeXRefs=true&includeDataFrom=AniDB");

return Get<File>($"/api/v3/File/{id}?include=XRefs&includeDataFrom=AniDB");
}

Expand All @@ -288,19 +264,12 @@ public Task<List<File>> GetFileByPath(string path)

public async Task<IReadOnlyList<File>> GetFilesForSeries(string seriesId)
{
if (UseOlderSeriesAndFileEndpoints)
return await Get<List<File>>($"/api/v3/Series/{seriesId}/File?pageSize=0&includeXRefs=true&includeDataFrom=AniDB").ConfigureAwait(false);

var listResult = await Get<ListResult<File>>($"/api/v3/Series/{seriesId}/File?pageSize=0&include=XRefs&includeDataFrom=AniDB").ConfigureAwait(false);
return listResult.List;
}

public async Task<ListResult<File>> GetFilesForImportFolder(int importFolderId, string subPath, int page = 1)
{
if (UseOlderImportFolderFileEndpoints) {
return await Get<ListResult<File>>($"/api/v3/ImportFolder/{importFolderId}/File?page={page}&pageSize=100&includeXRefs=true").ConfigureAwait(false);
}

return await Get<ListResult<File>>($"/api/v3/ImportFolder/{importFolderId}/File?page={page}&folderPath={Uri.EscapeDataString(subPath)}&pageSize=1000&include=XRefs").ConfigureAwait(false);
}

Expand Down Expand Up @@ -347,42 +316,24 @@ public async Task<bool> ScrobbleFile(string fileId, string episodeId, string eve

public Task<Episode> GetEpisode(string id)
{
return Get<Episode>($"/api/v3/Episode/{id}?includeDataFrom=AniDB,TvDB&includeXRefs=true");
return Get<Episode>($"/api/v3/Episode/{id}?includeDataFrom=AniDB,TMDB&includeXRefs=true");
}

public async Task<EpisodeImages?> GetEpisodeImages(string id)
{
try {
if (AllowEpisodeImages) {
var episodeImages = await Get<EpisodeImages>($"/api/v3/Episode/{id}/Images");
// If the episode has no 'movie' images, get the series images to compensate.
if (episodeImages.Posters.Count is 0) {
var episode1 = await GetEpisode(id);
var seriesImages1 = await GetSeriesImages(episode1.IDs.ParentSeries.ToString()) ?? new();

episodeImages.Posters = seriesImages1.Posters;
episodeImages.Logos = seriesImages1.Logos;
episodeImages.Banners = seriesImages1.Banners;
episodeImages.Backdrops = seriesImages1.Backdrops;
}
return episodeImages;
}

var episode0 = await GetEpisode(id);
var seriesId0 = episode0.IDs.ParentSeries.ToString();
if (UseEpisodeGetSeriesEndpoint) {
var series = await GetSeriesFromEpisode(id);
if (series != null)
seriesId0 = series.IDs.Shoko.ToString();
var episodeImages = await Get<EpisodeImages>($"/api/v3/Episode/{id}/Images");
// If the episode has no 'movie' images, get the series images to compensate.
if (episodeImages.Posters.Count is 0) {
var episode1 = await GetEpisode(id);
var seriesImages1 = await GetSeriesImages(episode1.IDs.ParentSeries.ToString()) ?? new();

episodeImages.Posters = seriesImages1.Posters;
episodeImages.Logos = seriesImages1.Logos;
episodeImages.Banners = seriesImages1.Banners;
episodeImages.Backdrops = seriesImages1.Backdrops;
}
var seriesImages0 = seriesId0 is not "0" ? await GetSeriesImages(seriesId0) ?? new() : new();
return new() {
Banners = seriesImages0.Banners,
Backdrops = seriesImages0.Backdrops,
Posters = seriesImages0.Posters,
Logos = seriesImages0.Logos,
Thumbnails = episode0.TvDBEntityList.FirstOrDefault()?.Thumbnail is { } thumbnail ? [thumbnail] : [],
};
return episodeImages;
}
catch (ApiException e) when (e.StatusCode == HttpStatusCode.NotFound) {
return null;
Expand All @@ -391,22 +342,22 @@ public Task<Episode> GetEpisode(string id)

public Task<ListResult<Episode>> GetEpisodesFromSeries(string seriesId)
{
return Get<ListResult<Episode>>($"/api/v3/Series/{seriesId}/Episode?pageSize=0&includeHidden=true&includeMissing=true&includeDataFrom=AniDB,TvDB&includeXRefs=true");
return Get<ListResult<Episode>>($"/api/v3/Series/{seriesId}/Episode?pageSize=0&includeHidden=true&includeMissing=true&includeDataFrom=AniDB,TMDB&includeXRefs=true");
}

public Task<Series> GetSeries(string id)
{
return Get<Series>($"/api/v3/Series/{id}?includeDataFrom=AniDB,TvDB");
return Get<Series>($"/api/v3/Series/{id}?includeDataFrom=AniDB,TMDB");
}

public Task<Series> GetSeriesFromEpisode(string id)
{
return Get<Series>($"/api/v3/Episode/{id}/Series?includeDataFrom=AniDB,TvDB");
return Get<Series>($"/api/v3/Episode/{id}/Series?includeDataFrom=AniDB,TMDB");
}

public Task<List<Series>> GetSeriesInGroup(string groupID, int filterID = 0, bool recursive = false)
{
return Get<List<Series>>($"/api/v3/Filter/{filterID}/Group/{groupID}/Series?recursive={recursive}&includeMissing=true&includeIgnored=false&includeDataFrom=AniDB,TvDB");
return Get<List<Series>>($"/api/v3/Filter/{filterID}/Group/{groupID}/Series?recursive={recursive}&includeMissing=true&includeIgnored=false&includeDataFrom=AniDB,TMDB");
}

public Task<List<Role>> GetSeriesCast(string id)
Expand Down
3 changes: 1 addition & 2 deletions Shokofin/Configuration/PluginConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,6 @@ public PluginConfiguration()
DescriptionProvider.Shoko,
DescriptionProvider.AniDB,
DescriptionProvider.TMDB,
DescriptionProvider.TvDB,
];
HideUnverifiedTags = true;
TagSources = TagSource.ContentIndicators | TagSource.Dynamic | TagSource.DynamicCast | TagSource.DynamicEnding | TagSource.Elements |
Expand Down Expand Up @@ -603,7 +602,7 @@ public PluginConfiguration()
VFS_Threads = 4;
VFS_AddReleaseGroup = false;
VFS_AddResolution = false;
VFS_AttachRoot = false;
VFS_AttachRoot = true;
VFS_Location = VirtualRootLocation.Default;
VFS_CustomLocation = null;
VFS_ResolveLinks = false;
Expand Down
16 changes: 2 additions & 14 deletions Shokofin/Pages/Settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -320,18 +320,6 @@ <h3 class="listItemBodyText">TMDB | Follow metadata language in library</h3>
<span class="material-icons keyboard_arrow_up" aria-hidden="true"></span>
</button>
</div>
<div class="listItem sortableOption" data-option="TvDB">
<label class="listItemCheckboxContainer">
<input is="emby-checkbox" type="checkbox" data-option="TvDB">
<span></span>
</label>
<div class="listItemBody">
<h3 class="listItemBodyText">TvDB | Follow metadata language in library</h3>
</div>
<button type="button" is="paper-icon-button-light" title="Up" class="btnSortableMoveUp btnSortable">
<span class="material-icons keyboard_arrow_up" aria-hidden="true"></span>
</button>
</div>
</div>
<div class="fieldDescription">The metadata providers to use as the source of descriptions for entities, in priority order.</div>
</div>
Expand Down Expand Up @@ -1168,8 +1156,8 @@ <h3>Basic Settings</h3>
<select is="emby-select" id="SpecialsPlacement" name="SpecialsPlacement" class="emby-select-withcolor emby-select">
<option value="AfterSeason">Always place specials after the normal episodes (Default)</option>
<option value="InBetweenSeasonByAirDate">Use release dates to place specials</option>
<option value="InBetweenSeasonByOtherData">Loosely use the TvDB/TMDB data available in Shoko to place specials</option>
<option value="InBetweenSeasonMixed">Either loosely use the TvDB/TMDB data available in Shoko or fallback to using release dates to place specials</option>
<option value="InBetweenSeasonByOtherData">Loosely use the TMDB data available in Shoko to place specials</option>
<option value="InBetweenSeasonMixed">Either loosely use the TMDB data available in Shoko or fallback to using release dates to place specials</option>
<option value="Excluded">Exclude specials from the seasons</option>
</select>
<div class="fieldDescription selectFieldDescription">Determines how specials are placed within seasons. <strong>Warning:</strong> Modifying this setting requires a recreation (read as; delete existing then create a new) of any libraries using this plugin — otherwise you <strong>will</strong> have mixed metadata.</div>
Expand Down
14 changes: 14 additions & 0 deletions Shokofin/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Jellyfin.Extensions;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Plugins;
Expand Down Expand Up @@ -211,6 +212,19 @@ public Plugin(UsageTracker usageTracker, IServerConfigurationManager configurati
// Disable VFS if we can't create symbolic links on Windows and no configuration exists.
if (!configExists && !CanCreateSymbolicLinks) {
Configuration.VFS_Enabled = false;
// Remove TvDB from the list of description providers.
var index = Configuration.DescriptionSourceList.IndexOf(Text.DescriptionProvider.TvDB);
if (index != -1) {
var list = Configuration.DescriptionSourceList.ToList();
list.RemoveAt(index);
Configuration.DescriptionSourceList = [.. list];
}
index = Configuration.DescriptionSourceOrder.IndexOf(Text.DescriptionProvider.TvDB);
if (index != -1) {
var list = Configuration.DescriptionSourceOrder.ToList();
list.RemoveAt(index);
Configuration.DescriptionSourceOrder = [.. list];
}
SaveConfiguration();
}
}
Expand Down
2 changes: 1 addition & 1 deletion Shokofin/Providers/CustomBoxSetProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ private async Task<bool> EnsureGroupCollectionIsCorrect(Folder collectionRoot, B
private bool EnsureNoTmdbIdIsSet(BoxSet collection)
{
var willRemove = collection.HasProviderId(MetadataProvider.TmdbCollection);
collection.SetProviderId(MetadataProvider.TmdbCollection.ToString(), null);
collection.ProviderIds.Remove(MetadataProvider.TmdbCollection.ToString());
return willRemove;
}

Expand Down
Loading

0 comments on commit e7ac1ef

Please sign in to comment.