On 6 Jan 2020, at 12:31, Stefan Schantl stefan.schantl@ipfire.org wrote:
Hello Kim,
thanks for keep working on this and sorry for the long delay.
Today I had some spare-time and checked your patch.
Besides there are still some formating issues because of your used Editor (New blank lines added, tabs are reformated, intensions are changed etc), I was not able to get a list of the supported Providers anymore after applying your Patch.
Some of those whitespace changes are required because Python 3 does not allow mixed tabs and spaces in the same line (file?) any more.
root@system:/home/ddns# python3 /usr/bin/ddns -d -c /etc/ddns/ddns.conf.sample list-providers Debugmodus eingeschaltet Laufe auf Distribution: unknown Lade Konfigurationsdatei /etc/ddns/ddns.conf.sample
The output should look like this:
root@system:/home/ddns# python2 /usr/bin/ddns -d -c /etc/ddns/ddns.conf.sample list-providers Debugmodus eingeschaltet Registered new provider: All-inkl.com (all-inkl.com) Registered new provider: ChangeIP.com (changeip.com) Registered new provider: DDNSS (ddnss.de) Registered new provider: desec.io (desec.io) Registered new provider: DHS International (dhs.org) Registered new provider: Lightning Wire Labs DNS Service (dns.lightningwirelabs.com) Registered new provider: DNSmadeEasy.com (dnsmadeeasy.com) Registered new provider: DNS Park (dnspark.com) Registered new provider: Domain-Offensive (do.de) Registered new provider: Google Domains (domains.google.com) Registered new provider: domopoli.de (domopoli.de) Registered new provider: DtDNS (dtdns.com) Registered new provider: Duck DNS (duckdns.org) Registered new provider: dy.fi (dy.fi) Registered new provider: Dyn (dyndns.org) Registered new provider: DyNS (dyns.net) Registered new provider: Dynu (dynu.com) Registered new provider: DynUp.DE (dynup.de) Registered new provider: EasyDNS (easydns.com) Registered new provider: eNom Inc. (enom.com) Registered new provider: EntryDNS (entrydns.net) Registered new provider: freedns.afraid.org (freedns.afraid.org) Registered new provider: INWX (inwx.com) Registered new provider: it's DNS (itsdns.de) Registered new provider: Joker.com Dynamic DNS (joker.com) Registered new provider: Loopia AB (loopia.se) Registered new provider: myonlineportal.net (myonlineportal.net) Registered new provider: Namecheap (namecheap.com) Registered new provider: No-IP (no-ip.com) Registered new provider: NOW-DNS (now-dns.com) Registered new provider: BIND nsupdate utility (nsupdate) Registered new provider: nsupdate.info (nsupdate.info) Registered new provider: OpenDNS (opendns.com) Registered new provider: OVH (ovh.com) Registered new provider: Regfish GmbH (regfish.com) Registered new provider: Schokokeks (schokokeks.org) Registered new provider: Selfhost.de (selfhost.de) Registered new provider: servercow.de (servercow.de) Registered new provider: SPDYN (spdns.org) Registered new provider: Strato AG (strato.com) Registered new provider: TwoDNS (twodns.de) Registered new provider: Udmedia GmbH (udmedia.de) Registered new provider: Variomedia (variomedia.de) Registered new provider: XLhost (xlhost.de) Registered new provider: Zoneedit (zoneedit.com) Registered new provider: zzzz (zzzz.io) Laufe auf Distribution: unknown Lade Konfigurationsdatei /etc/ddns/ddns.conf.sample all-inkl.com changeip.com ddnss.de desec.io dhs.org dns.lightningwirelabs.com dnsmadeeasy.com dnspark.com do.de domains.google.com domopoli.de dtdns.com duckdns.org dy.fi dyndns.org dyns.net dynu.com dynup.de easydns.com enom.com entrydns.net freedns.afraid.org inwx.com itsdns.de joker.com loopia.se myonlineportal.net namecheap.com no-ip.com now-dns.com nsupdate nsupdate.info opendns.com ovh.com regfish.com schokokeks.org selfhost.de servercow.de spdns.org strato.com twodns.de udmedia.de variomedia.de xlhost.de zoneedit.com zzzz.io
Please check your Patch and re-submit a fixed version.
Many thanks in advance,
-Stefan
Hi together,
Fixed the things Michael mentioned. Update of the headers and .gitignore will follow in a separate patch if we decide it is necessary.
I corrected additionally some intentions and adapted some PEP8 style guidelines
Greetings Kim
Index: src/ddns/system.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
--- src/ddns/system.py (revision c0277eeea2b2c1ed8f40f1248b28438e44e51912) +++ src/ddns/system.py (date 1577472902318) @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 #################################################################### ########### # # # ddns - A dynamic DNS client for IPFire # @@ -23,18 +23,20 @@ import re import ssl import socket -import urllib -import urllib2 +import urllib.request +import urllib.parse +import urllib.error
-from __version__ import CLIENT_VERSION +from .__version__ import CLIENT_VERSION from .errors import * -from i18n import _ +from .i18n import _
# Initialize the logger. import logging logger = logging.getLogger("ddns.system") logger.propagate = 1
class DDNSSystem(object): """ The DDNSSystem class adds a layer of abstraction @@ -79,7 +81,7 @@ with open("/var/ipfire/red/local- ipaddress") as f: return f.readline()
except IOError, e:
except IOError as e: # File not found if e.errno == 2: return
@@ -137,7 +139,7 @@ if data: logger.debug(" data: %s" % data)
req = urllib2.Request(url, data=data)
req = urllib.request.Request(url, data=data)
if username and password: basic_auth_header =
self._make_basic_auth_header(username, password) @@ -163,7 +165,7 @@ logger.debug(" %s: %s" % (k, v))
try:
resp = urllib2.urlopen(req, timeout=timeout)
resp = urllib.request.urlopen(req,
timeout=timeout)
# Log response header. logger.debug(_("Response header (Status Code
%s):") % resp.code) @@ -173,7 +175,7 @@ # Return the entire response object. return resp
except urllib2.HTTPError, e:
except urllib.error.HTTPError as e: # Log response header. logger.debug(_("Response header (Status Code
%s):") % e.code) for k, v in e.hdrs.items(): @@ -209,7 +211,7 @@ # Raise all other unhandled exceptions. raise
except urllib2.URLError, e:
except urllib.error.URLError as e: if e.reason: # Handle SSL errors if isinstance(e.reason, ssl.SSLError):
@@ -240,7 +242,7 @@ # Raise all other unhandled exceptions. raise
except socket.timeout, e:
except socket.timeout as e: logger.debug(_("Connection timeout")) raise DDNSConnectionTimeoutError
@@ -249,7 +251,7 @@ args = []
for k, v in data.items():
arg = "%s=%s" % (k, urllib.quote(v))
arg = "%s=%s" % (k, urllib.parse.quote(v)) args.append(arg)
return "&".join(args)
@@ -258,7 +260,7 @@ authstring = "%s:%s" % (username, password)
# Encode authorization data in base64.
authstring = base64.encodestring(authstring)
authstring = base64.encodebytes(authstring)
# Remove any newline characters. authstring = authstring.replace("\n", "")
@@ -354,7 +356,7 @@ # Resolve the host address. try: response = socket.getaddrinfo(hostname, None, family)
except socket.gaierror, e:
except socket.gaierror as e: # Name or service not known if e.errno == -2: return []
@@ -388,7 +390,7 @@ continue
# Add to repsonse list if not already in there.
if not address in addresses:
if address not in addresses: addresses.append(address)
return addresses
@@ -418,7 +420,7 @@ """ try: f = open("/etc/os-release", "r")
except IOError, e:
except IOError as e: # File not found if e.errno == 2: return
@@ -447,7 +449,7 @@ """ try: f = open("/etc/system-release", "r")
except IOError, e:
except IOError as e: # File not found if e.errno == 2: return
Index: src/ddns/i18n.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
--- src/ddns/i18n.py (revision c0277eeea2b2c1ed8f40f1248b28438e44e51912) +++ src/ddns/i18n.py (date 1577472902317) @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 #################################################################### ########### # # # ddns - A dynamic DNS client for IPFire # @@ -25,15 +25,14 @@
N_ = lambda x: x
def _(singular, plural=None, n=None): """ A function that returnes the translation of a string if available.
- The language is taken from the system environment.
"""
- if not plural is None:
- """
- if plural is not None: assert n is not None return gettext.dngettext(TEXTDOMAIN, singular, plural,
n)
return gettext.dgettext(TEXTDOMAIN, singular)
Index: configure.ac IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
--- configure.ac (revision c0277eeea2b2c1ed8f40f1248b28438e44e51912) +++ configure.ac (date 1577473544755) @@ -21,7 +21,7 @@ AC_PREREQ([2.64])
AC_INIT([ddns],
- [012],
- [013], [info@ipfire.org], [ddns], [http://git.ipfire.org/?p=oddments/ddns.git;a=summary])
@@ -54,7 +54,7 @@ AC_PATH_PROG([XSLTPROC], [xsltproc])
# Python -AM_PATH_PYTHON([2.7]) +AM_PATH_PYTHON([3.6])
save_LIBS="$LIBS"
Index: ddns.in IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
--- ddns.in (revision c0277eeea2b2c1ed8f40f1248b28438e44e51912) +++ ddns.in (date 1577472902316) @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 #################################################################### ########### # # # ddns - A dynamic DNS client for IPFire # @@ -27,27 +27,24 @@
CONFIGURATION_FILE = "@configsdir@/ddns.conf"
def main(): # Parse command line p = argparse.ArgumentParser(description=_("Dynamic DNS Updater"))
- p.add_argument("-d", "--debug", action="store_true",
help=_("Enable debugging output"))
- p.add_argument("-d", "--debug", action="store_true",
help=_("Enable debugging output"))
p.add_argument("-c", "--config", default=CONFIGURATION_FILE, help=_("Load configuration file (Default: %s)") % CONFIGURATION_FILE)
# Create subparsers for commands.
- subparsers = p.add_subparsers(help=_("Sub-command help"),
dest="subparsers_name")
- subparsers = p.add_subparsers(help=_("Sub-command help"),
dest="subparsers_name")
# guess-ip-addresses
- p_guess_ip_addresses = subparsers.add_parser("guess-ip-
addresses",
help=_("Guess the external IP addresses"))
- p_guess_ip_addresses = subparsers.add_parser("guess-ip-
addresses", help=_("Guess the external IP addresses"))
# list-providers
- p_list_providers = subparsers.add_parser("list-providers",
help=_("List all available providers"))
- p_list_providers = subparsers.add_parser("list-providers",
help=_("List all available providers"))
# update p_update = subparsers.add_parser("update", help=_("Update DNS record")) @@ -74,16 +71,16 @@ # IPv6 ipv6_address = d.system.guess_external_ip_address("ipv6") if ipv6_address:
print _("IPv6 Address: %s") % ipv6_address
print("IPv6 Address: %s" % ipv6_address)
# IPv4 ipv4_address =
d.system.guess_external_ip_address("ipv4") if ipv4_address:
print _("IPv4 Address: %s") % ipv4_address
print("IPv4 Address: %s" % ipv4_address)
elif args.subparsers_name == "list-providers": provider_names = d.get_provider_names()
print "\n".join(provider_names)
print("\n".join(provider_names))
elif args.subparsers_name == "update": d.updateone(hostname=args.hostname, force=args.force)
@@ -94,4 +91,5 @@ else: raise RuntimeError("Unhandled command: %s" % args.subparsers_name)
main() Index: src/ddns/database.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
--- src/ddns/database.py (revision c0277eeea2b2c1ed8f40f1248b28438e44e51912) +++ src/ddns/database.py (date 1577472902317) @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 #################################################################### ########### # # # ddns - A dynamic DNS client for IPFire # @@ -28,6 +28,7 @@ logger = logging.getLogger("ddns.database") logger.propagate = 1
class DDNSDatabase(object): def __init__(self, core, path): self.core = core @@ -82,6 +83,7 @@
def _close_database(self): if self._db:
# TODO: Check Unresolved attribute reference
'_db_close' for class 'DDNSDatabase' self._db_close() self._db = None
Index: src/ddns/providers.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
--- src/ddns/providers.py (revision c0277eeea2b2c1ed8f40f1248b28438e44e51912) +++ src/ddns/providers.py (date 1577472902318) @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 #################################################################### ########### # # # ddns - A dynamic DNS client for IPFire # @@ -23,10 +23,12 @@ import logging import os import subprocess -import urllib2 +import urllib.request +import urllib.error +import urllib.parse import xml.dom.minidom
-from i18n import _ +from .i18n import _
# Import all possible exception types. from .errors import * @@ -36,12 +38,14 @@
_providers = {}
def get(): """ Returns a dict with all automatically registered providers. """ return _providers.copy()
class DDNSProvider(object): # A short string that uniquely identifies # this provider. @@ -84,7 +88,7 @@ if not all((provider.handle, provider.name, provider.website)): raise DDNSError(_("Provider is not properly configured"))
assert not _providers.has_key(provider.handle),
\
assert provider.handle not in _providers, \ "Provider '%s' has already been
registered" % provider.handle
_providers[provider.handle] = provider
@@ -109,7 +113,7 @@ return "<DDNS Provider %s (%s)>" % (self.name, self.handle)
def __cmp__(self, other):
return cmp(self.hostname, other.hostname)
return (lambda a, b: (a > b)-(a < b))(self.hostname,
other.hostname)
@property def db(self): @@ -176,8 +180,8 @@ self.core.db.log_failure(self.hostname, e) raise
logger.info(_("Dynamic DNS update for %(hostname)s
(%(provider)s) successful") % \
{ "hostname" : self.hostname, "provider" :
self.name })
logger.info(_("Dynamic DNS update for %(hostname)s
(%(provider)s) successful") %
{"hostname": self.hostname,
"provider": self.name}) self.core.db.log_success(self.hostname)
def update(self): @@ -192,7 +196,7 @@
def remove_protocol(self, proto): if not self.can_remove_records:
raise RuntimeError, "can_remove_records is
enabled, but remove_protocol() not implemented"
raise RuntimeError("can_remove_records is
enabled, but remove_protocol() not implemented")
raise NotImplementedError
@@ -200,23 +204,21 @@ def requires_update(self): # If the IP addresses have changed, an update is required if self.ip_address_changed(self.protocols):
logger.debug(_("An update for %(hostname)s
(%(provider)s)"
" is performed because of an IP address
change") % \
{ "hostname" : self.hostname,
"provider" : self.name })
logger.debug(_("An update for %(hostname)s
(%(provider)s) is performed because of an IP address change") %
{"hostname": self.hostname, "provider":
self.name})
return True # If the holdoff time has expired, an update is
required, too if self.holdoff_time_expired():
logger.debug(_("An update for %(hostname)s
(%(provider)s)"
" is performed because the holdoff time
has expired") % \
{ "hostname" : self.hostname,
"provider" : self.name })
logger.debug(_("An update for %(hostname)s
(%(provider)s) is performed because the holdoff time has expired") %
{"hostname":
self.hostname, "provider": self.name})
return True # Otherwise, we don't need to perform an update
logger.debug(_("No update required for %(hostname)s
(%(provider)s)") % \
{ "hostname" : self.hostname, "provider" :
self.name })
logger.debug(_("No update required for %(hostname)s
(%(provider)s)") %
{"hostname": self.hostname,
"provider": self.name})
return False
@@ -234,8 +236,7 @@
# If there is no holdoff time, we won't update ever
again. if self.holdoff_failure_days is None:
logger.warning(_("An update has not been
performed because earlier updates failed for %s") \
% self.hostname)
logger.warning(_("An update has not been
performed because earlier updates failed for %s") % self.hostname) logger.warning(_("There will be no retries"))
return True
@@ -248,8 +249,7 @@ if now < holdoff_end: failure_message = self.db.last_update_failure_message(self.hostname)
logger.warning(_("An update has not been
performed because earlier updates failed for %s") \
% self.hostname)
logger.warning(_("An update has not been
performed because earlier updates failed for %s") % self.hostname)
if failure_message: logger.warning(_("Last failure
message:")) @@ -315,8 +315,8 @@ logger.debug("The holdoff time has expired for %s" % self.hostname) return True else:
logger.debug("Updates for %s are held off until
%s" % \
(self.hostname, holdoff_end))
logger.debug("Updates for %s are held off until
%s" %
(self.hostname,
holdoff_end)) return False
def send_request(self, *args, **kwargs): @@ -362,8 +362,8 @@
def prepare_request_data(self, proto): data = {
"hostname" : self.hostname,
"myip" : self.get_address(proto),
"hostname": self.hostname,
"myip": self.get_address(proto),
}
return data
@@ -375,8 +375,7 @@
def send_request(self, data): # Send update to the server.
response = DDNSProvider.send_request(self, self.url,
data=data,
username=self.username, password=self.password)
response = DDNSProvider.send_request(self, self.url,
data=data, username=self.username, password=self.password)
# Get the full response message. output = response.read()
@@ -413,7 +412,7 @@ will be sent by various providers. This class uses the python shipped XML minidom module to walk through the XML tree and return a requested element.
"""
"""
def get_xml_tag_value(self, document, content): # Send input to the parser.
@@ -494,9 +493,7 @@ # -t sets the timeout command = ["nsupdate", "-v", "-t", "60"]
p = subprocess.Popen(command, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
p = subprocess.Popen(command, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate(scriptlet)
if p.returncode == 0:
@@ -533,7 +530,7 @@
scriptlet.append("update delete %s. %s" %
(self.hostname, rrtype)) scriptlet.append("update add %s. %s %s %s" % \
(self.hostname, ttl, rrtype, address))
(self.hostname
, ttl, rrtype, address))
# Send the actions to the server. scriptlet.append("send")
@@ -570,11 +567,10 @@
# Send update to the server. try:
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Handle error codes.
except urllib2.HTTPError, e:
except urllib.error.HTTPError as e: if e.code == 422: raise DDNSRequestError(_("Domain not
found."))
@@ -585,7 +581,7 @@ return
# If we got here, some other update error happened.
raise DDNSUpdateError(_("Server response: %s") %
output)
raise DDNSUpdateError(_("Server response: %s") %
response)
class DDNSProviderDesecIO(DDNSProtocolDynDNS2, DDNSProvider): @@ -631,8 +627,8 @@
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"host" : self.hostname,
"ip": self.get_address(proto),
"host": self.hostname,
}
# Check if a token has been set.
@@ -642,8 +638,8 @@ # Check if username and hostname are given. elif self.username and self.password: data.update({
"user" : self.username,
"pwd" : self.password,
"user": self.username,
"pwd": self.password, })
# Raise an error if no auth details are given.
@@ -695,16 +691,15 @@
def update_protocol(self, proto): data = {
"domain" : self.hostname,
"ip" : self.get_address(proto),
"hostcmd" : "edit",
"hostcmdstage" : "2",
"type" : "4",
"domain": self.hostname,
"ip": self.get_address(proto),
"hostcmd": "edit",
"hostcmdstage": "2",
"type": "4",
}
# Send update to the server.
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Handle success messages. if response.code == 200:
@@ -728,13 +723,12 @@
def update_protocol(self, proto): data = {
"domain" : self.hostname,
"ip" : self.get_address(proto),
"domain": self.hostname,
"ip": self.get_address(proto),
}
# Send update to the server.
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Get the full response message. output = response.read()
@@ -777,9 +771,9 @@
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"id" : self.hostname,
"pw" : self.password
"ip": self.get_address(proto),
"id": self.hostname,
"pw": self.password
}
# Send update to the server.
@@ -873,6 +867,7 @@
url = "https://ddns.do.de/"
class DDNSProviderDynUp(DDNSProvider): handle = "dynup.de" name = "DynUp.DE" @@ -887,10 +882,10 @@
def update_protocol(self, proto): data = {
"username" : self.username,
"password" : self.password,
"hostname" : self.hostname,
"print" : '1',
"username": self.username,
"password": self.password,
"hostname": self.hostname,
"print": '1',
}
# Send update to the server.
@@ -903,14 +898,13 @@ output = output.strip()
# Handle success messages.
if output.startswith("I:OK") :
if output.startswith("I:OK"): return
# If we got here, some other update error happened. raise DDNSUpdateError
class DDNSProviderDynU(DDNSProtocolDynDNS2, DDNSProvider): handle = "dynu.com" name = "Dynu" @@ -952,13 +946,12 @@
def update_protocol(self, proto): data = {
"myip" : self.get_address(proto, "-"),
"hostname" : self.hostname,
"myip": self.get_address(proto, "-"),
"hostname": self.hostname,
}
# Send update to the server.
response = self.send_request(self.url, data=data,
username=self.username, password=self.password)
response = self.send_request(self.url, data=data,
username=self.username, password=self.password)
# Get the full response message. output = response.read()
@@ -1058,11 +1051,11 @@
def update_protocol(self, proto): data = {
"command" : "setdnshost",
"responsetype" : "xml",
"address" : self.get_address(proto),
"domainpassword" : self.password,
"zone" : self.hostname
"command": "setdnshost",
"responsetype": "xml",
"address": self.get_address(proto),
"domainpassword": self.password,
"zone": self.hostname
}
# Send update to the server.
@@ -1100,7 +1093,7 @@
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"ip": self.get_address(proto),
}
# Add auth token to the update url.
@@ -1111,7 +1104,7 @@ response = self.send_request(url, data=data)
# Handle error codes
except urllib2.HTTPError, e:
except urllib.error.HTTPError as e: if e.code == 404: raise DDNSAuthenticationError
@@ -1140,7 +1133,7 @@
def update_protocol(self, proto): data = {
"address" : self.get_address(proto),
"address": self.get_address(proto),
}
# Add auth token to the update url.
@@ -1167,53 +1160,53 @@
class DDNSProviderItsdns(DDNSProtocolDynDNS2, DDNSProvider):
handle = "inwx.com"
name = "INWX"
website = "https://www.inwx.com"
protocols = ("ipv6", "ipv4")
- handle = "inwx.com"
- name = "INWX"
- website = "https://www.inwx.com"
- protocols = ("ipv6", "ipv4")
# Information about the format of the HTTP request is
to be found
# here: https://www.inwx.com/en/nameserver2/dyndns
(requires login)
# Notice: The URL is the same for: inwx.com|de|at|ch|es
- # Information about the format of the HTTP request is to be
found
- # here: https://www.inwx.com/en/nameserver2/dyndns (requires
login)
- # Notice: The URL is the same for: inwx.com|de|at|ch|es
url = "https://dyndns.inwx.com/nic/update"
class DDNSProviderItsdns(DDNSProtocolDynDNS2, DDNSProvider):
handle = "itsdns.de"
name = "it's DNS"
website = "http://www.itsdns.de/"
protocols = ("ipv6", "ipv4")
- handle = "itsdns.de"
- name = "it's DNS"
- website = "http://www.itsdns.de/"
- protocols = ("ipv6", "ipv4")
# Information about the format of the HTTP request is
to be found
# here: https://www.itsdns.de/dynupdatehelp.htm
- # Information about the format of the HTTP request is to be
found
url = "https://www.itsdns.de/update.php"
- url = "https://www.itsdns.de/update.php"
class DDNSProviderJoker(DDNSProtocolDynDNS2, DDNSProvider):
handle = "joker.com"
name = "Joker.com Dynamic DNS"
website = "https://joker.com/"
protocols = ("ipv4",)
- handle = "joker.com"
- name = "Joker.com Dynamic DNS"
- website = "https://joker.com/"
- protocols = ("ipv4",)
# Information about the request can be found here:
#
https://joker.com/faq/content/11/427/en/what-is-dynamic-dns-dyndns.html
# Using DynDNS V2 protocol over HTTPS here
- # Information about the request can be found here:
- #
https://joker.com/faq/content/11/427/en/what-is-dynamic-dns-dyndns.html
- # Using DynDNS V2 protocol over HTTPS here
url = "https://svc.joker.com/nic/update"
- url = "https://svc.joker.com/nic/update"
class DDNSProviderGoogle(DDNSProtocolDynDNS2, DDNSProvider):
handle = "domains.google.com"
name = "Google Domains"
website = "https://domains.google.com/"
protocols = ("ipv4",)
- handle = "domains.google.com"
- name = "Google Domains"
- website = "https://domains.google.com/"
- protocols = ("ipv4",)
# Information about the format of the HTTP request is to be
found
# here:
https://support.google.com/domains/answer/6147083?hl=en
- # Information about the format of the HTTP request is to be
found
url = "https://domains.google.com/nic/update"
class DDNSProviderLightningWireLabs(DDNSProvider): @@ -1227,10 +1220,10 @@ url = "https://dns.lightningwirelabs.com/update"
def update(self):
data = {
"hostname" : self.hostname,
"address6" : self.get_address("ipv6", "-"),
"address4" : self.get_address("ipv4", "-"),
data = {
"hostname": self.hostname,
"address6": self.get_address("ipv6", "-"),
"address4": self.get_address("ipv4", "-"),
}
# Check if a token has been set.
@@ -1240,8 +1233,8 @@ # Check for username and password. elif self.username and self.password: data.update({
"username" : self.username,
"password" : self.password,
"username": self.username,
"password": self.password, })
# Raise an error if no auth details are given.
@@ -1283,8 +1276,8 @@
def prepare_request_data(self, proto): data = {
"hostname" : self.hostname,
"ip" : self.get_address(proto),
"hostname": self.hostname,
"ip": self.get_address(proto),
}
return data
@@ -1311,10 +1304,10 @@ address = self.get_address(proto)
data = {
"ip" : address,
"password" : self.password,
"host" : host,
"domain" : domain
"ip": address,
"password": self.password,
"host": host,
"domain": domain
}
# Send update to the server.
@@ -1359,8 +1352,8 @@ assert proto == "ipv4"
data = {
"hostname" : self.hostname,
"address" : self.get_address(proto),
"hostname": self.hostname,
"address": self.get_address(proto),
}
return data
@@ -1411,7 +1404,7 @@
def prepare_request_data(self, proto): data = {
"myip" : self.get_address(proto),
"myip": self.get_address(proto),
}
return data
@@ -1430,8 +1423,8 @@
def prepare_request_data(self, proto): data = {
"hostname" : self.hostname,
"myip" : self.get_address(proto),
"hostname": self.hostname,
"myip": self.get_address(proto),
}
return data
@@ -1454,7 +1447,7 @@ def prepare_request_data(self, proto): data = DDNSProtocolDynDNS2.prepare_request_data(self, proto) data.update({
"system" : "dyndns",
"system": "dyndns",
})
return data
@@ -1474,7 +1467,7 @@
def update(self): data = {
"fqdn" : self.hostname,
"fqdn": self.hostname,
}
# Check if we update an IPv6 address.
@@ -1488,7 +1481,7 @@ data["ipv4"] = address4
# Raise an error if none address is given.
if not data.has_key("ipv6") and not
data.has_key("ipv4"):
if "ipv6" not in data and "ipv4" not in data: raise DDNSConfigurationError
# Check if a token has been set.
@@ -1506,8 +1499,7 @@ response = self.send_request(self.url, data=data) else: # Send update to the server.
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Get the full response message. output = response.read()
@@ -1554,7 +1546,7 @@ def prepare_request_data(self, proto): data = DDNSProtocolDynDNS2.prepare_request_data(self, proto) data.update({
"hostname" : "1",
"hostname": "1",
})
return data
@@ -1571,10 +1563,10 @@
def update_protocol(self, proto): data = {
"ipaddr" : self.get_address(proto),
"hostname" : self.hostname,
"username" : self.username,
"pass" : self.password,
"ipaddr": self.get_address(proto),
"hostname": self.hostname,
"username": self.username,
"pass": self.password,
}
# Send request to provider
@@ -1632,8 +1624,8 @@ def prepare_request_data(self, proto): data = DDNSProtocolDynDNS2.prepare_request_data(self, proto) data.update({
"mx" : "NOCHG",
"backupmx" : "NOCHG"
"mx": "NOCHG",
"backupmx": "NOCHG"
})
return data
@@ -1655,8 +1647,8 @@ assert proto == "ipv4"
data = {
"ip" : self.get_address(proto),
"hostname" : self.hostname
"ip": self.get_address(proto),
"hostname": self.hostname
}
return data
@@ -1687,23 +1679,23 @@
def prepare_request_data(self, proto): data = {
"hostname" : self.hostname,
"myip" : self.get_address(proto),
"hostname": self.hostname,
"myip": self.get_address(proto),
}
return data
class DDNSProviderXLhost(DDNSProtocolDynDNS2, DDNSProvider):
handle = "xlhost.de"
name = "XLhost"
website = "http://xlhost.de/"
protocols = ("ipv4",)
- handle = "xlhost.de"
- name = "XLhost"
- website = "http://xlhost.de/"
- protocols = ("ipv4",)
# Information about the format of the HTTP request is to be
found
# here:
https://xlhost.de/faq/index_html?topicId=CQA2ELIPO4SQ
- # Information about the format of the HTTP request is to be
found
url = "https://nsupdate.xlhost.de/"
- url = "https://nsupdate.xlhost.de/"
class DDNSProviderZoneedit(DDNSProvider): @@ -1721,13 +1713,12 @@
def update_protocol(self, proto): data = {
"dnsto" : self.get_address(proto),
"host" : self.hostname
"dnsto": self.get_address(proto),
"host": self.hostname
}
# Send update to the server.
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Get the full response message. output = response.read()
@@ -1763,10 +1754,10 @@
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"id" : self.hostname,
"username" : self.username,
"password" : self.password,
"ip": self.get_address(proto),
"id": self.hostname,
"username": self.username,
"password": self.password,
}
# Send update to the server.
@@ -1813,8 +1804,8 @@
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"token" : self.token,
"ip": self.get_address(proto),
"token": self.token,
}
if proto == "ipv6":
Index: src/ddns/__init__.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
--- src/ddns/__init__.py (revision c0277eeea2b2c1ed8f40f1248b28438e44e51912) +++ src/ddns/__init__.py (date 1577472902316) @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 #################################################################### ########### # # # ddns - A dynamic DNS client for IPFire # @@ -21,19 +21,20 @@
import logging import logging.handlers -import ConfigParser +import configparser
-from i18n import _ +from .i18n import _
logger = logging.getLogger("ddns.core") logger.propagate = 1
-import database -import providers +from . import database +from . import providers
from .errors import * from .system import DDNSSystem
# Setup the logger. def setup_logging(): rootlogger = logging.getLogger("ddns") @@ -51,8 +52,10 @@ handler = logging.StreamHandler() rootlogger.addHandler(handler)
setup_logging()
class DDNSCore(object): def __init__(self, debug=False): # In debug mode, enable debug logging. @@ -89,7 +92,7 @@ def load_configuration(self, filename): logger.debug(_("Loading configuration file %s") % filename)
configs = ConfigParser.RawConfigParser()
configs = configparser.RawConfigParser()
configs.read([filename,])
# First apply all global configuration settings.
@@ -98,7 +101,7 @@ self.settings[k] = v
# Allow missing config section
except ConfigParser.NoSectionError:
except configparser.NoSectionError: pass
for entry in configs.sections():
@@ -127,7 +130,7 @@ # Check if the provider is actually supported and if there are # some dependencies missing on this system. if not provider.supported():
logger.warning("Provider '%s' is known,
but not supported on this machine" % (provider.name))
logger.warning("Provider '%s' is known,
but not supported on this machine" % provider.name) continue
# Create an instance of the provider object
with settings from the @@ -163,13 +166,13 @@ try: entry(force=force)
except DDNSError, e:
logger.error(_("Dynamic DNS update for
%(hostname)s (%(provider)s) failed:") % \
{ "hostname" : entry.hostname,
"provider" : entry.name })
except DDNSError as e:
logger.error(_("Dynamic DNS update for
%(hostname)s (%(provider)s) failed:") %
{"hostname": entry.hostname,
"provider": entry.name}) logger.error(" %s: %s" % (e.__class__.__name__, e.reason)) if e.message: logger.error(" %s" % e.message)
except Exception, e:
logger.error(_("Dynamic DNS update for
%(hostname)s (%(provider)s) throwed an unhandled exception:") % \
{ "hostname" : entry.hostname,
"provider" : entry.name }, exc_info=True)
except Exception:
logger.error(_("Dynamic DNS update for
%(hostname)s (%(provider)s) threw an unhandled exception:") %
{"hostname":
entry.hostname, "provider": entry.name}, exc_info=True) Index: src/ddns/errors.py IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
--- src/ddns/errors.py (revision c0277eeea2b2c1ed8f40f1248b28438e44e51912) +++ src/ddns/errors.py (date 1577472902317) @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 #################################################################### ########### # # # ddns - A dynamic DNS client for IPFire # @@ -21,6 +21,7 @@
N_ = lambda x: x
class DDNSError(Exception): """ Generic error class for all exceptions
Am 25.12.2019 um 16:52 schrieb Michael Tremer < michael.tremer@ipfire.org>:
Hi,
Thanks for working on this.
There are some issues with this patch.
First of all, the formatting is off and all leading spaces have been stripped.
On 25 Dec 2019, at 16:39, Kim kbarthel@ipfire.org wrote:
.gitignore | 1 + Makefile.am | 2 +- configure.ac | 6 +- ddns.in | 30 ++- src/ddns/__init__.py | 33 +-- src/ddns/database.py | 5 +- src/ddns/errors.py | 5 +- src/ddns/i18n.py | 11 +- src/ddns/providers.py | 545 +++++++++++++++++++++----------------
src/ddns/system.py | 44 ++-- 10 files changed, 339 insertions(+), 343 deletions(-)
diff --git a/.gitignore b/.gitignore index cd5023c..df7e7eb 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ intltool-extract.in intltool-merge.in intltool-update.in stamp-* +.idea
What does this have to do with the Python port?
diff --git a/Makefile.am b/Makefile.am index fc119b8..d36f880 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ ################################################################### ############ #
#
# Pakfire - The IPFire package management system # -# Copyright (C) 2013 Pakfire development team # +# Copyright (C) 2013-2019 Pakfire development team #
Pakfire?
#
#
# This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # diff --git a/configure.ac b/configure.ac index 14bccc0..320de10 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ ################################################################### ############ #
#
# Pakfire - The IPFire package management system # -# Copyright (C) 2013 Pakfire development team # +# Copyright (C) 2013-2019 Pakfire development team # #
#
# This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -21,7 +21,7 @@ AC_PREREQ([2.64])
AC_INIT([ddns],
- [012],
- [013], [info@ipfire.org], [ddns], [http://git.ipfire.org/?p=oddments/ddns.git;a=summary])
You do not need to tag a new release.
@@ -54,7 +54,7 @@ AC_PROG_SED AC_PATH_PROG([XSLTPROC], [xsltproc])
# Python -AM_PATH_PYTHON([2.7]) +AM_PATH_PYTHON([3])
Are you sure this will run with Python 3.0, 3.2, etc.?
I suppose it is safe to have 3.6 or even 3.8 here.
save_LIBS="$LIBS"
diff --git a/ddns.in b/ddns.in index 1ca5f83..9bb267a 100644 --- a/ddns.in +++ b/ddns.in @@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python3 ################################################################### ############ #
#
# ddns - A dynamic DNS client for IPFire # -# Copyright (C) 2012 IPFire development team # +# Copyright (C) 2012-2019 IPFire development team #
See above.
#
#
# This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -27,38 +27,35 @@ from ddns.i18n import _
CONFIGURATION_FILE = "@configsdir@/ddns.conf"
def main(): # Parse command line p = argparse.ArgumentParser(description=_("Dynamic DNS Updater"))
- p.add_argument("-d", "--debug", action="store_true",
help=_("Enable debugging output"))
- p.add_argument("-d", "--debug", action="store_true",
help=_("Enable debugging output"))
p.add_argument("-c", "--config", default=CONFIGURATION_FILE,
help=_("Load configuration file (Default: %s)") %
CONFIGURATION_FILE)
help=_("Load configuration file (Default: %s)")
% CONFIGURATION_FILE)
# Create subparsers for commands.
- subparsers = p.add_subparsers(help=_("Sub-command help"),
dest="subparsers_name")
- subparsers = p.add_subparsers(help=_("Sub-command help"),
dest="subparsers_name")
# guess-ip-addresses
- p_guess_ip_addresses = subparsers.add_parser("guess-ip-
addresses",
help=_("Guess the external IP addresses"))
- p_guess_ip_addresses = subparsers.add_parser("guess-ip-
addresses", help=_("Guess the external IP addresses"))
# list-providers
- p_list_providers = subparsers.add_parser("list-providers",
help=_("List all available providers"))
- p_list_providers = subparsers.add_parser("list-providers",
help=_("List all available providers"))
# update p_update = subparsers.add_parser("update", help=_("Update DNS record")) p_update.add_argument("hostname") p_update.add_argument("--force", action="store_true",
help=_("Execute update even if the record is already up
to date"))
help=_("Execute update even if the record
is already up to date"))
You have changed indentation here. Is there any need for it?
This doesn’t change the code, but further down, there is a lot of noise in the patch and I do not know why.
# update-all p_update_all = subparsers.add_parser("update-all", help=_("Update all DNS records")) p_update_all.add_argument("--force", action="store_true",
help=_("Execute update even if the record is already up
to date"))
help=_("Execute update even if the
record is already up to date"))
args = p.parse_args()
@@ -74,16 +71,16 @@ def main(): # IPv6 ipv6_address = d.system.guess_external_ip_address("ipv6") if ipv6_address:
print _("IPv6 Address: %s") % ipv6_address
print("IPv6 Address: %s" % ipv6_address)
You are removing the translation here.
# IPv4 ipv4_address =
d.system.guess_external_ip_address("ipv4") if ipv4_address:
print _("IPv4 Address: %s") % ipv4_address
print("IPv4 Address: %s" % ipv4_address)
Likewise.
elif args.subparsers_name == "list-providers": provider_names = d.get_provider_names()
print "\n".join(provider_names)
print("\n".join(provider_names))
elif args.subparsers_name == "update": d.updateone(hostname=args.hostname, force=args.force)
@@ -94,4 +91,5 @@ def main(): else: raise RuntimeError("Unhandled command: %s" % args.subparsers_name)
We only have one empty line after functions and two after classes.
main() diff --git a/src/ddns/__init__.py b/src/ddns/__init__.py index 7f2729c..4fffcf7 100644 --- a/src/ddns/__init__.py +++ b/src/ddns/__init__.py @@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python3 ################################################################### ############ #
#
# ddns - A dynamic DNS client for IPFire # -# Copyright (C) 2012 IPFire development team # +# Copyright (C) 2012-2019 IPFire development team # #
#
# This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -21,19 +21,20 @@
import logging import logging.handlers -import ConfigParser +import configparser
-from i18n import _ +from .i18n import _
logger = logging.getLogger("ddns.core") logger.propagate = 1
-import database -import providers +from . import database +from . import providers
from .errors import * from .system import DDNSSystem
Another blank line.
# Setup the logger. def setup_logging(): rootlogger = logging.getLogger("ddns") @@ -51,8 +52,10 @@ def setup_logging(): handler = logging.StreamHandler() rootlogger.addHandler(handler)
setup_logging()
And here again.
And again.
class DDNSCore(object): def __init__(self, debug=False): # In debug mode, enable debug logging. @@ -89,7 +92,7 @@ class DDNSCore(object): def load_configuration(self, filename): logger.debug(_("Loading configuration file %s") % filename)
configs = ConfigParser.RawConfigParser()
configs = configparser.RawConfigParser()
configs.read([filename,])
# First apply all global configuration settings.
@@ -98,7 +101,7 @@ class DDNSCore(object): self.settings[k] = v
# Allow missing config section
except ConfigParser.NoSectionError:
except configparser.NoSectionError: pass
for entry in configs.sections():
@@ -127,7 +130,7 @@ class DDNSCore(object): # Check if the provider is actually supported and if there are # some dependencies missing on this system. if not provider.supported():
logger.warning("Provider '%s' is known,
but not supported on this machine" % (provider.name))
logger.warning("Provider '%s' is known,
but not supported on this machine" % provider.name) continue
# Create an instance of the provider object
with settings from the @@ -163,13 +166,13 @@ class DDNSCore(object): try: entry(force=force)
except DDNSError, e:
logger.error(_("Dynamic DNS update for
%(hostname)s (%(provider)s) failed:") % \
{ "hostname" : entry.hostname,
"provider" : entry.name })
except DDNSError as e:
logger.error(_("Dynamic DNS update for
%(hostname)s (%(provider)s) failed:") %
{"hostname": entry.hostname,
"provider": entry.name})
You are removing spaces here for no reason.
logger.error(" %s: %s" %
(e.__class__.__name__, e.reason)) if e.message: logger.error(" %s" % e.message)
except Exception, e:
logger.error(_("Dynamic DNS update for
%(hostname)s (%(provider)s) throwed an unhandled exception:") % \
{ "hostname" : entry.hostname,
"provider" : entry.name }, exc_info=True)
except Exception:
logger.error(_("Dynamic DNS update for
%(hostname)s (%(provider)s) threw an unhandled exception:") %
{"hostname":
entry.hostname, "provider": entry.name}, exc_info=True)
See above.
diff --git a/src/ddns/database.py b/src/ddns/database.py index 70a7363..45c445f 100644 --- a/src/ddns/database.py +++ b/src/ddns/database.py @@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python3 ################################################################### ############ #
#
# ddns - A dynamic DNS client for IPFire # -# Copyright (C) 2014 IPFire development team # +# Copyright (C) 2012-2019 IPFire development team # #
#
# This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -82,6 +82,7 @@ class DDNSDatabase(object):
def _close_database(self): if self._db:
# TODO: Check Unresolved attribute reference
'_db_close' for class 'DDNSDatabase' self._db_close() self._db = None
What does this mean?
Does that mean this patch isn’t ready for production?
diff --git a/src/ddns/errors.py b/src/ddns/errors.py index a8a2017..128d20d 100644 --- a/src/ddns/errors.py +++ b/src/ddns/errors.py @@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python3 ################################################################### ############ #
#
# ddns - A dynamic DNS client for IPFire # -# Copyright (C) 2012-2017 IPFire development team # +# Copyright (C) 2012-2019 IPFire development team # #
#
# This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -21,6 +21,7 @@
N_ = lambda x: x
Blank line again.
class DDNSError(Exception): """ Generic error class for all exceptions diff --git a/src/ddns/i18n.py b/src/ddns/i18n.py index 170414d..b71f7dc 100644 --- a/src/ddns/i18n.py +++ b/src/ddns/i18n.py @@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python3 ################################################################### ############ #
#
# ddns - A dynamic DNS client for IPFire # -# Copyright (C) 2012 IPFire development team # +# Copyright (C) 2012-2019 IPFire development team # #
#
# This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -25,15 +25,14 @@ TEXTDOMAIN = "ddns"
N_ = lambda x: x
Blank line.
def _(singular, plural=None, n=None): """ A function that returnes the translation of a string if available.
- The language is taken from the system environment.
"""
- if not plural is None:
- """
- if plural is not None: assert n is not None return gettext.dngettext(TEXTDOMAIN, singular, plural,
n)
return gettext.dgettext(TEXTDOMAIN, singular)
diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 661fbcc..b4a27a1 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python3 ################################################################### ############ #
#
# ddns - A dynamic DNS client for IPFire # -# Copyright (C) 2012-2017 IPFire development team # +# Copyright (C) 2012-2019 IPFire development team # #
#
# This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -23,10 +23,10 @@ import datetime import logging import os import subprocess -import urllib2 +import urllib.request, urllib.error, urllib.parse import xml.dom.minidom
-from i18n import _ +from .i18n import _
# Import all possible exception types. from .errors import * @@ -36,12 +36,14 @@ logger.propagate = 1
_providers = {}
I will stop commenting on the blank lines now, but there is many many more.
def get(): """ Returns a dict with all automatically registered providers. """ return _providers.copy()
class DDNSProvider(object): # A short string that uniquely identifies # this provider. @@ -84,7 +86,7 @@ class DDNSProvider(object): if not all((provider.handle, provider.name, provider.website)): raise DDNSError(_("Provider is not properly configured"))
assert not _providers.has_key(provider.handle),
\
assert provider.handle not in _providers, \ "Provider '%s' has already been
registered" % provider.handle
_providers[provider.handle] = provider
@@ -109,7 +111,7 @@ class DDNSProvider(object): return "<DDNS Provider %s (%s)>" % (self.name, self.handle)
def __cmp__(self, other):
return cmp(self.hostname, other.hostname)
return (lambda a, b: (a > b)-(a < b))(self.hostname,
other.hostname)
__cmp__ should be replaced by __eq__ and __lt__ at least.
Those are straight forward comparisons of the hostname, and this lambda function is confusing and difficult to read.
@property def db(self): @@ -176,8 +178,8 @@ class DDNSProvider(object): self.core.db.log_failure(self.hostname, e) raise
logger.info(_("Dynamic DNS update for %(hostname)s
(%(provider)s) successful") % \
{ "hostname" : self.hostname, "provider" :
self.name })
logger.info(_("Dynamic DNS update for %(hostname)s
(%(provider)s) successful") %
{"hostname": self.hostname, "provider":
self.name})
Spaces.
self.core.db.log_success(self.hostname)
def update(self): @@ -192,7 +194,7 @@ class DDNSProvider(object):
def remove_protocol(self, proto): if not self.can_remove_records:
raise RuntimeError, "can_remove_records is
enabled, but remove_protocol() not implemented"
raise RuntimeError("can_remove_records is
enabled, but remove_protocol() not implemented")
raise NotImplementedError
@@ -201,22 +203,22 @@ class DDNSProvider(object): # If the IP addresses have changed, an update is required if self.ip_address_changed(self.protocols): logger.debug(_("An update for %(hostname)s (%(provider)s)"
" is performed because of an IP address
change") % \
{ "hostname" : self.hostname,
"provider" : self.name })
" is performed because of an IP
address change") %
{"hostname": self.hostname,
"provider": self.name})
Spaces.
return True # If the holdoff time has expired, an update is
required, too if self.holdoff_time_expired(): logger.debug(_("An update for %(hostname)s (%(provider)s)"
" is performed because the holdoff time
has expired") % \
{ "hostname" : self.hostname,
"provider" : self.name })
" is performed because the
holdoff time has expired") %
{"hostname": self.hostname,
"provider": self.name})
Likewise.
return True # Otherwise, we don't need to perform an update
logger.debug(_("No update required for %(hostname)s
(%(provider)s)") % \
{ "hostname" : self.hostname, "provider" :
self.name })
logger.debug(_("No update required for %(hostname)s
(%(provider)s)") %
{"hostname": self.hostname, "provider":
self.name})
Likewise.
return False
@@ -234,8 +236,7 @@ class DDNSProvider(object):
# If there is no holdoff time, we won't update ever
again. if self.holdoff_failure_days is None:
logger.warning(_("An update has not been
performed because earlier updates failed for %s") \
% self.hostname)
logger.warning(_("An update has not been
performed because earlier updates failed for %s") % self.hostname) logger.warning(_("There will be no retries"))
There is a limit to the length of a line. It should be 80 characters and in difficult cases can be 120 characters.
This has been tried here before, but your patch removes it. Why?
return True
@@ -248,8 +249,7 @@ class DDNSProvider(object): if now < holdoff_end: failure_message = self.db.last_update_failure_message(self.hostname)
logger.warning(_("An update has not been
performed because earlier updates failed for %s") \
% self.hostname)
logger.warning(_("An update has not been
performed because earlier updates failed for %s") % self.hostname)
Likewise.
if failure_message: logger.warning(_("Last failure
message:")) @@ -315,8 +315,8 @@ class DDNSProvider(object): logger.debug("The holdoff time has expired for %s" % self.hostname) return True else:
logger.debug("Updates for %s are held off until
%s" % \
(self.hostname, holdoff_end))
logger.debug("Updates for %s are held off until
%s" %
(self.hostname, holdoff_end)) return False
def send_request(self, *args, **kwargs):
@@ -362,8 +362,8 @@ class DDNSProtocolDynDNS2(object):
def prepare_request_data(self, proto): data = {
"hostname" : self.hostname,
"myip" : self.get_address(proto),
"hostname": self.hostname,
}"myip": self.get_address(proto),
Why are those spaces removed here?
They make the patch very long and they actually do not change anything.
return data
@@ -375,8 +375,7 @@ class DDNSProtocolDynDNS2(object):
def send_request(self, data): # Send update to the server.
response = DDNSProvider.send_request(self, self.url,
data=data,
username=self.username, password=self.password)
response = DDNSProvider.send_request(self, self.url,
data=data, username=self.username, password=self.password)
Again, a line that got "unwrapped".
# Get the full response message. output = response.read()
@@ -413,7 +412,7 @@ class DDNSResponseParserXML(object): will be sent by various providers. This class uses the python shipped XML minidom module to walk through the XML tree and return a requested element.
"""
- """
This is allowed, because Python 3 will complain about the spaces.
def get_xml_tag_value(self, document, content): # Send input to the parser. @@ -437,9 +436,9 @@ class DDNSResponseParserXML(object):
class DDNSProviderAllInkl(DDNSProvider):
- handle = "all-inkl.com"
- name = "All-inkl.com"
- website = "http://all-inkl.com/"
- handle = "all-inkl.com"
- name = "All-inkl.com"
- website = "http://all-inkl.com/" protocols = ("ipv4",)
Spaces removed. Why? See above. And below...
# There are only information provided by the vendor how to @@ -467,8 +466,8 @@ class DDNSProviderAllInkl(DDNSProvider):
class DDNSProviderBindNsupdate(DDNSProvider):
- handle = "nsupdate"
- name = "BIND nsupdate utility"
handle = "nsupdate"
name = "BIND nsupdate utility" website = "http://en.wikipedia.org/wiki/Nsupdate"
DEFAULT_TTL = 60
@@ -494,9 +493,7 @@ class DDNSProviderBindNsupdate(DDNSProvider): # -t sets the timeout command = ["nsupdate", "-v", "-t", "60"]
p = subprocess.Popen(command, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
p = subprocess.Popen(command, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate(scriptlet)
More unwrapped lines.
if p.returncode == 0:
@@ -533,7 +530,7 @@ class DDNSProviderBindNsupdate(DDNSProvider):
scriptlet.append("update delete %s. %s" %
(self.hostname, rrtype)) scriptlet.append("update add %s. %s %s %s" % \
(self.hostname, ttl, rrtype, address))
(self.hostname, ttl, rrtype,
address))
# Send the actions to the server. scriptlet.append("send")
@@ -551,9 +548,9 @@ class DDNSProviderBindNsupdate(DDNSProvider):
class DDNSProviderChangeIP(DDNSProvider):
- handle = "changeip.com"
- name = "ChangeIP.com"
- website = "https://changeip.com"
handle = "changeip.com"
name = "ChangeIP.com"
website = "https://changeip.com" protocols = ("ipv4",)
# Detailed information about the update api can be found here.
@@ -564,17 +561,16 @@ class DDNSProviderChangeIP(DDNSProvider):
def update_protocol(self, proto): data = {
"hostname" : self.hostname,
"myip" : self.get_address(proto),
"hostname": self.hostname,
"myip": self.get_address(proto),
}
# Send update to the server. try:
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Handle error codes.
except urllib2.HTTPError, e:
except urllib.error.HTTPError as e: if e.code == 422: raise DDNSRequestError(_("Domain not
found."))
@@ -585,13 +581,13 @@ class DDNSProviderChangeIP(DDNSProvider): return
# If we got here, some other update error happened.
raise DDNSUpdateError(_("Server response: %s") %
output)
raise DDNSUpdateError(_("Server response: %s") %
response)
class DDNSProviderDesecIO(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "desec.io"
- name = "desec.io"
- website = "https://www.desec.io"
handle = "desec.io"
name = "desec.io"
website = "https://www.desec.io" protocols = ("ipv6", "ipv4",)
# ipv4 / ipv6 records are automatically removed when the update
@@ -616,9 +612,9 @@ class DDNSProviderDesecIO(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderDDNSS(DDNSProvider):
- handle = "ddnss.de"
- name = "DDNSS"
- website = "http://www.ddnss.de"
handle = "ddnss.de"
name = "DDNSS"
website = "http://www.ddnss.de" protocols = ("ipv4",)
# Detailed information about how to send the update request and
possible response @@ -631,8 +627,8 @@ class DDNSProviderDDNSS(DDNSProvider):
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"host" : self.hostname,
"ip": self.get_address(proto),
"host": self.hostname,
}
# Check if a token has been set.
@@ -642,8 +638,8 @@ class DDNSProviderDDNSS(DDNSProvider): # Check if username and hostname are given. elif self.username and self.password: data.update({
"user" : self.username,
"pwd" : self.password,
"user": self.username,
"pwd": self.password, })
# Raise an error if no auth details are given.
@@ -682,9 +678,9 @@ class DDNSProviderDDNSS(DDNSProvider):
class DDNSProviderDHS(DDNSProvider):
- handle = "dhs.org"
- name = "DHS International"
- website = "http://dhs.org/"
handle = "dhs.org"
name = "DHS International"
website = "http://dhs.org/" protocols = ("ipv4",)
# No information about the used update api provided on webpage,
@@ -695,16 +691,15 @@ class DDNSProviderDHS(DDNSProvider):
def update_protocol(self, proto): data = {
"domain" : self.hostname,
"ip" : self.get_address(proto),
"hostcmd" : "edit",
"hostcmdstage" : "2",
"type" : "4",
"domain": self.hostname,
"ip": self.get_address(proto),
"hostcmd": "edit",
"hostcmdstage": "2",
"type": "4",
}
# Send update to the server.
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Handle success messages. if response.code == 200:
@@ -715,9 +710,9 @@ class DDNSProviderDHS(DDNSProvider):
class DDNSProviderDNSpark(DDNSProvider):
- handle = "dnspark.com"
- name = "DNS Park"
- website = "http://dnspark.com/"
handle = "dnspark.com"
name = "DNS Park"
website = "http://dnspark.com/" protocols = ("ipv4",)
# Informations to the used api can be found here:
@@ -728,13 +723,12 @@ class DDNSProviderDNSpark(DDNSProvider):
def update_protocol(self, proto): data = {
"domain" : self.hostname,
"ip" : self.get_address(proto),
"domain": self.hostname,
"ip": self.get_address(proto),
}
# Send update to the server.
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Get the full response message. output = response.read()
@@ -764,9 +758,9 @@ class DDNSProviderDNSpark(DDNSProvider):
class DDNSProviderDtDNS(DDNSProvider):
- handle = "dtdns.com"
- name = "DtDNS"
- website = "http://dtdns.com/"
handle = "dtdns.com"
name = "DtDNS"
website = "http://dtdns.com/" protocols = ("ipv4",)
# Information about the format of the HTTPS request is to be
found @@ -777,9 +771,9 @@ class DDNSProviderDtDNS(DDNSProvider):
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"id" : self.hostname,
"pw" : self.password
"ip": self.get_address(proto),
"id": self.hostname,
"pw": self.password
}
# Send update to the server.
@@ -819,9 +813,9 @@ class DDNSProviderDtDNS(DDNSProvider):
class DDNSProviderDuckDNS(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "duckdns.org"
- name = "Duck DNS"
- website = "http://www.duckdns.org/"
handle = "duckdns.org"
name = "Duck DNS"
website = "http://www.duckdns.org/" protocols = ("ipv4",)
# Information about the format of the request is to be found
@@ -831,9 +825,9 @@ class DDNSProviderDuckDNS(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderDyFi(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "dy.fi"
- name = "dy.fi"
- website = "https://www.dy.fi/"
handle = "dy.fi"
name = "dy.fi"
website = "https://www.dy.fi/" protocols = ("ipv4",)
# Information about the format of the request is to be found
@@ -849,9 +843,9 @@ class DDNSProviderDyFi(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderDynDNS(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "dyndns.org"
- name = "Dyn"
- website = "http://dyn.com/dns/"
handle = "dyndns.org"
name = "Dyn"
website = "http://dyn.com/dns/" protocols = ("ipv4",)
# Information about the format of the request is to be found
@@ -862,9 +856,9 @@ class DDNSProviderDynDNS(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderDomainOffensive(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "do.de"
- name = "Domain-Offensive"
- website = "https://www.do.de/"
handle = "do.de"
name = "Domain-Offensive"
website = "https://www.do.de/" protocols = ("ipv6", "ipv4")
# Detailed information about the request and response codes
@@ -873,10 +867,11 @@ class DDNSProviderDomainOffensive(DDNSProtocolDynDNS2, DDNSProvider):
url = "https://ddns.do.de/"
class DDNSProviderDynUp(DDNSProvider):
- handle = "dynup.de"
- name = "DynUp.DE"
- website = "http://dynup.de/"
handle = "dynup.de"
name = "DynUp.DE"
website = "http://dynup.de/" protocols = ("ipv4",)
# Information about the format of the HTTPS request is to be
found @@ -887,10 +882,10 @@ class DDNSProviderDynUp(DDNSProvider):
def update_protocol(self, proto): data = {
"username" : self.username,
"password" : self.password,
"hostname" : self.hostname,
"print" : '1',
"username": self.username,
"password": self.password,
"hostname": self.hostname,
"print": '1',
}
# Send update to the server.
@@ -903,18 +898,17 @@ class DDNSProviderDynUp(DDNSProvider): output = output.strip()
# Handle success messages.
if output.startswith("I:OK") :
if output.startswith("I:OK"): return
# If we got here, some other update error happened. raise DDNSUpdateError
class DDNSProviderDynU(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "dynu.com"
- name = "Dynu"
- website = "http://dynu.com/"
handle = "dynu.com"
name = "Dynu"
website = "http://dynu.com/" protocols = ("ipv6", "ipv4",)
# Detailed information about the request and response codes
@@ -939,9 +933,9 @@ class DDNSProviderDynU(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderEasyDNS(DDNSProvider):
- handle = "easydns.com"
- name = "EasyDNS"
- website = "http://www.easydns.com/"
handle = "easydns.com"
name = "EasyDNS"
website = "http://www.easydns.com/" protocols = ("ipv4",)
# Detailed information about the request and response codes
@@ -952,13 +946,12 @@ class DDNSProviderEasyDNS(DDNSProvider):
def update_protocol(self, proto): data = {
"myip" : self.get_address(proto, "-"),
"hostname" : self.hostname,
"myip": self.get_address(proto, "-"),
"hostname": self.hostname,
}
# Send update to the server.
response = self.send_request(self.url, data=data,
username=self.username, password=self.password)
response = self.send_request(self.url, data=data,
username=self.username, password=self.password)
# Get the full response message. output = response.read()
@@ -988,9 +981,9 @@ class DDNSProviderEasyDNS(DDNSProvider):
class DDNSProviderDomopoli(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "domopoli.de"
- name = "domopoli.de"
- website = "http://domopoli.de/"
handle = "domopoli.de"
name = "domopoli.de"
website = "http://domopoli.de/" protocols = ("ipv4",)
@@ -999,9 +992,9 @@ class DDNSProviderDomopoli(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderDynsNet(DDNSProvider):
- handle = "dyns.net"
- name = "DyNS"
- website = "http://www.dyns.net/"
- handle = "dyns.net"
- name = "DyNS"
- website = "http://www.dyns.net/" protocols = ("ipv4",) can_remove_records = False
@@ -1013,10 +1006,10 @@ class DDNSProviderDynsNet(DDNSProvider):
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"host" : self.hostname,
"username" : self.username,
"password" : self.password,
"ip": self.get_address(proto),
"host": self.hostname,
"username": self.username,
"password": self.password,
}
# Send update to the server.
@@ -1044,9 +1037,9 @@ class DDNSProviderDynsNet(DDNSProvider):
class DDNSProviderEnomCom(DDNSResponseParserXML, DDNSProvider):
- handle = "enom.com"
- name = "eNom Inc."
- website = "http://www.enom.com/"
handle = "enom.com"
name = "eNom Inc."
website = "http://www.enom.com/" protocols = ("ipv4",)
# There are very detailed information about how to send an
update request and @@ -1058,11 +1051,11 @@ class DDNSProviderEnomCom(DDNSResponseParserXML, DDNSProvider):
def update_protocol(self, proto): data = {
"command" : "setdnshost",
"responsetype" : "xml",
"address" : self.get_address(proto),
"domainpassword" : self.password,
"zone" : self.hostname
"command": "setdnshost",
"responsetype": "xml",
"address": self.get_address(proto),
"domainpassword": self.password,
"zone": self.hostname
}
# Send update to the server.
@@ -1088,9 +1081,9 @@ class DDNSProviderEnomCom(DDNSResponseParserXML, DDNSProvider):
class DDNSProviderEntryDNS(DDNSProvider):
- handle = "entrydns.net"
- name = "EntryDNS"
- website = "http://entrydns.net/"
handle = "entrydns.net"
name = "EntryDNS"
website = "http://entrydns.net/" protocols = ("ipv4",)
# Some very tiny details about their so called "Simple API" can
be found @@ -1100,7 +1093,7 @@ class DDNSProviderEntryDNS(DDNSProvider):
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"ip": self.get_address(proto),
}
# Add auth token to the update url.
@@ -1111,7 +1104,7 @@ class DDNSProviderEntryDNS(DDNSProvider): response = self.send_request(url, data=data)
# Handle error codes
except urllib2.HTTPError, e:
except urllib.error.HTTPError as e: if e.code == 404: raise DDNSAuthenticationError
@@ -1129,9 +1122,9 @@ class DDNSProviderEntryDNS(DDNSProvider):
class DDNSProviderFreeDNSAfraidOrg(DDNSProvider):
- handle = "freedns.afraid.org"
- name = "freedns.afraid.org"
- website = "http://freedns.afraid.org/"
handle = "freedns.afraid.org"
name = "freedns.afraid.org"
website = "http://freedns.afraid.org/"
# No information about the request or response could be found
on the vendor # page. All used values have been collected by testing. @@ -1140,7 +1133,7 @@ class DDNSProviderFreeDNSAfraidOrg(DDNSProvider):
def update_protocol(self, proto): data = {
"address" : self.get_address(proto),
"address": self.get_address(proto),
}
# Add auth token to the update url.
@@ -1167,59 +1160,59 @@ class DDNSProviderFreeDNSAfraidOrg(DDNSProvider):
class DDNSProviderItsdns(DDNSProtocolDynDNS2, DDNSProvider):
handle = "inwx.com"
name = "INWX"
website = "https://www.inwx.com"
protocols = ("ipv6", "ipv4")
- handle = "inwx.com"
- name = "INWX"
- website = "https://www.inwx.com"
- protocols = ("ipv6", "ipv4")
# Information about the format of the HTTP request is
to be found
# here: https://www.inwx.com/en/nameserver2/dyndns
(requires login)
# Notice: The URL is the same for: inwx.com|de|at|ch|es
- # Information about the format of the HTTP request is to be
found
- # here: https://www.inwx.com/en/nameserver2/dyndns (requires
login)
- # Notice: The URL is the same for: inwx.com|de|at|ch|es
url = "https://dyndns.inwx.com/nic/update"
class DDNSProviderItsdns(DDNSProtocolDynDNS2, DDNSProvider):
handle = "itsdns.de"
name = "it's DNS"
website = "http://www.itsdns.de/"
protocols = ("ipv6", "ipv4")
- handle = "itsdns.de"
- name = "it's DNS"
- website = "http://www.itsdns.de/"
- protocols = ("ipv6", "ipv4")
# Information about the format of the HTTP request is
to be found
# here: https://www.itsdns.de/dynupdatehelp.htm
- # Information about the format of the HTTP request is to be
found
url = "https://www.itsdns.de/update.php"
- url = "https://www.itsdns.de/update.php"
class DDNSProviderJoker(DDNSProtocolDynDNS2, DDNSProvider):
handle = "joker.com"
name = "Joker.com Dynamic DNS"
website = "https://joker.com/"
protocols = ("ipv4",)
- handle = "joker.com"
- name = "Joker.com Dynamic DNS"
- website = "https://joker.com/"
- protocols = ("ipv4",)
# Information about the request can be found here:
#
https://joker.com/faq/content/11/427/en/what-is-dynamic-dns-dyndns.html
# Using DynDNS V2 protocol over HTTPS here
- # Information about the request can be found here:
- #
https://joker.com/faq/content/11/427/en/what-is-dynamic-dns-dyndns.html
- # Using DynDNS V2 protocol over HTTPS here
url = "https://svc.joker.com/nic/update"
- url = "https://svc.joker.com/nic/update"
class DDNSProviderGoogle(DDNSProtocolDynDNS2, DDNSProvider):
handle = "domains.google.com"
name = "Google Domains"
website = "https://domains.google.com/"
protocols = ("ipv4",)
- handle = "domains.google.com"
- name = "Google Domains"
- website = "https://domains.google.com/"
- protocols = ("ipv4",)
# Information about the format of the HTTP request is to
be found
# here:
https://support.google.com/domains/answer/6147083?hl=en
- # Information about the format of the HTTP request is to be
found
url = "https://domains.google.com/nic/update"
class DDNSProviderLightningWireLabs(DDNSProvider):
- handle = "dns.lightningwirelabs.com"
- name = "Lightning Wire Labs DNS Service"
- website = "http://dns.lightningwirelabs.com/"
handle = "dns.lightningwirelabs.com"
name = "Lightning Wire Labs DNS Service"
website = "http://dns.lightningwirelabs.com/"
# Information about the format of the HTTPS request is to be
found # https://dns.lightningwirelabs.com/knowledge-base/api/ddns @@ -1227,10 +1220,10 @@ class DDNSProviderLightningWireLabs(DDNSProvider): url = "https://dns.lightningwirelabs.com/update"
def update(self):
data = {
"hostname" : self.hostname,
"address6" : self.get_address("ipv6", "-"),
"address4" : self.get_address("ipv4", "-"),
data = {
"hostname": self.hostname,
"address6": self.get_address("ipv6", "-"),
"address4": self.get_address("ipv4", "-"),
}
# Check if a token has been set.
@@ -1240,8 +1233,8 @@ class DDNSProviderLightningWireLabs(DDNSProvider): # Check for username and password. elif self.username and self.password: data.update({
"username" : self.username,
"password" : self.password,
"username": self.username,
"password": self.password, })
# Raise an error if no auth details are given.
@@ -1260,9 +1253,9 @@ class DDNSProviderLightningWireLabs(DDNSProvider):
class DDNSProviderLoopia(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "loopia.se"
- name = "Loopia AB"
- website = "https://www.loopia.com"
handle = "loopia.se"
name = "Loopia AB"
website = "https://www.loopia.com" protocols = ("ipv4",)
# Information about the format of the HTTP request is to be
found @@ -1272,9 +1265,9 @@ class DDNSProviderLoopia(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderMyOnlinePortal(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "myonlineportal.net"
- name = "myonlineportal.net"
- website = "https:/myonlineportal.net/"
handle = "myonlineportal.net"
name = "myonlineportal.net"
website = "https:/myonlineportal.net/"
# Information about the request and response can be obtained
here: # https://myonlineportal.net/howto_dyndns @@ -1283,17 +1276,17 @@ class DDNSProviderMyOnlinePortal(DDNSProtocolDynDNS2, DDNSProvider):
def prepare_request_data(self, proto): data = {
"hostname" : self.hostname,
"ip" : self.get_address(proto),
"hostname": self.hostname,
"ip": self.get_address(proto),
}
return data
class DDNSProviderNamecheap(DDNSResponseParserXML, DDNSProvider):
- handle = "namecheap.com"
- name = "Namecheap"
- website = "http://namecheap.com"
handle = "namecheap.com"
name = "Namecheap"
website = "http://namecheap.com" protocols = ("ipv4",)
# Information about the format of the HTTP request is to be
found @@ -1311,10 +1304,10 @@ class DDNSProviderNamecheap(DDNSResponseParserXML, DDNSProvider): address = self.get_address(proto)
data = {
"ip" : address,
"password" : self.password,
"host" : host,
"domain" : domain
"ip": address,
"password": self.password,
"host": host,
"domain": domain
}
# Send update to the server.
@@ -1344,9 +1337,9 @@ class DDNSProviderNamecheap(DDNSResponseParserXML, DDNSProvider):
class DDNSProviderNOIP(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "no-ip.com"
- name = "NoIP"
- website = "http://www.noip.com/"
handle = "no-ip.com"
name = "NoIP"
website = "http://www.noip.com/" protocols = ("ipv4",)
# Information about the format of the HTTP request is to be
found @@ -1359,17 +1352,17 @@ class DDNSProviderNOIP(DDNSProtocolDynDNS2, DDNSProvider): assert proto == "ipv4"
data = {
"hostname" : self.hostname,
"address" : self.get_address(proto),
"hostname": self.hostname,
"address": self.get_address(proto),
}
return data
class DDNSProviderNowDNS(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "now-dns.com"
- name = "NOW-DNS"
- website = "http://now-dns.com/"
handle = "now-dns.com"
name = "NOW-DNS"
website = "http://now-dns.com/" protocols = ("ipv6", "ipv4")
# Information about the format of the request is to be found
@@ -1380,9 +1373,9 @@ class DDNSProviderNowDNS(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderNsupdateINFO(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "nsupdate.info"
- name = "nsupdate.info"
- website = "http://nsupdate.info/"
handle = "nsupdate.info"
name = "nsupdate.info"
website = "http://nsupdate.info/" protocols = ("ipv6", "ipv4",)
# Information about the format of the HTTP request can be found
@@ -1411,16 +1404,16 @@ class DDNSProviderNsupdateINFO(DDNSProtocolDynDNS2, DDNSProvider):
def prepare_request_data(self, proto): data = {
"myip" : self.get_address(proto),
"myip": self.get_address(proto),
}
return data
class DDNSProviderOpenDNS(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "opendns.com"
- name = "OpenDNS"
- website = "http://www.opendns.com"
handle = "opendns.com"
name = "OpenDNS"
website = "http://www.opendns.com"
# Detailed information about the update request and possible # response codes can be obtained from here:
@@ -1430,17 +1423,17 @@ class DDNSProviderOpenDNS(DDNSProtocolDynDNS2, DDNSProvider):
def prepare_request_data(self, proto): data = {
"hostname" : self.hostname,
"myip" : self.get_address(proto),
"hostname": self.hostname,
"myip": self.get_address(proto),
}
return data
class DDNSProviderOVH(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "ovh.com"
- name = "OVH"
- website = "http://www.ovh.com/"
handle = "ovh.com"
name = "OVH"
website = "http://www.ovh.com/" protocols = ("ipv4",)
# OVH only provides very limited information about how to
@@ -1454,15 +1447,15 @@ class DDNSProviderOVH(DDNSProtocolDynDNS2, DDNSProvider): def prepare_request_data(self, proto): data = DDNSProtocolDynDNS2.prepare_request_data(self, proto) data.update({
"system" : "dyndns",
"system": "dyndns",
})
return data
class DDNSProviderRegfish(DDNSProvider):
- handle = "regfish.com"
- name = "Regfish GmbH"
handle = "regfish.com"
name = "Regfish GmbH" website = "http://www.regfish.com/"
# A full documentation to the providers api can be found here
@@ -1474,7 +1467,7 @@ class DDNSProviderRegfish(DDNSProvider):
def update(self): data = {
"fqdn" : self.hostname,
"fqdn": self.hostname,
}
# Check if we update an IPv6 address.
@@ -1488,7 +1481,7 @@ class DDNSProviderRegfish(DDNSProvider): data["ipv4"] = address4
# Raise an error if none address is given.
if not data.has_key("ipv6") and not
data.has_key("ipv4"):
if "ipv6" not in data and "ipv4" not in data: raise DDNSConfigurationError
# Check if a token has been set.
@@ -1506,8 +1499,7 @@ class DDNSProviderRegfish(DDNSProvider): response = self.send_request(self.url, data=data) else: # Send update to the server.
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Get the full response message. output = response.read()
@@ -1533,9 +1525,9 @@ class DDNSProviderRegfish(DDNSProvider):
class DDNSProviderSchokokeksDNS(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "schokokeks.org"
- name = "Schokokeks"
- website = "http://www.schokokeks.org/"
handle = "schokokeks.org"
name = "Schokokeks"
website = "http://www.schokokeks.org/" protocols = ("ipv4",)
# Information about the format of the request is to be found
@@ -1544,9 +1536,9 @@ class DDNSProviderSchokokeksDNS(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderSelfhost(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "selfhost.de"
- name = "Selfhost.de"
- website = "http://www.selfhost.de/"
handle = "selfhost.de"
name = "Selfhost.de"
website = "http://www.selfhost.de/" protocols = ("ipv4",)
@@ -1554,16 +1546,16 @@ class DDNSProviderSelfhost(DDNSProtocolDynDNS2, DDNSProvider): def prepare_request_data(self, proto): data = DDNSProtocolDynDNS2.prepare_request_data(self, proto) data.update({
"hostname" : "1",
"hostname": "1",
})
return data
class DDNSProviderServercow(DDNSProvider):
- handle = "servercow.de"
- name = "servercow.de"
- website = "https://servercow.de/"
handle = "servercow.de"
name = "servercow.de"
website = "https://servercow.de/" protocols = ("ipv4", "ipv6")
@@ -1571,10 +1563,10 @@ class DDNSProviderServercow(DDNSProvider):
def update_protocol(self, proto): data = {
"ipaddr" : self.get_address(proto),
"hostname" : self.hostname,
"username" : self.username,
"pass" : self.password,
"ipaddr": self.get_address(proto),
"hostname": self.hostname,
"username": self.username,
"pass": self.password,
}
# Send request to provider
@@ -1596,9 +1588,9 @@ class DDNSProviderServercow(DDNSProvider):
class DDNSProviderSPDNS(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "spdns.org"
- name = "SPDYN"
- website = "https://www.spdyn.de/"
handle = "spdns.org"
name = "SPDYN"
website = "https://www.spdyn.de/"
# Detailed information about request and response codes are
provided # by the vendor. They are using almost the same mechanism and status @@ -1619,9 +1611,9 @@ class DDNSProviderSPDNS(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderStrato(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "strato.com"
- name = "Strato AG"
- website = "http:/www.strato.com/"
handle = "strato.com"
name = "Strato AG"
website = "http:/www.strato.com/" protocols = ("ipv4",)
# Information about the request and response can be obtained
here: @@ -1632,17 +1624,17 @@ class DDNSProviderStrato(DDNSProtocolDynDNS2, DDNSProvider): def prepare_request_data(self, proto): data = DDNSProtocolDynDNS2.prepare_request_data(self, proto) data.update({
"mx" : "NOCHG",
"backupmx" : "NOCHG"
"mx": "NOCHG",
"backupmx": "NOCHG"
})
return data
class DDNSProviderTwoDNS(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "twodns.de"
- name = "TwoDNS"
- website = "http://www.twodns.de"
handle = "twodns.de"
name = "TwoDNS"
website = "http://www.twodns.de" protocols = ("ipv4",)
# Detailed information about the request can be found here
@@ -1655,17 +1647,17 @@ class DDNSProviderTwoDNS(DDNSProtocolDynDNS2, DDNSProvider): assert proto == "ipv4"
data = {
"ip" : self.get_address(proto),
"hostname" : self.hostname
"ip": self.get_address(proto),
"hostname": self.hostname
}
return data
class DDNSProviderUdmedia(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "udmedia.de"
- name = "Udmedia GmbH"
- website = "http://www.udmedia.de"
handle = "udmedia.de"
name = "Udmedia GmbH"
website = "http://www.udmedia.de" protocols = ("ipv4",)
# Information about the request can be found here
@@ -1675,9 +1667,9 @@ class DDNSProviderUdmedia(DDNSProtocolDynDNS2, DDNSProvider):
class DDNSProviderVariomedia(DDNSProtocolDynDNS2, DDNSProvider):
- handle = "variomedia.de"
- name = "Variomedia"
- website = "http://www.variomedia.de/"
handle = "variomedia.de"
name = "Variomedia"
website = "http://www.variomedia.de/" protocols = ("ipv6", "ipv4",)
# Detailed information about the request can be found here
@@ -1687,29 +1679,29 @@ class DDNSProviderVariomedia(DDNSProtocolDynDNS2, DDNSProvider):
def prepare_request_data(self, proto): data = {
"hostname" : self.hostname,
"myip" : self.get_address(proto),
"hostname": self.hostname,
"myip": self.get_address(proto),
}
return data
class DDNSProviderXLhost(DDNSProtocolDynDNS2, DDNSProvider):
handle = "xlhost.de"
name = "XLhost"
website = "http://xlhost.de/"
protocols = ("ipv4",)
- handle = "xlhost.de"
- name = "XLhost"
- website = "http://xlhost.de/"
- protocols = ("ipv4",)
# Information about the format of the HTTP request is to
be found
# here:
https://xlhost.de/faq/index_html?topicId=CQA2ELIPO4SQ
- # Information about the format of the HTTP request is to be
found
url = "https://nsupdate.xlhost.de/"
- url = "https://nsupdate.xlhost.de/"
class DDNSProviderZoneedit(DDNSProvider):
- handle = "zoneedit.com"
- name = "Zoneedit"
- website = "http://www.zoneedit.com"
handle = "zoneedit.com"
name = "Zoneedit"
website = "http://www.zoneedit.com" protocols = ("ipv4",)
# Detailed information about the request and the response codes
can be @@ -1721,13 +1713,12 @@ class DDNSProviderZoneedit(DDNSProvider):
def update_protocol(self, proto): data = {
"dnsto" : self.get_address(proto),
"host" : self.hostname
"dnsto": self.get_address(proto),
"host": self.hostname
}
# Send update to the server.
response = self.send_request(self.url,
username=self.username, password=self.password,
data=data)
response = self.send_request(self.url,
username=self.username, password=self.password, data=data)
# Get the full response message. output = response.read()
@@ -1749,9 +1740,9 @@ class DDNSProviderZoneedit(DDNSProvider):
class DDNSProviderDNSmadeEasy(DDNSProvider):
- handle = "dnsmadeeasy.com"
- name = "DNSmadeEasy.com"
- website = "http://www.dnsmadeeasy.com/"
handle = "dnsmadeeasy.com"
name = "DNSmadeEasy.com"
website = "http://www.dnsmadeeasy.com/" protocols = ("ipv4",)
# DNS Made Easy Nameserver Provider also offering Dynamic DNS
@@ -1763,10 +1754,10 @@ class DDNSProviderDNSmadeEasy(DDNSProvider):
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"id" : self.hostname,
"username" : self.username,
"password" : self.password,
"ip": self.get_address(proto),
"id": self.hostname,
"username": self.username,
"password": self.password,
}
# Send update to the server.
@@ -1797,9 +1788,9 @@ class DDNSProviderDNSmadeEasy(DDNSProvider):
class DDNSProviderZZZZ(DDNSProvider):
- handle = "zzzz.io"
- name = "zzzz"
- website = "https://zzzz.io"
handle = "zzzz.io"
name = "zzzz"
website = "https://zzzz.io" protocols = ("ipv6", "ipv4",)
# Detailed information about the update request can be found
here: @@ -1813,8 +1804,8 @@ class DDNSProviderZZZZ(DDNSProvider):
def update_protocol(self, proto): data = {
"ip" : self.get_address(proto),
"token" : self.token,
"ip": self.get_address(proto),
"token": self.token,
}
if proto == "ipv6":
diff --git a/src/ddns/system.py b/src/ddns/system.py index b7a51f6..59c0525 100644 --- a/src/ddns/system.py +++ b/src/ddns/system.py @@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python3 ################################################################### ############ #
#
# ddns - A dynamic DNS client for IPFire # -# Copyright (C) 2012 IPFire development team # +# Copyright (C) 2012-2019 IPFire development team # #
#
# This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -23,18 +23,20 @@ import base64 import re import ssl import socket -import urllib -import urllib2 +import urllib.request +import urllib.parse +import urllib.error
-from __version__ import CLIENT_VERSION +from .__version__ import CLIENT_VERSION from .errors import * -from i18n import _ +from .i18n import _
# Initialize the logger. import logging logger = logging.getLogger("ddns.system") logger.propagate = 1
class DDNSSystem(object): """ The DDNSSystem class adds a layer of abstraction @@ -79,7 +81,7 @@ class DDNSSystem(object): with open("/var/ipfire/red/local- ipaddress") as f: return f.readline()
except IOError, e:
except IOError as e: # File not found if e.errno == 2: return
@@ -137,7 +139,7 @@ class DDNSSystem(object): if data: logger.debug(" data: %s" % data)
req = urllib2.Request(url, data=data)
req = urllib.request.Request(url, data=data)
if username and password: basic_auth_header =
self._make_basic_auth_header(username, password) @@ -159,24 +161,24 @@ class DDNSSystem(object): assert req.get_method() == method
logger.debug(_("Request header:"))
for k, v in req.headers.items():
for k, v in list(req.headers.items()): logger.debug(" %s: %s" % (k, v))
try:
resp = urllib2.urlopen(req, timeout=timeout)
resp = urllib.request.urlopen(req,
timeout=timeout)
# Log response header. logger.debug(_("Response header (Status Code
%s):") % resp.code)
for k, v in resp.info().items():
for k, v in list(resp.info().items()): logger.debug(" %s: %s" % (k, v)) # Return the entire response object. return resp
except urllib2.HTTPError, e:
except urllib.error.HTTPError as e: # Log response header. logger.debug(_("Response header (Status Code
%s):") % e.code)
for k, v in e.hdrs.items():
for k, v in list(e.hdrs.items()): logger.debug(" %s: %s" % (k, v)) # 400 - Bad request
@@ -209,7 +211,7 @@ class DDNSSystem(object): # Raise all other unhandled exceptions. raise
except urllib2.URLError, e:
except urllib.error.URLError as e: if e.reason: # Handle SSL errors if isinstance(e.reason, ssl.SSLError):
@@ -240,7 +242,7 @@ class DDNSSystem(object): # Raise all other unhandled exceptions. raise
except socket.timeout, e:
except socket.timeout as e: logger.debug(_("Connection timeout")) raise DDNSConnectionTimeoutError
@@ -248,8 +250,8 @@ class DDNSSystem(object): def _format_query_args(self, data): args = []
for k, v in data.items():
arg = "%s=%s" % (k, urllib.quote(v))
for k, v in list(data.items()):
arg = "%s=%s" % (k, urllib.parse.quote(v)) args.append(arg)
return "&".join(args)
@@ -258,7 +260,7 @@ class DDNSSystem(object): authstring = "%s:%s" % (username, password)
# Encode authorization data in base64.
authstring = base64.encodestring(authstring)
authstring = base64.encodebytes(authstring)
# Remove any newline characters. authstring = authstring.replace("\n", "")
@@ -354,7 +356,7 @@ class DDNSSystem(object): # Resolve the host address. try: response = socket.getaddrinfo(hostname, None, family)
except socket.gaierror, e:
except socket.gaierror as e: # Name or service not known if e.errno == -2: return []
@@ -418,7 +420,7 @@ class DDNSSystem(object): """ try: f = open("/etc/os-release", "r")
except IOError, e:
except IOError as e: # File not found if e.errno == 2: return
@@ -447,7 +449,7 @@ class DDNSSystem(object): """ try: f = open("/etc/system-release", "r")
except IOError, e:
except IOError as e: # File not found if e.errno == 2: return
-- 2.24.1
This patch is very very long and does not need to be.
There should be no changes in the code styling and all those empty lines that are being added make the code messy.
Please remove them, cleanup the patch and submit again.
Best, -Michael
ddns mailing list ddns@lists.ipfire.org https://lists.ipfire.org/mailman/listinfo/ddns
ddns mailing list ddns@lists.ipfire.org https://lists.ipfire.org/mailman/listinfo/ddns
ddns mailing list ddns@lists.ipfire.org https://lists.ipfire.org/mailman/listinfo/ddns