]> git.ipfire.org Git - pakfire.git/commitdiff
Add new class FilePackage.
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 7 Feb 2011 00:20:47 +0000 (01:20 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 7 Feb 2011 00:20:47 +0000 (01:20 +0100)
This class is an additional wrapper to read packages of the
tar format.

pakfire/errors.py
pakfire/packages/base.py
pakfire/packages/binary.py
pakfire/packages/file.py [new file with mode: 0644]
pakfire/packages/source.py

index fa9f55c6c126330152f2e22fe7068b67922aad9a..ea12f452499116b8a2df9cea90dde5e7cea78d97 100644 (file)
@@ -15,6 +15,9 @@ class ConfigError(Error):
 class DownloadError(Error):
        pass
 
+class FileError(Error):
+       pass
+
 class PakfireError(Error):
        pass
 
index 88eddb86b36bc6f30f6a3da978fe590cae37e79c..5d5547f1e3f80fe2a1feffcf40493c55feebad02 100644 (file)
@@ -65,17 +65,6 @@ class Package(object):
 
                return "\n".join(s)
 
-       @property
-       def data(self):
-               """
-                       Link to the datafile that only gets established if
-                       we need access to it.
-               """
-               if not hasattr(self, "_data"):
-                       self._data = io.CpioArchive(self.filename)
-
-               return self._data
-
        @property
        def info(self):
                info = {
@@ -98,36 +87,17 @@ class Package(object):
        def size(self):
                """
                        Return the size of the package file.
-               """
-               return self.data.size
-
-       def get_file(self, filename):
-               """
-                       Get a file descriptor for the file.
 
-                       Raises KeyError if file is not available.
+                       This should be overloaded by another class and returns 0 for
+                       virtual packages.
                """
-               return self.data.get(filename)
+               return 0
 
        ### META INFORMATION ###
 
        @property
        def metadata(self):
-               if not hasattr(self, "_metadata"):
-                       info = self.get_file("info")
-                       _metadata = {}
-
-                       for line in info.read().splitlines():
-                               m = re.match(r"^(\w+)=(.*)$", line)
-                               if m is None:
-                                       continue
-
-                               key, val = m.groups()
-                               _metadata[key] = val.strip("\"")
-
-                       self._metadata = _metadata
-
-               return self._metadata
+               raise NotImplementedError
 
        @property
        def friendly_name(self):
@@ -201,12 +171,7 @@ class Package(object):
 
        @property
        def signature(self):
-               f = self.get_file("signature")
-               f.seek(0)
-               sig = f.read()
-               f.close()
-
-               return sig or None
+               raise NotImplementedError
 
        @property
        def build_date(self):
index 92c70bb11d80f6380dc84946e4f9a1acdf6fe4c7..bb9fdc3ea4abeab8bef3039cf0cd169a1ab8e20d 100644 (file)
@@ -4,18 +4,15 @@ import sys
 
 import packager
 
-from base import Package
+from file import FilePackage
 
-class BinaryPackage(Package):
+class BinaryPackage(FilePackage):
        type = "bin"
 
        @property
        def arch(self):
                return self.metadata.get("PKG_ARCH")
 
-       def extract(self, path):
-               pass
-
        @property
        def requires(self):
                ret = ""
@@ -31,15 +28,6 @@ class BinaryPackage(Package):
        def provides(self):
                return self.metadata.get("PKG_PROVIDES").split()
 
-       @property
-       def filelist(self):
-               # XXX this needs to be very fast
-               # and is totally broken ATM
-               f = self.get_file("filelist")
-               f.seek(0)
-
-               return f.read().split()
-
        def get_extractor(self, pakfire):
                return packager.Extractor(pakfire, self)
 
diff --git a/pakfire/packages/file.py b/pakfire/packages/file.py
new file mode 100644 (file)
index 0000000..2b12674
--- /dev/null
@@ -0,0 +1,152 @@
+#!/usr/bin/python
+
+import tarfile
+import os
+import re
+
+from pakfire.errors import FileError
+
+from base import Package
+
+class FilePackage(Package):
+       """
+               This class is a wrapper that reads package data from the (outer)
+               tarball and should never be used solely.
+       """
+       def __init__(self, filename):
+               self.filename = filename
+
+               # Place to keep the tarfile handle and cache the metadata
+               self._archive = None
+               self._metadata = {}
+
+               self.check()
+
+       def check(self):
+               """
+                       Initially check if the given file is of the correct type and
+                       can be opened.
+               """
+               if not tarfile.is_tarfile(self.filename):
+                       raise FileError, "Given file is not of correct format: %s" % self.filename
+
+       def __repr__(self):
+               return "<%s %s>" % (self.__class__.__name__, self.filename)
+
+       def __del__(self):
+               # Close tarfile handle
+               if self._archive:
+                       self._archive.close()
+
+       @property
+       def archive(self):
+               if not self._archive:
+                       self._archive = tarfile.open(self.filename)
+
+               return self._archive
+
+       def get_file(self, name):
+               """
+                       Return a file-object for the given filename.
+
+                       If the file does not exist KeyError is raised.
+               """
+               return self.archive.extractfile(name)
+
+       @property
+       def file_version(self):
+               """
+                       Returns the version of the package metadata.
+               """
+               return self.metadata.get("VERSION")
+
+       @property
+       def metadata(self):
+               """
+                       Read-in the metadata from the "info" file and cache it in _metadata.
+               """
+               if not self._metadata:
+                       f = self.get_file("info")
+
+                       for line in f.readlines():
+                               m = re.match(r"^(\w+)=(.*)$", line)
+                               if m is None:
+                                       continue
+
+                               key, val = m.groups()
+                               self._metadata[key] = val.strip("\"")
+
+                       f.close()
+
+               return self._metadata
+
+       @property
+       def size(self):
+               """
+                       Return the size of the package file.
+               """
+               return os.path.getsize(self.filename)
+
+       def __filelist_from_metadata(self):
+               f = self.get_file("filelist")
+
+               ret = f.readlines()
+
+               f.close()
+
+               return ret
+
+       def __filelist_from_payload(self):
+               # XXX expect uncompressed payload for now
+               # this is very simple and very slow
+
+               t = tarfile.open(fileobj=self.get_file("data.img"))
+
+               ret = ["/%s" % n for n in t.getnames()]
+
+               t.close()
+
+               return ret
+
+       @property
+       def filelist(self):
+               """
+                       Return a list of the files that are contained in the package
+                       payload.
+
+                       At first, we try to get them from the metadata (which is the
+                       'filelist' file).
+                       If the file is not existant, we will open the payload and
+                       read it instead. The latter is a very slow procedure and
+                       should not be used anyway.
+               """
+               try:
+                       return self.__filelist_from_metadata()
+               except KeyError:
+                       return self.__filelist_from_payload()
+
+       @property
+       def payload_compression(self):
+               """
+                       Return the compression type of the payload.
+               """
+               return self.metadata.get("PKG_PAYLOAD_COMP")
+
+       @property
+       def signature(self):
+               """
+                       Read the signature from the archive or return None if no
+                       signature does exist.
+               """
+               ret = None
+               try:
+                       f = self.get_file("signature")
+                       ret = f.read()
+                       f.close()
+
+               except KeyError:
+                       # signature file could not be found
+                       pass
+
+               return ret or None
+
index 91d5376f1189645c94a43d76c4863a7ec6ce7c3c..ad073ee88d8b76bfa08409c3103ea266ecc3df23 100644 (file)
@@ -1,8 +1,8 @@
 #!/usr/bin/python
 
-from base import Package
+from file import FilePackage
 
-class SourcePackage(Package):
+class SourcePackage(FilePackage):
        type = "src"
 
        @property