summaryrefslogtreecommitdiff
path: root/ick2/persistent.py
diff options
context:
space:
mode:
Diffstat (limited to 'ick2/persistent.py')
-rw-r--r--ick2/persistent.py61
1 files changed, 46 insertions, 15 deletions
diff --git a/ick2/persistent.py b/ick2/persistent.py
index bb0aeb6..1d79e3d 100644
--- a/ick2/persistent.py
+++ b/ick2/persistent.py
@@ -49,33 +49,64 @@ class PersistentStateInterface: # pragma: no cover
raise NotImplementedError()
-class MemoryPersistentState(PersistentStateInterface):
+class FilePersistentState(PersistentStateInterface):
def __init__(self):
- self._res = {}
+ self._dir = None
- def get_resource_ids(self, kind):
- if kind not in self._res:
- return []
- return list(self._res[kind].keys())
+ def get_directory(self):
+ return self._dir
+
+ def set_directory(self, dirname):
+ self._dir = dirname
+
+ def _safe(self, name):
+ return urllib.parse.quote(name, safe='')
+
+ def _unsafe(self, safe):
+ return urllib.parse.unquote(safe)
+
+ def _unsafe_list(self, safe_names):
+ return [self._unsafe(safe) for safe in safe_names]
+
+ def _dirname(self, kind):
+ return os.path.join(self._dir, self._safe(kind))
+
+ def _filename(self, kind, rid):
+ dirname = self._dirname(kind)
+ return os.path.join(dirname, self._safe(rid))
def has_resource(self, kind, rid):
- return kind in self._res and rid in self._res[kind]
+ filename = self._filename(kind, rid)
+ return os.path.exists(filename)
+
+ def get_resource_ids(self, kind):
+ dirname = self._dirname(kind)
+ if os.path.exists(dirname):
+ return self._unsafe_list(os.listdir(dirname))
+ return []
def get_resource(self, kind, rid):
- if kind not in self._res or rid not in self._res[kind]:
+ filename = self._filename(kind, rid)
+ if not os.path.exists(filename):
raise ick2.NotFound(kind=kind, rid=rid)
- return self._res[kind][rid]
+ with open(filename, 'r') as f:
+ as_dict = yaml.load(f, Loader=yaml.CSafeLoader)
+ return resource_from_dict(as_dict)
def write_resource(self, kind, rid, resource):
- if kind not in self._res:
- self._res[kind] = {}
- self._res[kind][rid] = resource
+ dirname = self._dirname(kind)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+
+ filename = self._filename(kind, rid)
+ with open(filename, 'w') as f:
+ yaml.dump(
+ resource.as_dict(), stream=f, Dumper=yaml.CSafeDumper)
def remove_resource(self, kind, rid):
- if kind not in self._res or rid not in self._res[kind]:
- raise ick2.NotFound(kind=kind, rid=rid)
- del self._res[kind][rid]
+ filename = self._filename(kind, rid)
+ os.remove(filename)
class NotFound(Exception):