diff options
author | 2022-06-20 13:36:09 +0200 | |
---|---|---|
committer | 2023-08-03 15:30:24 +0600 | |
commit | 6797ff836182c0727c71ee07e08bafc31f5b56e6 (patch) | |
tree | 6429de09c97acd6e188e75e4048b0b9baf2c8f0a /AptUrl | |
download | apturl-6797ff836182c0727c71ee07e08bafc31f5b56e6.tar.gz apturl-6797ff836182c0727c71ee07e08bafc31f5b56e6.zip |
Import Debian version 0.5.2+linuxmint13
apturl (0.5.2+linuxmint13) vanessa; urgency=medium
.
* bump - rebuild using XZ compression
.
apturl (0.5.2+linuxmint12) vanessa; urgency=medium
.
* Depend on mint-common
.
apturl (0.5.2+linuxmint11) ulyana; urgency=medium
.
* UI: Fix underlined label
.
apturl (0.5.2+linuxmint10) ulyana; urgency=medium
.
[ gogogogi ]
* Update hr.po (#5)
.
[ Michael Webster ]
* Fix dep resolution, improve initial query dialog (#4)
.
apturl (0.5.2+linuxmint9) ulyana; urgency=medium
.
* Switch from synaptic to mintcommon-aptdaemon backend
.
apturl (0.5.2+linuxmint8) ulyana; urgency=medium
.
* Fix refreshing cache
.
apturl (0.5.2+linuxmint7) tara; urgency=medium
.
* Fix xapp dependency
* Set dialog title
.
apturl (0.5.2+linuxmint6) tara; urgency=medium
.
* UI: don't skip taskbar, set icon properly
.
apturl (0.5.2+linuxmint5) sylvia; urgency=medium
.
[ monsta ]
* drop aptdaemon deps - not needed anymore (#2)
.
apturl (0.5.2+linuxmint4) serena; urgency=medium
.
[ gogogogi ]
* Fix po.hr
.
apturl (0.5.2+linuxmint3) sarah; urgency=medium
.
* Updated translations
.
apturl (0.5.2+linuxmint2) sarah; urgency=medium
.
* Remove channel/section support and dependencies on Ubuntu components and webkit
.
apturl (0.5.2+linuxmint1) sarah; urgency=medium
.
* Removed QT interface
* Remove backends (will be reimplemented without dependencies on Ubuntu components)
* Specify Gtk version in gi
* Implemented synaptics installations
.
apturl (0.5.2ubuntu11) xenial; urgency=medium
.
* Drop webkit1 support, we're switching to pure webkit2 now
.
apturl (0.5.2ubuntu10) xenial; urgency=medium
.
* debian/apturl.install:
- don't install the gconf schemas, it's probably useful to no one
nowadays (would only work for applications using the GNOME2 libgnome)
and creates a depends on gconf which we want to drop from the iso
.
apturl (0.5.2ubuntu9) wily; urgency=medium
.
* data/apturl-gtk.ui: set the dimension on the scrolledwindow rather
than the textview so the description is showing with a non zero height
.
apturl (0.5.2ubuntu8) wily; urgency=medium
.
* Use webkit2 in addition to webkit1. (LP: #1469221)
.
apturl (0.5.2ubuntu7) wily; urgency=medium
.
* Don't include Debian version in the python module version (LP: #1465549)
.
apturl (0.5.2ubuntu6) vivid; urgency=medium
.
[ Tim Lunn ]
* Don't use legacy icon names, these are no longer available in
adwaita-icon-theme. (LP: #1437150)
.
[ Iain Lane ]
* For dialog-question, go back to using the stock icon name as Humanity
doesn't yet have an icon with the new name.
.
apturl (0.5.2ubuntu5) vivid; urgency=medium
.
* Switch gnome-icon-theme to adwaita-icon-theme, which is its
successor. (LP: #1414613)
.
apturl (0.5.2ubuntu4) trusty; urgency=medium
.
* Drop libgtk2-perl Recommends to Suggests.
.
apturl (0.5.2ubuntu3) trusty; urgency=low
.
* AptUrl/AptUrl.py: don't use decode on a str (lp: #1050826)
.
apturl (0.5.2ubuntu2) saucy; urgency=low
.
* adjust backend to reuse the bits from update-manager (LP: #1200775)
.
apturl (0.5.2ubuntu1) raring; urgency=low
.
* AptUrl/gtk/backend/__init__.py: Drop "action-done" signal definition;
update-manager's GTK backend already defines it with different arguments,
so this is ineffective and confusing.
* AptUrl/gtk/GtkUI.py, _on_backend_done(): Add additional error signal
arguments, as defined by update-manager's backend.
* AptUrl/gtk/backend/InstallBackend{Aptdaemon,Synaptic}.py: Call action-done
signal with error arguments. (LP: #1103024)
* data/apturl-gtk.ui: Drop obsolete "has_separator" property. Fixes a
warning.
.
apturl (0.5.1ubuntu6) quantal; urgency=low
.
* AptUrl/gtk/backend/InstallBackendAptdaemon.py: Work around
incompatible Update Manager API change (as described in Launchpad
bug #1026257). LP: #1020980
.
apturl (0.5.1ubuntu5) quantal; urgency=low
.
* debian/control: Move python3-aptdaemon dependency to apturl binary
package (from apturl-common) since only the gtk backend needs it.
.
apturl (0.5.1ubuntu4) quantal; urgency=low
.
[ Brian Murray ]
* Port to Python 3:
- Use Python 3 style print functions
* AptUrl/Parser.py:
- ensure MAX_URL_LEN/10 returns an int
.
[ Colin Watson ]
* AptUrl/gtk/backend/InstallBackendSynaptic.py:
- Keep a reference to the data tuple passed to GObject.child_watch_add
to avoid attempts to destroy it without a thread context.
- Open temporary synaptic selections file in text mode.
.
[ Barry Warsaw ]
* Additional Python 3 fixes:
+ Port setup.py to Python 3.
+ Use the new python-apt API since the legacy API is not available in
Python 3.
+ ki18n() takes bytes.
+ Fix relative imports so the code can be run from source.
+ Fixed some additional packaging paths.
+ Change #! lines to use python3.
+ Changed debian/control and debian/rules to use python3.
+ Change debian/compat == 9
+ apturl now must require python3-aptdaemon.gtk3widgets (i.e. not |
synaptic) due to the Python 3 port of update-manager.
* Other changes:
+ Remove the need for threads in the KDE front-end.
+ Enable running the test suite via `python3 -m unittest discover`
+ i18n updates.
+ Various and sundry pyflakes, whitespace, style, line length, and
spelling fixes.
.
apturl (0.5.1ubuntu3) precise; urgency=low
.
* Take the unicode representation of the parser error message instead
of the string representation, so that we get clean i18n handling.
LP: #911144.
.
apturl (0.5.1ubuntu2) precise; urgency=low
.
* debian/control: Fix dependencies: python-gobject → python-gi.
.
apturl (0.5.1ubuntu1) oneiric-proposed; urgency=low
.
* add support for multiarch package names (LP: #872146)
.
apturl (0.5ubuntu1) oneiric; urgency=low
.
* port to gtk3, update dependencies
.
apturl (0.4.3ubuntu1) oneiric; urgency=low
.
* improve exception handling and shorten overly long strings
* add aptdaemon backend
* add dependencies to python-aptdaemon-gtk
.
apturl (0.4.2ubuntu5) natty; urgency=low
.
* debian/apturl-common.install:
- fix install file by removing no longer relevant
usr/share/omf (this fixes a FTBFS)
.
apturl (0.4.2ubuntu4) natty; urgency=low
.
* data/apturl.desktop:
- Add a desktop file to register mime type. LP: #698181
.
apturl (0.4.2ubuntu3) natty; urgency=low
.
* Don't hardcode python2.6 in the packaging.
* Build using dh_python2 instead of dh_pycentral.
.
apturl (0.4.2ubuntu2) natty; urgency=low
.
[ Harald Sitter ]
* Make apturl-kde explicity depend on python-qt4 and python-kde4
.
[ Colin Watson ]
* Make apturl recommend libgtk2-perl (>= 1:1.130) rather than
libgnome2-perl, matching debconf 1.5.36ubuntu3.
.
apturl (0.4.2ubuntu1) natty; urgency=low
.
* Switch from glade to GtkBuilder (LP: #403533)
.
apturl (0.4.1ubuntu7) maverick; urgency=low
.
* Fix KDE protocol files to enlist in the local protocol class
+ This makes KRunner in KDE SC 4.5 pick up apt:foo as call to apturl again
* Bump standards version to 3.9.1
* Switch to dpkg-source 3
* Switch all packages to arch:any rather than all
.
apturl (0.4.1ubuntu6) maverick; urgency=low
.
* Port apturl-kde to qapt-batch (LP: #497803)
* Replace the dependency on install-package with one on qapt-batch
.
apturl (0.4.1ubuntu5) maverick; urgency=low
.
* Fix LP: #576944 - Move the Firefox preferences to /etc/firefox
- update setup.py
- add debian/apturl-common.postinst
- add debian/apturl-common.preinst
* Don't install apturl.js in /usr/share/firerox - Firefox doesn't see this
- update debian/apturl-common.install
- update setup.py
* Add a couple of extra preferences for Firefox
- update data/apturl.js
.
apturl (0.4.1ubuntu4) lucid; urgency=low
.
* Drop python-gtkhtml2 recommends (moved to webkit).
.
apturl (0.4.1ubuntu3) lucid; urgency=low
.
* apturl.8:
- add example for the "channel" parameter
* AptUrl/gtk/GtkUI.py:
- use webkit instead of gtkhtml (ucid-duplicated-packages spec)
* debian/control:
- add python-webkit depend on debian/control
.
apturl (0.4.1ubuntu2) karmic; urgency=low
.
* Reupload merged 0.4.0ubuntu5 and 0.4.1ubuntu1, forgot to bzr push -.-
.
apturl (0.4.1ubuntu1) karmic; urgency=low
.
[ Harald Sitter ]
* Borrow encoding wrappers from GDebi to fix encodings in KDE UI
.
[ Michael Vogt ]
* AptUrl/gtk/GtkUI.py:
- Use software-properites to enable componenents
* debian/control:
- Remove dependency on gnome-app-install
- Add software-properties-gtk
.
apturl (0.4.0ubuntu5) karmic; urgency=low
.
* Borrow encoding wrappers from GDebi to fix encodings in KDE UI (implemented
via Helpers). These new wrappers utf8, _ and _n are used throughout the
whole application.
* Fix minor formatting error in KDE UI's _get_dialog
* link apturl's manpage to the apturl-gtk and apturl-kde manpages since
they share the same argument parser anyway
* Bump standards version to 3.8.3
* Port package build system to dh 7
+ Build-depend on debhelper 7
.
apturl (0.4.0ubuntu4) karmic; urgency=low
.
* build without "DH_PYCENTRAL=include-links" for now,
to work around breakage when upgrading from the previous
version that was build without the include-links option
(LP: #422825)
.
apturl (0.4.0ubuntu3) karmic; urgency=low
.
* Make KDE frontend use a Qt UI file (should make it easier to maintain)
* Enable KDE frontend to few HTML when about to enable a software channel
* Clean-up setup.py
* Make apturl script fall back to KDE frontend when -gtk is not installed even
if KDE_FULL_SESSION is not set
* Resolve self-relations of apturl binary package
* fix crash on ctrl-c (in KDE frontend)
.
apturl (0.4.0ubuntu2) karmic; urgency=low
.
* fix FTBFS
* fix crash on ctrl-c
.
apturl (0.4.0ubuntu1) karmic; urgency=low
.
[ Harald Sitter ]
* Add KDE frontend (LP: #293533)
.
[ Michael Vogt ]
* build with DH_PYCENTRAL=include-links
.
apturl (0.3.6ubuntu1) karmic; urgency=low
.
* AptUrl/AptUrl.py, AptUrl/UI.py, AptUrl/gtk/GtkUI.py:
- show channel info when enabling channels
* debian/control:
- recommend python-gthtml2 (for the channel info UI)
.
apturl (0.3.5ubuntu1) karmic; urgency=low
.
* AptUrl/AptUrl.py:
- when enabling sections, do not skip that if the requested
package is already known to the package cache
* AptUrl/Parser.py:
- support proper url synatax with "&" (thanks to asac)
* AptUrl/AptUrl.py:
- reopen the cache properly after a refresh=yes
.
apturl (0.3.3ubuntu1) jaunty; urgency=low
.
* AptUrl/AptUrl.py:
- fix crash on "refresh=yes" (LP: #327075)
.
apturl (0.3.2ubuntu2) jaunty; urgency=low
.
* AptUrl/gtk/GtkUI.py:
- fix gettext domain (LP: #304950)
* data/apturl.glade:
- fix missing translatable property (LP: #304925)
Thanks to Gabor Kelemen
* AptUrl/Helpers.py:
- fix crash for packages with no long description
(LP: #288576)
.
apturl (0.3.1ubuntu1) jaunty; urgency=low
.
* AptUrl/AptUrl.py:
- add additional sanitizing into the channel code
.
apturl (0.3.0ubuntu1) jaunty; urgency=low
.
* add README
* add basic string substituion for the variables
"$kernel" (uname -r) and "$distro" (lsb_release -s)
this allows stuff like:
"apt:linux-backports-module-$kernel"
* add new field "channel" that looks into
/usr/share/app-install/channels for known repositories that
the user might want to add
* refactored the UI code so that its easy to add a Qt
frontend, see AptUrl/UI.py and AptUrl/gtk/GtkUI.py
(volunteers welcome :)
* improved whitelist checking
.
apturl (0.2.7ubuntu1) intrepid; urgency=low
.
[ Siegfried-Angel Gevatter Pujals ]
* apturl:
- Show a different error message if the requested package is virtual; this
is the first step to fix Launchpad bug #230760.
- Show an error dialog if the /etc/apt/sources.list is invalid instead of
just crashing (LP: #206640).
- Catch KeyboardInterrupt's so that they don't show a traceback.
- Add a new exit code (RESULT_BADARGS, 4) for when the problem is with
the arguments with which apturl was called.
- Only ask once when enabling new components, and only list those
which aren't already enabled.
- Fix a crash which happened after enabling the requested component(s).
- Don't show an error message if the user didn't want to enable a
component; just silently skip the package.
- Improve the description:
+ Don't show the summary twice.
+ Remove single line breaks, like packages.ubuntu.com does.
+ Parse the Homepage field out of the description.
- Do not ask if you want to keep a software channel if it wasn't added.
- Use a constant to determine wheter new software channels can be added
or not (disabled by default, but that's better than having the code
commented out).
* AptUrl/Helpers.py:
- Add it.
* data/apturl.glade:
- Add a missing "can_default" property to fix an assertion error.
- Change the labels of the buttons on the installation confirmation dialog
so that they conform to the HIG. Thanks to Bruce Cowan (LP: #140472).
- Make the description field bigger and more visually appealing.
* AptUrl/Parser.py:
- Raise an Exception if one of the given package names contains characters
which are not allowed by the Debian Policy.
- Raise an Exception if one of the ?... values contains a space.
* apturl.8:
- Document all possible exit codes.
- Add a new example, and improve the comment of an existing one.
- Change the URL in "Bugs" from /apturl to /ubuntu/+source/apturl, as
that's where most bugs are.
* debian/control:
- Add Vcs-Browser field.
- Write all dependendency and build dependencies each on a line.
- Add python-gobject to the build dependencies (needed for the timer).
* debian/rules:
- Fix the clean rule so that it removes build/ and AptUrl/Version.py.
- Move the stuff from binary-arch to binary-indep, and remove the
binary-indep target to please lintian.
* debian/copyright:
- Update copyright years and author names.
.
[ Артём Попов ]
* data/apturl.protocol, setup.py:
- Register apturl in KDE as a protocol (LP: #227622).
.
apturl (0.2.6ubuntu1) intrepid; urgency=low
.
* apturl:
- add new ?refresh=1 option that allows forcing a apt-get update
before the package gets installed (thanks to Vadim Peretokin,
LP: #258173)
.
apturl (0.2.5ubuntu1) intrepid; urgency=low
.
* apturl:
- Hide python-apt's "API not stable yet" warning.
- If a package is already installed, show an informational box, not
an error message (LP: #237012).
- Give error dialogs the same icon as question dialogs have.
* apturl.8, debian/rules:
- Add a manpage (LP: #159422).
* debian/control:
- Bump the minimum debhelper version to 5.0.51~, as required for dh_icons.
- Improve the description.
* debian/copyright:
- Include the full GPL header.
.
apturl (0.2.4ubuntu1) intrepid; urgency=low
.
* make dialog less greedy to not cover up Synaptic (LP: #252028)
.
apturl (0.2.3ubuntu1) intrepid; urgency=low
.
* set always on top to prevent window from being hidden (LP: #234992)
.
apturl (0.2.2ubuntu1) hardy; urgency=low
.
* apturl:
- only add/ask about component enabling if the
component is actually not yet available (#163049)
- return correct error code when enabling
a component failed/got cancelt
- fix missing destroy in question() helper
- ensure that component is fully availabe (LP: #208722)
.
apturl (0.2.1ubuntu1) hardy; urgency=low
.
[ Michael Vogt ]
* apturl:
- fix broken enable of components
* debian/control:
- add missing python-apt dependency
.
[ Fabien Tassin ]
* setup.py:
- add support for firefox-3.0 (LP: #207281)
.
apturl (0.2.0ubuntu1) hardy; urgency=low
.
* apturl:
- run gtk.init_check() (LP: #197062)
- make the description better (split into summary/long descr)
- fix filename creation (LP: #138315)
- typo (LP: #200504)
- return proper exit codes on success/cancel/failure (LP: #132276)
- only run if the apt cache is not broken
* data/apturl.glade:
- default button is 'no'
- make it resizable
* po/POTFILES.in:
- add missing files (LP: #173846)
* date/apturl.schemas.in, setup.py:
- register apturl in gnome as a protocol
.
apturl (0.1.2ubuntu1) hardy; urgency=low
.
* support --http-proxy for better integration with the
proxy settings of firefox (LP: #162609)
* merged patch from Andy Owen to display a description
.
apturl (0.1.1ubuntu1) hardy; urgency=low
.
* AptUrl/Parser.py:
- Implemented multipackage installation (LP: #154593)
* tests/apturlparse.py:
- add test for the new multipackage feature
.
apturl (0.1ubuntu2) gutsy-proposed; urgency=low
.
* support --http-proxy for better integration with the
proxy settings of firefox (LP: #162609)
.
apturl (0.1ubuntu1) gutsy; urgency=low
.
* debian/control:
- fix typo in description (LP: #131828)
- add missing synaptic dependency (LP: #132067)
* apturl:
- check for already installed or unavailable packages
earlier (LP: #137053, LP: #137055)
- fix incorrect reference to GDebi (LP: #137065)
- disable adding repositories for now (LP: #139227)
.
apturl (0.0+bzr20070816) gutsy; urgency=low
.
* added i18n support
* added support for "minver"
* added support to add repositories and sections
* added suppor for removing sources again
.
apturl (0.0+bzr20070709) gutsy; urgency=low
.
* properly integrate with firefox
.
apturl (0.0+bzr20070702) gutsy; urgency=low
.
* Initial Release.
* Implements subset of https://wiki.ubuntu.com/AptFirefoxFileHandler
(to unblock firefox-distro-addon-support spec)
Diffstat (limited to 'AptUrl')
-rw-r--r-- | AptUrl/AptUrl.py | 193 | ||||
-rw-r--r-- | AptUrl/Helpers.py | 66 | ||||
-rw-r--r-- | AptUrl/Parser.py | 153 | ||||
-rw-r--r-- | AptUrl/UI.py | 23 | ||||
-rw-r--r-- | AptUrl/Version.py | 0 | ||||
-rw-r--r-- | AptUrl/__init__.py | 0 | ||||
-rw-r--r-- | AptUrl/gtk/GtkUI.py | 158 | ||||
-rw-r--r-- | AptUrl/gtk/__init__.py | 0 |
8 files changed, 593 insertions, 0 deletions
diff --git a/AptUrl/AptUrl.py b/AptUrl/AptUrl.py new file mode 100644 index 0000000..e712e5b --- /dev/null +++ b/AptUrl/AptUrl.py @@ -0,0 +1,193 @@ +# Copyright (c) 2007-2008 Canonical +# +# AUTHOR: +# Michael Vogt <mvo@ubuntu.com> +# With contributions by Siegfried-A. Gevatter <rainct@ubuntu.com> +# +# 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 + +from . import Parser +from . import Helpers +from .Helpers import _ + +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 + +# return codes +(RESULT_OK, + RESULT_CANCELT, + RESULT_ERROR, + RESULT_BADARGS) = list(range(4)) + +class AptUrlController(object): + + def __init__(self, ui): + self.ui = ui + + 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.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 + + changes = self.cache.get_changes() + additional_pkgs = [] + + for pkg in changes: + if pkg.marked_install: + additional_pkgs.append(pkg.name) + + # install it + ui.doInstall(apturl, extra_pkg_names=additional_pkgs) + + if not self.verifyInstall(apturl): + ret = RESULT_ERROR + + # return values + return ret diff --git a/AptUrl/Helpers.py b/AptUrl/Helpers.py new file mode 100644 index 0000000..d00b862 --- /dev/null +++ b/AptUrl/Helpers.py @@ -0,0 +1,66 @@ +# Copyright (c) 2008 Canonical +# +# AUTHOR: +# Siegfried-A. Gevatter <rainct@ubuntu.com> +# +# 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') diff --git a/AptUrl/Parser.py b/AptUrl/Parser.py new file mode 100644 index 0000000..0543d07 --- /dev/null +++ b/AptUrl/Parser.py @@ -0,0 +1,153 @@ +# Copyright (c) 2007-2008 Canonical +# +# AUTHOR: +# Michael Vogt <mvo@ubuntu.com> +# With contributions by Siegfried-A. Gevatter <rainct@ubuntu.com> +# +# 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 diff --git a/AptUrl/UI.py b/AptUrl/UI.py new file mode 100644 index 0000000..0fd502c --- /dev/null +++ b/AptUrl/UI.py @@ -0,0 +1,23 @@ + +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 + + def askInstallPackage(self): + pass + + # install/update progress + def doUpdate(self): + pass + def doInstall(self, apturl, extra_pkg_names=None): + pass + + # UI specific actions for enabling stuff + diff --git a/AptUrl/Version.py b/AptUrl/Version.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/AptUrl/Version.py diff --git a/AptUrl/__init__.py b/AptUrl/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/AptUrl/__init__.py diff --git a/AptUrl/gtk/GtkUI.py b/AptUrl/gtk/GtkUI.py new file mode 100644 index 0000000..dcc905f --- /dev/null +++ b/AptUrl/gtk/GtkUI.py @@ -0,0 +1,158 @@ +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('XApp', '1.0') +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject +from gi.repository import XApp +GObject.threads_init() + +import os +import sys +import apt_pkg +import subprocess +import tempfile + +from AptUrl.UI import AbstractUI +from AptUrl import Helpers +from AptUrl.Helpers import _ + +import mintcommon.aptdaemon + +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.require_update = False + + # 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("<big><b>%s</b></big>\n\n%s" % (summary, msg)) + XApp.set_window_icon_name(d, "package-x-generic") + 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 + + 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_title(package) + header_label = dia_xml.get_object('header_label') + header_label.set_markup("<b><big>%s</big></b>" % 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) + XApp.set_window_icon_name(dia, "package-x-generic") + + # 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 + + return True + + # progress etc + def doUpdate(self): + self.require_update = True + + def doInstall(self, apturl, extra_pkg_names=[]): + self.dia.hide() + packages = [] + packages.append(apturl.package) + packages += extra_pkg_names + self.install_packages(packages) + + def install_packages(self, package_names): + self.apt = mintcommon.aptdaemon.APT(None) + self.package_names = package_names + self.busy = True + if self.require_update: + self.apt.set_finished_callback(self.on_update_before_install_finished) + self.apt.update_cache() + else: + self.on_update_before_install_finished() + while self.busy: + while Gtk.events_pending(): + Gtk.main_iteration() + + def on_update_before_install_finished(self, transaction=None, exit_state=None): + self.apt.set_finished_callback(self.on_install_finished) + self.apt.set_cancelled_callback(self.on_install_finished) + self.apt.install_packages(self.package_names) + + def on_install_finished(self, transaction=None, exit_state=None): + del self.package_names + del self.apt + self.busy = False + self.dia.exit() + +if __name__ == "__main__": + ui = GtkUI() + ui.error("foo","bar") diff --git a/AptUrl/gtk/__init__.py b/AptUrl/gtk/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/AptUrl/gtk/__init__.py |