raise DDNSUpdateError(_("Server response: %s") % output)
+class DDNSResponseParserXML(object):
+ """
+ This class provides a parser for XML responses which
+ 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.
+ xmldoc = xml.dom.minidom.parseString(document)
+
+ # Get XML elements by the given content.
+ element = xmldoc.getElementsByTagName(content)
+
+ # If no element has been found, we directly can return None.
+ if not element:
+ return None
+
+ # Only get the first child from an element, even there are more than one.
+ firstchild = element[0].firstChild
+
+ # Get the value of the child.
+ value = firstchild.nodeValue
+
+ # Return the value.
+ return value
+
+
class DDNSProviderAllInkl(DDNSProvider):
handle = "all-inkl.com"
name = "All-inkl.com"
url = "http://api.cp.easydns.com/dyn/tomato.php"
+class DDNSProviderEnomCom(DDNSResponseParserXML, DDNSProvider):
+ handle = "enom.com"
+ name = "eNom Inc."
+ website = "http://www.enom.com/"
+
+ # There are very detailed information about how to send an update request and
+ # the respone codes.
+ # http://www.enom.com/APICommandCatalog/
+
+ url = "https://dynamic.name-services.com/interface.asp"
+
+ def update(self):
+ data = {
+ "command" : "setdnshost",
+ "responsetype" : "xml",
+ "address" : self.get_address("ipv4"),
+ "domainpassword" : self.password,
+ "zone" : self.hostname
+ }
+
+ # Send update to the server.
+ response = self.send_request(self.url, data=data)
+
+ # Get the full response message.
+ output = response.read()
+
+ # Handle success messages.
+ if self.get_xml_tag_value(output, "ErrCount") == "0":
+ return
+
+ # Handle error codes.
+ errorcode = self.get_xml_tag_value(output, "ResponseNumber")
+
+ if errorcode == "304155":
+ raise DDNSAuthenticationError
+ elif errorcode == "304153":
+ raise DDNSRequestError(_("Domain not found."))
+
+ # If we got here, some other update error happened.
+ raise DDNSUpdateError
+
+
+class DDNSProviderEntryDNS(DDNSProvider):
+ handle = "entrydns.net"
+ name = "EntryDNS"
+ website = "http://entrydns.net/"
+ protocols = ("ipv4",)
+
+ # Some very tiny details about their so called "Simple API" can be found
+ # here: https://entrydns.net/help
+ url = "https://entrydns.net/records/modify"
+
+ def update(self):
+ data = {
+ "ip" : self.get_address("ipv4")
+ }
+
+ # Add auth token to the update url.
+ url = "%s/%s" % (self.url, self.token)
+
+ # Send update to the server.
+ try:
+ response = self.send_request(url, method="PUT", data=data)
+
+ # Handle error codes
+ except urllib2.HTTPError, e:
+ if e.code == 404:
+ raise DDNSAuthenticationError
+
+ elif e.code == 422:
+ raise DDNSRequestError(_("An invalid IP address was submitted"))
+
+ raise
+
+ # Handle success messages.
+ if response.code == 200:
+ return
+
+ # If we got here, some other update error happened.
+ raise DDNSUpdateError
+
+
class DDNSProviderFreeDNSAfraidOrg(DDNSProvider):
handle = "freedns.afraid.org"
name = "freedns.afraid.org"
raise DDNSUpdateError
-class DDNSProviderNamecheap(DDNSProvider):
+class DDNSProviderNamecheap(DDNSResponseParserXML, DDNSProvider):
handle = "namecheap.com"
name = "Namecheap"
website = "http://namecheap.com"
url = "https://dynamicdns.park-your-domain.com/update"
- def parse_xml(self, document, content):
- # Send input to the parser.
- xmldoc = xml.dom.minidom.parseString(document)
-
- # Get XML elements by the given content.
- element = xmldoc.getElementsByTagName(content)
-
- # If no element has been found, we directly can return None.
- if not element:
- return None
-
- # Only get the first child from an element, even there are more than one.
- firstchild = element[0].firstChild
-
- # Get the value of the child.
- value = firstchild.nodeValue
-
- # Return the value.
- return value
-
def update(self):
# Namecheap requires the hostname splitted into a host and domain part.
host, domain = self.hostname.split(".", 1)
output = response.read()
# Handle success messages.
- if self.parse_xml(output, "IP") == self.get_address("ipv4"):
+ if self.get_xml_tag_value(output, "IP") == self.get_address("ipv4"):
return
# Handle error codes.
- errorcode = self.parse_xml(output, "ResponseNumber")
+ errorcode = self.get_xml_tag_value(output, "ResponseNumber")
if errorcode == "304156":
raise DDNSAuthenticationError
return data
+class DDNSProviderNsupdateINFO(DDNSProtocolDynDNS2, DDNSProvider):
+ handle = "nsupdate.info"
+ name = "nsupdate.info"
+ website = "http://www.nsupdate.info/"
+ protocols = ("ipv6", "ipv4",)
+
+ # Information about the format of the HTTP request can be found
+ # after login on the provider user intrface and here:
+ # http://nsupdateinfo.readthedocs.org/en/latest/user.html
+
+ # Nsupdate.info uses the hostname as user part for the HTTP basic auth,
+ # and for the password a so called secret.
+ @property
+ def username(self):
+ return self.get("hostname")
+
+ @property
+ def password(self):
+ return self.get("secret")
+
+ @property
+ def proto(self):
+ return self.get("proto")
+
+ @property
+ def url(self):
+ # The update URL is different by the used protocol.
+ if self.proto == "ipv4":
+ return "https://ipv4.nsupdate.info/nic/update"
+ elif self.proto == "ipv6":
+ return "https://ipv6.nsupdate.info/nic/update"
+ else:
+ raise DDNSUpdateError(_("Invalid protocol has been given"))
+
+ def _prepare_request_data(self):
+ data = {
+ "myip" : self.get_address(self.proto),
+ }
+
+ return data
+
+
class DDNSProviderOVH(DDNSProtocolDynDNS2, DDNSProvider):
handle = "ovh.com"
name = "OVH"