feat 支持自定义词表

This commit is contained in:
jxxghp
2023-07-17 13:05:06 +08:00
parent 5f613874db
commit 2b9c4b081e
9 changed files with 163 additions and 57 deletions

View File

@ -2,7 +2,7 @@ import re
import zhconv
import anitopy
from app.core.meta.metabase import MetaBase
from app.core.meta.release_groups import ReleaseGroupsMatcher
from app.core.meta.releasegroup import ReleaseGroupsMatcher
from app.utils.string import StringUtils
from app.schemas.types import MediaType

View File

@ -15,7 +15,9 @@ class MetaBase(object):
"""
# 是否处理的文件
isfile: bool = False
# 原字符串
# 原标题字符串
title: str = ""
# 识别用字符串
org_string: Optional[str] = None
# 副标题
subtitle: Optional[str] = None
@ -53,6 +55,8 @@ class MetaBase(object):
video_encode: Optional[str] = None
# 音频编码
audio_encode: Optional[str] = None
# 应用的识别词信息
apply_words: Optional[List[str]] = None
# 副标题解析
_subtitle_flag = False

View File

@ -3,7 +3,7 @@ from pathlib import Path
from app.core.config import settings
from app.core.meta.metabase import MetaBase
from app.core.meta.release_groups import ReleaseGroupsMatcher
from app.core.meta.releasegroup import ReleaseGroupsMatcher
from app.utils.string import StringUtils
from app.utils.tokens import Tokens
from app.schemas.types import MediaType

View File

@ -1,5 +1,7 @@
import regex as re
from app.db.systemconfig_oper import SystemConfigOper
from app.schemas.types import SystemConfigKey
from app.utils.singleton import Singleton
@ -8,8 +10,7 @@ class ReleaseGroupsMatcher(metaclass=Singleton):
识别制作组字幕组
"""
__release_groups: str = None
custom_release_groups: str = None
custom_separator: str = None
# 内置组
RELEASE_GROUPS: dict = {
"0ff": ['FF(?:(?:A|WE)B|CD|E(?:DU|B)|TV)'],
"1pt": [],
@ -74,6 +75,7 @@ class ReleaseGroupsMatcher(metaclass=Singleton):
}
def __init__(self):
self.systemconfig = SystemConfigOper()
release_groups = []
for site_groups in self.RELEASE_GROUPS.values():
for release_group in site_groups:
@ -89,8 +91,10 @@ class ReleaseGroupsMatcher(metaclass=Singleton):
if not title:
return ""
if not groups:
if self.custom_release_groups:
groups = f"{self.__release_groups}|{self.custom_release_groups}"
# 自定义组
custom_release_groups = self.systemconfig.get(SystemConfigKey.CustomReleaseGroups)
if custom_release_groups:
groups = f"{self.__release_groups}|{custom_release_groups}"
else:
groups = self.__release_groups
title = f"{title} "
@ -100,12 +104,4 @@ class ReleaseGroupsMatcher(metaclass=Singleton):
for item in re.findall(groups_re, title):
if item not in unique_groups:
unique_groups.append(item)
separator = self.custom_separator or "@"
return separator.join(unique_groups)
def update_custom(self, release_groups: str = None, separator: str = None):
"""
更新自定义制作组/字幕组自定义分隔符
"""
self.custom_release_groups = release_groups
self.custom_separator = separator
return "@".join(unique_groups)

118
app/core/meta/words.py Normal file
View File

@ -0,0 +1,118 @@
from typing import List, Tuple
import cn2an
import regex as re
from app.db.systemconfig_oper import SystemConfigOper
from app.log import logger
from app.schemas.types import SystemConfigKey
from app.utils.singleton import Singleton
class WordsMatcher(metaclass=Singleton):
def __init__(self):
self.systemconfig = SystemConfigOper()
def prepare(self, title: str) -> Tuple[str, List[str]]:
"""
预处理标题,支持三种格式
1屏蔽词
2被替换词 => 替换词
3前定位词 <> 后定位词 >> 偏移量EP
"""
appley_words = []
# 读取自定义识别词
words: List[str] = self.systemconfig.get(SystemConfigKey.CustomIdentifiers) or []
for word in words:
if not word:
continue
try:
if word.count(" => "):
# 替换词
strings = word.split(" => ")
title, message, state = self.__replace_regex(title, strings[0], strings[1])
elif word.count(" >> ") and word.count(" <> "):
# 集偏移
strings = word.split(" <> ")
offsets = strings[1].split(" >> ")
title, message, state = self.__episode_offset(title, strings[0], strings[1],
offsets[1])
else:
# 屏蔽词
title, message, state = self.__replace_regex(title, word, "")
if state:
appley_words.append(word)
else:
logger.error(f"自定义识别词替换失败:{message}")
except Exception as err:
print(str(err))
return title, appley_words
@staticmethod
def __replace_regex(title: str, replaced: str, replace: str) -> Tuple[str, str, bool]:
"""
正则替换
"""
try:
if not re.findall(r'%s' % replaced, title):
return title, "", False
else:
return re.sub(r'%s' % replaced, r'%s' % replace, title), "", True
except Exception as err:
print(str(err))
return title, str(err), False
@staticmethod
def __episode_offset(title: str, front: str, back: str, offset: str) -> Tuple[str, str, bool]:
"""
集数偏移
"""
try:
if back and not re.findall(r'%s' % back, title):
return title, "", False
if front and not re.findall(r'%s' % front, title):
return title, "", False
offset_word_info_re = re.compile(r'(?<=%s.*?)[0-9一二三四五六七八九十]+(?=.*?%s)' % (front, back))
episode_nums_str = re.findall(offset_word_info_re, title)
if not episode_nums_str:
return title, "", False
episode_nums_offset_str = []
offset_order_flag = False
for episode_num_str in episode_nums_str:
episode_num_int = int(cn2an.cn2an(episode_num_str, "smart"))
offset_caculate = offset.replace("EP", str(episode_num_int))
episode_num_offset_int = int(eval(offset_caculate))
# 向前偏移
if episode_num_int > episode_num_offset_int:
offset_order_flag = True
# 向后偏移
elif episode_num_int < episode_num_offset_int:
offset_order_flag = False
# 原值是中文数字转换回中文数字阿拉伯数字则还原0的填充
if not episode_num_str.isdigit():
episode_num_offset_str = cn2an.an2cn(episode_num_offset_int, "low")
else:
count_0 = re.findall(r"^0+", episode_num_str)
if count_0:
episode_num_offset_str = f"{count_0[0]}{episode_num_offset_int}"
else:
episode_num_offset_str = str(episode_num_offset_int)
episode_nums_offset_str.append(episode_num_offset_str)
episode_nums_dict = dict(zip(episode_nums_str, episode_nums_offset_str))
# 集数向前偏移,集数按升序处理
if offset_order_flag:
episode_nums_list = sorted(episode_nums_dict.items(), key=lambda x: x[1])
# 集数向后偏移,集数按降序处理
else:
episode_nums_list = sorted(episode_nums_dict.items(), key=lambda x: x[1], reverse=True)
for episode_num in episode_nums_list:
episode_offset_re = re.compile(
r'(?<=%s.*?)%s(?=.*?%s)' % (front, episode_num[0], back))
title = re.sub(episode_offset_re, r'%s' % episode_num[1], title)
return title, "", True
except Exception as err:
print(str(err))
return title, str(err), False