Skip to content

Commit

Permalink
Bump version number to 0.4.2. Allow Use converter.singbox_config to g…
Browse files Browse the repository at this point in the history
…et the result.
  • Loading branch information
dzhuang committed Jan 4, 2024
1 parent de13234 commit 943af3a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 29 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ converter = SingBoxConverter(
# auto_fix_empty_outbound=True,
)

print(converter.singbox_config)

converter.export_config(
# path="/path/to/output/config"
path="/path/to/output/config",
# nodes_only=True
)

```
Expand Down
2 changes: 1 addition & 1 deletion src/singbox_converter/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '0.4.1'
__version__ = '0.4.2'

from .core import SingBoxConverter

Expand Down
68 changes: 41 additions & 27 deletions src/singbox_converter/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,22 +103,35 @@ def __init__(
self.auto_fix_empty_outbound = auto_fix_empty_outbound
self.empty_outbound_node_tags = []

self._singbox_config = None

@property
def providers_config(self):
if self._providers_config is None:
self.get_and_validate_providers_config()

self.logger.debug(f"used providers_config: {self._providers_config}")
self.logger.debug(f"Used providers_config: \n{self._providers_config}")
return self._providers_config

@property
def template_config(self):
if self._template_config is None:
self._template_config = self.get_template_config()

self.logger.debug(f"used template_config: {self._template_config}")
self.logger.debug(f"Used template_config: \n{self._template_config}")
return self._template_config

@property
def singbox_config(self):
if self._singbox_config is None:
self._singbox_config = self.combine_to_config()

if self.logger.isEnabledFor(logging.DEBUG):
json_str = json.dumps(self._singbox_config, indent=2)
self.logger.debug(f"Generated config: \n{json_str}")

return self._singbox_config

def get_and_validate_providers_config(self):
if isinstance(self._providers_config_input, dict):
return self.validate_providers_config(
Expand Down Expand Up @@ -504,16 +517,16 @@ def pro_dns_from_route_rules(route_rule):
# "address": "tls://1.1.1.1",
# "detour": ""
# }
config_rules = self.template_config['route']['rules']
config_rules = self._singbox_config['route']['rules']
outbound_dns = []
dns_rules = self.template_config['dns']['rules']
dns_rules = self._singbox_config['dns']['rules']
asod = self.providers_config["auto_set_outbounds_dns"]
for rule in config_rules:
if rule['outbound'] not in ['block', 'dns-out']:
if rule['outbound'] != 'direct':
outbounds_dns_template = \
list(filter(lambda server: server['tag'] == asod["proxy"],
self.template_config['dns']['servers']))[0]
self._singbox_config['dns']['servers']))[0]
dns_obj = outbounds_dns_template.copy()
dns_obj['tag'] = rule['outbound'] + '_dns'
dns_obj['detour'] = rule['outbound']
Expand Down Expand Up @@ -544,10 +557,12 @@ def pro_dns_from_route_rules(route_rule):
for dr in dns_rules:
if dr not in _dns_rules:
_dns_rules.append(dr)
self.template_config['dns']['rules'] = _dns_rules
self.template_config['dns']['servers'].extend(outbound_dns)
self._singbox_config['dns']['rules'] = _dns_rules
self._singbox_config['dns']['servers'].extend(outbound_dns)

def combine_to_config(self):
self._singbox_config = self.template_config

def action_keywords(_nodes, action, keywords):
# filter将按顺序依次执行
# "filter":[
Expand Down Expand Up @@ -600,8 +615,8 @@ def pro_node_template(data_nodes, config_outbound, _group):
data = self.nodes

config_outbounds = (
self.template_config["outbounds"]
if self.template_config.get("outbounds") else None)
self._singbox_config["outbounds"]
if self._singbox_config.get("outbounds") else None)

temp_outbounds = []
if config_outbounds:
Expand Down Expand Up @@ -670,11 +685,11 @@ def pro_node_template(data_nodes, config_outbound, _group):
del po['filter']
for group in data:
temp_outbounds.extend(data[group])
self.template_config['outbounds'] = config_outbounds + temp_outbounds
self._singbox_config['outbounds'] = config_outbounds + temp_outbounds

# 自动配置路由规则到dns规则,避免dns泄露
dns_tags = [server.get('tag') for server in
self.template_config['dns']['servers']]
self._singbox_config['dns']['servers']]
asod = self.providers_config.get("auto_set_outbounds_dns")
if (asod and asod.get('proxy')
and asod.get('direct')
Expand All @@ -687,13 +702,13 @@ def pro_node_template(data_nodes, config_outbound, _group):
self.validate_rule_set()
self.validate_outbound_tags()

return self.template_config
return self._singbox_config

def remove_empty_bound_nodes(self):
if not self.auto_fix_empty_outbound:
return

root_outbounds = deepcopy(self.template_config.get("outbounds", []))
root_outbounds = deepcopy(self._singbox_config.get("outbounds", []))

while len(self.empty_outbound_node_tags):
_tag = self.empty_outbound_node_tags.pop(0)
Expand Down Expand Up @@ -726,10 +741,10 @@ def remove_empty_bound_nodes(self):

root_outbounds = new_root_outbounds

self.template_config["outbounds"] = root_outbounds
self._singbox_config["outbounds"] = root_outbounds

def validate_rule_set(self):
route = self.template_config.get("route", {})
route = self._singbox_config.get("route", {})
rules = route.get("rules", [])

used_rule_set = set()
Expand Down Expand Up @@ -761,7 +776,7 @@ def validate_rule_set(self):
new_rule_set = [rs for rs in rule_set_config
if rs["tag"] not in unused_rule_sets]

self.template_config["route"]["rule_set"] = new_rule_set
self._singbox_config["route"]["rule_set"] = new_rule_set

unused_rule_set_str = ", ".join(unused_rule_sets)
self.logger.warning(
Expand All @@ -772,11 +787,11 @@ def validate_outbound_tags(self):
unknowns = []
used_outbounds = set()

root_outbounds = self.template_config.get("outbounds", [])
root_outbounds = self._singbox_config.get("outbounds", [])

available_ob_tags = [ob["tag"] for ob in root_outbounds]

route_config = self.template_config.get("route", {})
route_config = self._singbox_config.get("route", {})
route_rules = route_config.get("rules", [])
route_rules_outbounds = [rr["outbound"] for rr in route_rules]
used_outbounds.update(route_rules_outbounds)
Expand All @@ -801,7 +816,7 @@ def validate_outbound_tags(self):

used_outbounds.add(final_route)

rule_sets = self.template_config.get("rule_set", [])
rule_sets = self._singbox_config.get("rule_set", [])
rule_set_download_detour = [rs["download_detour"] for rs in rule_sets]
used_outbounds.update(rule_set_download_detour)

Expand All @@ -814,7 +829,7 @@ def validate_outbound_tags(self):
"value": list(unknown_rs_ob_tags),
"location": "download_detour"})

dns_servers = self.template_config.get("dns", {}).get("servers", [])
dns_servers = self._singbox_config.get("dns", {}).get("servers", [])
dns_servers_detour = [
ds.get("detour") for ds in dns_servers if "detour" in ds]
used_outbounds.update(dns_servers_detour)
Expand Down Expand Up @@ -867,16 +882,15 @@ def validate_outbound_tags(self):
def export_config(self, path, nodes_only=False):

if not nodes_only:
final_config = self.combine_to_config()
content = self.singbox_config

else:
combined_contents = []
for sub_tag, contents in self.nodes.items():
content = []
for sub_tag, nodes in self.nodes.items():
# 遍历每个机场的内容
for content in contents:
for node_dict in nodes:
# 将内容添加到新列表中
combined_contents.append(content)
final_config = combined_contents # 只返回节点信息
content.append(node_dict)

with open(path, mode='w', encoding='utf-8') as f:
f.write(json.dumps(final_config, indent=2, ensure_ascii=False))
f.write(json.dumps(content, indent=2, ensure_ascii=False))

0 comments on commit 943af3a

Please sign in to comment.