# Copyright (c) 2005-2009 Canonical Ltd
#
# AUTHOR:
# Michael Vogt <mvo@ubuntu.com>
#
# This file is part of GDebi
#
# GDebi is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# GDebi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GDebi; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
import apt
import apt_pkg
import logging
import os
import sys
from gettext import gettext as _
from re import findall
from subprocess import PIPE, Popen, call
from apt.cache import Cache
from .DebPackage import DebPackage, DscSrcPackage
class GDebiCli(object):
def __init__(self, options):
# fixme, do graphic cache check
self.options = options
if options.quiet:
tp = apt.progress.base.OpProgress()
else:
tp = apt.progress.text.OpProgress()
# set architecture to architecture in root-dir
if options.rootdir and os.path.exists(options.rootdir+"/usr/bin/dpkg"):
arch = Popen([options.rootdir+"/usr/bin/dpkg",
"--print-architecture"],
stdout=PIPE,
universal_newlines=True).communicate()[0]
if arch:
apt_pkg.config.set("APT::Architecture",arch.strip())
if options.apt_opts:
for o in options.apt_opts:
if o.find('=') < 0:
sys.stderr.write(_("Configuration items must be specified with a =<value>\n"))
sys.exit(1)
(name, value) = o.split('=', 1)
try:
apt_pkg.config.set(name, value)
except:
sys.stderr.write(_("Couldn't set APT option %s to %s\n") % (name, value))
sys.exit(1)
self._cache = Cache(tp, rootdir=options.rootdir)
def open(self, file):
try:
if (file.endswith(".deb") or
"Debian binary package" in Popen(["file", file], stdout=PIPE, universal_newlines=True).communicate()[0]):
self._deb = DebPackage(file, self._cache)
elif (file.endswith(".dsc") or
os.path.basename(file) == "control"):
self._deb = DscSrcPackage(file, self._cache)
else:
sys.stderr.write(_("Unknown package type '%s', exiting\n") % file)
sys.exit(1)
except (IOError,SystemError,ValueError) as e:
logging.debug("error opening: %s" % e)
sys.stderr.write(_("Failed to open the software package\n"))
sys.stderr.write(_("The package might be corrupted or you are not "
"allowed to open the file. Check the permissions "
"of the file.\n"))
sys.exit(1)
# check the deps
if not self._deb.check():
sys.stderr.write(_("This package is uninstallable\n"))
sys.stderr.write(self._deb._failure_string + "\n")
return False
return True
def show_description(self):
try:
print(self._deb["Description"])
except KeyError:
print(_("No description is available"))
def show_dependencies(self):
print(self.get_dependencies_info())
def get_dependencies_info(self):
s = ""
# show what changes
(install, remove, unauthenticated) = self._deb.required_changes
if len(unauthenticated) > 0:
s += _("The following packages are UNAUTHENTICATED: ")
for pkgname in unauthenticated:
s += pkgname + " "
if len(remove) > 0:
s += _("Requires the REMOVAL of the following packages: ")
for pkgname in remove:
s += pkgname + " "
s += "\n"
if len(install) > 0:
s += _("Requires the installation of the following packages: ")
for pkgname in install:
s += pkgname + " "
s += "\n"
return s
def install(self):
# install the dependecnies
(install,remove,unauthenticated) = self._deb.required_changes
if len(install) > 0 or len(remove) > 0:
fprogress = apt.progress.text.AcquireProgress()
iprogress = apt.progress.base.InstallProgress()
try:
self._cache.commit(fprogress,iprogress)
except(apt.cache.FetchFailedException, SystemError) as e:
sys.stderr.write(_("Error during install: '%s'") % e)
return 1
# install the package itself
if self._deb.filename.endswith(".dsc"):
# FIXME: add option to only install build-dependencies
# (or build+install the deb) and then enable
# this code
#dir = self._deb.pkgname + "-" + apt_pkg.UpstreamVersion(self._deb["Version"])
#os.system("dpkg-source -x %s" % self._deb.filename)
#os.system("cd %s && dpkg-buildpackage -b -uc" % dir)
#for i in self._deb.binaries:
# os.system("gdebi %s_%s_*.deb" % (i,self._deb["Version"]))
return 0
else:
return call(["dpkg","--auto-deconfigure", "-i",self._deb.filename])
if __name__ == "__main__":
app = GDebiCli()
if not app.open(sys.argv[1]):
sys.exit(1)
msg = _("Do you want to install the software package? [y/N]:")
print(msg,)
sys.stdout.flush()
res = sys.stdin.readline()
try:
c = findall("[[(](\S+)/\S+[])]", msg)[0].lower()
except IndexError:
c = "y"
if res.lower().startswith(c):
sys.exit(app.install())