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 collections.abc import Generator
from typing import Protocol
import matchy.files.ops as ops
import json
import shutil
import pathlib
import copy
import logging
from functools import wraps
@ -169,6 +171,27 @@ def datetime_to_ts(ts: datetime) -> str:
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():
def __init__(self, data: dict, file: str | None = None):
"""Copy the data, migrate if needed, and validate"""
@ -196,7 +219,7 @@ class State():
func(tmp, *args, **kwargs)
_SCHEMA.validate(tmp._dict)
if tmp._file:
ops.save(tmp._file, tmp._dict)
_save(tmp._file, tmp._dict)
self._dict = tmp._dict
return inner
@ -367,7 +390,7 @@ def load_from_file(file: str) -> State:
"""
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)
ops.save(file, st._dict)
_save(file, st._dict)
return st

View file

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