diff --git a/.gitignore b/.gitignore index 3af6a7b9..505a3b1c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,10 @@ -__pycache__ -/venv \ No newline at end of file +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..c8cfe395 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.10 diff --git a/README.md b/README.md new file mode 100644 index 00000000..e69de29b diff --git a/netgen.py b/netgen.py index 0259581e..5c15495c 100755 --- a/netgen.py +++ b/netgen.py @@ -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): - copied_networks.pop(index) - copied_networks.extend(list(network.address_exclude(subnet))) - except TypeError: - pass + 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))) # 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() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..221cef76 --- /dev/null +++ b/pyproject.toml @@ -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" diff --git a/raydata.py b/raydata.py index e1041eb9..db56b6f6 100755 --- a/raydata.py +++ b/raydata.py @@ -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() diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..6b6158d8 --- /dev/null +++ b/uv.lock @@ -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" }, +]