Optimize indentity mixed zh&en name
This commit is contained in:
parent
b7ee0b956d
commit
488bf80551
|
@ -15,6 +15,7 @@ jobs:
|
|||
actions: "close-issues"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
inactive-day: 30
|
||||
exclude-labels: "enhancement,bug"
|
||||
close-reason: "not_planned"
|
||||
body: |
|
||||
This issue was closed due to inactive more than 30 days. You can reopen or recreate it if you think it should continue.
|
||||
|
|
|
@ -48,5 +48,26 @@ namespace Jellyfin.Plugin.MetaShark.Test
|
|||
}).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestGetMetadataAnime()
|
||||
{
|
||||
var info = new MovieInfo() { Name = "[SAIO-Raws] もののけ姫 Mononoke Hime [BD 1920x1036 HEVC-10bit OPUSx2 AC3]" };
|
||||
var doubanApi = new DoubanApi(loggerFactory);
|
||||
var tmdbApi = new TmdbApi(loggerFactory);
|
||||
var omdbApi = new OmdbApi(loggerFactory);
|
||||
var httpClientFactory = new DefaultHttpClientFactory();
|
||||
var libraryManagerStub = new Mock<ILibraryManager>();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var provider = new MovieProvider(httpClientFactory, loggerFactory, libraryManagerStub.Object, doubanApi, tmdbApi, omdbApi);
|
||||
var result = await provider.GetMetadata(info, CancellationToken.None);
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
var str = result.ToJson();
|
||||
Console.WriteLine(result.ToJson());
|
||||
}).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Plugin.MetaShark.Api;
|
||||
using Jellyfin.Plugin.MetaShark.Core;
|
||||
using Jellyfin.Plugin.MetaShark.Model;
|
||||
using Jellyfin.Plugin.MetaShark.Providers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Jellyfin.Plugin.MetaShark.Test
|
||||
{
|
||||
[TestClass]
|
||||
public class ParseNameTest
|
||||
{
|
||||
ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
|
||||
builder.AddSimpleConsole(options =>
|
||||
{
|
||||
options.IncludeScopes = true;
|
||||
options.SingleLine = true;
|
||||
options.TimestampFormat = "hh:mm:ss ";
|
||||
}));
|
||||
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void TestMovieParse()
|
||||
{
|
||||
// 混合中英文
|
||||
var fileName = "新世界.New.World.2013.BluRay.1080p.x265.10bit.MNHD-FRDS";
|
||||
var parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
fileName = "V字仇杀队.V.for.Vendetta.2006";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
// 只英文
|
||||
fileName = "New.World.2013.BluRay.1080p.x265.10bit.MNHD-FRDS";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
fileName = "Who.Am.I.1998.1080p.BluRay.x264.DTS-FGT";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
// 标题加年份
|
||||
fileName = "V字仇杀队 (2006)";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
|
||||
// anime
|
||||
fileName = "[SAIO-Raws] もののけ姫 Mononoke Hime [BD 1920x1036 HEVC-10bit OPUSx2 AC3].mp4";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestTVSeriesParse()
|
||||
{
|
||||
// 混合中英文
|
||||
var fileName = "新世界.New.World.2013.BluRay.1080p.x265.10bit.MNHD-FRDS";
|
||||
var parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
// 混合中英文带副标题
|
||||
fileName = "航海王:狂热行动.One.Piece.Stampede.2019.BD720P.X264.AAC.Japanese&Mandarin.CHS.Mp4Ba";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
// 只英文
|
||||
fileName = "She-Hulk.Attorney.at.Law.S01.1080p.WEBRip.x265-RARBG";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
fileName = "Bright.Future.S01.2022.2160p.HDR.WEB-DL.H265.AAC-BlackTV[BTBTT]";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
fileName = "Back.to.the.Future.Part.II.1989.BluRay.1080p.x265.10bit.2Audio-MiniHD[BTBTT]";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
|
||||
|
||||
// anime混合中日文
|
||||
fileName = "[异域-11番小队][罗马浴场 THERMAE_ROMAE][1-6+SP][BDRIP][720P][X264-10bit_AAC]";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
// anime
|
||||
fileName = "[Nekomoe kissaten][Shin Ikkitousen][01-03][720p][CHT]";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
fileName = "[SAIO-Raws] Fullmetal Alchemist Brotherhood [BD 1920x1080 HEVC-10bit OPUS][2009]";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestEposideParse()
|
||||
{
|
||||
// 混合中英文
|
||||
var fileName = "新世界.New.World.2013.BluRay.1080p.x265.10bit.MNHD-FRDS";
|
||||
var parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
// 只英文
|
||||
fileName = "She-Hulk.Attorney.At.Law.S01E01.1080p.WEBRip.x265-RARBG";
|
||||
var anitomyResult = AnitomySharp.AnitomySharp.Parse(fileName);
|
||||
Console.WriteLine(anitomyResult.ToJson());
|
||||
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
// anime
|
||||
fileName = "[YYDM-11FANS][THERMAE_ROMAE][02][BDRIP][720P][X264-10bit_AAC][7FF2269F]";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
fileName = "[WMSUB][Detective Conan - Zero‘s Tea Time ][S01][E06][BIG5][1080P].mp4";
|
||||
parseResult = NameParser.Parse(fileName);
|
||||
Console.WriteLine(parseResult.ToJson());
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@ namespace Jellyfin.Plugin.MetaShark.Api
|
|||
Regex regSid = new Regex(@"sid: (\d+?),", RegexOptions.Compiled);
|
||||
Regex regCat = new Regex(@"\[(.+?)\]", RegexOptions.Compiled);
|
||||
Regex regYear = new Regex(@"(\d{4})", RegexOptions.Compiled);
|
||||
Regex regOriginalName = new Regex(@"原名[::](.+?)\s*?\/", RegexOptions.Compiled);
|
||||
Regex regDirector = new Regex(@"导演: (.+?)\n", RegexOptions.Compiled);
|
||||
Regex regWriter = new Regex(@"编剧: (.+?)\n", RegexOptions.Compiled);
|
||||
Regex regActor = new Regex(@"主演: (.+?)\n", RegexOptions.Compiled);
|
||||
|
@ -165,6 +166,7 @@ namespace Jellyfin.Plugin.MetaShark.Api
|
|||
var cat = titleStr.GetMatchGroup(this.regCat);
|
||||
var subjectStr = movieElement.GetText("div.rating-info>.subject-cast") ?? string.Empty;
|
||||
var year = subjectStr.GetMatchGroup(this.regYear);
|
||||
var originalName = subjectStr.GetMatchGroup(this.regOriginalName);
|
||||
var desc = movieElement.GetText("div.content>p") ?? string.Empty;
|
||||
if (cat != "电影" && cat != "电视剧")
|
||||
{
|
||||
|
@ -174,7 +176,7 @@ namespace Jellyfin.Plugin.MetaShark.Api
|
|||
var movie = new DoubanSubject();
|
||||
movie.Sid = sid;
|
||||
movie.Name = name;
|
||||
movie.OriginalName = subjectStr.Split("/").FirstOrDefault(a => a.Contains("原名:"),"").Replace("原名:","");
|
||||
movie.OriginalName = !string.IsNullOrEmpty(originalName) ? originalName : name;
|
||||
movie.Genre = cat;
|
||||
movie.Category = cat;
|
||||
movie.Img = img;
|
||||
|
|
|
@ -57,7 +57,8 @@
|
|||
<label class="inputLabel inputLabelUnfocused" for="TmdbHost">Api Host</label>
|
||||
<input id="TmdbHost" name="TmdbHost" type="text" is="emby-input"
|
||||
placeholder="api.tmdb.org" />
|
||||
<div class="fieldDescription">填写Api域名,默认api.tmdb.org.(需重启才能生效)</div>
|
||||
<div class="fieldDescription">
|
||||
填写Api域名,可选api.tmdb.org/api.themoviedb.org,默认api.tmdb.org.(需重启才能生效)</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block emby-button">
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Plugin.MetaShark.Model;
|
||||
|
||||
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 seasonSuffixReg = new Regex(@"[ .]S\d{1,2}$", RegexOptions.Compiled);
|
||||
|
||||
public static ParseNameResult Parse(string fileName, bool isTvSeries = false)
|
||||
{
|
||||
var parseResult = new ParseNameResult();
|
||||
var anitomyResult = AnitomySharp.AnitomySharp.Parse(fileName);
|
||||
foreach (var item in anitomyResult)
|
||||
{
|
||||
switch (item.Category)
|
||||
{
|
||||
case AnitomySharp.Element.ElementCategory.ElementAnimeTitle:
|
||||
// 处理混合中英文的标题,中文一般在最前面,如V字仇杀队.V.for.Vendetta
|
||||
char[] seperatorChars = { ' ', '.' };
|
||||
var firstSpaceIndex = item.Value.IndexOfAny(seperatorChars);
|
||||
if (firstSpaceIndex > 0)
|
||||
{
|
||||
var firstString = item.Value.Substring(0, firstSpaceIndex);
|
||||
if (firstString.HasChinese())
|
||||
{
|
||||
parseResult.ChineseName = CleanName(firstString);
|
||||
parseResult.Name = CleanName(item.Value.Substring(firstSpaceIndex + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
parseResult.Name = CleanName(item.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parseResult.Name = CleanName(item.Value);
|
||||
}
|
||||
break;
|
||||
case AnitomySharp.Element.ElementCategory.ElementEpisodeNumber:
|
||||
var year = ParseYear(item.Value);
|
||||
if (year > 0)
|
||||
{
|
||||
parseResult.Year = year;
|
||||
}
|
||||
else
|
||||
{
|
||||
var indexNumber = item.Value.ToInt();
|
||||
if (indexNumber > 0)
|
||||
{
|
||||
parseResult.IndexNumber = item.Value.ToInt();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AnitomySharp.Element.ElementCategory.ElementAnimeType:
|
||||
if (item.Value == "SP")
|
||||
{
|
||||
parseResult.IsSpecial = true;
|
||||
}
|
||||
break;
|
||||
case AnitomySharp.Element.ElementCategory.ElementAnimeYear:
|
||||
parseResult.Year = item.Value.ToInt();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(parseResult.Name))
|
||||
{
|
||||
parseResult.Name = fileName;
|
||||
}
|
||||
|
||||
return parseResult;
|
||||
}
|
||||
|
||||
private static string CleanName(string name)
|
||||
{
|
||||
// 电视剧名称后紧跟季信息时,会附加到名称中,需要去掉
|
||||
name = seasonSuffixReg.Replace(name, string.Empty);
|
||||
|
||||
return name.Replace(".", " ").Trim();
|
||||
}
|
||||
|
||||
// emby原始电影解析
|
||||
public static ParseNameResult ParseMovie(string fileName)
|
||||
{
|
||||
var parseResult = new ParseNameResult();
|
||||
var nameOptions = new Emby.Naming.Common.NamingOptions();
|
||||
var result = Emby.Naming.Video.VideoResolver.CleanDateTime(fileName, nameOptions);
|
||||
if (Emby.Naming.Video.VideoResolver.TryCleanString(result.Name, nameOptions, out var cleanName))
|
||||
{
|
||||
parseResult.Name = cleanName;
|
||||
parseResult.Year = result.Year;
|
||||
}
|
||||
else
|
||||
{
|
||||
parseResult.Name = result.Name;
|
||||
parseResult.Year = result.Year;
|
||||
}
|
||||
return parseResult;
|
||||
}
|
||||
|
||||
|
||||
private static int ParseYear(string val)
|
||||
{
|
||||
var match = yearReg.Match(val);
|
||||
if (match.Success && match.Groups.Count > 0)
|
||||
{
|
||||
return match.Groups[0].Value.ToInt();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 判断是否为动漫
|
||||
// https://github.com/jxxghp/nas-tools/blob/f549c924558fd49e183333285bc6a804af1a2cb7/app/media/meta/metainfo.py#L51
|
||||
private static bool IsAnime(string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Regex.Match(name, @"【[+0-9XVPI-]+】\s*【", RegexOptions.IgnoreCase).Success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Regex.Match(name, @"\s+-\s+[\dv]{1,4}\s+", RegexOptions.IgnoreCase).Success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Regex.Match(name, @"S\d{2}\s*-\s*S\d{2}|S\d{2}|\s+S\d{1,2}|EP?\d{2,4}\s*-\s*EP?\d{2,4}|EP?\d{2,4}|\s+EP?\d{1,4}", RegexOptions.IgnoreCase).Success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Regex.Match(name, @"\[[+0-9XVPI-]+]\s*\[", RegexOptions.IgnoreCase).Success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,10 +46,21 @@ namespace Jellyfin.Plugin.MetaShark.Core
|
|||
|
||||
public static bool IsChinese(this string s)
|
||||
{
|
||||
Regex chineseReg = new Regex(@"[\u4e00-\u9fa5]{1,}", RegexOptions.Compiled);
|
||||
Regex chineseReg = new Regex(@"[\u4e00-\u9fa5:]{1,}", RegexOptions.Compiled);
|
||||
return chineseReg.IsMatch(s.Replace(" ", string.Empty).Trim());
|
||||
}
|
||||
|
||||
public static bool HasChinese(this string s)
|
||||
{
|
||||
Regex chineseReg = new Regex(@"[\u4e00-\u9fa5]", RegexOptions.Compiled);
|
||||
return chineseReg.Match(s).Success;
|
||||
}
|
||||
|
||||
public static bool IsSameLanguage(this string s1, string s2)
|
||||
{
|
||||
return s1.IsChinese() && s2.IsChinese();
|
||||
}
|
||||
|
||||
public static double Distance(this string s1, string s2)
|
||||
{
|
||||
var jw = new JaroWinkler();
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
|
||||
namespace Jellyfin.Plugin.MetaShark.Model
|
||||
{
|
||||
public class ParseNameResult : ItemLookupInfo
|
||||
{
|
||||
public string ChineseName { get; set; }
|
||||
|
||||
public bool IsSpecial { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
namespace Jellyfin.Plugin.MetaShark.Parser
|
||||
{
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class BTNamePareser
|
||||
{
|
||||
private Regex btGroupReg = new Regex(@"\[[a-zA-Z\-]*\]", RegexOptions.Compiled);
|
||||
private Regex yearReg = new Regex(@"[12][890][78901234][0-9]", RegexOptions.Compiled);
|
||||
private Regex resoReg = new Regex(@"([0-9]{3,4}[pP])|([0-9]{3,4}[iI])|([hH][dD])|(4[kK])|([sS][dD])", RegexOptions.Compiled);
|
||||
private Regex codeReg = new Regex(@"([hH]\.[0-9]{3})|([vV][cC]-?1)|([xX][vV][iI][dD])
|
||||
|([mM][pP][eE][Gg]-?\d)|([fF][lL][aA][Cc])|([aA][pP][eE])|([dD][tT][sS])|([aA][cC]-?\d)|([wW][aA][vV])
|
||||
|([mM][pP]\d)|([aA][lL][aA][cC])|([aA]{2}[cC])"
|
||||
, RegexOptions.Compiled);
|
||||
private Regex chineseReg = new Regex(@"[\u4e00-\u9fa5]{1,}", RegexOptions.Compiled);
|
||||
private Regex serisReg = new Regex(@"([sS][0-9]{1,2})|([Ss][eE][rR][iI][sS][0-9]{1,2})", RegexOptions.Compiled);
|
||||
private Regex episodeReg = new Regex(@"([eE][0-9]{1,3})|([Ee][pP][iI][sS][oO][dD][eE][0-9]{1,3})", RegexOptions.Compiled);
|
||||
|
||||
public class ResourceInfo
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
public string? ChineseName { get; set; }
|
||||
public string? EnglishName { get; set; }
|
||||
public string? Year { get; set; }
|
||||
public string? Resolution { get; set; }
|
||||
public string? Seris { get; set; }
|
||||
public string? Episode { get; set; }
|
||||
|
||||
public bool isSeris()
|
||||
{
|
||||
return Seris != null || Episode != null;
|
||||
}
|
||||
}
|
||||
|
||||
public ResourceInfo Match(string btFileName, ILogger _logger)
|
||||
{
|
||||
NameTrimmer trimmer = new NameTrimmer();
|
||||
var trimmedName = trimmer.trimName(btFileName, _logger);
|
||||
var btgroup = GetMatch(trimmedName, btGroupReg);
|
||||
var year = GetMatch(trimmedName, yearReg);
|
||||
var reso = GetMatch(trimmedName, resoReg);
|
||||
var code = GetMatch(trimmedName, codeReg);
|
||||
var chinese = GetMatch(trimmedName, chineseReg);
|
||||
var seris = GetMatch(trimmedName, serisReg);
|
||||
var episode = GetMatch(trimmedName, episodeReg);
|
||||
|
||||
ResourceInfo info = new ResourceInfo();
|
||||
info.ChineseName = chinese?.MatchContent;
|
||||
info.Year = year?.MatchContent;
|
||||
info.Seris = seris?.MatchContent;
|
||||
info.Episode = episode?.MatchContent;
|
||||
info.Resolution = reso?.MatchContent;
|
||||
info.Name = trimmedName;
|
||||
info.EnglishName = ReplaceMatch(trimmedName, "", chineseReg).Trim();
|
||||
return info;
|
||||
|
||||
}
|
||||
|
||||
private class MatchResult
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public string MatchContent { get; set; }
|
||||
|
||||
}
|
||||
private MatchResult? GetMatch(string text, Regex reg)
|
||||
{
|
||||
var match = reg.Match(text);
|
||||
if (match.Success && match.Groups.Count > 0)
|
||||
{
|
||||
return new MatchResult
|
||||
{
|
||||
Index = match.Groups[0].Index,
|
||||
MatchContent = match.Groups[0].Value.Trim(),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string ReplaceMatch(string text, string replacement, Regex reg)
|
||||
{
|
||||
return reg.Replace(text, replacement);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
|
||||
namespace Jellyfin.Plugin.MetaShark.Parser
|
||||
{
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
class NameTrimmer
|
||||
{
|
||||
|
||||
private static TreeNode node;
|
||||
private const string path = "/Parser/dict.txt";
|
||||
|
||||
|
||||
public static string AssemblyDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
|
||||
UriBuilder uri = new UriBuilder(codeBase);
|
||||
string path = Uri.UnescapeDataString(uri.Path);
|
||||
return Path.GetDirectoryName(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string trimName(string name, ILogger _logger)
|
||||
{
|
||||
if (NameTrimmer.node == null)
|
||||
{
|
||||
_logger.LogInformation($"生成词库树");
|
||||
List<string> dics = new List<string>();
|
||||
List<string> lines = File.ReadAllLines(AssemblyDirectory + path).ToList();
|
||||
lines.ForEach(line =>
|
||||
{
|
||||
string[] words = line.Split(" ");
|
||||
if (words.Length == 2)
|
||||
{
|
||||
dics.Add(words[0]);
|
||||
}
|
||||
});
|
||||
NameTrimmer.node = new TreeNode();
|
||||
node.insertMany(dics);
|
||||
_logger.LogInformation($"生成词库树完成");
|
||||
}
|
||||
_logger.LogInformation($"解析名称");
|
||||
foreach (char c in "!\"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~")
|
||||
{
|
||||
name = name.Replace(c, ' ');
|
||||
}
|
||||
string[] nameWords = name.Split(' ');
|
||||
string empStr = "";
|
||||
_logger.LogInformation($"开始比对" + name);
|
||||
foreach (string word in nameWords)
|
||||
{
|
||||
if (string.IsNullOrEmpty(word))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (NameTrimmer.node.search(word.ToLower()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
empStr += word + " ";
|
||||
}
|
||||
}
|
||||
_logger.LogInformation($"比对结果" + empStr);
|
||||
return empStr;
|
||||
}
|
||||
|
||||
private class TreeNode
|
||||
{
|
||||
private bool IsLeaf = false;
|
||||
private List<TreeNode> nodes = new List<TreeNode>();
|
||||
private char value;
|
||||
|
||||
public void insert(string word)
|
||||
{
|
||||
var currentNode = this;
|
||||
foreach (char c in word)
|
||||
{
|
||||
var findNode = currentNode.nodes.FirstOrDefault(a => a.value == c);
|
||||
if (findNode == null)
|
||||
{
|
||||
|
||||
TreeNode newNode = new TreeNode();
|
||||
newNode.value = c;
|
||||
currentNode.nodes.Add(newNode);
|
||||
currentNode = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentNode = findNode;
|
||||
}
|
||||
|
||||
}
|
||||
currentNode.IsLeaf = true;
|
||||
}
|
||||
public void insertMany(List<string> words)
|
||||
{
|
||||
foreach (var work in words)
|
||||
{
|
||||
this.insert(work);
|
||||
}
|
||||
}
|
||||
public bool search(string word)
|
||||
{
|
||||
var current = this;
|
||||
foreach (char c in word)
|
||||
{
|
||||
if (current != null)
|
||||
{
|
||||
current = current.nodes.FirstOrDefault(a => a.value == c);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return current != null ? current.IsLeaf : false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,419 +0,0 @@
|
|||
www 3268
|
||||
org 685
|
||||
mp4 16210
|
||||
cc 620
|
||||
the 10098
|
||||
web 4943
|
||||
dlrip 539
|
||||
x264 7897
|
||||
720p 7931
|
||||
mkv 7680
|
||||
tv 774
|
||||
rip 252
|
||||
flac 1199
|
||||
sis001 1584
|
||||
movie 298
|
||||
1080p 14008
|
||||
nf 320
|
||||
dl 2478
|
||||
x265 2381
|
||||
10bit 867
|
||||
hdr 350
|
||||
ddp5 748
|
||||
sexinsex 351
|
||||
net 857
|
||||
dark 217
|
||||
of 3905
|
||||
3d 389
|
||||
real 251
|
||||
x64 264
|
||||
com 5469
|
||||
rmvb 1159
|
||||
no 1867
|
||||
on 728
|
||||
live 427
|
||||
iso 542
|
||||
by 1886
|
||||
1280x720 487
|
||||
hevc 1810
|
||||
aac 3110
|
||||
x 833
|
||||
family 377
|
||||
multi 247
|
||||
subs 342
|
||||
thz 610
|
||||
la 1151
|
||||
heyzo 510
|
||||
xxx 7648
|
||||
2160p 1209
|
||||
ktr 2665
|
||||
rarbg 4056
|
||||
art 335
|
||||
little 382
|
||||
digital 421
|
||||
portable 237
|
||||
war 290
|
||||
with 1084
|
||||
bluray 3310
|
||||
h264 2757
|
||||
dts 1075
|
||||
xyz 411
|
||||
fc2ppv 632
|
||||
ts 514
|
||||
zip 3188
|
||||
you 452
|
||||
it 423
|
||||
va 303
|
||||
music 216
|
||||
mp3 996
|
||||
320kbps 236
|
||||
hd 2964
|
||||
cum 305
|
||||
avi 5544
|
||||
cd 251
|
||||
webrip 2874
|
||||
yts 427
|
||||
mx 331
|
||||
dvdrip 2255
|
||||
for 1090
|
||||
teen 377
|
||||
and 3868
|
||||
fuck 491
|
||||
480p 1169
|
||||
black 846
|
||||
in 2108
|
||||
vol 1066
|
||||
internal 215
|
||||
n1c 362
|
||||
to 1537
|
||||
7z 372
|
||||
ass 434
|
||||
b 435
|
||||
xvid 2726
|
||||
ac3 1482
|
||||
a 2816
|
||||
two 214
|
||||
i 979
|
||||
bdrip 1771
|
||||
rose 250
|
||||
me 1077
|
||||
1pondo 311
|
||||
dual 516
|
||||
raws 574
|
||||
girl 660
|
||||
gb 571
|
||||
pack 352
|
||||
edition 428
|
||||
avc 946
|
||||
new 919
|
||||
life 335
|
||||
h265 409
|
||||
hardcore 267
|
||||
red 269
|
||||
fc2 426
|
||||
ppv 448
|
||||
o 397
|
||||
white 342
|
||||
imageset 249
|
||||
all 555
|
||||
season 690
|
||||
hdtv 2013
|
||||
pl 417
|
||||
pedo 597
|
||||
baby 310
|
||||
eztv 1192
|
||||
re 730
|
||||
fhd 574
|
||||
bbqddq 216
|
||||
man 380
|
||||
tgx 708
|
||||
dd5 348
|
||||
h 798
|
||||
rartv 368
|
||||
tokyo 546
|
||||
hot 961
|
||||
xbay 208
|
||||
my 1027
|
||||
game 268
|
||||
rar 1740
|
||||
deep 264
|
||||
ru 376
|
||||
sex 986
|
||||
stars 233
|
||||
team 370
|
||||
audio 378
|
||||
repack 446
|
||||
her 547
|
||||
best 450
|
||||
dvd 575
|
||||
rus 816
|
||||
lostfilm 246
|
||||
e 346
|
||||
brrip 461
|
||||
fucked 240
|
||||
theav 244
|
||||
wa 324
|
||||
is 491
|
||||
english 984
|
||||
m 248
|
||||
ita 510
|
||||
eng 1380
|
||||
sub 398
|
||||
ii 315
|
||||
pthc 1820
|
||||
lolita 324
|
||||
xvx 475
|
||||
t 225
|
||||
69av 252
|
||||
one 554
|
||||
divx 207
|
||||
house 259
|
||||
hdrip 601
|
||||
bd 657
|
||||
american 349
|
||||
ntb 353
|
||||
tvboxnow 413
|
||||
chs 754
|
||||
v 391
|
||||
pdf 1202
|
||||
f 216
|
||||
complete 524
|
||||
collection 598
|
||||
ukr 201
|
||||
video 409
|
||||
studio 268
|
||||
ptsc 291
|
||||
blue 229
|
||||
angel 316
|
||||
bbc 224
|
||||
time 336
|
||||
series 264
|
||||
prt 400
|
||||
olo 512
|
||||
s 595
|
||||
de 750
|
||||
preteen 507
|
||||
anal 863
|
||||
r 409
|
||||
jpg 284
|
||||
wmv 1489
|
||||
ni 255
|
||||
last 240
|
||||
amzn 597
|
||||
part 521
|
||||
full 417
|
||||
remux 297
|
||||
ma 466
|
||||
w 212
|
||||
fucking 250
|
||||
aavv333 256
|
||||
big 927
|
||||
at 396
|
||||
hjd2048 287
|
||||
sd 733
|
||||
fgt 240
|
||||
child 237
|
||||
uncensored 384
|
||||
boy 284
|
||||
aac2 252
|
||||
4k 489
|
||||
cock 382
|
||||
ion10 268
|
||||
pussy 321
|
||||
tits 217
|
||||
c 813
|
||||
djvu 279
|
||||
wild 220
|
||||
club 411
|
||||
high 258
|
||||
d 487
|
||||
brazzers 265
|
||||
megusta 235
|
||||
dead 277
|
||||
gog 238
|
||||
out 248
|
||||
christmas 214
|
||||
private 253
|
||||
top 239
|
||||
wife 222
|
||||
3dmgame 292
|
||||
green 352
|
||||
french 391
|
||||
extreme 231
|
||||
mpg 788
|
||||
gets 250
|
||||
first 308
|
||||
korean 236
|
||||
star 622
|
||||
japanese 267
|
||||
av 293
|
||||
torrenting 483
|
||||
up 357
|
||||
l 226
|
||||
young 364
|
||||
sky 273
|
||||
story 241
|
||||
chinese 256
|
||||
hd1080p 344
|
||||
kleenex 326
|
||||
big5 479
|
||||
1920x1080 340
|
||||
carib 292
|
||||
v1 441
|
||||
hindi 208
|
||||
exe 407
|
||||
day 319
|
||||
pro 307
|
||||
atmos 291
|
||||
sexy 279
|
||||
love 927
|
||||
final 282
|
||||
epub 475
|
||||
night 286
|
||||
vs 296
|
||||
next 421
|
||||
msd 209
|
||||
us 295
|
||||
en 498
|
||||
porn 289
|
||||
k 233
|
||||
wrb 262
|
||||
girls 579
|
||||
nike 255
|
||||
blu 316
|
||||
ray 400
|
||||
j 207
|
||||
from 357
|
||||
alexis 207
|
||||
mide 205
|
||||
world 385
|
||||
san 278
|
||||
g 281
|
||||
hard 278
|
||||
good 217
|
||||
p 397
|
||||
blonde 206
|
||||
castellano 278
|
||||
rq 282
|
||||
cap 205
|
||||
mov 243
|
||||
cht 234
|
||||
your 301
|
||||
raw 212
|
||||
milf 240
|
||||
snis 245
|
||||
avistaz 1
|
||||
cinemaz 1
|
||||
exoticaz 1
|
||||
privatehd 1
|
||||
aidoru!online 1
|
||||
bibliotik 1
|
||||
bwt 1
|
||||
concertos 1
|
||||
xtr 1
|
||||
space 1
|
||||
torrents 1
|
||||
teamhd 1
|
||||
empornium 1
|
||||
六维空间 1
|
||||
skyeysnow 1
|
||||
ab 1
|
||||
btn 1
|
||||
ggn 1
|
||||
gfxpeers 1
|
||||
jpopsuki 1
|
||||
lztr 1
|
||||
nebulance 1
|
||||
ptp 1
|
||||
alpharatio 1
|
||||
anthelion 1
|
||||
bemaniso 1
|
||||
brks 1
|
||||
dic 1
|
||||
gpw 1
|
||||
forever 1
|
||||
oppaitime 1
|
||||
ops 1
|
||||
red 1
|
||||
snakepop 1
|
||||
sugoimusic 1
|
||||
uhdbits 1
|
||||
cgpeers 1
|
||||
iptorrents 1
|
||||
torrentstd 1
|
||||
1ptbar 1
|
||||
52pt 1
|
||||
爱薇网 1
|
||||
byrbt 1
|
||||
chdbits 1
|
||||
discfan 1
|
||||
torrentccf 1
|
||||
hdai 1
|
||||
hdatmos 1
|
||||
hdchina 1
|
||||
hdcity 1
|
||||
dolby 1
|
||||
hdfans 1
|
||||
hdhome 1
|
||||
hdsky 1
|
||||
hdtime 1
|
||||
hdzone 1
|
||||
海棠pt 1
|
||||
hudbt 1
|
||||
joyhd 1
|
||||
mteam 1
|
||||
lemonhd 1
|
||||
南洋pt 1
|
||||
nicept 1
|
||||
npubits 1
|
||||
opencd 1
|
||||
ourbits 1
|
||||
btschool 1
|
||||
tlfbits 1
|
||||
hd4fans 1
|
||||
伊甸园 1
|
||||
hdu 1
|
||||
pt@keepfrds 1
|
||||
ptmsg 1
|
||||
麦田pt 1
|
||||
葡萄 1
|
||||
聆音club 1
|
||||
溪涧草堂pt 1
|
||||
pter 1
|
||||
pthome 1
|
||||
烧包 1
|
||||
ssd 1
|
||||
北洋园 1
|
||||
u2 1
|
||||
ultrahd 1
|
||||
备胎 1
|
||||
haidan 1
|
||||
hdarea 1
|
||||
百川pt 1
|
||||
pttime 1
|
||||
aither 1
|
||||
asiancinema 1
|
||||
beyondhd 1
|
||||
blutopia 1
|
||||
jptv 1
|
||||
hdpost 1
|
||||
animetorrents 1
|
||||
bb 1
|
||||
ccfbits 1
|
||||
cinemageddon 1
|
||||
filelist 1
|
||||
hdb 1
|
||||
hdroute 1
|
||||
karagarga 1
|
||||
pornbits 1
|
||||
pussytorrents 1
|
||||
sdbits 1
|
||||
intheshadow 1
|
||||
tg 1
|
||||
ttg 1
|
||||
cinematik 1
|
||||
mtv 1
|
||||
myanonamouse 1
|
||||
torrentleech 1
|
||||
torrentseeds 1
|
||||
ptt 1
|
|
@ -21,7 +21,6 @@ using System.Web;
|
|||
using TMDbLib.Objects.General;
|
||||
using Jellyfin.Plugin.MetaShark.Configuration;
|
||||
using Jellyfin.Plugin.MetaShark.Core;
|
||||
using Jellyfin.Plugin.MetaShark.Parser;
|
||||
|
||||
namespace Jellyfin.Plugin.MetaShark.Providers
|
||||
{
|
||||
|
@ -81,16 +80,13 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
{
|
||||
// ParseName is required here.
|
||||
// Caller provides the filename with extension stripped and NOT the parsed filename
|
||||
BTNamePareser pareser = new BTNamePareser();
|
||||
var search_info = pareser.Match(info.Name, this._logger);
|
||||
string searchName = search_info.ChineseName != null ? search_info.ChineseName : search_info.EnglishName;
|
||||
var fileName = Path.GetFileName(info.Path) ?? info.Name;
|
||||
var parseResult = NameParser.Parse(fileName);
|
||||
var searchName = !string.IsNullOrEmpty(parseResult.ChineseName) ? parseResult.ChineseName : parseResult.Name;
|
||||
info.Year = parseResult.Year; // 默认parser对anime年份会解析出错,以anitomy为准
|
||||
|
||||
if (info.Year == null && search_info.Year != null)
|
||||
{
|
||||
info.Year = int.Parse(search_info.Year);
|
||||
}
|
||||
|
||||
this.Log($"GuessByDouban of [name]: {info.Name} year: {info.Year} search name: {searchName}");
|
||||
this.Log($"GuessByDouban of [name]: {info.Name} [fileName]: {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)
|
||||
|
@ -104,24 +100,33 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
{
|
||||
continue;
|
||||
}
|
||||
//英文关键词搜,结果是中文的情况,不适用相似匹配
|
||||
if (jw.Similarity(searchName, item.Name) > 0.8
|
||||
|| jw.Similarity(searchName, item.OriginalName) > 0.8)
|
||||
|
||||
|
||||
//英文关键词搜,结果是只有中文/繁体中文时,不适用相似匹配,如Who Am I
|
||||
if (jw.Similarity(searchName, item.Name) < 0.8 && jw.Similarity(searchName, item.OriginalName) < 0.8)
|
||||
{
|
||||
if (!searchName.IsSameLanguage(item.Name) && !searchName.IsSameLanguage(item.OriginalName))
|
||||
{
|
||||
// 特殊处理下使用英文搜索,只有中文标题的情况
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 不存在年份需要比较时,直接返回
|
||||
if (info.Year == null || info.Year == 0)
|
||||
{
|
||||
this.Log($"GuessByDouban of [name] found Sid: {item.Sid}");
|
||||
return item.Sid;
|
||||
}
|
||||
if (item.Name.Contains(searchName) && (info.Year != null && info.Year == item.Year))
|
||||
|
||||
if (info.Year == item.Year)
|
||||
{
|
||||
this.Log($"GuessByDouban of [name] found Sid: {item.Sid}");
|
||||
return item.Sid;
|
||||
}
|
||||
if (searchName.IsChinese() != item.Name.IsChinese()
|
||||
&& searchName.IsChinese() != item.OriginalName.IsChinese())
|
||||
{
|
||||
this.Log($"GuessByDouban of [name] found tmdb id: \"{item.Sid}\"");
|
||||
return item.Sid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -135,7 +140,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
return null;
|
||||
}
|
||||
|
||||
this.Log($"GuestDoubanSeasonByYear of [name]: {name} year: {year}");
|
||||
this.Log($"GuestDoubanSeasonByYear of [name]: {name} [year]: {year}");
|
||||
var result = await this._doubanApi.SearchAsync(name, cancellationToken).ConfigureAwait(false);
|
||||
var jw = new JaroWinkler();
|
||||
foreach (var item in result)
|
||||
|
@ -144,15 +149,22 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// this.Log($"GuestDoubanSeasonByYear name: {name} douban_name: {item.Name} douban_sid: {item.Sid} douban_year: {item.Year} score: {score} ");
|
||||
if (jw.Similarity(name, item.Name) > 0.8)
|
||||
//英文关键词搜,结果是只有中文/繁体中文时,不适用相似匹配,如Who Am I
|
||||
if (jw.Similarity(name, item.Name) < 0.8 && jw.Similarity(name, item.OriginalName) < 0.8)
|
||||
{
|
||||
this.Log($"GuestDoubanSeasonByYear of [name] found Sid: {item.Sid}");
|
||||
return item.Sid;
|
||||
if (!name.IsSameLanguage(item.Name) && !name.IsSameLanguage(item.OriginalName))
|
||||
{
|
||||
// 特殊处理下使用英文搜索,只有中文标题的情况
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((name.IsChinese() != item.Name.IsChinese()
|
||||
&& name.IsChinese() != item.OriginalName.IsChinese()) || year == item.Year)
|
||||
if (year == item.Year)
|
||||
{
|
||||
this.Log($"GuestDoubanSeasonByYear of [name] found Sid: \"{item.Sid}\"");
|
||||
return item.Sid;
|
||||
|
@ -162,61 +174,17 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
return null;
|
||||
}
|
||||
|
||||
// 通过季数,搜索结果按年份排序后,取对应季数索引项(不适合每季标题差异太大的,如葫芦兄弟和葫芦小金刚)
|
||||
protected async Task<string?> GuestDoubanSeasonByNumberAsync(string name, int? seasonNumber, CancellationToken cancellationToken)
|
||||
{
|
||||
if (seasonNumber == null || seasonNumber == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
this.Log($"GuestDoubanSeasonByNumber of [name]: {name} seasonNumber: {seasonNumber}");
|
||||
var result = await this._doubanApi.SearchAsync(name, cancellationToken).ConfigureAwait(false);
|
||||
var jw = new JaroWinkler();
|
||||
var matchList = new List<DoubanSubject>();
|
||||
foreach (var item in result)
|
||||
{
|
||||
if (item.Category != "电视剧")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var score = jw.Similarity(name, item.Name);
|
||||
if (score < 0.8)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// this.Log($"GuestDoubanSeasonByNumber name: {name} douban_name: {item.Name} douban_sid: {item.Sid} douban_year: {item.Year} score: {score} ");
|
||||
matchList.Add(item);
|
||||
}
|
||||
|
||||
matchList.Sort((x, y) => x.Year.CompareTo(y.Year));
|
||||
if (matchList.Count >= seasonNumber)
|
||||
{
|
||||
var matchItem = matchList[seasonNumber.Value - 1];
|
||||
var sid = matchItem.Sid;
|
||||
this.Log($"GuestDoubanSeasonByNumber of [name] found Sid: {sid}");
|
||||
return sid;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected async Task<string?> GuestByTmdbAsync(ItemLookupInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
// ParseName is required here.
|
||||
// Caller provides the filename with extension stripped and NOT the parsed filename
|
||||
BTNamePareser pareser = new BTNamePareser();
|
||||
var search_info = pareser.Match(info.Name, this._logger);
|
||||
string searchName = search_info.ChineseName != null ? search_info.ChineseName : search_info.EnglishName;
|
||||
var fileName = Path.GetFileName(info.Path) ?? info.Name;
|
||||
var parseResult = NameParser.Parse(fileName);
|
||||
var searchName = !string.IsNullOrEmpty(parseResult.ChineseName) ? parseResult.ChineseName : parseResult.Name;
|
||||
info.Year = parseResult.Year; // 默认parser对anime年份会解析出错,以anitomy为准
|
||||
|
||||
if (info.Year == null && search_info.Year != null)
|
||||
{
|
||||
info.Year = int.Parse(search_info.Year);
|
||||
}
|
||||
|
||||
this.Log($"GuestByTmdb of [name]: {info.Name} search name: {searchName}");
|
||||
this.Log($"GuestByTmdb of [name]: {info.Name} [fileName]: {fileName} [year]: {info.Year} [search name]: {searchName}");
|
||||
var jw = new JaroWinkler();
|
||||
|
||||
switch (info)
|
||||
|
@ -231,8 +199,8 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
this.Log($"GuestByTmdb of [name] found tmdb id: \"{item.Id}\"");
|
||||
return item.Id.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
if (searchName.IsChinese() != item.Title.IsChinese()
|
||||
&& searchName.IsChinese() != item.OriginalTitle.IsChinese())
|
||||
// 特殊处理下使用英文搜索,只有中文标题的情况,当匹配成功
|
||||
if (!searchName.IsSameLanguage(item.Title) && !searchName.IsSameLanguage(item.OriginalTitle))
|
||||
{
|
||||
this.Log($"GuestByTmdb of [name] found tmdb id: \"{item.Id}\"");
|
||||
return item.Id.ToString(CultureInfo.InvariantCulture);
|
||||
|
@ -249,8 +217,8 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
this.Log($"GuestByTmdb of [name] found tmdb id: \"{item.Id}\"");
|
||||
return item.Id.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
if (searchName.IsChinese() != item.Name.IsChinese()
|
||||
&& searchName.IsChinese() != item.OriginalName.IsChinese())
|
||||
// 特殊处理下使用英文搜索,只有中文标题的情况,当匹配成功
|
||||
if (!searchName.IsSameLanguage(item.Name) && !searchName.IsSameLanguage(item.OriginalName))
|
||||
{
|
||||
this.Log($"GuestByTmdb of [name] found tmdb id: \"{item.Id}\"");
|
||||
return item.Id.ToString(CultureInfo.InvariantCulture);
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
var metaSource = info.GetProviderId(Plugin.ProviderId); // 刷新元数据时会有值
|
||||
if (string.IsNullOrEmpty(sid) && string.IsNullOrEmpty(tmdbId))
|
||||
{
|
||||
// 自动扫描匹配搜索
|
||||
// 自动扫描搜索匹配元数据
|
||||
sid = await this.GuessByDoubanAsync(info, cancellationToken).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(sid))
|
||||
{
|
||||
|
|
|
@ -88,7 +88,7 @@ namespace Jellyfin.Plugin.MetaShark.Providers
|
|||
var metaSource = info.GetProviderId(Plugin.ProviderId); // 刷新元数据时会有值
|
||||
if (string.IsNullOrEmpty(sid) && string.IsNullOrEmpty(tmdbId))
|
||||
{
|
||||
// 刷新元数据自动匹配搜索
|
||||
// 自动扫描搜索匹配元数据
|
||||
sid = await this.GuessByDoubanAsync(info, cancellationToken).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(sid))
|
||||
{
|
||||
|
|
|
@ -57,5 +57,11 @@ rm -rf MediaBrowser*.dll Microsoft*.dll Newtonsoft*.dll System*.dll Emby*.dll Je
|
|||
|
||||
2. Create a folder, like `metashark` and copy `artifacts/*.dll` into it
|
||||
|
||||
3. Move folder `metashark` to jellyfin `data/plugin` folder
|
||||
3. Move folder `metashark` to jellyfin `data/plugins` folder
|
||||
|
||||
|
||||
## QA
|
||||
|
||||
1. Plugin run in error: `System.BadImageFormatException: Bad IL format.`
|
||||
|
||||
> Remove all hidden file in `metashark` plugin folder
|
Loading…
Reference in New Issue