Move ops functions into state

This commit is contained in:
Marc Di Luzio 2024-08-16 23:21:20 +01:00
parent 65db66bff4
commit c9446605bc
3 changed files with 34 additions and 38 deletions

View file

@ -1,26 +0,0 @@
"""File operation helpers"""
import json
import shutil
import pathlib
import os
def load(file: str) -> dict:
"""Load a json file directly as a dict"""
with open(file) as f:
return json.load(f)
def save(file: str, content: dict):
"""
Save out a content dictionary to a file
"""
# Ensure the save directory exists first
dir = pathlib.Path(os.path.dirname(file))
dir.mkdir(parents=True, exist_ok=True)
# Store in an intermediary directory first
intermediate = file + ".nxt"
with open(intermediate, "w") as f:
json.dump(content, f, indent=4)
shutil.move(intermediate, file)

View file

@ -4,7 +4,9 @@ from datetime import datetime
from schema import Schema, Use, Optional from schema import Schema, Use, Optional
from collections.abc import Generator from collections.abc import Generator
from typing import Protocol from typing import Protocol
import matchy.files.ops as ops import json
import shutil
import pathlib
import copy import copy
import logging import logging
from functools import wraps from functools import wraps
@ -169,6 +171,27 @@ def datetime_to_ts(ts: datetime) -> str:
return datetime.strftime(ts, _TIME_FORMAT) return datetime.strftime(ts, _TIME_FORMAT)
def _load(file: str) -> dict:
"""Load a json file directly as a dict"""
with open(file) as f:
return json.load(f)
def _save(file: str, content: dict):
"""
Save out a content dictionary to a file
"""
# Ensure the save directory exists first
dir = pathlib.Path(os.path.dirname(file))
dir.mkdir(parents=True, exist_ok=True)
# Store in an intermediary directory first
intermediate = file + ".nxt"
with open(intermediate, "w") as f:
json.dump(content, f, indent=4)
shutil.move(intermediate, file)
class State(): class State():
def __init__(self, data: dict, file: str | None = None): def __init__(self, data: dict, file: str | None = None):
"""Copy the data, migrate if needed, and validate""" """Copy the data, migrate if needed, and validate"""
@ -196,7 +219,7 @@ class State():
func(tmp, *args, **kwargs) func(tmp, *args, **kwargs)
_SCHEMA.validate(tmp._dict) _SCHEMA.validate(tmp._dict)
if tmp._file: if tmp._file:
ops.save(tmp._file, tmp._dict) _save(tmp._file, tmp._dict)
self._dict = tmp._dict self._dict = tmp._dict
return inner return inner
@ -367,7 +390,7 @@ def load_from_file(file: str) -> State:
""" """
Load the state from a files Load the state from a files
""" """
loaded = ops.load(file) if os.path.isfile(file) else _EMPTY_DICT loaded = _load(file) if os.path.isfile(file) else _EMPTY_DICT
st = State(loaded, file) st = State(loaded, file)
ops.save(file, st._dict) _save(file, st._dict)
return st return st

View file

@ -4,7 +4,6 @@
import matchy.files.state as state import matchy.files.state as state
import tempfile import tempfile
import os import os
import matchy.files.ops as ops
def test_basic_state(): def test_basic_state():
@ -19,11 +18,11 @@ def test_simple_load_reload():
with tempfile.TemporaryDirectory() as tmp: with tempfile.TemporaryDirectory() as tmp:
path = os.path.join(tmp, 'tmp.json') path = os.path.join(tmp, 'tmp.json')
st = state.load_from_file(path) st = state.load_from_file(path)
ops.save(st._file, st._dict) state._save(st._file, st._dict)
ops.save(st._file, st._dict) state._save(st._file, st._dict)
st = state.load_from_file(path) st = state.load_from_file(path)
ops.save(st._file, st._dict) state._save(st._file, st._dict)
st = state.load_from_file(path) st = state.load_from_file(path)
@ -32,13 +31,13 @@ def test_authscope():
with tempfile.TemporaryDirectory() as tmp: with tempfile.TemporaryDirectory() as tmp:
path = os.path.join(tmp, 'tmp.json') path = os.path.join(tmp, 'tmp.json')
st = state.load_from_file(path) st = state.load_from_file(path)
ops.save(st._file, st._dict) state._save(st._file, st._dict)
assert not st.get_user_has_scope(1, state.AuthScope.MATCHER) assert not st.get_user_has_scope(1, state.AuthScope.MATCHER)
st = state.load_from_file(path) st = state.load_from_file(path)
st.set_user_scope(1, state.AuthScope.MATCHER) st.set_user_scope(1, state.AuthScope.MATCHER)
ops.save(st._file, st._dict) state._save(st._file, st._dict)
st = state.load_from_file(path) st = state.load_from_file(path)
assert st.get_user_has_scope(1, state.AuthScope.MATCHER) assert st.get_user_has_scope(1, state.AuthScope.MATCHER)
@ -52,13 +51,13 @@ def test_channeljoin():
with tempfile.TemporaryDirectory() as tmp: with tempfile.TemporaryDirectory() as tmp:
path = os.path.join(tmp, 'tmp.json') path = os.path.join(tmp, 'tmp.json')
st = state.load_from_file(path) st = state.load_from_file(path)
ops.save(st._file, st._dict) state._save(st._file, st._dict)
assert not st.get_user_active_in_channel(1, "2") assert not st.get_user_active_in_channel(1, "2")
st = state.load_from_file(path) st = state.load_from_file(path)
st.set_user_active_in_channel(1, "2", True) st.set_user_active_in_channel(1, "2", True)
ops.save(st._file, st._dict) state._save(st._file, st._dict)
st = state.load_from_file(path) st = state.load_from_file(path)
assert st.get_user_active_in_channel(1, "2") assert st.get_user_active_in_channel(1, "2")