Initial commit.
[ddns.git] / ddns / system.py
1 #!/usr/bin/python
2
3 import re
4 import urllib2
5
6 from __version__ import CLIENT_VERSION
7 from i18n import _
8
9 # Initialize the logger.
10 import logging
11 logger = logging.getLogger("ddns.system")
12 logger.propagate = 1
13
14 class DDNSSystem(object):
15         """
16                 The DDNSSystem class adds a layer of abstraction
17                 between the ddns software and the system.
18         """
19
20         # The default useragent.
21         USER_AGENT = "IPFireDDNSUpdater/%s" % CLIENT_VERSION
22
23         def __init__(self, core):
24                 # Connection to the core of the program.
25                 self.core = core
26
27         @property
28         def proxy(self):
29                 proxy = self.core.settings.get("proxy")
30
31                 # Strip http:// at the beginning.
32                 if proxy.startswith("http://"):
33                         proxy = proxy[7:]
34
35                 return proxy
36
37         def guess_external_ipv4_address(self):
38                 """
39                         Sends a request to the internet to determine
40                         the public IP address.
41
42                         XXX does not work for IPv6.
43                 """
44                 response = self.send_request("http://checkip.dyndns.org/")
45
46                 if response.code == 200:
47                         match = re.search(r"Current IP Address: (\d+.\d+.\d+.\d+)", response.read())
48                         if match is None:
49                                 return
50
51                         return match.group(1)
52
53         def send_request(self, url, data=None, timeout=30):
54                 logger.debug("Sending request: %s" % url)
55                 if data:
56                         logger.debug("  data: %s" % data)
57
58                 req = urllib2.Request(url, data=data)
59
60                 # Set the user agent.
61                 req.add_header("User-Agent", self.USER_AGENT)
62
63                 # All requests should not be cached anywhere.
64                 req.add_header("Pragma", "no-cache")
65
66                 # Set the upstream proxy if needed.
67                 if self.proxy:
68                         logger.debug("Using proxy: %s" % self.proxy)
69
70                         # Configure the proxy for this request.
71                         req.set_proxy(self.proxy, "http")
72
73                 logger.debug(_("Request header:"))
74                 for k, v in req.headers.items():
75                         logger.debug("  %s: %s" % (k, v))
76
77                 try:
78                         resp = urllib2.urlopen(req)
79
80                         # Log response header.
81                         logger.debug(_("Response header:"))
82                         for k, v in resp.info().items():
83                                 logger.debug("  %s: %s" % (k, v))
84
85                         # Return the entire response object.
86                         return resp
87
88                 except urllib2.URLError, e:
89                         raise
90
91         def get_address(self, proto):
92                 assert proto in ("ipv6", "ipv4")
93
94                 if proto == "ipv4":
95                         # Check if the external IP address should be guessed from
96                         # a remote server.
97                         guess_ip = self.core.settings.get("guess_external_ip", "")
98
99                         # If the external IP address should be used, we just do
100                         # that.
101                         if guess_ip in ("true", "yes", "1"):
102                                 return self.guess_external_ipv4_address()
103
104                 # XXX TODO
105                 assert False