#!/usr/bin/python

import urllib, httplib
import sys
import re

# Usage: kgrab [-g] [-c] kernel_version

#    -g: retrieve tar.gz files instead of tar.bz2
#    -c: grab changelog only

#    Example: kgrab -g 2.6.10

MIRRORS = ['al','ad','ao','aq','ar','aw','au','az','ax','at','bs','bb','by',
           'be','bz','bm','bo','ba','bv','br','bm','bg','ca','cv','kl','cl',
           'cn','cx','co','cr','hr','cy','cz','dk','dm','do','ec','sv','ee',
           'fk','fo','fj','fi','fr','gf','de','gi','gr','gl','gp','gt','gd',
           'gy','ht','hn','hk','hu','is','in','id','ie','it','jp','kz','kr',
           'kw','kq','lv','li','lt','lu','mk','my','mt','mq','mx','md','mc',
           'mm','nl','nz','ni','no','pk','pa','py','pe','ph','pl','pt','pr',
           'ro','ru','pm','vc','sm','cs','sg','sk','si','es','sj','sz','se',
           'ch','tw','th','tt','tr','tm','tc','ua','ae','uk','us','uy','va',
           've','vn','vg','vi','eh']

def getIpAddress():
    try:
        ip = re.findall('[0-9.]+', urllib.urlopen('http://checkip.dyndns.org/').read())[-1]
    except:
        ip = '127.0.0.1'
    return ip

def getLocalMirror(mirrors):
    try:
        import GeoIP, socket
        ip = getIpAddress()
        gi = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE)   # Boilerplate from         
        cc = gi.country_code_by_addr(ip).lower()   # http://www.maxmind.com/app/python  
        root = '.kernel.org/pub/linux/kernel/'
        if cc in mirrors:
            url_root = 'http://www.%s%s' % (cc, root)
            print 'Local mirror %s found' % (url_root.split('/')[2])
        else:
            url_root = "http://www.kernel.org/pub/linux/kernel/"
            print "No local mirror found"
        return url_root
    except ImportError:
        url_root = "http://www.kernel.org/pub/linux/kernel/"
        print "GeoIP not installed"
        return url_root

def version(file):
    version = [(None), ("v1.0/", "v1.1/", "v1.2/", "v1.3/"), 
               ("v2.0/", "v2.1/", "v2.2/", "v2.3/", "v2.4/", "v2.5/", "v2.6/")]
    kversion = sys.argv[-1].split(".")
    d = version[int(kversion[0])][int(kversion[1])] + file + sys.argv[-1]
    return d

def fmt(n, suffix = 'B', places = 3):
    ''' human-readable; this function was lifted from the Python mailing list'''
    prefixes = ['', 'K', 'M']
    top = 10 ** places
    index = 0
    n = float(n)
    while abs(n) > top:
          n /= 1024
          index += 1
    return '%.1f %s%s' % (n, prefixes[index], suffix)

def info(bt, bs, ts):
    ct = bt * bs
    percent = float(ct) / float(ts)
    percent_dec = str(float(ct) / float(ts))
    percent_str = percent_dec[2:4] + "." + percent_dec[4:6]
    message = "Downloaded %s of a total %s. %s%% complete." % (fmt(ct), fmt(ts), percent_str)
    sys.stdout.write(message)
    sys.stdout.flush()
    sys.stdout.write("\b" * len(message))
    sys.stdout.flush()

def checkStatus(url):
    site = url.split('/')[2]
    res = '/' + "/".join(["%s" % (k) for k in list(url.split('/')[3:])])
    check = httplib.HTTPConnection(site)
    check.request("GET", res)
    response = check.getresponse()
    if response.status == 404:
        print "404: %s not found on %s" % (res, site) 
        sys.exit(2)
    else:
        print "Downloading %s" % (url)
        check.close()
        return url
    
def getfile(url):
    url = checkStatus(url)
    localfile = str(url.split("/")[-1])
    try:
        x = urllib.urlretrieve(url, localfile, info)
        print
        print "%s downloaded successfully" % (x[0])
    except:
        print "urllib error"
        sys.exit(1)

def main():
    url_root = getLocalMirror(MIRRORS)
    if "-g" in sys.argv:
        suffix = ".tar.gz"
    else:
        suffix = ".tar.bz2"
    if "-c" in sys.argv:
        d = version("ChangeLog-")
        suffix = ""
    else:
        d = version("linux-")
    url = url_root + d + suffix
    x = getfile(url)

if __name__ == '__main__':
    main()

# kgrab.py version 0.2 copyright 2005 Darren Kirby