jellyfin-plugin-metashark/Jellyfin.Plugin.MetaShark/Core/NameParser.cs

154 lines
5.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}