aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Providers/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Providers/Plugins')
-rw-r--r--MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs23
-rw-r--r--MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs36
-rw-r--r--MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs18
-rw-r--r--MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs44
-rw-r--r--MediaBrowser.Providers/Plugins/AudioDb/Configuration/config.html5
-rw-r--r--MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs13
-rw-r--r--MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html15
-rw-r--r--MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs83
-rw-r--r--MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs47
-rw-r--r--MediaBrowser.Providers/Plugins/Omdb/Configuration/config.html9
-rw-r--r--MediaBrowser.Providers/Plugins/Omdb/JsonOmdbNotAvailableInt32Converter.cs2
-rw-r--r--MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs5
-rw-r--r--MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs38
-rw-r--r--MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs63
-rw-r--r--MediaBrowser.Providers/Plugins/StudioImages/Configuration/PluginConfiguration.cs10
-rw-r--r--MediaBrowser.Providers/Plugins/StudioImages/Configuration/config.html3
-rw-r--r--MediaBrowser.Providers/Plugins/StudioImages/Plugin.cs21
-rw-r--r--MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs47
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/Api/TmdbController.cs4
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetExternalId.cs2
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs26
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs29
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/Configuration/config.html3
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieExternalId.cs2
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs30
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs106
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonExternalId.cs2
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonImageProvider.cs28
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs28
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs44
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs37
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs47
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs25
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesExternalId.cs2
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs27
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs65
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs122
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs48
38 files changed, 706 insertions, 453 deletions
diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs
index ad0247fb2..7f73afc53 100644
--- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading;
@@ -42,11 +43,8 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
/// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
- return new List<ImageType>
- {
- ImageType.Primary,
- ImageType.Disc
- };
+ yield return ImageType.Primary;
+ yield return ImageType.Disc;
}
/// <inheritdoc />
@@ -60,16 +58,19 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
var path = AudioDbAlbumProvider.GetAlbumInfoPath(_config.ApplicationPaths, id);
- await using FileStream jsonStream = AsyncFile.OpenRead(path);
- var obj = await JsonSerializer.DeserializeAsync<AudioDbAlbumProvider.RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
-
- if (obj != null && obj.album != null && obj.album.Count > 0)
+ FileStream jsonStream = AsyncFile.OpenRead(path);
+ await using (jsonStream.ConfigureAwait(false))
{
- return GetImages(obj.album[0]);
+ var obj = await JsonSerializer.DeserializeAsync<AudioDbAlbumProvider.RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+
+ if (obj is not null && obj.album is not null && obj.album.Count > 0)
+ {
+ return GetImages(obj.album[0]);
+ }
}
}
- return new List<RemoteImageInfo>();
+ return Enumerable.Empty<RemoteImageInfo>();
}
private IEnumerable<RemoteImageInfo> GetImages(AudioDbAlbumProvider.Album item)
diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs
index 43f30824b..55e2474a5 100644
--- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs
+++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs
@@ -68,14 +68,17 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
var path = GetAlbumInfoPath(_config.ApplicationPaths, id);
- await using FileStream jsonStream = AsyncFile.OpenRead(path);
- var obj = await JsonSerializer.DeserializeAsync<RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
-
- if (obj != null && obj.album != null && obj.album.Count > 0)
+ FileStream jsonStream = AsyncFile.OpenRead(path);
+ await using (jsonStream.ConfigureAwait(false))
{
- result.Item = new MusicAlbum();
- result.HasMetadata = true;
- ProcessResult(result.Item, obj.album[0], info.MetadataLanguage);
+ var obj = await JsonSerializer.DeserializeAsync<RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+
+ if (obj is not null && obj.album is not null && obj.album.Count > 0)
+ {
+ result.Item = new MusicAlbum();
+ result.HasMetadata = true;
+ ProcessResult(result.Item, obj.album[0], info.MetadataLanguage);
+ }
}
}
@@ -173,13 +176,18 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
Directory.CreateDirectory(Path.GetDirectoryName(path));
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-
- var fileStreamOptions = AsyncFile.WriteOptions;
- fileStreamOptions.Mode = FileMode.Create;
- fileStreamOptions.PreallocationSize = stream.Length;
- await using var xmlFileStream = new FileStream(path, fileStreamOptions);
- await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false);
+ var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
+ await using (stream.ConfigureAwait(false))
+ {
+ var fileStreamOptions = AsyncFile.WriteOptions;
+ fileStreamOptions.Mode = FileMode.Create;
+ fileStreamOptions.PreallocationSize = stream.Length;
+ var xmlFileStream = new FileStream(path, fileStreamOptions);
+ await using (xmlFileStream.ConfigureAwait(false))
+ {
+ await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false);
+ }
+ }
}
private static string GetAlbumDataPath(IApplicationPaths appPaths, string musicBrainzReleaseGroupId)
diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs
index 9c2447660..2232dfa0d 100644
--- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading;
@@ -42,7 +43,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
/// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
- return new List<ImageType>
+ return new ImageType[]
{
ImageType.Primary,
ImageType.Logo,
@@ -62,16 +63,19 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
var path = AudioDbArtistProvider.GetArtistInfoPath(_config.ApplicationPaths, id);
- await using FileStream jsonStream = AsyncFile.OpenRead(path);
- var obj = await JsonSerializer.DeserializeAsync<AudioDbArtistProvider.RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
-
- if (obj != null && obj.artists != null && obj.artists.Count > 0)
+ FileStream jsonStream = AsyncFile.OpenRead(path);
+ await using (jsonStream.ConfigureAwait(false))
{
- return GetImages(obj.artists[0]);
+ var obj = await JsonSerializer.DeserializeAsync<AudioDbArtistProvider.RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+
+ if (obj is not null && obj.artists is not null && obj.artists.Count > 0)
+ {
+ return GetImages(obj.artists[0]);
+ }
}
}
- return new List<RemoteImageInfo>();
+ return Enumerable.Empty<RemoteImageInfo>();
}
private IEnumerable<RemoteImageInfo> GetImages(AudioDbArtistProvider.Artist item)
diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs
index 538dc67c4..f3385b3a9 100644
--- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs
+++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs
@@ -67,14 +67,17 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
var path = GetArtistInfoPath(_config.ApplicationPaths, id);
- await using FileStream jsonStream = AsyncFile.OpenRead(path);
- var obj = await JsonSerializer.DeserializeAsync<RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
-
- if (obj != null && obj.artists != null && obj.artists.Count > 0)
+ FileStream jsonStream = AsyncFile.OpenRead(path);
+ await using (jsonStream.ConfigureAwait(false))
{
- result.Item = new MusicArtist();
- result.HasMetadata = true;
- ProcessResult(result.Item, obj.artists[0], info.MetadataLanguage);
+ var obj = await JsonSerializer.DeserializeAsync<RootObject>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+
+ if (obj is not null && obj.artists is not null && obj.artists.Count > 0)
+ {
+ result.Item = new MusicArtist();
+ result.HasMetadata = true;
+ ProcessResult(result.Item, obj.artists[0], info.MetadataLanguage);
+ }
}
}
@@ -149,18 +152,23 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
var url = BaseUrl + "/artist-mb.php?i=" + musicBrainzId;
- var path = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId);
-
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-
- Directory.CreateDirectory(Path.GetDirectoryName(path));
-
- var fileStreamOptions = AsyncFile.WriteOptions;
- fileStreamOptions.Mode = FileMode.Create;
- fileStreamOptions.PreallocationSize = stream.Length;
- await using var xmlFileStream = new FileStream(path, fileStreamOptions);
- await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false);
+ response.EnsureSuccessStatusCode();
+ var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
+ await using (stream.ConfigureAwait(false))
+ {
+ var path = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId);
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
+
+ var fileStreamOptions = AsyncFile.WriteOptions;
+ fileStreamOptions.Mode = FileMode.Create;
+ fileStreamOptions.PreallocationSize = stream.Length;
+ var xmlFileStream = new FileStream(path, fileStreamOptions);
+ await using (xmlFileStream.ConfigureAwait(false))
+ {
+ await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false);
+ }
+ }
}
/// <summary>
diff --git a/MediaBrowser.Providers/Plugins/AudioDb/Configuration/config.html b/MediaBrowser.Providers/Plugins/AudioDb/Configuration/config.html
index eab252005..2093effca 100644
--- a/MediaBrowser.Providers/Plugins/AudioDb/Configuration/config.html
+++ b/MediaBrowser.Providers/Plugins/AudioDb/Configuration/config.html
@@ -1,12 +1,13 @@
<!DOCTYPE html>
<html>
<head>
- <title>AudioDB</title>
+ <title>TheAudioDB</title>
</head>
<body>
- <div data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
+ <div id="configPage" data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
<div data-role="content">
<div class="content-primary">
+ <h1>TheAudioDB</h1>
<form class="configForm">
<label class="checkboxContainer">
<input is="emby-checkbox" type="checkbox" id="replaceAlbumName" />
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs
index 22229e377..21a15c58c 100644
--- a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs
+++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Model.Plugins;
-using MetaBrainz.MusicBrainz;
namespace MediaBrowser.Providers.Plugins.MusicBrainz.Configuration;
@@ -8,16 +7,22 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz.Configuration;
/// </summary>
public class PluginConfiguration : BasePluginConfiguration
{
- private const string DefaultServer = "musicbrainz.org";
+ /// <summary>
+ /// The default server URL.
+ /// </summary>
+ public const string DefaultServer = "https://musicbrainz.org";
- private const double DefaultRateLimit = 1.0;
+ /// <summary>
+ /// The default rate limit.
+ /// </summary>
+ public const double DefaultRateLimit = 1.0;
private string _server = DefaultServer;
private double _rateLimit = DefaultRateLimit;
/// <summary>
- /// Gets or sets the server url.
+ /// Gets or sets the server URL.
/// </summary>
public string Server
{
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html
index 6f1296bb7..24f2ac0ca 100644
--- a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html
+++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html
@@ -4,17 +4,18 @@
<title>MusicBrainz</title>
</head>
<body>
- <div data-role="page" class="page type-interior pluginConfigurationPage musicBrainzConfigPage" data-require="emby-input,emby-button,emby-checkbox">
+ <div id="configPage" data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
<div data-role="content">
<div class="content-primary">
- <form class="musicBrainzConfigForm">
+ <h1>MusicBrainz</h1>
+ <form class="configForm">
<div class="inputContainer">
<input is="emby-input" type="text" id="server" required label="Server" />
<div class="fieldDescription">This can be a mirror of the official server or even a custom server.</div>
</div>
<div class="inputContainer">
- <input is="emby-input" type="number" id="rateLimit" pattern="[0-9]*" required min="0" max="10000" label="Rate Limit" />
- <div class="fieldDescription">Span of time between requests in milliseconds. The official server is limited to one request every two seconds.</div>
+ <input is="emby-input" type="number" id="rateLimit" required pattern="[0-9]*" min="0" max="10" step=".01" label="Rate Limit" />
+ <div class="fieldDescription">Span of time between requests in seconds. The official server is limited to one request every seconds.</div>
</div>
<label class="checkboxContainer">
<input is="emby-checkbox" type="checkbox" id="replaceArtistName" />
@@ -32,7 +33,7 @@
uniquePluginId: "8c95c4d2-e50c-4fb0-a4f3-6c06ff0f9a1a"
};
- document.querySelector('.musicBrainzConfigPage')
+ document.querySelector('.configPage')
.addEventListener('pageshow', function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(MusicBrainzPluginConfig.uniquePluginId).then(function (config) {
@@ -49,14 +50,14 @@
bubbles: true,
cancelable: false
}));
-
+
document.querySelector('#replaceArtistName').checked = config.ReplaceArtistName;
Dashboard.hideLoadingMsg();
});
});
- document.querySelector('.musicBrainzConfigForm')
+ document.querySelector('.configForm')
.addEventListener('submit', function (e) {
Dashboard.showLoadingMsg();
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs
index 4d9feca6d..d0bd7d609 100644
--- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs
+++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs
@@ -8,11 +8,14 @@ using Jellyfin.Extensions;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Plugins;
using MediaBrowser.Model.Providers;
using MediaBrowser.Providers.Music;
+using MediaBrowser.Providers.Plugins.MusicBrainz.Configuration;
using MetaBrainz.MusicBrainz;
using MetaBrainz.MusicBrainz.Interfaces.Entities;
using MetaBrainz.MusicBrainz.Interfaces.Searches;
+using Microsoft.Extensions.Logging;
namespace MediaBrowser.Providers.Plugins.MusicBrainz;
@@ -21,20 +24,19 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz;
/// </summary>
public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, AlbumInfo>, IHasOrder, IDisposable
{
- private readonly Query _musicBrainzQuery;
+ private readonly ILogger<MusicBrainzAlbumProvider> _logger;
+ private Query _musicBrainzQuery;
/// <summary>
/// Initializes a new instance of the <see cref="MusicBrainzAlbumProvider"/> class.
/// </summary>
- public MusicBrainzAlbumProvider()
+ /// <param name="logger">The logger.</param>
+ public MusicBrainzAlbumProvider(ILogger<MusicBrainzAlbumProvider> logger)
{
- MusicBrainz.Plugin.Instance!.ConfigurationChanged += (_, _) =>
- {
- Query.DefaultServer = MusicBrainz.Plugin.Instance.Configuration.Server;
- Query.DelayBetweenRequests = MusicBrainz.Plugin.Instance.Configuration.RateLimit;
- };
-
+ _logger = logger;
_musicBrainzQuery = new Query();
+ ReloadConfig(null, MusicBrainz.Plugin.Instance!.Configuration);
+ MusicBrainz.Plugin.Instance!.ConfigurationChanged += ReloadConfig;
}
/// <inheritdoc />
@@ -43,6 +45,29 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, Albu
/// <inheritdoc />
public int Order => 0;
+ private void ReloadConfig(object? sender, BasePluginConfiguration e)
+ {
+ var configuration = (PluginConfiguration)e;
+ if (Uri.TryCreate(configuration.Server, UriKind.Absolute, out var server))
+ {
+ Query.DefaultServer = server.DnsSafeHost;
+ Query.DefaultPort = server.Port;
+ Query.DefaultUrlScheme = server.Scheme;
+ }
+ else
+ {
+ // Fallback to official server
+ _logger.LogWarning("Invalid MusicBrainz server specified, falling back to official server");
+ var defaultServer = new Uri(PluginConfiguration.DefaultServer);
+ Query.DefaultServer = defaultServer.Host;
+ Query.DefaultPort = defaultServer.Port;
+ Query.DefaultUrlScheme = defaultServer.Scheme;
+ }
+
+ Query.DelayBetweenRequests = configuration.RateLimit;
+ _musicBrainzQuery = new Query();
+ }
+
/// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(AlbumInfo searchInfo, CancellationToken cancellationToken)
{
@@ -51,13 +76,13 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, Albu
if (!string.IsNullOrEmpty(releaseId))
{
- var releaseResult = await _musicBrainzQuery.LookupReleaseAsync(new Guid(releaseId), Include.ReleaseGroups, cancellationToken).ConfigureAwait(false);
+ var releaseResult = await _musicBrainzQuery.LookupReleaseAsync(new Guid(releaseId), Include.Artists | Include.ReleaseGroups, cancellationToken).ConfigureAwait(false);
return GetReleaseResult(releaseResult).SingleItemAsEnumerable();
}
if (!string.IsNullOrEmpty(releaseGroupId))
{
- var releaseGroupResult = await _musicBrainzQuery.LookupReleaseGroupAsync(new Guid(releaseGroupId), Include.None, null, cancellationToken).ConfigureAwait(false);
+ var releaseGroupResult = await _musicBrainzQuery.LookupReleaseGroupAsync(new Guid(releaseGroupId), Include.Releases, null, cancellationToken).ConfigureAwait(false);
return GetReleaseGroupResult(releaseGroupResult.Releases);
}
@@ -112,7 +137,9 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, Albu
foreach (var result in releaseSearchResults)
{
- yield return GetReleaseResult(result);
+ // Fetch full release info, otherwise artists are missing
+ var fullResult = _musicBrainzQuery.LookupRelease(result.Id, Include.Artists | Include.ReleaseGroups);
+ yield return GetReleaseResult(fullResult);
}
}
@@ -122,21 +149,33 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, Albu
{
Name = releaseSearchResult.Title,
ProductionYear = releaseSearchResult.Date?.Year,
- PremiereDate = releaseSearchResult.Date?.NearestDate
+ PremiereDate = releaseSearchResult.Date?.NearestDate,
+ SearchProviderName = Name
};
- if (releaseSearchResult.ArtistCredit?.Count > 0)
+ // Add artists and use first as album artist
+ var artists = releaseSearchResult.ArtistCredit;
+ if (artists is not null && artists.Count > 0)
{
- searchResult.AlbumArtist = new RemoteSearchResult
+ var artistResults = new RemoteSearchResult[artists.Count];
+ for (int i = 0; i < artists.Count; i++)
{
- SearchProviderName = Name,
- Name = releaseSearchResult.ArtistCredit[0].Name
- };
+ var artist = artists[i];
+ var artistResult = new RemoteSearchResult
+ {
+ Name = artist.Name
+ };
- if (releaseSearchResult.ArtistCredit[0].Artist?.Id is not null)
- {
- searchResult.AlbumArtist.SetProviderId(MetadataProvider.MusicBrainzArtist, releaseSearchResult.ArtistCredit[0].Artist!.Id.ToString());
+ if (artist.Artist?.Id is not null)
+ {
+ artistResult.SetProviderId(MetadataProvider.MusicBrainzArtist, artist.Artist!.Id.ToString());
+ }
+
+ artistResults[i] = artistResult;
}
+
+ searchResult.AlbumArtist = artistResults[0];
+ searchResult.Artists = artistResults;
}
searchResult.SetProviderId(MetadataProvider.MusicBrainzAlbum, releaseSearchResult.Id.ToString());
@@ -167,7 +206,7 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, Albu
// TODO: Actually try to match the release. Simply taking the first result is stupid.
var releaseGroup = await _musicBrainzQuery.LookupReleaseGroupAsync(new Guid(releaseGroupId), Include.None, null, cancellationToken).ConfigureAwait(false);
var release = releaseGroup.Releases?.Count > 0 ? releaseGroup.Releases[0] : null;
- if (release != null)
+ if (release is not null)
{
releaseId = release.Id.ToString();
result.HasMetadata = true;
@@ -193,7 +232,7 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, Albu
releaseResult = releaseSearchResults.Results.Count > 0 ? releaseSearchResults.Results[0].Item : null;
}
- if (releaseResult != null)
+ if (releaseResult is not null)
{
releaseId = releaseResult.Id.ToString();
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs
index 2cc3a13be..1323d2604 100644
--- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs
+++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs
@@ -4,16 +4,18 @@ using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
-using System.Xml;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Plugins;
using MediaBrowser.Model.Providers;
using MediaBrowser.Providers.Music;
+using MediaBrowser.Providers.Plugins.MusicBrainz.Configuration;
using MetaBrainz.MusicBrainz;
using MetaBrainz.MusicBrainz.Interfaces.Entities;
using MetaBrainz.MusicBrainz.Interfaces.Searches;
+using Microsoft.Extensions.Logging;
namespace MediaBrowser.Providers.Plugins.MusicBrainz;
@@ -22,25 +24,47 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz;
/// </summary>
public class MusicBrainzArtistProvider : IRemoteMetadataProvider<MusicArtist, ArtistInfo>, IDisposable
{
- private readonly Query _musicBrainzQuery;
+ private readonly ILogger<MusicBrainzArtistProvider> _logger;
+ private Query _musicBrainzQuery;
/// <summary>
/// Initializes a new instance of the <see cref="MusicBrainzArtistProvider"/> class.
/// </summary>
- public MusicBrainzArtistProvider()
+ /// <param name="logger">The logger.</param>
+ public MusicBrainzArtistProvider(ILogger<MusicBrainzArtistProvider> logger)
{
- MusicBrainz.Plugin.Instance!.ConfigurationChanged += (_, _) =>
- {
- Query.DefaultServer = MusicBrainz.Plugin.Instance.Configuration.Server;
- Query.DelayBetweenRequests = MusicBrainz.Plugin.Instance.Configuration.RateLimit;
- };
-
+ _logger = logger;
_musicBrainzQuery = new Query();
+ ReloadConfig(null, MusicBrainz.Plugin.Instance!.Configuration);
+ MusicBrainz.Plugin.Instance!.ConfigurationChanged += ReloadConfig;
}
/// <inheritdoc />
public string Name => "MusicBrainz";
+ private void ReloadConfig(object? sender, BasePluginConfiguration e)
+ {
+ var configuration = (PluginConfiguration)e;
+ if (Uri.TryCreate(configuration.Server, UriKind.Absolute, out var server))
+ {
+ Query.DefaultServer = server.DnsSafeHost;
+ Query.DefaultPort = server.Port;
+ Query.DefaultUrlScheme = server.Scheme;
+ }
+ else
+ {
+ // Fallback to official server
+ _logger.LogWarning("Invalid MusicBrainz server specified, falling back to official server");
+ var defaultServer = new Uri(PluginConfiguration.DefaultServer);
+ Query.DefaultServer = defaultServer.Host;
+ Query.DefaultPort = defaultServer.Port;
+ Query.DefaultUrlScheme = defaultServer.Scheme;
+ }
+
+ Query.DelayBetweenRequests = configuration.RateLimit;
+ _musicBrainzQuery = new Query();
+ }
+
/// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ArtistInfo searchInfo, CancellationToken cancellationToken)
{
@@ -92,7 +116,8 @@ public class MusicBrainzArtistProvider : IRemoteMetadataProvider<MusicArtist, Ar
{
Name = artist.Name,
ProductionYear = artist.LifeSpan?.Begin?.Year,
- PremiereDate = artist.LifeSpan?.Begin?.NearestDate
+ PremiereDate = artist.LifeSpan?.Begin?.NearestDate,
+ SearchProviderName = Name,
};
searchResult.SetProviderId(MetadataProvider.MusicBrainzArtist, artist.Id.ToString());
@@ -113,7 +138,7 @@ public class MusicBrainzArtistProvider : IRemoteMetadataProvider<MusicArtist, Ar
var singleResult = searchResults.FirstOrDefault();
- if (singleResult != null)
+ if (singleResult is not null)
{
musicBrainzId = singleResult.GetProviderId(MetadataProvider.MusicBrainzArtist);
result.Item.Overview = singleResult.Overview;
diff --git a/MediaBrowser.Providers/Plugins/Omdb/Configuration/config.html b/MediaBrowser.Providers/Plugins/Omdb/Configuration/config.html
index f4375b3cb..d00c1f9f8 100644
--- a/MediaBrowser.Providers/Plugins/Omdb/Configuration/config.html
+++ b/MediaBrowser.Providers/Plugins/Omdb/Configuration/config.html
@@ -4,9 +4,10 @@
<title>OMDb</title>
</head>
<body>
- <div data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
+ <div id="configPage" data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
<div data-role="content">
<div class="content-primary">
+ <h1>OMDb</h1>
<form class="configForm">
<label class="checkboxContainer">
<input is="emby-checkbox" type="checkbox" id="castAndCrew" />
@@ -33,16 +34,16 @@
});
});
-
+
document.querySelector('.configForm')
.addEventListener('submit', function (e) {
Dashboard.showLoadingMsg();
-
+
ApiClient.getPluginConfiguration(PluginConfig.pluginId).then(function (config) {
config.CastAndCrew = document.querySelector('#castAndCrew').checked;
ApiClient.updatePluginConfiguration(PluginConfig.pluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
});
-
+
e.preventDefault();
return false;
});
diff --git a/MediaBrowser.Providers/Plugins/Omdb/JsonOmdbNotAvailableInt32Converter.cs b/MediaBrowser.Providers/Plugins/Omdb/JsonOmdbNotAvailableInt32Converter.cs
index 8bfdc461e..38379ae5d 100644
--- a/MediaBrowser.Providers/Plugins/Omdb/JsonOmdbNotAvailableInt32Converter.cs
+++ b/MediaBrowser.Providers/Plugins/Omdb/JsonOmdbNotAvailableInt32Converter.cs
@@ -16,7 +16,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
if (reader.TokenType == JsonTokenType.String)
{
var str = reader.GetString();
- if (str == null || str.Equals("N/A", StringComparison.OrdinalIgnoreCase))
+ if (str is null || str.Equals("N/A", StringComparison.OrdinalIgnoreCase))
{
return null;
}
diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs
index 60b373483..140a64f52 100644
--- a/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs
@@ -38,10 +38,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
- return new List<ImageType>
- {
- ImageType.Primary
- };
+ yield return ImageType.Primary;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs
index e5753b2b5..e4bb4eaea 100644
--- a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs
@@ -90,7 +90,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var imdbId = searchInfo.GetProviderId(MetadataProvider.Imdb);
var urlQuery = new StringBuilder("plot=full&r=json");
- if (episodeSearchInfo != null)
+ if (episodeSearchInfo is not null)
{
episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out imdbId);
if (searchInfo.IndexNumber.HasValue)
@@ -137,29 +137,31 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var url = OmdbProvider.GetOmdbUrl(urlQuery.ToString());
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
-
- if (isSearch)
+ var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
+ await using (stream.ConfigureAwait(false))
{
- var searchResultList = await JsonSerializer.DeserializeAsync<SearchResultList>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
- if (searchResultList?.Search != null)
+ if (isSearch)
{
- var resultCount = searchResultList.Search.Count;
- var result = new RemoteSearchResult[resultCount];
- for (var i = 0; i < resultCount; i++)
+ var searchResultList = await JsonSerializer.DeserializeAsync<SearchResultList>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ if (searchResultList?.Search is not null)
{
- result[i] = ResultToMetadataResult(searchResultList.Search[i], searchInfo, indexNumberEnd);
+ var resultCount = searchResultList.Search.Count;
+ var result = new RemoteSearchResult[resultCount];
+ for (var i = 0; i < resultCount; i++)
+ {
+ result[i] = ResultToMetadataResult(searchResultList.Search[i], searchInfo, indexNumberEnd);
+ }
+
+ return result;
}
-
- return result;
}
- }
- else
- {
- var result = await JsonSerializer.DeserializeAsync<SearchResult>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
- if (string.Equals(result?.Response, "true", StringComparison.OrdinalIgnoreCase))
+ else
{
- return new[] { ResultToMetadataResult(result, searchInfo, indexNumberEnd) };
+ var result = await JsonSerializer.DeserializeAsync<SearchResult>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ if (string.Equals(result?.Response, "true", StringComparison.OrdinalIgnoreCase))
+ {
+ return new[] { ResultToMetadataResult(result, searchInfo, indexNumberEnd) };
+ }
}
}
diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
index 10077e5c8..3fd4ae1fc 100644
--- a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
@@ -13,6 +13,7 @@ using System.Net.Http.Json;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using Jellyfin.Extensions.Json;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
@@ -98,8 +99,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
// item.VoteCount = voteCount;
}
- if (!string.IsNullOrEmpty(result.imdbRating)
- && float.TryParse(result.imdbRating, NumberStyles.Any, CultureInfo.InvariantCulture, out var imdbRating)
+ if (float.TryParse(result.imdbRating, CultureInfo.InvariantCulture, out var imdbRating)
&& imdbRating >= 0)
{
item.CommunityRating = imdbRating;
@@ -141,7 +141,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var seasonResult = await GetSeasonRootObject(seriesImdbId, seasonNumber, cancellationToken).ConfigureAwait(false);
- if (seasonResult?.Episodes == null)
+ if (seasonResult?.Episodes is null)
{
return false;
}
@@ -161,7 +161,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
}
// finally, search by numbers
- if (result == null)
+ if (result is null)
{
foreach (var episode in seasonResult.Episodes)
{
@@ -173,7 +173,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
}
}
- if (result == null)
+ if (result is null)
{
return false;
}
@@ -209,8 +209,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
// item.VoteCount = voteCount;
}
- if (!string.IsNullOrEmpty(result.imdbRating)
- && float.TryParse(result.imdbRating, NumberStyles.Any, CultureInfo.InvariantCulture, out var imdbRating)
+ if (float.TryParse(result.imdbRating, CultureInfo.InvariantCulture, out var imdbRating)
&& imdbRating >= 0)
{
item.CommunityRating = imdbRating;
@@ -234,15 +233,21 @@ namespace MediaBrowser.Providers.Plugins.Omdb
internal async Task<RootObject> GetRootObject(string imdbId, CancellationToken cancellationToken)
{
var path = await EnsureItemInfo(imdbId, cancellationToken).ConfigureAwait(false);
- await using var stream = AsyncFile.OpenRead(path);
- return await JsonSerializer.DeserializeAsync<RootObject>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ var stream = AsyncFile.OpenRead(path);
+ await using (stream.ConfigureAwait(false))
+ {
+ return await JsonSerializer.DeserializeAsync<RootObject>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ }
}
internal async Task<SeasonRootObject> GetSeasonRootObject(string imdbId, int seasonId, CancellationToken cancellationToken)
{
var path = await EnsureSeasonInfo(imdbId, seasonId, cancellationToken).ConfigureAwait(false);
- await using var stream = AsyncFile.OpenRead(path);
- return await JsonSerializer.DeserializeAsync<SeasonRootObject>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ var stream = AsyncFile.OpenRead(path);
+ await using (stream.ConfigureAwait(false))
+ {
+ return await JsonSerializer.DeserializeAsync<SeasonRootObject>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ }
}
/// <summary>Gets OMDB URL.</summary>
@@ -317,8 +322,11 @@ namespace MediaBrowser.Providers.Plugins.Omdb
imdbParam));
var rootObject = await _httpClientFactory.CreateClient(NamedClient.Default).GetFromJsonAsync<RootObject>(url, _jsonOptions, cancellationToken).ConfigureAwait(false);
- await using FileStream jsonFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
- await JsonSerializer.SerializeAsync(jsonFileStream, rootObject, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ FileStream jsonFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
+ await using (jsonFileStream.ConfigureAwait(false))
+ {
+ await JsonSerializer.SerializeAsync(jsonFileStream, rootObject, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ }
return path;
}
@@ -357,18 +365,18 @@ namespace MediaBrowser.Providers.Plugins.Omdb
seasonId));
var rootObject = await _httpClientFactory.CreateClient(NamedClient.Default).GetFromJsonAsync<SeasonRootObject>(url, _jsonOptions, cancellationToken).ConfigureAwait(false);
- await using FileStream jsonFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
- await JsonSerializer.SerializeAsync(jsonFileStream, rootObject, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ FileStream jsonFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
+ await using (jsonFileStream.ConfigureAwait(false))
+ {
+ await JsonSerializer.SerializeAsync(jsonFileStream, rootObject, _jsonOptions, cancellationToken).ConfigureAwait(false);
+ }
return path;
}
internal string GetDataFilePath(string imdbId)
{
- if (string.IsNullOrEmpty(imdbId))
- {
- throw new ArgumentNullException(nameof(imdbId));
- }
+ ArgumentException.ThrowIfNullOrEmpty(imdbId);
var dataPath = Path.Combine(_configurationManager.ApplicationPaths.CachePath, "omdb");
@@ -379,10 +387,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
internal string GetSeasonFilePath(string imdbId, int seasonId)
{
- if (string.IsNullOrEmpty(imdbId))
- {
- throw new ArgumentNullException(nameof(imdbId));
- }
+ ArgumentException.ThrowIfNullOrEmpty(imdbId);
var dataPath = Path.Combine(_configurationManager.ApplicationPaths.CachePath, "omdb");
@@ -420,7 +425,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var person = new PersonInfo
{
Name = result.Director,
- Type = PersonType.Director
+ Type = PersonKind.Director
};
itemResult.AddPerson(person);
@@ -431,7 +436,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var person = new PersonInfo
{
Name = result.Writer,
- Type = PersonType.Writer
+ Type = PersonKind.Writer
};
itemResult.AddPerson(person);
@@ -450,7 +455,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var person = new PersonInfo
{
Name = actor,
- Type = PersonType.Actor
+ Type = PersonKind.Actor
};
itemResult.AddPerson(person);
@@ -540,13 +545,13 @@ namespace MediaBrowser.Providers.Plugins.Omdb
public float? GetRottenTomatoScore()
{
- if (Ratings != null)
+ if (Ratings is not null)
{
var rating = Ratings.FirstOrDefault(i => string.Equals(i.Source, "Rotten Tomatoes", StringComparison.OrdinalIgnoreCase));
- if (rating?.Value != null)
+ if (rating?.Value is not null)
{
var value = rating.Value.TrimEnd('%');
- if (float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var score))
+ if (float.TryParse(value, CultureInfo.InvariantCulture, out var score))
{
return score;
}
diff --git a/MediaBrowser.Providers/Plugins/StudioImages/Configuration/PluginConfiguration.cs b/MediaBrowser.Providers/Plugins/StudioImages/Configuration/PluginConfiguration.cs
index cb422ef3d..0bfab9824 100644
--- a/MediaBrowser.Providers/Plugins/StudioImages/Configuration/PluginConfiguration.cs
+++ b/MediaBrowser.Providers/Plugins/StudioImages/Configuration/PluginConfiguration.cs
@@ -1,13 +1,17 @@
-#pragma warning disable CS1591
-
-using MediaBrowser.Model.Plugins;
+using MediaBrowser.Model.Plugins;
namespace MediaBrowser.Providers.Plugins.StudioImages.Configuration
{
+ /// <summary>
+ /// Plugin configuration class for the studio image provider.
+ /// </summary>
public class PluginConfiguration : BasePluginConfiguration
{
private string _repository = Plugin.DefaultServer;
+ /// <summary>
+ /// Gets or sets the studio image repository URL.
+ /// </summary>
public string RepositoryUrl
{
get
diff --git a/MediaBrowser.Providers/Plugins/StudioImages/Configuration/config.html b/MediaBrowser.Providers/Plugins/StudioImages/Configuration/config.html
index 63750dbcd..85ebe443f 100644
--- a/MediaBrowser.Providers/Plugins/StudioImages/Configuration/config.html
+++ b/MediaBrowser.Providers/Plugins/StudioImages/Configuration/config.html
@@ -4,9 +4,10 @@
<title>Studio Images</title>
</head>
<body>
- <div data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
+ <div id="configPage" data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
<div data-role="content">
<div class="content-primary">
+ <h1>Studio Images</h1>
<form class="configForm">
<div class="inputContainer">
<input is="emby-input" type="text" id="repository" label="Repository" />
diff --git a/MediaBrowser.Providers/Plugins/StudioImages/Plugin.cs b/MediaBrowser.Providers/Plugins/StudioImages/Plugin.cs
index 5e653d039..78150153a 100644
--- a/MediaBrowser.Providers/Plugins/StudioImages/Plugin.cs
+++ b/MediaBrowser.Providers/Plugins/StudioImages/Plugin.cs
@@ -1,5 +1,4 @@
#nullable disable
-#pragma warning disable CS1591
using System;
using System.Collections.Generic;
@@ -11,27 +10,47 @@ using MediaBrowser.Providers.Plugins.StudioImages.Configuration;
namespace MediaBrowser.Providers.Plugins.StudioImages
{
+ /// <summary>
+ /// Artwork Plugin class.
+ /// </summary>
public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
{
+ /// <summary>
+ /// Artwork repository URL.
+ /// </summary>
public const string DefaultServer = "https://raw.github.com/jellyfin/emby-artwork/master/studios";
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Plugin"/> class.
+ /// </summary>
+ /// <param name="applicationPaths">application paths.</param>
+ /// <param name="xmlSerializer">xml serializer.</param>
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
: base(applicationPaths, xmlSerializer)
{
Instance = this;
}
+ /// <summary>
+ /// Gets the instance of Artwork plugin.
+ /// </summary>
public static Plugin Instance { get; private set; }
+ /// <inheritdoc/>
public override Guid Id => new Guid("872a7849-1171-458d-a6fb-3de3d442ad30");
+ /// <inheritdoc/>
public override string Name => "Studio Images";
+ /// <inheritdoc/>
public override string Description => "Get artwork for studios from any Jellyfin-compatible repository.";
// TODO remove when plugin removed from server.
+
+ /// <inheritdoc/>
public override string ConfigurationFileName => "Jellyfin.Plugin.StudioImages.xml";
+ /// <inheritdoc/>
public IEnumerable<PluginPageInfo> GetPages()
{
yield return new PluginPageInfo
diff --git a/MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs b/MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs
index ef822a22a..ae244da19 100644
--- a/MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs
@@ -1,7 +1,5 @@
#nullable disable
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -21,12 +19,21 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.StudioImages
{
+ /// <summary>
+ /// Studio image provider.
+ /// </summary>
public class StudiosImageProvider : IRemoteImageProvider
{
private readonly IServerConfigurationManager _config;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IFileSystem _fileSystem;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="StudiosImageProvider"/> class.
+ /// </summary>
+ /// <param name="config">The <see cref="IServerConfigurationManager"/>.</param>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="fileSystem">The <see cref="IFileSystem"/>.</param>
public StudiosImageProvider(IServerConfigurationManager config, IHttpClientFactory httpClientFactory, IFileSystem fileSystem)
{
_config = config;
@@ -34,21 +41,25 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
_fileSystem = fileSystem;
}
+ /// <inheritdoc />
public string Name => "Artwork Repository";
+ /// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is Studio;
}
+ /// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
- return new List<ImageType>
+ return new ImageType[]
{
ImageType.Thumb
};
}
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var thumbsPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotestudiothumbs.txt");
@@ -59,7 +70,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
var imageInfo = GetImage(item, thumbsPath, ImageType.Thumb, "thumb");
- if (imageInfo == null)
+ if (imageInfo is null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
@@ -103,6 +114,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
return EnsureList(url, file, _fileSystem, cancellationToken);
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
@@ -110,13 +122,13 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
}
/// <summary>
- /// Ensures the list.
+ /// Ensures the existence of a file listing.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="file">The file.</param>
/// <param name="fileSystem">The file system.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
+ /// <returns>A Task to ensure existence of a file listing.</returns>
public async Task<string> EnsureList(string url, string file, IFileSystem fileSystem, CancellationToken cancellationToken)
{
var fileInfo = fileSystem.GetFileInfo(file);
@@ -126,14 +138,26 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
Directory.CreateDirectory(Path.GetDirectoryName(file));
- await using var response = await httpClient.GetStreamAsync(url, cancellationToken).ConfigureAwait(false);
- await using var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
- await response.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
+ var response = await httpClient.GetStreamAsync(url, cancellationToken).ConfigureAwait(false);
+ await using (response.ConfigureAwait(false))
+ {
+ var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
+ await using (fileStream.ConfigureAwait(false))
+ {
+ await response.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
+ }
+ }
}
return file;
}
+ /// <summary>
+ /// Get matching image for an item.
+ /// </summary>
+ /// <param name="item">The <see cref="BaseItem"/>.</param>
+ /// <param name="images">The enumerable of image strings.</param>
+ /// <returns>The matching image string.</returns>
public string FindMatch(BaseItem item, IEnumerable<string> images)
{
var name = GetComparableName(item.Name);
@@ -151,6 +175,11 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
.Replace("/", string.Empty, StringComparison.Ordinal);
}
+ /// <summary>
+ /// Get available image strings for a file.
+ /// </summary>
+ /// <param name="file">The file.</param>
+ /// <returns>All images strings of a file.</returns>
public IEnumerable<string> GetAvailableImages(string file)
{
using var fileStream = File.OpenRead(file);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Api/TmdbController.cs b/MediaBrowser.Providers/Plugins/Tmdb/Api/TmdbController.cs
index 0bab7c3ca..450ee2a33 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/Api/TmdbController.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/Api/TmdbController.cs
@@ -8,10 +8,10 @@ using TMDbLib.Objects.General;
namespace MediaBrowser.Providers.Plugins.Tmdb.Api
{
/// <summary>
- /// The TMDb api controller.
+ /// The TMDb API controller.
/// </summary>
[ApiController]
- [Authorize(Policy = "DefaultAuthorization")]
+ [Authorize]
[Route("[controller]")]
[Produces(MediaTypeNames.Application.Json)]
public class TmdbController : ControllerBase
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetExternalId.cs b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetExternalId.cs
index 3217ac2f1..0e768bb83 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetExternalId.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetExternalId.cs
@@ -7,7 +7,7 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
{
/// <summary>
- /// External ID for a TMDB box set.
+ /// External id for a TMDb box set.
/// </summary>
public class TmdbBoxSetExternalId : IExternalId
{
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs
index 29a557c31..a4c6cb47d 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs
@@ -1,7 +1,3 @@
-#nullable disable
-
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -18,35 +14,48 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
{
+ /// <summary>
+ /// BoxSet image provider powered by TMDb.
+ /// </summary>
public class TmdbBoxSetImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbBoxSetImageProvider"/> class.
+ /// </summary>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbBoxSetImageProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
{
_httpClientFactory = httpClientFactory;
_tmdbClientManager = tmdbClientManager;
}
+ /// <inheritdoc />
public string Name => TmdbUtils.ProviderName;
+ /// <inheritdoc />
public int Order => 0;
+ /// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is BoxSet;
}
+ /// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
- return new List<ImageType>
+ return new ImageType[]
{
ImageType.Primary,
ImageType.Backdrop
};
}
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var tmdbId = Convert.ToInt32(item.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture);
@@ -61,7 +70,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
// TODO use image languages if All Languages isn't toggled, but there's currently no way to get that value in here
var collection = await _tmdbClientManager.GetCollectionAsync(tmdbId, null, null, cancellationToken).ConfigureAwait(false);
- if (collection?.Images == null)
+ if (collection?.Images is null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
@@ -70,12 +79,13 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
var backdrops = collection.Images.Backdrops;
var remoteImages = new List<RemoteImageInfo>(posters.Count + backdrops.Count);
- _tmdbClientManager.ConvertPostersToRemoteImageInfo(posters, language, remoteImages);
- _tmdbClientManager.ConvertBackdropsToRemoteImageInfo(backdrops, language, remoteImages);
+ remoteImages.AddRange(_tmdbClientManager.ConvertPostersToRemoteImageInfo(posters, language));
+ remoteImages.AddRange(_tmdbClientManager.ConvertBackdropsToRemoteImageInfo(backdrops, language));
return remoteImages;
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs
index 62bc9c65f..c2018d820 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs
@@ -1,7 +1,3 @@
-#nullable disable
-
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -18,12 +14,21 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
{
+ /// <summary>
+ /// BoxSet provider powered by TMDb.
+ /// </summary>
public class TmdbBoxSetProvider : IRemoteMetadataProvider<BoxSet, BoxSetInfo>
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
private readonly ILibraryManager _libraryManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbBoxSetProvider"/> class.
+ /// </summary>
+ /// <param name="libraryManager">The <see cref="ILibraryManager"/>.</param>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbBoxSetProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager, ILibraryManager libraryManager)
{
_httpClientFactory = httpClientFactory;
@@ -31,8 +36,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
_libraryManager = libraryManager;
}
+ /// <inheritdoc />
public string Name => TmdbUtils.ProviderName;
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(BoxSetInfo searchInfo, CancellationToken cancellationToken)
{
var tmdbId = Convert.ToInt32(searchInfo.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture);
@@ -42,7 +49,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
{
var collection = await _tmdbClientManager.GetCollectionAsync(tmdbId, language, TmdbUtils.GetImageLanguagesParam(language), cancellationToken).ConfigureAwait(false);
- if (collection == null)
+ if (collection is null)
{
return Enumerable.Empty<RemoteSearchResult>();
}
@@ -53,7 +60,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
SearchProviderName = Name
};
- if (collection.Images != null)
+ if (collection.Images is not null)
{
result.ImageUrl = _tmdbClientManager.GetPosterUrl(collection.PosterPath);
}
@@ -65,7 +72,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
var collectionSearchResults = await _tmdbClientManager.SearchCollectionAsync(searchInfo.Name, language, cancellationToken).ConfigureAwait(false);
- var collections = new List<RemoteSearchResult>();
+ var collections = new RemoteSearchResult[collectionSearchResults.Count];
for (var i = 0; i < collectionSearchResults.Count; i++)
{
var collection = new RemoteSearchResult
@@ -75,12 +82,13 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
};
collection.SetProviderId(MetadataProvider.Tmdb, collectionSearchResults[i].Id.ToString(CultureInfo.InvariantCulture));
- collections.Add(collection);
+ collections[i] = collection;
}
return collections;
}
+ /// <inheritdoc />
public async Task<MetadataResult<BoxSet>> GetMetadata(BoxSetInfo info, CancellationToken cancellationToken)
{
var tmdbId = Convert.ToInt32(info.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture);
@@ -94,7 +102,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
var cleanedName = TmdbUtils.CleanName(parsedName.Name);
var searchResults = await _tmdbClientManager.SearchCollectionAsync(cleanedName, language, cancellationToken).ConfigureAwait(false);
- if (searchResults != null && searchResults.Count > 0)
+ if (searchResults is not null && searchResults.Count > 0)
{
tmdbId = searchResults[0].Id;
}
@@ -106,7 +114,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
{
var collection = await _tmdbClientManager.GetCollectionAsync(tmdbId, language, TmdbUtils.GetImageLanguagesParam(language), cancellationToken).ConfigureAwait(false);
- if (collection != null)
+ if (collection is not null)
{
var item = new BoxSet
{
@@ -124,6 +132,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
return result;
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Configuration/config.html b/MediaBrowser.Providers/Plugins/Tmdb/Configuration/config.html
index 48ec0535c..cd21516f9 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/Configuration/config.html
+++ b/MediaBrowser.Providers/Plugins/Tmdb/Configuration/config.html
@@ -4,9 +4,10 @@
<title>TMDb</title>
</head>
<body>
- <div data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
+ <div id="configPage" data-role="page" class="page type-interior pluginConfigurationPage configPage" data-require="emby-input,emby-button,emby-checkbox">
<div data-role="content">
<div class="content-primary">
+ <h1>TMDb</h1>
<form class="configForm">
<label class="checkboxContainer">
<input is="emby-checkbox" type="checkbox" id="includeAdult" />
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieExternalId.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieExternalId.cs
index 31310a8d4..38d2c5c69 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieExternalId.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieExternalId.cs
@@ -7,7 +7,7 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
/// <summary>
- /// External ID for a TMBD movie.
+ /// External id for a TMDb movie.
/// </summary>
public class TmdbMovieExternalId : IExternalId
{
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs
index 16f0089f8..bfec48e7c 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs
@@ -1,7 +1,3 @@
-#nullable disable
-
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -19,29 +15,41 @@ using TMDbLib.Objects.Find;
namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
+ /// <summary>
+ /// Movie image provider powered by TMDb.
+ /// </summary>
public class TmdbMovieImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbMovieImageProvider"/> class.
+ /// </summary>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbMovieImageProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
{
_httpClientFactory = httpClientFactory;
_tmdbClientManager = tmdbClientManager;
}
+ /// <inheritdoc />
public int Order => 0;
+ /// <inheritdoc />
public string Name => TmdbUtils.ProviderName;
+ /// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is Movie || item is Trailer;
}
+ /// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
- return new List<ImageType>
+ return new ImageType[]
{
ImageType.Primary,
ImageType.Backdrop,
@@ -49,6 +57,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
};
}
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var language = item.GetPreferredMetadataLanguage();
@@ -63,7 +72,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
}
var movieResult = await _tmdbClientManager.FindByExternalIdAsync(movieImdbId, FindExternalSource.Imdb, language, cancellationToken).ConfigureAwait(false);
- if (movieResult?.MovieResults != null && movieResult.MovieResults.Count > 0)
+ if (movieResult?.MovieResults is not null && movieResult.MovieResults.Count > 0)
{
movieTmdbId = movieResult.MovieResults[0].Id;
}
@@ -79,7 +88,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
.GetMovieAsync(movieTmdbId, null, null, cancellationToken)
.ConfigureAwait(false);
- if (movie?.Images == null)
+ if (movie?.Images is null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
@@ -89,13 +98,14 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
var logos = movie.Images.Logos;
var remoteImages = new List<RemoteImageInfo>(posters.Count + backdrops.Count + logos.Count);
- _tmdbClientManager.ConvertPostersToRemoteImageInfo(posters, language, remoteImages);
- _tmdbClientManager.ConvertBackdropsToRemoteImageInfo(backdrops, language, remoteImages);
- _tmdbClientManager.ConvertLogosToRemoteImageInfo(logos, language, remoteImages);
+ remoteImages.AddRange(_tmdbClientManager.ConvertPostersToRemoteImageInfo(posters, language));
+ remoteImages.AddRange(_tmdbClientManager.ConvertBackdropsToRemoteImageInfo(backdrops, language));
+ remoteImages.AddRange(_tmdbClientManager.ConvertLogosToRemoteImageInfo(logos, language));
return remoteImages;
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs
index f14f31858..2f62e117e 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs
@@ -1,7 +1,3 @@
-#nullable disable
-
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -9,6 +5,7 @@ using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities;
@@ -23,7 +20,7 @@ using TMDbLib.Objects.Search;
namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
/// <summary>
- /// Class MovieDbProvider.
+ /// Movie provider powered by TMDb.
/// </summary>
public class TmdbMovieProvider : IRemoteMetadataProvider<Movie, MovieInfo>, IHasOrder
{
@@ -31,6 +28,12 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
private readonly ILibraryManager _libraryManager;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbMovieProvider"/> class.
+ /// </summary>
+ /// <param name="libraryManager">The <see cref="ILibraryManager"/>.</param>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbMovieProvider(
ILibraryManager libraryManager,
TmdbClientManager tmdbClientManager,
@@ -41,11 +44,13 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
_httpClientFactory = httpClientFactory;
}
- public string Name => TmdbUtils.ProviderName;
-
/// <inheritdoc />
public int Order => 1;
+ /// <inheritdoc />
+ public string Name => TmdbUtils.ProviderName;
+
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(MovieInfo searchInfo, CancellationToken cancellationToken)
{
if (searchInfo.TryGetProviderId(MetadataProvider.Tmdb, out var id))
@@ -58,32 +63,35 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
cancellationToken)
.ConfigureAwait(false);
- var remoteResult = new RemoteSearchResult
+ if (movie is not null)
{
- Name = movie.Title ?? movie.OriginalTitle,
- SearchProviderName = Name,
- ImageUrl = _tmdbClientManager.GetPosterUrl(movie.PosterPath),
- Overview = movie.Overview
- };
+ var remoteResult = new RemoteSearchResult
+ {
+ Name = movie.Title ?? movie.OriginalTitle,
+ SearchProviderName = Name,
+ ImageUrl = _tmdbClientManager.GetPosterUrl(movie.PosterPath),
+ Overview = movie.Overview
+ };
- if (movie.ReleaseDate != null)
- {
- var releaseDate = movie.ReleaseDate.Value.ToUniversalTime();
- remoteResult.PremiereDate = releaseDate;
- remoteResult.ProductionYear = releaseDate.Year;
- }
+ if (movie.ReleaseDate is not null)
+ {
+ var releaseDate = movie.ReleaseDate.Value.ToUniversalTime();
+ remoteResult.PremiereDate = releaseDate;
+ remoteResult.ProductionYear = releaseDate.Year;
+ }
- remoteResult.SetProviderId(MetadataProvider.Tmdb, movie.Id.ToString(CultureInfo.InvariantCulture));
+ remoteResult.SetProviderId(MetadataProvider.Tmdb, movie.Id.ToString(CultureInfo.InvariantCulture));
- if (!string.IsNullOrWhiteSpace(movie.ImdbId))
- {
- remoteResult.SetProviderId(MetadataProvider.Imdb, movie.ImdbId);
- }
+ if (!string.IsNullOrWhiteSpace(movie.ImdbId))
+ {
+ remoteResult.SetProviderId(MetadataProvider.Imdb, movie.ImdbId);
+ }
- return new[] { remoteResult };
+ return new[] { remoteResult };
+ }
}
- IReadOnlyList<SearchMovie> movieResults;
+ IReadOnlyList<SearchMovie>? movieResults = null;
if (searchInfo.TryGetProviderId(MetadataProvider.Imdb, out id))
{
var result = await _tmdbClientManager.FindByExternalIdAsync(
@@ -91,18 +99,20 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
FindExternalSource.Imdb,
TmdbUtils.GetImageLanguagesParam(searchInfo.MetadataLanguage),
cancellationToken).ConfigureAwait(false);
- movieResults = result.MovieResults;
+ movieResults = result?.MovieResults;
}
- else if (searchInfo.TryGetProviderId(MetadataProvider.Tvdb, out id))
+
+ if (movieResults is null && searchInfo.TryGetProviderId(MetadataProvider.Tvdb, out id))
{
var result = await _tmdbClientManager.FindByExternalIdAsync(
id,
FindExternalSource.TvDb,
TmdbUtils.GetImageLanguagesParam(searchInfo.MetadataLanguage),
cancellationToken).ConfigureAwait(false);
- movieResults = result.MovieResults;
+ movieResults = result?.MovieResults;
}
- else
+
+ if (movieResults is null)
{
movieResults = await _tmdbClientManager
.SearchMovieAsync(searchInfo.Name, searchInfo.Year ?? 0, searchInfo.MetadataLanguage, cancellationToken)
@@ -133,6 +143,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
return remoteSearchResults;
}
+ /// <inheritdoc />
public async Task<MetadataResult<Movie>> GetMetadata(MovieInfo info, CancellationToken cancellationToken)
{
var tmdbId = info.GetProviderId(MetadataProvider.Tmdb);
@@ -144,7 +155,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
// Caller provides the filename with extension stripped and NOT the parsed filename
var parsedName = _libraryManager.ParseName(info.Name);
var cleanedName = TmdbUtils.CleanName(parsedName.Name);
- var searchResults = await _tmdbClientManager.SearchMovieAsync(cleanedName, info.Year ?? parsedName.Year ?? 0, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
+ var searchResults = await _tmdbClientManager.SearchMovieAsync(cleanedName, info.Year ?? parsedName.Year ?? 0, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
if (searchResults.Count > 0)
{
@@ -170,7 +181,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
.GetMovieAsync(Convert.ToInt32(tmdbId, CultureInfo.InvariantCulture), info.MetadataLanguage, TmdbUtils.GetImageLanguagesParam(info.MetadataLanguage), cancellationToken)
.ConfigureAwait(false);
- if (movieResult == null)
+ if (movieResult is null)
{
return new MetadataResult<Movie>();
}
@@ -192,7 +203,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
movie.SetProviderId(MetadataProvider.Tmdb, tmdbId);
movie.SetProviderId(MetadataProvider.Imdb, movieResult.ImdbId);
- if (movieResult.BelongsToCollection != null)
+ if (movieResult.BelongsToCollection is not null)
{
movie.SetProviderId(MetadataProvider.TmdbCollection, movieResult.BelongsToCollection.Id.ToString(CultureInfo.InvariantCulture));
movie.CollectionName = movieResult.BelongsToCollection.Name;
@@ -200,18 +211,18 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
movie.CommunityRating = Convert.ToSingle(movieResult.VoteAverage);
- if (movieResult.Releases?.Countries != null)
+ if (movieResult.Releases?.Countries is not null)
{
var releases = movieResult.Releases.Countries.Where(i => !string.IsNullOrWhiteSpace(i.Certification)).ToList();
var ourRelease = releases.FirstOrDefault(c => string.Equals(c.Iso_3166_1, info.MetadataCountryCode, StringComparison.OrdinalIgnoreCase));
var usRelease = releases.FirstOrDefault(c => string.Equals(c.Iso_3166_1, "US", StringComparison.OrdinalIgnoreCase));
- if (ourRelease != null)
+ if (ourRelease is not null)
{
movie.OfficialRating = TmdbUtils.BuildParentalRating(ourRelease.Iso_3166_1, ourRelease.Certification);
}
- else if (usRelease != null)
+ else if (usRelease is not null)
{
movie.OfficialRating = usRelease.Certification;
}
@@ -220,7 +231,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
movie.PremiereDate = movieResult.ReleaseDate;
movie.ProductionYear = movieResult.ReleaseDate?.Year;
- if (movieResult.ProductionCompanies != null)
+ if (movieResult.ProductionCompanies is not null)
{
movie.SetStudios(movieResult.ProductionCompanies.Select(c => c.Name));
}
@@ -232,7 +243,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
movie.AddGenre(genre);
}
- if (movieResult.Keywords?.Keywords != null)
+ if (movieResult.Keywords?.Keywords is not null)
{
for (var i = 0; i < movieResult.Keywords.Keywords.Count; i++)
{
@@ -240,7 +251,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
}
}
- if (movieResult.Credits?.Cast != null)
+ if (movieResult.Credits?.Cast is not null)
{
foreach (var actor in movieResult.Credits.Cast.OrderBy(a => a.Order).Take(Plugin.Instance.Configuration.MaxCastMembers))
{
@@ -248,7 +259,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
Name = actor.Name.Trim(),
Role = actor.Character,
- Type = PersonType.Actor,
+ Type = PersonKind.Actor,
SortOrder = actor.Order
};
@@ -266,22 +277,15 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
}
}
- if (movieResult.Credits?.Crew != null)
+ if (movieResult.Credits?.Crew is not null)
{
- var keepTypes = new[]
- {
- PersonType.Director,
- PersonType.Writer,
- PersonType.Producer
- };
-
foreach (var person in movieResult.Credits.Crew)
{
// Normalize this
var type = TmdbUtils.MapCrewToPersonType(person);
- if (!keepTypes.Contains(type, StringComparison.OrdinalIgnoreCase) &&
- !keepTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase))
+ if (!TmdbUtils.WantedCrewKinds.Contains(type)
+ && !TmdbUtils.WantedCrewTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase))
{
continue;
}
@@ -307,7 +311,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
}
}
- if (movieResult.Videos?.Results != null)
+ if (movieResult.Videos?.Results is not null)
{
var trailers = new List<MediaUrl>();
for (var i = 0; i < movieResult.Videos.Results.Count; i++)
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonExternalId.cs b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonExternalId.cs
index 9804d60bd..027399aec 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonExternalId.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonExternalId.cs
@@ -6,7 +6,7 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.People
{
/// <summary>
- /// External ID for a TMDB person.
+ /// External id for a TMDb person.
/// </summary>
public class TmdbPersonExternalId : IExternalId
{
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonImageProvider.cs
index 7ce4cfe67..9e5404b32 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonImageProvider.cs
@@ -1,5 +1,3 @@
-#pragma warning disable CS1591
-
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@@ -14,11 +12,19 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.People
{
+ /// <summary>
+ /// Person image provider powered by TMDb.
+ /// </summary>
public class TmdbPersonImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbPersonImageProvider"/> class.
+ /// </summary>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbPersonImageProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
{
_httpClientFactory = httpClientFactory;
@@ -31,19 +37,19 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People
/// <inheritdoc />
public int Order => 0;
+ /// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is Person;
}
+ /// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
- return new List<ImageType>
- {
- ImageType.Primary
- };
+ yield return ImageType.Primary;
}
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var person = (Person)item;
@@ -55,19 +61,15 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People
var language = item.GetPreferredMetadataLanguage();
var personResult = await _tmdbClientManager.GetPersonAsync(int.Parse(personTmdbId, CultureInfo.InvariantCulture), language, cancellationToken).ConfigureAwait(false);
- if (personResult?.Images?.Profiles == null)
+ if (personResult?.Images?.Profiles is null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
- var profiles = personResult.Images.Profiles;
- var remoteImages = new List<RemoteImageInfo>(profiles.Count);
-
- _tmdbClientManager.ConvertProfilesToRemoteImageInfo(profiles, language, remoteImages);
-
- return remoteImages;
+ return _tmdbClientManager.ConvertProfilesToRemoteImageInfo(personResult.Images.Profiles, language);
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs
index 8790e3759..5c6e71fd8 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs
@@ -1,7 +1,3 @@
-#nullable disable
-
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -16,26 +12,36 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.People
{
+ /// <summary>
+ /// Person image provider powered by TMDb.
+ /// </summary>
public class TmdbPersonProvider : IRemoteMetadataProvider<Person, PersonLookupInfo>
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbPersonProvider"/> class.
+ /// </summary>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbPersonProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
{
_httpClientFactory = httpClientFactory;
_tmdbClientManager = tmdbClientManager;
}
+ /// <inheritdoc />
public string Name => TmdbUtils.ProviderName;
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(PersonLookupInfo searchInfo, CancellationToken cancellationToken)
{
if (searchInfo.TryGetProviderId(MetadataProvider.Tmdb, out var personTmdbId))
{
var personResult = await _tmdbClientManager.GetPersonAsync(int.Parse(personTmdbId, CultureInfo.InvariantCulture), searchInfo.MetadataLanguage, cancellationToken).ConfigureAwait(false);
- if (personResult != null)
+ if (personResult is not null)
{
var result = new RemoteSearchResult
{
@@ -44,7 +50,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People
Overview = personResult.Biography
};
- if (personResult.Images?.Profiles != null && personResult.Images.Profiles.Count > 0)
+ if (personResult.Images?.Profiles is not null && personResult.Images.Profiles.Count > 0)
{
result.ImageUrl = _tmdbClientManager.GetProfileUrl(personResult.Images.Profiles[0].FilePath);
}
@@ -61,7 +67,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People
var personSearchResult = await _tmdbClientManager.SearchPersonAsync(searchInfo.Name, cancellationToken).ConfigureAwait(false);
- var remoteSearchResults = new List<RemoteSearchResult>();
+ var remoteSearchResults = new RemoteSearchResult[personSearchResult.Count];
for (var i = 0; i < personSearchResult.Count; i++)
{
var person = personSearchResult[i];
@@ -73,12 +79,13 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People
};
remoteSearchResult.SetProviderId(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture));
- remoteSearchResults.Add(remoteSearchResult);
+ remoteSearchResults[i] = remoteSearchResult;
}
return remoteSearchResults;
}
+ /// <inheritdoc />
public async Task<MetadataResult<Person>> GetMetadata(PersonLookupInfo info, CancellationToken cancellationToken)
{
var personTmdbId = Convert.ToInt32(info.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture);
@@ -98,6 +105,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People
if (personTmdbId > 0)
{
var person = await _tmdbClientManager.GetPersonAsync(personTmdbId, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
+ if (person is null)
+ {
+ return result;
+ }
result.HasMetadata = true;
@@ -131,6 +142,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People
return result;
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs
index 5eec776b5..d1fec7cb1 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs
@@ -1,7 +1,3 @@
-#nullable disable
-
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -17,30 +13,44 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
+ /// <summary>
+ /// TV episode image provider powered by TheMovieDb.
+ /// </summary>
public class TmdbEpisodeImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbEpisodeImageProvider"/> class.
+ /// </summary>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbEpisodeImageProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
{
_httpClientFactory = httpClientFactory;
_tmdbClientManager = tmdbClientManager;
}
- // After TheTvDb
+ /// <inheritdoc />
public int Order => 1;
+ /// <inheritdoc />
public string Name => TmdbUtils.ProviderName;
+ /// <inheritdoc />
+ public bool Supports(BaseItem item)
+ {
+ return item is Controller.Entities.TV.Episode;
+ }
+
+ /// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
- return new List<ImageType>
- {
- ImageType.Primary
- };
+ yield return ImageType.Primary;
}
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var episode = (Controller.Entities.TV.Episode)item;
@@ -48,7 +58,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var seriesTmdbId = Convert.ToInt32(series?.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture);
- if (seriesTmdbId <= 0)
+ if (series is null || seriesTmdbId <= 0)
{
return Enumerable.Empty<RemoteImageInfo>();
}
@@ -69,26 +79,18 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.ConfigureAwait(false);
var stills = episodeResult?.Images?.Stills;
- if (stills == null)
+ if (stills is null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
- var remoteImages = new List<RemoteImageInfo>(stills.Count);
-
- _tmdbClientManager.ConvertStillsToRemoteImageInfo(stills, language, remoteImages);
-
- return remoteImages;
+ return _tmdbClientManager.ConvertStillsToRemoteImageInfo(stills, language);
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
}
-
- public bool Supports(BaseItem item)
- {
- return item is Controller.Entities.TV.Episode;
- }
}
}
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs
index f50f15877..f18575aa9 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs
@@ -1,7 +1,3 @@
-#nullable disable
-
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -9,6 +5,7 @@ using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities;
@@ -19,22 +16,32 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
+ /// <summary>
+ /// TV episode provider powered by TheMovieDb.
+ /// </summary>
public class TmdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbEpisodeProvider"/> class.
+ /// </summary>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbEpisodeProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
{
_httpClientFactory = httpClientFactory;
_tmdbClientManager = tmdbClientManager;
}
- // After TheTvDb
+ /// <inheritdoc />
public int Order => 1;
+ /// <inheritdoc />
public string Name => TmdbUtils.ProviderName;
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken)
{
// The search query must either provide an episode number or date
@@ -68,6 +75,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
};
}
+ /// <inheritdoc />
public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken)
{
var metadataResult = new MetadataResult<Episode>();
@@ -78,7 +86,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
return metadataResult;
}
- info.SeriesProviderIds.TryGetValue(MetadataProvider.Tmdb.ToString(), out string tmdbId);
+ info.SeriesProviderIds.TryGetValue(MetadataProvider.Tmdb.ToString(), out string? tmdbId);
var seriesTmdbId = Convert.ToInt32(tmdbId, CultureInfo.InvariantCulture);
if (seriesTmdbId <= 0)
@@ -98,7 +106,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.GetEpisodeAsync(seriesTmdbId, seasonNumber.Value, episodeNumber.Value, info.SeriesDisplayOrder, info.MetadataLanguage, TmdbUtils.GetImageLanguagesParam(info.MetadataLanguage), cancellationToken)
.ConfigureAwait(false);
- if (episodeResult == null)
+ if (episodeResult is null)
{
return metadataResult;
}
@@ -140,7 +148,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
item.SetProviderId(MetadataProvider.TvRage, externalIds.TvrageId);
}
- if (episodeResult.Videos?.Results != null)
+ if (episodeResult.Videos?.Results is not null)
{
foreach (var video in episodeResult.Videos.Results)
{
@@ -153,7 +161,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var credits = episodeResult.Credits;
- if (credits?.Cast != null)
+ if (credits?.Cast is not null)
{
foreach (var actor in credits.Cast.OrderBy(a => a.Order).Take(Plugin.Instance.Configuration.MaxCastMembers))
{
@@ -161,13 +169,13 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
Name = actor.Name.Trim(),
Role = actor.Character,
- Type = PersonType.Actor,
+ Type = PersonKind.Actor,
SortOrder = actor.Order
});
}
}
- if (credits?.GuestStars != null)
+ if (credits?.GuestStars is not null)
{
foreach (var guest in credits.GuestStars.OrderBy(a => a.Order).Take(Plugin.Instance.Configuration.MaxCastMembers))
{
@@ -175,21 +183,21 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
Name = guest.Name.Trim(),
Role = guest.Character,
- Type = PersonType.GuestStar,
+ Type = PersonKind.GuestStar,
SortOrder = guest.Order
});
}
}
// and the rest from crew
- if (credits?.Crew != null)
+ if (credits?.Crew is not null)
{
foreach (var person in credits.Crew)
{
// Normalize this
var type = TmdbUtils.MapCrewToPersonType(person);
- if (!TmdbUtils.WantedCrewTypes.Contains(type, StringComparison.OrdinalIgnoreCase)
+ if (!TmdbUtils.WantedCrewKinds.Contains(type)
&& !TmdbUtils.WantedCrewTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase))
{
continue;
@@ -209,6 +217,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
return metadataResult;
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs
index 4446fa966..a743601ed 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs
@@ -1,5 +1,3 @@
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -16,26 +14,44 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
+ /// <summary>
+ /// TV season image provider powered by TheMovieDb.
+ /// </summary>
public class TmdbSeasonImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbSeasonImageProvider"/> class.
+ /// </summary>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbSeasonImageProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
{
_httpClientFactory = httpClientFactory;
_tmdbClientManager = tmdbClientManager;
}
+ /// <inheritdoc/>
public int Order => 1;
+ /// <inheritdoc/>
public string Name => TmdbUtils.ProviderName;
- public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
+ /// <inheritdoc />
+ public bool Supports(BaseItem item)
{
- return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
+ return item is Season;
}
+ /// <inheritdoc />
+ public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
+ {
+ yield return ImageType.Primary;
+ }
+
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var season = (Season)item;
@@ -43,7 +59,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var seriesTmdbId = Convert.ToInt32(series?.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture);
- if (seriesTmdbId <= 0 || season?.IndexNumber == null)
+ if (seriesTmdbId <= 0 || season?.IndexNumber is null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
@@ -56,29 +72,18 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.ConfigureAwait(false);
var posters = seasonResult?.Images?.Posters;
- if (posters == null)
+ if (posters is null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
- var remoteImages = new List<RemoteImageInfo>(posters.Count);
-
- _tmdbClientManager.ConvertPostersToRemoteImageInfo(posters, language, remoteImages);
-
- return remoteImages;
- }
-
- public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
- {
- return new List<ImageType>
- {
- ImageType.Primary
- };
+ return _tmdbClientManager.ConvertPostersToRemoteImageInfo(posters, language);
}
- public bool Supports(BaseItem item)
+ /// <inheritdoc />
+ public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
- return item is Season;
+ return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
}
}
}
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs
index 64ed3f408..10efb68b9 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs
@@ -1,5 +1,3 @@
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -7,6 +5,7 @@ using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities;
@@ -17,19 +16,29 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
+ /// <summary>
+ /// TV season provider powered by TheMovieDb.
+ /// </summary>
public class TmdbSeasonProvider : IRemoteMetadataProvider<Season, SeasonInfo>
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbSeasonProvider"/> class.
+ /// </summary>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbSeasonProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
{
_httpClientFactory = httpClientFactory;
_tmdbClientManager = tmdbClientManager;
}
+ /// <inheritdoc />
public string Name => TmdbUtils.ProviderName;
+ /// <inheritdoc />
public async Task<MetadataResult<Season>> GetMetadata(SeasonInfo info, CancellationToken cancellationToken)
{
var result = new MetadataResult<Season>();
@@ -47,7 +56,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.GetSeasonAsync(Convert.ToInt32(seriesTmdbId, CultureInfo.InvariantCulture), seasonNumber.Value, info.MetadataLanguage, TmdbUtils.GetImageLanguagesParam(info.MetadataLanguage), cancellationToken)
.ConfigureAwait(false);
- if (seasonResult == null)
+ if (seasonResult is null)
{
return result;
}
@@ -71,7 +80,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
// TODO why was this disabled?
var credits = seasonResult.Credits;
- if (credits?.Cast != null)
+ if (credits?.Cast is not null)
{
var cast = credits.Cast.OrderBy(c => c.Order).Take(Plugin.Instance.Configuration.MaxCastMembers).ToList();
for (var i = 0; i < cast.Count; i++)
@@ -80,20 +89,20 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
Name = cast[i].Name.Trim(),
Role = cast[i].Character,
- Type = PersonType.Actor,
+ Type = PersonKind.Actor,
SortOrder = cast[i].Order
});
}
}
- if (credits?.Crew != null)
+ if (credits?.Crew is not null)
{
foreach (var person in credits.Crew)
{
// Normalize this
var type = TmdbUtils.MapCrewToPersonType(person);
- if (!TmdbUtils.WantedCrewTypes.Contains(type, StringComparison.OrdinalIgnoreCase)
+ if (!TmdbUtils.WantedCrewKinds.Contains(type)
&& !TmdbUtils.WantedCrewTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase))
{
continue;
@@ -114,11 +123,13 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
return result;
}
+ /// <inheritdoc />
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(SeasonInfo searchInfo, CancellationToken cancellationToken)
{
return Task.FromResult(Enumerable.Empty<RemoteSearchResult>());
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesExternalId.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesExternalId.cs
index 8a2be80cd..df04cb2e7 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesExternalId.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesExternalId.cs
@@ -6,7 +6,7 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
/// <summary>
- /// External ID for a TMDB series.
+ /// External id for a TMDb series.
/// </summary>
public class TmdbSeriesExternalId : IExternalId
{
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs
index 130d6ce44..192fb052d 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs
@@ -1,5 +1,3 @@
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -16,30 +14,41 @@ using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
+ /// <summary>
+ /// TV series image provider powered by TheMovieDb.
+ /// </summary>
public class TmdbSeriesImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbSeriesImageProvider"/> class.
+ /// </summary>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbSeriesImageProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
{
_httpClientFactory = httpClientFactory;
_tmdbClientManager = tmdbClientManager;
}
+ /// <inheritdoc />
public string Name => TmdbUtils.ProviderName;
- // After tvdb and fanart
+ /// <inheritdoc />
public int Order => 2;
+ /// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is Series;
}
+ /// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
- return new List<ImageType>
+ return new ImageType[]
{
ImageType.Primary,
ImageType.Backdrop,
@@ -47,6 +56,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
};
}
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var tmdbId = item.GetProviderId(MetadataProvider.Tmdb);
@@ -63,7 +73,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.GetSeriesAsync(Convert.ToInt32(tmdbId, CultureInfo.InvariantCulture), null, null, cancellationToken)
.ConfigureAwait(false);
- if (series?.Images == null)
+ if (series?.Images is null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
@@ -73,13 +83,14 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var logos = series.Images.Logos;
var remoteImages = new List<RemoteImageInfo>(posters.Count + backdrops.Count + logos.Count);
- _tmdbClientManager.ConvertPostersToRemoteImageInfo(posters, language, remoteImages);
- _tmdbClientManager.ConvertBackdropsToRemoteImageInfo(backdrops, language, remoteImages);
- _tmdbClientManager.ConvertLogosToRemoteImageInfo(logos, language, remoteImages);
+ remoteImages.AddRange(_tmdbClientManager.ConvertPostersToRemoteImageInfo(posters, language));
+ remoteImages.AddRange(_tmdbClientManager.ConvertBackdropsToRemoteImageInfo(backdrops, language));
+ remoteImages.AddRange(_tmdbClientManager.ConvertLogosToRemoteImageInfo(logos, language));
return remoteImages;
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs
index 4d26052fa..8dc2d6938 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs
@@ -1,7 +1,3 @@
-#nullable disable
-
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -9,6 +5,7 @@ using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities;
@@ -23,12 +20,21 @@ using TMDbLib.Objects.TvShows;
namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
+ /// <summary>
+ /// TV series provider powered by TheMovieDb.
+ /// </summary>
public class TmdbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILibraryManager _libraryManager;
private readonly TmdbClientManager _tmdbClientManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TmdbSeriesProvider"/> class.
+ /// </summary>
+ /// <param name="libraryManager">The <see cref="ILibraryManager"/>.</param>
+ /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
+ /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
public TmdbSeriesProvider(
ILibraryManager libraryManager,
IHttpClientFactory httpClientFactory,
@@ -39,11 +45,13 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
_tmdbClientManager = tmdbClientManager;
}
+ /// <inheritdoc />
public string Name => TmdbUtils.ProviderName;
- // After TheTVDB
+ /// <inheritdoc />
public int Order => 1;
+ /// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken)
{
if (searchInfo.TryGetProviderId(MetadataProvider.Tmdb, out var tmdbId))
@@ -52,7 +60,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.GetSeriesAsync(Convert.ToInt32(tmdbId, CultureInfo.InvariantCulture), searchInfo.MetadataLanguage, searchInfo.MetadataLanguage, cancellationToken)
.ConfigureAwait(false);
- if (series != null)
+ if (series is not null)
{
var remoteResult = MapTvShowToRemoteSearchResult(series);
@@ -67,7 +75,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.ConfigureAwait(false);
var tvResults = findResult?.TvResults;
- if (tvResults != null)
+ if (tvResults is not null)
{
var imdbIdResults = new RemoteSearchResult[tvResults.Count];
for (var i = 0; i < tvResults.Count; i++)
@@ -88,7 +96,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
.ConfigureAwait(false);
var tvResults = findResult?.TvResults;
- if (tvResults != null)
+ if (tvResults is not null)
{
var tvIdResults = new RemoteSearchResult[tvResults.Count];
for (var i = 0; i < tvResults.Count; i++)
@@ -125,7 +133,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
};
remoteResult.SetProviderId(MetadataProvider.Tmdb, series.Id.ToString(CultureInfo.InvariantCulture));
- if (series.ExternalIds != null)
+ if (series.ExternalIds is not null)
{
if (!string.IsNullOrEmpty(series.ExternalIds.ImdbId))
{
@@ -159,6 +167,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
return remoteResult;
}
+ /// <inheritdoc />
public async Task<MetadataResult<Series>> GetMetadata(SeriesInfo info, CancellationToken cancellationToken)
{
var result = new MetadataResult<Series>
@@ -201,7 +210,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
}
}
- if (string.IsNullOrEmpty(tmdbId))
+ if (!int.TryParse(tmdbId, CultureInfo.InvariantCulture, out int tmdbIdInt))
{
return result;
}
@@ -209,9 +218,14 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
cancellationToken.ThrowIfCancellationRequested();
var tvShow = await _tmdbClientManager
- .GetSeriesAsync(Convert.ToInt32(tmdbId, CultureInfo.InvariantCulture), info.MetadataLanguage, TmdbUtils.GetImageLanguagesParam(info.MetadataLanguage), cancellationToken)
+ .GetSeriesAsync(tmdbIdInt, info.MetadataLanguage, TmdbUtils.GetImageLanguagesParam(info.MetadataLanguage), cancellationToken)
.ConfigureAwait(false);
+ if (tvShow is null)
+ {
+ return result;
+ }
+
result = new MetadataResult<Series>
{
Item = MapTvShowToSeries(tvShow, info.MetadataCountryCode),
@@ -223,7 +237,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
result.AddPerson(person);
}
- result.HasMetadata = result.Item != null;
+ result.HasMetadata = result.Item is not null;
return result;
}
@@ -242,17 +256,17 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
series.Overview = seriesResult.Overview;
- if (seriesResult.Networks != null)
+ if (seriesResult.Networks is not null)
{
series.Studios = seriesResult.Networks.Select(i => i.Name).ToArray();
}
- if (seriesResult.Genres != null)
+ if (seriesResult.Genres is not null)
{
series.Genres = seriesResult.Genres.Select(i => i.Name).ToArray();
}
- if (seriesResult.Keywords?.Results != null)
+ if (seriesResult.Keywords?.Results is not null)
{
for (var i = 0; i < seriesResult.Keywords.Results.Count; i++)
{
@@ -278,7 +292,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
series.PremiereDate = seriesResult.FirstAirDate;
var ids = seriesResult.ExternalIds;
- if (ids != null)
+ if (ids is not null)
{
if (!string.IsNullOrWhiteSpace(ids.ImdbId))
{
@@ -302,20 +316,20 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var usRelease = contentRatings.FirstOrDefault(c => string.Equals(c.Iso_3166_1, "US", StringComparison.OrdinalIgnoreCase));
var minimumRelease = contentRatings.FirstOrDefault();
- if (ourRelease != null)
+ if (ourRelease is not null)
{
series.OfficialRating = TmdbUtils.BuildParentalRating(ourRelease.Iso_3166_1, ourRelease.Rating);
}
- else if (usRelease != null)
+ else if (usRelease is not null)
{
series.OfficialRating = usRelease.Rating;
}
- else if (minimumRelease != null)
+ else if (minimumRelease is not null)
{
series.OfficialRating = minimumRelease.Rating;
}
- if (seriesResult.Videos?.Results != null)
+ if (seriesResult.Videos?.Results is not null)
{
foreach (var video in seriesResult.Videos.Results)
{
@@ -331,7 +345,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
private IEnumerable<PersonInfo> GetPersons(TvShow seriesResult)
{
- if (seriesResult.Credits?.Cast != null)
+ if (seriesResult.Credits?.Cast is not null)
{
foreach (var actor in seriesResult.Credits.Cast.OrderBy(a => a.Order).Take(Plugin.Instance.Configuration.MaxCastMembers))
{
@@ -339,7 +353,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
Name = actor.Name.Trim(),
Role = actor.Character,
- Type = PersonType.Actor,
+ Type = PersonKind.Actor,
SortOrder = actor.Order,
ImageUrl = _tmdbClientManager.GetPosterUrl(actor.ProfilePath)
};
@@ -353,7 +367,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
}
}
- if (seriesResult.Credits?.Crew != null)
+ if (seriesResult.Credits?.Crew is not null)
{
var keepTypes = new[]
{
@@ -367,8 +381,8 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
// Normalize this
var type = TmdbUtils.MapCrewToPersonType(person);
- if (!keepTypes.Contains(type, StringComparison.OrdinalIgnoreCase)
- && !keepTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase))
+ if (!TmdbUtils.WantedCrewKinds.Contains(type)
+ && !TmdbUtils.WantedCrewTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase))
{
continue;
}
@@ -383,6 +397,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
}
}
+ /// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs b/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs
index 7d7733407..500ebaf71 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs
@@ -1,6 +1,4 @@
-#nullable disable
-
-using System;
+using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
@@ -50,10 +48,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="imageLanguages">A comma-separated list of image languages.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The TMDb movie or null if not found.</returns>
- public async Task<Movie> GetMovieAsync(int tmdbId, string language, string imageLanguages, CancellationToken cancellationToken)
+ public async Task<Movie?> GetMovieAsync(int tmdbId, string? language, string? imageLanguages, CancellationToken cancellationToken)
{
var key = $"movie-{tmdbId.ToString(CultureInfo.InvariantCulture)}-{language}";
- if (_memoryCache.TryGetValue(key, out Movie movie))
+ if (_memoryCache.TryGetValue(key, out Movie? movie))
{
return movie;
}
@@ -73,7 +71,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
extraMethods,
cancellationToken).ConfigureAwait(false);
- if (movie != null)
+ if (movie is not null)
{
_memoryCache.Set(key, movie, TimeSpan.FromHours(CacheDurationInHours));
}
@@ -89,10 +87,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="imageLanguages">A comma-separated list of image languages.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The TMDb collection or null if not found.</returns>
- public async Task<Collection> GetCollectionAsync(int tmdbId, string language, string imageLanguages, CancellationToken cancellationToken)
+ public async Task<Collection?> GetCollectionAsync(int tmdbId, string? language, string? imageLanguages, CancellationToken cancellationToken)
{
var key = $"collection-{tmdbId.ToString(CultureInfo.InvariantCulture)}-{language}";
- if (_memoryCache.TryGetValue(key, out Collection collection))
+ if (_memoryCache.TryGetValue(key, out Collection? collection))
{
return collection;
}
@@ -106,7 +104,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
CollectionMethods.Images,
cancellationToken).ConfigureAwait(false);
- if (collection != null)
+ if (collection is not null)
{
_memoryCache.Set(key, collection, TimeSpan.FromHours(CacheDurationInHours));
}
@@ -122,10 +120,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="imageLanguages">A comma-separated list of image languages.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The TMDb tv show information or null if not found.</returns>
- public async Task<TvShow> GetSeriesAsync(int tmdbId, string language, string imageLanguages, CancellationToken cancellationToken)
+ public async Task<TvShow?> GetSeriesAsync(int tmdbId, string? language, string? imageLanguages, CancellationToken cancellationToken)
{
var key = $"series-{tmdbId.ToString(CultureInfo.InvariantCulture)}-{language}";
- if (_memoryCache.TryGetValue(key, out TvShow series))
+ if (_memoryCache.TryGetValue(key, out TvShow? series))
{
return series;
}
@@ -145,7 +143,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
extraMethods: extraMethods,
cancellationToken: cancellationToken).ConfigureAwait(false);
- if (series != null)
+ if (series is not null)
{
_memoryCache.Set(key, series, TimeSpan.FromHours(CacheDurationInHours));
}
@@ -162,7 +160,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="imageLanguages">A comma-separated list of image languages.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The TMDb tv show episode group information or null if not found.</returns>
- private async Task<TvGroupCollection> GetSeriesGroupAsync(int tvShowId, string displayOrder, string language, string imageLanguages, CancellationToken cancellationToken)
+ private async Task<TvGroupCollection?> GetSeriesGroupAsync(int tvShowId, string displayOrder, string? language, string? imageLanguages, CancellationToken cancellationToken)
{
TvGroupType? groupType =
string.Equals(displayOrder, "originalAirDate", StringComparison.Ordinal) ? TvGroupType.OriginalAirDate :
@@ -174,13 +172,13 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
string.Equals(displayOrder, "tv", StringComparison.Ordinal) ? TvGroupType.TV :
null;
- if (groupType == null)
+ if (groupType is null)
{
return null;
}
var key = $"group-{tvShowId.ToString(CultureInfo.InvariantCulture)}-{displayOrder}-{language}";
- if (_memoryCache.TryGetValue(key, out TvGroupCollection group))
+ if (_memoryCache.TryGetValue(key, out TvGroupCollection? group))
{
return group;
}
@@ -190,7 +188,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
var series = await GetSeriesAsync(tvShowId, language, imageLanguages, cancellationToken).ConfigureAwait(false);
var episodeGroupId = series?.EpisodeGroups.Results.Find(g => g.Type == groupType)?.Id;
- if (episodeGroupId == null)
+ if (episodeGroupId is null)
{
return null;
}
@@ -200,7 +198,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
language: TmdbUtils.NormalizeLanguage(language),
cancellationToken: cancellationToken).ConfigureAwait(false);
- if (group != null)
+ if (group is not null)
{
_memoryCache.Set(key, group, TimeSpan.FromHours(CacheDurationInHours));
}
@@ -217,10 +215,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="imageLanguages">A comma-separated list of image languages.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The TMDb tv season information or null if not found.</returns>
- public async Task<TvSeason> GetSeasonAsync(int tvShowId, int seasonNumber, string language, string imageLanguages, CancellationToken cancellationToken)
+ public async Task<TvSeason?> GetSeasonAsync(int tvShowId, int seasonNumber, string? language, string? imageLanguages, CancellationToken cancellationToken)
{
var key = $"season-{tvShowId.ToString(CultureInfo.InvariantCulture)}-s{seasonNumber.ToString(CultureInfo.InvariantCulture)}-{language}";
- if (_memoryCache.TryGetValue(key, out TvSeason season))
+ if (_memoryCache.TryGetValue(key, out TvSeason? season))
{
return season;
}
@@ -235,7 +233,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
extraMethods: TvSeasonMethods.Credits | TvSeasonMethods.Images | TvSeasonMethods.ExternalIds | TvSeasonMethods.Videos,
cancellationToken: cancellationToken).ConfigureAwait(false);
- if (season != null)
+ if (season is not null)
{
_memoryCache.Set(key, season, TimeSpan.FromHours(CacheDurationInHours));
}
@@ -254,10 +252,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="imageLanguages">A comma-separated list of image languages.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The TMDb tv episode information or null if not found.</returns>
- public async Task<TvEpisode> GetEpisodeAsync(int tvShowId, int seasonNumber, int episodeNumber, string displayOrder, string language, string imageLanguages, CancellationToken cancellationToken)
+ public async Task<TvEpisode?> GetEpisodeAsync(int tvShowId, int seasonNumber, int episodeNumber, string displayOrder, string? language, string? imageLanguages, CancellationToken cancellationToken)
{
var key = $"episode-{tvShowId.ToString(CultureInfo.InvariantCulture)}-s{seasonNumber.ToString(CultureInfo.InvariantCulture)}e{episodeNumber.ToString(CultureInfo.InvariantCulture)}-{displayOrder}-{language}";
- if (_memoryCache.TryGetValue(key, out TvEpisode episode))
+ if (_memoryCache.TryGetValue(key, out TvEpisode? episode))
{
return episode;
}
@@ -265,12 +263,12 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
await EnsureClientConfigAsync().ConfigureAwait(false);
var group = await GetSeriesGroupAsync(tvShowId, displayOrder, language, imageLanguages, cancellationToken).ConfigureAwait(false);
- if (group != null)
+ if (group is not null)
{
var season = group.Groups.Find(s => s.Order == seasonNumber);
// Episode order starts at 0
var ep = season?.Episodes.Find(e => e.Order == episodeNumber - 1);
- if (ep != null)
+ if (ep is not null)
{
seasonNumber = ep.SeasonNumber;
episodeNumber = ep.EpisodeNumber;
@@ -286,7 +284,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
extraMethods: TvEpisodeMethods.Credits | TvEpisodeMethods.Images | TvEpisodeMethods.ExternalIds | TvEpisodeMethods.Videos,
cancellationToken: cancellationToken).ConfigureAwait(false);
- if (episode != null)
+ if (episode is not null)
{
_memoryCache.Set(key, episode, TimeSpan.FromHours(CacheDurationInHours));
}
@@ -301,10 +299,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="language">The episode's language.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The TMDb person information or null if not found.</returns>
- public async Task<Person> GetPersonAsync(int personTmdbId, string language, CancellationToken cancellationToken)
+ public async Task<Person?> GetPersonAsync(int personTmdbId, string language, CancellationToken cancellationToken)
{
var key = $"person-{personTmdbId.ToString(CultureInfo.InvariantCulture)}-{language}";
- if (_memoryCache.TryGetValue(key, out Person person))
+ if (_memoryCache.TryGetValue(key, out Person? person))
{
return person;
}
@@ -317,7 +315,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
PersonMethods.TvCredits | PersonMethods.MovieCredits | PersonMethods.Images | PersonMethods.ExternalIds,
cancellationToken).ConfigureAwait(false);
- if (person != null)
+ if (person is not null)
{
_memoryCache.Set(key, person, TimeSpan.FromHours(CacheDurationInHours));
}
@@ -333,14 +331,14 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="language">The item's language.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The TMDb item or null if not found.</returns>
- public async Task<FindContainer> FindByExternalIdAsync(
+ public async Task<FindContainer?> FindByExternalIdAsync(
string externalId,
FindExternalSource source,
string language,
CancellationToken cancellationToken)
{
var key = $"find-{source.ToString()}-{externalId.ToString(CultureInfo.InvariantCulture)}-{language}";
- if (_memoryCache.TryGetValue(key, out FindContainer result))
+ if (_memoryCache.TryGetValue(key, out FindContainer? result))
{
return result;
}
@@ -353,7 +351,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
TmdbUtils.NormalizeLanguage(language),
cancellationToken).ConfigureAwait(false);
- if (result != null)
+ if (result is not null)
{
_memoryCache.Set(key, result, TimeSpan.FromHours(CacheDurationInHours));
}
@@ -372,7 +370,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
public async Task<IReadOnlyList<SearchTv>> SearchSeriesAsync(string name, string language, int year = 0, CancellationToken cancellationToken = default)
{
var key = $"searchseries-{name}-{language}";
- if (_memoryCache.TryGetValue(key, out SearchContainer<SearchTv> series))
+ if (_memoryCache.TryGetValue(key, out SearchContainer<SearchTv>? series) && series is not null)
{
return series.Results;
}
@@ -400,7 +398,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
public async Task<IReadOnlyList<SearchPerson>> SearchPersonAsync(string name, CancellationToken cancellationToken)
{
var key = $"searchperson-{name}";
- if (_memoryCache.TryGetValue(key, out SearchContainer<SearchPerson> person))
+ if (_memoryCache.TryGetValue(key, out SearchContainer<SearchPerson>? person) && person is not null)
{
return person.Results;
}
@@ -442,7 +440,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
public async Task<IReadOnlyList<SearchMovie>> SearchMovieAsync(string name, int year, string language, CancellationToken cancellationToken)
{
var key = $"moviesearch-{name}-{year.ToString(CultureInfo.InvariantCulture)}-{language}";
- if (_memoryCache.TryGetValue(key, out SearchContainer<SearchMovie> movies))
+ if (_memoryCache.TryGetValue(key, out SearchContainer<SearchMovie>? movies) && movies is not null)
{
return movies.Results;
}
@@ -471,7 +469,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
public async Task<IReadOnlyList<SearchCollection>> SearchCollectionAsync(string name, string language, CancellationToken cancellationToken)
{
var key = $"collectionsearch-{name}-{language}";
- if (_memoryCache.TryGetValue(key, out SearchContainer<SearchCollection> collections))
+ if (_memoryCache.TryGetValue(key, out SearchContainer<SearchCollection>? collections) && collections is not null)
{
return collections.Results;
}
@@ -496,7 +494,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="size">The image size to fetch.</param>
/// <param name="path">The relative URL of the image.</param>
/// <returns>The absolute URL.</returns>
- private string GetUrl(string size, string path)
+ private string? GetUrl(string? size, string path)
{
if (string.IsNullOrEmpty(path))
{
@@ -511,7 +509,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// </summary>
/// <param name="posterPath">The relative URL of the poster.</param>
/// <returns>The absolute URL.</returns>
- public string GetPosterUrl(string posterPath)
+ public string? GetPosterUrl(string posterPath)
{
return GetUrl(Plugin.Instance.Configuration.PosterSize, posterPath);
}
@@ -521,7 +519,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// </summary>
/// <param name="actorProfilePath">The relative URL of the profile image.</param>
/// <returns>The absolute URL.</returns>
- public string GetProfileUrl(string actorProfilePath)
+ public string? GetProfileUrl(string actorProfilePath)
{
return GetUrl(Plugin.Instance.Configuration.ProfileSize, actorProfilePath);
}
@@ -531,55 +529,45 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// </summary>
/// <param name="images">The input images.</param>
/// <param name="requestLanguage">The requested language.</param>
- /// <param name="results">The collection to add the remote images into.</param>
- public void ConvertPostersToRemoteImageInfo(List<ImageData> images, string requestLanguage, List<RemoteImageInfo> results)
- {
- ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.PosterSize, ImageType.Primary, requestLanguage, results);
- }
+ /// <returns>The remote images.</returns>
+ public IEnumerable<RemoteImageInfo> ConvertPostersToRemoteImageInfo(IReadOnlyList<ImageData> images, string requestLanguage)
+ => ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.PosterSize, ImageType.Primary, requestLanguage);
/// <summary>
/// Converts backdrop <see cref="ImageData"/>s into <see cref="RemoteImageInfo"/>s.
/// </summary>
/// <param name="images">The input images.</param>
/// <param name="requestLanguage">The requested language.</param>
- /// <param name="results">The collection to add the remote images into.</param>
- public void ConvertBackdropsToRemoteImageInfo(List<ImageData> images, string requestLanguage, List<RemoteImageInfo> results)
- {
- ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.BackdropSize, ImageType.Backdrop, requestLanguage, results);
- }
+ /// <returns>The remote images.</returns>
+ public IEnumerable<RemoteImageInfo> ConvertBackdropsToRemoteImageInfo(IReadOnlyList<ImageData> images, string requestLanguage)
+ => ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.BackdropSize, ImageType.Backdrop, requestLanguage);
/// <summary>
/// Converts logo <see cref="ImageData"/>s into <see cref="RemoteImageInfo"/>s.
/// </summary>
/// <param name="images">The input images.</param>
/// <param name="requestLanguage">The requested language.</param>
- /// <param name="results">The collection to add the remote images into.</param>
- public void ConvertLogosToRemoteImageInfo(List<ImageData> images, string requestLanguage, List<RemoteImageInfo> results)
- {
- ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.LogoSize, ImageType.Logo, requestLanguage, results);
- }
+ /// <returns>The remote images.</returns>
+ public IEnumerable<RemoteImageInfo> ConvertLogosToRemoteImageInfo(IReadOnlyList<ImageData> images, string requestLanguage)
+ => ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.LogoSize, ImageType.Logo, requestLanguage);
/// <summary>
/// Converts profile <see cref="ImageData"/>s into <see cref="RemoteImageInfo"/>s.
/// </summary>
/// <param name="images">The input images.</param>
/// <param name="requestLanguage">The requested language.</param>
- /// <param name="results">The collection to add the remote images into.</param>
- public void ConvertProfilesToRemoteImageInfo(List<ImageData> images, string requestLanguage, List<RemoteImageInfo> results)
- {
- ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.ProfileSize, ImageType.Primary, requestLanguage, results);
- }
+ /// <returns>The remote images.</returns>
+ public IEnumerable<RemoteImageInfo> ConvertProfilesToRemoteImageInfo(IReadOnlyList<ImageData> images, string requestLanguage)
+ => ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.ProfileSize, ImageType.Primary, requestLanguage);
/// <summary>
/// Converts still <see cref="ImageData"/>s into <see cref="RemoteImageInfo"/>s.
/// </summary>
/// <param name="images">The input images.</param>
/// <param name="requestLanguage">The requested language.</param>
- /// <param name="results">The collection to add the remote images into.</param>
- public void ConvertStillsToRemoteImageInfo(List<ImageData> images, string requestLanguage, List<RemoteImageInfo> results)
- {
- ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.StillSize, ImageType.Primary, requestLanguage, results);
- }
+ /// <returns>The remote images.</returns>
+ public IEnumerable<RemoteImageInfo> ConvertStillsToRemoteImageInfo(IReadOnlyList<ImageData> images, string requestLanguage)
+ => ConvertToRemoteImageInfo(images, Plugin.Instance.Configuration.StillSize, ImageType.Primary, requestLanguage);
/// <summary>
/// Converts <see cref="ImageData"/>s into <see cref="RemoteImageInfo"/>s.
@@ -588,8 +576,8 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// <param name="size">The size of the image to fetch.</param>
/// <param name="type">The type of the image.</param>
/// <param name="requestLanguage">The requested language.</param>
- /// <param name="results">The collection to add the remote images into.</param>
- private void ConvertToRemoteImageInfo(List<ImageData> images, string size, ImageType type, string requestLanguage, List<RemoteImageInfo> results)
+ /// <returns>The remote images.</returns>
+ private IEnumerable<RemoteImageInfo> ConvertToRemoteImageInfo(IReadOnlyList<ImageData> images, string? size, ImageType type, string requestLanguage)
{
// sizes provided are for original resolution, don't store them when downloading scaled images
var scaleImage = !string.Equals(size, "original", StringComparison.OrdinalIgnoreCase);
@@ -598,7 +586,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
{
var image = images[i];
- results.Add(new RemoteImageInfo
+ yield return new RemoteImageInfo
{
Url = GetUrl(size, image.FilePath),
CommunityRating = image.VoteAverage,
@@ -609,7 +597,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
ProviderName = TmdbUtils.ProviderName,
Type = type,
RatingType = RatingType.Score
- });
+ };
}
}
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs b/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs
index 685eb222f..516eee758 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
+using Jellyfin.Data.Enums;
using MediaBrowser.Model.Entities;
using TMDbLib.Objects.General;
@@ -14,7 +16,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
private static readonly Regex _nonWords = new(@"[\W_]+", RegexOptions.Compiled);
/// <summary>
- /// URL of the TMDB instance to use.
+ /// URL of the TMDb instance to use.
/// </summary>
public const string BaseTmdbUrl = "https://www.themoviedb.org/";
@@ -39,6 +41,16 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
};
/// <summary>
+ /// The crew kinds to keep.
+ /// </summary>
+ public static readonly PersonKind[] WantedCrewKinds =
+ {
+ PersonKind.Director,
+ PersonKind.Writer,
+ PersonKind.Producer
+ };
+
+ /// <summary>
/// Cleans the name according to TMDb requirements.
/// </summary>
/// <param name="name">The name of the entity.</param>
@@ -50,30 +62,30 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
}
/// <summary>
- /// Maps the TMDB provided roles for crew members to Jellyfin roles.
+ /// Maps the TMDb provided roles for crew members to Jellyfin roles.
/// </summary>
/// <param name="crew">Crew member to map against the Jellyfin person types.</param>
/// <returns>The Jellyfin person type.</returns>
- public static string MapCrewToPersonType(Crew crew)
+ public static PersonKind MapCrewToPersonType(Crew crew)
{
if (crew.Department.Equals("production", StringComparison.OrdinalIgnoreCase)
&& crew.Job.Contains("director", StringComparison.OrdinalIgnoreCase))
{
- return PersonType.Director;
+ return PersonKind.Director;
}
if (crew.Department.Equals("production", StringComparison.OrdinalIgnoreCase)
&& crew.Job.Contains("producer", StringComparison.OrdinalIgnoreCase))
{
- return PersonType.Producer;
+ return PersonKind.Producer;
}
if (crew.Department.Equals("writing", StringComparison.OrdinalIgnoreCase))
{
- return PersonType.Writer;
+ return PersonKind.Writer;
}
- return string.Empty;
+ return PersonKind.Unknown;
}
/// <summary>
@@ -103,9 +115,9 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
languages.Add(preferredLanguage);
- if (preferredLanguage.Length == 5) // like en-US
+ if (preferredLanguage.Length == 5) // Like en-US
{
- // Currently, TMDB supports 2-letter language codes only
+ // Currently, TMDb supports 2-letter language codes only.
// They are planning to change this in the future, thus we're
// supplying both codes if we're having a 5-letter code.
languages.Add(preferredLanguage.Substring(0, 2));
@@ -114,6 +126,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
languages.Add("null");
+ // Always add English as fallback language
if (!string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase))
{
languages.Add("en");
@@ -127,21 +140,22 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
/// </summary>
/// <param name="language">The language code.</param>
/// <returns>The normalized language code.</returns>
- public static string NormalizeLanguage(string language)
+ [return: NotNullIfNotNull(nameof(language))]
+ public static string? NormalizeLanguage(string? language)
{
if (string.IsNullOrEmpty(language))
{
return language;
}
- // They require this to be uppercase
- // Everything after the hyphen must be written in uppercase due to a way TMDB wrote their api.
+ // TMDb requires this to be uppercase
+ // Everything after the hyphen must be written in uppercase due to a way TMDb wrote their API.
// See here: https://www.themoviedb.org/talk/5119221d760ee36c642af4ad?page=3#56e372a0c3a3685a9e0019ab
var parts = language.Split('-');
if (parts.Length == 2)
{
- // TMDB doesn't support Switzerland (de-CH, it-CH or fr-CH) so use the language (de, it or fr) without country code
+ // TMDb doesn't support Switzerland (de-CH, it-CH or fr-CH) so use the language (de, it or fr) without country code
if (string.Equals(parts[1], "CH", StringComparison.OrdinalIgnoreCase))
{
return parts[0];
@@ -174,14 +188,14 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
}
/// <summary>
- /// Combines the metadata country code and the parental rating from the Api into the value we store in our database.
+ /// Combines the metadata country code and the parental rating from the API into the value we store in our database.
/// </summary>
- /// <param name="countryCode">The Iso 3166-1 country code of the rating country.</param>
- /// <param name="ratingValue">The rating value returned by the Tmdb Api.</param>
+ /// <param name="countryCode">The ISO 3166-1 country code of the rating country.</param>
+ /// <param name="ratingValue">The rating value returned by the TMDb API.</param>
/// <returns>The combined parental rating of country code+rating value.</returns>
public static string BuildParentalRating(string countryCode, string ratingValue)
{
- // exclude US because we store us values as TV-14 without the country code.
+ // Exclude US because we store US values as TV-14 without the country code.
var ratingPrefix = string.Equals(countryCode, "US", StringComparison.OrdinalIgnoreCase) ? string.Empty : countryCode + "-";
var newRating = ratingPrefix + ratingValue;