diff options
Diffstat (limited to 'MediaBrowser.Providers/Plugins')
9 files changed, 279 insertions, 83 deletions
diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs index ff30af879..49ece22a9 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs @@ -94,7 +94,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb if (!string.IsNullOrWhiteSpace(result.strArtist)) { - item.AlbumArtists = new string[] { result.strArtist }; + item.AlbumArtists = [result.strArtist]; } if (!string.IsNullOrEmpty(result.intYearReleased)) @@ -104,7 +104,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb if (!string.IsNullOrEmpty(result.strGenre)) { - item.Genres = new[] { result.strGenre }; + item.Genres = [result.strGenre]; } item.SetProviderId(MetadataProvider.AudioDbArtist, result.idArtist); @@ -170,6 +170,11 @@ namespace MediaBrowser.Providers.Plugins.AudioDb var url = AudioDbArtistProvider.BaseUrl + "/album-mb.php?i=" + musicBrainzReleaseGroupId; var path = GetAlbumInfoPath(_config.ApplicationPaths, musicBrainzReleaseGroupId); + var fileInfo = _fileSystem.GetFileSystemInfo(path); + if (fileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2) + { + return; + } Directory.CreateDirectory(Path.GetDirectoryName(path)); diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Configuration/PluginConfiguration.cs b/MediaBrowser.Providers/Plugins/Tmdb/Configuration/PluginConfiguration.cs index 99b759ae2..f11b1d95a 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Configuration/PluginConfiguration.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/Configuration/PluginConfiguration.cs @@ -39,6 +39,21 @@ namespace MediaBrowser.Providers.Plugins.Tmdb public int MaxCastMembers { get; set; } = 15; /// <summary> + /// Gets or sets a value indicating the maximum number of crew members to fetch for an item. + /// </summary> + public int MaxCrewMembers { get; set; } = 15; + + /// <summary> + /// Gets or sets a value indicating whether to hide cast members without profile images. + /// </summary> + public bool HideMissingCastMembers { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether to hide crew members without profile images. + /// </summary> + public bool HideMissingCrewMembers { get; set; } + + /// <summary> /// Gets or sets a value indicating the poster image size to fetch. /// </summary> public string? PosterSize { get; set; } diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Configuration/config.html b/MediaBrowser.Providers/Plugins/Tmdb/Configuration/config.html index f3c24e7b4..89d380ec1 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Configuration/config.html +++ b/MediaBrowser.Providers/Plugins/Tmdb/Configuration/config.html @@ -25,9 +25,24 @@ <input is="emby-checkbox" type="checkbox" id="importSeasonName" /> <span>Import season name from metadata fetched for series.</span> </label> - <div class="inputContainer"> - <input is="emby-input" type="number" id="maxCastMembers" pattern="[0-9]*" required min="0" max="1000" label="Max Cast Members" /> - <div class="fieldDescription">The maximum number of cast members to fetch for an item.</div> + <div class="verticalSection"> + <h2>Cast & Crew Settings</h2> + <div class="inputContainer"> + <input is="emby-input" type="number" id="maxCastMembers" pattern="[0-9]*" required min="0" max="1000" label="Max Cast Members" /> + <div class="fieldDescription">The maximum number of cast members to fetch for an item.</div> + </div> + <div class="inputContainer"> + <input is="emby-input" type="number" id="maxCrewMembers" pattern="[0-9]*" required min="0" max="1000" label="Max Crew Members" /> + <div class="fieldDescription">The maximum number of crew members to fetch for an item.</div> + </div> + <label class="checkboxContainer"> + <input is="emby-checkbox" type="checkbox" id="hideMissingCastMembers" /> + <span>Hide cast members without profile images.</span> + </label> + <label class="checkboxContainer"> + <input is="emby-checkbox" type="checkbox" id="hideMissingCrewMembers" /> + <span>Hide crew members without profile images.</span> + </label> </div> <div class="verticalSection verticalSection-extrabottompadding"> <h2>Image Scaling</h2> @@ -129,6 +144,8 @@ document.querySelector('#excludeTagsSeries').checked = config.ExcludeTagsSeries; document.querySelector('#excludeTagsMovies').checked = config.ExcludeTagsMovies; document.querySelector('#importSeasonName').checked = config.ImportSeasonName; + document.querySelector('#hideMissingCastMembers').checked = config.HideMissingCastMembers; + document.querySelector('#hideMissingCrewMembers').checked = config.HideMissingCrewMembers; var maxCastMembers = document.querySelector('#maxCastMembers'); maxCastMembers.value = config.MaxCastMembers; @@ -137,12 +154,18 @@ cancelable: false })); + var maxCrewMembers = document.querySelector('#maxCrewMembers'); + maxCrewMembers.value = config.MaxCrewMembers; + maxCrewMembers.dispatchEvent(new Event('change', { + bubbles: true, + cancelable: false + })); + pluginConfig = config; configureImageScaling(); }); }); - document.querySelector('.configForm') .addEventListener('submit', function (e) { Dashboard.showLoadingMsg(); @@ -153,6 +176,9 @@ config.ExcludeTagsMovies = document.querySelector('#excludeTagsMovies').checked; config.ImportSeasonName = document.querySelector('#importSeasonName').checked; config.MaxCastMembers = document.querySelector('#maxCastMembers').value; + config.MaxCrewMembers = document.querySelector('#maxCrewMembers').value; + config.HideMissingCastMembers = document.querySelector('#hideMissingCastMembers').checked; + config.HideMissingCrewMembers = document.querySelector('#hideMissingCrewMembers').checked; config.PosterSize = document.querySelector('#selectPosterSize').value; config.BackdropSize = document.querySelector('#selectBackdropSize').value; config.LogoSize = document.querySelector('#selectLogoSize').value; diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs index 9bb6507fe..2f8cb68ef 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs @@ -144,6 +144,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies { var tmdbId = info.GetProviderId(MetadataProvider.Tmdb); var imdbId = info.GetProviderId(MetadataProvider.Imdb); + var config = Plugin.Instance.Configuration; if (string.IsNullOrEmpty(tmdbId) && string.IsNullOrEmpty(imdbId)) { @@ -249,12 +250,26 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies if (movieResult.Credits?.Cast is not null) { - foreach (var actor in movieResult.Credits.Cast.OrderBy(a => a.Order).Take(Plugin.Instance.Configuration.MaxCastMembers)) + var castQuery = movieResult.Credits.Cast.AsEnumerable(); + + if (config.HideMissingCastMembers) { + castQuery = castQuery.Where(a => !string.IsNullOrEmpty(a.ProfilePath)); + } + + castQuery = castQuery.OrderBy(a => a.Order).Take(config.MaxCastMembers); + + foreach (var actor in castQuery) + { + if (string.IsNullOrWhiteSpace(actor.Name)) + { + continue; + } + var personInfo = new PersonInfo { Name = actor.Name.Trim(), - Role = actor.Character.Trim(), + Role = actor.Character?.Trim() ?? string.Empty, Type = PersonKind.Actor, SortOrder = actor.Order }; @@ -275,32 +290,47 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies if (movieResult.Credits?.Crew is not null) { - foreach (var person in movieResult.Credits.Crew) + var crewQuery = movieResult.Credits.Crew + .Select(crewMember => new + { + CrewMember = crewMember, + PersonType = TmdbUtils.MapCrewToPersonType(crewMember) + }) + .Where(entry => + TmdbUtils.WantedCrewKinds.Contains(entry.PersonType) || + TmdbUtils.WantedCrewTypes.Contains(entry.CrewMember.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase)); + + if (config.HideMissingCrewMembers) + { + crewQuery = crewQuery.Where(entry => !string.IsNullOrEmpty(entry.CrewMember.ProfilePath)); + } + + crewQuery = crewQuery.Take(config.MaxCrewMembers); + + foreach (var entry in crewQuery) { - // Normalize this - var type = TmdbUtils.MapCrewToPersonType(person); + var crewMember = entry.CrewMember; - if (!TmdbUtils.WantedCrewKinds.Contains(type) - && !TmdbUtils.WantedCrewTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase)) + if (string.IsNullOrWhiteSpace(crewMember.Name)) { continue; } var personInfo = new PersonInfo { - Name = person.Name.Trim(), - Role = person.Job?.Trim(), - Type = type + Name = crewMember.Name.Trim(), + Role = crewMember.Job?.Trim() ?? string.Empty, + Type = entry.PersonType }; - if (!string.IsNullOrWhiteSpace(person.ProfilePath)) + if (!string.IsNullOrWhiteSpace(crewMember.ProfilePath)) { - personInfo.ImageUrl = _tmdbClientManager.GetProfileUrl(person.ProfilePath); + personInfo.ImageUrl = _tmdbClientManager.GetProfileUrl(crewMember.ProfilePath); } - if (person.Id > 0) + if (crewMember.Id > 0) { - personInfo.SetProviderId(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture)); + personInfo.SetProviderId(MetadataProvider.Tmdb, crewMember.Id.ToString(CultureInfo.InvariantCulture)); } metadataResult.AddPerson(personInfo); diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs index 73c3b4f16..7d0900cfd 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs @@ -81,6 +81,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken) { var metadataResult = new MetadataResult<Episode>(); + var config = Plugin.Instance.Configuration; // Allowing this will dramatically increase scan times if (info.IsMissingEpisode) @@ -206,52 +207,106 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV if (credits?.Cast is not null) { - foreach (var actor in credits.Cast.OrderBy(a => a.Order).Take(Plugin.Instance.Configuration.MaxCastMembers)) + var castQuery = config.HideMissingCastMembers + ? credits.Cast.Where(a => !string.IsNullOrEmpty(a.ProfilePath)).OrderBy(a => a.Order) + : credits.Cast.OrderBy(a => a.Order); + + foreach (var actor in castQuery.Take(config.MaxCastMembers)) { - metadataResult.AddPerson(new PersonInfo + if (string.IsNullOrWhiteSpace(actor.Name)) + { + continue; + } + + var personInfo = new PersonInfo { Name = actor.Name.Trim(), - Role = actor.Character.Trim(), + Role = actor.Character?.Trim() ?? string.Empty, Type = PersonKind.Actor, - SortOrder = actor.Order - }); + SortOrder = actor.Order, + ImageUrl = _tmdbClientManager.GetProfileUrl(actor.ProfilePath) + }; + + if (actor.Id > 0) + { + personInfo.SetProviderId(MetadataProvider.Tmdb, actor.Id.ToString(CultureInfo.InvariantCulture)); + } + + metadataResult.AddPerson(personInfo); } } if (credits?.GuestStars is not null) { - foreach (var guest in credits.GuestStars.OrderBy(a => a.Order).Take(Plugin.Instance.Configuration.MaxCastMembers)) + var guestQuery = config.HideMissingCastMembers + ? credits.GuestStars.Where(a => !string.IsNullOrEmpty(a.ProfilePath)).OrderBy(a => a.Order) + : credits.GuestStars.OrderBy(a => a.Order); + + foreach (var guest in guestQuery.Take(config.MaxCastMembers)) { - metadataResult.AddPerson(new PersonInfo + if (string.IsNullOrWhiteSpace(guest.Name)) + { + continue; + } + + var personInfo = new PersonInfo { Name = guest.Name.Trim(), - Role = guest.Character.Trim(), + Role = guest.Character?.Trim() ?? string.Empty, Type = PersonKind.GuestStar, - SortOrder = guest.Order - }); + SortOrder = guest.Order, + ImageUrl = _tmdbClientManager.GetProfileUrl(guest.ProfilePath) + }; + + if (guest.Id > 0) + { + personInfo.SetProviderId(MetadataProvider.Tmdb, guest.Id.ToString(CultureInfo.InvariantCulture)); + } + + metadataResult.AddPerson(personInfo); } } - // and the rest from crew if (credits?.Crew is not null) { - foreach (var person in credits.Crew) + var crewQuery = credits.Crew + .Select(crewMember => new + { + CrewMember = crewMember, + PersonType = TmdbUtils.MapCrewToPersonType(crewMember) + }) + .Where(entry => + TmdbUtils.WantedCrewKinds.Contains(entry.PersonType) || + TmdbUtils.WantedCrewTypes.Contains(entry.CrewMember.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase)); + + if (config.HideMissingCrewMembers) + { + crewQuery = crewQuery.Where(entry => !string.IsNullOrEmpty(entry.CrewMember.ProfilePath)); + } + + foreach (var entry in crewQuery.Take(config.MaxCrewMembers)) { - // Normalize this - var type = TmdbUtils.MapCrewToPersonType(person); + var crewMember = entry.CrewMember; - if (!TmdbUtils.WantedCrewKinds.Contains(type) - && !TmdbUtils.WantedCrewTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase)) + if (string.IsNullOrWhiteSpace(crewMember.Name)) { continue; } - metadataResult.AddPerson(new PersonInfo + var personInfo = new PersonInfo { - Name = person.Name.Trim(), - Role = person.Job?.Trim(), - Type = type - }); + Name = crewMember.Name.Trim(), + Role = crewMember.Job?.Trim() ?? string.Empty, + Type = entry.PersonType, + ImageUrl = _tmdbClientManager.GetProfileUrl(crewMember.ProfilePath) + }; + + if (crewMember.Id > 0) + { + personInfo.SetProviderId(MetadataProvider.Tmdb, crewMember.Id.ToString(CultureInfo.InvariantCulture)); + } + + metadataResult.AddPerson(personInfo); } } diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs index b0a1e00df..cfef0d656 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs @@ -42,6 +42,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV public async Task<MetadataResult<Season>> GetMetadata(SeasonInfo info, CancellationToken cancellationToken) { var result = new MetadataResult<Season>(); + var config = Plugin.Instance.Configuration; info.SeriesProviderIds.TryGetValue(MetadataProvider.Tmdb.ToString(), out string? seriesTmdbId); @@ -65,10 +66,12 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV result.Item = new Season { IndexNumber = seasonNumber, - Overview = seasonResult.Overview + Overview = seasonResult.Overview, + PremiereDate = seasonResult.AirDate, + ProductionYear = seasonResult.AirDate?.Year }; - if (Plugin.Instance.Configuration.ImportSeasonName) + if (config.ImportSeasonName) { result.Item.Name = seasonResult.Name; } @@ -77,47 +80,81 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV // TODO why was this disabled? var credits = seasonResult.Credits; + 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++) + var castQuery = config.HideMissingCastMembers + ? credits.Cast.Where(a => !string.IsNullOrEmpty(a.ProfilePath)).OrderBy(a => a.Order) + : credits.Cast.OrderBy(a => a.Order); + + foreach (var actor in castQuery.Take(config.MaxCastMembers)) { - var member = cast[i]; - result.AddPerson(new PersonInfo + if (string.IsNullOrWhiteSpace(actor.Name)) + { + continue; + } + + var personInfo = new PersonInfo { - Name = member.Name.Trim(), - Role = member.Character.Trim(), + Name = actor.Name.Trim(), + Role = actor.Character?.Trim() ?? string.Empty, Type = PersonKind.Actor, - SortOrder = member.Order - }); + SortOrder = actor.Order, + ImageUrl = _tmdbClientManager.GetProfileUrl(actor.ProfilePath) + }; + + if (actor.Id > 0) + { + personInfo.SetProviderId(MetadataProvider.Tmdb, actor.Id.ToString(CultureInfo.InvariantCulture)); + } + + result.AddPerson(personInfo); } } if (credits?.Crew is not null) { - foreach (var person in credits.Crew) + var crewQuery = credits.Crew + .Select(crewMember => new + { + CrewMember = crewMember, + PersonType = TmdbUtils.MapCrewToPersonType(crewMember) + }) + .Where(entry => + TmdbUtils.WantedCrewKinds.Contains(entry.PersonType) || + TmdbUtils.WantedCrewTypes.Contains(entry.CrewMember.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase)); + + if (config.HideMissingCrewMembers) { - // Normalize this - var type = TmdbUtils.MapCrewToPersonType(person); + crewQuery = crewQuery.Where(entry => !string.IsNullOrEmpty(entry.CrewMember.ProfilePath)); + } - if (!TmdbUtils.WantedCrewKinds.Contains(type) - && !TmdbUtils.WantedCrewTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase)) + foreach (var entry in crewQuery.Take(config.MaxCrewMembers)) + { + var crewMember = entry.CrewMember; + + if (string.IsNullOrWhiteSpace(crewMember.Name)) { continue; } - result.AddPerson(new PersonInfo + var personInfo = new PersonInfo { - Name = person.Name.Trim(), - Role = person.Job?.Trim(), - Type = type - }); + Name = crewMember.Name.Trim(), + Role = crewMember.Job?.Trim() ?? string.Empty, + Type = entry.PersonType, + ImageUrl = _tmdbClientManager.GetProfileUrl(crewMember.ProfilePath) + }; + + if (crewMember.Id > 0) + { + personInfo.SetProviderId(MetadataProvider.Tmdb, crewMember.Id.ToString(CultureInfo.InvariantCulture)); + } + + result.AddPerson(personInfo); } } - result.Item.PremiereDate = seasonResult.AirDate; - result.Item.ProductionYear = seasonResult.AirDate?.Year; - return result; } diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs index 9ace9c674..8791712c7 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs @@ -323,17 +323,31 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV private IEnumerable<PersonInfo> GetPersons(TvShow seriesResult) { + var config = Plugin.Instance.Configuration; + if (seriesResult.Credits?.Cast is not null) { - foreach (var actor in seriesResult.Credits.Cast.OrderBy(a => a.Order).Take(Plugin.Instance.Configuration.MaxCastMembers)) + IEnumerable<Cast> castQuery = seriesResult.Credits.Cast.OrderBy(a => a.Order); + + if (config.HideMissingCastMembers) + { + castQuery = castQuery.Where(a => !string.IsNullOrEmpty(a.ProfilePath)); + } + + foreach (var actor in castQuery.Take(config.MaxCastMembers)) { + if (string.IsNullOrWhiteSpace(actor.Name)) + { + continue; + } + var personInfo = new PersonInfo { Name = actor.Name.Trim(), - Role = actor.Character.Trim(), + Role = actor.Character?.Trim() ?? string.Empty, Type = PersonKind.Actor, SortOrder = actor.Order, - ImageUrl = _tmdbClientManager.GetPosterUrl(actor.ProfilePath) + ImageUrl = _tmdbClientManager.GetProfileUrl(actor.ProfilePath) }; if (actor.Id > 0) @@ -347,30 +361,44 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV if (seriesResult.Credits?.Crew is not null) { - var keepTypes = new[] + var crewQuery = seriesResult.Credits.Crew + .Select(crewMember => new + { + CrewMember = crewMember, + PersonType = TmdbUtils.MapCrewToPersonType(crewMember) + }) + .Where(entry => + TmdbUtils.WantedCrewKinds.Contains(entry.PersonType) || + TmdbUtils.WantedCrewTypes.Contains(entry.CrewMember.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase)); + + if (config.HideMissingCrewMembers) { - PersonType.Director, - PersonType.Writer, - PersonType.Producer - }; + crewQuery = crewQuery.Where(entry => !string.IsNullOrEmpty(entry.CrewMember.ProfilePath)); + } - foreach (var person in seriesResult.Credits.Crew) + foreach (var entry in crewQuery.Take(config.MaxCrewMembers)) { - // Normalize this - var type = TmdbUtils.MapCrewToPersonType(person); + var crewMember = entry.CrewMember; - if (!TmdbUtils.WantedCrewKinds.Contains(type) - && !TmdbUtils.WantedCrewTypes.Contains(person.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase)) + if (string.IsNullOrWhiteSpace(crewMember.Name)) { continue; } - yield return new PersonInfo + var personInfo = new PersonInfo { - Name = person.Name.Trim(), - Role = person.Job?.Trim(), - Type = type + Name = crewMember.Name.Trim(), + Role = crewMember.Job?.Trim() ?? string.Empty, + Type = entry.PersonType, + ImageUrl = _tmdbClientManager.GetProfileUrl(crewMember.ProfilePath) }; + + if (crewMember.Id > 0) + { + personInfo.SetProviderId(MetadataProvider.Tmdb, crewMember.Id.ToString(CultureInfo.InvariantCulture)); + } + + yield return personInfo; } } } diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs b/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs index 4916a95d9..767004c9e 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs @@ -374,7 +374,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb /// <returns>The TMDb tv show information.</returns> public async Task<IReadOnlyList<SearchTv>> SearchSeriesAsync(string name, string language, int year = 0, CancellationToken cancellationToken = default) { - var key = $"searchseries-{name}-{language}"; + var key = $"searchseries-{name}-{year.ToString(CultureInfo.InvariantCulture)}-{language}"; if (_memoryCache.TryGetValue(key, out SearchContainer<SearchTv>? series) && series is not null) { return series.Results; diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs b/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs index a7c93ac4c..afbada3b3 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb PersonKind.Producer }; - [GeneratedRegex(@"[\W_]+")] + [GeneratedRegex(@"[\W_-[ยท]]+")] private static partial Regex NonWordRegex(); /// <summary> |
