File: addr_default_web.py

package info (click to toggle)
ddupdate 0.7.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 420 kB
  • sloc: python: 1,899; sh: 38; makefile: 35
file content (59 lines) | stat: -rw-r--r-- 1,751 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"""
ddupdate plugin to retrieve address as seen from internet.

See: ddupdate(8)
"""

import urllib.request
import re

from ddupdate.ddplugin import AddressPlugin, AddressError, IpAddr


_URLS = [
    'http://checkip.dyndns.org/',
    'https://api.ipify.org?format=json',
    'https://ifconfig.co'
]


class DefaultWebPlugin(AddressPlugin):
    """
    Get the external address as seen from the web.

    Relies on urls defined in _URLS, trying each in turn when running
    into trouble.

    Options used: none
    """

    _name = 'default-web-ip'
    _oneliner = 'Obtain external address as seen from the net'

    def get_ip(self, log, options):
        """Implement AddressPlugin.get_ip()."""
        def check_url(url):
            """Get reply from host and decode."""
            log.debug('trying ' + url)
            try:
                with urllib.request.urlopen(url) as response:
                    html = response.read().decode('utf-8')
            except (urllib.error.HTTPError, urllib.error.URLError):
                log.debug("Bad response at %s (ignored)" % url)
                return None
            log.debug("Got response: %s", html)
            pat = re.compile(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
            match = pat.search(html)
            if match:
                return html[match.start(): match.end()]
            log.debug("Cannot parse address reply")
            return None

        for ix, url in enumerate(_URLS):
            ip = check_url(url)
            if ip:
                return IpAddr(ip)
            if ix + 1 < len(_URLS):
                log.info("Falling back to %s", _URLS[ix + 1])
        raise AddressError(
            "Cannot obtain ip address (%s, %s and %s tried)" % tuple(_URLS))