ddns 2.13.3__tar.gz → 3.0.2__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.1
2
2
  Name: ddns
3
- Version: 2.13.3
3
+ Version: 3.0.2
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
@@ -14,7 +14,6 @@ Classifier: Development Status :: 5 - Production/Stable
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: Topic :: Software Development :: Build Tools
16
16
  Classifier: License :: OSI Approved :: MIT License
17
- Classifier: Programming Language :: Python :: 2.7
18
17
  Classifier: Programming Language :: Python :: 3
19
18
  Requires-Python: >=2.5, <4
20
19
  Description-Content-Type: text/markdown
@@ -36,7 +35,7 @@ License-File: LICENSE
36
35
  - 兼容和跨平台:
37
36
  - [x] 可执行文件(无需 python 环境)
38
37
  - [x] 多系统兼容 ![cross platform](https://img.shields.io/badge/platform-windows_%7C%20linux_%7C%20osx-success.svg?style=social)
39
- - [x] python2 和 python3 支持 ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)
38
+ - [x] python3 支持 ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)(2.x支持python2和python3)
40
39
  - [x] PIP 安装 ![PyPI - Wheel](https://img.shields.io/pypi/wheel/ddns.svg?style=social)
41
40
  - [x] Docker 支持(@NN708)
42
41
  - 域名支持:
@@ -143,7 +142,7 @@ python run.py -c /path/to/config.json
143
142
 
144
143
  | key | type | required | default | description | tips |
145
144
  | :----: | :----------------: | :------: | :---------: | :---------------: | ----------------------------------------------------------------------------------------------------------- |
146
- | id | string | √ | 无 | api 访问 ID | Cloudflare 为邮箱(使用 Token 时留空)<br>HE.net 可留空 |
145
+ | id | string | √ | 无 | api 访问 ID | Cloudflare 为邮箱(使用 Token 时留空)<br>HE.net 可留空<br>华为云为 Access Key ID (AK) |
147
146
  | token | string | √ | 无 | api 授权 token | 部分平台叫 secret key , **反馈粘贴时删除** |
148
147
  | dns | string | No | `"dnspod"` | dns 服务商 | 阿里 DNS 为`alidns`,<br>Cloudflare 为 `cloudflare`,<br>dns.com 为 `dnscom`,<br>DNSPOD 国内为 `dnspod`,<br>DNSPOD 国际版为 `dnspod_com`,<br>HE.net 为`he`,<br>华为 DNS 为`huaweidns`,<br>自定义回调为`callback` |
149
148
  | ipv4 | array | No | `[]` | ipv4 域名列表 | 为`[]`时,不会获取和更新 IPv4 地址 |
@@ -14,7 +14,7 @@
14
14
  - 兼容和跨平台:
15
15
  - [x] 可执行文件(无需 python 环境)
16
16
  - [x] 多系统兼容 ![cross platform](https://img.shields.io/badge/platform-windows_%7C%20linux_%7C%20osx-success.svg?style=social)
17
- - [x] python2 和 python3 支持 ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)
17
+ - [x] python3 支持 ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)(2.x支持python2和python3)
18
18
  - [x] PIP 安装 ![PyPI - Wheel](https://img.shields.io/pypi/wheel/ddns.svg?style=social)
19
19
  - [x] Docker 支持(@NN708)
20
20
  - 域名支持:
@@ -121,7 +121,7 @@ python run.py -c /path/to/config.json
121
121
 
122
122
  | key | type | required | default | description | tips |
123
123
  | :----: | :----------------: | :------: | :---------: | :---------------: | ----------------------------------------------------------------------------------------------------------- |
124
- | id | string | √ | 无 | api 访问 ID | Cloudflare 为邮箱(使用 Token 时留空)<br>HE.net 可留空 |
124
+ | id | string | √ | 无 | api 访问 ID | Cloudflare 为邮箱(使用 Token 时留空)<br>HE.net 可留空<br>华为云为 Access Key ID (AK) |
125
125
  | token | string | √ | 无 | api 授权 token | 部分平台叫 secret key , **反馈粘贴时删除** |
126
126
  | dns | string | No | `"dnspod"` | dns 服务商 | 阿里 DNS 为`alidns`,<br>Cloudflare 为 `cloudflare`,<br>dns.com 为 `dnscom`,<br>DNSPOD 国内为 `dnspod`,<br>DNSPOD 国际版为 `dnspod_com`,<br>HE.net 为`he`,<br>华为 DNS 为`huaweidns`,<br>自定义回调为`callback` |
127
127
  | ipv4 | array | No | `[]` | ipv4 域名列表 | 为`[]`时,不会获取和更新 IPv4 地址 |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ddns
3
- Version: 2.13.3
3
+ Version: 3.0.2
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
@@ -14,7 +14,6 @@ Classifier: Development Status :: 5 - Production/Stable
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: Topic :: Software Development :: Build Tools
16
16
  Classifier: License :: OSI Approved :: MIT License
17
- Classifier: Programming Language :: Python :: 2.7
18
17
  Classifier: Programming Language :: Python :: 3
19
18
  Requires-Python: >=2.5, <4
20
19
  Description-Content-Type: text/markdown
@@ -36,7 +35,7 @@ License-File: LICENSE
36
35
  - 兼容和跨平台:
37
36
  - [x] 可执行文件(无需 python 环境)
38
37
  - [x] 多系统兼容 ![cross platform](https://img.shields.io/badge/platform-windows_%7C%20linux_%7C%20osx-success.svg?style=social)
39
- - [x] python2 和 python3 支持 ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)
38
+ - [x] python3 支持 ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)(2.x支持python2和python3)
40
39
  - [x] PIP 安装 ![PyPI - Wheel](https://img.shields.io/pypi/wheel/ddns.svg?style=social)
41
40
  - [x] Docker 支持(@NN708)
42
41
  - 域名支持:
@@ -143,7 +142,7 @@ python run.py -c /path/to/config.json
143
142
 
144
143
  | key | type | required | default | description | tips |
145
144
  | :----: | :----------------: | :------: | :---------: | :---------------: | ----------------------------------------------------------------------------------------------------------- |
146
- | id | string | √ | 无 | api 访问 ID | Cloudflare 为邮箱(使用 Token 时留空)<br>HE.net 可留空 |
145
+ | id | string | √ | 无 | api 访问 ID | Cloudflare 为邮箱(使用 Token 时留空)<br>HE.net 可留空<br>华为云为 Access Key ID (AK) |
147
146
  | token | string | √ | 无 | api 授权 token | 部分平台叫 secret key , **反馈粘贴时删除** |
148
147
  | dns | string | No | `"dnspod"` | dns 服务商 | 阿里 DNS 为`alidns`,<br>Cloudflare 为 `cloudflare`,<br>dns.com 为 `dnscom`,<br>DNSPOD 国内为 `dnspod`,<br>DNSPOD 国际版为 `dnspod_com`,<br>HE.net 为`he`,<br>华为 DNS 为`huaweidns`,<br>自定义回调为`callback` |
149
148
  | ipv4 | array | No | `[]` | ipv4 域名列表 | 为`[]`时,不会获取和更新 IPv4 地址 |
@@ -143,12 +143,19 @@ def request(method, path, param=None, body=None, **params):
143
143
 
144
144
  def get_zone_id(domain):
145
145
  """
146
- 切割域名获取主域名和对应ID https://support.huaweicloud.com/api-dns/zh-cn_topic_0037134402.html
146
+ 切割域名获取主域名和对应ID https://support.huaweicloud.com/api-dns/dns_api_62003.html
147
+ 优先匹配级数最长的主域名
147
148
  """
148
- zones = request('GET', '/v2/zones', limit=500)['zones']
149
- domain += '.'
150
- zone = next((z for z in zones if domain.endswith(z.get('name'))), None)
151
- zoneid = zone and zone['id']
149
+ zoneid = None
150
+ domain_slice = domain.split('.')
151
+ index = len(domain_slice)
152
+ root_domain = '.'.join(domain_slice[-2:])
153
+ zones = request('GET', '/v2/zones', limit=500, name=root_domain)['zones']
154
+ while (not zoneid) and (index >= 2):
155
+ domain = '.'.join(domain_slice[-index:]) + '.'
156
+ zone = next((z for z in zones if domain == (z.get('name'))), None)
157
+ zoneid = zone and zone['id']
158
+ index -= 1
152
159
  return zoneid
153
160
 
154
161
 
@@ -156,7 +163,7 @@ def get_records(zoneid, **conditions):
156
163
  """
157
164
  获取记录ID
158
165
  返回满足条件的所有记录[]
159
- https://support.huaweicloud.com/api-dns/zh-cn_topic_0037129970.html
166
+ https://support.huaweicloud.com/api-dns/dns_api_64004.html
160
167
  TODO 大于500翻页
161
168
  """
162
169
  cache_key = zoneid + "_" + \
@@ -187,13 +194,13 @@ def get_records(zoneid, **conditions):
187
194
  return records
188
195
 
189
196
 
190
- def update_record(domain, value, record_type='A', name=None):
197
+ def update_record(domain, value, record_type='A'):
191
198
  """
192
199
  更新记录
193
200
  update
194
- https://support.huaweicloud.com/api-dns/dns_api_64006.html
201
+ https://support.huaweicloud.com/api-dns/UpdateRecordSet.html
195
202
  add
196
- https://support.huaweicloud.com/api-dns/zh-cn_topic_0037134404.html
203
+ https://support.huaweicloud.com/api-dns/dns_api_64001.html
197
204
  """
198
205
  info(">>>>>%s(%s)", domain, record_type)
199
206
  zoneid = get_zone_id(domain)
@@ -207,20 +214,27 @@ def update_record(domain, value, record_type='A', name=None):
207
214
  for (rid, record) in records.items():
208
215
  if record['records'] != value:
209
216
  """
217
+ PUT https://{endpoint}/v2/zones/{zone_id}/recordsets/{recordset_id}
218
+
210
219
  {
211
- "description": "This is an example record set.",
212
- "ttl": 3600,
213
- "records": [
214
- "192.168.10.1",
215
- "192.168.10.2"
216
- ]
220
+ "name" : "www.example.com.",
221
+ "description" : "This is an example record set.",
222
+ "type" : "A",
223
+ "ttl" : 3600,
224
+ "records" : [ "192.168.10.1", "192.168.10.2" ]
217
225
  }
218
226
  """
219
227
  body = {
228
+ "name": domain,
229
+ "description": "Managed by DDNS.",
230
+ "type": record_type,
220
231
  "records": [
221
232
  value
222
233
  ]
223
234
  }
235
+ # 如果TTL不为空,则添加到字典中
236
+ if Config.TTL is not None:
237
+ body['ttl'] = Config.TTL
224
238
  res = request('PUT', '/v2/zones/' + zoneid + '/recordsets/' + record['id'],
225
239
  body=str(jsonencode(body)))
226
240
  if res:
@@ -231,14 +245,17 @@ def update_record(domain, value, record_type='A', name=None):
231
245
  else:
232
246
  result[rid] = domain
233
247
  else: # create
234
- print(domain)
235
248
  body = {
236
249
  "name": domain,
250
+ "description": "Managed by DDNS.",
237
251
  "type": record_type,
238
252
  "records": [
239
253
  value
240
254
  ]
241
255
  }
256
+ # 如果TTL不为空,则添加到字典中
257
+ if Config.TTL is not None:
258
+ body['ttl'] = Config.TTL
242
259
  res = request('POST', '/v2/zones/' + zoneid + '/recordsets',
243
260
  body=str(jsonencode(body)))
244
261
  if res:
@@ -18,7 +18,7 @@ from util import ip
18
18
  from util.cache import Cache
19
19
  from util.config import init_config, get_config
20
20
 
21
- __version__ = "v2.13.3@2023-04-19T11:45:22+00:00" # CI 时会被Tag替换
21
+ __version__ = "v3.0.2@2024-06-13T12:25:13+00:00" # CI 时会被Tag替换
22
22
  __description__ = "automatically update DNS records to dynamic local IP [自动更新DNS记录指向本地IP]"
23
23
  __doc__ = """
24
24
  ddns[%s]
@@ -27,7 +27,7 @@ ddns[%s]
27
27
  Copyright (c) New Future (MIT License)
28
28
  """ % (__version__)
29
29
 
30
- environ["DDNS_VERSION"] = "v2.13.3"
30
+ environ["DDNS_VERSION"] = "v3.0.2"
31
31
 
32
32
  if getattr(sys, 'frozen', False):
33
33
  # https://github.com/pyinstaller/pyinstaller/wiki/Recipe-OpenSSL-Certificate
@@ -41,7 +41,7 @@ def get_ip(ip_type, index="default"):
41
41
  """
42
42
  if index is False: # disabled
43
43
  return False
44
- elif type(index) == list: # 如果获取到的规则是列表,则依次判断列表中每一个规则,直到找到一个可以正确获取到的IP
44
+ elif type(index) is list: # 如果获取到的规则是列表,则依次判断列表中每一个规则,直到找到一个可以正确获取到的IP
45
45
  value = None
46
46
  for i in index:
47
47
  value = get_ip(ip_type, i)
@@ -69,9 +69,9 @@ def get_ip(ip_type, index="default"):
69
69
  def change_dns_record(dns, proxy_list, **kw):
70
70
  for proxy in proxy_list:
71
71
  if not proxy or (proxy.upper() in ['DIRECT', 'NONE']):
72
- dns.PROXY = None
72
+ dns.Config.PROXY = None
73
73
  else:
74
- dns.PROXY = proxy
74
+ dns.Config.PROXY = proxy
75
75
  record_type, domain = kw['record_type'], kw['domain']
76
76
  print('\n%s %s(%s) ==> %s [via %s]' %
77
77
  (asctime(), domain, record_type, kw['ip'], proxy))
@@ -104,6 +104,7 @@ def update_ip(ip_type, cache, dns, proxy_list):
104
104
  record_type = (ip_type == '4') and 'A' or 'AAAA'
105
105
  update_fail = False # https://github.com/NewFuture/DDNS/issues/16
106
106
  for domain in domains:
107
+ domain = domain.lower() # https://github.com/NewFuture/DDNS/issues/431
107
108
  if change_dns_record(dns, proxy_list, domain=domain, ip=address, record_type=record_type):
108
109
  update_fail = True
109
110
  if cache is not False:
@@ -135,7 +135,7 @@ setup(
135
135
  # that you indicate whether you support Python 2, Python 3 or both.
136
136
  # These classifiers are *not* checked by 'pip install'. See instead
137
137
  # 'python_requires' below.
138
- 'Programming Language :: Python :: 2.7',
138
+ # 'Programming Language :: Python :: 2.7',
139
139
  'Programming Language :: Python :: 3',
140
140
  ],
141
141
 
@@ -50,7 +50,7 @@ def _open(url, reg):
50
50
  try:
51
51
  debug("open: %s", url)
52
52
  res = urlopen(
53
- Request(url, headers={'User-Agent': 'curl/7.63.0-ddns'}), timeout=60
53
+ Request(url, headers={'User-Agent': 'Mozilla/5.0 ddns'}), timeout=60
54
54
  ).read().decode('utf8', 'ignore')
55
55
  debug("response: %s", res)
56
56
  return compile(reg).search(res).group()
@@ -58,11 +58,11 @@ def _open(url, reg):
58
58
  error(e)
59
59
 
60
60
 
61
- def public_v4(url="https://myip4.ipip.net", reg=IPV4_REG): # 公网IPV4地址
61
+ def public_v4(url="https://api-ipv4.ip.sb/ip", reg=IPV4_REG): # 公网IPV4地址
62
62
  return _open(url, reg)
63
63
 
64
64
 
65
- def public_v6(url="https://myip6.ipip.net", reg=IPV6_REG): # 公网IPV6地址
65
+ def public_v6(url="https://api-ipv6.ip.sb/ip", reg=IPV6_REG): # 公网IPV6地址
66
66
  return _open(url, reg)
67
67
 
68
68
 
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