"
msg = _("Do you want to enable the following "
"software channel: '%s'?") % channel
self._get_dialog('', summary, msg,
buttons=KDialog.Yes | KDialog.No)
webview = QWebView()
webview.setHtml(channel_info_html)
webview.setFixedSize(400,200)
self.d.vlayout_right.addWidget(webview)
res = self.dialog.exec_()
if res != KDialog.Accepted:
return False
return True
def doEnableSection(self, sections):
cmd = ["kdesudo",
"--",
"software-properties-kde",
"--enable-component", "%s" % ' '.join(sections)]
try:
output = subprocess.check_output(
cmd,
stdout=subprocess.PIPE,
universal_newlines=True)
except (OSError, subprocess.CalledProcessError) as e:
print("Execution failed: %s" % e, file=sys.stderr)
return True
# FIXME: Very ugly, but kdesudo doesn't return the correct exit states
print(output)
if not output.startswith("Enabled the "):
return False
return True
def doEnableChannel(self, channelpath, channelkey):
cmd = ["kdesudo",
"--",
"install", "--mode=644","--owner=0",channelpath,
apt_pkg.Config.FindDir("Dir::Etc::sourceparts")]
res = subprocess.call(cmd, universal_newlines=True)
if res != 0:
return False
# install the key as well
if os.path.exists(channelkey):
cmd = ["kdesudo",
"--",
"apt-key", "add",channelkey]
res = subprocess.call(cmd, universal_newlines=True)
if res != 0:
return False
return True
def askInstallPackage(self, package, summary, description, homepage):
header = "
" + _("Install additional software?") + "
"
body = _("Do you want to install package '%s'?") % package
self.d.header_label.setText(header)
self.d.body_label.setText(body)
self.dialog.setButtons(KDialog.ButtonCode(KDialog.Yes | KDialog.No))
res = self.dialog.exec_()
if res != KDialog.Accepted:
return False
return True
# progress etc
def doUpdate(self):
subprocess.check_call([
'qapt-batch',
'--attach', str(self.dialog.winId()),
'--update'
],
universal_newlines=True)
def doInstall(self, apturl):
subprocess.check_call([
'qapt-batch',
'--attach', str(self.dialog.winId()),
'--install',
apturl.package
],
universal_newlines=True)
if __name__ == "__main__":
ui = KdeUI()
ui.error("foo","bar")
# kate: space-indent on; indent-width 4; mixedindent off; indent-mode python;
apturl-0.5.2ubuntu4/AptUrl/kde/__init__.py 0000664 0000000 0000000 00000000000 12252035543 015316 0 ustar apturl-0.5.2ubuntu4/AptUrl/AptUrl.py 0000664 0000000 0000000 00000021313 12252035561 014235 0 ustar # Copyright (c) 2007-2008 Canonical
#
# AUTHOR:
# Michael Vogt
# With contributions by Siegfried-A. Gevatter
#
# This file is part of AptUrl
#
# AptUrl 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.
#
# AptUrl 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 AptUrl; 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 aptsources.distro
from . import Parser
from . import Helpers
from .Helpers import _
from aptsources.sourceslist import SourcesList
from optparse import OptionParser
import os
import os.path
# adding new repositories is currently disabled because some people have
# security concerns about this feature
allow_new_repositories = False
# channels that we know about
channelsdir = "/usr/share/app-install/channels"
# return codes
(RESULT_OK,
RESULT_CANCELT,
RESULT_ERROR,
RESULT_BADARGS) = list(range(4))
class AptUrlController(object):
def __init__(self, ui):
self.ui = ui
def enableSection(self, apturl):
# parse sources.list
sourceslist = SourcesList()
distro = aptsources.distro.get_distro()
distro.get_sources(sourceslist)
# check if we actually need to enable anything
requested_components = []
for component in apturl.section:
if not component in distro.enabled_comps:
requested_components.append(component)
# if not, we are fine
if not requested_components:
return RESULT_OK
# otherwise ask the user if the really wants to anble them
if not self.ui.askEnableSections(apturl.section):
return RESULT_CANCELT
if not self.ui.doEnableSection(apturl.section):
self.ui.error(_("Enabling '%s' failed") %
", ".join(apturl.section))
return RESULT_ERROR
self.ui.doUpdate()
self.openCache()
return RESULT_OK
def enableChannel(self, apturl):
# ensure that no funny path tricks can be played
# by e.g. passing "apt:foo?channel=../../"
channel = os.path.basename(apturl.channel)
channelpath = "%s/%s.list" % (channelsdir,channel)
channelkey = "%s/%s.key" % (channelsdir,channel)
channelhtml = "%s/%s.eula" % (channelsdir,channel)
# check
if not os.path.exists(channelpath):
self.ui.error(_("Unknown channel '%s'") % channel,
_("The channel '%s' is not known") % channel)
return RESULT_ERROR
channel_info_html = ""
if os.path.exists(channelhtml):
channel_info_html = open(channelhtml).read()
if not self.ui.askEnableChannel(apturl.channel, channel_info_html):
return RESULT_CANCELT
if not self.ui.doEnableChannel(channelpath, channelkey):
self.ui.error(_("Enabling channel '%s' failed") % apturl.channel)
return RESULT_ERROR
self.ui.doUpdate()
self.openCache()
return RESULT_OK
def openCache(self):
try:
self.cache = apt.Cache()
except SystemError as strerr:
if not '/etc/apt/sources.list' in str(strerr):
raise
self.ui.error(_("Invalid /etc/apt/sources.list file"), strerr)
return False
if self.cache._depcache.broken_count > 0:
err_header = _("Software index is broken")
err_body = _("This is a major failure of your software "
"management system. Please check for broken packages "
"with synaptic, check the file permissions and "
"correctness of the file '/etc/apt/sources.list' and "
"reload the software information with: "
"'sudo apt-get update' and 'sudo apt-get install -f'."
)
self.ui.error(err_header, err_body)
return False
return True
def parseArgs(self):
parser = OptionParser()
parser.add_option("-p", "--http-proxy", dest="http_proxy",
default=None, help="use http proxy")
(options, args) = parser.parse_args()
# eval and add proxy
if options.http_proxy is not None:
proxy = options.http_proxy
if not ":" in proxy:
proxy += ":3128"
os.environ["http_proxy"] = "http://%s" % proxy
# parse
try:
apturl_list = Parser.parse(args[0])
except IndexError as e:
self.ui.error(_("Need a url to continue, exiting"))
return []
except Parser.InvalidUrlException as e:
self.ui.error(_("Invalid url: '%s' given, exiting") % e.url,
str(e))
return []
return (apturl_list)
def verifyInstall(self, apturl):
" verify that the install package actually is installed "
# check if the package got actually installed
self.openCache()
pkg = self.cache[apturl.package]
if (not pkg.is_installed or
pkg._pkg.current_state != apt_pkg.CURSTATE_INSTALLED or
self.cache._depcache.broken_count > 0):
return False
return True
def main(self):
# global return code
ret = RESULT_OK
ui = self.ui
# parse arguments
apturl_list = self.parseArgs()
if not apturl_list:
return RESULT_BADARGS
# open cache
if not self.openCache():
return RESULT_ERROR
# now go over the url list
for apturl in apturl_list:
# FIXME: move this code block into a func like
# evalAptUrl()
if not apturl.schema in ("apt", "apt+http"):
self.ui.error(_("Can not deal with protocol '%s' ")
% apturl.schema)
continue
if apturl.section:
if self.enableSection(apturl) != RESULT_OK:
continue
elif apturl.channel:
if self.enableChannel(apturl) != RESULT_OK:
continue
elif apturl.refresh is not None:
ui.doUpdate()
if not self.openCache():
return RESULT_ERROR
# now check the package
if apturl.package not in self.cache:
try:
package_in_cache = bool(self.cache._cache[apturl.package])
except KeyError:
package_in_cache = False
if package_in_cache:
ui.error(_("Package '%s' is virtual.") % apturl.package)
continue
else:
ui.error(_("Could not find package '%s'.")
% apturl.package)
continue
if (self.cache[apturl.package].is_installed and
apturl.minver is None):
ui.message(_("Package '%s' is already installed")
% apturl.package)
continue
# ask the user
pkg = self.cache[apturl.package]
(sum, desc, homepage) = Helpers.parse_pkg(pkg)
if not ui.askInstallPackage(apturl.package, sum, desc, homepage):
ret = RESULT_CANCELT
continue
# try to install it
try:
self.cache[apturl.package].mark_install()
except SystemError as e:
ui.error(_("Can not install '%s' (%s) ") % (apturl.package, e))
continue
if apturl.minver is not None:
verStr = self.cache[apturl.package].candidate.version
if apt_pkg.version_compare(verStr, apturl.minver) < 1:
ui.error(_(
"Package '%s' requests minimal version '%s', but "
"only '%s' is available") % (apturl.package,
apturl.minver,
verStr))
continue
# install it
ui.doInstall(apturl)
if not self.verifyInstall(apturl):
ret = RESULT_ERROR
# return values
return ret
apturl-0.5.2ubuntu4/AptUrl/Helpers.py 0000664 0000000 0000000 00000004043 12252035543 014431 0 ustar # Copyright (c) 2008 Canonical
#
# AUTHOR:
# Siegfried-A. Gevatter
#
# This file is part of AptUrl
#
# AptUrl 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.
#
# AptUrl 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 AptUrl; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import gettext
import subprocess
def _(str):
return utf8(gettext.gettext(str))
def _n(singular, plural, n):
return utf8(gettext.ngettext(singular, plural, n))
def utf8(str):
if str is bytes:
try:
return str.decode('UTF-8')
except UnicodeDecodeError:
# assume latin1 as fallback
return str.decode('latin1')
else:
return str
def get_dist():
return subprocess.check_output(
'lsb_release -c -s'.split(),
universal_newlines=True).strip()
def parse_pkg(pkgobj):
summary = ""
description = ""
pkg_description = pkgobj.candidate.description
if pkg_description.count("\n") > 0:
summary, description = pkg_description.split('\n', 1)
else:
summary = pkg_description
lines = description.rstrip('\n').split('\n')
if len(lines) > 1 and lines[-1].startswith('Homepage: '):
homepage = lines[-1].split(' ', 1)[1]
description = '\n'.join(lines[:-1])
else:
homepage = pkgobj.candidate.homepage
return (summary, description, homepage)
def format_description(description):
const = 'APTURL_DOUBLE_EMPTY_LINE_PLACEHOLDER'
return description.replace('\n\n', const).replace('\n', ' ').replace(
const, '\n\n')
apturl-0.5.2ubuntu4/AptUrl/gtk/ 0000775 0000000 0000000 00000000000 12252036013 013232 5 ustar apturl-0.5.2ubuntu4/AptUrl/gtk/GtkUI.py 0000664 0000000 0000000 00000016070 12252035543 014602 0 ustar from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GObject
GObject.threads_init()
import os
import sys
import apt_pkg
import subprocess
from AptUrl.UI import AbstractUI
from AptUrl import Helpers
from AptUrl.Helpers import _
from .backend import get_backend
APTURL_UI_FILE = os.environ.get(
# Set this envar to use a test .ui file.
'APTURL_UI_FILE',
# System file to use if the envar is not set.
'/usr/share/apturl/apturl-gtk.ui'
)
class GtkUI(AbstractUI):
def __init__(self):
Gtk.init_check(sys.argv)
# create empty dialog
self.dia_xml = Gtk.Builder()
self.dia_xml.set_translation_domain("apturl")
self.dia_xml.add_from_file(APTURL_UI_FILE)
self.dia = self.dia_xml.get_object('confirmation_dialog')
self.dia.start_available = lambda: Gtk.main_quit()
self.dia.start_error = lambda: Gtk.main_quit()
self.dia.exit = lambda: Gtk.main_quit()
self.dia.realize()
self.backend = get_backend(self.dia)
def _action_done(self, backend, action, authorized, success, err_str, err_desc):
self.dia.set_sensitive(True)
Gtk.main_quit()
# generic dialogs
def _get_dialog(self, dialog_type, summary, msg="",
buttons=Gtk.ButtonsType.CLOSE):
" internal helper for dialog construction "
d = Gtk.MessageDialog(parent=self.dia,
flags=Gtk.DialogFlags.MODAL,
type=dialog_type,
buttons=buttons)
d.set_title("")
d.set_markup("%s\n\n%s" % (summary, msg))
d.set_icon(Gtk.IconTheme.get_default().load_icon('deb', 16, False))
d.set_keep_above(True)
d.realize()
d.get_window().set_functions(Gdk.WMFunction.MOVE)
return d
def error(self, summary, msg=""):
d = self._get_dialog(Gtk.MessageType.ERROR, summary, msg)
d.run()
d.destroy()
return False
def message(self, summary, msg="", title=""):
d = self._get_dialog(Gtk.MessageType.INFO, summary, msg)
d.set_title(title)
d.run()
d.destroy()
return True
def yesNoQuestion(self, summary, msg, title="", default='no'):
d = self._get_dialog(Gtk.MessageType.QUESTION, summary, msg,
buttons=Gtk.ButtonsType.YES_NO)
d.set_title(title)
res = d.run()
d.destroy()
if res != Gtk.ResponseType.YES:
return False
return True
# specific dialogs
def askEnableChannel(self, channel, channel_info_html):
summary = _("Enable additional software channel")
msg = _("Do you want to enable the following "
"software channel: '%s'?") % channel
d = self._get_dialog(Gtk.MessageType.QUESTION, summary, msg,
buttons=Gtk.ButtonsType.YES_NO)
if channel_info_html:
try:
from gi.repository import WebKit
v=WebKit.WebView()
v.load_string(channel_info_html, "text/html", "utf-8", "file:/")
sw = Gtk.ScrolledWindow()
sw.add(v)
d.get_content_area().pack_start(sw, True, True, 0)
sw.set_size_request(400, 200)
sw.show_all()
except ImportError:
pass
res = d.run()
d.destroy()
if res != Gtk.ResponseType.YES:
return False
return True
def doEnableSection(self, sections):
cmd = ["gksu", "--desktop",
"/usr/share/applications/software-properties.desktop",
"--",
"software-properties-gtk",
"-e", "%s" % ' '.join(sections)]
try:
output = subprocess.communicate(
cmd,
stdout=subprocess.PIPE,
universal_newlines=True)
except (OSError, subprocess.CalledProcessError) as e:
print("Execution failed: %s" % e, file=sys.stderr)
return True
#FIXME: Very ugly, but gksu doesn't return the correct exit states
if not output.startswith("Enabled the "):
return False
return True
def doEnableChannel(self, channelpath, channelkey):
cmd = ["gksu",
"--desktop",
"/usr/share/applications/gnome-app-install.desktop",
"--",
"install", "--mode=644","--owner=0",channelpath,
apt_pkg.Config.FindDir("Dir::Etc::sourceparts")]
res = subprocess.call(cmd, universal_newlines=True)
if res != 0:
return False
# install the key as well
if os.path.exists(channelkey):
cmd = ["gksu",
"--desktop",
"/usr/share/applications/gnome-app-install.desktop",
"--",
"apt-key", "add",channelkey]
res = subprocess.call(cmd, universal_newlines=True)
if res != 0:
return False
return True
def askInstallPackage(self, package, summary, description, homepage):
# populate the dialog
dia = self.dia
dia_xml = self.dia_xml
header = _("Install additional software?")
body = _("Do you want to install package '%s'?") % package
dia.set_keep_above(True)
dia.set_title('')
header_label = dia_xml.get_object('header_label')
header_label.set_markup("%s" % header)
body_label = dia_xml.get_object('body_label')
body_label.set_label(body)
description_text_view = dia_xml.get_object('description_text_view')
tbuf = Gtk.TextBuffer()
desc = "%s\n\n%s" % (summary, Helpers.format_description(description))
tbuf.set_text(desc)
description_text_view.set_buffer(tbuf)
dia.set_icon(Gtk.IconTheme.get_default().load_icon('deb', 16, False))
# check if another package manager is already running
# FIXME: just checking for the existance of the file is
# not sufficient, it need to be tested if it can
# be locked via apt_pkg.get_lock()
# - but that needs to run as root
# - a dbus helper might be the best answer here
#args = (update_button_status, dia_xml.get_object("yes_button"),
# dia_xml.get_object("infolabel"))
#args[0](*args[1:])
#timer_id = GObject.timeout_add(750, *args )
# show the dialog
res = dia.run()
#GObject.source_remove(timer_id)
if res != Gtk.ResponseType.YES:
dia.hide()
return False
# don't set on-top while installing
dia.set_keep_above(False)
return True
# progress etc
def doUpdate(self):
self.backend.update()
self.dia.set_sensitive(False)
Gtk.main()
def doInstall(self, apturl):
self.backend.commit([apturl.package], [], False)
self.dia.set_sensitive(False)
Gtk.main()
if __name__ == "__main__":
ui = GtkUI()
ui.error("foo","bar")
apturl-0.5.2ubuntu4/AptUrl/gtk/__init__.py 0000664 0000000 0000000 00000000000 12252035543 015340 0 ustar apturl-0.5.2ubuntu4/AptUrl/gtk/backend/ 0000775 0000000 0000000 00000000000 12252036013 014621 5 ustar apturl-0.5.2ubuntu4/AptUrl/gtk/backend/InstallBackendAptdaemon.py 0000664 0000000 0000000 00000006147 12252035543 021721 0 ustar #!/usr/bin/env python
# -*- coding: utf-8 -*-
# (c) 2005-2009 Canonical, GPL
from aptdaemon import client, errors
from defer import inline_callbacks
from aptdaemon.gtk3widgets import AptProgressDialog
from aptdaemon.enums import EXIT_SUCCESS
from UpdateManager.backend import InstallBackend
from UpdateManager.UnitySupport import UnitySupport
import apt_pkg
import dbus
class InstallBackendAptdaemon(InstallBackend):
"""Makes use of aptdaemon to refresh the cache and to install updates."""
def __init__(self, window_main):
# Pass None for datadir because of LP: #1026257
InstallBackend.__init__(self, window_main, self.ACTION_INSTALL)
self.client = client.AptClient()
self.unity = UnitySupport()
@inline_callbacks
def update(self):
"""Refresh the package list"""
try:
apt_pkg.pkgsystem_unlock()
except SystemError:
pass
try:
trans = yield self.client.update_cache(defer=True)
yield self._run_in_dialog(trans, self.UPDATE)
except errors.NotAuthorizedError as e:
self._action_done(self.UPDATE, False, False, str(e), None)
except:
self.action_done(self.UPDATE, True, False, None, None)
raise
@inline_callbacks
def commit(self, pkgs_install, pkgs_upgrade, close_on_done):
"""Commit a list of package adds and removes"""
try:
apt_pkg.pkgsystem_unlock()
except SystemError:
pass
try:
reinstall = remove = purge = downgrade = []
trans = yield self.client.commit_packages(
pkgs_install, reinstall, remove, purge, pkgs_upgrade,
downgrade, defer=True)
trans.connect("progress-changed", self._on_progress_changed)
yield self._run_in_dialog(trans, self.ACTION_INSTALL)
except errors.NotAuthorizedError as e:
self._action_done(self.ACTION_INSTALL, False, False, str(e), None)
except dbus.DBusException as e:
if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":
raise
self._action_done(self.ACTION_INSTALL, False, False, None, None)
except Exception as e:
self._action_done(self.ACTION_INSTALL, True, False, None, None)
raise
def _on_progress_changed(self, trans, progress):
#print("_on_progress_changed", progress)
self.unity.set_progress(progress)
@inline_callbacks
def _run_in_dialog(self, trans, action):
dia = AptProgressDialog(trans, parent=self.window_main)
dia.set_icon_name("update-manager")
dia.connect("finished", self._on_finished, action)
yield dia.run()
def _on_finished(self, dialog, action):
dialog.hide()
# tell unity to hide the progress again
self.unity.set_progress(-1)
self._action_done(action,
True, dialog._transaction.exit == EXIT_SUCCESS, None, None)
if __name__ == "__main__":
b = InstallBackendAptdaemon(None)
b.commit(["2vcard"], [], False)
from gi.repository import Gtk
Gtk.main()
apturl-0.5.2ubuntu4/AptUrl/gtk/backend/InstallBackendSynaptic.py 0000664 0000000 0000000 00000004763 12252035543 021605 0 ustar #!/usr/bin/env python
# -*- coding: utf-8 -*-
# (c) 2005-2007 Canonical, GPL
import apt_pkg
import os
import tempfile
from gettext import gettext as _
from gi.repository import GObject
from UpdateManager.backend import InstallBackend
class InstallBackendSynaptic(InstallBackend):
""" Install backend based on synaptic """
def _run_synaptic(self, action, opt, tempf):
"""Execute synaptic."""
try:
apt_pkg.pkgsystem_unlock()
except SystemError:
pass
cmd = ["/usr/bin/gksu",
"--desktop", "/usr/share/applications/update-manager.desktop",
"--", "/usr/sbin/synaptic", "--hide-main-window",
"--non-interactive", "--parent-window-id",
"%s" % self.window_main.window.xid ]
cmd.extend(opt)
flags = GObject.SPAWN_DO_NOT_REAP_CHILD
(pid, stdin, stdout, stderr) = GObject.spawn_async(cmd, flags=flags)
# Keep a reference to the data tuple passed to
# GObject.child_watch_add to avoid attempts to destroy it without a
# thread context: https://bugs.launchpad.net/bugs/724687
self.child_data = (action, tempf)
GObject.child_watch_add(pid, self._on_synaptic_exit, self.child_data)
def _on_synaptic_exit(self, pid, condition, data):
action, tempf = data
if tempf:
tempf.close()
self.emit("action-done", action, True, os.WEXITSTATUS(condition) == 0, None, None)
def update(self):
opt = ["--update-at-startup"]
tempf = None
self._run_synaptic(self.UPDATE, opt, tempf)
def commit(self, pkgs_install, pkgs_upgrade, close_on_done):
# close when update was successful (its ok to use a Synaptic::
# option here, it will not get auto-saved, because synaptic does
# not save options in non-interactive mode)
opt = []
if close_on_done:
opt.append("-o")
opt.append("Synaptic::closeZvt=true")
# custom progress strings
opt.append("--progress-str")
opt.append("%s" % _("Please wait, this can take some time."))
opt.append("--finish-str")
opt.append("%s" % _("Update is complete"))
tempf = tempfile.NamedTemporaryFile(mode="w+")
for pkg_name in pkgs_install + pkgs_upgrade:
tempf.write("%s\tinstall\n" % pkg_name)
opt.append("--set-selections-file")
opt.append("%s" % tempf.name)
tempf.flush()
self._run_synaptic(self.INSTALL, opt, tempf)
apturl-0.5.2ubuntu4/AptUrl/gtk/backend/__init__.py 0000664 0000000 0000000 00000003256 12252035543 016747 0 ustar #!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Integration of package managers into UpdateManager"""
# (c) 2005-2009 Canonical, GPL
import os
import os.path
from gi.repository import GObject
class InstallBackend(GObject.GObject):
"""The abstract backend that can install/remove packages"""
(INSTALL, UPDATE) = range(2)
def __init__(self, window_main):
"""init backend
takes a gtk main window as parameter
"""
GObject.GObject.__init__(self)
self.window_main = window_main
def commit(self, pkgs_install, pkgs_upgrade, close_on_done):
"""Commit the cache changes """
raise NotImplemented
def update(self):
"""Run a update to refresh the package list"""
raise NotImplemented
def get_backend(*args, **kwargs):
"""Select and return a package manager backend."""
# try aptdaemon
if (os.path.exists("/usr/sbin/aptd") and
not "UPDATE_MANAGER_FORCE_BACKEND_SYNAPTIC" in os.environ):
# check if the gtkwidgets are installed as well
try:
from .InstallBackendAptdaemon import InstallBackendAptdaemon
return InstallBackendAptdaemon(*args, **kwargs)
except ImportError:
import logging
logging.exception("importing aptdaemon")
# try synaptic
if (os.path.exists("/usr/sbin/synaptic") and
not "UPDATE_MANAGER_FORCE_BACKEND_APTDAEMON" in os.environ):
from .InstallBackendSynaptic import InstallBackendSynaptic
return InstallBackendSynaptic(*args, **kwargs)
# nothing found, raise
raise Exception("No working backend found, please try installing "
"synaptic or aptdaemon")
apturl-0.5.2ubuntu4/AptUrl/__init__.py 0000664 0000000 0000000 00000000000 12252035543 014553 0 ustar apturl-0.5.2ubuntu4/AptUrl/Parser.py 0000664 0000000 0000000 00000012165 12252035543 014267 0 ustar # Copyright (c) 2007-2008 Canonical
#
# AUTHOR:
# Michael Vogt
# With contributions by Siegfried-A. Gevatter
#
# This file is part of AptUrl
#
# AptUrl 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.
#
# AptUrl 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 AptUrl; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import os
import string
from string import Template
from .Helpers import get_dist
from .Helpers import _
class InvalidUrlException(Exception):
def __init__(self, url, msg=""):
self.url = url
self.message = msg
def __str__(self):
return self.message
MAX_URL_LEN=255
# substituion mapping
apturl_substitution_mapping = {
"distro" : get_dist(),
"kernel" : os.uname()[2]
}
# whitelist for the uri
whitelist = []
whitelist.extend(string.ascii_letters)
whitelist.extend(string.digits)
whitelist.extend(['_',':','?','/','+','.','~','=','<','>','-',',','$','&'])
class AptUrl(object):
" a class that contains the parsed data from an apt url "
def __init__(self):
self.package = None
self.schema = None
self.minver = None
self.refresh = None
# for added repos
self.keyfile = None
self.repo_url = None
self.dist = '/'
# for known sections
self.section = []
# for known channels
self.channel = None
def is_format_package_name(string):
" return True if string would be an acceptable name for a Debian package "
return (string.replace("+", "").replace("-", "").replace(".", "").replace(":", "").isalnum()
and string.islower() and string[0].isalnum() and len(string) > 1)
def do_apt_url_substitution(apt_url, mapping):
" substitute known templates against the field package and channel "
for field in ["package","channel"]:
if getattr(apt_url, field):
s=Template(getattr(apt_url, field))
setattr(apt_url, field, s.substitute(mapping))
def match_against_whitelist(raw_url):
" test if the url matches the internal whitelist "
for char in raw_url:
if not char in whitelist:
raise InvalidUrlException(
raw_url, _("Non whitelist char in the uri"))
return True
def set_value(apt_url, s):
" set a key,value pair from string s to AptUrl object "
(key, value) = s.split("=")
try:
if ' ' in value:
raise InvalidUrlException(apt_url, _("Whitespace in key=value"))
if type(getattr(apt_url, key)) == type([]):
getattr(apt_url, key).append(value)
else:
setattr(apt_url, key, value)
except Exception as e:
raise InvalidUrlException(apt_url, _("Exception '%s'") % e)
def parse(full_url, mapping=apturl_substitution_mapping):
" parse an apt url and return a list of AptUrl objects "
# apt:pkg1?k11=v11?k12=v12,pkg2?k21=v21?k22=v22,...
res = []
if len(full_url) > MAX_URL_LEN:
url = "%s ..." % full_url[0:(MAX_URL_LEN // 10)]
raise InvalidUrlException(url, _("Url string '%s' too long") % url)
# check against whitelist
match_against_whitelist(full_url)
for url in full_url.split(";"):
if not ":" in url:
raise InvalidUrlException(url, _("No ':' in the uri"))
# now parse it
(schema, packages) = url.split(":", 1)
packages = packages.split(",")
for package in packages:
apt_url = AptUrl()
apt_url.schema = schema
# check for schemas of the form: apt+http://
if schema.startswith("apt+"):
apt_url.repo_url = schema[len("apt+"):] + ":" + package.split("?",1)[0]
else:
if "?" in package:
apt_url.package = package.split("?")[0].lstrip("/")
else:
apt_url.package = package.lstrip("/")
# now parse the ?... bits
if "?" in package:
key_value_pairs = package.split("?")[1:]
for s in key_value_pairs:
if "&" in s:
and_key_value_pairs = s.split("&")
for s in and_key_value_pairs:
set_value(apt_url, s)
else:
set_value(apt_url, s)
# do substitution (if needed)
do_apt_url_substitution(apt_url, mapping)
# check if the package name is valid
if not is_format_package_name(apt_url.package):
raise InvalidUrlException(url, "Invalid package name '%s'" % apt_url.package)
res.append(apt_url)
return res
apturl-0.5.2ubuntu4/AptUrl/UI.py 0000664 0000000 0000000 00000003224 12252035543 013344 0 ustar
from .Helpers import _, _n
class AbstractUI(object):
# generic dialogs
def error(self, summary, msg):
return False
def yesNoQuestion(self, summary, msg, title, default='no'):
pass
def message(self, summary, msg):
return True
# specific dialogs
def askEnableSections(self, sections):
" generic implementation, can be overridden "
return self.yesNoQuestion(_("Enable additional components"),
_n("Do you want to enable the following "
"component: '%s'?",
"Do you want to enable the following "
"components: '%s'?",
len(sections)) % ", ".join(sections))
def askEnableChannel(self, channel, channel_info_html):
" generic implementation, can be overridden "
return self.yesNoQuestion(_("Enable additional software channel"),
_("Do you want to enable the following "
"software channel: '%s'?") % channel)
def askInstallPackage(self):
pass
# install/update progress
def doUpdate(self):
pass
def doInstall(self, pkglist):
pass
# UI specific actions for enabling stuff
# FIXME: the next two functions shoud go into generic code
# that checks for the availablility of tools
# like gksu or kdesudo and uses them
# appropriately
def doEnableSection(self, sections):
pass
def doEnableChannel(self, channelpath, channelkey):
pass
apturl-0.5.2ubuntu4/apturl-gtk 0000775 0000000 0000000 00000003010 12252035543 013257 0 ustar #!/usr/bin/python3
#
# Copyright (c) 2007-2008 Canonical
#
# AUTHOR:
# Michael Vogt
# With contributions by Siegfried-A. Gevatter
#
# This file is part of AptUrl
#
# AptUrl 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.
#
# AptUrl 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 AptUrl; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# ignore apt's "API not stable yet" warning
import warnings
warnings.filterwarnings("ignore", category=FutureWarning, append=1)
import sys
import gettext
from gettext import gettext as _
from AptUrl.AptUrl import AptUrlController, RESULT_CANCELT
from AptUrl.gtk.GtkUI import GtkUI
if __name__ == "__main__":
localesApp="apturl"
localesDir="/usr/share/locale"
gettext.bindtextdomain(localesApp, localesDir)
gettext.textdomain(localesApp)
ui = GtkUI()
apturl = AptUrlController(ui)
try:
sys.exit(apturl.main())
except KeyboardInterrupt:
print(_("User requested interrupt."))
sys.exit(RESULT_CANCELT)