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