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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ddns
3
- Version: 4.0.0b4
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) [![Docker Image Size](https://img.shields.io/docker/image-size/newfuture/ddns/latest?logo=docker&style=social)](https://hub.docker.com/r/newfuture/ddns)[![Docker Platforms](https://img.shields.io/badge/arch-amd64%20%7C%20arm64%20%7C%20arm%2Fv7%20%7C%20arm%2Fv6%20%7C%20ppc64le%20%7C%20s390x%20%7C%20386%20%7C%20mips64le-blue?style=social)](https://hub.docker.com/r/newfuture/ddns)
60
- - [PIP 安装 (兼容Python2)](https://pypi.org/project/ddns/) ![PyPI - Wheel](https://img.shields.io/pypi/wheel/ddns.svg?logo=pypi&style=social) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)
61
60
  - [二进制文件](https://github.com/NewFuture/DDNS/releases/latest) ![cross platform](https://img.shields.io/badge/system-windows_%7C%20linux_%7C%20mac-success.svg?style=social)
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) [![Docker Image Size](https://img.shields.io/docker/image-size/newfuture/ddns/latest?logo=docker&style=social)](https://hub.docker.com/r/newfuture/ddns)[![Docker Platforms](https://img.shields.io/badge/arch-amd64%20%7C%20arm64%20%7C%20arm%2Fv7%20%7C%20arm%2Fv6%20%7C%20ppc64le%20%7C%20s390x%20%7C%20386%20%7C%20mips64le-blue?style=social)](https://hub.docker.com/r/newfuture/ddns)
19
- - [PIP 安装 (兼容Python2)](https://pypi.org/project/ddns/) ![PyPI - Wheel](https://img.shields.io/pypi/wheel/ddns.svg?logo=pypi&style=social) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)
20
19
  - [二进制文件](https://github.com/NewFuture/DDNS/releases/latest) ![cross platform](https://img.shields.io/badge/system-windows_%7C%20linux_%7C%20mac-success.svg?style=social)
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.0b4
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) [![Docker Image Size](https://img.shields.io/docker/image-size/newfuture/ddns/latest?logo=docker&style=social)](https://hub.docker.com/r/newfuture/ddns)[![Docker Platforms](https://img.shields.io/badge/arch-amd64%20%7C%20arm64%20%7C%20arm%2Fv7%20%7C%20arm%2Fv6%20%7C%20ppc64le%20%7C%20s390x%20%7C%20386%20%7C%20mips64le-blue?style=social)](https://hub.docker.com/r/newfuture/ddns)
60
- - [PIP 安装 (兼容Python2)](https://pypi.org/project/ddns/) ![PyPI - Wheel](https://img.shields.io/pypi/wheel/ddns.svg?logo=pypi&style=social) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)
61
60
  - [二进制文件](https://github.com/NewFuture/DDNS/releases/latest) ![cross platform](https://img.shields.io/badge/system-windows_%7C%20linux_%7C%20mac-success.svg?style=social)
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-beta4@2025-06-10T17:58:37+00:00" # CI 时会被Tag替换
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-beta4"
32
+ environ["DDNS_VERSION"] = "v4.0.0-beta5"
33
+
32
34
 
33
- if getattr(sys, 'frozen', False):
34
- # https://github.com/pyinstaller/pyinstaller/wiki/Recipe-OpenSSL-Certificate
35
- environ['SSL_CERT_FILE'] = path.join(
36
- getattr(sys, '_MEIPASS'), 'lib', 'cert.pem')
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 is False: # disabled
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
- if env_name in environ: # 环境变量
133
- return environ.get(env_name)
134
- elif env_name.upper() in environ: # 大写环境变量
135
- return environ.get(env_name.upper())
136
- elif env_name.lower() in environ: # 小写环境变量
137
- return environ.get(env_name.lower())
138
- return default
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