Skip to content

Commit

Permalink
Merge pull request #86 from MartinFalatic/mff-enhance-add-file-from-m…
Browse files Browse the repository at this point in the history
…emory
  • Loading branch information
Changaco authored Oct 20, 2019
2 parents 4375f15 + 3c5b695 commit e682c8c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
29 changes: 27 additions & 2 deletions libarchive/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ def add_files(self, *paths, **kw):

def add_file_from_memory(
self, entry_path, entry_size, entry_data,
filetype=REGULAR_FILE,
permission=DEFAULT_UNIX_PERMISSION
filetype=REGULAR_FILE, permission=DEFAULT_UNIX_PERMISSION,
atime=None, mtime=None, ctime=None, birthtime=None,
):
""""Add file from memory to archive.
Expand All @@ -93,6 +93,14 @@ def add_file_from_memory(
:type filetype: octal number
:param permission: with which permission should entry be created
:type permission: octal number
:param atime: Last access time
:type atime: int seconds or tuple (int seconds, int nanoseconds)
:param mtime: Last modified time
:type mtime: int seconds or tuple (int seconds, int nanoseconds)
:param ctime: Creation time
:type ctime: int seconds or tuple (int seconds, int nanoseconds)
:param birthtime: Birth time (for archive formats that support it)
:type birthtime: int seconds or tuple (int seconds, int nanoseconds)
"""
archive_pointer = self._pointer

Expand All @@ -110,6 +118,23 @@ def add_file_from_memory(
entry_set_size(archive_entry_pointer, entry_size)
entry_set_filetype(archive_entry_pointer, filetype)
entry_set_perm(archive_entry_pointer, permission)

if atime is not None:
if not isinstance(atime, tuple):
atime = (atime, 0)
archive_entry.set_atime(*atime)
if mtime is not None:
if not isinstance(mtime, tuple):
mtime = (mtime, 0)
archive_entry.set_mtime(*mtime)
if ctime is not None:
if not isinstance(ctime, tuple):
ctime = (ctime, 0)
archive_entry.set_ctime(*ctime)
if birthtime is not None:
if not isinstance(birthtime, tuple):
birthtime = (birthtime, 0)
archive_entry.set_birthtime(*birthtime)
write_header(archive_pointer, archive_entry_pointer)

for chunk in entry_data:
Expand Down
21 changes: 20 additions & 1 deletion tests/test_rwx.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import json

import libarchive
from libarchive.entry import format_time
from libarchive.extract import EXTRACT_OWNER, EXTRACT_PERM, EXTRACT_TIME
from libarchive.write import memory_writer
from mock import patch
Expand Down Expand Up @@ -131,12 +132,23 @@ def test_adding_entry_from_memory(archfmt, data_bytes):

blocks = []

archfmt = 'zip'
has_birthtime = archfmt != 'zip'

atime = (1482144741, 495628118)
mtime = (1482155417, 659017086)
ctime = (1482145211, 536858081)
btime = (1482144740, 495628118) if has_birthtime else None

def write_callback(data):
blocks.append(data[:])
return len(data)

with libarchive.custom_writer(write_callback, archfmt) as archive:
archive.add_file_from_memory(entry_path, entry_size, entry_data)
archive.add_file_from_memory(
entry_path, entry_size, entry_data,
atime=atime, mtime=mtime, ctime=ctime, birthtime=btime
)

buf = b''.join(blocks)
with libarchive.memory_reader(buf) as memory_archive:
Expand All @@ -145,3 +157,10 @@ def write_callback(data):
actual = b''.join(archive_entry.get_blocks())
assert expected == actual
assert archive_entry.path == entry_path
assert archive_entry.atime in (atime[0], format_time(*atime))
assert archive_entry.mtime in (mtime[0], format_time(*mtime))
assert archive_entry.ctime in (ctime[0], format_time(*ctime))
if has_birthtime:
assert archive_entry.birthtime in (
btime[0], format_time(*btime)
)

0 comments on commit e682c8c

Please sign in to comment.