Package: libarchive
IntroductionA ctypes-based adapter to libarchive. The source-code is written to be clear
and intuitive.Even 7-Zip is supported for both reading and writing.I could definitely use some help, if any is available. Completeness will
require a bit more work (seelibarchive’s archive.h and archive_entry.h).InstallationPyPI:$ sudo pip install libarchiveNotesThe Ubuntulibarchivepackage maintainer only provides a “libarchive.so” symlink in the dev package so you’ll have to install thelibarchive-devpackage.For example:apt-get install libarchive-devEncryption is not currently supported since it’s not supported in the underlying library (libarchive). Notethis inquiryand thewishlist item.OS X has a system version oflibarchivethat is very old. As a result, many users have encountered issues importing an alternate one. Specifically, often they install a different one via Brew but this will not be [sym]linked into the system like other packages. This is a precaution taken by Brew to prevent undefined behavior in the parts of OS X that depend on the factory version. In order to work around this, you should setLD_LIBRARY_PATH(or prepend ifLD_LIBRARY_PATHis already defined) with the path of the location of the library version you want to use. You’ll want to set this from your user-profile script (unless your environment can not support this and you need to prepend something like “LD_LIBRARY_PATH=/some/path” to the front of the command-line or set it viaos.environabove where you import this package). Atoolhas been provided that will print the path of the first version oflibarchiveinstalled via Brew. Just copy-and-paste it. Thanks to @SkyLeach for discussing the issue and treatments.Task ListDoneTaskXRead entries from physical fileXRead entries from archive hosted in memory bufferXWrite physical files from archiveXLoad memory buffer from archiveXPopulate physical archive from physical filesXPopulate archive hosted in memory buffer_Populate archive entries from memory buffers_Fill-out the entry object’s information/accessorsExamplesTo extract to the current directory from a physical file (and print each
relative filepath):import libarchive.public

for entry in libarchive.public.file_pour('/tmp/test.zip'):
    print(entry)To extract to the current directory from memory:import libarchive.public

with open('/tmp/test.zip', 'rb') as f:
    for entry in libarchive.public.memory_pour(f.read()):
        print(entry)To read files from a physical archive:import libarchive.public

with libarchive.public.file_reader('test.7z') as e:
    for entry in e:
        with open('/tmp/' + str(entry), 'wb') as f:
            for block in entry.get_blocks():
                f.write(block)To read files from memory:import libarchive.public

with open('test.7z', 'rb') as f:
    buffer_ = f.read()
    with libarchive.public.memory_reader(buffer_) as e:
        for entry in e:
            with open('/tmp/' + str(entry), 'wb') as f:
                for block in entry.get_blocks():
                    f.write(block)To specify a format and/or filter for reads (rather than detecting it):import libarchive.public
import libarchive.constants

with open('test.7z', 'rb') as f:
    buffer_ = f.read()
    with libarchive.public.memory_reader(
            buffer_,
            format_code=libarchive.constants.ARCHIVE_FORMAT_TAR_USTAR,
            filter_code=libarchive.constants.ARCHIVE_FILTER_GZIP
        ) as e:
        for entry in e:
            with open('/tmp/' + str(entry), 'wb') as f:
                for block in entry.get_blocks():
                    f.write(block)To read the “filetype” flag for each entry:import libarchive.public

with open('test.7z', 'rb') as f:
    buffer_ = f.read()
    with libarchive.public.memory_reader(f.read()) as e:
        for entry in e:
            print(entry.filetype)The output of this is:EntryFileType(IFREG=True, IFLNK=True, IFSOCK=True, IFCHR=False, IFBLK=False, IFDIR=False, IFIFO=False)
EntryFileType(IFREG=True, IFLNK=True, IFSOCK=True, IFCHR=False, IFBLK=False, IFDIR=False, IFIFO=False)
EntryFileType(IFREG=True, IFLNK=True, IFSOCK=True, IFCHR=False, IFBLK=False, IFDIR=False, IFIFO=False)To create a physical archive from physical files:import libarchive.public
import libarchive.constants

libarchive.public.create_file(
    'create.7z',
    libarchive.constants.ARCHIVE_FORMAT_7ZIP,
    ['/etc/profile']):The path of the file to add will be recorded verbatim.To create an archive in memory from physical files:import libarchive.public
import libarchive.constants

with open('/tmp/new.7z', 'wb') as f:
    def writer(buffer_, length):
        f.write(buffer_)
        return length

    libarchive.public.create_generic(
        writer,
        format_name=libarchive.constants.ARCHIVE_FORMAT_7ZIP,
        files=['/etc/profile']):Testinglibarchiveusesnosefor testing:tests$ ./run.py