> On 6 Jan 2020, at 12:31, Stefan Schantl wrote: > > Hello Kim, > > thanks for keep working on this and sorry for the long delay. > > Today I had some spare-time and checked your patch. > > Besides there are still some formating issues because of your used > Editor (New blank lines added, tabs are reformated, intensions are > changed etc), I was not able to get a list of the supported Providers > anymore after applying your Patch. Some of those whitespace changes are required because Python 3 does not allow mixed tabs and spaces in the same line (file?) any more. > root(a)system:/home/ddns# python3 /usr/bin/ddns -d -c > /etc/ddns/ddns.conf.sample list-providers > Debugmodus eingeschaltet > Laufe auf Distribution: unknown > Lade Konfigurationsdatei /etc/ddns/ddns.conf.sample > > The output should look like this: > > root(a)system:/home/ddns# python2 /usr/bin/ddns -d -c > /etc/ddns/ddns.conf.sample list-providers > Debugmodus eingeschaltet > Registered new provider: All-inkl.com (all-inkl.com) > Registered new provider: ChangeIP.com (changeip.com) > Registered new provider: DDNSS (ddnss.de) > Registered new provider: desec.io (desec.io) > Registered new provider: DHS International (dhs.org) > Registered new provider: Lightning Wire Labs DNS Service > (dns.lightningwirelabs.com) > Registered new provider: DNSmadeEasy.com (dnsmadeeasy.com) > Registered new provider: DNS Park (dnspark.com) > Registered new provider: Domain-Offensive (do.de) > Registered new provider: Google Domains (domains.google.com) > Registered new provider: domopoli.de (domopoli.de) > Registered new provider: DtDNS (dtdns.com) > Registered new provider: Duck DNS (duckdns.org) > Registered new provider: dy.fi (dy.fi) > Registered new provider: Dyn (dyndns.org) > Registered new provider: DyNS (dyns.net) > Registered new provider: Dynu (dynu.com) > Registered new provider: DynUp.DE (dynup.de) > Registered new provider: EasyDNS (easydns.com) > Registered new provider: eNom Inc. (enom.com) > Registered new provider: EntryDNS (entrydns.net) > Registered new provider: freedns.afraid.org (freedns.afraid.org) > Registered new provider: INWX (inwx.com) > Registered new provider: it's DNS (itsdns.de) > Registered new provider: Joker.com Dynamic DNS (joker.com) > Registered new provider: Loopia AB (loopia.se) > Registered new provider: myonlineportal.net (myonlineportal.net) > Registered new provider: Namecheap (namecheap.com) > Registered new provider: No-IP (no-ip.com) > Registered new provider: NOW-DNS (now-dns.com) > Registered new provider: BIND nsupdate utility (nsupdate) > Registered new provider: nsupdate.info (nsupdate.info) > Registered new provider: OpenDNS (opendns.com) > Registered new provider: OVH (ovh.com) > Registered new provider: Regfish GmbH (regfish.com) > Registered new provider: Schokokeks (schokokeks.org) > Registered new provider: Selfhost.de (selfhost.de) > Registered new provider: servercow.de (servercow.de) > Registered new provider: SPDYN (spdns.org) > Registered new provider: Strato AG (strato.com) > Registered new provider: TwoDNS (twodns.de) > Registered new provider: Udmedia GmbH (udmedia.de) > Registered new provider: Variomedia (variomedia.de) > Registered new provider: XLhost (xlhost.de) > Registered new provider: Zoneedit (zoneedit.com) > Registered new provider: zzzz (zzzz.io) > Laufe auf Distribution: unknown > Lade Konfigurationsdatei /etc/ddns/ddns.conf.sample > all-inkl.com > changeip.com > ddnss.de > desec.io > dhs.org > dns.lightningwirelabs.com > dnsmadeeasy.com > dnspark.com > do.de > domains.google.com > domopoli.de > dtdns.com > duckdns.org > dy.fi > dyndns.org > dyns.net > dynu.com > dynup.de > easydns.com > enom.com > entrydns.net > freedns.afraid.org > inwx.com > itsdns.de > joker.com > loopia.se > myonlineportal.net > namecheap.com > no-ip.com > now-dns.com > nsupdate > nsupdate.info > opendns.com > ovh.com > regfish.com > schokokeks.org > selfhost.de > servercow.de > spdns.org > strato.com > twodns.de > udmedia.de > variomedia.de > xlhost.de > zoneedit.com > zzzz.io > > Please check your Patch and re-submit a fixed version. > > Many thanks in advance, > > -Stefan >> Hi together, >> >> Fixed the things Michael mentioned. Update of the headers and >> .gitignore will follow in a separate patch if we decide it is >> necessary. >> >> I corrected additionally some intentions and adapted some PEP8 style >> guidelines >> >> Greetings >> Kim >> >> Index: src/ddns/system.py >> IDEA additional info: >> Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP >> <+>UTF-8 >> =================================================================== >> --- src/ddns/system.py (revision >> c0277eeea2b2c1ed8f40f1248b28438e44e51912) >> +++ src/ddns/system.py (date 1577472902318) >> @@ -1,4 +1,4 @@ >> -#!/usr/bin/python >> +#!/usr/bin/python3 >> #################################################################### >> ########### >> # >> # >> # ddns - A dynamic DNS client for IPFire >> # >> @@ -23,18 +23,20 @@ >> import re >> import ssl >> import socket >> -import urllib >> -import urllib2 >> +import urllib.request >> +import urllib.parse >> +import urllib.error >> >> -from __version__ import CLIENT_VERSION >> +from .__version__ import CLIENT_VERSION >> from .errors import * >> -from i18n import _ >> +from .i18n import _ >> >> # Initialize the logger. >> import logging >> logger = logging.getLogger("ddns.system") >> logger.propagate = 1 >> >> + >> class DDNSSystem(object): >> """ >> The DDNSSystem class adds a layer of abstraction >> @@ -79,7 +81,7 @@ >> with open("/var/ipfire/red/local- >> ipaddress") as f: >> return f.readline() >> >> - except IOError, e: >> + except IOError as e: >> # File not found >> if e.errno == 2: >> return >> @@ -137,7 +139,7 @@ >> if data: >> logger.debug(" data: %s" % data) >> >> - req = urllib2.Request(url, data=data) >> + req = urllib.request.Request(url, data=data) >> >> if username and password: >> basic_auth_header = >> self._make_basic_auth_header(username, password) >> @@ -163,7 +165,7 @@ >> logger.debug(" %s: %s" % (k, v)) >> >> try: >> - resp = urllib2.urlopen(req, timeout=timeout) >> + resp = urllib.request.urlopen(req, >> timeout=timeout) >> >> # Log response header. >> logger.debug(_("Response header (Status Code >> %s):") % resp.code) >> @@ -173,7 +175,7 @@ >> # Return the entire response object. >> return resp >> >> - except urllib2.HTTPError, e: >> + except urllib.error.HTTPError as e: >> # Log response header. >> logger.debug(_("Response header (Status Code >> %s):") % e.code) >> for k, v in e.hdrs.items(): >> @@ -209,7 +211,7 @@ >> # Raise all other unhandled exceptions. >> raise >> >> - except urllib2.URLError, e: >> + except urllib.error.URLError as e: >> if e.reason: >> # Handle SSL errors >> if isinstance(e.reason, ssl.SSLError): >> @@ -240,7 +242,7 @@ >> # Raise all other unhandled exceptions. >> raise >> >> - except socket.timeout, e: >> + except socket.timeout as e: >> logger.debug(_("Connection timeout")) >> >> raise DDNSConnectionTimeoutError >> @@ -249,7 +251,7 @@ >> args = [] >> >> for k, v in data.items(): >> - arg = "%s=%s" % (k, urllib.quote(v)) >> + arg = "%s=%s" % (k, urllib.parse.quote(v)) >> args.append(arg) >> >> return "&".join(args) >> @@ -258,7 +260,7 @@ >> authstring = "%s:%s" % (username, password) >> >> # Encode authorization data in base64. >> - authstring = base64.encodestring(authstring) >> + authstring = base64.encodebytes(authstring) >> >> # Remove any newline characters. >> authstring = authstring.replace("\n", "") >> @@ -354,7 +356,7 @@ >> # Resolve the host address. >> try: >> response = socket.getaddrinfo(hostname, None, >> family) >> - except socket.gaierror, e: >> + except socket.gaierror as e: >> # Name or service not known >> if e.errno == -2: >> return [] >> @@ -388,7 +390,7 @@ >> continue >> >> # Add to repsonse list if not already in there. >> - if not address in addresses: >> + if address not in addresses: >> addresses.append(address) >> >> return addresses >> @@ -418,7 +420,7 @@ >> """ >> try: >> f = open("/etc/os-release", "r") >> - except IOError, e: >> + except IOError as e: >> # File not found >> if e.errno == 2: >> return >> @@ -447,7 +449,7 @@ >> """ >> try: >> f = open("/etc/system-release", "r") >> - except IOError, e: >> + except IOError as e: >> # File not found >> if e.errno == 2: >> return >> Index: src/ddns/i18n.py >> IDEA additional info: >> Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP >> <+>UTF-8 >> =================================================================== >> --- src/ddns/i18n.py (revision >> c0277eeea2b2c1ed8f40f1248b28438e44e51912) >> +++ src/ddns/i18n.py (date 1577472902317) >> @@ -1,4 +1,4 @@ >> -#!/usr/bin/python >> +#!/usr/bin/python3 >> #################################################################### >> ########### >> # >> # >> # ddns - A dynamic DNS client for IPFire >> # >> @@ -25,15 +25,14 @@ >> >> N_ = lambda x: x >> >> + >> def _(singular, plural=None, n=None): >> """ >> A function that returnes the translation of a string if >> available. >> - >> The language is taken from the system environment. >> - """ >> - if not plural is None: >> + """ >> + if plural is not None: >> assert n is not None >> return gettext.dngettext(TEXTDOMAIN, singular, plural, >> n) >> >> return gettext.dgettext(TEXTDOMAIN, singular) >> - >> Index: configure.ac >> IDEA additional info: >> Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP >> <+>UTF-8 >> =================================================================== >> --- configure.ac (revision >> c0277eeea2b2c1ed8f40f1248b28438e44e51912) >> +++ configure.ac (date 1577473544755) >> @@ -21,7 +21,7 @@ >> AC_PREREQ([2.64]) >> >> AC_INIT([ddns], >> - [012], >> + [013], >> [info(a)ipfire.org], >> [ddns], >> [http://git.ipfire.org/?p=oddments/ddns.git;a=summary]) >> @@ -54,7 +54,7 @@ >> AC_PATH_PROG([XSLTPROC], [xsltproc]) >> >> # Python >> -AM_PATH_PYTHON([2.7]) >> +AM_PATH_PYTHON([3.6]) >> >> save_LIBS="$LIBS" >> >> Index: ddns.in >> IDEA additional info: >> Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP >> <+>UTF-8 >> =================================================================== >> --- ddns.in (revision c0277eeea2b2c1ed8f40f1248b28438e44e51912) >> +++ ddns.in (date 1577472902316) >> @@ -1,4 +1,4 @@ >> -#!/usr/bin/python >> +#!/usr/bin/python3 >> #################################################################### >> ########### >> # >> # >> # ddns - A dynamic DNS client for IPFire >> # >> @@ -27,27 +27,24 @@ >> >> CONFIGURATION_FILE = "@configsdir@/ddns.conf" >> >> + >> def main(): >> # Parse command line >> p = argparse.ArgumentParser(description=_("Dynamic DNS >> Updater")) >> >> - p.add_argument("-d", "--debug", action="store_true", >> - help=_("Enable debugging output")) >> + p.add_argument("-d", "--debug", action="store_true", >> help=_("Enable debugging output")) >> >> p.add_argument("-c", "--config", default=CONFIGURATION_FILE, >> help=_("Load configuration file (Default: %s)") % >> CONFIGURATION_FILE) >> >> # Create subparsers for commands. >> - subparsers = p.add_subparsers(help=_("Sub-command help"), >> - dest="subparsers_name") >> + subparsers = p.add_subparsers(help=_("Sub-command help"), >> dest="subparsers_name") >> >> # guess-ip-addresses >> - p_guess_ip_addresses = subparsers.add_parser("guess-ip- >> addresses", >> - help=_("Guess the external IP addresses")) >> + p_guess_ip_addresses = subparsers.add_parser("guess-ip- >> addresses", help=_("Guess the external IP addresses")) >> >> # list-providers >> - p_list_providers = subparsers.add_parser("list-providers", >> - help=_("List all available providers")) >> + p_list_providers = subparsers.add_parser("list-providers", >> help=_("List all available providers")) >> >> # update >> p_update = subparsers.add_parser("update", help=_("Update DNS >> record")) >> @@ -74,16 +71,16 @@ >> # IPv6 >> ipv6_address = >> d.system.guess_external_ip_address("ipv6") >> if ipv6_address: >> - print _("IPv6 Address: %s") % ipv6_address >> + print("IPv6 Address: %s" % ipv6_address) >> >> # IPv4 >> ipv4_address = >> d.system.guess_external_ip_address("ipv4") >> if ipv4_address: >> - print _("IPv4 Address: %s") % ipv4_address >> + print("IPv4 Address: %s" % ipv4_address) >> >> elif args.subparsers_name == "list-providers": >> provider_names = d.get_provider_names() >> - print "\n".join(provider_names) >> + print("\n".join(provider_names)) >> >> elif args.subparsers_name == "update": >> d.updateone(hostname=args.hostname, force=args.force) >> @@ -94,4 +91,5 @@ >> else: >> raise RuntimeError("Unhandled command: %s" % >> args.subparsers_name) >> >> + >> main() >> Index: src/ddns/database.py >> IDEA additional info: >> Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP >> <+>UTF-8 >> =================================================================== >> --- src/ddns/database.py (revision >> c0277eeea2b2c1ed8f40f1248b28438e44e51912) >> +++ src/ddns/database.py (date 1577472902317) >> @@ -1,4 +1,4 @@ >> -#!/usr/bin/python >> +#!/usr/bin/python3 >> #################################################################### >> ########### >> # >> # >> # ddns - A dynamic DNS client for IPFire >> # >> @@ -28,6 +28,7 @@ >> logger = logging.getLogger("ddns.database") >> logger.propagate = 1 >> >> + >> class DDNSDatabase(object): >> def __init__(self, core, path): >> self.core = core >> @@ -82,6 +83,7 @@ >> >> def _close_database(self): >> if self._db: >> + # TODO: Check Unresolved attribute reference >> '_db_close' for class 'DDNSDatabase' >> self._db_close() >> self._db = None >> >> Index: src/ddns/providers.py >> IDEA additional info: >> Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP >> <+>UTF-8 >> =================================================================== >> --- src/ddns/providers.py (revision >> c0277eeea2b2c1ed8f40f1248b28438e44e51912) >> +++ src/ddns/providers.py (date 1577472902318) >> @@ -1,4 +1,4 @@ >> -#!/usr/bin/python >> +#!/usr/bin/python3 >> #################################################################### >> ########### >> # >> # >> # ddns - A dynamic DNS client for IPFire >> # >> @@ -23,10 +23,12 @@ >> import logging >> import os >> import subprocess >> -import urllib2 >> +import urllib.request >> +import urllib.error >> +import urllib.parse >> import xml.dom.minidom >> >> -from i18n import _ >> +from .i18n import _ >> >> # Import all possible exception types. >> from .errors import * >> @@ -36,12 +38,14 @@ >> >> _providers = {} >> >> + >> def get(): >> """ >> Returns a dict with all automatically registered >> providers. >> """ >> return _providers.copy() >> >> + >> class DDNSProvider(object): >> # A short string that uniquely identifies >> # this provider. >> @@ -84,7 +88,7 @@ >> if not all((provider.handle, provider.name, >> provider.website)): >> raise DDNSError(_("Provider is not >> properly configured")) >> >> - assert not _providers.has_key(provider.handle), >> \ >> + assert provider.handle not in _providers, \ >> "Provider '%s' has already been >> registered" % provider.handle >> >> _providers[provider.handle] = provider >> @@ -109,7 +113,7 @@ >> return "" % (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 > _______________________________________________ > ddns mailing list > ddns(a)lists.ipfire.org > https://lists.ipfire.org/mailman/listinfo/ddns