From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefan Schantl To: ddns@lists.ipfire.org Subject: Re: [PATCH] DDNS: Port to python3 Date: Mon, 06 Jan 2020 13:31:48 +0100 Message-ID: <3125c3335d44ab24744fe1f9ed75974f1c142d8a.camel@ipfire.org> In-Reply-To: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3508262843831252438==" List-Id: --===============3508262843831252438== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit 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 "" % (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 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 "" % (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 --===============3508262843831252438== Content-Type: application/pgp-signature Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="signature.asc" MIME-Version: 1.0 LS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS0KCmlRSXpCQUFCQ2dBZEZpRUVXTzBOWHRTcnZo YXN5dERuVHRkT0ZZK1RzdDRGQWw0VEtMUUFDZ2tRVHRkT0ZZK1QKc3Q1MTJRLytMY0JxdmVKWGRL WWpSSDh6NFgwSk1jbmlFKzBFby9wNTBoL0RkZmhtQVE2RUd1dFYwN1JQbmE3aQpZRHVxbXpPSUsy akFTM3g1N1ZJZHl2bXRvb3JhNmRhT1ZjVjRZRWtySFdaZjF6eVAySk9pbFdGUmtNd2ljQ2I4Cndw M0tFOEo2TGIzM05Sb0FIbGNDcHQ2eWVaQVhoKzIrY1M3NW1PSnAzZ003SURnUU83VW1DNDhzRGY5 SmUrL1UKVDVxVTducmtPRnk3dXJxbTRjSXAxNk1nNUVPa0J1b1ZId0R2M2RnTXZVRm9VZEZneHZm RUo2TWFxOGR6Q1dqMwpEZDhFQWxmbVE0Z1daSXNKWWRodldoZE0zeXY5UWFMWUY0OEtHK2FBUWpk dldVbkdMbE1OTnJIMnAxeWlNY0xMCk1ub2N1MzFSOXJRNHZzNG93YjU3TTREMklvNHpkM3orOUc4 dHFPRDhVN1lrS3pIeUpaTGQ4SWZQWVRneDBWT3QKRmhpa3hiOE1KRWVOazk3T21zMUJ0bnliNHhF UE0rcVZ0dVpaTlpQSDc4ZFRibGVCNjVjb0FvLzJPVHQwOUJmNwo0RjRzU2swaUdDRlN4Ym8zMUtz VG9IQjlJYTEzQVhwaERDRmd5T1BGYnRSUERibE5qSFpxNHJjS0lRREd6NFd3Cjd4MEtRV1JDa05Y YkhXRjhTckFFcFZxcEhqZ1J1Tyt1Vk1OU1NWVTV6MitMdlZlQkdZaENteEhNSDRkaFJkYmkKZTN3 dE1TSGovN2ErcUJWUTZKZlFNOXFxNDhLbklIdlVacEV2QWllK1ozS1hleDlCY21mV1JwUnVtdnlp YjRuQwpkaDZyVmlmU0NnT0dyRUN4RTJkUktxUlBabHBEbkU2NTFUcXJaa0taNDl5VHpJcnFYbHM9 Cj1TektKCi0tLS0tRU5EIFBHUCBTSUdOQVRVUkUtLS0tLQo= --===============3508262843831252438==--