Fix domain MRS pattern generation

This commit is contained in:
dajiaohuang committed 2026-10-23 00:37:14 +08:00
1 parent 575637df38
commit c66ee73b45
2 files changed
+71 -4

No files matched your search

+13 -4
View File
@@ -214,6 +214,15 @@ def parse_list_rule_line(line):
def is_domain_rule_type(rule_type):
return rule_type in ('DOMAIN', 'DOMAIN-SUFFIX', 'DOMAIN-KEYWORD', 'DOMAIN-REGEX')
def format_mrs_domain_rule(rule_type, rule_value):
"""Translate supported Clash domain rules to MRS domain patterns."""
if rule_type == 'DOMAIN':
return rule_value
if rule_type == 'DOMAIN-SUFFIX':
# MRS uses +. to match both the suffix and its root domain.
return f'+.{rule_value}'
return f'{rule_type},{rule_value}'
def is_ip_rule_type(rule_type):
return rule_type in ('IP-CIDR', 'IP-CIDR6', 'IP-SUFFIX', 'IP-ASN')
@@ -257,7 +266,7 @@ def split_yaml_file(filepath):
unique_domains = sorted(set(domains))
domain_yaml = "payload:\n"
for rule_type, d in unique_domains:
domain_yaml += f" - {rule_type},{d}\n"
domain_yaml += f" - {format_mrs_domain_rule(rule_type, d)}\n"
write_file(f"{base_name}_domain.yaml", domain_yaml)
if ips:
unique_ips = sorted(set(ips))
@@ -290,7 +299,7 @@ def split_list_file(filepath):
unique_domains = sorted(set(domains))
domain_text = ""
for rule_type, d in unique_domains:
domain_text += f"{rule_type},{d}\n"
domain_text += f"{format_mrs_domain_rule(rule_type, d)}\n"
write_file(f"{base_name}_domain.list", domain_text)
if ips:
unique_ips = sorted(set(ips))
@@ -343,7 +352,7 @@ def generate_clash_provider_yaml(domain_list, ip_list, filename, title="payload"
if unique_domains:
domain_yaml = f"{title}:\n"
for domain in unique_domains:
domain_yaml += f" - DOMAIN-SUFFIX,{domain}\n"
domain_yaml += f" - {format_mrs_domain_rule('DOMAIN-SUFFIX', domain)}\n"
write_file(f"{base_name}_domain.yaml", domain_yaml)
# IP 规则 - YAML 格式
@@ -372,7 +381,7 @@ def generate_clash_ruleset_list(domain_list, ip_list, filename, title="GFWList")
if unique_domains:
domain_text = ""
for domain in unique_domains:
domain_text += f"DOMAIN-SUFFIX,{domain}\n"
domain_text += f"{format_mrs_domain_rule('DOMAIN-SUFFIX', domain)}\n"
write_file(f"{base_name}_domain.list", domain_text)
# IP 规则 - text 格式
+58
View File
@@ -0,0 +1,58 @@
import importlib.util
import tempfile
import unittest
from pathlib import Path
SCRIPT = Path(__file__).resolve().parents[1] / "gfwlist_parser.py"
SPEC = importlib.util.spec_from_file_location("gfwlist_parser", SCRIPT)
assert SPEC is not None and SPEC.loader is not None
PARSER = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(PARSER)
class MrsDomainPatternTests(unittest.TestCase):
def test_generated_clash_rules_are_preserved_and_mrs_inputs_are_patterns(self):
domain = "synthetic.example.invalid"
ip = "192.0.2.1"
with tempfile.TemporaryDirectory() as temporary_directory:
root = Path(temporary_directory)
provider = root / "provider.yaml"
ruleset = root / "ruleset.list"
PARSER.generate_clash_provider_yaml([domain], [ip], str(provider))
PARSER.generate_clash_ruleset_list([domain], [ip], str(ruleset))
PARSER.split_yaml_file(str(provider))
PARSER.split_list_file(str(ruleset))
self.assertIn(f"DOMAIN-SUFFIX,{domain}", provider.read_text(encoding="utf-8"))
self.assertIn(f"DOMAIN-SUFFIX,{domain}\n", ruleset.read_text(encoding="utf-8"))
self.assertEqual(
(root / "provider_domain.yaml").read_text(encoding="utf-8"),
f"payload:\n - +.{domain}\n",
)
self.assertEqual(
(root / "ruleset_domain.list").read_text(encoding="utf-8"),
f"+.{domain}\n",
)
self.assertEqual(
(root / "provider_ip.yaml").read_text(encoding="utf-8"),
f"payload:\n - {ip}/32\n",
)
self.assertEqual(
(root / "ruleset_ip.list").read_text(encoding="utf-8"),
f"{ip}/32\n",
)
def test_exact_and_suffix_rule_mappings(self):
domain = "synthetic.example.invalid"
self.assertEqual(PARSER.format_mrs_domain_rule("DOMAIN", domain), domain)
self.assertEqual(
PARSER.format_mrs_domain_rule("DOMAIN-SUFFIX", domain),
f"+.{domain}",
)
if __name__ == "__main__":
unittest.main()