Added write and read history file functions

This commit is contained in:
Qubasa
2023-12-31 15:17:12 +01:00
parent e0bba046ea
commit 7069d746ad
3 changed files with 37 additions and 20 deletions

View File

@@ -9,7 +9,7 @@ from clan_cli.flakes.inspect import FlakeConfig, inspect_flake
from ..clan_uri import ClanURI from ..clan_uri import ClanURI
from ..dirs import user_history_file from ..dirs import user_history_file
from ..locked_open import locked_open from ..locked_open import read_history_file, write_history_file
class EnhancedJSONEncoder(json.JSONEncoder): class EnhancedJSONEncoder(json.JSONEncoder):
@@ -34,14 +34,12 @@ def list_history() -> list[HistoryEntry]:
if not user_history_file().exists(): if not user_history_file().exists():
return [] return []
with locked_open(user_history_file(), "r") as f: try:
try: parsed = read_history_file()
content: str = f.read() logs = [HistoryEntry(**p) for p in parsed]
parsed: list[dict] = json.loads(content) except (json.JSONDecodeError, TypeError) as ex:
logs = [HistoryEntry(**p) for p in parsed] print("Failed to load history. Invalid JSON.")
except (json.JSONDecodeError, TypeError) as ex: print(f"{user_history_file()}: {ex}")
print("Failed to load history. Invalid JSON.")
print(f"{user_history_file()}: {ex}")
return logs return logs
@@ -69,9 +67,7 @@ def add_history(uri: ClanURI) -> list[HistoryEntry]:
) )
logs.append(history) logs.append(history)
with locked_open(user_history_file(), "w+") as f: write_history_file(logs)
f.write(json.dumps(logs, cls=EnhancedJSONEncoder, indent=4))
f.truncate()
return logs return logs

View File

@@ -2,12 +2,10 @@
import argparse import argparse
import copy import copy
import datetime import datetime
import json
from ..dirs import user_history_file from ..locked_open import write_history_file
from ..locked_open import locked_open
from ..nix import nix_metadata from ..nix import nix_metadata
from .add import EnhancedJSONEncoder, HistoryEntry, list_history from .add import HistoryEntry, list_history
def update_history() -> list[HistoryEntry]: def update_history() -> list[HistoryEntry]:
@@ -29,9 +27,7 @@ def update_history() -> list[HistoryEntry]:
# TODO: Delete stale entries # TODO: Delete stale entries
new_logs.append(new_entry) new_logs.append(new_entry)
with locked_open(user_history_file(), "w+") as f: write_history_file(new_logs)
f.write(json.dumps(new_logs, cls=EnhancedJSONEncoder, indent=4))
f.truncate()
return new_logs return new_logs

View File

@@ -1,11 +1,23 @@
import dataclasses
import fcntl import fcntl
import json
from collections.abc import Generator from collections.abc import Generator
from contextlib import contextmanager from contextlib import contextmanager
from pathlib import Path from pathlib import Path
from typing import Any
from .dirs import user_history_file
class EnhancedJSONEncoder(json.JSONEncoder):
def default(self, o: Any) -> Any:
if dataclasses.is_dataclass(o):
return dataclasses.asdict(o)
return super().default(o)
@contextmanager @contextmanager
def locked_open(filename: str | Path, mode: str = "r") -> Generator: def _locked_open(filename: str | Path, mode: str = "r") -> Generator:
""" """
This is a context manager that provides an advisory write lock on the file specified by `filename` when entering the context, and releases the lock when leaving the context. The lock is acquired using the `fcntl` module's `LOCK_EX` flag, which applies an exclusive write lock to the file. This is a context manager that provides an advisory write lock on the file specified by `filename` when entering the context, and releases the lock when leaving the context. The lock is acquired using the `fcntl` module's `LOCK_EX` flag, which applies an exclusive write lock to the file.
""" """
@@ -13,3 +25,16 @@ def locked_open(filename: str | Path, mode: str = "r") -> Generator:
fcntl.flock(fd, fcntl.LOCK_EX) fcntl.flock(fd, fcntl.LOCK_EX)
yield fd yield fd
fcntl.flock(fd, fcntl.LOCK_UN) fcntl.flock(fd, fcntl.LOCK_UN)
def write_history_file(data: Any) -> None:
with _locked_open(user_history_file(), "w+") as f:
f.write(json.dumps(data, cls=EnhancedJSONEncoder, indent=4))
f.truncate()
def read_history_file() -> list[dict]:
with _locked_open(user_history_file(), "r") as f:
content: str = f.read()
parsed: list[dict] = json.loads(content)
return parsed