Skip to content

Commit e682c8c

Browse files
authored
Merge pull request #86 from MartinFalatic/mff-enhance-add-file-from-memory
2 parents 4375f15 + 3c5b695 commit e682c8c

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

libarchive/write.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ def add_files(self, *paths, **kw):
7777

7878
def add_file_from_memory(
7979
self, entry_path, entry_size, entry_data,
80-
filetype=REGULAR_FILE,
81-
permission=DEFAULT_UNIX_PERMISSION
80+
filetype=REGULAR_FILE, permission=DEFAULT_UNIX_PERMISSION,
81+
atime=None, mtime=None, ctime=None, birthtime=None,
8282
):
8383
""""Add file from memory to archive.
8484
@@ -93,6 +93,14 @@ def add_file_from_memory(
9393
:type filetype: octal number
9494
:param permission: with which permission should entry be created
9595
:type permission: octal number
96+
:param atime: Last access time
97+
:type atime: int seconds or tuple (int seconds, int nanoseconds)
98+
:param mtime: Last modified time
99+
:type mtime: int seconds or tuple (int seconds, int nanoseconds)
100+
:param ctime: Creation time
101+
:type ctime: int seconds or tuple (int seconds, int nanoseconds)
102+
:param birthtime: Birth time (for archive formats that support it)
103+
:type birthtime: int seconds or tuple (int seconds, int nanoseconds)
96104
"""
97105
archive_pointer = self._pointer
98106

@@ -110,6 +118,23 @@ def add_file_from_memory(
110118
entry_set_size(archive_entry_pointer, entry_size)
111119
entry_set_filetype(archive_entry_pointer, filetype)
112120
entry_set_perm(archive_entry_pointer, permission)
121+
122+
if atime is not None:
123+
if not isinstance(atime, tuple):
124+
atime = (atime, 0)
125+
archive_entry.set_atime(*atime)
126+
if mtime is not None:
127+
if not isinstance(mtime, tuple):
128+
mtime = (mtime, 0)
129+
archive_entry.set_mtime(*mtime)
130+
if ctime is not None:
131+
if not isinstance(ctime, tuple):
132+
ctime = (ctime, 0)
133+
archive_entry.set_ctime(*ctime)
134+
if birthtime is not None:
135+
if not isinstance(birthtime, tuple):
136+
birthtime = (birthtime, 0)
137+
archive_entry.set_birthtime(*birthtime)
113138
write_header(archive_pointer, archive_entry_pointer)
114139

115140
for chunk in entry_data:

tests/test_rwx.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import json
77

88
import libarchive
9+
from libarchive.entry import format_time
910
from libarchive.extract import EXTRACT_OWNER, EXTRACT_PERM, EXTRACT_TIME
1011
from libarchive.write import memory_writer
1112
from mock import patch
@@ -131,12 +132,23 @@ def test_adding_entry_from_memory(archfmt, data_bytes):
131132

132133
blocks = []
133134

135+
archfmt = 'zip'
136+
has_birthtime = archfmt != 'zip'
137+
138+
atime = (1482144741, 495628118)
139+
mtime = (1482155417, 659017086)
140+
ctime = (1482145211, 536858081)
141+
btime = (1482144740, 495628118) if has_birthtime else None
142+
134143
def write_callback(data):
135144
blocks.append(data[:])
136145
return len(data)
137146

138147
with libarchive.custom_writer(write_callback, archfmt) as archive:
139-
archive.add_file_from_memory(entry_path, entry_size, entry_data)
148+
archive.add_file_from_memory(
149+
entry_path, entry_size, entry_data,
150+
atime=atime, mtime=mtime, ctime=ctime, birthtime=btime
151+
)
140152

141153
buf = b''.join(blocks)
142154
with libarchive.memory_reader(buf) as memory_archive:
@@ -145,3 +157,10 @@ def write_callback(data):
145157
actual = b''.join(archive_entry.get_blocks())
146158
assert expected == actual
147159
assert archive_entry.path == entry_path
160+
assert archive_entry.atime in (atime[0], format_time(*atime))
161+
assert archive_entry.mtime in (mtime[0], format_time(*mtime))
162+
assert archive_entry.ctime in (ctime[0], format_time(*ctime))
163+
if has_birthtime:
164+
assert archive_entry.birthtime in (
165+
btime[0], format_time(*btime)
166+
)

0 commit comments

Comments
 (0)