dynamicdns 0.1.0rc1__tar.gz → 0.1.0rc3__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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "editor.defaultFormatter": "charliermarsh.ruff",
3
+ "editor.rulers": [
4
+ 100
5
+ ],
6
+ "editor.formatOnSave": true,
7
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dynamicdns
3
- Version: 0.1.0rc1
3
+ Version: 0.1.0rc3
4
4
  Summary: Collection of Dynamic DNS providers
5
5
  Project-URL: Documentation, https://github.com/tr4nt0r/dynamicdns#readme
6
6
  Project-URL: Issues, https://github.com/tr4nt0r/dynamicdns/issues
@@ -2,12 +2,12 @@
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
- from .providers import Provider, ProviderConf, providers
5
+ from .providers import Provider, ProviderConf, PROVIDERS
6
6
  from .updater import Updater
7
7
 
8
- __version__ = "0.1.0rc1"
8
+ __version__ = "0.1.0rc3"
9
9
  __all__ = [
10
- "providers",
10
+ "PROVIDERS",
11
11
  "Provider",
12
12
  "ProviderConf",
13
13
  "Updater",
@@ -2,7 +2,6 @@
2
2
 
3
3
  from typing import Final
4
4
 
5
- CONF_HOSTS: Final = "hosts"
6
5
  CONF_HOST: Final = "host"
7
6
  CONF_TOKEN: Final = "token"
8
7
  CONF_USERNAME: Final = "username"
@@ -13,3 +12,4 @@ CONF_VERBOSE: Final = "verbose"
13
12
  CONF_TXT: Final = "txt"
14
13
  CONF_CLEAR: Final = "clear"
15
14
  CONF_DOMAIN: Final = "domain"
15
+ CONF_URL: Final = "url"
@@ -16,6 +16,7 @@ from .const import (
16
16
  CONF_IPV6_ADDRESS,
17
17
  CONF_PASSWORD,
18
18
  CONF_TOKEN,
19
+ CONF_URL,
19
20
  CONF_USERNAME,
20
21
  )
21
22
 
@@ -23,12 +24,14 @@ from .const import (
23
24
  class Provider(StrEnum):
24
25
  """Dynamic DNS providers."""
25
26
 
26
- DUCKDNS = "duckdns"
27
- MYTHICBEASTS_IPV4 = "mythicbeasts_ipv4"
28
27
  ANYDNS = "anydns"
28
+ DUCKDNS = "duckdns"
29
29
  FREEDNS = "freedns"
30
30
  FREEDNS_IPV6 = "freedns_ipv6"
31
+ MYTHICBEASTS = "mythicbeasts"
31
32
  NAMECHEAP = "namecheap"
33
+ NO_IP = "no_ip"
34
+ CUSTOM = "custom"
32
35
 
33
36
 
34
37
  @dataclass(frozen=True, kw_only=True)
@@ -44,13 +47,16 @@ class ProviderConf:
44
47
 
45
48
  def render_url(self, data: dict[str, str]) -> URL:
46
49
  """Render the provider URL with given data and remove unused query parameters."""
47
-
48
- url = URL(self.base_url)
50
+ url = URL(data.get(CONF_URL) or self.base_url)
49
51
  url = url.with_path(url.path.format(**data))
52
+ if url.user:
53
+ url = url.with_user(url.user.format(**data))
54
+ if url.password:
55
+ url = url.with_password(url.password.format(**data))
50
56
  return url % {k: data[v] for k, v in self.params.items() if v in data}
51
57
 
52
58
 
53
- providers: dict[Provider, ProviderConf] = {
59
+ PROVIDERS: dict[Provider, ProviderConf] = {
54
60
  Provider.DUCKDNS: ProviderConf(
55
61
  name="Duck DNS",
56
62
  base_url="https://www.duckdns.org/update?verbose=true",
@@ -68,8 +74,8 @@ providers: dict[Provider, ProviderConf] = {
68
74
  ),
69
75
  success_fn=lambda x: x.startswith("OK"),
70
76
  ),
71
- Provider.MYTHICBEASTS_IPV4: ProviderConf(
72
- name="Mythic Beasts IPv4",
77
+ Provider.MYTHICBEASTS: ProviderConf(
78
+ name="Mythic Beasts",
73
79
  base_url="https://ipv4.api.mythic-beasts.com/dns/v2/dynamic/{domain}",
74
80
  method="POST",
75
81
  params={"username": CONF_USERNAME, "password": CONF_PASSWORD},
@@ -85,7 +91,7 @@ providers: dict[Provider, ProviderConf] = {
85
91
  name="AnyDNS.info",
86
92
  base_url="https://anydns.info/update.php",
87
93
  params={
88
- "host": CONF_HOST,
94
+ "host": CONF_DOMAIN,
89
95
  "user": CONF_USERNAME,
90
96
  "password": CONF_PASSWORD,
91
97
  "ip": CONF_IP_ADDRESS,
@@ -93,14 +99,14 @@ providers: dict[Provider, ProviderConf] = {
93
99
  },
94
100
  schema=vol.Schema(
95
101
  {
96
- vol.Required(CONF_HOST): str,
102
+ vol.Required(CONF_DOMAIN): str,
97
103
  vol.Required(CONF_USERNAME): str,
98
104
  vol.Required(CONF_PASSWORD): str,
99
105
  },
100
106
  ),
101
107
  ),
102
108
  Provider.FREEDNS: ProviderConf(
103
- name="FreeDNS IPv4",
109
+ name="FreeDNS",
104
110
  base_url="https://sync.afraid.org/u/{token}/",
105
111
  params={"address": CONF_IP_ADDRESS},
106
112
  schema=vol.Schema({vol.Required(CONF_TOKEN): str}),
@@ -132,5 +138,31 @@ providers: dict[Provider, ProviderConf] = {
132
138
  vol.Required(CONF_PASSWORD): str,
133
139
  }
134
140
  ),
141
+ success_fn=lambda x: "<ErrCount>0</ErrCount>" in x,
142
+ ),
143
+ Provider.NO_IP: ProviderConf(
144
+ name="NO-IP.com",
145
+ base_url="https://{username}:{password}@dynupdate.no-ip.com/nic/update",
146
+ params={
147
+ "hostname": CONF_DOMAIN,
148
+ "myip": CONF_IP_ADDRESS,
149
+ },
150
+ schema=vol.Schema(
151
+ {
152
+ vol.Required(CONF_DOMAIN, default="all.ddnskey.com"): str,
153
+ vol.Required(CONF_USERNAME): str,
154
+ vol.Required(CONF_PASSWORD): str,
155
+ }
156
+ ),
157
+ success_fn=lambda x: x.startswith(("good", "nochg")),
158
+ ),
159
+ Provider.CUSTOM: ProviderConf(
160
+ name="Custom dynamic DNS provider",
161
+ base_url="{url}",
162
+ params={
163
+ "ip": CONF_IP_ADDRESS,
164
+ "ipv6": CONF_IPV6_ADDRESS,
165
+ },
166
+ schema=vol.Schema({vol.Required(CONF_URL): str}),
135
167
  ),
136
168
  }
@@ -6,7 +6,7 @@ import logging
6
6
 
7
7
  from aiohttp import ClientSession
8
8
 
9
- from .providers import Provider, providers
9
+ from .providers import Provider, PROVIDERS
10
10
 
11
11
  _LOGGER = logging.getLogger(__package__)
12
12
 
@@ -23,15 +23,16 @@ class Updater:
23
23
  """Initialize."""
24
24
 
25
25
  self.session = session
26
- self.method = providers[provider].method
27
- self.url = providers[provider].render_url(data)
28
- self.success = providers[provider].success_fn
26
+ self.provider = provider
27
+ self.method = PROVIDERS[provider].method
28
+ self.url = PROVIDERS[provider].render_url(data)
29
+ self.success = PROVIDERS[provider].success_fn
29
30
 
30
31
  async def update(self) -> bool:
31
32
  """Update the dynamic DNS record."""
32
33
 
33
34
  async with self.session.request(self.method, self.url) as res:
34
- _LOGGER.debug(await res.text())
35
+ _LOGGER.debug("[%s]: %s", self.provider.name, await res.text())
35
36
  return (
36
37
  self.success(await res.text()) if self.success is not None else res.ok
37
38
  )
@@ -1,4 +0,0 @@
1
- {
2
- "editor.defaultFormatter": "charliermarsh.ruff",
3
- "editor.rulers": [100],
4
- }
File without changes
File without changes
File without changes