feat: add agent tools for querying and managing filter rules and rule groups

- Add tools for querying built-in and custom filter rules, and for adding, updating, and deleting custom rules and rule groups
- Refactor filter module to use shared builtin rule definitions
- Enhance rule group querying to include syntax guidance and usage references
- Add unittests for agent filter rule tools registration and parsing logic
This commit is contained in:
jxxghp
2026-04-30 12:56:38 +08:00
parent abda9d3212
commit 28a2386f2f
15 changed files with 1776 additions and 166 deletions

View File

@@ -1,14 +1,13 @@
import re
from copy import deepcopy
from typing import List, Tuple, Union, Dict, Optional
from app.core.context import TorrentInfo, MediaInfo
from app.core.metainfo import MetaInfo
from app.helper.rule import RuleHelper
from app.log import logger
from app.modules import _ModuleBase
from app.modules.filter.RuleParser import RuleParser
from app.modules.filter.builtin_rules import BUILTIN_RULE_SET
from app.schemas.types import ModuleType, OtherModulesType, SystemConfigKey
from app.utils.string import StringUtils
class FilterModule(_ModuleBase):
@@ -18,128 +17,10 @@ class FilterModule(_ModuleBase):
# 媒体信息
media: MediaInfo = None
# 内置规则集
rule_set: Dict[str, dict] = {
# 蓝光原盘
"BLU": {
"include": [r'(?i)(\bBlu-?Ray\b.*\b(?:VC-?1|AVC|MPEG-?2)\b|\b(?:UHD|4K|2160p)\b(?:.*Blu-?Ray)?.*\b(?:HEVC|H\.?265)\b|\bBlu-?Ray\b.*\b(?:UHD|4K|2160p)\b.*\b(?:HEVC|H\.?265)\b|\b(?:COMPLETE|FULL)\b.*\b(?:(?:UHD|4K|2160p)\b.*)?Blu-?Ray\b|\b(BD25|BD50|BD66|BD100|BDMV|MiniBD)\b)'],
"exclude": [r'(?i)(\b[XH]\.?264\b|\b[XH]\.?265\b|\bWEB-?DL\b|\bWEB-?RIP\b|\bHDTV(?:RIP)?\b|\bREMUX\b|\bBDRip\b|\bBRRip\b|\bHDRip\b|\bENCODE\b|\b(?<!WEB-|HDTV)RIP\b)']
},
# 4K
"4K": {
"include": [r'4k|2160p|x2160'],
"exclude": []
},
# 1080P
"1080P": {
"include": [r'1080[pi]|x1080'],
"exclude": []
},
# 720P
"720P": {
"include": [r'720[pi]|x720'],
"exclude": []
},
# 中字
"CNSUB": {
"include": [
r'[中国國繁简](/|\s|\\|\|)?[繁简英粤]|[英简繁](/|\s|\\|\|)?[中繁简]'
r'|繁體|简体|[中国國][字配]|国语|國語|中文|中字|简日|繁日|简繁|繁体'
r'|([\s,.-\[])(chs|cht)(|[\s,.-\]])'
r'|(?<![a-z0-9])(gb|big5)(?![a-z0-9])'],
"exclude": [],
"tmdb": {
"original_language": "zh,cn"
}
},
# 官种
"GZ": {
"include": [r'官方', r'官种', r'官组'],
"match": ["labels"]
},
# 特效字幕
"SPECSUB": {
"include": [r'特效'],
"exclude": []
},
# BluRay
"BLURAY": {
"include": [r'Blu-?Ray'],
"exclude": []
},
# UHD
"UHD": {
"include": [r'UHD|UltraHD'],
"exclude": []
},
# H265
"H265": {
"include": [r'[Hx].?265|HEVC'],
"exclude": []
},
# H264
"H264": {
"include": [r'[Hx].?264|AVC'],
"exclude": []
},
# 杜比视界
"DOLBY": {
"include": [r"Dolby[\s.]+Vision|DOVI|[\s.]+DV[\s.]+|杜比视界"],
"exclude": []
},
# 杜比全景声
"ATMOS": {
"include": [r"Dolby[\s.+]+Atmos|Atmos|杜比全景[声聲]"],
"exclude": []
},
# HDR
"HDR": {
"include": [r"[\s.]+HDR[\s.]+|HDR10|HDR10\+"],
"exclude": []
},
# SDR
"SDR": {
"include": [r"[\s.]+SDR[\s.]+"],
"exclude": []
},
# 重编码
"REMUX": {
"include": [r'REMUX'],
"exclude": []
},
# WEB-DL
"WEBDL": {
"include": [r'WEB-?DL|WEB-?RIP'],
"exclude": []
},
# 免费
"FREE": {
"downloadvolumefactor": 0
},
# 国语配音
"CNVOI": {
"include": [r'[国國][语語]配音|[国國]配|[国國][语語]'],
"exclude": [],
"tmdb": {
"original_language": "zh"
}
},
# 粤语配音
"HKVOI": {
"include": [r'粤语配音|粤语'],
"exclude": []
},
# 60FPS
"60FPS": {
"include": [r'60fps|60帧'],
"exclude": []
},
# 3D
"3D": {
"include": [r'3D'],
"exclude": []
},
}
# 保留一份只读内置规则定义,方便查询工具准确区分“内置规则”和“自定义规则”。
builtin_rule_set: Dict[str, dict] = deepcopy(BUILTIN_RULE_SET)
# 运行期规则集 = 内置规则 + 自定义规则覆盖。
rule_set: Dict[str, dict] = {}
def __init__(self):
super().__init__()
@@ -147,6 +28,8 @@ class FilterModule(_ModuleBase):
def init_module(self) -> None:
self.parser = RuleParser()
# 每次重载都先恢复为纯内置规则,避免旧的自定义规则残留在内存里。
self.rule_set = deepcopy(self.builtin_rule_set)
self.__init_custom_rules()
def __init_custom_rules(self):

View File

@@ -0,0 +1,131 @@
"""过滤器内置规则定义。"""
from typing import Dict
# 内置规则只在这里维护一份,便于过滤模块和 Agent 工具共享同一套事实来源。
BUILTIN_RULE_SET: Dict[str, dict] = {
# 蓝光原盘
"BLU": {
"include": [
r"(?i)(\bBlu-?Ray\b.*\b(?:VC-?1|AVC|MPEG-?2)\b|\b(?:UHD|4K|2160p)\b(?:.*Blu-?Ray)?.*\b(?:HEVC|H\.?265)\b|\bBlu-?Ray\b.*\b(?:UHD|4K|2160p)\b.*\b(?:HEVC|H\.?265)\b|\b(?:COMPLETE|FULL)\b.*\b(?:(?:UHD|4K|2160p)\b.*)?Blu-?Ray\b|\b(BD25|BD50|BD66|BD100|BDMV|MiniBD)\b)"
],
"exclude": [
r"(?i)(\b[XH]\.?264\b|\b[XH]\.?265\b|\bWEB-?DL\b|\bWEB-?RIP\b|\bHDTV(?:RIP)?\b|\bREMUX\b|\bBDRip\b|\bBRRip\b|\bHDRip\b|\bENCODE\b|\b(?<!WEB-|HDTV)RIP\b)"
],
},
# 4K
"4K": {
"include": [r"4k|2160p|x2160"],
"exclude": [],
},
# 1080P
"1080P": {
"include": [r"1080[pi]|x1080"],
"exclude": [],
},
# 720P
"720P": {
"include": [r"720[pi]|x720"],
"exclude": [],
},
# 中字
"CNSUB": {
"include": [
r"[中国國繁简](/|\s|\\|\|)?[繁简英粤]|[英简繁](/|\s|\\|\|)?[中繁简]"
r"|繁體|简体|[中国國][字配]|国语|國語|中文|中字|简日|繁日|简繁|繁体"
r"|([\s,.-\[])(chs|cht)(|[\s,.-\]])"
r"|(?<![a-z0-9])(gb|big5)(?![a-z0-9])"
],
"exclude": [],
"tmdb": {
"original_language": "zh,cn",
},
},
# 官种
"GZ": {
"include": [r"官方", r"官种", r"官组"],
"match": ["labels"],
},
# 特效字幕
"SPECSUB": {
"include": [r"特效"],
"exclude": [],
},
# BluRay
"BLURAY": {
"include": [r"Blu-?Ray"],
"exclude": [],
},
# UHD
"UHD": {
"include": [r"UHD|UltraHD"],
"exclude": [],
},
# H265
"H265": {
"include": [r"[Hx].?265|HEVC"],
"exclude": [],
},
# H264
"H264": {
"include": [r"[Hx].?264|AVC"],
"exclude": [],
},
# 杜比视界
"DOLBY": {
"include": [r"Dolby[\s.]+Vision|DOVI|[\s.]+DV[\s.]+|杜比视界"],
"exclude": [],
},
# 杜比全景声
"ATMOS": {
"include": [r"Dolby[\s.+]+Atmos|Atmos|杜比全景[声聲]"],
"exclude": [],
},
# HDR
"HDR": {
"include": [r"[\s.]+HDR[\s.]+|HDR10|HDR10\+"],
"exclude": [],
},
# SDR
"SDR": {
"include": [r"[\s.]+SDR[\s.]+"],
"exclude": [],
},
# 重编码
"REMUX": {
"include": [r"REMUX"],
"exclude": [],
},
# WEB-DL
"WEBDL": {
"include": [r"WEB-?DL|WEB-?RIP"],
"exclude": [],
},
# 免费
"FREE": {
"downloadvolumefactor": 0,
},
# 国语配音
"CNVOI": {
"include": [r"[国國][语語]配音|[国國]配|[国國][语語]"],
"exclude": [],
"tmdb": {
"original_language": "zh",
},
},
# 粤语配音
"HKVOI": {
"include": [r"粤语配音|粤语"],
"exclude": [],
},
# 60FPS
"60FPS": {
"include": [r"60fps|60帧"],
"exclude": [],
},
# 3D
"3D": {
"include": [r"3D"],
"exclude": [],
},
}