]> git.ipfire.org Git - pakfire.git/commitdiff
Some rework on transactions and initial downloader code.
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 21 Feb 2011 01:10:23 +0000 (02:10 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 21 Feb 2011 01:10:23 +0000 (02:10 +0100)
Move the install/update/remove decision into TransactionSet and
makes Transaction more straight-forward.

pakfire/__init__.py
pakfire/builder.py
pakfire/constants.py
pakfire/depsolve.py
pakfire/downloader.py [new file with mode: 0644]
pakfire/packages/listing.py
pakfire/repository.py
pakfire/transaction.py
po/POTFILES.in
po/pakfire.pot

index f8378dcd96267640f14cdb6b70e99acb79110b85..a64f0e6f264e0c268258fd7ef5b52292087c1c62 100644 (file)
@@ -167,14 +167,13 @@ class Pakfire(object):
                                ds.add_requires(req)
 
                ds.resolve()
-
-               ts = transaction.TransactionSet(self, ds)
-               ts.dump()
+               ds.dump()
 
                ret = cli.ask_user(_("Is this okay?"))
                if not ret:
                        return
 
+               ts = transaction.Transaction(self, ds)
                ts.run()
 
        def provides(self, patterns):
index 8895c874d96e23ff861b433443123e3550af2b14..712264508030626458c76f7e42019bb47ed3b29c 100644 (file)
@@ -144,14 +144,14 @@ class Builder(object):
                        ds.add_requires("icecream")
 
                ds.resolve()
+               ds.dump()
 
                # Get build dependencies from source package.
                if isinstance(self.pkg, packages.SourcePackage):
                        for req in self.pkg.requires:
                                ds.add_requires(req)
 
-               ts = transaction.TransactionSet(self.pakfire, ds)
-               ts.dump()
+               ts = transaction.Transaction(self.pakfire, ds)
                ts.run()
 
                # Copy the makefile and load source tarballs.
@@ -169,9 +169,9 @@ class Builder(object):
                        for r in requires:
                                ds.add_requires(r)
                        ds.resolve()
+                       ds.dump()
 
-                       ts = transaction.TransactionSet(self.pakfire, ds)
-                       ts.dump()
+                       ts = transaction.Transaction(self.pakfire, ds)
                        ts.run()
 
        @property
index 9963c950e022fd4c597d364498fc77fbd0d9b634..6dfb7cfe88de1eacc26a236312a03f7bc4e6603e 100644 (file)
@@ -11,6 +11,7 @@ CONFIG_FILE = os.path.join(SYSCONFDIR, "pakfire.conf")
 
 CACHE_DIR = "/var/cache/pakfire"
 CCACHE_CACHE_DIR = os.path.join(CACHE_DIR, "ccache")
+REPO_CACHE_DIR = os.path.join(CACHE_DIR, "repos")
 
 LOCAL_BUILD_REPO_PATH = "/var/lib/pakfire/local"
 
@@ -33,6 +34,8 @@ BUILD_ROOT = "/var/lib/pakfire/build"
 SOURCE_DOWNLOAD_URL = "http://source.ipfire.org/source-3.x/"
 SOURCE_CACHE_DIR = os.path.join(CACHE_DIR, "sources")
 
+TIME_24H = 60*60*24
+
 SOURCE_PACKAGE_META = """\
 
 PKG_NAME="%(PKG_NAME)s"
index ae7393447d9f367d3ba957d4c3e88d1a4a0ea73b..133b4c8e1bc538e2b47bb14407ae30f310413553 100644 (file)
@@ -5,13 +5,20 @@ import re
 
 import packages
 import repository
+import transaction
+import util
 
 from errors import *
 
+from i18n import _
+
+PKG_DUMP_FORMAT = " %-21s %-8s %-21s %-19s %5s "
+
 class Requires(object):
-       def __init__(self, pkg, requires):
+       def __init__(self, pkg, requires, dep=False):
                self.pkg = pkg
                self.requires = requires
+               self.dep = dep
 
        def __repr__(self):
                return "<%s %s>" % (self.__class__.__name__, self.requires)
@@ -73,18 +80,21 @@ class DependencySet(object):
                self.__requires = []
                self.__obsoletes = []
 
+               # Create a new transaction set.
+               self.ts = transaction.TransactionSet()
+
                # Read-in all packages from the database that have
                # been installed previously and need to be taken into
                # account when resolving dependencies.
                for pkg in self.repos.local.packages:
-                       self.add_package(pkg)
+                       self.add_package(pkg, transaction=False)
 
-       def add_requires(self, requires, pkg=None):
+       def add_requires(self, requires, pkg=None, dep=False):
                # XXX for now, we skip the virtual perl requires
                if requires.startswith("perl(") or requires.startswith("perl>") or requires.startswith("perl="):
                        return
 
-               requires = Requires(pkg, requires)
+               requires = Requires(pkg, requires, dep)
 
                if requires in self.__requires:
                        return
@@ -102,20 +112,31 @@ class DependencySet(object):
 
                self.__obsoletes.append(obsoletes)
 
-       def add_package(self, pkg):
+       def add_package(self, pkg, dep=False, transaction=True):
                #print pkg, sorted(self.__packages)
                #assert not pkg in self.__packages
                if pkg in self.__packages:
                        logging.debug("Trying to add package which is already in the dependency set: %s" % pkg)
                        return
 
-               if not isinstance(pkg, packages.DatabasePackage):
-                       logging.info(" --> Adding package to dependency set: %s" % pkg.friendly_name)
+               if transaction:
+                       transaction_mode = "install"
+                       for p in self.__packages:
+                               if pkg.name == p.name:
+                                       transaction_mode = "update"
+                                       break
+
+                       # Add package to transaction set
+                       func = getattr(self.ts, transaction_mode)
+                       func(pkg, dep=dep)
+
+               #if not isinstance(pkg, packages.DatabasePackage):
+               #       logging.info(" --> Adding package to dependency set: %s" % pkg.friendly_name)
                self.__packages.append(pkg)
 
                # Add the requirements of the newly added package.
                for req in pkg.requires:
-                       self.add_requires(req, pkg)
+                       self.add_requires(req, pkg, dep=True)
 
                # Remove all requires that are fulfilled by this package.
                # For that we copy the matching requires to _requires and remove them
@@ -156,9 +177,68 @@ class DependencySet(object):
 
                        best = candidates.get_most_recent()
                        if best:
-                               self.add_package(best)
+                               self.add_package(best, dep=requires.dep)
 
                if unresolveable_reqs:
                        raise DependencyError, "Cannot resolve %s" % \
                                " ".join([r.requires for r in unresolveable_reqs])
 
+       def dump_pkg(self, format, pkg):
+               return format % (
+                       pkg.name,
+                       pkg.arch,
+                       pkg.friendly_version,
+                       pkg.repo.name,
+                       util.format_size(pkg.size),
+               )
+
+       def dump_pkgs(self, caption, pkgs):
+               if not pkgs:
+                       return []
+
+               s = [caption,]
+               for pkg in sorted(pkgs):
+                       s.append(self.dump_pkg(PKG_DUMP_FORMAT, pkg))
+               s.append("")
+               return s
+
+       def dump(self):
+               width = 80
+               line = "=" * width
+
+               s = []
+               s.append(line)
+               s.append(PKG_DUMP_FORMAT % (_("Package"), _("Arch"), _("Version"), _("Repository"), _("Size")))
+               s.append(line)
+
+               s += self.dump_pkgs(_("Installing:"), self.ts.installs)
+               s += self.dump_pkgs(_("Installing for dependencies:"), self.ts.install_deps)
+               s += self.dump_pkgs(_("Updating:"), self.ts.updates)
+               s += self.dump_pkgs(_("Updating for dependencies:"), self.ts.update_deps)
+               s += self.dump_pkgs(_("Removing:"), self.ts.removes)
+               s += self.dump_pkgs(_("Removing for dependencies:"), self.ts.remove_deps)
+
+               s.append(_("Transaction Summary"))
+               s.append(line)
+
+               format = "%-20s %-4d %s"
+
+               if self.ts.installs or self.ts.install_deps:
+                       s.append(format % (_("Install"),
+                               len(self.ts.installs + self.ts.install_deps), _("Package(s)")))
+
+               if self.ts.updates or self.ts.update_deps:
+                       s.append(format % (_("Updates"),
+                               len(self.ts.updates + self.ts.update_deps), _("Package(s)")))
+
+               if self.ts.removes or self.ts.remove_deps:
+                       s.append(format % (_("Remove"),
+                               len(self.ts.removes + self.ts.remove_deps), _("Package(s)")))
+
+               download_size = sum([p.size for p in self.ts.installs + \
+                       self.ts.install_deps + self.ts.updates + self.ts.update_deps])
+               s.append(_("Total download size: %s") % util.format_size(download_size))
+               s.append("")
+
+               for line in s:
+                       logging.info(line)
diff --git a/pakfire/downloader.py b/pakfire/downloader.py
new file mode 100644 (file)
index 0000000..486b903
--- /dev/null
@@ -0,0 +1,120 @@
+#!/usr/bin/python
+
+import json
+import logging
+
+from urlgrabber.grabber import URLGrabber, URLGrabError
+from urlgrabber.mirror import MGRandomOrder
+from urlgrabber.progress import TextMultiFileMeter
+
+from constants import *
+
+MIRRORLIST_MAXSIZE = 1024**2
+
+class PakfireGrabber(URLGrabber):
+       """
+               Class to make some modifications on the urlgrabber configuration.
+       """
+       pass
+
+
+class Mirror(object):
+       def __init__(self, mirror, location=None, preferred=False):
+               # Save URL of the mirror in full format
+               self.mirror = mirror
+
+               # Save the location (if given)
+               self.location = location
+
+               # Save preference
+               self.preferred = False
+
+
+class MirrorList(object):
+       def __init__(self, pakfire, repo):
+               self.pakfire = pakfire
+               self.repo = repo
+
+               self.__mirrors = []
+
+               # Save URL to more mirrors.
+               self.mirrorlist = repo.mirrorlist
+
+               self.update(force=False)
+
+       @property
+       def cache(self):
+               """
+                       Shortcut to cache from repository.
+               """
+               return self.repo.cache
+
+       def update(self, force=False):
+               # XXX should this be allowed?
+               if not self.mirrorlist:
+                       return 
+
+               logging.debug("Updating mirrorlist for repository '%s' (force=%s)" % (self.repo.name, force))
+
+               cache_filename = "mirrors/mirrorlist"
+
+               # Force the update if no mirrorlist is available.
+               if not self.cache.exists(cache_filename):
+                       force = True
+
+               if not force and self.cache.exists(cache_filename):
+                       age = self.cache.age(cache_filename)
+
+                       # If the age could be determined and is higher than 24h,
+                       # we force an update.
+                       if age and age > TIME_24H:
+                               force = True
+
+               if force:
+                       g = PakfireGrabber()
+
+                       try:
+                               mirrordata = g.urlread(self.mirrorlist, limit=MIRRORLIST_MAXSIZE)
+                       except URLGrabError, e:
+                               logging.warning("Could not update the mirrorlist for repo '%s': %s" % (self.repo.name, e))
+                               return
+
+                       # XXX check for empty files or damaged output
+
+                       # Save new mirror data to cache.
+                       f = self.cache.open(cache_filename, "w")
+                       f.write(mirrordata)
+                       f.close()
+
+               # Read mirrorlist from cache and parse it.
+               with self.cache.open(cache_filename) as f:
+                       self.parse_mirrordata(f.read())
+
+       def parse_mirrordata(self, data):
+               data = json.loads(data)
+
+               for mirror in data["mirrors"]:
+                       self.add_mirror(**mirror)
+
+       def add_mirror(self, *args, **kwargs):
+               mirror = Mirror(*args, **kwargs)
+
+               self.__mirrors.append(mirror)
+
+       @property
+       def preferred(self):
+               """
+                       Return a generator for all mirrors that are preferred.
+               """
+               for mirror in self.__mirrors:
+                       if mirror.preferred:
+                               yield mirror
+
+       @property
+       def all(self):
+               """
+                       Return a generator for all mirrors.
+               """
+               for mirror in self.__mirrors:
+                       yield mirror
+
index fbc14b5ba2fa347d66e9ecdf5633549e4647a503..bdaaeee0b094d2f724ecc8dc45f00b085989278e 100644 (file)
@@ -22,6 +22,11 @@ class PackageListing(object):
        def __len__(self):
                return len(self.__packages)
 
+       def get_by_name(self, name):
+               for pkg in self.__packages:
+                       if pkg.name == name:
+                               yield pkg
+
        def get_most_recent(self):
                if self.__packages:
                        return self.__packages[-1]
index fea2a6801c2869212898ef248886d471d77f7d2d..599c3cb27d0e28471c1077799a3d2e25e9f3e959 100644 (file)
@@ -3,15 +3,14 @@
 import fnmatch
 import logging
 import os
+import stat
+import time
 
 from ConfigParser import ConfigParser
 
-from urlgrabber.grabber import URLGrabber
-from urlgrabber.mirror import MGRandomOrder
-from urlgrabber.progress import TextMultiFileMeter
-
 import base
 import database
+import downloader
 import index
 import packages
 
@@ -62,6 +61,7 @@ class Repositories(object):
                        "name" : name,
                        "enabled" : True,
                        "gpgkey" : None,
+                       "mirrorlist" : None,
                }
                _args.update(args)
 
@@ -344,17 +344,77 @@ class LocalBuildRepository(LocalRepository):
                return 20000
 
 
+class RepositoryCache(object):
+       """
+               An object that is able to cache all data that is loaded from a
+               remote repository.
+       """
+
+       def __init__(self, pakfire, repo):
+               self.pakfire = pakfire
+               self.repo = repo
+
+               self.create()
+
+       @property
+       def path(self):
+               return os.path.join(REPO_CACHE_DIR, self.repo.name, self.repo.arch)
+
+       def create(self):
+               """
+                       Create all necessary directories.
+               """
+               for d in ("mirrors", "packages", "metadata"):
+                       path = os.path.join(self.path, d)
+
+                       if not os.path.exists(path):
+                               os.makedirs(path)
+
+       def exists(self, filename):
+               """
+                       Returns True if a file exists and False if it doesn't.
+               """
+               return os.path.exists(os.path.join(self.path, filename))
+
+       def age(self, filename):
+               """
+                       Returns the age of a downloaded file in minutes.
+                       i.e. the time from download until now.
+               """
+               if not self.exists(filename):
+                       return None
+
+               filename = os.path.join(self.path, filename)
+
+               # Creation time of the file
+               ctime = os.stat(filename)[stat.ST_CTIME]
+
+               return (time.time() - ctime) / 60
+
+       def open(self, filename, *args, **kwargs):
+               filename = os.path.join(self.path, filename)
+
+               return open(filename, *args, **kwargs)
+
+
 class RemoteRepository(RepositoryFactory):
-       def __init__(self, pakfire, name, description, url, gpgkey, enabled):
+       def __init__(self, pakfire, name, description, url, mirrorlist, gpgkey, enabled):
                RepositoryFactory.__init__(self, pakfire, name, description)
 
                self.url, self.gpgkey = url, gpgkey
+               self.mirrorlist = mirrorlist
 
                if enabled in (True, 1, "1", "yes", "y"):
                        self.enabled = True
                else:
                        self.enabled = False
 
+               # Create a cache for the repository where we can keep all temporary data.
+               self.cache = RepositoryCache(self.pakfire, self)
+
+               # Initialize mirror servers.
+               self.mirrors = downloader.MirrorList(self.pakfire, self)
+
                if self.local:
                        self.index = index.DirectoryIndex(self.pakfire, self, self.url)
                else:
@@ -376,12 +436,16 @@ class RemoteRepository(RepositoryFactory):
                # Otherwise not.
                return False
 
+       @property
+       def arch(self):
+               return self.pakfire.distro.arch
+
        @property
        def path(self):
                if self.local:
                        return self.url[7:]
 
-               raise Exception, "XXX find some cache dir"
+               return self.cache.path
 
        @property
        def priority(self):
@@ -399,13 +463,6 @@ class RemoteRepository(RepositoryFactory):
 
                return priority
 
-       @property
-       def mirrorlist(self):
-               # XXX
-               return [
-                       "http://mirror0.ipfire.org/",
-               ]
-
        def fetch_file(self, filename):
                grabber = URLGrabber(
                        progress_obj = TextMultiFileMeter(),
index a652f22eb625465fcb83ee455d16c7077679afef..932119ea66491c0cfa7d6cb39d06515b7804d12c 100644 (file)
@@ -3,6 +3,7 @@
 import logging
 
 import depsolve
+import packages
 import util
 
 from i18n import _
@@ -90,24 +91,54 @@ class ActionRemove(Action):
 
 
 class TransactionSet(object):
-       def __init__(self, pakfire, ds):
-               self.pakfire = pakfire
-               self.ds = ds
+       def __init__(self):
+               self.installs = []
+               self.install_deps = []
 
-               self._actions = []
+               self.updates = []
+               self.update_deps = []
 
-               self._installs = []
-               self._removes = []
-               self._updates = []
+               self.removes = []
+               self.remove_deps = []
 
-               # Reference to local repository
-               self.local = pakfire.repos.local
+       def install(self, pkg, dep=False):
+               logging.info(" --> Marking package for install: %s" % pkg.friendly_name)
 
-               self._packages = self.local.get_all()
+               if dep:
+                       self.install_deps.append(pkg)
+               else:
+                       self.installs.append(pkg)
 
-               self.populate()
+       def remove(self, pkg, dep=False):
+               logging.info(" --> Marking package for remove: %s" % pkg.friendly_name)
+
+               if dep:
+                       self.remove_deps.append(pkg)
+               else:
+                       self.removes.append(pkg)
+
+       def update(self, pkg, dep=False):
+               logging.info(" --> Marking package for update: %s" % pkg.friendly_name)
+
+               if dep:
+                       self.update_deps.append(pkg)
+               else:
+                       self.updates.append(pkg)
+
+       def download(self):
+               pass
+
+
+class Transaction(object):
+       def __init__(self, pakfire, ds):
+               self.pakfire = pakfire
+               self.ds = ds
+
+               self._actions = []
 
        def _install_pkg(self, pkg):
+               assert isinstance(pkg, packages.BinaryPackage)
+
                # XXX add dependencies for running the script here
                action_prein   = ActionScriptPreIn(self.pakfire, pkg)
 
@@ -119,41 +150,32 @@ class TransactionSet(object):
                for action in (action_prein, action_extract, action_postin):
                        self.add_action(action)
 
-               self._installs.append(pkg)
-
        def _update_pkg(self, pkg):
+               assert isinstance(pkg, packages.BinaryPackage)
+
                action_extract = ActionExtract(self.pakfire, pkg)
 
                self.add_action(action_extract)
-               self._updates.append(pkg)
 
        def _remove_pkg(self, pkg):
                # XXX TBD
-               self._removes.append(pkg)
+               pass
 
        def populate(self):
-               # XXX need to check later, if this really works
-
                # Determine which packages we have to add
                # and which we have to remove.
 
-               for pkg in self.ds.packages:
-                       pkgs = self.local.get_by_name(pkg.name)
-                       pkgs = [p for p in pkgs]
-                       if not pkgs:
-                               # Got a new package to install
-                               self._install_pkg(pkg)
+               # Add all packages that need to be installed.
+               for pkg in self.ds.ts.installs + self.ds.ts.install_deps:
+                       self._install_pkg(pkg)
 
-                       else:
-                               # Check for updates
-                               for _pkg in pkgs:
-                                       if pkg > _pkg:
-                                               self._update_pkg(pkg)
-                                               break
+               # Add all packages that need to be updated.
+               for pkg in self.ds.ts.updates + self.ds.ts.update_deps:
+                       self._update_pkg(pkg)
 
-               for pkg in self._packages:
-                       if not pkg in self.ds.packages:
-                               self._remove_pkg(pkg)
+               # Add all packages that need to be removed.
+               for pkg in self.ds.ts.removes + self.ds.ts.remove_deps:
+                       self._remove_pkg(pkg)
 
        def add_action(self, action):
                logging.debug("New action added: %s" % action)
@@ -167,18 +189,6 @@ class TransactionSet(object):
                for _action in self.actions:
                        _action.remove_dep(action)
 
-       @property
-       def installs(self):
-               return sorted(self._installs)
-
-       @property
-       def updates(self):
-               return sorted(self._updates)
-
-       @property
-       def removes(self):
-               return sorted(self._removes)
-
        @property
        def actions(self):
                for action in self._actions:
@@ -196,6 +206,12 @@ class TransactionSet(object):
                        logging.error("Action finished with an error: %s - %s" % (action, e))
 
        def run(self):
+               # Download all packages.
+               self.ds.ts.download()
+
+               # Create all the actions that need to be done.
+               self.populate()
+
                while True:
                        if not [a for a in self.actions]:
                                break
@@ -208,60 +224,3 @@ class TransactionSet(object):
                                self.run_action(action)
                                self.remove_action(action)
 
-       def dump_pkg(self, format, pkg):
-               return format % (
-                       pkg.name,
-                       pkg.arch,
-                       pkg.friendly_version,
-                       pkg.repo.name,
-                       util.format_size(pkg.size),
-               )
-
-       def dump(self):
-               width = 80
-               line = "=" * width
-               format = " %-21s %-8s %-21s %-19s %5s "
-
-               s = []
-               s.append(line)
-               s.append(format % (_("Package"), _("Arch"), _("Version"), _("Repository"), _("Size")))
-               s.append(line)
-
-               if self.installs:
-                       s.append(_("Installing:"))
-                       for pkg in self.installs:
-                               s.append(self.dump_pkg(format, pkg))
-                       s.append("")
-
-               if self.updates:
-                       s.append(_("Updating:"))
-                       for pkg in self.updates:
-                               s.append(self.dump_pkg(format, pkg))
-                       s.append("")
-
-               if self.removes:
-                       s.append(_("Removing:"))
-                       for pkg in self.removes:
-                               s.append(self.dump_pkg(format, pkg))
-                       s.append("")
-
-               s.append(_("Transaction Summary"))
-               s.append(line)
-               
-               format = "%-20s %-4d %s"
-               
-               if self.installs:
-                       s.append(format % (_("Install"), len(self.installs), _("Package(s)")))
-               
-               if self.updates:
-                       s.append(format % (_("Updates"), len(self.updates), _("Package(s)")))
-               
-               if self.removes:
-                       s.append(format % (_("Remove"), len(self.removes), _("Package(s)")))
-
-               download_size = sum([p.size for p in self.installs + self.updates])
-               s.append(_("Total download size: %s") % util.format_size(download_size))
-               s.append("")
-
-               print "\n".join(s)
-
index c554e6be547d8cbc3b93012e866f47bca76868bc..a74b5f5263007ea97fa288ca2e2cf021e22189f4 100644 (file)
@@ -6,6 +6,7 @@ pakfire/constants.py
 pakfire/database.py
 pakfire/depsolve.py
 pakfire/distro.py
+pakfire/downloader.py
 pakfire/errors.py
 pakfire/i18n.py
 pakfire/index.py
index 48e6a9250d81ebe8e5ef9e59408dc4e9e4eb21f6..5c286ab14034d97f05318b139441235b9dec0c38 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-02-20 11:01+0100\n"
+"POT-Creation-Date: 2011-02-21 02:10+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -150,112 +150,124 @@ msgstr ""
 msgid "Path to input packages."
 msgstr ""
 
-#: ../pakfire/__init__.py:174
-msgid "Is this okay?"
-msgstr ""
-
-#: ../pakfire/packages/base.py:51
-msgid "Name"
+#: ../pakfire/depsolve.py:211
+msgid "Package"
 msgstr ""
 
-#: ../pakfire/packages/base.py:52 ../pakfire/transaction.py:227
+#: ../pakfire/depsolve.py:211 ../pakfire/packages/base.py:51
 msgid "Arch"
 msgstr ""
 
-#: ../pakfire/packages/base.py:53 ../pakfire/transaction.py:227
+#: ../pakfire/depsolve.py:211 ../pakfire/packages/base.py:52
 msgid "Version"
 msgstr ""
 
-#: ../pakfire/packages/base.py:54
-msgid "Release"
+#: ../pakfire/depsolve.py:211
+msgid "Repository"
 msgstr ""
 
-#: ../pakfire/packages/base.py:55 ../pakfire/transaction.py:227
+#: ../pakfire/depsolve.py:211 ../pakfire/packages/base.py:54
 msgid "Size"
 msgstr ""
 
-#: ../pakfire/packages/base.py:56
-msgid "Repo"
+#: ../pakfire/depsolve.py:214
+msgid "Installing:"
 msgstr ""
 
-#: ../pakfire/packages/base.py:57
-msgid "Summary"
+#: ../pakfire/depsolve.py:215
+msgid "Installing for dependencies:"
 msgstr ""
 
-#: ../pakfire/packages/base.py:58
-msgid "URL"
+#: ../pakfire/depsolve.py:216
+msgid "Updating:"
 msgstr ""
 
-#: ../pakfire/packages/base.py:59
-msgid "License"
+#: ../pakfire/depsolve.py:217
+msgid "Updating for dependencies:"
 msgstr ""
 
-#: ../pakfire/packages/base.py:62
-msgid "Description"
+#: ../pakfire/depsolve.py:218
+msgid "Removing:"
 msgstr ""
 
-#: ../pakfire/packages/base.py:68
-msgid "Build ID"
+#: ../pakfire/depsolve.py:219
+msgid "Removing for dependencies:"
 msgstr ""
 
-#: ../pakfire/packages/base.py:69
-msgid "Build date"
+#: ../pakfire/depsolve.py:221
+msgid "Transaction Summary"
 msgstr ""
 
-#: ../pakfire/packages/base.py:70
-msgid "Build host"
+#: ../pakfire/depsolve.py:227
+msgid "Install"
 msgstr ""
 
-#: ../pakfire/packages/packager.py:70
-msgid "Extracting"
+#: ../pakfire/depsolve.py:228 ../pakfire/depsolve.py:232
+#: ../pakfire/depsolve.py:236
+msgid "Package(s)"
 msgstr ""
 
-#: ../pakfire/packages/packager.py:125
-msgid "Extracting:"
+#: ../pakfire/depsolve.py:231
+msgid "Updates"
 msgstr ""
 
-#: ../pakfire/transaction.py:227
-msgid "Package"
+#: ../pakfire/depsolve.py:235
+msgid "Remove"
 msgstr ""
 
-#: ../pakfire/transaction.py:227
-msgid "Repository"
+#: ../pakfire/depsolve.py:240
+#, python-format
+msgid "Total download size: %s"
 msgstr ""
 
-#: ../pakfire/transaction.py:231
-msgid "Installing:"
+#: ../pakfire/__init__.py:172
+msgid "Is this okay?"
 msgstr ""
 
-#: ../pakfire/transaction.py:237
-msgid "Updating:"
+#: ../pakfire/packages/base.py:50
+msgid "Name"
 msgstr ""
 
-#: ../pakfire/transaction.py:243
-msgid "Removing:"
+#: ../pakfire/packages/base.py:53
+msgid "Release"
 msgstr ""
 
-#: ../pakfire/transaction.py:248
-msgid "Transaction Summary"
+#: ../pakfire/packages/base.py:55
+msgid "Repo"
 msgstr ""
 
-#: ../pakfire/transaction.py:254
-msgid "Install"
+#: ../pakfire/packages/base.py:56
+msgid "Summary"
 msgstr ""
 
-#: ../pakfire/transaction.py:254 ../pakfire/transaction.py:257
-#: ../pakfire/transaction.py:260
-msgid "Package(s)"
+#: ../pakfire/packages/base.py:57
+msgid "URL"
 msgstr ""
 
-#: ../pakfire/transaction.py:257
-msgid "Updates"
+#: ../pakfire/packages/base.py:58
+msgid "License"
 msgstr ""
 
-#: ../pakfire/transaction.py:260
-msgid "Remove"
+#: ../pakfire/packages/base.py:61
+msgid "Description"
 msgstr ""
 
-#: ../pakfire/transaction.py:263
-#, python-format
-msgid "Total download size: %s"
+#: ../pakfire/packages/base.py:67
+msgid "Build ID"
+msgstr ""
+
+#: ../pakfire/packages/base.py:68
+msgid "Build date"
+msgstr ""
+
+#: ../pakfire/packages/base.py:69
+msgid "Build host"
+msgstr ""
+
+#: ../pakfire/packages/packager.py:70
+msgid "Extracting"
+msgstr ""
+
+#: ../pakfire/packages/packager.py:125
+msgid "Extracting:"
 msgstr ""