#!/usr/bin/python
"""
    Tool for building some afrihost specific packages

    Copyright  Afrihost.com (PTY) Ltd 2008
    Original file by: Ed Pascoe <ed@pascoe.co.za>
"""
__author__  = "Ed Pascoe <ed@pascoe.co.za>"
__credits__ = "Afrihost.com -- The best webhosting. Ever."

import urllib2,os,sys,os.path
import csv
import optparse
import tarfile

#['nrpe', '2.12', 'nagios/nrpe/nrpe-2.12.tar.gz', 'builds/std.sh']
class  Afribuild:
    base="https://svn.afrihost.com/source/"
    packages={}
    def __init__(self):
        try:
            fh=urllib2.urlopen(self.base+'version.list')
        except:
            fh=os.popen("curl -k '%s'" % self.base+'version.list','r')
        reader=csv.reader(fh)
        for row in reader:
            if not row: continue
            if row[0][0]=='#': continue
            if len(row) < 4: continue
            self.packages[row[0]]=row[1:]
        fh.close()
    def list(self):
        """List all packages their version and the software url"""
        for p in self.packages.keys():
            data=self.packages[p]
            print "%-20s %-10s %s" % (p,data[0],data[1])
    def versionExpand(self,version):
        """Generates a version number as a large int to make comparing easy
           Eg: 1.2.3 is returned as 100020003
        """
        total=0
        try:parts= version.split('.')
        except AttributeError: return int(version) #No dots in the version
        mult=10000 ** (len(parts) -1)
        for p in parts:
            total=total+(int(p) * mult)
            mult=mult / 10000
        return total
    def versionGet(self,software):
        """Return the latest available version of the software"""
        #print "Looking for",software
        #print self.packages[software]
        return self.packages[software][0]
    def buildshellDownload(self,software):
        """Downloads the correct program for the build then makes it executable
           so it can be run directly by os.system. Returns the name of the program 
        """
        shellurl=self.packages[software][2]
        shellurl=self.urlExpand(shellurl)
        sname=os.path.basename(shellurl) #So we know what to call this file
        try:
            fh=urllib2.urlopen(shellurl)
        except:
            fh=os.popen("curl -k '%s'" % shellurl,'r')
            #print "Could not open",shellurl
            #raise
        f=file(sname,"w")
        f.write(fh.read())
        fh.close()
        f.close()
        os.chmod(sname,0755) #Make executable So its easy to execute directly
        return sname
    def urlExpand(self,url):
        """Makes sure the url is not relative"""
        if url.find("://")==-1:
            url=self.base + url
        return url
    def upgrade(self,software):
        """Upgrade software"""
        try:
            print "Installing/upgrading '%s'" % (software)
            try: os.mkdir(os.environ['HOME']+"/build")
            except: pass
            os.chdir(os.environ['HOME']+"/build")
            url=self.urlExpand(self.packages[software][1])
            tfname=os.path.basename(url)
            print "Downloading from"+url+" to "+tfname

            fh=urllib2.urlopen(url)
            f=file(tfname,"w")
            f.write(fh.read())
            f.close()
            fh.close()

        except:
            os.system("curl -k -o '%s' '%s'" % (tfname,url))
        if tfname.find("gz") > -1: 
            rflag="r:gz"
            cmd="tar -xzvf"
        elif tfname.find("bz2") > -1: 
            rflag="r:bz2"
            cmd="tar -xjvf"
        else: #Assume no compression, just a plain tar file
            rflag="r"
            cmd="tar -xf"
        tfh=tarfile.open(tfname,rflag)
        for tarinfo in tfh:
            directory=tarinfo.name #The first entry in the tar file is the directory we are looking for
            break
            print tarinfo.name
        tfh.close()
        if os.path.exists(directory):
            os.system("rm -rf '%s' > /dev/null 2> /dev/null" % (directory))
        os.system("%s '%s'" % (cmd,tfname))
        os.chdir(directory)
        buildtool=self.buildshellDownload(software)
        os.system("./%s" % (buildtool))

if __name__=='__main__':
    usage="Usage: %prog [<options>] packages " +"\n"+__doc__+"\n"
    parser=optparse.OptionParser(usage)
    parser.add_option("--list", "-l",  dest="list", action="store_true",default=0, help="List all available software and their versions")
    parser.add_option("--version", "-v",  dest="version", default=-1,type="string", help="Version of the current software")
    parser.add_option("--upgrade", "-u",  dest="package", type="string", help="upgrade to latest version of the software")
    (options,args) = parser.parse_args()

    ab=Afribuild()
    if options.version and options.package:
        if ab.versionExpand(options.version) < ab.versionExpand(ab.versionGet(options.package)):
            ab.upgrade(options.package)
    if options.list:
        ab.list()
            
        
