* Re: [PATCH] DDNS: Port to python3
[not found] <C6E3B0A6-0514-498E-858B-EA48C9E162AF@ipfire.org>
@ 2020-01-06 12:31 ` Stefan Schantl
2020-01-06 14:44 ` Michael Tremer
0 siblings, 1 reply; 4+ messages in thread
From: Stefan Schantl @ 2020-01-06 12:31 UTC (permalink / raw)
To: ddns
[-- Attachment #1: Type: text/plain, Size: 106454 bytes --]
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.
root(a)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(a)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(a)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"
> + 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
> + # here: https://www.itsdns.de/dynupdatehelp.htm
>
> - 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
> + # here: https://support.google.com/domains/answer/6147083?hl=en
>
> - url = "https://domains.google.com/nic/update"
> + 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
> + # here: https://xlhost.de/faq/index_html?topicId=CQA2ELIPO4SQ
>
> - 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(a)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(a)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(a)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",)
> >
> > # https://www.domopoli.de/?page=howto#DynDns_start
> > @@ -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"
> > + 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
> > + # here: https://www.itsdns.de/dynupdatehelp.htm
> >
> > - 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
> > + # here: https://support.google.com/domains/answer/6147083?hl=en
> >
> > - url = "https://domains.google.com/nic/update"
> > + 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",)
> >
> > url = "https://carol.selfhost.de/nic/update"
> > @@ -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")
> >
> > url = "https://www.servercow.de/dnsupdate/update.php"
> > @@ -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
> > + # here: https://xlhost.de/faq/index_html?topicId=CQA2ELIPO4SQ
> >
> > - 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(a)lists.ipfire.org
> > https://lists.ipfire.org/mailman/listinfo/ddns
>
> _______________________________________________
> ddns mailing list
> ddns(a)lists.ipfire.org
> https://lists.ipfire.org/mailman/listinfo/ddns
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] DDNS: Port to python3
2020-01-06 12:31 ` [PATCH] DDNS: Port to python3 Stefan Schantl
@ 2020-01-06 14:44 ` Michael Tremer
0 siblings, 0 replies; 4+ messages in thread
From: Michael Tremer @ 2020-01-06 14:44 UTC (permalink / raw)
To: ddns
[-- Attachment #1: Type: text/plain, Size: 110175 bytes --]
> On 6 Jan 2020, at 12:31, Stefan Schantl <stefan.schantl(a)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(a)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(a)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(a)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"
>> + 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
>> + # here: https://www.itsdns.de/dynupdatehelp.htm
>>
>> - 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
>> + # here: https://support.google.com/domains/answer/6147083?hl=en
>>
>> - url = "https://domains.google.com/nic/update"
>> + 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
>> + # here: https://xlhost.de/faq/index_html?topicId=CQA2ELIPO4SQ
>>
>> - 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(a)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(a)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(a)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",)
>>>
>>> # https://www.domopoli.de/?page=howto#DynDns_start
>>> @@ -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"
>>> + 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
>>> + # here: https://www.itsdns.de/dynupdatehelp.htm
>>>
>>> - 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
>>> + # here: https://support.google.com/domains/answer/6147083?hl=en
>>>
>>> - url = "https://domains.google.com/nic/update"
>>> + 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",)
>>>
>>> url = "https://carol.selfhost.de/nic/update"
>>> @@ -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")
>>>
>>> url = "https://www.servercow.de/dnsupdate/update.php"
>>> @@ -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
>>> + # here: https://xlhost.de/faq/index_html?topicId=CQA2ELIPO4SQ
>>>
>>> - 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(a)lists.ipfire.org
>>> https://lists.ipfire.org/mailman/listinfo/ddns
>>
>> _______________________________________________
>> ddns mailing list
>> ddns(a)lists.ipfire.org
>> https://lists.ipfire.org/mailman/listinfo/ddns
> _______________________________________________
> ddns mailing list
> ddns(a)lists.ipfire.org
> https://lists.ipfire.org/mailman/listinfo/ddns
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] DDNS: Port to python3
2019-12-25 15:39 ` Kim
@ 2019-12-25 15:52 ` Michael Tremer
0 siblings, 0 replies; 4+ messages in thread
From: Michael Tremer @ 2019-12-25 15:52 UTC (permalink / raw)
To: ddns
[-- Attachment #1: Type: text/plain, Size: 62911 bytes --]
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(a)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(a)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",)
>
> # https://www.domopoli.de/?page=howto#DynDns_start
> @@ -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"
> + 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
> + # here: https://www.itsdns.de/dynupdatehelp.htm
>
> - 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
> + # here: https://support.google.com/domains/answer/6147083?hl=en
>
> - url = "https://domains.google.com/nic/update"
> + 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",)
>
> url = "https://carol.selfhost.de/nic/update"
> @@ -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")
>
> url = "https://www.servercow.de/dnsupdate/update.php"
> @@ -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
> + # here: https://xlhost.de/faq/index_html?topicId=CQA2ELIPO4SQ
>
> - 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(a)lists.ipfire.org
> https://lists.ipfire.org/mailman/listinfo/ddns
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] DDNS: Port to python3
[not found] <29BE055B-AC06-45CB-BF63-D344E2DEC6A9@ipfire.org>
@ 2019-12-25 15:39 ` Kim
2019-12-25 15:52 ` Michael Tremer
0 siblings, 1 reply; 4+ messages in thread
From: Kim @ 2019-12-25 15:39 UTC (permalink / raw)
To: ddns
[-- Attachment #1: Type: text/plain, Size: 57200 bytes --]
---
.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
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 #
# #
# 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(a)ipfire.org],
[ddns],
[http://git.ipfire.org/?p=oddments/ddns.git;a=summary])
@@ -54,7 +54,7 @@ AC_PROG_SED
AC_PATH_PROG([XSLTPROC], [xsltproc])
# Python
-AM_PATH_PYTHON([2.7])
+AM_PATH_PYTHON([3])
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 #
# #
# 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"))
# 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)
# 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 @@ def main():
else:
raise RuntimeError("Unhandled command: %s" % args.subparsers_name)
+
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
+
# 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()
+
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})
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)
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
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
+
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
+
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 = {}
+
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)
@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})
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})
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})
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 @@ 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"))
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)
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),
}
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)
# 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.
- """
+ """
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",)
# 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)
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",)
# https://www.domopoli.de/?page=howto#DynDns_start
@@ -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"
+ 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
+ # here: https://www.itsdns.de/dynupdatehelp.htm
- 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
+ # here: https://support.google.com/domains/answer/6147083?hl=en
- url = "https://domains.google.com/nic/update"
+ 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",)
url = "https://carol.selfhost.de/nic/update"
@@ -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")
url = "https://www.servercow.de/dnsupdate/update.php"
@@ -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
+ # here: https://xlhost.de/faq/index_html?topicId=CQA2ELIPO4SQ
- 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
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-01-06 14:44 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <C6E3B0A6-0514-498E-858B-EA48C9E162AF@ipfire.org>
2020-01-06 12:31 ` [PATCH] DDNS: Port to python3 Stefan Schantl
2020-01-06 14:44 ` Michael Tremer
[not found] <29BE055B-AC06-45CB-BF63-D344E2DEC6A9@ipfire.org>
2019-12-25 15:39 ` Kim
2019-12-25 15:52 ` Michael Tremer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox