iup 0.2__py3-none-any.whl → 0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iup/__init__.py +5 -0
- iup/main.py +55 -11
- {iup-0.2.dist-info → iup-0.4.dist-info}/METADATA +1 -1
- iup-0.4.dist-info/RECORD +8 -0
- {iup-0.2.dist-info → iup-0.4.dist-info}/WHEEL +1 -1
- iup/default_config.py +0 -21
- iup-0.2.dist-info/RECORD +0 -9
- {iup-0.2.dist-info → iup-0.4.dist-info}/entry_points.txt +0 -0
- {iup-0.2.dist-info → iup-0.4.dist-info}/top_level.txt +0 -0
iup/__init__.py
CHANGED
iup/main.py
CHANGED
|
@@ -4,6 +4,7 @@ import argparse
|
|
|
4
4
|
from os import path
|
|
5
5
|
import re
|
|
6
6
|
import paramiko
|
|
7
|
+
import iup
|
|
7
8
|
from iup.config import Config
|
|
8
9
|
import ipaddress
|
|
9
10
|
|
|
@@ -16,21 +17,57 @@ MAGIC_STR = "update rule to"
|
|
|
16
17
|
MAGIC_STR2 = "update blk"
|
|
17
18
|
|
|
18
19
|
def is_domain_name(string: str):
|
|
19
|
-
if
|
|
20
|
-
return True
|
|
21
|
-
else:
|
|
20
|
+
if not string:
|
|
22
21
|
return False
|
|
23
|
-
|
|
22
|
+
s = string.strip().lower()
|
|
23
|
+
return re.fullmatch(HOSTNAME_PATTERN, s) is not None
|
|
24
|
+
|
|
24
25
|
def is_ip_address(ip_str: str):
|
|
25
26
|
try:
|
|
26
27
|
ip = ipaddress.ip_address(ip_str)
|
|
27
28
|
return ip is not None
|
|
28
29
|
except ValueError:
|
|
29
30
|
return False
|
|
30
|
-
|
|
31
|
+
|
|
32
|
+
|
|
31
33
|
def parse_host_name(hostname_str: str):
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
"""Normalize input and return domain name only (no scheme, no port).
|
|
35
|
+
|
|
36
|
+
Accepts inputs like:
|
|
37
|
+
- a.com:443
|
|
38
|
+
- https://a.com
|
|
39
|
+
- http//:a.com:443
|
|
40
|
+
|
|
41
|
+
Returns domain (e.g. 'a.com') or None. IP addresses are rejected.
|
|
42
|
+
"""
|
|
43
|
+
if not hostname_str:
|
|
44
|
+
return None
|
|
45
|
+
s = hostname_str.strip()
|
|
46
|
+
# detect and strip scheme (require '://', e.g. http:// or https://)
|
|
47
|
+
# this prevents malformed inputs like 'http:a.com:443' being treated as scheme
|
|
48
|
+
m = re.match(r'^([a-zA-Z][a-zA-Z0-9+\-]*)://', s)
|
|
49
|
+
has_scheme = bool(m)
|
|
50
|
+
if m:
|
|
51
|
+
s = s[m.end():]
|
|
52
|
+
# remove credentials if present (user:pass@host)
|
|
53
|
+
if '@' in s:
|
|
54
|
+
s = s.split('@')[-1]
|
|
55
|
+
# if there was a scheme, remove path part
|
|
56
|
+
if has_scheme and '/' in s:
|
|
57
|
+
s = s.split('/')[0]
|
|
58
|
+
# now s should be host[:port]
|
|
59
|
+
host_port = s.strip()
|
|
60
|
+
# strip port if present (last :digits)
|
|
61
|
+
if ':' in host_port:
|
|
62
|
+
parts = host_port.rsplit(':', 1)
|
|
63
|
+
if parts[1].isdigit():
|
|
64
|
+
host_port = parts[0]
|
|
65
|
+
host = host_port.strip().lower()
|
|
66
|
+
# reject pure IPs
|
|
67
|
+
if is_ip_address(host):
|
|
68
|
+
return None
|
|
69
|
+
if is_domain_name(host):
|
|
70
|
+
return host
|
|
34
71
|
return None
|
|
35
72
|
|
|
36
73
|
def parse_port(port: str):
|
|
@@ -55,8 +92,9 @@ def read_hostname_from_file(path: str):
|
|
|
55
92
|
with open(path, 'r') as f:
|
|
56
93
|
for line in f:
|
|
57
94
|
host_name_str = line.strip()
|
|
58
|
-
|
|
59
|
-
|
|
95
|
+
parsed = parse_host_name(host_name_str)
|
|
96
|
+
if parsed:
|
|
97
|
+
hostnames.append(parsed)
|
|
60
98
|
hostnames = list(dict.fromkeys(hostnames))
|
|
61
99
|
return hostnames
|
|
62
100
|
|
|
@@ -64,6 +102,11 @@ def load_and_overlay_config() -> Config:
|
|
|
64
102
|
parser = argparse.ArgumentParser(description='参数说明')
|
|
65
103
|
parser.add_argument("-nr", "--no_refresh", action='store_true', default=False, help="是否刷新")
|
|
66
104
|
parser.add_argument("sources", nargs='+', help='域名或者域名文件路径')
|
|
105
|
+
parser.add_argument(
|
|
106
|
+
"--version",
|
|
107
|
+
action="version",
|
|
108
|
+
version=f"%(prog)s version {iup.__version__} installed in {path.dirname(__file__)}",
|
|
109
|
+
)
|
|
67
110
|
args = parser.parse_args()
|
|
68
111
|
config_path = path.join(path.dirname(__file__), 'config.ini')
|
|
69
112
|
if not path.exists(config_path):
|
|
@@ -113,8 +156,9 @@ def gen_hostnames_by_sources(sources):
|
|
|
113
156
|
hostnames = []
|
|
114
157
|
for source in sources:
|
|
115
158
|
if not path.exists(source):
|
|
116
|
-
|
|
117
|
-
|
|
159
|
+
parsed = parse_host_name(source)
|
|
160
|
+
if parsed:
|
|
161
|
+
hostnames.append(parsed)
|
|
118
162
|
elif path.isfile(source):
|
|
119
163
|
hostnames += read_hostname_from_file(source)
|
|
120
164
|
return list(dict.fromkeys(hostnames))
|
iup-0.4.dist-info/RECORD
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
iup/__init__.py,sha256=WXPOI9BwESIVzJ-XhG7bIFhsRg98u_v5gp16nY0bcbI,108
|
|
2
|
+
iup/config.py,sha256=Ecg9m83D_Cp_inYrltt--oPcupVvCw9oo8m5ukKyWLA,2862
|
|
3
|
+
iup/main.py,sha256=zp5hwKjakNMbv1ITwlSJuukrtN5kqjAq-jyMegdzMl0,6671
|
|
4
|
+
iup-0.4.dist-info/METADATA,sha256=mPaJ2h7F5i2W-XFXIh6IV3AohZ1gUmyY1ugi_RP0Sho,204
|
|
5
|
+
iup-0.4.dist-info/WHEEL,sha256=WnJ8fYhv8N4SYVK2lLYNI6N0kVATA7b0piVUNvqIIJE,91
|
|
6
|
+
iup-0.4.dist-info/entry_points.txt,sha256=ER1eUBmB6bXwudHBT51NoOtDSlnUgBi4T6J9_kA4pwc,68
|
|
7
|
+
iup-0.4.dist-info/top_level.txt,sha256=abec3YOzJRti4IxzOLIn-uDOPTtYUE-Uv65cAv1v8JY,4
|
|
8
|
+
iup-0.4.dist-info/RECORD,,
|
iup/default_config.py
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
from configparser import ConfigParser
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
DEFAULT_CONFIG = '''[common]
|
|
8
|
-
host = 192.168.1.1
|
|
9
|
-
port = 22
|
|
10
|
-
username = root
|
|
11
|
-
password = 123457
|
|
12
|
-
refresh = False'''
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def write_default_config(path):
|
|
16
|
-
with open(path, 'w', encoding='utf-8') as f:
|
|
17
|
-
f.write(DEFAULT_CONFIG)
|
|
18
|
-
|
|
19
|
-
def write_config(config: ConfigParser, path):
|
|
20
|
-
with open(path, 'w', encoding='utf-8') as f:
|
|
21
|
-
config.write(f)
|
iup-0.2.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
iup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
iup/config.py,sha256=Ecg9m83D_Cp_inYrltt--oPcupVvCw9oo8m5ukKyWLA,2862
|
|
3
|
-
iup/default_config.py,sha256=JsNdlf_Imsa8KYlrI7A38fgBCDvn9zTZMotMK2kd0CQ,433
|
|
4
|
-
iup/main.py,sha256=pPwHBn6vhKNqpDw6aPMdaG0eWOIzEmi6Bx7usA-9BfY,5334
|
|
5
|
-
iup-0.2.dist-info/METADATA,sha256=ulXkVNr0sOFsTSipP_C5FZEPaI1cilwPrUM0xaZN8Vc,204
|
|
6
|
-
iup-0.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
|
7
|
-
iup-0.2.dist-info/entry_points.txt,sha256=ER1eUBmB6bXwudHBT51NoOtDSlnUgBi4T6J9_kA4pwc,68
|
|
8
|
-
iup-0.2.dist-info/top_level.txt,sha256=abec3YOzJRti4IxzOLIn-uDOPTtYUE-Uv65cAv1v8JY,4
|
|
9
|
-
iup-0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|