diff options
Diffstat (limited to '')
-rw-r--r-- | doc/NEWS | 7 | ||||
-rw-r--r-- | portato/backend/portage/__init__.py | 2 | ||||
-rw-r--r-- | portato/backend/portage/settings_22.py | 8 | ||||
-rw-r--r-- | portato/backend/portage/system.py | 11 | ||||
-rw-r--r-- | portato/db/__init__.py | 95 | ||||
-rw-r--r-- | portato/db/eix_sql.py | 7 | ||||
-rw-r--r-- | portato/db/exceptions.py | 2 | ||||
-rw-r--r-- | portato/db/sql.py | 2 | ||||
-rw-r--r-- | portato/gui/templates/AboutWindow.ui | 2 | ||||
-rw-r--r-- | portato/gui/templates/MailInfoWindow.ui | 2 | ||||
-rw-r--r-- | portato/gui/templates/MainWindow.ui | 2 | ||||
-rw-r--r-- | portato/gui/templates/PkgListWindow.ui | 2 | ||||
-rw-r--r-- | portato/gui/templates/PluginWindow.ui | 2 | ||||
-rw-r--r-- | portato/gui/templates/PreferenceWindow.ui | 2 | ||||
-rw-r--r-- | portato/gui/templates/SearchWindow.ui | 2 | ||||
-rw-r--r-- | portato/gui/templates/SplashScreen.ui | 2 | ||||
-rw-r--r-- | portato/gui/windows/main.py | 2 | ||||
-rw-r--r-- | portato/gui/windows/preference.py | 8 |
18 files changed, 99 insertions, 61 deletions
@@ -1,3 +1,10 @@ +0.14.1: + +- fix several bugs +- workaround for bug #557715 +- honor portage-API changes +- handle portage-2.1.8.* and above also as portage-2.2 + 0.14: - allow eix as backend DB diff --git a/portato/backend/portage/__init__.py b/portato/backend/portage/__init__.py index 6a68bbc..3b0d18b 100644 --- a/portato/backend/portage/__init__.py +++ b/portato/backend/portage/__init__.py @@ -17,7 +17,7 @@ from portage import VERSION as PV VERSION = tuple(map(int, (x.split("_")[0] for x in PV.split(".")))) -if VERSION >= (2, 2): +if VERSION >= (2, 2) or VERSION >= (2, 1, 8): debug("Using portage-2.2") from .system_22 import PortageSystem_22 as PortageSystem from .package_22 import PortagePackage_22 as PortagePackage diff --git a/portato/backend/portage/settings_22.py b/portato/backend/portage/settings_22.py index 253ecaa..33ac60d 100644 --- a/portato/backend/portage/settings_22.py +++ b/portato/backend/portage/settings_22.py @@ -12,7 +12,11 @@ -import portage.sets +try: + import portage.sets as psets +except ImportError: + import portage._sets as psets + from .settings import PortageSettings class PortageSettings_22 (PortageSettings): @@ -24,4 +28,4 @@ class PortageSettings_22 (PortageSettings): def load (self): PortageSettings.load(self) - self.setsconfig = portage.sets.load_default_config(self.settings, self.trees[self.settings["ROOT"]]) + self.setsconfig = psets.load_default_config(self.settings, self.trees[self.settings["ROOT"]]) diff --git a/portato/backend/portage/system.py b/portato/backend/portage/system.py index a7fea5d..54d0021 100644 --- a/portato/backend/portage/system.py +++ b/portato/backend/portage/system.py @@ -224,7 +224,11 @@ class PortageSystem (SystemInterface): return list(filter(self.find_lambda(name), categories)) def split_cpv (self, cpv): - cpv = portage.dep_getcpv(cpv) + try: + cpv = portage.dep_getcpv(cpv) + except portage.exception.InvalidAtom: + pass + return portage.catpkgsplit(cpv) def sort_package_list(self, pkglist, only_cpv = False): @@ -274,12 +278,15 @@ class PortageSystem (SystemInterface): if len(inst) > 1: myslots = set() + splitp = p.split('[', 1) # split away the useflags for i in inst: # get the slots of the installed packages myslots.add(i.get_slot()) myslots.add(best_p.get_slot()) # add the slot of the best package in portage for slot in myslots: - crit = "%s:%s" % (p, slot) + crit = splitp[:] + crit[0] = "%s:%s" % (crit[0], slot) + crit = "[".join(crit) # re-add possible useflags append(crit, self.find_best_match(crit), inst) else: append(p, best_p, inst) diff --git a/portato/db/__init__.py b/portato/db/__init__.py index 74479e6..6672284 100644 --- a/portato/db/__init__.py +++ b/portato/db/__init__.py @@ -10,66 +10,79 @@ # # Written by René 'Necoro' Neumann <necoro@necoro.net> +from collections import namedtuple + from . import database as db -from .exceptions import UnknownDatabaseTypeError, DatabaseInstantiationError +from .exceptions import UnknownDatabaseTypeError, DatabaseInstantiationError, DatabaseInitError from ..session import Session, SectionDict from ..helper import debug, warning, error, info +from ..odict import OrderedDict + +DBType = namedtuple("DBType", "name descr module cls alt") + +types = [ + ("eixsql", + DBType( + _("eix + SQLite"), + _("Similar to SQLite, but now uses the eix database to get the package information.\nThis should be much faster on startup, but requires that your eix database is always up-to-date.\nAdditionally, this is the only database allowing searching in descriptions."), + "eix_sql", "EixSQLDatabase", + "sql")), + ("sql", + DBType( + _("SQLite"), + _("Uses an SQLite-database to store package information.\nMay take longer to generate at the first time, but has advantages if portato is re-started with an unchanged portage tree. Additionally it allows to use fast SQL expressions for fetching the data."), + "sql", "SQLDatabase", + "dict")), + ("dict", + DBType( + _("Hashmap"), + _("Uses an in-memory hashmap to store package information.\nHas been used since at least version 0.3.3, but all information has to be regenerated on each startup."), + "hash", "HashDatabase", + None)) + ] -types = ( - ("eixsql", _("eix + SQLite"), _("Similar to SQLite, but now uses the eix database to get the package information.\nThis should be much faster on startup, but requires that your eix database is always up-to-date.\nAdditionally, this is the only database allowing searching in descriptions.")), - ("sql", _("SQLite"), _("Uses an SQLite-database to store package information.\nMay take longer to generate at the first time, but has advantages if portato is re-started with an unchanged portage tree. Additionally it allows to use fast SQL expressions for fetching the data.")), - ("dict", _("Hashmap"), _("Uses an in-memory hashmap to store package information.\nHas been used since at least version 0.3.3, but all information has to be regenerated on each startup.")) - ) +types = OrderedDict(types) class Database(db.Database): DEFAULT = "dict" def __new__ (cls, type = None): - if not '_the_instance' in cls.__dict__: - dbcls = cls._generate(type) - cls._the_instance = dbcls(cls._get_session()) - elif type is not None: - raise DatabaseInstantiationError("Database instantiation called with 'type' argument multiple times.") + try: + if not '_the_instance' in cls.__dict__: + dbcls = cls._generate(type) + cls._the_instance = dbcls(cls._get_session()) + elif type is not None: + raise DatabaseInstantiationError("Database instantiation called with 'type' argument multiple times.") + except (ImportError, DatabaseInitError) as e: + db = types[cls.DB_TYPE] + error(_("Cannot load %s."), db.cls) + error(_("Error: %s"), e) + + if db.alt is not None: + return cls.__new__(cls, db.alt) + else: + error(_("No alternative database given. Aborting.")) + raise DatabaseInstantiationError("Cannot load database.") + return cls._the_instance @classmethod def _generate(cls, type): - if type is None: warning("No database type specified! Falling back to default.") type = cls.DEFAULT - - cls.DB_TYPE = type - msg = _("Using database type '%s'") - if type == "sql": - info(msg, "SQLDatabase") - try: - from .sql import SQLDatabase - except ImportError: - warning(_("Cannot load %s."), "SQLDatabase") - return cls._generate("dict") - else: - return SQLDatabase - - elif type == "dict": - info(msg, "HashDatabase") - from .hash import HashDatabase - return HashDatabase - - elif type == "eixsql": - info(msg,"EixSQLDatabase") - try: - from .eix_sql import EixSQLDatabase - except ImportError: - warning(_("Cannot load %s."), "EixSQLDatabase.") - return cls._generate("sql") - else: - return EixSQLDatabase - - else: + try: + db = types[type] + except KeyError: error(_("Unknown database type: %s"), type) raise UnknownDatabaseTypeError(type) + + cls.DB_TYPE = type + info(_("Using database type '%s'"), db.cls) + + mod = __import__(db.module, globals(), locals(), [db.cls]) + return getattr(mod, db.cls) @classmethod def _get_session(cls): diff --git a/portato/db/eix_sql.py b/portato/db/eix_sql.py index 2a693e9..e93a613 100644 --- a/portato/db/eix_sql.py +++ b/portato/db/eix_sql.py @@ -20,10 +20,14 @@ except ImportError: import os from .sql import SQLDatabase +from .exceptions import DatabaseInitError from ..eix import EixReader from ..helper import debug, warning from ..backend import system +class EixInitError (DatabaseInitError): + pass + class EixSQLDatabase (SQLDatabase): CACHE_FILE = "/var/cache/eix" @@ -35,6 +39,9 @@ class EixSQLDatabase (SQLDatabase): warning(_("Cache file '%s' does not exist. Using default instead."), self.cache) self.cache = self.CACHE_FILE + if not os.path.exists(self.cache): + raise EixInitError(_("Cache file '%s' does not exist.") % self.cache) + debug("Using '%s' as eix cache file.", self.cache) session["cache"] = self.cache diff --git a/portato/db/exceptions.py b/portato/db/exceptions.py index 8a6e424..82fa337 100644 --- a/portato/db/exceptions.py +++ b/portato/db/exceptions.py @@ -22,3 +22,5 @@ class DatabaseInstantiationError (DatabaseError): class UnsupportedSearchTypeError(DatabaseError): pass +class DatabaseInitError (DatabaseError): + pass diff --git a/portato/db/sql.py b/portato/db/sql.py index a891e1a..7eb1a3b 100644 --- a/portato/db/sql.py +++ b/portato/db/sql.py @@ -261,7 +261,7 @@ class SQLDatabase (Database): if self._type & self.SEARCH_NAME: if "/" in restrict: - rest = "(name LIKE '%s%%' AND cat LIKE '%s')" % restrict.split("/",1) + rest = "(name LIKE '%s%%' AND cat LIKE '%s')" % tuple(restrict.split("/",1)) else: rest = "(name LIKE '%%%(restrict)s%%' OR cat LIKE '%(restrict)s%%')" % {"restrict":restrict} diff --git a/portato/gui/templates/AboutWindow.ui b/portato/gui/templates/AboutWindow.ui index 893958a..79c8522 100644 --- a/portato/gui/templates/AboutWindow.ui +++ b/portato/gui/templates/AboutWindow.ui @@ -1,6 +1,6 @@ <?xml version="1.0"?> <interface> - <requires lib="gtk+" version="2.14"/> + <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkAboutDialog" id="AboutWindow"> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> diff --git a/portato/gui/templates/MailInfoWindow.ui b/portato/gui/templates/MailInfoWindow.ui index e3cdd1f..fec34ed 100644 --- a/portato/gui/templates/MailInfoWindow.ui +++ b/portato/gui/templates/MailInfoWindow.ui @@ -1,6 +1,6 @@ <?xml version="1.0"?> <interface> - <requires lib="gtk+" version="2.14"/> + <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkWindow" id="MailInfoWindow"> <property name="title" translatable="yes">Send Bug Mail ...</property> diff --git a/portato/gui/templates/MainWindow.ui b/portato/gui/templates/MainWindow.ui index 2eaaae1..63cf225 100644 --- a/portato/gui/templates/MainWindow.ui +++ b/portato/gui/templates/MainWindow.ui @@ -1,6 +1,6 @@ <?xml version="1.0"?> <interface> - <requires lib="gtk+" version="2.14"/> + <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkWindow" id="MainWindow"> <property name="border_width">2</property> diff --git a/portato/gui/templates/PkgListWindow.ui b/portato/gui/templates/PkgListWindow.ui index fdcdb23..80ba5c7 100644 --- a/portato/gui/templates/PkgListWindow.ui +++ b/portato/gui/templates/PkgListWindow.ui @@ -1,6 +1,6 @@ <?xml version="1.0"?> <interface> - <requires lib="gtk+" version="2.14"/> + <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkWindow" id="PkgListWindow"> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> diff --git a/portato/gui/templates/PluginWindow.ui b/portato/gui/templates/PluginWindow.ui index 42a3156..fed260c 100644 --- a/portato/gui/templates/PluginWindow.ui +++ b/portato/gui/templates/PluginWindow.ui @@ -1,6 +1,6 @@ <?xml version="1.0"?> <interface> - <requires lib="gtk+" version="2.14"/> + <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkWindow" id="PluginWindow"> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> diff --git a/portato/gui/templates/PreferenceWindow.ui b/portato/gui/templates/PreferenceWindow.ui index 0f0a16f..1e8bf7d 100644 --- a/portato/gui/templates/PreferenceWindow.ui +++ b/portato/gui/templates/PreferenceWindow.ui @@ -1,6 +1,6 @@ <?xml version="1.0"?> <interface> - <requires lib="gtk+" version="2.14"/> + <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkAdjustment" id="adjustment1"> <property name="upper">300</property> diff --git a/portato/gui/templates/SearchWindow.ui b/portato/gui/templates/SearchWindow.ui index f62d259..fa17396 100644 --- a/portato/gui/templates/SearchWindow.ui +++ b/portato/gui/templates/SearchWindow.ui @@ -1,6 +1,6 @@ <?xml version="1.0"?> <interface> - <requires lib="gtk+" version="2.14"/> + <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkWindow" id="SearchWindow"> <property name="width_request">350</property> diff --git a/portato/gui/templates/SplashScreen.ui b/portato/gui/templates/SplashScreen.ui index c136062..2cc5152 100644 --- a/portato/gui/templates/SplashScreen.ui +++ b/portato/gui/templates/SplashScreen.ui @@ -1,6 +1,6 @@ <?xml version="1.0"?> <interface> - <requires lib="gtk+" version="2.14"/> + <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkWindow" id="SplashScreen"> <property name="width_request">300</property> diff --git a/portato/gui/windows/main.py b/portato/gui/windows/main.py index 261b999..164de81 100644 --- a/portato/gui/windows/main.py +++ b/portato/gui/windows/main.py @@ -175,7 +175,7 @@ class PackageTable: ftexts.append(t) for t in ftexts: - link = gtk.LinkButton(t) + link = gtk.LinkButton(uri = t, label = t) link.set_alignment(0.0, 0.5) link.set_border_width(0) self.linkBox.add(link) diff --git a/portato/gui/windows/preference.py b/portato/gui/windows/preference.py index 772c0c7..b8c13d8 100644 --- a/portato/gui/windows/preference.py +++ b/portato/gui/windows/preference.py @@ -168,14 +168,12 @@ class PreferenceWindow (AbstractDialog): self.databaseCombo = self.tree.get_widget("databaseCombo") model = gtk.ListStore(str, str, str) - ctr = 0 active = 0 - for k, name, desc in db.types: - if k == dbtype: + for ctr, (key, t) in enumerate(db.types.iteritems()): + if key == dbtype: active = ctr - model.append([name, desc, k]) - ctr += 1 + model.append([t.name, t.descr, key]) self.databaseCombo.set_model(model) self.databaseCombo.set_active(active) |