From 39c23ddf379752354215c414ed1f03c6c56ab1dd Mon Sep 17 00:00:00 2001 From: Bastian Kleineidam Date: Wed, 20 Feb 2013 21:16:32 +0100 Subject: [PATCH] Support lzma module in Python 3.3 --- doc/changelog.txt | 2 ++ patoolib/__init__.py | 11 +++++-- patoolib/programs/py_lzma.py | 62 ++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 patoolib/programs/py_lzma.py diff --git a/doc/changelog.txt b/doc/changelog.txt index 4b6b0ea..2e165bc 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -1,5 +1,7 @@ 0.19 "" (released xx.xx.2013) +* Support the lzma module in Python >= 3.3 + 0.18 "Skyfall" (released 15.12.2012) diff --git a/patoolib/__init__.py b/patoolib/__init__.py index 3db028c..62aae81 100644 --- a/patoolib/__init__.py +++ b/patoolib/__init__.py @@ -79,6 +79,13 @@ ArchiveMimetypes = { 'audio/flac': 'flac', } +try: + # use Python 3 lzma module if available + import lzma + py_lzma = ('py_lzma',) +except ImportError: + py_lzma = () + # List of programs supporting the given archive format and command. # If command is None, the program supports all commands (list, extract, ...) # Programs starting with "py_" are Python modules. @@ -208,10 +215,10 @@ ArchivePrograms = { }, # XXX Python 3.3 has native lzma module - use that after porting to 3.3 'lzma': { - 'extract': ('lzma',), + 'extract': ('lzma',) + py_lzma, 'list': ('py_echo',), 'test': ('lzma',), - 'create': ('lzma',), + 'create': ('lzma',) + py_lzma, }, 'rzip': { 'extract': ('rzip',), diff --git a/patoolib/programs/py_lzma.py b/patoolib/programs/py_lzma.py new file mode 100644 index 0000000..a525975 --- /dev/null +++ b/patoolib/programs/py_lzma.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2012 Bastian Kleineidam +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +"""Archive commands for the lzma Python module.""" +from .. import util +import lzma + +READ_SIZE_BYTES = 1024*1024 + +def extract_lzma(archive, compression, cmd, **kwargs): + """Extract a LZMA archive with the lzma Python module.""" + verbose = kwargs['verbose'] + outdir = kwargs['outdir'] + if verbose: + util.log_info('extracting %s...' % archive) + targetname = util.get_single_outfile(outdir, archive) + lzmafile = lzma.LZMAFile(archive) + try: + with open(targetname, 'wb') as targetfile + data = lzmafile.read(READ_SIZE_BYTES) + while data: + targetfile.write(data) + data = lzmafile.read(READ_SIZE_BYTES) + finally: + lzmafile.close() + if verbose: + util.log_info('... extracted to %s' % targetname) + return None + + +def create_lzma(archive, compression, cmd, *args, **kwargs): + """Create a LZMA archive with the lzma Python module.""" + verbose = kwargs['verbose'] + if verbose: + util.log_info('creating %s...' % archive) + if len(args) > 1: + util.log_error('multi-file compression not supported in Python lzma') + lzmafile = lzma.LZMAFile(archive, 'wb') + try: + filename = args[0] + with open(filename) as srcfile: + data = srcfile.read(READ_SIZE_BYTES) + while data: + lzmafile.write(data) + data = srcfile.read(READ_SIZE_BYTES) + if verbose: + util.log_info('... added %s' % filename) + finally: + lzmafile.close() + return None