]> git.ipfire.org Git - pakfire.git/commitdiff
Bunch of misc. changes.
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 13 Feb 2011 11:04:24 +0000 (12:04 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 13 Feb 2011 11:04:24 +0000 (12:04 +0100)
Some code to export repository metadata.

pakfire/__init__.py
pakfire/builder.py
pakfire/cli.py
pakfire/constants.py
pakfire/database.py
pakfire/index.py
pakfire/packages/__init__.py
pakfire/packages/installed.py
pakfire/packages/packager.py
pakfire/repository.py
pakfire/transaction.py

index 25329169caa0a10fa77c2f939d2ccbb10917375a..ea7a59775084e00f0316551928010b22927070ab 100644 (file)
@@ -159,3 +159,29 @@ class Pakfire(object):
 
                ts.run()
 
+       def provides(self, patterns):
+               pkgs = []
+
+               for pattern in patterns:
+                       pkgs += self.repos.get_by_provides(pattern)
+
+               pkgs = packages.PackageListing(pkgs)
+               #pkgs.unique()
+
+               return pkgs
+
+       def repo_create(self, path):
+               if not os.path.exists(path) or not os.path.isdir(path):
+                       raise PakfireError, "Given path is not existant or not a directory: %s" % path
+
+               repo = repository.RemoteRepository(
+                       self,
+                       name="new",
+                       description="New repository.",
+                       url="file://%s" % path,
+                       gpgkey="XXX",
+                       enabled=True,
+               )
+
+               repo.save_index()
+
index dee646674c7d8a25ab356f8cd0fbdd7ef36177ab..97cfe302db89d6e010434b646be8b1dd41334095 100644 (file)
@@ -12,6 +12,7 @@ import time
 
 import depsolve
 import packages
+import repository
 import transaction
 import util
 
@@ -29,7 +30,7 @@ class Builder(object):
 
                self.settings = {
                        "enable_loop_devices" : True,
-                       "enable_icecream" : False,
+                       "enable_icecream" : True,
                }
                self.settings.update(settings)
 
@@ -452,7 +453,7 @@ class Builder(object):
 
                self._packages = []
                for pkg in pkgs:
-                       pkg = packages.VirtualPackage(self.pakfire, repo, pkg)
+                       pkg = packages.VirtualPackage(self.pakfire, pkg) # XXX had to remove repo here?!
                        self._packages.append(pkg)
 
                return self._packages
index e554b174f3953610abb5b7561619457d9e232211..a7e09f844042741d8cac882893ad22188bf7b229 100644 (file)
@@ -4,6 +4,7 @@ import argparse
 import sys
 
 import packages
+import repository
 
 from pakfire import Pakfire
 
@@ -50,6 +51,7 @@ class Cli(object):
                self.parse_command_info()
                self.parse_command_search()
                self.parse_command_update()
+               self.parse_command_provides()
 
                # Finally parse all arguments from the command line and save them.
                self.args = self.parser.parse_args()
@@ -67,6 +69,7 @@ class Cli(object):
                        "update"       : self.handle_update,
                        "info"         : self.handle_info,
                        "search"       : self.handle_search,
+                       "provides"     : self.handle_provides,
                }
 
        def parse_common_arguments(self):
@@ -119,6 +122,14 @@ class Cli(object):
                        help=_("A pattern to search for."))
                sub_search.add_argument("action", action="store_const", const="search")
 
+       def parse_command_provides(self):
+               # Implement the "provides" command
+               sub_provides = self.sub_commands.add_parser("provides",
+                       help=_("Get a list of packages that provide a given file or feature."))
+               sub_provides.add_argument("pattern", nargs="+",
+                       help=_("File or feature to search for."))
+               sub_provides.add_argument("action", action="store_const", const="provides")
+
        def run(self):
                action = self.args.action
 
@@ -168,6 +179,12 @@ class Cli(object):
        def handle_localinstall(self):
                return self.handle_install(local=True)
 
+       def handle_provides(self):
+               pkgs = self.pakfire.provides(self.args.pattern)
+
+               for pkg in pkgs:
+                       print pkg.dump()
+
 
 class CliBuilder(Cli):
        def __init__(self):
@@ -186,6 +203,7 @@ class CliBuilder(Cli):
                self.parse_command_search()
                self.parse_command_shell()
                self.parse_command_update()
+               self.parse_command_repo()
 
                # Finally parse all arguments from the command line and save them.
                self.args = self.parser.parse_args()
@@ -197,12 +215,13 @@ class CliBuilder(Cli):
                )
 
                self.action2func = {
-                       "build"   : self.handle_build,
-                       "dist"    : self.handle_dist,
-                       "update"  : self.handle_update,
-                       "info"    : self.handle_info,
-                       "search"  : self.handle_search,
-                       "shell"   : self.handle_shell,
+                       "build"       : self.handle_build,
+                       "dist"        : self.handle_dist,
+                       "update"      : self.handle_update,
+                       "info"        : self.handle_info,
+                       "search"      : self.handle_search,
+                       "shell"       : self.handle_shell,
+                       "repo_create" : self.handle_repo_create,
                }
 
        def parse_command_update(self):
@@ -246,6 +265,20 @@ class CliBuilder(Cli):
                sub_dist.add_argument("--resultdir", nargs="?",
                        help=_("Path were the output files should be copied to."))
 
+       def parse_command_repo(self):
+               sub_repo = self.sub_commands.add_parser("repo",
+                       help=_("Repository management commands."))
+
+               sub_repo_commands = sub_repo.add_subparsers()
+
+               self.parse_command_repo_create(sub_repo_commands)
+
+       def parse_command_repo_create(self, sub_commands):
+               sub_create = sub_commands.add_parser("create",
+                       help=_("Create a new repository index."))
+               sub_create.add_argument("path", nargs=1, help=_("Path to the packages."))
+               sub_create.add_argument("action", action="store_const", const="repo_create")
+
        def handle_build(self):
                print self.args
                # Get the package descriptor from the command line options
@@ -308,3 +341,8 @@ class CliBuilder(Cli):
 
                self.pakfire.dist(pkg, self.args.resultdir)
 
+       def handle_repo_create(self):
+               path = self.args.path[0]
+
+               self.pakfire.repo_create(path)
+
index a91137567697f6d20aa86b5b2e94358d633972af..326777b57732495bd6af51ab605ef2965fa811a0 100644 (file)
@@ -10,6 +10,7 @@ CONFIG_FILE = os.path.join(SYSCONFDIR, "pakfire.conf")
 CACHE_DIR = "/var/cache/pakfire"
 
 PACKAGES_DB = "var/lib/pakfire/packages.db"
+REPOSITORY_DB = "index.db"
 
 BUFFER_SIZE = 1024**2
 
index 69724dcf193ff5867e34ea4e96d1f1033b511dcf..4c1a1c61073ec36f80d0819e0afe3f485a7cceb6 100644 (file)
@@ -16,7 +16,7 @@ class Database(object):
 
        def __del__(self):
                if self._db:
-                       self._db.commit()
+                       #self._db.commit()
                        self._db.close()
 
        def create(self):
@@ -50,7 +50,7 @@ class Database(object):
                return self._db.cursor()
 
 
-class LocalPackageDatabase(Database):
+class PackageDatabase(Database):
        def create(self):
                c = self.cursor()
 
@@ -71,6 +71,7 @@ class LocalPackageDatabase(Database):
                                epoch           INTEGER,
                                version         TEXT,
                                release         TEXT,
+                               filename        TEXT,
                                installed       INTEGER,
                                reason          TEXT,
                                repository      TEXT,
@@ -101,6 +102,66 @@ class LocalPackageDatabase(Database):
 
                c.close()
 
+       def package_exists(self, pkg):
+               return not self.get_id_by_pkg(pkg) is None
+
+       def get_id_by_pkg(self, pkg):
+               c = self.cursor()
+
+               c.execute("SELECT id FROM packages WHERE name = ? AND version = ? AND \
+                       release = ? AND epoch = ? LIMIT 1", (pkg.name, pkg.version, pkg.release, pkg.epoch))
+
+               ret = None
+               for i in c:
+                       ret = i["id"]
+                       break
+               
+               c.close()
+
+               return ret
+
+       def add_package(self, pkg):
+               if self.package_exists(pkg):
+                       logging.debug("Skipping package which already exists in database: %s" % pkg.friendly_name)
+                       return
+
+               logging.debug("Adding package to database: %s" % pkg.friendly_name)
+
+               c = self.cursor()
+               c.execute("""
+                       INSERT INTO packages(
+                               name,
+                               epoch,
+                               version,
+                               release,
+                               filename,
+                               provides,
+                               requires
+                       ) VALUES(?, ?, ?, ?, ?, ?, ?)""",
+                       (
+                               pkg.name,
+                               pkg.epoch,
+                               pkg.version,
+                               pkg.release,
+                               pkg.filename,
+                               " ".join(pkg.provides),
+                               " ".join(pkg.requires),
+                       )
+               )
+               c.close()
+               self.commit()
+
+               pkg_id = self.get_id_by_pkg(pkg)
+
+               c = self.cursor()
+               for file in pkg.filelist:
+                       c.execute("INSERT INTO files(name, pkg) VALUES(?, ?)", (file, pkg_id))
+
+               c.close()
+               self.commit()
+
+
+class LocalPackageDatabase(PackageDatabase):
        def add_package(self, pkg, installed=True):
                c = self.cursor()
 
index bb6b43c7a3b0806158d2908942f828b0fb01635e..757d7a47c081c607e77e710cdaa4c1c418cf749f 100644 (file)
@@ -3,6 +3,7 @@
 import logging
 import os
 
+import database
 import packages
 
 from constants import *
@@ -61,9 +62,20 @@ class DirectoryIndex(Index):
 
                Index.__init__(self, pakfire, repo)
 
+               # Always update this because it will otherwise contain no data
+               self.update(force=True)
+
        def update(self, force=False):
                logging.debug("Updating repository index '%s' (force=%s)" % (self.path, force))
 
+               # Do nothing if the update is not forced but populate the database
+               # if no packages are present.
+               if not force and self._packages:
+                       return
+
+               # If we update the cache, we clear it first.
+               self._packages = []
+
                for dir, subdirs, files in os.walk(self.path):
                        for file in files:
                                # Skip files that do not have the right extension
@@ -81,19 +93,38 @@ class DirectoryIndex(Index):
 
                                self._packages.append(package)
 
+       def save(self, path=None):
+               if not path:
+                       path = self.path
+
+               path = os.path.join(path, "index.db")
+
+               db = database.PackageDatabase(self.pakfire, path)
 
-class InstalledIndex(Index):
+               for pkg in self.packages:
+                       db.add_package(pkg)
+
+               db.close()
+
+
+class DatabaseIndex(Index):
        def __init__(self, pakfire, repo, db):
                self.db = db
 
                Index.__init__(self, pakfire, repo)
 
+       def update(self, force=False):
+               """
+                       Nothing to do here.
+               """
+               pass
+
        def get_all_by_name(self, name):
                c = self.db.cursor()
                c.execute("SELECT * FROM packages WHERE name = ?", name)
 
                for pkg in c:
-                       yield package.InstalledPackage(self.pakfire, self.db, pkg)
+                       yield package.DatabasePackage(self.pakfire, self.db, pkg)
 
                c.close()
 
@@ -113,7 +144,12 @@ class InstalledIndex(Index):
                c.execute("SELECT * FROM packages")
 
                for pkg in c:
-                       yield packages.InstalledPackage(self.pakfire, self.db, pkg)
+                       yield packages.DatabasePackage(self.pakfire, self.db, pkg)
 
                c.close()
 
+
+# XXX maybe this can be removed later?
+class InstalledIndex(DatabaseIndex):
+       pass
+
index bb302e905e3277d6c6b79c4008b02d660710b991..af5711871dbc6006a22d6a14a47f0354ff6a69db 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 
 from binary import BinaryPackage
-from installed import InstalledPackage
+from installed import DatabasePackage, InstalledPackage
 from source import SourcePackage
 from virtual import VirtualPackage
 
index 5ddb2d0e7f5383802d7b4bc01ee120bbc49b0867..05c43a811ec57506ea0ad724f93d0c1cf02541f3 100644 (file)
@@ -7,11 +7,8 @@ import util
 
 from base import Package
 
-
-# XXX maybe this gets renamed to "DatabasePackage" or something similar.
-
-class InstalledPackage(Package):
-       type = "installed"
+class DatabasePackage(Package):
+       type = "db"
 
        def __init__(self, pakfire, db, data):
                Package.__init__(self, pakfire, pakfire.repos.local)
@@ -153,3 +150,8 @@ class InstalledPackage(Package):
                        (filename, self.id, size, type, hash1, time.time()))
                c.close()
 
+
+# XXX maybe we can remove this later?
+class InstalledPackage(DatabasePackage):
+       type = "installed"
+
index 6d82d63d1484b73ccca1f7bcac4458b65dbbb411..8c4229f7e08d85b7541dc1be11eebd78d6b90d44 100644 (file)
@@ -23,7 +23,10 @@ class Extractor(object):
                self.archive = None
                self._tempfile = None
 
-               self._uncompress_data()
+               if pkg.payload_compression == "XXX":
+                       self.archive = tarfile.open(fileobj=self.data)
+               else:
+                       self._uncompress_data()
 
        def cleanup(self):
                # XXX not called by anything
@@ -87,16 +90,16 @@ class Extractor(object):
                if member.isdir() and os.path.exists(target):
                        return
 
-               if self.pakfire.config.get("debug"):
-                       msg = "Creating file (%s:%03d:%03d) " % \
-                               (tarfile.filemode(member.mode), member.uid, member.gid)
-                       if member.issym():
-                               msg += "/%s -> %s" % (member.name, member.linkname)
-                       elif member.islnk():
-                               msg += "/%s link to /%s" % (member.name, member.linkname)
-                       else:
-                               msg += "/%s" % member.name
-                       logging.debug(msg)
+               #if self.pakfire.config.get("debug"):
+               #       msg = "Creating file (%s:%03d:%03d) " % \
+               #               (tarfile.filemode(member.mode), member.uid, member.gid)
+               #       if member.issym():
+               #               msg += "/%s -> %s" % (member.name, member.linkname)
+               #       elif member.islnk():
+               #               msg += "/%s link to /%s" % (member.name, member.linkname)
+               #       else:
+               #               msg += "/%s" % member.name
+               #       logging.debug(msg)
 
                # Remove file if it has been existant
                if not member.isdir() and os.path.exists(target):
index 276c64f0e5f192da68e0617d6f677252469e57e5..c0a2b66e413949807df625b0e7bfcfe778b1e9f9 100644 (file)
@@ -300,6 +300,9 @@ class RemoteRepository(RepositoryFactory):
                if self.index:
                        self.index.update(force=force)
 
+       def save_index(self, path=None):
+               self.index.save(path)
+
        #def get_all(self, requires):
        #       for pkg in self.index.get_all():
        #               if pkg.does_provide(requires):
index 283b789e7837a6980c82edf8fa21377b707c523f..f5f42c142e26ae47d2daed35a9761ba65410bf6b 100644 (file)
@@ -268,3 +268,4 @@ class TransactionSet(object):
                s.append("")
 
                print "\n".join(s)
+