piermesh/src/Daisy/Cache.py

155 lines
4.7 KiB
Python
Raw Normal View History

2024-08-01 01:09:11 +00:00
from Daisy.Daisy import Daisy
import os
2024-11-26 17:43:02 +00:00
import logging
2024-08-01 01:09:11 +00:00
import msgpack
# TODO: Dumping to cacheFile
2024-11-26 17:43:02 +00:00
logger = logging.getLogger("__main__." + __name__)
2024-08-01 01:09:11 +00:00
class Cache:
"""
2024-11-26 17:43:02 +00:00
In memory collection of Daisy records, provides a search functionality currently utilized by `Daisy.Catch.Catch`
2024-08-01 22:03:59 +00:00
`🔗 Source <https://git.utopic.work/PierMesh/piermesh/src/branch/main/Daisy/Cache.py>`__
2024-08-01 01:09:11 +00:00
"""
def __init__(
self,
2024-11-23 03:34:39 +00:00
daisyCryptography,
2024-08-01 01:09:11 +00:00
filepaths=None,
cacheFile=None,
path: str = "daisy",
2024-11-26 17:43:02 +00:00
walk: bool = False
2024-08-01 01:09:11 +00:00
):
"""
Parameters
----------
2024-11-26 17:43:02 +00:00
daisyCryptography: Daisy.CryptographyUtil.SteelPetal
Record cryptography reference
2024-08-01 01:09:11 +00:00
filepaths
Either a list of filepaths to load or None
cacheFile
2024-11-26 17:43:02 +00:00
Path to a cache file which is a collection of paths to load or None
2024-08-01 01:09:11 +00:00
path: str
Path prefix to load records from
walk: bool
Whether to automatically walk the path and load records
"""
2024-11-23 03:34:39 +00:00
self.daisyCryptography = daisyCryptography
2024-08-01 01:09:11 +00:00
self.data = {}
self.path = path
2024-11-23 03:34:39 +00:00
if not os.path.exists(self.path):
os.makedirs(self.path)
2024-11-26 17:43:02 +00:00
if filepaths is not None:
2024-08-01 01:09:11 +00:00
for fp in filepaths:
fp = path + "/" + fp
if os.path.isfile(fp):
2024-11-23 03:34:39 +00:00
self.data[fp] = Daisy(fp, daisyCryptography)
2024-11-26 17:43:02 +00:00
elif cacheFile is not None:
self.cacheFile = cacheFile
2024-08-01 01:09:11 +00:00
with open(cacheFile, "r") as f:
for fp in f.read().split("\n"):
2024-11-23 03:34:39 +00:00
self.data[fp] = Daisy(fp, daisyCryptography)
2024-08-01 01:09:11 +00:00
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
2024-11-23 03:34:39 +00:00
self.data[tpath] = Daisy(tpath, daisyCryptography)
2024-08-01 01:09:11 +00:00
2024-08-12 10:29:58 +00:00
def create(self, path: str, data: dict, remote=False):
2024-08-01 01:09:11 +00:00
"""
Create new record
Parameters
----------
path: str
Path to create record at
data: dict
Data to populate record with
2024-11-26 17:43:02 +00:00
remote: bool
Whether this is a reference to a distributed file (not implemented yet)
2024-08-01 01:09:11 +00:00
"""
2024-11-26 17:43:02 +00:00
if not remote:
2024-08-12 10:29:58 +00:00
with open(self.path + "/" + path, "wb") as f:
f.write(msgpack.dumps(data))
2024-11-26 17:43:02 +00:00
logger.debug("Done creating record")
2024-11-23 03:34:39 +00:00
self.data[path] = Daisy(self.path + "/" + path, self.daisyCryptography)
2024-11-26 17:43:02 +00:00
logger.debug("Done loading to Daisy")
2024-08-12 10:29:58 +00:00
return self.data[path]
else:
2024-11-26 17:43:02 +00:00
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]
2024-08-01 01:09:11 +00:00
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):
2024-11-23 03:34:39 +00:00
self.data[path] = Daisy(self.path + "/" + path, self.daisyCryptography)
2024-08-01 01:09:11 +00:00
return self.data[path]
else:
2024-11-26 17:43:02 +00:00
path = self.path + "/" + path
logger.debug(f"File {path} does not exist")
2024-08-01 01:09:11 +00:00
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):
"""
2024-11-26 17:43:02 +00:00
Search cache for record for records with keys and values matching those
in the keydict
2024-08-01 01:09:11 +00:00
keydict: dict
strict: bool
2024-11-26 17:43:02 +00:00
Whether to require all keys/values match
2024-08-01 01:09:11 +00:00
"""
results = []
for key, val in self.data.items():
val = val.get()
2024-11-26 17:43:02 +00:00
if strict and type(val) is not str:
2024-08-01 01:09:11 +00:00
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])
2024-11-26 17:43:02 +00:00
elif type(val) is not str:
2024-08-01 01:09:11 +00:00
for k, v in keydict.items():
if k in val.keys():
if v in val[k]:
results.append([key, val])
return results