155 lines
4.7 KiB
Python
Executable File
155 lines
4.7 KiB
Python
Executable File
from Daisy.Daisy import Daisy
|
|
|
|
import os
|
|
import logging
|
|
|
|
import msgpack
|
|
|
|
# TODO: Dumping to cacheFile
|
|
|
|
|
|
logger = logging.getLogger("__main__." + __name__)
|
|
|
|
class Cache:
|
|
"""
|
|
In memory collection of Daisy records, provides a search functionality currently utilized by `Daisy.Catch.Catch`
|
|
|
|
`🔗 Source <https://git.utopic.work/PierMesh/piermesh/src/branch/main/Daisy/Cache.py>`__
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
daisyCryptography,
|
|
filepaths=None,
|
|
cacheFile=None,
|
|
path: str = "daisy",
|
|
walk: bool = False
|
|
):
|
|
"""
|
|
Parameters
|
|
----------
|
|
daisyCryptography: Daisy.CryptographyUtil.SteelPetal
|
|
Record cryptography reference
|
|
|
|
filepaths
|
|
Either a list of filepaths to load or None
|
|
|
|
cacheFile
|
|
Path to a cache file which is a collection of paths to load or None
|
|
|
|
path: str
|
|
Path prefix to load records from
|
|
|
|
walk: bool
|
|
Whether to automatically walk the path and load records
|
|
"""
|
|
self.daisyCryptography = daisyCryptography
|
|
self.data = {}
|
|
self.path = path
|
|
|
|
if not os.path.exists(self.path):
|
|
os.makedirs(self.path)
|
|
|
|
if filepaths is not None:
|
|
for fp in filepaths:
|
|
fp = path + "/" + fp
|
|
if os.path.isfile(fp):
|
|
self.data[fp] = Daisy(fp, daisyCryptography)
|
|
elif cacheFile is not None:
|
|
self.cacheFile = cacheFile
|
|
with open(cacheFile, "r") as f:
|
|
for fp in f.read().split("\n"):
|
|
self.data[fp] = Daisy(fp, daisyCryptography)
|
|
elif walk:
|
|
for root, dirs, files in os.walk(self.path):
|
|
for p in dirs + files:
|
|
if not (".json" in p):
|
|
if not (".md" in p):
|
|
tpath = root + "/" + p
|
|
self.data[tpath] = Daisy(tpath, daisyCryptography)
|
|
|
|
def create(self, path: str, data: dict, remote=False):
|
|
"""
|
|
Create new record
|
|
|
|
Parameters
|
|
----------
|
|
path: str
|
|
Path to create record at
|
|
|
|
data: dict
|
|
Data to populate record with
|
|
|
|
remote: bool
|
|
Whether this is a reference to a distributed file (not implemented yet)
|
|
"""
|
|
if not remote:
|
|
with open(self.path + "/" + path, "wb") as f:
|
|
f.write(msgpack.dumps(data))
|
|
logger.debug("Done creating record")
|
|
self.data[path] = Daisy(self.path + "/" + path, self.daisyCryptography)
|
|
logger.debug("Done loading to Daisy")
|
|
return self.data[path]
|
|
else:
|
|
logger.debug("Not that (you shouldn't be here yet, remote Daisy links aren't ready yet)")
|
|
# TODO: Full remote path functionality
|
|
pass
|
|
# self.data[path] = Ref(path, remote)
|
|
# return self.data[path]
|
|
|
|
def get(self, path: str):
|
|
"""
|
|
Get record at path, else return False
|
|
|
|
path: str
|
|
Path of record
|
|
"""
|
|
if path in self.data.keys():
|
|
return self.data[path]
|
|
else:
|
|
if os.path.exists(self.path + "/" + path):
|
|
self.data[path] = Daisy(self.path + "/" + path, self.daisyCryptography)
|
|
return self.data[path]
|
|
else:
|
|
path = self.path + "/" + path
|
|
logger.debug(f"File {path} does not exist")
|
|
return False
|
|
|
|
def refresh(self):
|
|
"""
|
|
Reload from disk to memory
|
|
"""
|
|
for key in self.data.keys():
|
|
self.data[key].read()
|
|
|
|
def search(self, keydict: dict, strict: bool = True):
|
|
"""
|
|
Search cache for record for records with keys and values matching those
|
|
in the keydict
|
|
|
|
keydict: dict
|
|
|
|
strict: bool
|
|
Whether to require all keys/values match
|
|
"""
|
|
results = []
|
|
for key, val in self.data.items():
|
|
val = val.get()
|
|
if strict and type(val) is not str:
|
|
addcheck = False
|
|
for k, v in keydict.items():
|
|
if k in val.keys():
|
|
if v in val[k]:
|
|
addcheck = True
|
|
else:
|
|
addcheck = False
|
|
break
|
|
if addcheck:
|
|
results.append([key, val])
|
|
elif type(val) is not str:
|
|
for k, v in keydict.items():
|
|
if k in val.keys():
|
|
if v in val[k]:
|
|
results.append([key, val])
|
|
return results
|