feat: add tmdb backdrop
This commit is contained in:
parent
194cb3471c
commit
8cb221a204
|
@ -1,13 +1,10 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||
<PackageReference Include="Moq" Version="4.18.2" />
|
||||
|
@ -15,11 +12,9 @@
|
|||
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
|
||||
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Jellyfin.Plugin.MetaShark\Jellyfin.Plugin.MetaShark.csproj">
|
||||
<ExcludeAssets></ExcludeAssets>
|
||||
<ExcludeAssets />
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,60 @@
|
|||
using Jellyfin.Plugin.MetaShark.Api;
|
||||
using Jellyfin.Plugin.MetaShark.Core;
|
||||
using Jellyfin.Plugin.MetaShark.Providers;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jellyfin.Plugin.MetaShark.Test
|
||||
{
|
||||
[TestClass]
|
||||
public class MovieImageProviderTest
|
||||
{
|
||||
|
||||
ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
|
||||
builder.AddSimpleConsole(options =>
|
||||
{
|
||||
options.IncludeScopes = true;
|
||||
options.SingleLine = true;
|
||||
options.TimestampFormat = "hh:mm:ss ";
|
||||
}));
|
||||
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void TestGetMovieImage()
|
||||
{
|
||||
var info = new MediaBrowser.Controller.Entities.Movies.Movie()
|
||||
{
|
||||
Name = "机动战士高达 逆袭的夏亚",
|
||||
PreferredMetadataLanguage = "zh",
|
||||
ProviderIds = new Dictionary<string, string> { { BaseProvider.DoubanProviderId, "1401536" }, { MetadataProvider.Tmdb.ToString(), "16157" } }
|
||||
};
|
||||
var doubanApi = new DoubanApi(loggerFactory);
|
||||
var tmdbApi = new TmdbApi(loggerFactory);
|
||||
var omdbApi = new OmdbApi(loggerFactory);
|
||||
var httpClientFactory = new DefaultHttpClientFactory();
|
||||
var libraryManagerStub = new Mock<ILibraryManager>();
|
||||
var httpContextAccessorStub = new Mock<IHttpContextAccessor>();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var provider = new MovieImageProvider(httpClientFactory, loggerFactory, libraryManagerStub.Object, httpContextAccessorStub.Object, doubanApi, tmdbApi, omdbApi);
|
||||
var result = await provider.GetImages(info, CancellationToken.None);
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
var str = result.ToJson();
|
||||
Console.WriteLine(result.ToJson());
|
||||
}).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -54,6 +54,14 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
|||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
// 只中文
|
||||
fileName = "机动战士高达 逆袭的夏亚";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
fileName = "秒速5厘米";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
|
||||
// 标题加年份
|
||||
|
@ -98,6 +106,9 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
|||
|
||||
// anime混合中日文
|
||||
fileName = "[异域-11番小队][罗马浴场 THERMAE_ROMAE][1-6+SP][BDRIP][720P][X264-10bit_AAC]";
|
||||
var anitomyResult = AnitomySharp.AnitomySharp.Parse(fileName);
|
||||
Console.WriteLine(anitomyResult.ToJson());
|
||||
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
|
@ -121,9 +132,6 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
|||
|
||||
// 只英文
|
||||
fileName = "She-Hulk.Attorney.At.Law.S01E01.1080p.WEBRip.x265-RARBG";
|
||||
var anitomyResult = AnitomySharp.AnitomySharp.Parse(fileName);
|
||||
Console.WriteLine(anitomyResult.ToJson());
|
||||
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
|
|
|
@ -79,8 +79,8 @@ namespace Jellyfin.Plugin.MetaShark.Api
|
|||
Regex regFamily = new Regex(@"家庭成员: \n(.+?)\n", RegexOptions.Compiled);
|
||||
Regex regCelebrityImdb = new Regex(@"imdb编号:\s+?(nm\d+)", RegexOptions.Compiled);
|
||||
|
||||
// 默认1秒请求1次
|
||||
private TimeLimiter _defaultTimeConstraint = TimeLimiter.GetFromMaxCountByInterval(1, TimeSpan.FromMilliseconds(1000));
|
||||
// 默认500毫秒请求1次
|
||||
private TimeLimiter _defaultTimeConstraint = TimeLimiter.GetFromMaxCountByInterval(1, TimeSpan.FromMilliseconds(500));
|
||||
// 未登录最多1分钟10次请求,不然5分钟后会被封ip
|
||||
private TimeLimiter _guestTimeConstraint = TimeLimiter.Compose(new CountByIntervalAwaitableConstraint(10, TimeSpan.FromMinutes(1)), new CountByIntervalAwaitableConstraint(1, TimeSpan.FromMilliseconds(5000)));
|
||||
// 登录后最多1分钟20次请求,不然会触发机器人检验
|
||||
|
|
|
@ -35,6 +35,8 @@ public class PluginConfiguration : BasePluginConfiguration
|
|||
|
||||
public bool EnableTmdbSearch { get; set; } = false;
|
||||
|
||||
public bool EnableTmdbBackdrop { get; set; } = false;
|
||||
|
||||
public string TmdbApiKey { get; set; } = string.Empty;
|
||||
|
||||
public string TmdbHost { get; set; } = string.Empty;
|
||||
|
|
|
@ -69,6 +69,14 @@
|
|||
</label>
|
||||
<div class="fieldDescription">勾选后,识别时会同时返回TheMovieDb搜索结果</div>
|
||||
</div>
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label class="emby-checkbox-label" for="EnableTmdbBackdrop">
|
||||
<input id="EnableTmdbBackdrop" name="EnableTmdbBackdrop" 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" />
|
||||
|
@ -104,6 +112,7 @@
|
|||
document.querySelector('#EnableDoubanAvoidRiskControl').checked = config.EnableDoubanAvoidRiskControl;
|
||||
document.querySelector('#EnableTmdb').checked = config.EnableTmdb;
|
||||
document.querySelector('#EnableTmdbSearch').checked = config.EnableTmdbSearch;
|
||||
document.querySelector('#EnableTmdbBackdrop').checked = config.EnableTmdbBackdrop;
|
||||
document.querySelector('#TmdbApiKey').value = config.TmdbApiKey;
|
||||
document.querySelector('#TmdbHost').value = config.TmdbHost;
|
||||
|
||||
|
@ -121,6 +130,7 @@
|
|||
config.EnableDoubanAvoidRiskControl = document.querySelector('#EnableDoubanAvoidRiskControl').checked;
|
||||
config.EnableTmdb = document.querySelector('#EnableTmdb').checked;
|
||||
config.EnableTmdbSearch = document.querySelector('#EnableTmdbSearch').checked;
|
||||
config.EnableTmdbBackdrop = document.querySelector('#EnableTmdbBackdrop').checked;
|
||||
config.TmdbApiKey = document.querySelector('#TmdbApiKey').value;
|
||||
config.TmdbHost = document.querySelector('#TmdbHost').value;
|
||||
ApiClient.updatePluginConfiguration(TemplateConfig.pluginUniqueId, config).then(function (result) {
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
|||
private static readonly Regex yearReg = new Regex(@"[12][890][0-9][0-9]", RegexOptions.Compiled);
|
||||
private static readonly Regex seasonSuffixReg = new Regex(@"[ .]S\d{1,2}$", RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex unusedReg = new Regex(@"\[.+?\]|\(.+?\)", RegexOptions.Compiled);
|
||||
private static readonly Regex unusedReg = new Regex(@"\[.+?\]|\(.+?\)|【.+?】", RegexOptions.Compiled);
|
||||
|
||||
public static ParseNameResult Parse(string fileName, bool isTvSeries = false)
|
||||
{
|
||||
|
@ -25,15 +25,16 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
|||
{
|
||||
case AnitomySharp.Element.ElementCategory.ElementAnimeTitle:
|
||||
// 处理混合中英文的标题,中文一般在最前面,如V字仇杀队.V.for.Vendetta
|
||||
char[] seperatorChars = { ' ', '.' };
|
||||
var firstSpaceIndex = item.Value.IndexOfAny(seperatorChars);
|
||||
char[] delimiters = { ' ', '.' };
|
||||
var firstSpaceIndex = item.Value.IndexOfAny(delimiters);
|
||||
if (firstSpaceIndex > 0)
|
||||
{
|
||||
var firstString = item.Value.Substring(0, firstSpaceIndex);
|
||||
if (firstString.HasChinese())
|
||||
var lastString = item.Value.Substring(firstSpaceIndex + 1);
|
||||
if (firstString.HasChinese() && !lastString.HasChinese())
|
||||
{
|
||||
parseResult.ChineseName = CleanName(firstString);
|
||||
parseResult.Name = CleanName(item.Value.Substring(firstSpaceIndex + 1));
|
||||
parseResult.Name = CleanName(lastString);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
{
|
||||
return Enumerable.Empty<RemoteImageInfo>();
|
||||
}
|
||||
var backdropImgs = await GetBackdrop(sid, cancellationToken);
|
||||
var backdropImgs = await GetBackdrop(item, cancellationToken);
|
||||
|
||||
var res = new List<RemoteImageInfo> {
|
||||
new RemoteImageInfo
|
||||
|
@ -139,20 +139,21 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
/// <summary>
|
||||
/// Query for a background photo
|
||||
/// </summary>
|
||||
/// <param name="sid">a subject/movie id</param>
|
||||
/// <param name="cancellationToken">Instance of the <see cref="CancellationToken"/> interface.</param>
|
||||
private async Task<IEnumerable<RemoteImageInfo>> GetBackdrop(string sid, CancellationToken cancellationToken)
|
||||
private async Task<IEnumerable<RemoteImageInfo>> GetBackdrop(BaseItem item, CancellationToken cancellationToken)
|
||||
{
|
||||
this.Log("GetBackdrop of sid: {0}", sid);
|
||||
var photo = await this._doubanApi.GetWallpaperBySidAsync(sid, cancellationToken);
|
||||
var sid = item.GetProviderId(DoubanProviderId);
|
||||
var tmdbId = item.GetProviderId(MetadataProvider.Tmdb);
|
||||
var list = new List<RemoteImageInfo>();
|
||||
|
||||
if (photo == null)
|
||||
// 从豆瓣获取背景图
|
||||
if (!string.IsNullOrEmpty(sid))
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
return photo.Where(x => x.Width > x.Height * 1.3).Select(x =>
|
||||
var photo = await this._doubanApi.GetWallpaperBySidAsync(sid, cancellationToken);
|
||||
if (photo != null && photo.Count > 0)
|
||||
{
|
||||
this.Log("GetBackdrop from douban sid: {0}", sid);
|
||||
list = photo.Where(x => x.Width > x.Height * 1.3).Select(x =>
|
||||
{
|
||||
return new RemoteImageInfo
|
||||
{
|
||||
|
@ -160,8 +161,37 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
Url = x.Large,
|
||||
Type = ImageType.Backdrop,
|
||||
};
|
||||
}).ToList();
|
||||
|
||||
}
|
||||
}
|
||||
if (list.Count > 0)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
// 从TheMovieDb获取背景图
|
||||
if (config.EnableTmdbBackdrop && !string.IsNullOrEmpty(tmdbId))
|
||||
{
|
||||
var language = item.GetPreferredMetadataLanguage();
|
||||
var movie = await _tmdbApi
|
||||
.GetMovieAsync(tmdbId.ToInt(), language, language, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (movie != null && !string.IsNullOrEmpty(movie.BackdropPath))
|
||||
{
|
||||
this.Log("GetBackdrop from tmdb id: {0}", tmdbId);
|
||||
list.Add(new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = _tmdbApi.GetBackdropUrl(movie.BackdropPath),
|
||||
Type = ImageType.Backdrop,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue