#!/usr/bin/python 
# -*- python -*- 

############################################################################### 
# 
# Name:     package-updater 
# Version:  0.4 
# Author:   Dax Bunce 
# Date:     27 April 2005 
# Purpose:  To build new binary backages as a result of security vulnerablities 
#           or packages dropping out of portage. 
# 
# History:  27 April 2005 initial version 
#           Parts of code ripped from glsa-check, binpkgmain and 
#           the 14th of Feb newsletter: 
#           http://www.gentoo.org/news/en/gwn/20050214-newsletter.xml#doc_chap8 
# 
############################################################################### 
import os,string,sys,portage,re 
sys.path.insert(0, "/usr/lib/gentoolkit/pym") 
sys.path.insert(0, "/usr/lib/portage/pym") 
from output import * 
from glsa import * 
settings = portage.config() 

pretend = 0 
upgrade_packages = [] 

#Check for security upgrades. 
def security(): 
    print (red("Security, upgrade to these versions:")) 
    # build glsa lists 
    glsaconfig = checkconfig(portage.config(clone=portage.settings)) 
    completelist = get_glsa_list(glsaconfig["GLSA_DIR"], glsaconfig) 
    if os.access(glsaconfig["CHECKFILE"], os.R_OK): 
        checklist = [line.strip() for line in open(glsaconfig["CHECKFILE"], "r").readlines()] 
    else: 
        checklist = [] 
    todolist = [e for e in completelist if e not in checklist] 

    for myid in todolist: 
        try: 
            myglsa = Glsa(myid, glsaconfig) 
        except GlsaTypeException, e: 
            if verbose: 
                print "invalid GLSA: %s (error message was: %s)" % (myid, e) 
            continue 

        mergelist = myglsa.getMergeList() 

        for pkg in mergelist: 
            if not upgrade_packages.count(pkg): 
                print (blue(pkg)) 
                answer = ask() 
                if answer == "y": 
                    upgrade_packages.append(pkg) 

#Check for packages in portage that have upgrades available 
def obsolete(): 
    ignore = removed(1) 
    print (red("Obsolete packages:")) 
    obsolete = [x for x in portage.db["/"]["vartree"].getallcpv() if len(portage.portdb.xmatch("match-all","="+x))==0] 
    portdb = portage.portdbapi(settings["PORTDIR"]) 
    for pkg in obsolete: 
        if not ignore.count(pkg) or upgrade_packages.count(pkg): 
            pkg_nover = re.match('(.*)-\d+',pkg) 
            rec_upgrade = portdb.xmatch("bestmatch-visible", pkg_nover.group(1)) 
            print(blue("Upgrade "+pkg+" to "+rec_upgrade)) 
            answer = ask() 
            if answer == "y": 
                upgrade_packages.append(rec_upgrade) 

#Check for packages no longer in portage 
def removed(quiet): 
    output = [] 
    if not quiet: 
        print (red("Removed, these require manual intervention")) 
    removed = [x for x in portage.db["/"]["vartree"].getallcpv() if len(portage.portdb.xmatch("match-all",portage.pkgsplit(x)[0]))==0] 
    for pkg in  removed: 
        output.append(pkg) 
        if not quiet: 
            print (yellow(pkg)) 
    return output 

def upgrade(): 
    security() 
    obsolete()    
    emerge_list = '' 
    for pkg in upgrade_packages: 
        if pkg: 
            emerge_list = emerge_list + " =" + pkg 
    if pretend: 
        print (green("Pretend only")) 
        removed(0) 
        print "emerge -b "+emerge_list 
    else: 
        print(green("Emerging "+emerge_list)) 
        print(blue("All output in emerge_log")) 
        removed(0) 
        print(red("This may take a very long time.....")) 
        #os.system("/usr/bin/emerge -b %s >> emerge_log 2>&1"%(emerge_list)) 
        for package in upgrade_packages: 
            if pkg: 
                try: 
                    print(blue("Emerging "+package)) 
                    os.system("/usr/bin/emerge -b =%s >> emerge_log 2>&1"%(package)) 
                except: 
                    print(red("Error emerging "+package)) 
        print(yellow("Complete, check emerge_log for errors and post messages")) 
def ask(): 
    response=raw_input("[y]: ") 
    if string.upper(response) == "Y" or response == "": 
        return 'y' 
    return 'n' 

#Start the script 
upgrade() 

