------------
Introduction
------------
A 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 (see *libarchive*'s archive.h and archive_entry.h).
------------
Installation
------------
PyPI::
$ sudo pip install libarchive
-----
Notes
-----
- The Ubuntu `libarchive` package maintainer only provides a "libarchive.so" symlink in the dev package so you'll have to install the `libarchive-dev` package.
For example::
apt-get install libarchive-dev
- Encryption is not currently supported since it's not supported in the underlying library (*libarchive*). Note `this inquiry <https://github.com/libarchive/libarchive/issues/579>`_ and the `wishlist item <https://github.com/libarchive/libarchive/wiki/WishList#encrypted-backup-support>`_.
- OS X has a system version of `libarchive` that 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 set `LD_LIBRARY_PATH` (or prepend if `LD_LIBRARY_PATH` is 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 via `os.environ` above where you import this package). A `tool <tools/brew_find_libarchive>`_ has been provided that will print the path of the first version of `libarchive` installed via Brew. Just copy-and-paste it. Thanks to @SkyLeach for discussing the issue and treatments.
---------
Task List
---------
===== =================================================
Done Task
===== =================================================
X Read entries from physical file
X Read entries from archive hosted in memory buffer
X Write physical files from archive
X Load memory buffer from archive
X Populate physical archive from physical files
X Populate archive hosted in memory buffer
_ Populate archive entries from memory buffers
_ Fill-out the entry object's information/accessors
===== =================================================
--------
Examples
--------
To 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
for entry in libarchive.public.create_file(
'create.7z',
libarchive.constants.ARCHIVE_FORMAT_7ZIP,
['/etc/profile']):
print(entry)
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
for entry in libarchive.public.create_generic(
writer,
format_name=libarchive.constants.ARCHIVE_FORMAT_7ZIP,
files=['/etc/profile']):
print(entry)
-------
Testing
-------
*libarchive* uses `nose <https://nose.readthedocs.org>`_ for testing::
tests$ ./run.py
Raw data
{
"_id": null,
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"cheesecake_code_kwalitee_id": null,
"keywords": "archive libarchive 7z tar bz2 zip gz",
"upload_time": "2017-09-25 05:35:08",
"author": "Dustin Oprea",
"home_page": "https://github.com/dsoprea/PyEasyArchive",
"github_user": "dsoprea",
"download_url": "https://pypi.python.org/packages/66/32/a05f6f90d0973ee1a64e11a51f6e3679f2b78c578eb7d761f4db823c3d91/libarchive-0.4.4.tar.gz",
"platform": "",
"version": "0.4.4",
"cheesecake_documentation_id": null,
"description": "------------\nIntroduction\n------------\n\nA ctypes-based adapter to libarchive. The source-code is written to be clear \nand intuitive.\n\nEven 7-Zip is supported for both reading and writing.\n\nI could definitely use some help, if any is available. Completeness will \nrequire a bit more work (see *libarchive*'s archive.h and archive_entry.h).\n\n\n------------\nInstallation\n------------\n\nPyPI::\n\n $ sudo pip install libarchive\n\n\n-----\nNotes\n-----\n\n- The Ubuntu `libarchive` package maintainer only provides a \"libarchive.so\" symlink in the dev package so you'll have to install the `libarchive-dev` package.\n\n For example::\n\n apt-get install libarchive-dev\n \n- Encryption is not currently supported since it's not supported in the underlying library (*libarchive*). Note `this inquiry <https://github.com/libarchive/libarchive/issues/579>`_ and the `wishlist item <https://github.com/libarchive/libarchive/wiki/WishList#encrypted-backup-support>`_.\n\n- OS X has a system version of `libarchive` that 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 set `LD_LIBRARY_PATH` (or prepend if `LD_LIBRARY_PATH` is 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 via `os.environ` above where you import this package). A `tool <tools/brew_find_libarchive>`_ has been provided that will print the path of the first version of `libarchive` installed via Brew. Just copy-and-paste it. Thanks to @SkyLeach for discussing the issue and treatments.\n\n\n---------\nTask List\n---------\n\n===== =================================================\nDone Task\n===== =================================================\n X Read entries from physical file\n X Read entries from archive hosted in memory buffer\n X Write physical files from archive\n X Load memory buffer from archive\n X Populate physical archive from physical files\n X Populate archive hosted in memory buffer\n _ Populate archive entries from memory buffers\n _ Fill-out the entry object's information/accessors\n===== =================================================\n\n\n--------\nExamples\n--------\n\nTo extract to the current directory from a physical file (and print each \nrelative filepath)::\n\n import libarchive.public\n\n for entry in libarchive.public.file_pour('/tmp/test.zip'):\n print(entry)\n\nTo extract to the current directory from memory::\n\n import libarchive.public\n\n with open('/tmp/test.zip', 'rb') as f:\n for entry in libarchive.public.memory_pour(f.read()):\n print(entry)\n\nTo read files from a physical archive::\n\n import libarchive.public\n\n with libarchive.public.file_reader('test.7z') as e:\n for entry in e:\n with open('/tmp/' + str(entry), 'wb') as f:\n for block in entry.get_blocks():\n f.write(block)\n\nTo read files from memory::\n\n import libarchive.public\n\n with open('test.7z', 'rb') as f:\n buffer_ = f.read()\n with libarchive.public.memory_reader(buffer_) as e:\n for entry in e:\n with open('/tmp/' + str(entry), 'wb') as f:\n for block in entry.get_blocks():\n f.write(block)\n\nTo specify a format and/or filter for reads (rather than detecting it)::\n\n import libarchive.public\n import libarchive.constants\n\n with open('test.7z', 'rb') as f:\n buffer_ = f.read()\n with libarchive.public.memory_reader(\n buffer_,\n format_code=libarchive.constants.ARCHIVE_FORMAT_TAR_USTAR, \n filter_code=libarchive.constants.ARCHIVE_FILTER_GZIP\n ) as e:\n for entry in e:\n with open('/tmp/' + str(entry), 'wb') as f:\n for block in entry.get_blocks():\n f.write(block)\n\nTo read the \"filetype\" flag for each entry::\n\n import libarchive.public\n\n with open('test.7z', 'rb') as f:\n buffer_ = f.read()\n with libarchive.public.memory_reader(f.read()) as e:\n for entry in e:\n print(entry.filetype)\n\nThe output of this is::\n\n EntryFileType(IFREG=True, IFLNK=True, IFSOCK=True, IFCHR=False, IFBLK=False, IFDIR=False, IFIFO=False)\n EntryFileType(IFREG=True, IFLNK=True, IFSOCK=True, IFCHR=False, IFBLK=False, IFDIR=False, IFIFO=False)\n EntryFileType(IFREG=True, IFLNK=True, IFSOCK=True, IFCHR=False, IFBLK=False, IFDIR=False, IFIFO=False)\n\nTo create a physical archive from physical files::\n\n import libarchive.public\n import libarchive.constants\n\n for entry in libarchive.public.create_file(\n 'create.7z',\n libarchive.constants.ARCHIVE_FORMAT_7ZIP, \n ['/etc/profile']):\n print(entry)\n\nTo create an archive in memory from physical files::\n\n import libarchive.public\n import libarchive.constants\n\n with open('/tmp/new.7z', 'wb') as f:\n def writer(buffer_, length):\n f.write(buffer_)\n return length\n\n for entry in libarchive.public.create_generic(\n writer,\n format_name=libarchive.constants.ARCHIVE_FORMAT_7ZIP, \n files=['/etc/profile']):\n print(entry)\n\n\n-------\nTesting\n-------\n\n*libarchive* uses `nose <https://nose.readthedocs.org>`_ for testing::\n\n tests$ ./run.py",
"lcname": "libarchive",
"name": "libarchive",
"github": true,
"coveralls": false,
"bugtrack_url": null,
"license": "GPL 2",
"travis_ci": false,
"github_project": "PyEasyArchive",
"summary": "Python adapter for universal, libarchive-based archive access.",
"split_keywords": [
"archive",
"libarchive",
"7z",
"tar",
"bz2",
"zip",
"gz"
],
"author_email": "myselfasunder@gmail.com",
"urls": [
{
"has_sig": false,
"upload_time": "2017-09-25T05:35:08",
"comment_text": "",
"python_version": "source",
"url": "https://pypi.python.org/packages/66/32/a05f6f90d0973ee1a64e11a51f6e3679f2b78c578eb7d761f4db823c3d91/libarchive-0.4.4.tar.gz",
"md5_digest": "7ed2425b05228f1e93e5e0bcf52e4150",
"downloads": 0,
"filename": "libarchive-0.4.4.tar.gz",
"packagetype": "sdist",
"path": "66/32/a05f6f90d0973ee1a64e11a51f6e3679f2b78c578eb7d761f4db823c3d91/libarchive-0.4.4.tar.gz",
"size": 13915
}
],
"cheesecake_installability_id": null
}