This commit is contained in:
riglen
2026-03-31 16:39:23 +08:00
parent 0d49398e2d
commit 09a9faa1be
7 changed files with 1274 additions and 37 deletions

View File

@@ -5,7 +5,7 @@ from typing import Any
import yaml
from app.models import AppConfig, ClientConfig, SourceSnapshot
from app.models import AppConfig, ClientConfig, ProxyGroupConfig, SourceSnapshot
from app.services.rules import build_inline_rules, build_rule_provider_entries, build_rule_set_references
@@ -13,6 +13,107 @@ def dump_yaml(data: dict[str, Any]) -> str:
return yaml.safe_dump(data, allow_unicode=True, sort_keys=False, default_flow_style=False)
def _expand_proxy_tokens(
proxies: list[str],
*,
client: ClientConfig,
source_auto_names: list[str],
selector_names: list[str],
) -> list[str]:
expanded: list[str] = []
tokens = {
"{{ main_policy }}": [client.main_policy],
"{{main_policy}}": [client.main_policy],
"{{ source_policy }}": [client.source_policy],
"{{source_policy}}": [client.source_policy],
"{{ mixed_auto_policy }}": [client.mixed_auto_policy],
"{{mixed_auto_policy}}": [client.mixed_auto_policy],
"{{ manual_policy }}": [client.manual_policy],
"{{manual_policy}}": [client.manual_policy],
"{{ direct_policy }}": [client.direct_policy],
"{{direct_policy}}": [client.direct_policy],
"{{ source_auto_groups }}": source_auto_names,
"{{source_auto_groups}}": source_auto_names,
"{{ selector_groups }}": selector_names,
"{{selector_groups}}": selector_names,
}
for item in proxies:
expanded.extend(tokens.get(item, [item]))
return expanded
def _build_thin_filter_group(
*,
client_type: str,
client: ClientConfig,
group: ProxyGroupConfig,
selected_source_names: list[str],
) -> dict[str, Any]:
built: dict[str, Any] = {
"name": group.name,
"type": group.type,
"filter": group.filter,
}
if group.type == "url-test":
built["url"] = str(group.url or client.test_url)
built["interval"] = group.interval or client.test_interval
if group.tolerance is not None:
built["tolerance"] = group.tolerance
if client_type == "mihomo":
built["use"] = selected_source_names
else:
built["include-all"] = True
return built
def _build_bundle_filter_group(
*,
client: ClientConfig,
group: ProxyGroupConfig,
all_proxy_names: list[str],
) -> dict[str, Any]:
matched = [name for name in all_proxy_names if group.filter and re.search(group.filter, name)]
built: dict[str, Any] = {
"name": group.name,
"type": group.type,
"proxies": matched or [client.direct_policy],
}
if group.type == "url-test":
built["url"] = str(group.url or client.test_url)
built["interval"] = group.interval or client.test_interval
if group.tolerance is not None:
built["tolerance"] = group.tolerance
return built
def _build_custom_policy_groups(
*,
app_config: AppConfig,
client: ClientConfig,
source_auto_names: list[str],
selector_names: list[str],
) -> list[dict[str, Any]]:
groups: list[dict[str, Any]] = []
for group in app_config.policy_groups:
built: dict[str, Any] = {
"name": group.name,
"type": group.type,
"proxies": _expand_proxy_tokens(
group.proxies,
client=client,
source_auto_names=source_auto_names,
selector_names=selector_names,
),
}
if group.type == "url-test":
built["url"] = str(group.url or client.test_url)
built["interval"] = group.interval or client.test_interval
if group.tolerance is not None:
built["tolerance"] = group.tolerance
groups.append(built)
return groups
def build_thin_profile(
*,
client_type: str,
@@ -156,7 +257,7 @@ def _build_thin_groups(client_type: str, app_config: AppConfig, client: ClientCo
groups.append(mixed_auto)
region_names: list[str] = []
selector_names: list[str] = []
for region in app_config.regions.values():
group = {
"name": region.name,
@@ -171,7 +272,32 @@ def _build_thin_groups(client_type: str, app_config: AppConfig, client: ClientCo
else:
group["include-all"] = True
groups.append(group)
region_names.append(region.name)
selector_names.append(region.name)
for selector in app_config.selector_groups:
if selector.filter:
groups.append(
_build_thin_filter_group(
client_type=client_type,
client=client,
group=selector,
selected_source_names=selected_source_names,
)
)
else:
groups.append(
{
"name": selector.name,
"type": selector.type,
"proxies": _expand_proxy_tokens(
selector.proxies,
client=client,
source_auto_names=source_auto_names,
selector_names=selector_names,
),
}
)
selector_names.append(selector.name)
groups.append(
{
@@ -181,6 +307,14 @@ def _build_thin_groups(client_type: str, app_config: AppConfig, client: ClientCo
}
)
groups.append(manual)
groups.extend(
_build_custom_policy_groups(
app_config=app_config,
client=client,
source_auto_names=source_auto_names,
selector_names=selector_names,
)
)
groups.append(
{
"name": client.main_policy,
@@ -188,7 +322,7 @@ def _build_thin_groups(client_type: str, app_config: AppConfig, client: ClientCo
"proxies": [
client.source_policy,
client.mixed_auto_policy,
*region_names,
*selector_names,
client.manual_policy,
client.direct_policy,
],
@@ -230,7 +364,7 @@ def _build_bundle_groups(
}
)
region_names: list[str] = []
selector_names: list[str] = []
for region in app_config.regions.values():
matched = [name for name in all_proxy_names if re.search(region.filter, name)]
groups.append(
@@ -243,7 +377,31 @@ def _build_bundle_groups(
"proxies": matched or [client.direct_policy],
}
)
region_names.append(region.name)
selector_names.append(region.name)
for selector in app_config.selector_groups:
if selector.filter:
groups.append(
_build_bundle_filter_group(
client=client,
group=selector,
all_proxy_names=all_proxy_names,
)
)
else:
groups.append(
{
"name": selector.name,
"type": selector.type,
"proxies": _expand_proxy_tokens(
selector.proxies,
client=client,
source_auto_names=source_auto_names,
selector_names=selector_names,
),
}
)
selector_names.append(selector.name)
groups.append(
{
@@ -259,6 +417,14 @@ def _build_bundle_groups(
"proxies": [*all_proxy_names, client.direct_policy] if all_proxy_names else [client.direct_policy],
}
)
groups.extend(
_build_custom_policy_groups(
app_config=app_config,
client=client,
source_auto_names=source_auto_names,
selector_names=selector_names,
)
)
groups.append(
{
"name": client.main_policy,
@@ -266,7 +432,7 @@ def _build_bundle_groups(
"proxies": [
client.source_policy,
client.mixed_auto_policy,
*region_names,
*selector_names,
client.manual_policy,
client.direct_policy,
],