diff --git a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbEpisodeExternalId.cs b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbEpisodeExternalId.cs index 7f7f586..a19efa6 100644 --- a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbEpisodeExternalId.cs +++ b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbEpisodeExternalId.cs @@ -18,7 +18,7 @@ public class TvdbEpisodeExternalId : IExternalId public ExternalIdMediaType? Type => ExternalIdMediaType.Episode; /// - public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=episode&id={0}"; + public string? UrlFormatString => null; /// public bool Supports(IHasProviderIds item) => item is Episode; diff --git a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbMovieSlugExternalId.cs b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbMovieSlugExternalId.cs index 32e448c..f34fc7a 100644 --- a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbMovieSlugExternalId.cs +++ b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbMovieSlugExternalId.cs @@ -9,7 +9,7 @@ namespace Jellyfin.Plugin.Tvdb.Providers.ExternalId public class TvdbMovieSlugExternalId : IExternalId { /// - public string ProviderName => TvdbPlugin.ProviderName; + public string ProviderName => TvdbPlugin.ProviderName + " Slug"; /// public string Key => TvdbPlugin.SlugProviderId; @@ -18,7 +18,7 @@ public class TvdbMovieSlugExternalId : IExternalId public ExternalIdMediaType? Type => ExternalIdMediaType.Movie; /// - public string? UrlFormatString => TvdbUtils.TvdbBaseUrl + "movies/{0}"; + public string? UrlFormatString => null; /// public bool Supports(IHasProviderIds item) => item is Movie; diff --git a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbPersonExternalId.cs b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbPersonExternalId.cs index f737cd7..807d4ec 100644 --- a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbPersonExternalId.cs +++ b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbPersonExternalId.cs @@ -25,7 +25,7 @@ public class TvdbPersonExternalId : IExternalId public ExternalIdMediaType? Type => ExternalIdMediaType.Person; /// - public string? UrlFormatString => TvdbUtils.TvdbBaseUrl + "people/{0}"; + public string? UrlFormatString => null; /// public bool Supports(IHasProviderIds item) => item is Person; diff --git a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeasonExternalId.cs b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeasonExternalId.cs index 54317e3..16c6bdc 100644 --- a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeasonExternalId.cs +++ b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeasonExternalId.cs @@ -18,7 +18,7 @@ public class TvdbSeasonExternalId : IExternalId public ExternalIdMediaType? Type => ExternalIdMediaType.Season; /// - public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "dereferrer/season/{0}"; + public string? UrlFormatString => null; /// public bool Supports(IHasProviderIds item) => item is Season; diff --git a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbExternalId.cs b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeriesExternalId.cs similarity index 67% rename from Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbExternalId.cs rename to Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeriesExternalId.cs index 58ed5fc..869f4ae 100644 --- a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbExternalId.cs +++ b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeriesExternalId.cs @@ -6,19 +6,19 @@ namespace Jellyfin.Plugin.Tvdb.Providers.ExternalId { /// - public class TvdbExternalId : IExternalId + public class TvdbSeriesExternalId : IExternalId { /// - public string ProviderName => TvdbPlugin.ProviderName; + public string ProviderName => TvdbPlugin.ProviderName + " Numerical"; /// public string Key => TvdbPlugin.ProviderId; /// - public ExternalIdMediaType? Type => null; + public ExternalIdMediaType? Type => ExternalIdMediaType.Series; /// - public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=series&id={0}"; + public string? UrlFormatString => null; /// public bool Supports(IHasProviderIds item) => item is Series; diff --git a/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeriesSlugExternalId.cs b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeriesSlugExternalId.cs new file mode 100644 index 0000000..fe76d5b --- /dev/null +++ b/Jellyfin.Plugin.Tvdb/Providers/ExternalId/TvdbSeriesSlugExternalId.cs @@ -0,0 +1,26 @@ +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; + +namespace Jellyfin.Plugin.Tvdb.Providers.ExternalId +{ + /// + public class TvdbSeriesSlugExternalId : IExternalId + { + /// + public string ProviderName => TvdbPlugin.ProviderName + " Slug"; + + /// + public string Key => TvdbPlugin.SlugProviderId; + + /// + public ExternalIdMediaType? Type => ExternalIdMediaType.Series; + + /// + public string? UrlFormatString => null; + + /// + public bool Supports(IHasProviderIds item) => item is Series; + } +} diff --git a/Jellyfin.Plugin.Tvdb/Providers/TvdbExternalUrlProvider.cs b/Jellyfin.Plugin.Tvdb/Providers/TvdbExternalUrlProvider.cs new file mode 100644 index 0000000..d1510a8 --- /dev/null +++ b/Jellyfin.Plugin.Tvdb/Providers/TvdbExternalUrlProvider.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; + +namespace Jellyfin.Plugin.Tvdb.Providers +{ + /// + /// Provides external urls for TheTVDB. + /// + public class TvdbExternalUrlProvider : IExternalUrlProvider + { + private readonly FrozenSet _supportedOrders = new[] { "official", "regional", "alternate", "altdvd", "dvd", "absolute" }.ToFrozenSet(); + + /// + public string Name => TvdbPlugin.ProviderName; + + /// + public IEnumerable GetExternalUrls(BaseItem item) + { + var externalId = item.GetProviderId(TvdbPlugin.ProviderId); + var slugId = item.GetProviderId(TvdbPlugin.SlugProviderId); + + switch (item) + { + case Series: + if (string.IsNullOrEmpty(slugId) && !string.IsNullOrEmpty(externalId)) + { + yield return TvdbUtils.TvdbBaseUrl + $"?tab=series&id={externalId}"; + } + else if (!string.IsNullOrEmpty(slugId)) + { + yield return TvdbUtils.TvdbBaseUrl + $"series/{slugId}"; + } + + break; + case Season season: + season.Series.ProviderIds.TryGetValue(TvdbPlugin.SlugProviderId, out var seriesSlugId); + var displayOrder = season.Series.DisplayOrder; + if (string.IsNullOrEmpty(displayOrder)) + { + displayOrder = "official"; + } + + if (_supportedOrders.Contains(displayOrder) && !string.IsNullOrEmpty(seriesSlugId)) + { + yield return TvdbUtils.TvdbBaseUrl + $"series/{seriesSlugId}/seasons/{displayOrder}/{item.IndexNumber}"; + } + else if (string.Equals(displayOrder, "official", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(externalId)) + { + // This url format only works for official order + yield return TvdbUtils.TvdbBaseUrl + $"dereferrer/season/{externalId}"; + } + + break; + case Episode episode: + episode.Series.ProviderIds.TryGetValue(TvdbPlugin.SlugProviderId, out seriesSlugId); + if (!string.IsNullOrEmpty(seriesSlugId) && !string.IsNullOrEmpty(externalId)) + { + yield return TvdbUtils.TvdbBaseUrl + $"series/{seriesSlugId}/episodes/{externalId}"; + } + else if (!string.IsNullOrEmpty(externalId)) + { + yield return TvdbUtils.TvdbBaseUrl + $"?tab=episode&id={externalId}"; + } + + break; + case Movie: + if (!string.IsNullOrEmpty(slugId)) + { + yield return TvdbUtils.TvdbBaseUrl + $"movies/{slugId}"; + } + + break; + case Person: + if (!string.IsNullOrEmpty(externalId)) + { + yield return TvdbUtils.TvdbBaseUrl + $"people/{externalId}"; + } + + break; + } + } + } +} diff --git a/Jellyfin.Plugin.Tvdb/Providers/TvdbSeriesProvider.cs b/Jellyfin.Plugin.Tvdb/Providers/TvdbSeriesProvider.cs index 67e2f93..9be0aa5 100644 --- a/Jellyfin.Plugin.Tvdb/Providers/TvdbSeriesProvider.cs +++ b/Jellyfin.Plugin.Tvdb/Providers/TvdbSeriesProvider.cs @@ -436,9 +436,11 @@ private void MapSeriesToResult(MetadataResult result, SeriesExtendedReco result.ResultLanguage = info.MetadataLanguage; series.AirDays = TvdbUtils.GetAirDays(tvdbSeries.AirsDays).ToArray(); series.AirTime = tvdbSeries.AirsTime; - // series.CommunityRating = (float?)tvdbSeries.SiteRating; // Attempts to default to USA if not found series.OfficialRating = tvdbSeries.ContentRatings?.FirstOrDefault(x => string.Equals(x.Country, TvdbCultureInfo.GetCountryInfo(info.MetadataCountryCode)?.ThreeLetterISORegionName, StringComparison.OrdinalIgnoreCase))?.Name ?? tvdbSeries.ContentRatings?.FirstOrDefault(x => string.Equals(x.Country, "usa", StringComparison.OrdinalIgnoreCase))?.Name; + + series.SetProviderIdIfHasValue(TvdbPlugin.SlugProviderId, tvdbSeries.Slug); + if (tvdbSeries.Lists is not null && tvdbSeries.Lists is JsonElement jsonElement) { var collections = jsonElement.Deserialize>();