Skip to content

Commit 382ea82

Browse files
authored
Merge pull request #118 from Changaco/v4
2 parents 8256dba + ad73e00 commit 382ea82

12 files changed

Lines changed: 586 additions & 220 deletions

File tree

.github/workflows/main.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: CI
2+
on:
3+
# Trigger the workflow on push or pull request events but only for the master branch
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
# Allow running this workflow manually from the Actions tab
9+
workflow_dispatch:
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v2
15+
- name: Install libarchive
16+
run: sudo apt-get install -y libarchive13
17+
- name: Install Python 3.9
18+
uses: actions/setup-python@v2
19+
with:
20+
python-version: '3.9'
21+
- name: Install Python 3.8
22+
uses: actions/setup-python@v2
23+
with:
24+
python-version: '3.8'
25+
- name: Install Python 3.7
26+
uses: actions/setup-python@v2
27+
with:
28+
python-version: '3.7'
29+
- name: Install tox
30+
run: pip install tox
31+
- name: Run the tests
32+
run: tox

.travis.yml

Lines changed: 0 additions & 42 deletions
This file was deleted.

README.rst

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
.. image:: https://travis-ci.org/Changaco/python-libarchive-c.svg
2-
:target: https://travis-ci.org/Changaco/python-libarchive-c
3-
41
A Python interface to libarchive. It uses the standard ctypes_ module to
52
dynamically load and access the C library.
63

@@ -17,7 +14,7 @@ Compatibility
1714
python
1815
------
1916

20-
python-libarchive-c is currently tested with python 3.6, 3.7, 3.8, and 3.9.
17+
python-libarchive-c is currently tested with python 3.7, 3.8, and 3.9.
2118

2219
If you find an incompatibility with older versions you can send us a small patch,
2320
but we won't accept big changes.
@@ -36,32 +33,86 @@ Import::
3633

3734
import libarchive
3835

39-
To extract an archive to the current directory::
36+
Extracting archives
37+
-------------------
38+
39+
To extract an archive, use the ``extract_file`` function::
4040

41+
os.chdir('/path/to/target/directory')
4142
libarchive.extract_file('test.zip')
4243

43-
``extract_memory`` extracts from a buffer instead, and ``extract_fd`` extracts
44-
from a file descriptor.
44+
Alternatively, the ``extract_memory`` function can be used to extract from a buffer,
45+
and ``extract_fd`` from a file descriptor.
46+
47+
The ``extract_*`` functions all have an integer ``flags`` argument which is passed
48+
directly to the C function ``archive_write_disk_set_options()``. You can import
49+
the ``EXTRACT_*`` constants from the ``libarchive.extract`` module and see the
50+
official description of each flag in the ``archive_write_disk(3)`` man page.
51+
52+
By default, when the ``flags`` argument is ``None``, the ``SECURE_NODOTDOT``,
53+
``SECURE_NOABSOLUTEPATHS`` and ``SECURE_SYMLINKS`` flags are passed to
54+
libarchive, unless the current directory is the root (``/``).
4555

46-
To read an archive::
56+
Reading archives
57+
----------------
58+
59+
To read an archive, use the ``file_reader`` function::
4760

4861
with libarchive.file_reader('test.7z') as archive:
4962
for entry in archive:
5063
for block in entry.get_blocks():
5164
...
5265

53-
``memory_reader`` reads from a memory buffer instead, and ``fd_reader`` reads
54-
from a file descriptor.
66+
Alternatively, the ``memory_reader`` function can be used to read from a buffer,
67+
``fd_reader`` from a file descriptor, ``stream_reader`` from a stream object
68+
(which must support the standard ``readinto`` method), and ``custom_reader``
69+
from anywhere using callbacks.
5570

56-
To create an archive::
71+
To learn about the attributes of the ``entry`` object, see the ``libarchive/entry.py``
72+
source code or run ``help(libarchive.entry.ArchiveEntry)`` in a Python shell.
5773

58-
with libarchive.file_writer('test.tar.gz', 'ustar', 'gzip') as archive:
59-
archive.add_files('libarchive/', 'README.rst')
74+
Displaying progress
75+
~~~~~~~~~~~~~~~~~~~
6076

61-
``memory_writer`` writes to a memory buffer instead, ``fd_writer`` writes to a
62-
file descriptor, and ``custom_writer`` sends the data to a callback function.
77+
If your program processes large archives, you can keep track of its progress
78+
with the ``bytes_read`` attribute. Here's an example of a progress bar using
79+
`tqdm <https://pypi.org/project/tqdm/>`_::
6380

64-
You can also find more thorough examples in the ``tests/`` directory.
81+
with tqdm(total=os.stat(archive_path).st_size, unit='bytes') as pbar, \
82+
libarchive.file_reader(archive_path) as archive:
83+
for entry in archive:
84+
...
85+
pbar.update(archive.bytes_read - pbar.n)
86+
87+
Creating archives
88+
-----------------
89+
90+
To create an archive, use the ``file_writer`` function::
91+
92+
from libarchive.entry import FileType
93+
94+
with libarchive.file_writer('test.tar.gz', 'ustar', 'gzip') as archive:
95+
# Add the `libarchive/` directory and everything in it (recursively),
96+
# then the `README.rst` file.
97+
archive.add_files('libarchive/', 'README.rst')
98+
# Add a regular file defined from scratch.
99+
data = b'foobar'
100+
archive.add_file_from_memory('../escape-test', len(data), data)
101+
# Add a directory defined from scratch.
102+
early_epoch = (42, 42) # 1970-01-01 00:00:42.000000042
103+
archive.add_file_from_memory(
104+
'metadata-test', 0, b'',
105+
filetype=FileType.DIRECTORY, permission=0o755, uid=4242, gid=4242,
106+
atime=early_epoch, mtime=early_epoch, ctime=early_epoch, birthtime=early_epoch,
107+
)
108+
109+
Alternatively, the ``memory_writer`` function can be used to write to a memory buffer,
110+
``fd_writer`` to a file descriptor, and ``custom_writer`` to a callback function.
111+
112+
For each of those functions, the mandatory second argument is the archive format,
113+
and the optional third argument is the compression format (called “filter” in
114+
libarchive). The acceptable values are listed in ``libarchive.ffi.WRITE_FORMATS``
115+
and ``libarchive.ffi.WRITE_FILTERS``.
65116

66117
License
67118
=======

0 commit comments

Comments
 (0)