Optimize identity

This commit is contained in:
cxfksword 2023-03-05 15:53:56 +08:00
parent ebc701845a
commit 3f0ad0112d
5 changed files with 91 additions and 17 deletions

View File

@ -176,6 +176,20 @@ namespace Jellyfin.Plugin.MetaShark.Test
Assert.AreEqual(parseResult.ParentIndexNumber, 1);
Assert.AreEqual(parseResult.IndexNumber, 1);
// 日文
fileName = "プロポーズ大作戦Ep05_x264.mp4";
parseResult = NameParser.Parse(fileName);
Assert.AreEqual(parseResult.Name, "プロポーズ大作戦Ep05");
Assert.AreEqual(parseResult.ParentIndexNumber, null);
Assert.AreEqual(parseResult.IndexNumber, 5);
fileName = "[01] [ANK-Raws] あっちこっち 01 (BDrip 1920x1080 HEVC-YUV420P10 FLAC)";
parseResult = NameParser.Parse(fileName);
Assert.AreEqual(parseResult.Name, "あっちこっち 01");
Assert.AreEqual(parseResult.ParentIndexNumber, null);
Assert.AreEqual(parseResult.IndexNumber, 1);
// 只中文
fileName = "齊天大聖 第02集";
parseResult = NameParser.Parse(fileName);
@ -183,6 +197,13 @@ namespace Jellyfin.Plugin.MetaShark.Test
Assert.AreEqual(parseResult.ParentIndexNumber, null);
Assert.AreEqual(parseResult.IndexNumber, 2);
fileName = "齊天大聖 第 02 期";
parseResult = NameParser.Parse(fileName);
Assert.AreEqual(parseResult.Name, "齊天大聖");
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);

View File

@ -97,7 +97,7 @@ namespace Jellyfin.Plugin.MetaShark.Test
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);
var result = await provider.GuestDoubanSeasonByYearAsync("机动战士高达0083 星尘的回忆", 1991, null, CancellationToken.None);
Assert.AreEqual(result, "1766564");
}).GetAwaiter().GetResult();
}

View File

@ -13,17 +13,22 @@ 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 fixSeasonNumberReg = new Regex(@"(\[|\.)S(\d{1,2})(\]|\.)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex startWithHyphenCharReg = new Regex(@"^[-~]", RegexOptions.Compiled);
private static readonly Regex chineseIndexNumberReg = new Regex(@"第([0-9零一二三四五六七八九]+?)(集|章|话|話)", RegexOptions.Compiled);
private static readonly Regex chineseIndexNumberReg = new Regex(@"第\s*?([0-9零一二三四五六七八九]+?)\s*?(集|章|话|話|期)", RegexOptions.Compiled);
public static ParseNameResult Parse(string fileName, bool isTvSeries = false)
private static readonly Regex normalizeNameReg = new Regex(@"第\s*?([0-9零一二三四五六七八九]+?)\s*?(集|章|话|話|期)", RegexOptions.Compiled);
private static readonly Regex specialIndexNumberReg = new Regex(@"ep(\d{1,2})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static ParseNameResult Parse(string fileName, bool isEpisode = false)
{
fileName = NormalizeFileName(fileName);
var parseResult = new ParseNameResult();
var anitomyResult = AnitomySharp.AnitomySharp.Parse(fileName);
var isAnime = IsAnime(fileName);
@ -110,13 +115,13 @@ namespace Jellyfin.Plugin.MetaShark.Core
}
}
// 修复纯中文集数
// 修复纯中文集数/特殊标识集数
if (parseResult.IndexNumber is null)
{
parseResult.IndexNumber = ParseChineseIndexNumber(fileName);
parseResult.IndexNumber = ParseChineseOrSpecialIndexNumber(fileName);
}
// 解析不到title时使用默认名
// 解析不到title时或解析出多个title时使用默认名
if (string.IsNullOrEmpty(parseResult.Name))
{
parseResult.Name = fileName;
@ -167,14 +172,22 @@ namespace Jellyfin.Plugin.MetaShark.Core
return 0;
}
private static int? ParseChineseIndexNumber(string fileName)
private static string NormalizeFileName(string fileName)
{
// 去掉中文集数之间的空格要不然Anitomy解析不正确
fileName = normalizeNameReg.Replace(fileName, m => m.Value.Replace(" ", ""));
return fileName;
}
private static int? ParseChineseOrSpecialIndexNumber(string fileName)
{
var match = chineseIndexNumberReg.Match(fileName);
if (match.Success && match.Groups.Count > 1)
{
if (int.TryParse(match.Groups[1].Value, out var seasonNumber))
if (int.TryParse(match.Groups[1].Value, out var indexNumber))
{
return seasonNumber;
return indexNumber;
}
var number = Utils.ChineseNumberToInt(match.Groups[1].Value);
@ -183,6 +196,18 @@ namespace Jellyfin.Plugin.MetaShark.Core
return number;
}
}
else
{
match = specialIndexNumberReg.Match(fileName);
if (match.Success && match.Groups.Count > 1)
{
if (int.TryParse(match.Groups[1].Value, out var indexNumber))
{
return indexNumber;
}
}
}
return null;
}
@ -196,7 +221,7 @@ namespace Jellyfin.Plugin.MetaShark.Core
}
var folder = Path.GetFileName(Path.GetDirectoryName(path)) ?? string.Empty;
return folder == "SPs" || folder.Contains("特典");
return folder == "SPs" || folder == "Specials" || folder.Contains("特典");
}

View File

@ -171,20 +171,20 @@ namespace Jellyfin.Plugin.MetaShark.Providers
return null;
}
public async Task<string?> GuestDoubanSeasonByYearAsync(string name, int? year, CancellationToken cancellationToken)
public async Task<string?> GuestDoubanSeasonByYearAsync(string seriesName, int? year, int? seasonNumber, CancellationToken cancellationToken)
{
if (year == null || year == 0)
{
return null;
}
this.Log($"GuestDoubanSeasonByYear of [name]: {name} [year]: {year}");
this.Log($"GuestDoubanSeasonByYear of [name]: {seriesName} [year]: {year}");
// 先通过suggest接口查找减少搜索页访问次数避免封禁suggest没法区分电影或电视剧排序也比搜索页差些
if (config.EnableDoubanAvoidRiskControl)
{
var suggestResult = await this._doubanApi.SearchBySuggestAsync(name, cancellationToken).ConfigureAwait(false);
var suggestItem = suggestResult.Where(x => x.Year == year && x.Name == name).FirstOrDefault();
var suggestResult = await this._doubanApi.SearchBySuggestAsync(seriesName, cancellationToken).ConfigureAwait(false);
var suggestItem = suggestResult.Where(x => x.Year == year && x.Name == seriesName).FirstOrDefault();
if (suggestItem != null)
{
this.Log($"Found douban [id]: {suggestItem.Name}({suggestItem.Sid}) (suggest)");
@ -200,10 +200,18 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// 通过搜索页面查找
var result = await this._doubanApi.SearchAsync(name, cancellationToken).ConfigureAwait(false);
var result = await this._doubanApi.SearchAsync(seriesName, cancellationToken).ConfigureAwait(false);
var item = result.Where(x => x.Category == "电视剧" && x.Year == year).FirstOrDefault();
if (item != null && !string.IsNullOrEmpty(item.Sid))
{
// 判断名称中是否有第X季有的话和seasonNumber比较用于修正多季都在同一年时每次都是错误取第一个的情况
var nameIndexNumber = ParseChineseSeasonNumberByName(item.Name);
if (nameIndexNumber.HasValue && seasonNumber.HasValue && nameIndexNumber != seasonNumber)
{
this.Log($"GuestDoubanSeasonByYear not found!");
return null;
}
this.Log($"Found douban [id]: {item.Name}({item.Sid})");
return item.Sid;
}
@ -380,6 +388,26 @@ namespace Jellyfin.Plugin.MetaShark.Providers
}
public int? ParseChineseSeasonNumberByName(string name)
{
var regSeason = new Regex(@"\s第([0-9零一二三四五六七八九]+?)(季|部)", RegexOptions.Compiled);
var match = regSeason.Match(name);
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)
{
return seasonNumber;
}
}
return null;
}
/// <summary>
/// 浏览器来源请求返回代理地址no-referer对于background-image不生效其他客户端请求返回原始图片地址
/// </summary>

View File

@ -165,7 +165,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
if (!string.IsNullOrEmpty(seriesName) && seasonYear > 0)
{
var seasonSid = await this.GuestDoubanSeasonByYearAsync(seriesName, seasonYear, cancellationToken).ConfigureAwait(false);
var seasonSid = await this.GuestDoubanSeasonByYearAsync(seriesName, seasonYear, seasonNumber, cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrEmpty(seasonSid))
{
return seasonSid;