Add tmdb search toggle config

This commit is contained in:
cxfksword 2022-10-28 11:54:04 +08:00
parent 0effb688f5
commit 49b1a2f498
13 changed files with 147 additions and 95 deletions

View File

@ -94,7 +94,7 @@ namespace Jellyfin.Plugin.MetaShark.Api
private void SetDoubanCookie(CookieContainer cookieContainer)
{
var configCookie = Plugin.Instance?.Configuration.DoubanCookies.Trim() ?? string.Empty;
var configCookie = Plugin.Instance!.Configuration.DoubanCookies.Trim();
if (string.IsNullOrEmpty(configCookie))
{
return;

View File

@ -35,8 +35,7 @@ namespace Jellyfin.Plugin.MetaShark.Api
{
_logger = loggerFactory.CreateLogger<TmdbApi>();
_memoryCache = new MemoryCache(new MemoryCacheOptions());
var config = Plugin.Instance?.Configuration ?? new PluginConfiguration();
var apiKey = string.IsNullOrEmpty(config.TmdbApiKey) ? DEFAULT_API_KEY : config.TmdbApiKey;
var apiKey = string.IsNullOrEmpty(Plugin.Instance!.Configuration.TmdbApiKey) ? DEFAULT_API_KEY : Plugin.Instance!.Configuration.TmdbApiKey;
_tmDbClient = new TMDbClient(apiKey);
_tmDbClient.RequestTimeout = TimeSpan.FromSeconds(10);
// Not really interested in NotFoundException
@ -676,7 +675,7 @@ namespace Jellyfin.Plugin.MetaShark.Api
private bool IsEnable()
{
return Plugin.Instance?.Configuration.EnableTmdb ?? true;
return Plugin.Instance!.Configuration.EnableTmdb;
}
}

View File

@ -30,6 +30,9 @@ public class PluginConfiguration : BasePluginConfiguration
public string Pattern { get; set; } = @"(S\d{2}|E\d{2}|HDR|\d{3,4}p|WEBRip|WEB|YIFY|BrRip|BluRay|H265|H264|x264|AAC\.\d\.\d|AAC|HDTV|mkv|mp4)|(\[.*\])|(\-\w+|\{.*\}|【.*】|\(.*\)|\d+MB)|(\.|\-)";
public bool EnableTmdb { get; set; } = true;
public bool EnableTmdbSearch { get; set; } = false;
public string TmdbApiKey { get; set; } = string.Empty;
public string DoubanCookies { get; set; } = string.Empty;

View File

@ -34,12 +34,20 @@
<h3>TheMovieDb</h3>
</legend>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<label class="emby-checkbox-label" for="EnableTmdb">
<input id="EnableTmdb" name="EnableTmdb" type="checkbox" is="emby-checkbox" />
<span>启用从TheMovieDb获取元数据</span>
</label>
<div class="fieldDescription">勾选后会尝试从TheMovieDb获取季度和剧集元数据</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label" for="EnableTmdbSearch">
<input id="EnableTmdbSearch" name="EnableTmdbSearch" type="checkbox"
is="emby-checkbox" />
<span>显示TheMovieDb搜索结果</span>
</label>
<div class="fieldDescription">勾选后识别时会同时返回TheMovieDb搜索结果</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="TmdbApiKey">Api Key</label>
<input id="TmdbApiKey" name="TmdbApiKey" type="text" is="emby-input" />
@ -65,6 +73,7 @@
document.querySelector('#current_version').value = "v" + config.Version;
document.querySelector('#DoubanCookies').value = config.DoubanCookies;
document.querySelector('#EnableTmdb').checked = config.EnableTmdb;
document.querySelector('#EnableTmdbSearch').checked = config.EnableTmdbSearch;
document.querySelector('#TmdbApiKey').value = config.TmdbApiKey;
Dashboard.hideLoadingMsg();
});
@ -76,6 +85,7 @@
ApiClient.getPluginConfiguration(TemplateConfig.pluginUniqueId).then(function (config) {
config.DoubanCookies = document.querySelector('#DoubanCookies').value;
config.EnableTmdb = document.querySelector('#EnableTmdb').checked;
config.EnableTmdbSearch = document.querySelector('#EnableTmdbSearch').checked;
config.TmdbApiKey = document.querySelector('#TmdbApiKey').value;
ApiClient.updatePluginConfiguration(TemplateConfig.pluginUniqueId, config).then(function (result) {
Dashboard.processPluginConfigurationUpdateResult(result);

View File

@ -66,6 +66,19 @@ namespace Jellyfin.Plugin.MetaShark.Model
public List<DoubanCelebrity> Celebrities { get; set; }
public List<DoubanCelebrity> LimitDirectorCelebrities
{
get
{
// 限制导演最多返回5个
var limitCelebrities = new List<DoubanCelebrity>();
limitCelebrities.AddRange(Celebrities.Where(x => x.RoleType == MediaBrowser.Model.Entities.PersonType.Director).Take(5));
limitCelebrities.AddRange(Celebrities.Where(x => x.RoleType != MediaBrowser.Model.Entities.PersonType.Director));
return limitCelebrities;
}
}
[JsonIgnore]
public string ImgMiddle
{
@ -83,6 +96,9 @@ namespace Jellyfin.Plugin.MetaShark.Model
return this.Genre.Split("/").Select(x => x.Trim()).Where(x => !string.IsNullOrEmpty(x)).ToArray();
}
}
}
public class DoubanCelebrity

View File

@ -32,7 +32,7 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
: base(applicationPaths, xmlSerializer)
{
Instance = this;
Plugin.Instance = this;
}
/// <inheritdoc />

View File

@ -38,9 +38,6 @@ namespace Jellyfin.Plugin.MetaShark.Providers
/// </summary>
public const string TmdbProviderName = "TheMovieDb";
protected readonly Configuration.PluginConfiguration _config;
protected readonly ILogger _logger;
protected readonly IHttpClientFactory _httpClientFactory;
protected readonly DoubanApi _doubanApi;
@ -54,7 +51,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
{
get
{
return this._config.Pattern;
return Plugin.Instance!.Configuration.Pattern;
}
}
@ -66,9 +63,6 @@ namespace Jellyfin.Plugin.MetaShark.Providers
this._libraryManager = libraryManager;
this._logger = logger;
this._httpClientFactory = httpClientFactory;
this._config = Plugin.Instance == null ?
new Configuration.PluginConfiguration() :
Plugin.Instance.Configuration;
}

View File

@ -54,7 +54,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
var sid = item.GetProviderId(DoubanProviderId);
var metaSource = item.GetProviderId(Plugin.ProviderId);
this.Log($"GetImages for item: {item.Name} [metaSource]: {metaSource}");
if (!string.IsNullOrEmpty(sid) && metaSource == MetaSource.Douban)
if (metaSource != MetaSource.Tmdb && !string.IsNullOrEmpty(sid))
{
var primary = await this._doubanApi.GetMovieAsync(sid, cancellationToken);
var dropback = await GetBackdrop(sid, cancellationToken);

View File

@ -51,7 +51,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// 从douban搜索
var res = await this._doubanApi.SearchAsync(info.Name, cancellationToken).ConfigureAwait(false);
result.AddRange(res.Take(this._config.MaxSearchResult).Select(x =>
result.AddRange(res.Take(Plugin.Instance!.Configuration.MaxSearchResult).Select(x =>
{
return new RemoteSearchResult
{
@ -65,19 +65,22 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// 从tmdb搜索
var tmdbList = await _tmdbApi.SearchMovieAsync(info.Name, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
result.AddRange(tmdbList.Take(this._config.MaxSearchResult).Select(x =>
if (Plugin.Instance?.Configuration.EnableTmdbSearch ?? false)
{
return new RemoteSearchResult
var tmdbList = await _tmdbApi.SearchMovieAsync(info.Name, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
result.AddRange(tmdbList.Take(Plugin.Instance!.Configuration.MaxSearchResult).Select(x =>
{
SearchProviderName = TmdbProviderName,
ProviderIds = new Dictionary<string, string> { { MetadataProvider.Tmdb.ToString(), x.Id.ToString(CultureInfo.InvariantCulture) } },
Name = x.Title ?? x.OriginalTitle,
ImageUrl = this._tmdbApi.GetPosterUrl(x.PosterPath),
Overview = x.Overview,
ProductionYear = x.ReleaseDate?.Year,
};
}));
return new RemoteSearchResult
{
SearchProviderName = TmdbProviderName,
ProviderIds = new Dictionary<string, string> { { MetadataProvider.Tmdb.ToString(), x.Id.ToString(CultureInfo.InvariantCulture) } },
Name = x.Title ?? x.OriginalTitle,
ImageUrl = this._tmdbApi.GetPosterUrl(x.PosterPath),
Overview = x.Overview,
ProductionYear = x.ReleaseDate?.Year,
};
}));
}
return result;
}
@ -90,7 +93,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
var sid = info.GetProviderId(DoubanProviderId);
var tmdbId = info.GetProviderId(MetadataProvider.Tmdb);
var metaSource = info.GetProviderId(Plugin.ProviderId);
var metaSource = info.GetProviderId(Plugin.ProviderId); // 刷新元数据时会有值
if (string.IsNullOrEmpty(sid) && string.IsNullOrEmpty(tmdbId))
{
// 刷新元数据匹配搜索
@ -140,7 +143,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
result.Item = movie;
result.QueriedById = true;
result.HasMetadata = true;
subject.Celebrities.Take(this._config.MaxCastMembers).ToList().ForEach(c => result.AddPerson(new PersonInfo
subject.LimitDirectorCelebrities.Take(Plugin.Instance!.Configuration.MaxCastMembers).ToList().ForEach(c => result.AddPerson(new PersonInfo
{
Name = c.Name,
Type = c.RoleType,
@ -217,7 +220,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// 演员
if (item.Credits?.Cast != null)
{
foreach (var actor in item.Credits.Cast.OrderBy(a => a.Order).Take(this._config.MaxCastMembers))
foreach (var actor in item.Credits.Cast.OrderBy(a => a.Order).Take(Plugin.Instance!.Configuration.MaxCastMembers))
{
var personInfo = new PersonInfo
{

View File

@ -58,7 +58,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// get image from douban
var sid = item.GetProviderId(DoubanProviderId);
if (metaSource == MetaSource.Douban && !string.IsNullOrEmpty(sid))
if (metaSource != MetaSource.Tmdb && !string.IsNullOrEmpty(sid))
{
var primary = await this._doubanApi.GetMovieAsync(sid, cancellationToken).ConfigureAwait(false);
if (primary == null)

View File

@ -19,6 +19,7 @@ using System.Threading;
using System.Threading.Tasks;
using TMDbLib.Objects.Find;
using TMDbLib.Objects.TvShows;
using System.Text.RegularExpressions;
namespace Jellyfin.Plugin.MetaShark.Providers
{
@ -26,31 +27,12 @@ namespace Jellyfin.Plugin.MetaShark.Providers
{
public SeasonProvider(IHttpClientFactory httpClientFactory, ILoggerFactory loggerFactory, ILibraryManager libraryManager, DoubanApi doubanApi, TmdbApi tmdbApi, OmdbApi omdbApi)
: base(httpClientFactory, loggerFactory.CreateLogger<SeriesProvider>(), libraryManager, doubanApi, tmdbApi, omdbApi)
: base(httpClientFactory, loggerFactory.CreateLogger<SeasonProvider>(), libraryManager, doubanApi, tmdbApi, omdbApi)
{
}
public string Name => Plugin.PluginName;
/// <summary>
/// Pattern for media name filtering
/// </summary>
private string _pattern;
public string Pattern
{
get
{
if (string.IsNullOrEmpty(_pattern))
{
return Plugin.Instance?.Configuration.Pattern;
}
return _pattern;
}
set
{
_pattern = value;
}
}
/// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(SeasonInfo info, CancellationToken cancellationToken)
@ -62,7 +44,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
/// <inheritdoc />
public async Task<MetadataResult<Season>> GetMetadata(SeasonInfo info, CancellationToken cancellationToken)
{
this.Log($"GetSeasonMetaData of [name]: {info.Name} number: {info.IndexNumber}");
var result = new MetadataResult<Season>();
info.SeriesProviderIds.TryGetValue(MetadataProvider.Tmdb.ToString(), out var seriesTmdbId);
@ -70,8 +52,9 @@ namespace Jellyfin.Plugin.MetaShark.Providers
info.SeriesProviderIds.TryGetValue(DoubanProviderId, out var sid);
var seasonNumber = info.IndexNumber;
var seasonSid = info.GetProviderId(DoubanProviderId);
this.Log($"GetSeasonMetaData of [name]: {info.Name} number: {info.IndexNumber} seriesTmdbId: {seriesTmdbId} sid: {sid} metaSource: {metaSource}");
if (metaSource == MetaSource.Douban && !string.IsNullOrEmpty(sid))
if (metaSource != MetaSource.Tmdb && !string.IsNullOrEmpty(sid))
{
// 从sereis获取正确名称季名称有时不对
var series = await this._doubanApi.GetMovieAsync(sid, cancellationToken).ConfigureAwait(false);
@ -122,7 +105,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
result.Item = movie;
result.HasMetadata = true;
subject.Celebrities.Take(this._config.MaxCastMembers).ToList().ForEach(c => result.AddPerson(new PersonInfo
subject.LimitDirectorCelebrities.Take(Plugin.Instance!.Configuration.MaxCastMembers).ToList().ForEach(c => result.AddPerson(new PersonInfo
{
Name = c.Name,
Type = c.RoleType,
@ -157,37 +140,78 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// series使用TMDB元数据来源
// tmdb季级没有对应id只通过indexNumber区分
if (string.IsNullOrWhiteSpace(seriesTmdbId) || !seasonNumber.HasValue)
if (!string.IsNullOrWhiteSpace(seriesTmdbId) && seasonNumber.HasValue)
{
var seasonResult = await this._tmdbApi
.GetSeasonAsync(seriesTmdbId.ToInt(), seasonNumber.Value, info.MetadataLanguage, null, cancellationToken)
.ConfigureAwait(false);
if (seasonResult == null)
{
this.Log($"Not found season from TMDB. {info.Name} seriesTmdbId: {seriesTmdbId} seasonNumber: {seasonNumber}");
return result;
}
result.HasMetadata = true;
result.Item = new Season
{
IndexNumber = seasonNumber,
Overview = seasonResult.Overview,
PremiereDate = seasonResult.AirDate,
ProductionYear = seasonResult.AirDate?.Year,
};
if (!string.IsNullOrEmpty(seasonResult.ExternalIds?.TvdbId))
{
result.Item.SetProviderId(MetadataProvider.Tvdb, seasonResult.ExternalIds.TvdbId);
}
foreach (var person in GetPersons(seasonResult))
{
result.AddPerson(person);
}
return result;
}
var seasonResult = await this._tmdbApi
.GetSeasonAsync(seriesTmdbId.ToInt(), seasonNumber.Value, info.MetadataLanguage, null, cancellationToken)
.ConfigureAwait(false);
if (seasonResult == null)
{
this.Log($"Not found season from TMDB. {info.Name} seriesTmdbId: {seriesTmdbId} seasonNumber: {seasonNumber}");
return result;
}
result.HasMetadata = true;
result.Item = new Season
{
IndexNumber = seasonNumber,
Overview = seasonResult.Overview,
PremiereDate = seasonResult.AirDate,
ProductionYear = seasonResult.AirDate?.Year,
};
// 季手工修正(先手工修改元数据,再刷新元数据->覆盖所有元数据),通过季名称重新搜索
// var guessName = Regex.Replace(info.Name, Pattern, " ");
// this.Log($"Try search season by name. original name: {info.Name} guess name: {guessName}");
// var guessSid = await this.GuestByDoubanAsync(info, cancellationToken).ConfigureAwait(false);
// if (!string.IsNullOrEmpty(guessSid))
// {
if (!string.IsNullOrEmpty(seasonResult.ExternalIds?.TvdbId))
{
result.Item.SetProviderId(MetadataProvider.Tvdb, seasonResult.ExternalIds.TvdbId);
}
foreach (var person in GetPersons(seasonResult))
{
result.AddPerson(person);
}
// var subject = await this._doubanApi.GetMovieAsync(guessSid, cancellationToken).ConfigureAwait(false);
// if (subject != null)
// {
// subject.Celebrities = await this._doubanApi.GetCelebritiesBySidAsync(guessSid, cancellationToken).ConfigureAwait(false);
// var movie = new Season
// {
// ProviderIds = new Dictionary<string, string> { { DoubanProviderId, subject.Sid } },
// Name = subject.Name,
// OriginalTitle = subject.OriginalName,
// CommunityRating = subject.Rating,
// Overview = subject.Intro,
// ProductionYear = subject.Year,
// Genres = subject.Genres,
// PremiereDate = subject.ScreenTime,
// IndexNumber = info.IndexNumber,
// };
// result.Item = movie;
// result.HasMetadata = true;
// subject.Celebrities.Take(Plugin.Instance!.Configuration.MaxCastMembers).ToList().ForEach(c => result.AddPerson(new PersonInfo
// {
// Name = c.Name,
// Type = c.RoleType,
// Role = c.Role,
// ImageUrl = c.Img,
// ProviderIds = new Dictionary<string, string> { { DoubanProviderId, c.Id } },
// }));
// return result;
// }
// }
return result;
}
@ -198,7 +222,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// 演员
if (item.Credits?.Cast != null)
{
foreach (var actor in item.Credits.Cast.OrderBy(a => a.Order).Take(this._config.MaxCastMembers))
foreach (var actor in item.Credits.Cast.OrderBy(a => a.Order).Take(Plugin.Instance!.Configuration.MaxCastMembers))
{
var personInfo = new PersonInfo
{

View File

@ -54,7 +54,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
var sid = item.GetProviderId(DoubanProviderId);
var metaSource = item.GetProviderId(Plugin.ProviderId);
this.Log($"GetImages for item: {item.Name} [metaSource]: {metaSource}");
if (!string.IsNullOrEmpty(sid) && metaSource == MetaSource.Douban)
if (metaSource != MetaSource.Tmdb && !string.IsNullOrEmpty(sid))
{
var primary = await this._doubanApi.GetMovieAsync(sid, cancellationToken);
var dropback = await GetBackdrop(sid, cancellationToken);

View File

@ -44,7 +44,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// 从douban搜索
var res = await this._doubanApi.SearchAsync(info.Name, cancellationToken).ConfigureAwait(false);
result.AddRange(res.Take(this._config.MaxSearchResult).Select(x =>
result.AddRange(res.Take(Plugin.Instance!.Configuration.MaxSearchResult).Select(x =>
{
return new RemoteSearchResult
{
@ -57,19 +57,22 @@ namespace Jellyfin.Plugin.MetaShark.Providers
}));
// 尝试从tmdb搜索
var tmdbList = await this._tmdbApi.SearchSeriesAsync(info.Name, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
result.AddRange(tmdbList.Take(this._config.MaxSearchResult).Select(x =>
if (Plugin.Instance?.Configuration.EnableTmdbSearch ?? false)
{
return new RemoteSearchResult
var tmdbList = await this._tmdbApi.SearchSeriesAsync(info.Name, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
result.AddRange(tmdbList.Take(Plugin.Instance!.Configuration.MaxSearchResult).Select(x =>
{
SearchProviderName = TmdbProviderName,
ProviderIds = new Dictionary<string, string> { { MetadataProvider.Tmdb.ToString(), x.Id.ToString(CultureInfo.InvariantCulture) } },
Name = x.Name ?? x.OriginalName,
ImageUrl = this._tmdbApi.GetPosterUrl(x.PosterPath),
Overview = x.Overview,
ProductionYear = x.FirstAirDate?.Year,
};
}));
return new RemoteSearchResult
{
SearchProviderName = TmdbProviderName,
ProviderIds = new Dictionary<string, string> { { MetadataProvider.Tmdb.ToString(), x.Id.ToString(CultureInfo.InvariantCulture) } },
Name = x.Name ?? x.OriginalName,
ImageUrl = this._tmdbApi.GetPosterUrl(x.PosterPath),
Overview = x.Overview,
ProductionYear = x.FirstAirDate?.Year,
};
}));
}
return result;
}
@ -82,7 +85,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
var sid = info.GetProviderId(DoubanProviderId);
var tmdbId = info.GetProviderId(MetadataProvider.Tmdb);
var metaSource = info.GetProviderId(Plugin.ProviderId);
var metaSource = info.GetProviderId(Plugin.ProviderId); // 刷新元数据时会有值
if (string.IsNullOrEmpty(sid) && string.IsNullOrEmpty(tmdbId))
{
// 刷新元数据自动匹配搜索
@ -139,7 +142,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
result.Item = item;
result.QueriedById = true;
result.HasMetadata = true;
subject.Celebrities.Take(this._config.MaxCastMembers).ToList().ForEach(c => result.AddPerson(new PersonInfo
subject.LimitDirectorCelebrities.Take(Plugin.Instance!.Configuration.MaxCastMembers).ToList().ForEach(c => result.AddPerson(new PersonInfo
{
Name = c.Name,
Type = c.RoleType,
@ -276,7 +279,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// 演员
if (seriesResult.Credits?.Cast != null)
{
foreach (var actor in seriesResult.Credits.Cast.OrderBy(a => a.Order).Take(this._config.MaxCastMembers))
foreach (var actor in seriesResult.Credits.Cast.OrderBy(a => a.Order).Take(Plugin.Instance!.Configuration.MaxCastMembers))
{
var personInfo = new PersonInfo
{