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.
- {ddns-2.13.3 → ddns-3.0.2}/PKG-INFO +3 -4
- {ddns-2.13.3 → ddns-3.0.2}/README.md +2 -2
- {ddns-2.13.3 → ddns-3.0.2}/ddns.egg-info/PKG-INFO +3 -4
- {ddns-2.13.3 → ddns-3.0.2}/dns/huaweidns.py +33 -16
- {ddns-2.13.3 → ddns-3.0.2}/run.py +6 -5
- {ddns-2.13.3 → ddns-3.0.2}/setup.py +1 -1
- {ddns-2.13.3 → ddns-3.0.2}/util/ip.py +3 -3
- {ddns-2.13.3 → ddns-3.0.2}/LICENSE +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/ddns.egg-info/SOURCES.txt +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/ddns.egg-info/dependency_links.txt +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/ddns.egg-info/entry_points.txt +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/ddns.egg-info/top_level.txt +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/dns/__init__.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/dns/alidns.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/dns/callback.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/dns/cloudflare.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/dns/dnscom.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/dns/dnspod.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/dns/dnspod_com.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/dns/he.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/setup.cfg +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/util/__init__.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/util/cache.py +0 -0
- {ddns-2.13.3 → ddns-3.0.2}/util/config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ddns
|
|
3
|
-
Version:
|
|
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] 多系统兼容 
|
|
39
|
-
- [x]
|
|
38
|
+
- [x] python3 支持 (2.x支持python2和python3)
|
|
40
39
|
- [x] PIP 安装 
|
|
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] 多系统兼容 
|
|
17
|
-
- [x]
|
|
17
|
+
- [x] python3 支持 (2.x支持python2和python3)
|
|
18
18
|
- [x] PIP 安装 
|
|
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:
|
|
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] 多系统兼容 
|
|
39
|
-
- [x]
|
|
38
|
+
- [x] python3 支持 (2.x支持python2和python3)
|
|
40
39
|
- [x] PIP 安装 
|
|
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/
|
|
146
|
+
切割域名获取主域名和对应ID https://support.huaweicloud.com/api-dns/dns_api_62003.html
|
|
147
|
+
优先匹配级数最长的主域名
|
|
147
148
|
"""
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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/
|
|
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'
|
|
197
|
+
def update_record(domain, value, record_type='A'):
|
|
191
198
|
"""
|
|
192
199
|
更新记录
|
|
193
200
|
update
|
|
194
|
-
https://support.huaweicloud.com/api-dns/
|
|
201
|
+
https://support.huaweicloud.com/api-dns/UpdateRecordSet.html
|
|
195
202
|
add
|
|
196
|
-
https://support.huaweicloud.com/api-dns/
|
|
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
|
-
"
|
|
212
|
-
"
|
|
213
|
-
"
|
|
214
|
-
|
|
215
|
-
|
|
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__ = "
|
|
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"] = "
|
|
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)
|
|
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': '
|
|
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://
|
|
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://
|
|
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
|
|
File without changes
|
|
File without changes
|