ddns 4.0.0b4__tar.gz → 4.0.0b5__tar.gz
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.
Potentially problematic release.
This version of ddns might be problematic. Click here for more details.
- {ddns-4.0.0b4 → ddns-4.0.0b5}/PKG-INFO +8 -2
- {ddns-4.0.0b4 → ddns-4.0.0b5}/README.md +7 -1
- {ddns-4.0.0b4 → ddns-4.0.0b5}/ddns.egg-info/PKG-INFO +8 -2
- {ddns-4.0.0b4 → ddns-4.0.0b5}/run.py +16 -10
- {ddns-4.0.0b4 → ddns-4.0.0b5}/util/config.py +41 -7
- {ddns-4.0.0b4 → ddns-4.0.0b5}/LICENSE +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/ddns.egg-info/SOURCES.txt +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/ddns.egg-info/dependency_links.txt +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/ddns.egg-info/entry_points.txt +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/ddns.egg-info/top_level.txt +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/dns/__init__.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/dns/alidns.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/dns/callback.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/dns/cloudflare.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/dns/dnscom.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/dns/dnspod.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/dns/dnspod_com.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/dns/he.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/dns/huaweidns.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/setup.cfg +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/setup.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/util/__init__.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/util/cache.py +0 -0
- {ddns-4.0.0b4 → ddns-4.0.0b5}/util/ip.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ddns
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.0b5
|
|
4
4
|
Summary: automatically update DNS records to dynamic local IP [自动更新DNS记录指向本地IP]
|
|
5
5
|
Home-page: https://ddns.newfuture.cc
|
|
6
6
|
Author: NewFuture
|
|
@@ -57,8 +57,12 @@ Dynamic: summary
|
|
|
57
57
|
|
|
58
58
|
- 兼容和跨平台:
|
|
59
59
|
- [Docker (@NN708)](https://hub.docker.com/r/newfuture/ddns) [](https://hub.docker.com/r/newfuture/ddns)[](https://hub.docker.com/r/newfuture/ddns)
|
|
60
|
-
- [PIP 安装 (兼容Python2)](https://pypi.org/project/ddns/)  
|
|
61
60
|
- [二进制文件](https://github.com/NewFuture/DDNS/releases/latest) 
|
|
61
|
+
|
|
62
|
+
- 配置方式:
|
|
63
|
+
- [命令行参数](#详细配置)
|
|
64
|
+
- [JSON 配置文件](#详细配置)
|
|
65
|
+
- [环境变量配置](doc/env.md) 📖
|
|
62
66
|
|
|
63
67
|
- 域名支持:
|
|
64
68
|
- 多个域名支持
|
|
@@ -157,6 +161,8 @@ Dynamic: summary
|
|
|
157
161
|
2. JSON 配置文件(值为 null 认为是有效值,会覆盖环境变量的设置,如果没有对应的 key 则会尝试使用环境变量)
|
|
158
162
|
3. 环境变量 DDNS_ 前缀加上 key 全大写或者全小写,点转下划线(`${ddns_id}` 或 `${DDNS_ID}`,`${DDNS_LOG_LEVEL}`)
|
|
159
163
|
|
|
164
|
+
> 📖 **环境变量详细配置**: 查看 [环境变量配置文档](doc/env.md) 了解所有环境变量的详细用法和示例
|
|
165
|
+
|
|
160
166
|
<details open>
|
|
161
167
|
<summary markdown="span">config.json 配置文件</summary>
|
|
162
168
|
|
|
@@ -16,8 +16,12 @@
|
|
|
16
16
|
|
|
17
17
|
- 兼容和跨平台:
|
|
18
18
|
- [Docker (@NN708)](https://hub.docker.com/r/newfuture/ddns) [](https://hub.docker.com/r/newfuture/ddns)[](https://hub.docker.com/r/newfuture/ddns)
|
|
19
|
-
- [PIP 安装 (兼容Python2)](https://pypi.org/project/ddns/)  
|
|
20
19
|
- [二进制文件](https://github.com/NewFuture/DDNS/releases/latest) 
|
|
20
|
+
|
|
21
|
+
- 配置方式:
|
|
22
|
+
- [命令行参数](#详细配置)
|
|
23
|
+
- [JSON 配置文件](#详细配置)
|
|
24
|
+
- [环境变量配置](doc/env.md) 📖
|
|
21
25
|
|
|
22
26
|
- 域名支持:
|
|
23
27
|
- 多个域名支持
|
|
@@ -116,6 +120,8 @@
|
|
|
116
120
|
2. JSON 配置文件(值为 null 认为是有效值,会覆盖环境变量的设置,如果没有对应的 key 则会尝试使用环境变量)
|
|
117
121
|
3. 环境变量 DDNS_ 前缀加上 key 全大写或者全小写,点转下划线(`${ddns_id}` 或 `${DDNS_ID}`,`${DDNS_LOG_LEVEL}`)
|
|
118
122
|
|
|
123
|
+
> 📖 **环境变量详细配置**: 查看 [环境变量配置文档](doc/env.md) 了解所有环境变量的详细用法和示例
|
|
124
|
+
|
|
119
125
|
<details open>
|
|
120
126
|
<summary markdown="span">config.json 配置文件</summary>
|
|
121
127
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ddns
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.0b5
|
|
4
4
|
Summary: automatically update DNS records to dynamic local IP [自动更新DNS记录指向本地IP]
|
|
5
5
|
Home-page: https://ddns.newfuture.cc
|
|
6
6
|
Author: NewFuture
|
|
@@ -57,8 +57,12 @@ Dynamic: summary
|
|
|
57
57
|
|
|
58
58
|
- 兼容和跨平台:
|
|
59
59
|
- [Docker (@NN708)](https://hub.docker.com/r/newfuture/ddns) [](https://hub.docker.com/r/newfuture/ddns)[](https://hub.docker.com/r/newfuture/ddns)
|
|
60
|
-
- [PIP 安装 (兼容Python2)](https://pypi.org/project/ddns/)  
|
|
61
60
|
- [二进制文件](https://github.com/NewFuture/DDNS/releases/latest) 
|
|
61
|
+
|
|
62
|
+
- 配置方式:
|
|
63
|
+
- [命令行参数](#详细配置)
|
|
64
|
+
- [JSON 配置文件](#详细配置)
|
|
65
|
+
- [环境变量配置](doc/env.md) 📖
|
|
62
66
|
|
|
63
67
|
- 域名支持:
|
|
64
68
|
- 多个域名支持
|
|
@@ -157,6 +161,8 @@ Dynamic: summary
|
|
|
157
161
|
2. JSON 配置文件(值为 null 认为是有效值,会覆盖环境变量的设置,如果没有对应的 key 则会尝试使用环境变量)
|
|
158
162
|
3. 环境变量 DDNS_ 前缀加上 key 全大写或者全小写,点转下划线(`${ddns_id}` 或 `${DDNS_ID}`,`${DDNS_LOG_LEVEL}`)
|
|
159
163
|
|
|
164
|
+
> 📖 **环境变量详细配置**: 查看 [环境变量配置文档](doc/env.md) 了解所有环境变量的详细用法和示例
|
|
165
|
+
|
|
160
166
|
<details open>
|
|
161
167
|
<summary markdown="span">config.json 配置文件</summary>
|
|
162
168
|
|
|
@@ -9,9 +9,10 @@ DDNS
|
|
|
9
9
|
# nuitka-project: --product-version=0.0.0
|
|
10
10
|
|
|
11
11
|
from os import path, environ, name as os_name
|
|
12
|
+
from io import TextIOWrapper
|
|
13
|
+
from subprocess import check_output
|
|
12
14
|
from tempfile import gettempdir
|
|
13
15
|
from logging import basicConfig, info, warning, error, debug
|
|
14
|
-
from subprocess import check_output
|
|
15
16
|
|
|
16
17
|
import sys
|
|
17
18
|
|
|
@@ -19,7 +20,7 @@ from util import ip
|
|
|
19
20
|
from util.cache import Cache
|
|
20
21
|
from util.config import init_config, get_config
|
|
21
22
|
|
|
22
|
-
__version__ = "v4.0.0-
|
|
23
|
+
__version__ = "v4.0.0-beta5@2025-06-12T01:13:18+00:00" # CI 时会被Tag替换
|
|
23
24
|
__description__ = "automatically update DNS records to dynamic local IP [自动更新DNS记录指向本地IP]"
|
|
24
25
|
__doc__ = """
|
|
25
26
|
ddns[%s]
|
|
@@ -28,12 +29,18 @@ ddns[%s]
|
|
|
28
29
|
Copyright (c) New Future (MIT License)
|
|
29
30
|
""" % (__version__)
|
|
30
31
|
|
|
31
|
-
environ["DDNS_VERSION"] = "v4.0.0-
|
|
32
|
+
environ["DDNS_VERSION"] = "v4.0.0-beta5"
|
|
33
|
+
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
def is_false(value):
|
|
36
|
+
"""
|
|
37
|
+
判断值是否为 False
|
|
38
|
+
字符串 'false', 或者 False, 或者 'none';
|
|
39
|
+
0 不是 False
|
|
40
|
+
"""
|
|
41
|
+
if isinstance(value, str):
|
|
42
|
+
return value.strip().lower() in ['false', 'none']
|
|
43
|
+
return value is False
|
|
37
44
|
|
|
38
45
|
|
|
39
46
|
def get_ip(ip_type, index="default"):
|
|
@@ -45,7 +52,7 @@ def get_ip(ip_type, index="default"):
|
|
|
45
52
|
value = None
|
|
46
53
|
try:
|
|
47
54
|
debug("get_ip(%s, %s)", ip_type, index)
|
|
48
|
-
if index
|
|
55
|
+
if is_false(index): # disabled
|
|
49
56
|
return False
|
|
50
57
|
elif isinstance(index, list): # 如果获取到的规则是列表,则依次判断列表中每一个规则,直到获取到IP
|
|
51
58
|
for i in index:
|
|
@@ -163,9 +170,8 @@ def main():
|
|
|
163
170
|
|
|
164
171
|
if __name__ == '__main__':
|
|
165
172
|
encoding = sys.stdout.encoding
|
|
166
|
-
if encoding is not None and encoding.lower() != 'utf-8':
|
|
173
|
+
if encoding is not None and encoding.lower() != 'utf-8' and hasattr(sys.stdout, 'buffer'):
|
|
167
174
|
# 兼容windows 和部分ASCII编码的老旧系统
|
|
168
|
-
from io import TextIOWrapper
|
|
169
175
|
sys.stdout = TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
|
170
176
|
sys.stderr = TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
|
|
171
177
|
main()
|
|
@@ -4,6 +4,7 @@ from argparse import Action, ArgumentParser, Namespace, RawTextHelpFormatter
|
|
|
4
4
|
from json import load as loadjson, dump as dumpjson
|
|
5
5
|
from os import stat, environ, path
|
|
6
6
|
from logging import error, getLevelName
|
|
7
|
+
from ast import literal_eval
|
|
7
8
|
|
|
8
9
|
import sys
|
|
9
10
|
|
|
@@ -13,6 +14,11 @@ __config = {} # type: dict
|
|
|
13
14
|
log_levels = ['CRITICAL', 'FATAL', 'ERROR',
|
|
14
15
|
'WARN', 'WARNING', 'INFO', 'DEBUG', 'NOTSET']
|
|
15
16
|
|
|
17
|
+
# 支持数组的参数列表
|
|
18
|
+
ARRAY_PARAMS = ['index4', 'index6', 'ipv4', 'ipv6', 'proxy']
|
|
19
|
+
# 简单数组,支持’,’, ‘;’ 分隔的参数列表
|
|
20
|
+
SIMPLE_ARRAY_PARAMS = ['ipv4', 'ipv6', 'proxy']
|
|
21
|
+
|
|
16
22
|
|
|
17
23
|
def str2bool(v):
|
|
18
24
|
"""
|
|
@@ -35,6 +41,32 @@ def log_level(value):
|
|
|
35
41
|
return getLevelName(value.upper())
|
|
36
42
|
|
|
37
43
|
|
|
44
|
+
def parse_array_string(value, enable_simple_split):
|
|
45
|
+
"""
|
|
46
|
+
解析数组字符串
|
|
47
|
+
仅当 trim 之后以 '[' 开头以 ']' 结尾时,才尝试使用 ast.literal_eval 解析
|
|
48
|
+
默认返回原始字符串
|
|
49
|
+
"""
|
|
50
|
+
if not isinstance(value, str):
|
|
51
|
+
return value
|
|
52
|
+
|
|
53
|
+
trimmed = value.strip()
|
|
54
|
+
if trimmed.startswith('[') and trimmed.endswith(']'):
|
|
55
|
+
try:
|
|
56
|
+
# 尝试使用 ast.literal_eval 解析数组
|
|
57
|
+
parsed_value = literal_eval(trimmed)
|
|
58
|
+
# 确保解析结果是列表或元组
|
|
59
|
+
if isinstance(parsed_value, (list, tuple)):
|
|
60
|
+
return list(parsed_value)
|
|
61
|
+
except (ValueError, SyntaxError) as e:
|
|
62
|
+
# 解析失败时返回原始字符串
|
|
63
|
+
error('Failed to parse array string: %s. Exception: %s', value, e)
|
|
64
|
+
elif enable_simple_split and ',' in trimmed:
|
|
65
|
+
# 尝试使用逗号或分号分隔符解析
|
|
66
|
+
return [item.strip() for item in trimmed.split(',') if item.strip()]
|
|
67
|
+
return value
|
|
68
|
+
|
|
69
|
+
|
|
38
70
|
def init_config(description, doc, version):
|
|
39
71
|
"""
|
|
40
72
|
配置
|
|
@@ -128,14 +160,16 @@ def get_config(key, default=None):
|
|
|
128
160
|
return getattr(__cli_args, key)
|
|
129
161
|
if key in __config:
|
|
130
162
|
return __config.get(key)
|
|
163
|
+
# 检查环境变量
|
|
131
164
|
env_name = 'DDNS_' + key.replace('.', '_') # type:str
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return
|
|
138
|
-
|
|
165
|
+
variations = [env_name, env_name.upper(), env_name.lower()]
|
|
166
|
+
value = next((environ.get(v) for v in variations if v in environ), None)
|
|
167
|
+
|
|
168
|
+
# 如果找到环境变量值且参数支持数组,尝试解析为数组
|
|
169
|
+
if value is not None and key in ARRAY_PARAMS:
|
|
170
|
+
return parse_array_string(value, key in SIMPLE_ARRAY_PARAMS)
|
|
171
|
+
|
|
172
|
+
return value if value is not None else default
|
|
139
173
|
|
|
140
174
|
|
|
141
175
|
class ExtendAction(Action):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|