diff --git a/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs b/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs index 6421a13..14ec431 100644 --- a/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs +++ b/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs @@ -37,6 +37,10 @@ namespace Jellyfin.Plugin.MetaShark.Test parseResult = NameParser.Parse(fileName); Console.WriteLine(parseResult.ToJson()); + fileName = "罗马假日.Roman.Holiday.1953.WEB-DL.1080p.x265.AAC.2Audios.GREENOTEA"; + parseResult = NameParser.Parse(fileName); + Console.WriteLine(parseResult.ToJson()); + // 只英文 fileName = "New.World.2013.BluRay.1080p.x265.10bit.MNHD-FRDS"; parseResult = NameParser.Parse(fileName); diff --git a/Jellyfin.Plugin.MetaShark/Api/DoubanApi.cs b/Jellyfin.Plugin.MetaShark/Api/DoubanApi.cs index f0f58f5..3d82683 100644 --- a/Jellyfin.Plugin.MetaShark/Api/DoubanApi.cs +++ b/Jellyfin.Plugin.MetaShark/Api/DoubanApi.cs @@ -162,12 +162,14 @@ namespace Jellyfin.Plugin.MetaShark.Api EnsureLoadDoubanCookie(); + // LimitRequestFrequently(2000); - keyword = HttpUtility.UrlEncode(keyword); - var url = $"https://www.douban.com/search?cat=1002&q={keyword}"; + var encodedKeyword = HttpUtility.UrlEncode(keyword); + var url = $"https://www.douban.com/search?cat=1002&q={encodedKeyword}"; var response = await httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false); if (!response.IsSuccessStatusCode) { + this._logger.LogWarning("douban搜索请求失败. keyword: {0} statusCode: {1}", keyword, response.StatusCode); return list; } @@ -208,6 +210,11 @@ namespace Jellyfin.Plugin.MetaShark.Api list.Add(movie); } + if (list.Count <= 0) + { + this._logger.LogWarning("douban搜索不到内容,这消息大量出现时,可能触发了爬虫风控。。。keyword: {0}", keyword); + } + _memoryCache.Set>(cacheKey, list, expiredOption); return list; @@ -229,6 +236,7 @@ namespace Jellyfin.Plugin.MetaShark.Api } EnsureLoadDoubanCookie(); + // LimitRequestFrequently(); var url = $"https://movie.douban.com/subject/{sid}/"; var response = await httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false); @@ -339,6 +347,7 @@ namespace Jellyfin.Plugin.MetaShark.Api } EnsureLoadDoubanCookie(); + // LimitRequestFrequently(); var list = new List(); var url = $"https://movie.douban.com/subject/{sid}/celebrities"; @@ -482,7 +491,9 @@ namespace Jellyfin.Plugin.MetaShark.Api return searchResult; } + EnsureLoadDoubanCookie(); + // LimitRequestFrequently(); keyword = HttpUtility.UrlEncode(keyword); @@ -536,6 +547,7 @@ namespace Jellyfin.Plugin.MetaShark.Api } EnsureLoadDoubanCookie(); + // LimitRequestFrequently(); var list = new List(); var url = $"https://movie.douban.com/subject/{sid}/photos?type=W&start=0&sortby=size&size=a&subtype=a"; @@ -587,20 +599,24 @@ namespace Jellyfin.Plugin.MetaShark.Api } - protected void LimitRequestFrequently() + protected void LimitRequestFrequently(int interval = 1000) { + var diff = 0; lock (_lock) { var ts = DateTime.Now - lastRequestTime; - var diff = (int)(200 - ts.TotalMilliseconds); + diff = (int)(interval - ts.TotalMilliseconds); if (diff > 0) { + this._logger.LogInformation("请求太频繁,等待{0}毫秒后继续执行...", diff); Thread.Sleep(diff); } + lastRequestTime = DateTime.Now; } } + private string? GetText(IElement el, string css) { var node = el.QuerySelector(css); diff --git a/Jellyfin.Plugin.MetaShark/Core/NameParser.cs b/Jellyfin.Plugin.MetaShark/Core/NameParser.cs index 6563b9f..1ec9800 100644 --- a/Jellyfin.Plugin.MetaShark/Core/NameParser.cs +++ b/Jellyfin.Plugin.MetaShark/Core/NameParser.cs @@ -10,10 +10,10 @@ namespace Jellyfin.Plugin.MetaShark.Core { public static class NameParser { - private static readonly Regex yearReg = new Regex(@"[12][890][78901234][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 unusedReg = new Regex(@"\[.+?\]", RegexOptions.Compiled); + private static readonly Regex unusedReg = new Regex(@"\[.+?\]|\(.+?\)", RegexOptions.Compiled); public static ParseNameResult Parse(string fileName, bool isTvSeries = false) { @@ -86,7 +86,7 @@ namespace Jellyfin.Plugin.MetaShark.Core // 电视剧名称后紧跟季信息时,会附加到名称中,需要去掉 name = seasonSuffixReg.Replace(name, string.Empty); - // 删除多余的[]信息 + // 删除多余的[]/()附加信息 name = unusedReg.Replace(name, string.Empty); return name.Replace(".", " ").Trim(); diff --git a/Jellyfin.Plugin.MetaShark/Providers/BaseProvider.cs b/Jellyfin.Plugin.MetaShark/Providers/BaseProvider.cs index d4496c1..2738017 100644 --- a/Jellyfin.Plugin.MetaShark/Providers/BaseProvider.cs +++ b/Jellyfin.Plugin.MetaShark/Providers/BaseProvider.cs @@ -72,13 +72,13 @@ namespace Jellyfin.Plugin.MetaShark.Providers { // ParseName is required here. // Caller provides the filename with extension stripped and NOT the parsed filename - var fileName = info.Name; + var fileName = GetNotParsedName(info); var parseResult = NameParser.Parse(fileName); var searchName = !string.IsNullOrEmpty(parseResult.ChineseName) ? parseResult.ChineseName : parseResult.Name; info.Year = parseResult.Year; // 默认parser对anime年份会解析出错,以anitomy为准 - this.Log($"GuessByDouban of [name]: {info.Name} [year]: {info.Year} [search name]: {searchName}"); + this.Log($"GuessByDouban of [name]: {info.Name} [file_name]: {fileName} [year]: {info.Year} [search name]: {searchName}"); var result = await this._doubanApi.SearchAsync(searchName, cancellationToken).ConfigureAwait(false); var jw = new JaroWinkler(); foreach (var item in result) @@ -173,12 +173,13 @@ namespace Jellyfin.Plugin.MetaShark.Providers { // ParseName is required here. // Caller provides the filename with extension stripped and NOT the parsed filename - var fileName = info.Name; + var fileName = GetNotParsedName(info); var parseResult = NameParser.Parse(fileName); var searchName = !string.IsNullOrEmpty(parseResult.ChineseName) ? parseResult.ChineseName : parseResult.Name; info.Year = parseResult.Year; // 默认parser对anime年份会解析出错,以anitomy为准 - this.Log($"GuestByTmdb of [name]: {info.Name} [year]: {info.Year} [search name]: {searchName}"); + + this.Log($"GuestByTmdb of [name]: {info.Name} [file_name]: {fileName} [year]: {info.Year} [search name]: {searchName}"); var jw = new JaroWinkler(); switch (info) @@ -384,5 +385,16 @@ namespace Jellyfin.Plugin.MetaShark.Providers return language; } + + protected string GetNotParsedName(ItemLookupInfo info) + { + var directoryName = Path.GetFileName(Path.GetDirectoryName(info.Path)); + if (directoryName != null && directoryName.StartsWith(info.Name)) + { + return directoryName; + } + + return Path.GetFileNameWithoutExtension(info.Path) ?? info.Name; + } } } diff --git a/Jellyfin.Plugin.MetaShark/Providers/MovieProvider.cs b/Jellyfin.Plugin.MetaShark/Providers/MovieProvider.cs index 53de691..c46170c 100644 --- a/Jellyfin.Plugin.MetaShark/Providers/MovieProvider.cs +++ b/Jellyfin.Plugin.MetaShark/Providers/MovieProvider.cs @@ -97,10 +97,10 @@ namespace Jellyfin.Plugin.MetaShark.Providers { // 自动扫描搜索匹配元数据 sid = await this.GuessByDoubanAsync(info, cancellationToken).ConfigureAwait(false); - if (string.IsNullOrEmpty(sid)) - { - tmdbId = await this.GuestByTmdbAsync(info, cancellationToken).ConfigureAwait(false); - } + // if (string.IsNullOrEmpty(sid)) + // { + // tmdbId = await this.GuestByTmdbAsync(info, cancellationToken).ConfigureAwait(false); + // } } if (metaSource != MetaSource.Tmdb && !string.IsNullOrEmpty(sid)) diff --git a/Jellyfin.Plugin.MetaShark/Providers/SeriesProvider.cs b/Jellyfin.Plugin.MetaShark/Providers/SeriesProvider.cs index 8e3f373..6571b79 100644 --- a/Jellyfin.Plugin.MetaShark/Providers/SeriesProvider.cs +++ b/Jellyfin.Plugin.MetaShark/Providers/SeriesProvider.cs @@ -90,10 +90,10 @@ namespace Jellyfin.Plugin.MetaShark.Providers { // 自动扫描搜索匹配元数据 sid = await this.GuessByDoubanAsync(info, cancellationToken).ConfigureAwait(false); - if (string.IsNullOrEmpty(sid)) - { - tmdbId = await this.GuestByTmdbAsync(info, cancellationToken).ConfigureAwait(false); - } + // if (string.IsNullOrEmpty(sid)) + // { + // tmdbId = await this.GuestByTmdbAsync(info, cancellationToken).ConfigureAwait(false); + // } } if (metaSource != MetaSource.Tmdb && !string.IsNullOrEmpty(sid)) diff --git a/README.md b/README.md index 8d5a06c..c3c42af 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,8 @@ jellyfin电影元数据插件,影片信息只要从豆瓣获取,并由TheMov 3. 识别时默认不返回TheMovieDb结果,有需要可以到插件配置中打开 4. 假如网络原因访问TheMovieDb比较慢,可以到插件配置中关闭从TheMovieDb获取数据(关闭后不会再获取剧集信息) - + +> 🚨建议一次不要刮削太多电影,要不然会触发豆瓣风控,导致被封IP(封IP需要等6小时左右才能恢复访问) ## How to build