Optimize identity

This commit is contained in:
cxfksword 2023-02-20 21:09:08 +08:00
parent ee19b16c7b
commit b46ab340f1
7 changed files with 84 additions and 65 deletions

View File

@ -107,10 +107,13 @@ namespace Jellyfin.Plugin.MetaShark.Api
httpClient.DefaultRequestHeaders.Add("Referer", "https://movie.douban.com/");
this.LoadLoadDoubanCookie();
Plugin.Instance!.ConfigurationChanged += (_, _) =>
if (Plugin.Instance != null)
{
this.LoadLoadDoubanCookie();
};
Plugin.Instance.ConfigurationChanged += (_, _) =>
{
this.LoadLoadDoubanCookie();
};
}
}

View File

@ -16,7 +16,7 @@ namespace Jellyfin.Plugin.MetaShark.Core
private static readonly Regex unusedReg = new Regex(@"\[.+?\]|\(.+?\)|【.+?】", RegexOptions.Compiled);
private static readonly Regex extrasReg = new Regex(@"\[(CM|Menu|NCED|NCOP|Drama)[0-9_]*?\]", RegexOptions.Compiled);
private static readonly Regex extrasReg = new Regex(@"\[(OP|ED|PV|CM|Menu|NCED|NCOP|Drama|PreView)[0-9_]*?\]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static ParseNameResult Parse(string fileName, bool isTvSeries = false)
{

View File

@ -149,7 +149,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
item = result.Where(x => x.Category == cat && x.Year == info.Year).FirstOrDefault();
if (item != null)
{
this.Log($"GuessByDouban found -> {item.Name}({item.Sid})");
this.Log($"Found douban [id]: {item.Name}({item.Sid})");
return item.Sid;
}
}
@ -181,13 +181,13 @@ namespace Jellyfin.Plugin.MetaShark.Providers
var suggestItem = suggestResult.Where(x => x.Year == year && x.Name == name).FirstOrDefault();
if (suggestItem != null)
{
this.Log($"GuestDoubanSeasonByYear found -> {suggestItem.Name}({suggestItem.Sid}) (suggest)");
this.Log($"Found douban [id]: {suggestItem.Name}({suggestItem.Sid}) (suggest)");
return suggestItem.Sid;
}
suggestItem = suggestResult.Where(x => x.Year == year).FirstOrDefault();
if (suggestItem != null)
{
this.Log($"GuestDoubanSeasonByYear found -> {suggestItem.Name}({suggestItem.Sid}) (suggest)");
this.Log($"Found douban [id]: {suggestItem.Name}({suggestItem.Sid}) (suggest)");
return suggestItem.Sid;
}
}
@ -198,7 +198,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
var item = result.Where(x => x.Category == "电视剧" && x.Year == year).FirstOrDefault();
if (item != null && !string.IsNullOrEmpty(item.Sid))
{
this.Log($"GuestDoubanSeasonByYear found -> {item.Name}({item.Sid})");
this.Log($"Found douban [id]: {item.Name}({item.Sid})");
return item.Sid;
}
@ -207,36 +207,30 @@ namespace Jellyfin.Plugin.MetaShark.Providers
}
protected async Task<string?> GuestByTmdbAsync(ItemLookupInfo info, CancellationToken cancellationToken)
protected async Task<string?> GuestByTmdbAsync(string name, int? year, ItemLookupInfo info, CancellationToken cancellationToken)
{
// ParseName is required here.
// Caller provides the filename with extension stripped and NOT the parsed filename
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} [file_name]: {fileName} [year]: {info.Year} [search name]: {searchName}");
this.Log($"GuestByTmdb of [name]: {name} [year]: {year}");
switch (info)
{
case MovieInfo:
var movieResults = await this._tmdbApi.SearchMovieAsync(searchName, info.Year ?? 0, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
var movieResults = await this._tmdbApi.SearchMovieAsync(name, year ?? 0, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
var movieItem = movieResults.FirstOrDefault();
if (movieItem != null)
{
// bt种子都是英文名但电影是中日韩泰印法地区时都不适用相似匹配去掉限制
this.Log($"GuestByTmdb found -> {movieItem.Title}({movieItem.Id})");
this.Log($"Found tmdb [id]: {movieItem.Title}({movieItem.Id})");
return movieItem.Id.ToString(CultureInfo.InvariantCulture);
}
break;
case SeriesInfo:
var seriesResults = await this._tmdbApi.SearchSeriesAsync(searchName, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
var seriesResults = await this._tmdbApi.SearchSeriesAsync(name, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
var seriesItem = seriesResults.FirstOrDefault();
if (seriesItem != null)
{
// bt种子都是英文名但电影是中日韩泰印法地区时都不适用相似匹配去掉限制
this.Log($"GuestByTmdb found -> {seriesItem.Name}({seriesItem.Id})");
this.Log($"Found tmdb [id]: -> {seriesItem.Name}({seriesItem.Id})");
return seriesItem.Id.ToString(CultureInfo.InvariantCulture);
}
break;

View File

@ -1,5 +1,4 @@
using System.Reflection.Metadata;
using Jellyfin.Plugin.MetaShark.Api;
using Jellyfin.Plugin.MetaShark.Api;
using Jellyfin.Plugin.MetaShark.Core;
using Jellyfin.Plugin.MetaShark.Model;
using MediaBrowser.Common.Net;
@ -58,18 +57,19 @@ namespace Jellyfin.Plugin.MetaShark.Providers
/// <inheritdoc />
public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken)
{
// 重新识别时info的IndexNumber和ParentIndexNumber是从文件路径解析出来的假如命名不规范就会导致解析出错误值
// 刷新元数据不覆盖时IndexNumber和ParentIndexNumber是从当前的元数据获取
this.Log($"GetEpisodeMetadata of [name]: {info.Name} number: {info.IndexNumber} ParentIndexNumber: {info.ParentIndexNumber}");
// 刷新元数据四种模式差别:
// 自动扫描匹配info的Name、IndexNumber和ParentIndexNumber是从文件名解析出来的假如命名不规范就会导致解析出错误值
// 识别info的Name、IndexNumber和ParentIndexNumber是从文件名解析出来的provinceIds有指定选择项的ProvinceId
// 搜索缺少的元数据info的Name、IndexNumber和ParentIndexNumber是从当前的元数据获取provinceIds保留所有旧值
// 覆盖所有元数据info的Name、IndexNumber和ParentIndexNumber是从当前的元数据获取provinceIds保留所有旧值
this.Log($"GetEpisodeMetadata of [name]: {info.Name} number: {info.IndexNumber} ParentIndexNumber: {info.ParentIndexNumber} IsAutomated: {info.IsAutomated}");
var result = new MetadataResult<Episode>();
// 动画特典和extras处理
var specialEpisode = this.HandleAnimeSpecialAndExtras(info.Path);
if (specialEpisode != null)
var specialResult = this.HandleAnimeSpecialAndExtras(info);
if (specialResult != null)
{
result.HasMetadata = true;
result.Item = specialEpisode;
return result;
return specialResult;
}
// 剧集信息只有tmdb有
@ -78,8 +78,9 @@ namespace Jellyfin.Plugin.MetaShark.Providers
var episodeNumber = info.IndexNumber;
var indexNumberEnd = info.IndexNumberEnd;
// 修正anime命名格式导致的seasonNumber错误从season元数据读取)
var parent = _libraryManager.FindByPath(Path.GetDirectoryName(info.Path), true);
if (parent is Season season && seasonNumber != season.IndexNumber)
var episodeItem = _libraryManager.FindByPath(info.Path, false);
var season = episodeItem != null ? ((Episode)episodeItem).Season : null;
if (season != null && seasonNumber != season.IndexNumber)
{
this.Log("FixSeasionNumber: old: {0} new: {1}", seasonNumber, season.IndexNumber);
seasonNumber = season.IndexNumber;
@ -130,17 +131,15 @@ namespace Jellyfin.Plugin.MetaShark.Providers
return result;
}
// 判断tmdb剧集信息数目和视频是否一致不一致不处理
var videoFilesCount = this.GetVideoFileCount(Path.GetDirectoryName(info.Path));
if (!info.IsAutomated && parent is Season)
// 自动搜索匹配时判断tmdb剧集信息数目和视频是否一致不一致不处理
if (info.IsAutomated)
{
// 刷新元数据时直接从season拿准确的视频数并排除特典等没有季号的视频
videoFilesCount = ((Season)parent).GetEpisodes().Where(x => x.ParentIndexNumber == parent.IndexNumber).Count();
}
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 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];
@ -224,32 +223,47 @@ namespace Jellyfin.Plugin.MetaShark.Providers
return guessInfo;
}
private Episode? HandleAnimeSpecialAndExtras(string filePath)
private MetadataResult<Episode>? HandleAnimeSpecialAndExtras(EpisodeInfo info)
{
var fileName = Path.GetFileNameWithoutExtension(filePath) ?? string.Empty;
var fileName = Path.GetFileNameWithoutExtension(info.Path) ?? string.Empty;
if (NameParser.IsExtra(fileName))
{
this.Log($"Found anime extra of [name]: {fileName}");
return new Episode
var result = new MetadataResult<Episode>();
result.HasMetadata = true;
// 假如已有ParentIndexNumber设为特典覆盖掉
if (info.ParentIndexNumber.HasValue)
{
result.Item = new Episode
{
ParentIndexNumber = 0,
IndexNumber = null,
Name = fileName
};
return result;
}
// 没ParentIndexNumber时使用文件名
result.Item = new Episode
{
Name = fileName
};
return result;
}
if (NameParser.IsSpecial(filePath))
if (NameParser.IsSpecial(info.Path))
{
this.Log($"Found anime sp of [name]: {fileName}");
var guessInfo = this.GuessEpisodeNumber(fileName);
var ep = new Episode
var result = new MetadataResult<Episode>();
result.HasMetadata = true;
result.Item = new Episode
{
ParentIndexNumber = 0,
IndexNumber = guessInfo.episodeNumber,
IndexNumber = null,
Name = fileName
};
if (!string.IsNullOrEmpty(guessInfo.Name))
{
ep.Name = guessInfo.Name;
}
return ep;
return result;
}
return null;

View File

@ -146,6 +146,17 @@ namespace Jellyfin.Plugin.MetaShark.Providers
}
}
// 尝试通过搜索匹配获取tmdbId
if (string.IsNullOrEmpty(tmdbId) && subject.Year > 0)
{
var newTmdbId = await this.GuestByTmdbAsync(subject.Name, subject.Year, info, cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrEmpty(newTmdbId))
{
tmdbId = newTmdbId;
movie.SetProviderId(MetadataProvider.Tmdb, tmdbId);
}
}
// 通过imdb获取电影系列信息
if (this.config.EnableTmdbCollection && !string.IsNullOrEmpty(tmdbId))
{

View File

@ -53,7 +53,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
info.SeriesProviderIds.TryGetValue(DoubanProviderId, out var sid);
var seasonNumber = info.IndexNumber; // S00/Season 00特典目录会为0
var seasonSid = info.GetProviderId(DoubanProviderId);
this.Log($"GetSeasonMetaData of [name]: {info.Name} number: {info.IndexNumber} seriesTmdbId: {seriesTmdbId} sid: {sid} metaSource: {metaSource}");
this.Log($"GetSeasonMetaData of [name]: {info.Name} number: {info.IndexNumber} seriesTmdbId: {seriesTmdbId} sid: {sid} metaSource: {metaSource} IsAutomated: {info.IsAutomated}");
if (metaSource != MetaSource.Tmdb && !string.IsNullOrEmpty(sid))
{
@ -63,7 +63,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
{
return result;
}
var seasonName = RemoveSeasonSubfix(series.Name);
var seriesName = RemoveSeasonSubfix(series.Name);
// TODO:季文件夹名称不规范没法拿到seasonNumber尝试从文件名猜出
@ -79,9 +79,9 @@ namespace Jellyfin.Plugin.MetaShark.Providers
seasonYear = season?.AirDate?.Year ?? 0;
}
if (!string.IsNullOrEmpty(seasonName) && seasonYear > 0)
if (!string.IsNullOrEmpty(seriesName) && seasonYear > 0)
{
seasonSid = await this.GuestDoubanSeasonByYearAsync(seasonName, seasonYear, cancellationToken).ConfigureAwait(false);
seasonSid = await this.GuestDoubanSeasonByYearAsync(seriesName, seasonYear, cancellationToken).ConfigureAwait(false);
}
}

View File

@ -81,7 +81,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
/// <inheritdoc />
public async Task<MetadataResult<Series>> GetMetadata(SeriesInfo info, CancellationToken cancellationToken)
{
this.Log($"GetSeriesMetadata of [name]: {info.Name} [providerIds]: {info.ProviderIds.ToJson()}");
this.Log($"GetSeriesMetadata of [name]: {info.Name} [providerIds]: {info.ProviderIds.ToJson()} IsAutomated: {info.IsAutomated}");
var result = new MetadataResult<Series>();
// 使用刷新元数据时providerIds会保留旧有值只有识别/新增才会没值
@ -95,10 +95,6 @@ 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 (metaSource != MetaSource.Tmdb && !string.IsNullOrEmpty(sid))
@ -111,10 +107,11 @@ namespace Jellyfin.Plugin.MetaShark.Providers
}
subject.Celebrities = await this._doubanApi.GetCelebritiesBySidAsync(sid, cancellationToken).ConfigureAwait(false);
var seriesName = RemoveSeasonSubfix(subject.Name);
var item = new Series
{
ProviderIds = new Dictionary<string, string> { { DoubanProviderId, subject.Sid }, { Plugin.ProviderId, MetaSource.Douban } },
Name = RemoveSeasonSubfix(subject.Name),
Name = seriesName,
OriginalTitle = subject.OriginalName,
CommunityRating = subject.Rating,
Overview = subject.Intro,
@ -142,7 +139,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// 尝试通过搜索匹配获取tmdbId
if (string.IsNullOrEmpty(tmdbId))
{
var newTmdbId = await this.GuestByTmdbAsync(info, cancellationToken).ConfigureAwait(false);
var newTmdbId = await this.GuestByTmdbAsync(seriesName, subject.Year, info, cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrEmpty(newTmdbId))
{
tmdbId = newTmdbId;