Optimize season & episode metadata fetch
This commit is contained in:
parent
20f753a826
commit
ae30940672
|
@ -133,6 +133,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var score = jw.Similarity(name, item.Name);
|
||||
// this.Log($"GuestDoubanSeasonByYear name: {name} douban_name: {item.Name} douban_sid: {item.Sid} douban_year: {item.Year} score: {score} ");
|
||||
if (score < 0.8)
|
||||
|
@ -150,6 +151,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
return null;
|
||||
}
|
||||
|
||||
// 通过季数,搜索结果按年份排序后,取对应季数索引项(不适合每季标题差异太大的,如葫芦兄弟和葫芦小金刚)
|
||||
protected async Task<string?> GuestDoubanSeasonByNumberAsync(string name, int? seasonNumber, CancellationToken cancellationToken)
|
||||
{
|
||||
if (seasonNumber == null || seasonNumber == 0)
|
||||
|
@ -167,6 +169,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var score = jw.Similarity(name, item.Name);
|
||||
if (score < 0.8)
|
||||
{
|
||||
|
@ -227,26 +230,6 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
}
|
||||
|
||||
|
||||
protected int GetVideoFileCount(string? dir)
|
||||
{
|
||||
if (dir == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var dirInfo = new DirectoryInfo(dir);
|
||||
var files = dirInfo.GetFiles();
|
||||
var nameOptions = new Emby.Naming.Common.NamingOptions();
|
||||
var videoFilesCount = 0;
|
||||
foreach (var fileInfo in files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden)))
|
||||
{
|
||||
if (Emby.Naming.Video.VideoResolver.IsVideoFile(fileInfo.FullName, nameOptions))
|
||||
{
|
||||
videoFilesCount++;
|
||||
}
|
||||
}
|
||||
return videoFilesCount;
|
||||
}
|
||||
|
||||
|
||||
protected string GetProxyImageUrl(string url)
|
||||
|
|
|
@ -9,6 +9,7 @@ using MediaBrowser.Controller.Providers;
|
|||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
@ -22,8 +23,9 @@ using MediaBrowser.Controller.Entities;
|
|||
|
||||
namespace Jellyfin.Plugin.MetaShark.Providers
|
||||
{
|
||||
public class EpisodeProvider : BaseProvider, IRemoteMetadataProvider<Episode, EpisodeInfo>
|
||||
public class EpisodeProvider : BaseProvider, IRemoteMetadataProvider<Episode, EpisodeInfo>, IDisposable
|
||||
{
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
|
||||
private static readonly Regex[] EpisodeFileNameRegex =
|
||||
{
|
||||
|
@ -38,6 +40,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
public EpisodeProvider(IHttpClientFactory httpClientFactory, ILoggerFactory loggerFactory, ILibraryManager libraryManager, DoubanApi doubanApi, TmdbApi tmdbApi, OmdbApi omdbApi)
|
||||
: base(httpClientFactory, loggerFactory.CreateLogger<EpisodeProvider>(), libraryManager, doubanApi, tmdbApi, omdbApi)
|
||||
{
|
||||
this._memoryCache = new MemoryCache(new MemoryCacheOptions());
|
||||
}
|
||||
|
||||
public string Name => Plugin.PluginName;
|
||||
|
@ -112,6 +115,8 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
this.Log("Can‘t found episode data from tmdb. Name: {0} seriesTmdbId: {1} seasonNumber: {2} episodeNumber: {3}", info.Name, seriesTmdbId, seasonNumber, episodeNumber);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断tmdb剧集信息数目和视频是否一致,不一致不处理
|
||||
var videoFilesCount = this.GetVideoFileCount(Path.GetDirectoryName(info.Path));
|
||||
if (videoFilesCount > 0 && seasonResult.Episodes.Count != videoFilesCount)
|
||||
{
|
||||
|
@ -194,5 +199,50 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
return guessInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected int GetVideoFileCount(string? dir)
|
||||
{
|
||||
if (dir == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var cacheKey = $"filecount_{dir}";
|
||||
if (this._memoryCache.TryGetValue<int>(cacheKey, out var videoFilesCount))
|
||||
{
|
||||
return videoFilesCount;
|
||||
}
|
||||
|
||||
var dirInfo = new DirectoryInfo(dir);
|
||||
var files = dirInfo.GetFiles();
|
||||
var nameOptions = new Emby.Naming.Common.NamingOptions();
|
||||
|
||||
foreach (var fileInfo in files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden)))
|
||||
{
|
||||
if (Emby.Naming.Video.VideoResolver.IsVideoFile(fileInfo.FullName, nameOptions))
|
||||
{
|
||||
videoFilesCount++;
|
||||
}
|
||||
}
|
||||
|
||||
var expiredOption = new MemoryCacheEntryOptions() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1) };
|
||||
this._memoryCache.Set<int>(cacheKey, videoFilesCount, expiredOption);
|
||||
return videoFilesCount;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_memoryCache.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,11 +82,6 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
}
|
||||
}
|
||||
|
||||
// 尝试通过豆瓣按年份排序后,按季数索引取对应一个
|
||||
if (string.IsNullOrEmpty(seasonSid) && !string.IsNullOrEmpty(seriesName) && seasonNumber.HasValue)
|
||||
{
|
||||
seasonSid = await this.GuestDoubanSeasonByNumberAsync(seriesName, seasonNumber, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// 获取季豆瓣数据
|
||||
if (!string.IsNullOrEmpty(seasonSid))
|
||||
|
@ -125,6 +120,17 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
}
|
||||
|
||||
|
||||
// tmdb有数据,豆瓣找不到,尝试获取tmdb的季数据
|
||||
if (string.IsNullOrEmpty(seasonSid) && !string.IsNullOrWhiteSpace(seriesTmdbId) && seasonNumber.HasValue)
|
||||
{
|
||||
var tmdbResult = await this.GetMetadataByTmdb(info, seriesTmdbId, seasonNumber.Value, cancellationToken).ConfigureAwait(false);
|
||||
if (tmdbResult != null)
|
||||
{
|
||||
return tmdbResult;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 从豆瓣获取不到季信息,直接使用series信息
|
||||
result.Item = new Season
|
||||
{
|
||||
|
@ -148,34 +154,11 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
// tmdb季级没有对应id,只通过indexNumber区分
|
||||
if (!string.IsNullOrWhiteSpace(seriesTmdbId) && seasonNumber.HasValue)
|
||||
{
|
||||
var seasonResult = await this._tmdbApi
|
||||
.GetSeasonAsync(seriesTmdbId.ToInt(), seasonNumber.Value, info.MetadataLanguage, null, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
if (seasonResult == null)
|
||||
var tmdbResult = await this.GetMetadataByTmdb(info, seriesTmdbId, seasonNumber.Value, cancellationToken).ConfigureAwait(false);
|
||||
if (tmdbResult != null)
|
||||
{
|
||||
this.Log($"Not found season from TMDB. {info.Name} seriesTmdbId: {seriesTmdbId} seasonNumber: {seasonNumber}");
|
||||
return result;
|
||||
return tmdbResult;
|
||||
}
|
||||
|
||||
result.HasMetadata = true;
|
||||
result.Item = new Season
|
||||
{
|
||||
IndexNumber = seasonNumber,
|
||||
Overview = seasonResult.Overview,
|
||||
PremiereDate = seasonResult.AirDate,
|
||||
ProductionYear = seasonResult.AirDate?.Year,
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(seasonResult.ExternalIds?.TvdbId))
|
||||
{
|
||||
result.Item.SetProviderId(MetadataProvider.Tvdb, seasonResult.ExternalIds.TvdbId);
|
||||
}
|
||||
foreach (var person in GetPersons(seasonResult))
|
||||
{
|
||||
result.AddPerson(person);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -222,6 +205,40 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<MetadataResult<Season>?> GetMetadataByTmdb(SeasonInfo info, string seriesTmdbId, int seasonNumber, CancellationToken cancellationToken)
|
||||
{
|
||||
var seasonResult = await this._tmdbApi
|
||||
.GetSeasonAsync(seriesTmdbId.ToInt(), seasonNumber, info.MetadataLanguage, info.MetadataLanguage, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
if (seasonResult == null)
|
||||
{
|
||||
this.Log($"Not found season from TMDB. {info.Name} seriesTmdbId: {seriesTmdbId} seasonNumber: {seasonNumber}");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var result = new MetadataResult<Season>();
|
||||
result.HasMetadata = true;
|
||||
result.Item = new Season
|
||||
{
|
||||
IndexNumber = seasonNumber,
|
||||
Overview = seasonResult.Overview,
|
||||
PremiereDate = seasonResult.AirDate,
|
||||
ProductionYear = seasonResult.AirDate?.Year,
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(seasonResult.ExternalIds?.TvdbId))
|
||||
{
|
||||
result.Item.SetProviderId(MetadataProvider.Tvdb, seasonResult.ExternalIds.TvdbId);
|
||||
}
|
||||
foreach (var person in GetPersons(seasonResult))
|
||||
{
|
||||
result.AddPerson(person);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private IEnumerable<PersonInfo> GetPersons(TvSeason item)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue