From: Michael Tremer Date: Thu, 10 Mar 2011 10:41:01 +0000 (+0100) Subject: Remove Extractor class and replace it by code that is located in the actions. X-Git-Tag: 0.9.3~78^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=283226775de547d22984712a2517e1a2514bfdcc;p=pakfire.git Remove Extractor class and replace it by code that is located in the actions. --- diff --git a/pakfire/compress.py b/pakfire/compress.py index 779e3179c..19cfb39d7 100644 --- a/pakfire/compress.py +++ b/pakfire/compress.py @@ -16,26 +16,19 @@ PROGRESS_WIDGETS = [ " ", ] - -def __compress_helper(filename, comp, flush, progress=None): +def __compress_helper(i, o, comp, flush, progress=None): if progress: widgets = [ "%-30s " % os.path.basename(filename)] + PROGRESS_WIDGETS maxval = os.path.getsize(filename) - + progress = progressbar.ProgressBar( widgets=widgets, maxval=maxval, - term_width=80, ) progress.start() - i = open(filename) - os.unlink(filename) - - o = open(filename, "w") - size = 0 buf = i.read(BUFFER_SIZE) while buf: @@ -49,14 +42,24 @@ def __compress_helper(filename, comp, flush, progress=None): o.write(flush()) - i.close() - o.close() - if progress: progress.finish() +def compress(filename, filename2=None, algo="xz", progress=None): + i = open(filename) + + if not filename2: + filename2 = filename + os.unlink(filename) + + o = open(filename2, "w") + + compressobj(i, o, algo="xz", progress=None) -def compress(filename, algo="xz", progress=None): + i.close() + o.close() + +def compressobj(i, o, algo="xz", progress=None): comp = None if algo == "xz": comp = lzma.LZMACompressor() @@ -64,11 +67,23 @@ def compress(filename, algo="xz", progress=None): elif algo == "zlib": comp = zlib.compressobj(9) - return __compress_helper(filename, comp.compress, comp.flush, - progress=progress) + return __compress_helper(i, o, comp.compress, comp.flush, progress=progress) + +def decompress(filename, filename2=None, algo="xz", progress=None): + i = open(filename) + + if not filename2: + filename2 = filename + os.unlink(filename) + o = open(filename2, "w") -def decompress(filename, algo="xz", progress=None): + decompressobj(i, o, algo="xz", progress=None) + + i.close() + o.close() + +def decompressobj(i, o, algo="xz", progress=None): comp = None if algo == "xz": comp = lzma.LZMADecompressor() @@ -76,9 +91,5 @@ def decompress(filename, algo="xz", progress=None): elif algo == "zlib": comp = zlib.decompressobj(9) - return __compress_helper(filename, comp.decompress, comp.flush, - progress=progress) - + return __compress_helper(i, o, comp.decompress, comp.flush, progress=progress) -if __name__ == "__main__": - decompress("test.img", progress=True) diff --git a/pakfire/packages/binary.py b/pakfire/packages/binary.py index 65414724f..efff2a756 100644 --- a/pakfire/packages/binary.py +++ b/pakfire/packages/binary.py @@ -2,8 +2,6 @@ import sys -import packager - from file import FilePackage class BinaryPackage(FilePackage): @@ -47,6 +45,3 @@ class BinaryPackage(FilePackage): def obsoletes(self): return self.metadata.get("PKG_OBSOLETES", "").split() - def get_extractor(self, pakfire): - return packager.Extractor(pakfire, self) - diff --git a/pakfire/packages/packager.py b/pakfire/packages/packager.py index db7ef5a75..66f2872b7 100644 --- a/pakfire/packages/packager.py +++ b/pakfire/packages/packager.py @@ -18,141 +18,6 @@ import pakfire.compress from pakfire.constants import * from pakfire.i18n import _ -class Extractor(object): - def __init__(self, pakfire, pkg): - self.pakfire = pakfire - self.pkg = pkg - - self.archive = pkg.open_archive() - self.data = self.archive.extractfile("data.img") - - self.archive = None - self._tempfile = None - - if self.pkg.payload_compression: - self.uncompress_payload() - else: - self.archive = tarfile.open(fileobj=self.data) - - def __del__(self): - self.data.close() - self.archive.close() - - def cleanup(self): - # XXX not called by anything - if self._tempfile: - os.unlink(self._tempfile) - - def uncompress_payload(self): - # XXX this function uncompresses the data.img file - # and saves the bare tarball to /tmp which takes a lot - # of space. - - # Create a temporary file to save the content in - f, self._tempfile = tempfile.mkstemp() - f = open(self._tempfile, "w") - - if self.pkg.payload_compression == "xz": - decompressor = lzma.LZMADecompressor() - - elif self.pkg.payload_compression == "zlib": - decompressor = zlib.decompressobj() - - buf = self.data.read(BUFFER_SIZE) - while buf: - f.write(decompressor.decompress(buf)) - - buf = self.data.read(BUFFER_SIZE) - - f.write(decompressor.flush()) - f.close() - - self.archive = tarfile.open(self._tempfile) - - @property - def files(self): - return self.archive.getnames() - - def extractall(self, path="/", callback=None): - pbar = self._make_progressbar() - - if pbar: - pbar.start() - else: - print " %s %-20s" % (_("Extracting"), self.pkg.name) - - i = 0 - for name in self.files: - i += 1 - self.extract(name, path, callback=callback) - - if pbar: - pbar.update(i) - - if pbar: - pbar.finish() - #sys.stdout.write("\n") - - def extract(self, filename, path="/", callback=None): - member = self.archive.getmember(filename) - target = os.path.join(path, filename) - - # If the member is a directory and if it already exists, we - # don't need to create it again. - 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) - - # Remove file if it has been existant - if not member.isdir() and os.path.exists(target): - os.unlink(target) - - self.archive.extract(member, path=path) - - # XXX implement setting of xattrs/acls here - - if callback and not member.isdir(): - callback(member.name, hash1="XXX", size=member.size) - - def _make_progressbar(self): - # Don't display a progressbar if we are running in debug mode. - if self.pakfire.config.get("debug"): - return - - if not sys.stdout.isatty(): - return - - widgets = [ - " ", - "%s %-20s" % (_("Extracting:"), self.pkg.name), - " ", - progressbar.Bar(left="[", right="]"), - " ", -# progressbar.Percentage(), -# " ", - progressbar.ETA(), - " ", - ] - - # maxval must be > 0 and so we assume that - # empty packages have at least one file. - maxval = len(self.files) or 1 - - return progressbar.ProgressBar( - widgets=widgets, - maxval=maxval, - term_width=80, - ) # XXX disable because python 2.6 does not support tarfile with filter # diff --git a/pakfire/transaction.py b/pakfire/transaction.py index 3c7006b55..f77337428 100644 --- a/pakfire/transaction.py +++ b/pakfire/transaction.py @@ -1,8 +1,13 @@ #!/usr/bin/python import logging +import os import progressbar +import sys +import tarfile +import tempfile +import compress import depsolve import packages import util @@ -45,7 +50,7 @@ class Action(object): return self.pakfire.repos.local @staticmethod - def make_progress(self, message, maxval): + def make_progress(message, maxval): # Return nothing if stdout is not a terminal. if not sys.stdout.isatty(): return @@ -60,24 +65,10 @@ class Action(object): " ", ] - return progressbar.ProgressBar(widgets=widgets, maxval=maxval) + pb = progressbar.ProgressBar(widgets=widgets, maxval=maxval) + pb.start() - -class ActionExtract(Action): - def run(self): - logging.debug("Extracting package %s" % self.pkg.friendly_name) - - # Create package in the database - virtpkg = self.local.index.add_package(self.pkg) - - # Grab an instance of the extractor and set it up - extractor = self.pkg.get_extractor(self.pakfire) - - # Extract all files to instroot - extractor.extractall(self.pakfire.path) - - # Remove all temporary files - extractor.cleanup() + return pb class ActionCleanup(Action): @@ -161,7 +152,101 @@ class ActionScriptPostUn(ActionScript): class ActionInstall(Action): - pass + def extract(self, message, prefix=None): + logging.debug("Extracting package %s" % self.pkg.friendly_name) + + if prefix is None: + prefix = self.pakfire.path + + # A place to store temporary data. + tempf = None + + # Open package data for read. + archive = self.pkg.open_archive() + + # Get the package payload. + payload = archive.extractfile("data.img") + + # Decompress the payload if needed. + if self.pkg.payload_compression: + # Create a temporary file to store the decompressed output. + garbage, tempf = tempfile.mkstemp(prefix="pakfire") + + i = payload + o = open(tempf, "w") + + # Decompress the package payload. + compress.decompressobj(i, o, algo=self.pkg.payload_compression) + + i.close() + o.close() + + payload = open(tempf) + + # Open the tarball in the package. + payload_archive = tarfile.open(fileobj=payload) + + members = payload_archive.getmembers() + + # Load progressbar. + pb = self.make_progress("%-40s" % message, len(members)) + + i = 0 + for member in members: + # Update progress. + if pb: + i += 1 + pb.update(i) + + target = os.path.join(prefix, member.name) + + # If the member is a directory and if it already exists, we + # don't need to create it again. + + if os.path.exists(target): + if member.isdir(): + continue + + else: + # Remove file if it has been existant + os.unlink(target) + + #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) + + payload_archive.extract(member, path=prefix) + + # XXX implement setting of xattrs/acls here + + # Close all open files. + payload_archive.close() + payload.close() + archive.close() + + if tempf: + os.unlink(tempf) + + # Create package in the database + self.local.index.add_package(self.pkg) + + if pb: + pb.finish() + + def run(self): + self.extract(_("Installing: %s") % self.pkg.name) + + +class ActionUpdate(ActionInstall): + def run(self): + self.extract(_("Updating: %s") % self.pkg.name) class ActionRemove(ActionCleanup): @@ -171,7 +256,7 @@ class ActionRemove(ActionCleanup): if not files: return - self.remove_files(_("Remove: %s") % pkg.name, files) + self.remove_files(_("Removing: %s") % self.pkg.name, files) class TransactionSet(object): @@ -276,22 +361,22 @@ class Transaction(object): # XXX add dependencies for running the script here action_prein = ActionScriptPreIn(self.pakfire, pkg) - action_extract = ActionExtract(self.pakfire, pkg, deps=[action_prein]) + action_install = ActionInstall(self.pakfire, pkg, deps=[action_prein]) # XXX add dependencies for running the script here - action_postin = ActionScriptPostIn(self.pakfire, pkg, deps=[action_extract]) + action_postin = ActionScriptPostIn(self.pakfire, pkg, deps=[action_install]) - for action in (action_prein, action_extract, action_postin): + for action in (action_prein, action_install, action_postin): self.add_action(action) def _update_pkg(self, pkg): assert isinstance(pkg, packages.BinaryPackage) - action_extract = ActionExtract(self.pakfire, pkg) + action_update = ActionUpdate(self.pakfire, pkg) - action_cleanup = ActionCleanup(self.pakfire, pkg, deps=[action_extract]) + action_cleanup = ActionCleanup(self.pakfire, pkg, deps=[action_update]) - for action in (action_extract, action_cleanup): + for action in (action_update, action_cleanup): self.add_action(action) def _remove_pkg(self, pkg): diff --git a/po/pakfire.pot b/po/pakfire.pot index 3fabc6460..dff4e14ad 100644 --- a/po/pakfire.pot +++ b/po/pakfire.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-03-09 20:46+0100\n" +"POT-Creation-Date: 2011-03-10 11:38+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -280,25 +280,27 @@ msgstr "" msgid "Requires" msgstr "" -#: ../pakfire/packages/packager.py:82 -msgid "Extracting" +#: ../pakfire/repository/index.py:300 +#, python-format +msgid "%s: package database" msgstr "" -#: ../pakfire/packages/packager.py:137 -msgid "Extracting:" +#: ../pakfire/transaction.py:130 +#, python-format +msgid "Cleanup: %s" msgstr "" -#: ../pakfire/repository/index.py:300 +#: ../pakfire/transaction.py:244 #, python-format -msgid "%s: package database" +msgid "Installing: %s" msgstr "" -#: ../pakfire/transaction.py:139 +#: ../pakfire/transaction.py:249 #, python-format -msgid "Cleanup: %s" +msgid "Updating: %s" msgstr "" -#: ../pakfire/transaction.py:174 +#: ../pakfire/transaction.py:259 #, python-format -msgid "Remove: %s" +msgid "Removing: %s" msgstr ""