get IP

#!/usr/bin/env python2
from __future__ import print_function
"""

use as

sudo -u tor tor
torsocks python2 ipgetter.py


for anon use lawl


This module is designed to fetch your external IP address from the internet.
It is used mostly when behind a NAT.
It picks your IP randomly from a serverlist to minimize request overhead on a single server

API Usage
=========

    >>> import ipgetter
    >>> myip = ipgetter.myip()
    >>> myip
    '8.8.8.8'

    >>> ipgetter.IPgetter().test()

    Number of servers: 47
    IP's :
    8.8.8.8 = 47 ocurrencies

"""

import                re     , sys
import                random ,  socket

from threading  import Timer
from sys        import version_info
import   future.moves.urllib.request
urllib = future.moves.urllib.request
PY3K   = version_info >= (3, 0)
__version__            = "0.6"


def myip():
    return IPgetter().get_external_ip()


class IPgetter(object):

    """
    This class is designed to fetch your external IP address from the internet.
    It is used mostly when behind a NAT.
    It picks your IP randomly from a serverlist to minimize request overhead    on a single server
    """

    def __init__(self):
        print("\n\n The full test of 45 servers takes 1 minute to see through.   ", end='')
        sys.stdout.write(" ~ ") #       print( " - " ) # print(e)
        sys.stdout.flush()


        self.server_list = ['http://checkip.dyndns.com/',
                            'http://checkip.dyndns.org/plain',
                            'http://checkmyip.com/',
                            'http://checkmyip.net/',
                            'http://formyip.com/',
                            'http://getmyipaddress.org/',
                            'http://httpbin.org/ip',
                            'http://icanhazip.com/',
                            'http://ifconfig.me/ip',
                            'http://ip-lookup.net/',
                            'http://ip.dnsexit.com',
                            'http://ip.my-proxy.com/',
                            'http://ipecho.net/plain',
                            'http://ipgoat.com/',
                            'http://ipinfo.io/',
                            'http://ipogre.com/linux.php',
                            'http://myexternalip.com/',
                            'http://myexternalip.com/raw',
                            'http://websiteipaddress.com/WhatIsMyIp',
                            'http://whatismyipaddress.com/',
                            'http://whatsmyip.net/',
                            'http://wtfismyip.com/',
                            'http://www.bobborst.com/tools/whatsmyip/',
                            'http://www.canyouseeme.org/',
                            'http://www.displaymyip.com/',
                            'http://www.dslreports.com/whois',
                            'http://www.findmyip.co/',
                            'http://www.geoiptool.com/',
                            'http://www.howtofindmyipaddress.com/',
                            'http://www.infosniper.net/',
                            'http://www.ip-adress.com/',
                            'http://www.ip-adress.eu/',
                            'http://www.ipchicken.com/',
                            'http://www.iplocation.net/',
                            'http://www.lawrencegoetz.com/programs/ipinfo/',
                            'http://www.mon-ip.com/en/my-ip/',
                            'http://www.my-ip-address.net/',
                            'http://www.myip.ru',
                            'http://www.myipnumber.com/my-ip-address.asp',
                            'http://www.tracemyip.org/',
                            'http://www.trackip.net/',
                            'http://www.whatsmyipaddress.net/',
                            'https://check.torproject.org/',
                            'https://www.privateinternetaccess.com/pages/whats-my-ip/'  ,
                            'https://www.whatsmydns.net/whats-my-ip-address.html'       ]

        self.timeout = 1.6
        self.url = None

    def get_external_ip(self):
        """
        This function gets your IP from a random server
        """

        random.shuffle(self.server_list)
        myip = ''
        for server in self.server_list[:3]:
            myip = self.fetch(server)
            if myip != '':
                return myip
            else:
                continue
        return ''

    def handle_timeout(self, url):
        if self.url is not None:
            self.url.close()
            self.url = None

    def fetch(self, server):
        """
        This function gets your IP from a specific server
        """
        t = None
        socket_default_timeout = socket.getdefaulttimeout()
        opener                 = urllib.build_opener()
        opener.addheaders = [('User-agent',  "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0")]

        try:            # Close url resource if fetching not finished within timeout.
            t = Timer(self.timeout, self.handle_timeout, [self.url])
            t.start()

            # Open URL.
            if version_info[0:2] == (2, 5):
                # Support for Python 2.5.* using socket hack
                # (Changes global socket timeout.)
                socket.setdefaulttimeout(self.timeout)
                self.url = opener.open(server)
            else:
                self.url = opener.open(server, timeout=self.timeout)

            # Read response.
            content = self.url.read()

            # Didn't want to import chardet. Prefered to stick to stdlib
            if PY3K:
                try:
                    content = content.decode('UTF-8')
                except UnicodeDecodeError:
                    content = content.decode('ISO-8859-1')

            p  = '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.('
            p += '25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|['
            p += '01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
            m  = re.search(                p,                content)
            myip = m.group(0)
            if len(myip) > 0:                return myip
            else:                            return ''
        except Exception as e:
            sys.stdout.write(" ~ ") #       print( " - " ) # print(e)
            sys.stdout.flush()
            return ''
        finally:
            if  self.url is not None:
                self.url.close()
                self.url =      None
            if  t        is not None:                t.cancel()

            # Reset default socket timeout.
            if  socket.getdefaulttimeout() != socket_default_timeout:
                socket.setdefaulttimeout(     socket_default_timeout)

    def test(self):
        """
        This functions tests the consistency of the servers
        on the list when retrieving your IP.
        All results should be the same.
        """

        resultdict = {}
        for server in self.server_list:
            resultdict.update(**{server: self.fetch(server)})

        ips     = sorted(resultdict.values())
        ips_set = set(ips)

        print()
        print('Number of servers: {}'.format(len(self.server_list)) , " of which "   )
        print()

        for ip, ocorrencia in zip(ips_set, map(lambda x: ips.count(x), ips_set)):
            print('{0} = {1} occurranc{2}'.format(ip if len(ip) > 0 else 'broken server', ocorrencia, 'y' if ocorrencia == 1 else 'es'))

        print('\n')
        print(resultdict)

if __name__ == '__main__':
    #print(myip())
    e  = IPgetter()
    e.test()
    #e    = IPgetter().test()