Optimize identity
This commit is contained in:
parent
ebc701845a
commit
3f0ad0112d
|
@ -176,6 +176,20 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
||||||
Assert.AreEqual(parseResult.ParentIndexNumber, 1);
|
Assert.AreEqual(parseResult.ParentIndexNumber, 1);
|
||||||
Assert.AreEqual(parseResult.IndexNumber, 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集";
|
fileName = "齊天大聖 第02集";
|
||||||
parseResult = NameParser.Parse(fileName);
|
parseResult = NameParser.Parse(fileName);
|
||||||
|
@ -183,6 +197,13 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
||||||
Assert.AreEqual(parseResult.ParentIndexNumber, null);
|
Assert.AreEqual(parseResult.ParentIndexNumber, null);
|
||||||
Assert.AreEqual(parseResult.IndexNumber, 2);
|
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
|
// anime
|
||||||
fileName = "[YYDM-11FANS][THERMAE_ROMAE][02][BDRIP][720P][X264-10bit_AAC][7FF2269F]";
|
fileName = "[YYDM-11FANS][THERMAE_ROMAE][02][BDRIP][720P][X264-10bit_AAC][7FF2269F]";
|
||||||
parseResult = NameParser.Parse(fileName);
|
parseResult = NameParser.Parse(fileName);
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var provider = new SeasonProvider(httpClientFactory, loggerFactory, libraryManagerStub.Object, httpContextAccessorStub.Object, doubanApi, tmdbApi, omdbApi);
|
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");
|
Assert.AreEqual(result, "1766564");
|
||||||
}).GetAwaiter().GetResult();
|
}).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 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 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);
|
||||||
|
|
||||||
private static readonly Regex fixSeasonNumberReg = new Regex(@"(\[|\.)S(\d{1,2})(\]|\.)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
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 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 parseResult = new ParseNameResult();
|
||||||
var anitomyResult = AnitomySharp.AnitomySharp.Parse(fileName);
|
var anitomyResult = AnitomySharp.AnitomySharp.Parse(fileName);
|
||||||
var isAnime = IsAnime(fileName);
|
var isAnime = IsAnime(fileName);
|
||||||
|
@ -110,13 +115,13 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修复纯中文集数
|
// 修复纯中文集数/特殊标识集数
|
||||||
if (parseResult.IndexNumber is null)
|
if (parseResult.IndexNumber is null)
|
||||||
{
|
{
|
||||||
parseResult.IndexNumber = ParseChineseIndexNumber(fileName);
|
parseResult.IndexNumber = ParseChineseOrSpecialIndexNumber(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析不到title时,使用默认名
|
// 解析不到title时,或解析出多个title时,使用默认名
|
||||||
if (string.IsNullOrEmpty(parseResult.Name))
|
if (string.IsNullOrEmpty(parseResult.Name))
|
||||||
{
|
{
|
||||||
parseResult.Name = fileName;
|
parseResult.Name = fileName;
|
||||||
|
@ -167,14 +172,22 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
||||||
return 0;
|
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);
|
var match = chineseIndexNumberReg.Match(fileName);
|
||||||
if (match.Success && match.Groups.Count > 1)
|
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);
|
var number = Utils.ChineseNumberToInt(match.Groups[1].Value);
|
||||||
|
@ -183,6 +196,18 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
||||||
return number;
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +221,7 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
var folder = Path.GetFileName(Path.GetDirectoryName(path)) ?? string.Empty;
|
var folder = Path.GetFileName(Path.GetDirectoryName(path)) ?? string.Empty;
|
||||||
return folder == "SPs" || folder.Contains("特典");
|
return folder == "SPs" || folder == "Specials" || folder.Contains("特典");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -171,20 +171,20 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
||||||
return null;
|
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)
|
if (year == null || year == 0)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Log($"GuestDoubanSeasonByYear of [name]: {name} [year]: {year}");
|
this.Log($"GuestDoubanSeasonByYear of [name]: {seriesName} [year]: {year}");
|
||||||
|
|
||||||
// 先通过suggest接口查找,减少搜索页访问次数,避免封禁(suggest没法区分电影或电视剧,排序也比搜索页差些)
|
// 先通过suggest接口查找,减少搜索页访问次数,避免封禁(suggest没法区分电影或电视剧,排序也比搜索页差些)
|
||||||
if (config.EnableDoubanAvoidRiskControl)
|
if (config.EnableDoubanAvoidRiskControl)
|
||||||
{
|
{
|
||||||
var suggestResult = await this._doubanApi.SearchBySuggestAsync(name, cancellationToken).ConfigureAwait(false);
|
var suggestResult = await this._doubanApi.SearchBySuggestAsync(seriesName, cancellationToken).ConfigureAwait(false);
|
||||||
var suggestItem = suggestResult.Where(x => x.Year == year && x.Name == name).FirstOrDefault();
|
var suggestItem = suggestResult.Where(x => x.Year == year && x.Name == seriesName).FirstOrDefault();
|
||||||
if (suggestItem != null)
|
if (suggestItem != null)
|
||||||
{
|
{
|
||||||
this.Log($"Found douban [id]: {suggestItem.Name}({suggestItem.Sid}) (suggest)");
|
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();
|
var item = result.Where(x => x.Category == "电视剧" && x.Year == year).FirstOrDefault();
|
||||||
if (item != null && !string.IsNullOrEmpty(item.Sid))
|
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})");
|
this.Log($"Found douban [id]: {item.Name}({item.Sid})");
|
||||||
return 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>
|
/// <summary>
|
||||||
/// 浏览器来源请求,返回代理地址(no-referer对于background-image不生效),其他客户端请求,返回原始图片地址
|
/// 浏览器来源请求,返回代理地址(no-referer对于background-image不生效),其他客户端请求,返回原始图片地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -165,7 +165,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(seriesName) && seasonYear > 0)
|
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))
|
if (!string.IsNullOrEmpty(seasonSid))
|
||||||
{
|
{
|
||||||
return seasonSid;
|
return seasonSid;
|
||||||
|
|
Loading…
Reference in New Issue