Optimize identity
This commit is contained in:
parent
1cb72f488a
commit
a754686a5a
|
@ -48,6 +48,12 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
|||
Assert.AreEqual(parseResult.Name, "Roman Holiday");
|
||||
Assert.AreEqual(parseResult.Year, 1953);
|
||||
|
||||
fileName = "【更多蓝光电影访问】红辣椒[简繁中文字幕].Paprika.2006.RERiP.1080p.BluRay.x264.DTS-WiKi";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Assert.AreEqual(parseResult.ChineseName, "红辣椒");
|
||||
Assert.AreEqual(parseResult.Name, "Paprika");
|
||||
Assert.AreEqual(parseResult.Year, 2006);
|
||||
|
||||
// 只英文
|
||||
fileName = "A.Chinese.Odyssey.Part.1.1995.BluRay.1080p.x265.10bit.2Audio-MiniHD";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
|
@ -170,6 +176,13 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
|||
Assert.AreEqual(parseResult.ParentIndexNumber, 1);
|
||||
Assert.AreEqual(parseResult.IndexNumber, 1);
|
||||
|
||||
// 只中文
|
||||
fileName = "齊天大聖 第02集";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Assert.AreEqual(parseResult.Name, "齊天大聖 第02集");
|
||||
Assert.AreEqual(parseResult.ParentIndexNumber, null);
|
||||
Assert.AreEqual(parseResult.IndexNumber, 2);
|
||||
|
||||
// anime
|
||||
fileName = "[YYDM-11FANS][THERMAE_ROMAE][02][BDRIP][720P][X264-10bit_AAC][7FF2269F]";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
|
|
|
@ -63,23 +63,43 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
|||
var httpContextAccessorStub = new Mock<IHttpContextAccessor>();
|
||||
|
||||
var provider = new SeasonProvider(httpClientFactory, loggerFactory, libraryManagerStub.Object, httpContextAccessorStub.Object, doubanApi, tmdbApi, omdbApi);
|
||||
var result = provider.GuessSeasonNumberByFileName("/data/downloads/jellyfin/tv/向往的生活/第2季");
|
||||
var result = provider.GuessSeasonNumberByDirectoryName("/data/downloads/jellyfin/tv/向往的生活/第2季");
|
||||
Assert.AreEqual(result, 2);
|
||||
|
||||
result = provider.GuessSeasonNumberByFileName("/data/downloads/jellyfin/tv/向往的生活 第2季");
|
||||
result = provider.GuessSeasonNumberByDirectoryName("/data/downloads/jellyfin/tv/向往的生活 第2季");
|
||||
Assert.AreEqual(result, 2);
|
||||
|
||||
result = provider.GuessSeasonNumberByFileName("/data/downloads/jellyfin/tv/向往的生活/第三季");
|
||||
result = provider.GuessSeasonNumberByDirectoryName("/data/downloads/jellyfin/tv/向往的生活/第三季");
|
||||
Assert.AreEqual(result, 3);
|
||||
|
||||
result = provider.GuessSeasonNumberByFileName("/data/downloads/jellyfin/tv/攻壳机动队Ghost_in_The_Shell_S.A.C._2nd_GIG");
|
||||
result = provider.GuessSeasonNumberByDirectoryName("/data/downloads/jellyfin/tv/攻壳机动队Ghost_in_The_Shell_S.A.C._2nd_GIG");
|
||||
Assert.AreEqual(result, 2);
|
||||
|
||||
result = provider.GuessSeasonNumberByFileName("/data/downloads/jellyfin/tv/Spice and Wolf/Spice and Wolf 2");
|
||||
result = provider.GuessSeasonNumberByDirectoryName("/data/downloads/jellyfin/tv/Spice and Wolf/Spice and Wolf 2");
|
||||
Assert.AreEqual(result, 2);
|
||||
|
||||
result = provider.GuessSeasonNumberByFileName("/data/downloads/jellyfin/tv/Spice and Wolf/Spice and Wolf 2 test");
|
||||
result = provider.GuessSeasonNumberByDirectoryName("/data/downloads/jellyfin/tv/Spice and Wolf/Spice and Wolf 2 test");
|
||||
Assert.AreEqual(result, null);
|
||||
|
||||
result = provider.GuessSeasonNumberByDirectoryName("/data/downloads/jellyfin/tv/[BDrip] Made in Abyss S02 [7鲁ACG x Sakurato]");
|
||||
Assert.AreEqual(result, 2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestGuestDoubanSeasonByYearAsync()
|
||||
{
|
||||
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 SeasonProvider(httpClientFactory, loggerFactory, libraryManagerStub.Object, httpContextAccessorStub.Object, doubanApi, tmdbApi, omdbApi);
|
||||
var result = await provider.GuestDoubanSeasonByYearAsync("机动战士高达0083 星尘的回忆", 1991, CancellationToken.None);
|
||||
Assert.AreEqual(result, "1766564");
|
||||
}).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace Jellyfin.Plugin.MetaShark.Api
|
|||
Regex regId = new Regex(@"/(\d+?)/", RegexOptions.Compiled);
|
||||
Regex regSid = new Regex(@"sid: (\d+?),", RegexOptions.Compiled);
|
||||
Regex regCat = new Regex(@"\[(.+?)\]", RegexOptions.Compiled);
|
||||
Regex regYear = new Regex(@"(\d{4})", RegexOptions.Compiled);
|
||||
Regex regYear = new Regex(@"([12][890][0-9][0-9])", RegexOptions.Compiled);
|
||||
Regex regTitle = new Regex(@"<title>([\w\W]+?)</title>", RegexOptions.Compiled);
|
||||
Regex regKeywordMeta = new Regex(@"<meta name=""keywords"" content=""(.+?)""", RegexOptions.Compiled);
|
||||
Regex regOriginalName = new Regex(@"原名[::](.+?)\s*?\/", RegexOptions.Compiled);
|
||||
|
|
|
@ -25,6 +25,9 @@ public enum SomeOptions
|
|||
/// </summary>
|
||||
public class PluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
public const int MAX_CAST_MEMBERS = 15;
|
||||
public const int MAX_SEARCH_RESULT = 5;
|
||||
|
||||
public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? string.Empty;
|
||||
|
||||
public string DoubanCookies { get; set; } = string.Empty;
|
||||
|
@ -55,7 +58,7 @@ public class PluginConfiguration : BasePluginConfiguration
|
|||
|
||||
public int MaxCastMembers { get; set; } = 15;
|
||||
|
||||
public int MaxSearchResult { get; set; } = 3;
|
||||
public int MaxSearchResult { get; set; } = 5;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
|||
|
||||
private static readonly Regex startWithHyphenCharReg = new Regex(@"^[-~~]", RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex chineseIndexNumberReg = new Regex(@"第([0-9零一二三四五六七八九]+?)(集|章|话|話)", RegexOptions.Compiled);
|
||||
|
||||
public static ParseNameResult Parse(string fileName, bool isTvSeries = false)
|
||||
{
|
||||
var parseResult = new ParseNameResult();
|
||||
|
@ -108,6 +110,12 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
|||
}
|
||||
}
|
||||
|
||||
// 修复纯中文集数
|
||||
if (parseResult.IndexNumber is null)
|
||||
{
|
||||
parseResult.IndexNumber = ParseChineseIndexNumber(fileName);
|
||||
}
|
||||
|
||||
// 解析不到title时,使用默认名
|
||||
if (string.IsNullOrEmpty(parseResult.Name))
|
||||
{
|
||||
|
@ -159,21 +167,36 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static int? ParseChineseIndexNumber(string fileName)
|
||||
{
|
||||
var match = chineseIndexNumberReg.Match(fileName);
|
||||
if (match.Success && match.Groups.Count > 1)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out var seasonNumber))
|
||||
{
|
||||
return seasonNumber;
|
||||
}
|
||||
|
||||
var number = Utils.ChineseNumberToInt(match.Groups[1].Value);
|
||||
if (number.HasValue)
|
||||
{
|
||||
return number;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool IsSpecialDirectory(string path)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(path) ?? string.Empty;
|
||||
if (IsAnime(fileName))
|
||||
if (IsAnime(fileName) && fileName.Contains("[SP]"))
|
||||
{
|
||||
if (fileName.Contains("[SP]"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
string folder = Path.GetFileName(Path.GetDirectoryName(path)) ?? string.Empty;
|
||||
return folder == "SPs";
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
var folder = Path.GetFileName(Path.GetDirectoryName(path)) ?? string.Empty;
|
||||
return folder == "SPs" || folder.Contains("特典");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,20 +21,29 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
|||
/// </summary>
|
||||
public static int? ChineseNumberToInt(string str)
|
||||
{
|
||||
switch (str)
|
||||
if (string.IsNullOrEmpty(str)) return null;
|
||||
|
||||
var chineseNumberMap = new Dictionary<Char, Char>() {
|
||||
{'一', '1'},
|
||||
{'二', '2'},
|
||||
{'三', '3'},
|
||||
{'四', '4'},
|
||||
{'五', '5'},
|
||||
{'六', '6'},
|
||||
{'七', '7'},
|
||||
{'八', '8'},
|
||||
{'九', '9'},
|
||||
{'零', '0'},
|
||||
};
|
||||
|
||||
var numberArr = str.ToCharArray().Select(x => chineseNumberMap.ContainsKey(x) ? chineseNumberMap[x] : x).ToArray();
|
||||
var newNumberStr = new string(numberArr);
|
||||
if (int.TryParse(new string(numberArr), out var number))
|
||||
{
|
||||
case "一": return 1;
|
||||
case "二": return 2;
|
||||
case "三": return 3;
|
||||
case "四": return 4;
|
||||
case "五": return 5;
|
||||
case "六": return 6;
|
||||
case "七": return 7;
|
||||
case "八": return 8;
|
||||
case "九": return 9;
|
||||
case "零": return 0;
|
||||
default: return null;
|
||||
return number;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
return null;
|
||||
}
|
||||
|
||||
protected async Task<string?> GuestDoubanSeasonByYearAsync(string name, int? year, CancellationToken cancellationToken)
|
||||
public async Task<string?> GuestDoubanSeasonByYearAsync(string name, int? year, CancellationToken cancellationToken)
|
||||
{
|
||||
if (year == null || year == 0)
|
||||
{
|
||||
|
@ -280,6 +280,71 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
}
|
||||
|
||||
|
||||
public int? GuessSeasonNumberByDirectoryName(string path)
|
||||
{
|
||||
// TODO: 有时series name中会带有季信息
|
||||
// 当没有season级目录时,path为空,直接返回
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var fileName = Path.GetFileName(path);
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var regSeason = new Regex(@"第([0-9零一二三四五六七八九]+?)(季|部)", RegexOptions.Compiled);
|
||||
var match = regSeason.Match(fileName);
|
||||
if (match.Success && match.Groups.Count > 1)
|
||||
{
|
||||
var seasonNumber = match.Groups[1].Value.ToInt();
|
||||
if (seasonNumber <= 0)
|
||||
{
|
||||
seasonNumber = Utils.ChineseNumberToInt(match.Groups[1].Value) ?? 0;
|
||||
}
|
||||
if (seasonNumber > 0)
|
||||
{
|
||||
this.Log($"Found season number of filename: {fileName} seasonNumber: {seasonNumber}");
|
||||
return seasonNumber;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var seasonNameMap = new Dictionary<string, int>() {
|
||||
{@"[ ._](I|1st|S01|S1)[ ._]", 1},
|
||||
{@"[ ._](II|2nd|S02|S2)[ ._]", 2},
|
||||
{@"[ ._](III|3rd|S03|S3)[ ._]", 3},
|
||||
{@"[ ._](IIII|4th|S04|S4)[ ._]", 3},
|
||||
};
|
||||
|
||||
foreach (var entry in seasonNameMap)
|
||||
{
|
||||
if (Regex.IsMatch(fileName, entry.Key))
|
||||
{
|
||||
this.Log($"Found season number of filename: {fileName} seasonNumber: {entry.Value}");
|
||||
return entry.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// // 带数字末尾的
|
||||
// match = Regex.Match(fileName, @"[ ._](\d{1,2})$");
|
||||
// if (match.Success && match.Groups.Count > 1)
|
||||
// {
|
||||
// var seasonNumber = match.Groups[1].Value.ToInt();
|
||||
// if (seasonNumber > 0)
|
||||
// {
|
||||
// this.Log($"Found season number of filename: {fileName} seasonNumber: {seasonNumber}");
|
||||
// return seasonNumber;
|
||||
// }
|
||||
// }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 浏览器来源请求,返回代理地址(no-referer对于background-image不生效),其他客户端请求,返回原始图片地址
|
||||
/// </summary>
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
var result = new MetadataResult<Episode>();
|
||||
|
||||
// 动画特典和extras处理
|
||||
var specialResult = this.HandleAnimeSpecialAndExtras(info);
|
||||
var specialResult = this.HandleAnimeExtras(info);
|
||||
if (specialResult != null)
|
||||
{
|
||||
return specialResult;
|
||||
|
@ -94,15 +94,15 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
}
|
||||
|
||||
// TODO:自动搜索匹配或识别时,判断tmdb剧集信息数目和视频是否一致,不一致不处理(现在通过IsAutomated判断不太准确)
|
||||
if (info.IsAutomated)
|
||||
{
|
||||
var videoFilesCount = this.GetVideoFileCount(Path.GetDirectoryName(info.Path));
|
||||
if (videoFilesCount > 0 && seasonResult.Episodes.Count != videoFilesCount)
|
||||
{
|
||||
this.Log("Tmdb episode number not match. Name: {0} tmdb episode count: {1} video files count: {2}", info.Name, seasonResult.Episodes.Count, videoFilesCount);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// if (info.IsAutomated)
|
||||
// {
|
||||
// var videoFilesCount = this.GetVideoFileCount(Path.GetDirectoryName(info.Path));
|
||||
// if (videoFilesCount > 0 && seasonResult.Episodes.Count != videoFilesCount)
|
||||
// {
|
||||
// this.Log("Tmdb episode number not match. Name: {0} tmdb episode count: {1} video files count: {2}", info.Name, seasonResult.Episodes.Count, videoFilesCount);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
|
||||
var episodeResult = seasonResult.Episodes[episodeNumber.Value - 1];
|
||||
|
||||
|
@ -133,6 +133,10 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新解析文件名
|
||||
/// 注意:这里修改替换ParentIndexNumber值后,会重新触发SeasonProvier的GetMetadata方法,并带上最新的季数IndexNumber
|
||||
/// </summary>
|
||||
public EpisodeInfo FixParseInfo(EpisodeInfo info)
|
||||
{
|
||||
// 使用AnitomySharp进行重新解析,解决anime识别错误
|
||||
|
@ -152,7 +156,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
{
|
||||
var episodeItem = _libraryManager.FindByPath(info.Path, false);
|
||||
var season = episodeItem != null ? ((Episode)episodeItem).Season : null;
|
||||
if (season != null && info.ParentIndexNumber != season.IndexNumber)
|
||||
if (season != null && season.IndexNumber.HasValue && info.ParentIndexNumber != season.IndexNumber)
|
||||
{
|
||||
this.Log("FixSeasonNumber: old: {0} new: {1}", info.ParentIndexNumber, season.IndexNumber);
|
||||
info.ParentIndexNumber = season.IndexNumber;
|
||||
|
@ -167,6 +171,20 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
// }
|
||||
}
|
||||
|
||||
// 从series文件夹名称猜出season number (没有季文件夹的在SeasonProvider处理不了,因为info.Path会为空,只能在这里处理)
|
||||
var seasonFolderPath = Path.GetDirectoryName(info.Path);
|
||||
if (info.ParentIndexNumber is null && seasonFolderPath != null)
|
||||
{
|
||||
info.ParentIndexNumber = this.GuessSeasonNumberByDirectoryName(seasonFolderPath);
|
||||
}
|
||||
|
||||
|
||||
// 识别特典
|
||||
if (info.ParentIndexNumber is null && NameParser.IsAnime(fileName) && (parseResult.IsSpecial || NameParser.IsSpecialDirectory(info.Path)))
|
||||
{
|
||||
info.ParentIndexNumber = 0;
|
||||
}
|
||||
|
||||
// 设为默认季数为1
|
||||
if (info.ParentIndexNumber is null)
|
||||
{
|
||||
|
@ -174,13 +192,8 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
info.ParentIndexNumber = 1;
|
||||
}
|
||||
|
||||
// 特典
|
||||
if (NameParser.IsAnime(fileName) && parseResult.IsSpecial)
|
||||
{
|
||||
info.ParentIndexNumber = 0;
|
||||
}
|
||||
|
||||
// 特典优先使用文件名
|
||||
// 特典优先使用文件名(特典除了前面特别设置,还有SXX/Season XX等默认的)
|
||||
if (info.ParentIndexNumber.HasValue && info.ParentIndexNumber == 0)
|
||||
{
|
||||
info.Name = parseResult.SpecialName == info.Name ? fileName : parseResult.SpecialName;
|
||||
|
@ -198,7 +211,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
}
|
||||
|
||||
|
||||
private MetadataResult<Episode>? HandleAnimeSpecialAndExtras(EpisodeInfo info)
|
||||
private MetadataResult<Episode>? HandleAnimeExtras(EpisodeInfo info)
|
||||
{
|
||||
// 特典或extra视频可能和正片剧集放在同一目录
|
||||
var fileName = Path.GetFileNameWithoutExtension(info.Path) ?? info.Name;
|
||||
|
@ -229,20 +242,21 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
return result;
|
||||
}
|
||||
|
||||
if (parseResult.IsSpecial || NameParser.IsSpecialDirectory(info.Path))
|
||||
{
|
||||
this.Log($"Found anime sp of [name]: {fileName}");
|
||||
var result = new MetadataResult<Episode>();
|
||||
result.HasMetadata = true;
|
||||
result.Item = new Episode
|
||||
{
|
||||
ParentIndexNumber = 0,
|
||||
IndexNumber = parseResult.IndexNumber,
|
||||
Name = parseResult.SpecialName == info.Name ? fileName : parseResult.SpecialName,
|
||||
};
|
||||
//// 特典也有剧集信息,不在这里处理
|
||||
// if (parseResult.IsSpecial || NameParser.IsSpecialDirectory(info.Path))
|
||||
// {
|
||||
// this.Log($"Found anime sp of [name]: {fileName}");
|
||||
// var result = new MetadataResult<Episode>();
|
||||
// result.HasMetadata = true;
|
||||
// result.Item = new Episode
|
||||
// {
|
||||
// ParentIndexNumber = 0,
|
||||
// IndexNumber = parseResult.IndexNumber,
|
||||
// Name = parseResult.SpecialName == info.Name ? fileName : parseResult.SpecialName,
|
||||
// };
|
||||
|
||||
return result;
|
||||
}
|
||||
// return result;
|
||||
// }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,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(Configuration.PluginConfiguration.MAX_SEARCH_RESULT).Select(x =>
|
||||
{
|
||||
return new RemoteSearchResult
|
||||
{
|
||||
|
@ -69,7 +69,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
if (this.config.EnableTmdbSearch)
|
||||
{
|
||||
var tmdbList = await _tmdbApi.SearchMovieAsync(info.Name, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
|
||||
result.AddRange(tmdbList.Take(this.config.MaxSearchResult).Select(x =>
|
||||
result.AddRange(tmdbList.Take(Configuration.PluginConfiguration.MAX_SEARCH_RESULT).Select(x =>
|
||||
{
|
||||
return new RemoteSearchResult
|
||||
{
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
|
||||
|
||||
var res = await this._doubanApi.SearchCelebrityAsync(searchInfo.Name, cancellationToken).ConfigureAwait(false);
|
||||
result.AddRange(res.Take(this.config.MaxSearchResult).Select(x =>
|
||||
result.AddRange(res.Take(Configuration.PluginConfiguration.MAX_SEARCH_RESULT).Select(x =>
|
||||
{
|
||||
return new RemoteSearchResult
|
||||
{
|
||||
|
@ -84,7 +84,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<MetadataResult<Person>?> GetMetadata(PersonLookupInfo info, CancellationToken cancellationToken)
|
||||
public async Task<MetadataResult<Person>> GetMetadata(PersonLookupInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = new MetadataResult<Person>();
|
||||
|
||||
|
|
|
@ -56,10 +56,11 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
|
||||
if (metaSource != MetaSource.Tmdb && !string.IsNullOrEmpty(sid))
|
||||
{
|
||||
// 季文件夹名称不规范,没法拿到seasonNumber,尝试从文件名猜出
|
||||
// 季文件夹名称不规范,没法拿到seasonNumber,尝试从文件夹名猜出
|
||||
// 注意:本办法没法处理没有季文件夹的/虚拟季,因为path会为空
|
||||
if (seasonNumber is null)
|
||||
{
|
||||
seasonNumber = this.GuessSeasonNumberByFileName(info.Path);
|
||||
seasonNumber = this.GuessSeasonNumberByDirectoryName(info.Path);
|
||||
}
|
||||
|
||||
// 搜索豆瓣季id
|
||||
|
@ -130,68 +131,6 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
return await this.GetMetadataByTmdb(info, seriesTmdbId, seasonNumber, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public int? GuessSeasonNumberByFileName(string path)
|
||||
{
|
||||
// 当没有season级目录时,path为空,直接返回
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: 有时series name中会带有季信息
|
||||
var fileName = Path.GetFileName(path);
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var regSeason = new Regex(@"第(.)(季|部)", RegexOptions.Compiled);
|
||||
var match = regSeason.Match(fileName);
|
||||
if (match.Success && match.Groups.Count > 1)
|
||||
{
|
||||
var seasonNumber = match.Groups[1].Value.ToInt();
|
||||
if (seasonNumber <= 0)
|
||||
{
|
||||
seasonNumber = Utils.ChineseNumberToInt(match.Groups[1].Value) ?? 0;
|
||||
}
|
||||
if (seasonNumber > 0)
|
||||
{
|
||||
this.Log($"Found season number of filename: {fileName} seasonNumber: {seasonNumber}");
|
||||
return seasonNumber;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var seasonNameMap = new Dictionary<string, int>() {
|
||||
{@"[ ._](I|1st)[ ._]", 1},
|
||||
{@"[ ._](II|2nd)[ ._]", 2},
|
||||
{@"[ ._](III|3rd)[ ._]", 3},
|
||||
{@"[ ._](IIII|4th)[ ._]", 3},
|
||||
};
|
||||
|
||||
foreach (var entry in seasonNameMap)
|
||||
{
|
||||
if (Regex.IsMatch(fileName, entry.Key))
|
||||
{
|
||||
this.Log($"Found season number of filename: {fileName} seasonNumber: {entry.Value}");
|
||||
return entry.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// 带数字末尾的
|
||||
match = Regex.Match(fileName, @"[ ._](\d{1,2})$");
|
||||
if (match.Success && match.Groups.Count > 1)
|
||||
{
|
||||
var seasonNumber = match.Groups[1].Value.ToInt();
|
||||
if (seasonNumber > 0)
|
||||
{
|
||||
this.Log($"Found season number of filename: {fileName} seasonNumber: {seasonNumber}");
|
||||
return seasonNumber;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<string?> GuessDoubanSeasonId(string? sid, string? seriesTmdbId, int? seasonNumber, ItemLookupInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
|
@ -45,7 +45,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(Configuration.PluginConfiguration.MAX_SEARCH_RESULT).Select(x =>
|
||||
{
|
||||
return new RemoteSearchResult
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
if (this.config.EnableTmdbSearch)
|
||||
{
|
||||
var tmdbList = await this._tmdbApi.SearchSeriesAsync(info.Name, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
|
||||
result.AddRange(tmdbList.Take(this.config.MaxSearchResult).Select(x =>
|
||||
result.AddRange(tmdbList.Take(Configuration.PluginConfiguration.MAX_SEARCH_RESULT).Select(x =>
|
||||
{
|
||||
return new RemoteSearchResult
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue