Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 47 additions & 11 deletions jsonstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
import json
import os.path
import sys
import io
import pyAesCrypt
from os import stat, remove
from collections import OrderedDict
from copy import deepcopy
from tempfile import mktemp

__all__ = ["JsonStore"]

Expand All @@ -34,11 +38,30 @@ def _do_auto_commit(self):
self._save()

def _load(self):
# Check if file exists. Create it if it doesn't
if not os.path.exists(self._path):
with open(self._path, "w+b") as store:
store.write("{}".encode("utf-8"))
with open(self._path, "r+b") as store:
raw_data = store.read().decode("utf-8")
empty_json_data = "{}".encode(self._encoding)
if self._secure:
tempFile = mktemp()
with open(tempFile, "wb") as tempStore:
tempStore.write(empty_json_data)
pyAesCrypt.encryptFile(tempFile, self._path, self._password, self._bufferSize)
os.remove(tempFile)
else:
with open(self._path, "wb") as store:
store.write(empty_json_data)

# Read the contents of the file
if self._secure:
tempFile = mktemp()
pyAesCrypt.decryptFile(self._path, tempFile, self._password, self._bufferSize)
with open(tempFile, "rb") as tmp:
raw_data = tmp.read().decode(self._encoding)
os.remove(tempFile)
else:
with open(self._path, "rb") as store:
raw_data = store.read().decode(self._encoding)

if not raw_data:
data = OrderedDict()
else:
Expand All @@ -48,26 +71,39 @@ def _load(self):
raise ValueError("Root element is not an object")
self.__dict__["_data"] = data

def get_dump(self):
return self._data

def _save(self):
temp = self._path + "~"
with open(temp, "wb") as store:
output = json.dumps(self._data, indent=self._indent)
store.write(output.encode("utf-8"))
tempFile = temp + "2" if self._secure else temp
with open(temp, "wb") as tempStore:
jsonStr = json.dumps(self._data, indent=self._indent)
data = jsonStr.encode(self._encoding)
tempStore.write(data)

if self._secure:
pyAesCrypt.encryptFile(temp, tempFile, self._password, self._bufferSize)
os.remove(temp)

if sys.version_info >= (3, 3):
os.replace(temp, self._path)
os.replace(tempFile, self._path)
elif os.name == "windows":
os.remove(self._path)
os.rename(temp, self._path)
os.rename(tempFile, self._path)
else:
os.rename(temp, self._path)
os.rename(tempFile, self._path)

def __init__(self, path, indent=2, auto_commit=True):
def __init__(self, path, indent=2, auto_commit=False, password=None):
self.__dict__.update(
{
"_auto_commit": auto_commit,
"_data": None,
"_path": path,
"_encoding": "utf-8",
"_secure": True if password else None,
"_password": password,
"_bufferSize": 64 * 1024,
"_indent": indent,
"_states": [],
}
Expand Down
Loading