bunker/bunker/backends/directory_store.py

85 lines
2.4 KiB
Python

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 = "ds"
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