#!/usr/bin/env python import getopt import sys import os import subprocess slaptget = '/usr/sbin/slapt-get' slaptsrc = '/usr/bin/slapt-src' # create a copy of the default environment initial_env = dict() class Colours: RED = '\033[01;31m' GREEN = '\033[01;32m' RESET = '\033[00m' def disable(self): self.RED = '' self.GREEN = '' self.RESET = '' colour = Colours() def main(argv): try: opts, args = getopt.getopt(argv, "nhuUis", ["no-colour", "help", "update", "upgrade" , "install", "search", "simulate"]) action = "search" for opt, arg in opts: if opt in ("-n", "--no-colour"): colour.disable() elif opt in ("-h", "--help"): usage() sys.exit(0) elif opt in ("-u", "--update"): check_for_root() retval = update() sys.exit(retval) elif opt in ("-U", "--upgrade"): check_for_root() retval = upgrade() sys.exit(retval) elif opt in ("-i", "--install"): check_for_root() action = "simulate" elif opt in ("-S", "--simulate"): action = "simulate" elif opt in ("-s", "--search"): pass if not len(args) > 0: usage() sys.exit(0) if action == "install": install(args) if action == "simulate": simulate(args) elif action == "search": search(args) except getopt.GetoptError: usage() sys.exit(1) def check_for_root(): if os.geteuid() != 0: print "This action requires root priviliges." sys.exit(1) def string_red(string): return colour.RED+string+colour.RESET def string_green(string): return colour.GREEN+string+colour.RESET def pkg_installed(): pkg_installed = [] for i in os.listdir('/var/log/packages'): pkg_installed.append(i.rpartition('-')[0].rpartition('-')[0].rpartition('-')[0]) return pkg_installed def pkglist(args): cmd = [slaptget, '--search'] for arg in args: cmd.append(arg) env = dict() for i in initial_env: env[i] = initial_env[i] env['LANG'] = 'C' p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) pkglist_output = p.communicate()[0] status = p.returncode pkglist_output = pkglist_output.splitlines() pkgs = [] pkgnames = [] for line in pkglist_output: pkgfullname = line.partition('[inst=')[0] pkgshortname = pkgfullname.rpartition('-')[0].rpartition('-')[0].rpartition('-')[0] if pkgshortname not in pkgnames: pkgnames.append(pkgshortname) if pkgshortname in pkg_installed(): pkginst = True else: pkginst = False pkgdesc = line.partition(']: ')[2] pkgs.append([pkgshortname, pkginst, pkgdesc]) return pkgs def slackbuildlist(args): cmd = [slaptsrc, '--search'] for arg in args: cmd.append(arg) env = dict() for i in initial_env: env[i] = initial_env[i] env['LANG'] = 'C' p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) pkglist_output = p.communicate()[0] status = p.returncode pkglist_output = pkglist_output.splitlines() pkgs = [] pkgnames = [] for line in pkglist_output: pkgfullname = line.partition(' - ')[0] pkgshortname = pkgfullname.rpartition(':')[0] if pkgshortname not in pkgnames: pkgnames.append(pkgshortname) if pkgshortname in pkg_installed(): pkginst = True else: pkginst = False pkgdesc = line.partition(' - ')[2] pkgs.append([pkgshortname, pkginst, pkgdesc]) return pkgs def search(args): print "Available packages:" pl = pkglist(args) if pl == []: print "None" else: for i in pl: pkgname, pkginst, pkgdesc = i[0], i[1], i[2] if pkginst is True: pkginst = string_green('Installed') else: pkginst = string_red('Not installed') print pkgname+' ['+pkginst+']:', pkgdesc print "\nAvailable SlackBuilds:" sl = slackbuildlist(args) if sl == []: print "None" else: for i in sl: pkgname, pkginst, pkgdesc = i[0], i[1], i[2] if pkginst is True: pkginst = string_green('Installed') else: pkginst = string_red('Not installed') print pkgname+' ['+pkginst+']:', pkgdesc def checkrepos (args, slapt, src, unmet): pl = pkglist(args) sl = slackbuildlist(args) p = [] for i in pl: if i not in slapt: p.append(i[0]) s = [] for i in sl: if i not in src: s.append(i[0]) for arg in args: if arg not in pkg_installed() and arg in p: deps = slaptgetdeps(arg) # parse output of slapt-get -s slapt.append(arg) slapt.extend(deps) elif arg not in pkg_installed() and arg in s: deps = slaptsrcdeps(arg) src.append(arg) foo, depslapt, depsrc, missing = checkrepos(deps, [], [], []) for dep in depslapt: if dep not in slapt: slapt.append(dep) src.extend(depsrc) unmet.extend(missing) elif arg not in pkg_installed(): unmet.append(arg) return args, slapt, src, unmet def simulate(args): apps, slapt, src, unmet = checkrepos(args, [], [], []) if unmet != []: print 'The following dependencies are unavailable ', for i in unmet: print i, print sys.exit(1) if slapt != []: print 'The following packages will be installed from Salix repos: ', for i in slapt: print i, print if src != []: print 'The following packages will be built from source: ', for i in src: print i, print def slaptgetdeps(arg): return ['foo', 'bar'] def install(args): pl = pkglist(args) sl = slackbuildlist(args) p = [] for i in pl: p.append(i[0]) s = [] for i in sl: s.append(i[0]) for arg in args: if arg not in pkg_installed(): if arg in p: installpkg(arg) elif arg in s: installsb(arg) else: print 'No such package or SlackBuild: '+arg sys.exit(1) def installpkg(pkg): p = subprocess.Popen([slaptget, '--no-prompt', '--install', pkg]) retval = p.wait() if retval != 0: sys.exit(retval) def installsb(slackbuild): deps = slaptsrcdeps(slackbuild) if deps != []: install(deps) p = subprocess.Popen([slaptsrc, '--no-dep', '--yes', '--install', slackbuild]) retval = p.wait() if retval != 0: sys.exit(retval) def update(): print "Updating package cache..." p = subprocess.Popen([slaptget, '--update']) retval = p.wait() if retval == 0: print "\nUpdating SlackBuild cache..." p = subprocess.Popen([slaptsrc, '--update']) retval = p.wait() return retval def upgrade(): p = subprocess.Popen([slaptget, '--upgrade']) retval = p.wait() return retval def slaptsrcdeps(pkg): deps = [] DEVNULL = open('/dev/null', 'w') args = [slaptsrc, '--show', pkg] env = dict() for i in initial_env: env[i] = initial_env[i] env['LANG'] = 'C' p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=DEVNULL, env=env) output = p.communicate()[0] data = '' for line in output.splitlines(): if line.startswith('SlackBuild Requires:'): data = line.partition(':')[2] newdeps = data.replace('\n', ',').strip(' ').split(',') for i in newdeps: if i is not '' and i != '%README%': if i not in deps: deps.append(i) DEVNULL.close() return deps def usage(): print 'USAGE:', os.path.basename(sys.argv[0]),'[OPTIONS] [STRING(s)]' print print 'OPTIONS:' print ' -u, --update ','update package and SlackBuild caches' print ' -U, --upgrade ','upgrade packages' print ' -s, --search ','search for specified packages (default action)' print ' -i, --install ','install specified packages' print ' -n, --no-colour ','disable colour output' print ' -h, --help ','this help message' if __name__ == "__main__": try: main(sys.argv[1:]) except KeyboardInterrupt: sys.exit(2)