added a directory store
This commit is contained in:
parent
5b355a008d
commit
8a32fbfb4d
|
@ -1,3 +1,7 @@
|
|||
from .kvs import KeyValueStore
|
||||
from .directory_store import DirectoryStore
|
||||
|
||||
components = {KeyValueStore.component_type: KeyValueStore}
|
||||
components = {
|
||||
KeyValueStore.component_type: KeyValueStore
|
||||
, DirectoryStore.component_type: DirectoryStore
|
||||
}
|
||||
|
|
84
bunker/backends/directory_store.py
Normal file
84
bunker/backends/directory_store.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
import os
|
||||
import tarfile
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from .component import AbstractComponent
|
||||
|
||||
class DirectoryStore(AbstractComponent):
|
||||
"""
|
||||
This is a store for encrypting the content of a
|
||||
whole directory. Encrypted are all files, ie. ``os.path.isfile``
|
||||
returns true. All other files are ignored.
|
||||
|
||||
Note that if ``delete`` is true all the ignored will be deleted!
|
||||
This should not be a problem, as ``DirectoryStore`` does usually
|
||||
not operate on true directories but on temporary directories that
|
||||
are filled with content by anonther layer.
|
||||
"""
|
||||
component_type = "dir"
|
||||
def __init__(self, bunker, name, password, directory=None, delete=None):
|
||||
AbstractComponent.__init__(self, bunker, name, password)
|
||||
|
||||
if(directory is None):
|
||||
directory = tempfile.mkdtemp()
|
||||
delete = True
|
||||
|
||||
self._directory = directory
|
||||
self._delete = delete
|
||||
|
||||
file_, type_ = bunker._load_component(name, password)
|
||||
if(type_ != self.component_type):
|
||||
raise TypeError(
|
||||
"loaded component type ({}) != required component type({})".format(
|
||||
type_
|
||||
, self.component_type))
|
||||
|
||||
tar = tarfile.TarFile(fileobj=file_, mode="r")
|
||||
print(tar.getmembers())
|
||||
tar.extractall(self._directory)
|
||||
|
||||
|
||||
@classmethod
|
||||
def new(cls, bunker, name, password):
|
||||
directory = tempfile.mkdtemp()
|
||||
delete = True
|
||||
bunker._add_component(name, password, DirectoryStore.component_type)
|
||||
|
||||
file_, type_ = bunker._load_component(name, password)
|
||||
tar = tarfile.TarFile(fileobj=file_, mode="w")
|
||||
|
||||
for fname in os.listdir(directory):
|
||||
if(os.path.isfile(os.path.join(directory, fname))):
|
||||
tar.add(os.path.join(directory, fname), arcname=fname)
|
||||
|
||||
tar.close()
|
||||
bunker._save_component(name, password, file_)
|
||||
|
||||
return cls(bunker, name, password, directory, delete)
|
||||
|
||||
|
||||
def write_back(self):
|
||||
file_, type_ = self._bunker._load_component(self._name, self._password)
|
||||
tar = tarfile.TarFile(fileobj=file_, mode="w")
|
||||
for fname in os.listdir(self._directory):
|
||||
if(os.path.isfile(os.path.join(self._directory, fname))):
|
||||
tar.add(os.path.join(self._directory, fname), arcname=fname)
|
||||
|
||||
tar.close()
|
||||
self._bunker._save_component(self._name, self._password, file_)
|
||||
|
||||
def close(self, notify_bunker=True):
|
||||
self.write_back()
|
||||
self._name = ""
|
||||
self._password = b""
|
||||
|
||||
if(self._delete):
|
||||
shutil.rmtree(self._directory)
|
||||
|
||||
if(notify_bunker):
|
||||
self._bunker.notify_component_is_closed(self)
|
||||
|
||||
def get_directory(self):
|
||||
return self._directory
|
||||
|
55
test/test_backends_directory_store.py
Normal file
55
test/test_backends_directory_store.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
import os
|
||||
import pytest
|
||||
|
||||
from bunker.bunker import Bunker
|
||||
from bunker.backends.directory_store import DirectoryStore
|
||||
|
||||
@pytest.fixture
|
||||
def bunker_and_password(tmpdir):
|
||||
path = os.path.join(str(tmpdir), "test.bunker")
|
||||
bunker = Bunker.open(path)
|
||||
|
||||
return bunker, b"H6ihKLXV8HMQWbJs"
|
||||
|
||||
def test_add_directory_store(bunker_and_password):
|
||||
bunker, password = bunker_and_password
|
||||
|
||||
ds = bunker.add_component("dir", "test.dir", password)
|
||||
|
||||
assert isinstance(ds, DirectoryStore)
|
||||
|
||||
@pytest.fixture
|
||||
def bunker_ds_password_name(tmpdir):
|
||||
path = os.path.join(str(tmpdir), "test.bunker")
|
||||
password = b"H6ihKLXV8HMQWbJs"
|
||||
bunker = Bunker.open(path)
|
||||
|
||||
ds = bunker.add_component("dir", "test.dir", password)
|
||||
|
||||
return bunker, ds, password, "test.dir"
|
||||
|
||||
@pytest.fixture
|
||||
def file_contents():
|
||||
return {
|
||||
"foo.tx": "test 123"
|
||||
, "bar.tx": "foobar"
|
||||
}
|
||||
|
||||
def test_directory_store_add_get_files(bunker_ds_password_name, file_contents):
|
||||
bunker, ds, password, name = bunker_ds_password_name
|
||||
directory = ds.get_directory()
|
||||
for fname, content in file_contents.items():
|
||||
with open(os.path.join(directory, fname), "w") as fout:
|
||||
fout.write(content)
|
||||
ds.close()
|
||||
ds = bunker.get_component(name, password)
|
||||
directory = ds.get_directory()
|
||||
|
||||
for fname, content in file_contents.items():
|
||||
with open(os.path.join(directory, fname), "r") as fin:
|
||||
assert fin.read() == content
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user