4
0
mirror of https://github.com/darkclip/netlist.git synced 2026-11-11 00:34:07 +08:00
This commit is contained in:
darkclip 2025-04-11 05:06:14 +08:00
parent 62dd05536c
commit 93e17c23f4
7 changed files with 111 additions and 39 deletions

12
.gitignore vendored
View File

@ -1,2 +1,10 @@
__pycache__
/venv
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info
# Virtual environments
.venv

1
.python-version Normal file
View File

@ -0,0 +1 @@
3.10

0
README.md Normal file
View File

View File

@ -3,8 +3,8 @@
from __future__ import annotations
import typing
import argparse
import sys
import os
from pathlib import Path
from ipaddress import IPv4Network, IPv6Network, AddressValueError
@ -15,7 +15,7 @@ except ImportError:
def prepare_networks(
nets_or_files: typing.List[str], family: typing.List[int] | None = None
nets_or_files: typing.List[str], family: typing.List[int]
) -> typing.List[IPv4Network | IPv6Network]:
networks = []
for net in nets_or_files:
@ -53,20 +53,19 @@ def find_updated_networks(
) -> typing.List[IPv4Network | IPv6Network]:
copied_networks = networks.copy()
for index, network in enumerate(networks):
try:
if subnet.subnet_of(network):
if type(network) is not type(subnet):
continue
if subnet.subnet_of(network): # type: ignore
copied_networks.pop(index)
copied_networks.extend(list(network.address_exclude(subnet)))
except TypeError:
pass
copied_networks.extend(list(network.address_exclude(subnet))) # type: ignore
return copied_networks
def main(args):
def run(args: argparse.Namespace) -> None:
includes = getattr(args, 'include', [])
excludes = getattr(args, 'exclude', [])
family = getattr(args, 'family', None)
output = getattr(args, 'output', None)
family = getattr(args, 'family', [])
output: Path | None = getattr(args, 'output', None)
in_networks = prepare_networks(includes, family)
if len(in_networks) == 0:
@ -91,7 +90,7 @@ def main(args):
out_networks.extend(out6)
output_lines = [
f"{getattr(args,'prefix','')}{str(network)}{getattr(args,'suffix','')}\n"
f'{getattr(args, "prefix", "")}{str(network)}{getattr(args, "suffix", "")}\n'
for network in out_networks
]
@ -100,10 +99,9 @@ def main(args):
print(line, end='')
else:
print(f'Included Networks: {len(in_networks)}')
output: Path
output_file = output.resolve()
if not output_file.parent.exists():
os.makedirs(output_file.parent)
output_file.parent.mkdir(parents=True)
if output_file.is_dir():
print('Can not write to directory.')
if output_file.exists():
@ -115,9 +113,7 @@ def main(args):
print(f'Generated Networks: {len(output_lines)}')
if __name__ == '__main__':
import argparse
def main() -> None:
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
@ -157,6 +153,10 @@ if __name__ == '__main__':
parser.add_argument(
'-s', '--suffix', type=str, default='', help='write line suffix'
)
parser.set_defaults(func=main)
parser.set_defaults(func=run)
args = parser.parse_args()
args.func(args)
if __name__ == '__main__':
main()

16
pyproject.toml Normal file
View File

@ -0,0 +1,16 @@
[project]
name = "netlist"
version = "0.1.0"
description = "generate netlist"
readme = "README.md"
requires-python = ">=3.10"
dependencies = ["protobuf>=6.30.2"]
[project.optional-dependencies]
network = ["aggregate-prefixes>=0.7.2"]
[tool.setuptools]
py-modules = []
[tool.ruff.format]
quote-style = "single"

View File

@ -3,8 +3,8 @@
from __future__ import annotations
import typing
import argparse
import sys
import os
import json
from pathlib import Path
from ipaddress import IPv4Network, IPv6Network, AddressValueError
@ -13,7 +13,7 @@ import ray_pb2
def load_formatter(formatter: Path | None) -> dict | None:
try:
format_file_path = formatter.resolve()
format_file_path = formatter.resolve() # type: ignore
with format_file_path.open(encoding='utf-8') as fp:
return json.load(fp)
except (AttributeError, OSError, json.JSONDecodeError, TypeError):
@ -21,11 +21,11 @@ def load_formatter(formatter: Path | None) -> dict | None:
return None
def init_protobuf(data_type: str = None) -> tuple:
def init_protobuf(data_type: str | None = None) -> tuple:
if data_type == 'geoip':
return (ray_pb2.GeoIPList(), 'cidr')
return (ray_pb2.GeoIPList(), 'cidr') # type: ignore
if data_type == 'geosite':
return (ray_pb2.GeoSiteList(), 'domain')
return (ray_pb2.GeoSiteList(), 'domain') # type: ignore
return (None, None)
@ -68,10 +68,10 @@ def load_resource(
if brief_search.lower() not in entry.country_code.lower():
continue
print(
f"{entry.country_code}: {sum(map(lambda record: not domain_types or record.type in domain_types, getattr(entry, list_name, None)))}"
f'{entry.country_code}: {sum(map(lambda record: not domain_types or record.type in domain_types, getattr(entry, list_name, [])))}'
)
continue
for record in getattr(entry, list_name, None):
for record in getattr(entry, list_name, []):
if list_name == 'cidr':
try:
resources.append(IPv4Network((record.ip, record.prefix)))
@ -87,16 +87,16 @@ def load_resource(
prefix = ''
suffix = ''
if format_dict:
prefix = format_dict.get('prefix').get(str(record.type))
suffix = format_dict.get('suffix').get(str(record.type))
prefix = format_dict.get('prefix', {}).get(str(record.type))
suffix = format_dict.get('suffix', {}).get(str(record.type))
if record.value:
resources.append(f'{prefix}{record.value}{suffix}')
return resources
def main(args):
def run(args: argparse.Namespace) -> None:
input_files = getattr(args, 'input', [])
output = getattr(args, 'output', None)
output: Path | None = getattr(args, 'output', None)
if (search := getattr(args, 'brief', None)) is not None:
load_resource(
@ -121,17 +121,16 @@ def main(args):
print('No legal data.')
sys.exit(1)
output_lines = [
f"{getattr(args,'prefix','')}{str(entry)}{getattr(args,'suffix','')}"
f'{getattr(args, "prefix", "")}{str(entry)}{getattr(args, "suffix", "")}'
for entry in data_list
]
if output is None:
for line in output_lines:
print(line, end='')
else:
output: Path
output_file = output.resolve()
if not output_file.parent.exists():
os.makedirs(output_file.parent)
output_file.parent.mkdir(parents=True)
if output_file.is_dir():
print('Can not write to directory.')
if output_file.exists():
@ -143,9 +142,7 @@ def main(args):
print(f'Output: {len(output_lines)}')
if __name__ == '__main__':
import argparse
def main() -> None:
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
@ -185,11 +182,11 @@ if __name__ == '__main__':
parser.add_argument(
'-s', '--suffix', type=str, default='\n', help='write line suffix'
)
parser.set_defaults(func=main)
parser.set_defaults(func=run)
subparser = parser.add_subparsers(dest='data_type', required=True)
parser_geoip = subparser.add_parser(
_parser_geoip = subparser.add_parser(
'geoip',
help='use geoip as input',
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
@ -214,3 +211,7 @@ if __name__ == '__main__':
args = parser.parse_args()
args.func(args)
if __name__ == '__main__':
main()

46
uv.lock generated Normal file
View File

@ -0,0 +1,46 @@
version = 1
revision = 1
requires-python = ">=3.10"
[[package]]
name = "aggregate-prefixes"
version = "0.7.2"
source = { registry = "https://mirrors.nju.edu.cn/pypi/web/simple" }
sdist = { url = "https://mirrors.nju.edu.cn/pypi/web/packages/70/fc/651df135a8f672674d2fcaa2f4355e78594d88e3964f965849d2c32b1b30/aggregate_prefixes-0.7.2.tar.gz", hash = "sha256:6a459faa9cfff5822bf1ed5a7a4bc34818925f25db80f0534c2ca3ae73f64aec" }
wheels = [
{ url = "https://mirrors.nju.edu.cn/pypi/web/packages/ea/0e/1979fcd5a5a500b02240a0869df943cb4a70d5af820f6e6c667aa5f5d5d7/aggregate_prefixes-0.7.2-py3-none-any.whl", hash = "sha256:020a146a17de31edd26ce69eeebde28a8eb94638dbfee767052d6871544f02a6" },
]
[[package]]
name = "netlist"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "protobuf" },
]
[package.optional-dependencies]
network = [
{ name = "aggregate-prefixes" },
]
[package.metadata]
requires-dist = [
{ name = "aggregate-prefixes", marker = "extra == 'network'", specifier = ">=0.7.2" },
{ name = "protobuf", specifier = ">=6.30.2" },
]
provides-extras = ["network"]
[[package]]
name = "protobuf"
version = "6.30.2"
source = { registry = "https://mirrors.nju.edu.cn/pypi/web/simple" }
sdist = { url = "https://mirrors.nju.edu.cn/pypi/web/packages/c8/8c/cf2ac658216eebe49eaedf1e06bc06cbf6a143469236294a1171a51357c3/protobuf-6.30.2.tar.gz", hash = "sha256:35c859ae076d8c56054c25b59e5e59638d86545ed6e2b6efac6be0b6ea3ba048" }
wheels = [
{ url = "https://mirrors.nju.edu.cn/pypi/web/packages/be/85/cd53abe6a6cbf2e0029243d6ae5fb4335da2996f6c177bb2ce685068e43d/protobuf-6.30.2-cp310-abi3-win32.whl", hash = "sha256:b12ef7df7b9329886e66404bef5e9ce6a26b54069d7f7436a0853ccdeb91c103" },
{ url = "https://mirrors.nju.edu.cn/pypi/web/packages/97/e9/7b9f1b259d509aef2b833c29a1f3c39185e2bf21c9c1be1cd11c22cb2149/protobuf-6.30.2-cp310-abi3-win_amd64.whl", hash = "sha256:7653c99774f73fe6b9301b87da52af0e69783a2e371e8b599b3e9cb4da4b12b9" },
{ url = "https://mirrors.nju.edu.cn/pypi/web/packages/8e/66/7f3b121f59097c93267e7f497f10e52ced7161b38295137a12a266b6c149/protobuf-6.30.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:0eb523c550a66a09a0c20f86dd554afbf4d32b02af34ae53d93268c1f73bc65b" },
{ url = "https://mirrors.nju.edu.cn/pypi/web/packages/d0/89/bbb1bff09600e662ad5b384420ad92de61cab2ed0f12ace1fd081fd4c295/protobuf-6.30.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:50f32cc9fd9cb09c783ebc275611b4f19dfdfb68d1ee55d2f0c7fa040df96815" },
{ url = "https://mirrors.nju.edu.cn/pypi/web/packages/28/50/1925de813499546bc8ab3ae857e3ec84efe7d2f19b34529d0c7c3d02d11d/protobuf-6.30.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4f6c687ae8efae6cf6093389a596548214467778146b7245e886f35e1485315d" },
{ url = "https://mirrors.nju.edu.cn/pypi/web/packages/e5/a1/93c2acf4ade3c5b557d02d500b06798f4ed2c176fa03e3c34973ca92df7f/protobuf-6.30.2-py3-none-any.whl", hash = "sha256:ae86b030e69a98e08c77beab574cbcb9fff6d031d57209f574a5aea1445f4b51" },
]