Rework radar system

This commit is contained in:
Ayzen
2026-10-06 12:32:26 +03:00
parent 552cdc688a
commit 5bb86b7165
299 changed files with 13537 additions and 27763 deletions
+67 -13
View File
@@ -1,12 +1,66 @@
"""Atomic writes for JSON settings shared by GUI and pipeline processes."""
"""Filesystem-safe names and atomic writes shared by storage and pipeline settings."""
from __future__ import annotations
import json
import os
import ctypes
from contextlib import suppress
from pathlib import Path
import tempfile
import stat
import re
from uuid import uuid4
_renameat2 = ctypes.CDLL(None, use_errno=True).renameat2
_renameat2.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p, ctypes.c_uint]
_renameat2.restype = ctypes.c_int
def rename_no_replace(source: Path, destination: Path) -> None:
"""Publish a file or directory atomically, refusing to replace an existing name."""
# Linux AT_FDCWD=-100 and RENAME_NOREPLACE=1; also supported by FAT filesystems.
if _renameat2(-100, os.fsencode(source), -100, os.fsencode(destination), 1):
error = ctypes.get_errno()
raise OSError(error, os.strerror(error), str(destination))
def temporary_file(destination: Path) -> Path:
"""Create a sibling file using the destination's permissions or the current umask."""
path = destination.with_name(f".{destination.name}.{uuid4().hex}.tmp")
descriptor = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o666)
try:
try:
mode = stat.S_IMODE(destination.stat().st_mode)
except FileNotFoundError:
pass
else:
os.fchmod(descriptor, mode)
except BaseException:
path.unlink()
raise
finally:
os.close(descriptor)
return path
def sync_directory(path: Path) -> None:
"""Make directory entry changes durable after replacing or removing files."""
descriptor = os.open(path, os.O_RDONLY | os.O_DIRECTORY)
try:
os.fsync(descriptor)
finally:
os.close(descriptor)
def make_directory(path: Path, *, durable: bool = False) -> None:
"""Create missing parents, optionally syncing each newly created directory entry."""
if not durable:
path.mkdir(parents=True, exist_ok=True)
elif not path.is_dir():
make_directory(path.parent, durable=True)
path.mkdir(exist_ok=True)
sync_directory(path.parent)
def atomic_write_json(path: Path, payload: object, *, durable: bool = False) -> Path:
@@ -21,27 +75,27 @@ def atomic_write_text(path: Path, text: str, *, durable: bool = False) -> Path:
rename one another's work. Durable writes also sync the file and directory;
frequent live settings can omit those syncs to avoid unnecessary disk I/O.
"""
path.parent.mkdir(parents=True, exist_ok=True)
make_directory(path.parent, durable=durable)
temporary = None
try:
with tempfile.NamedTemporaryFile(
mode="w", encoding="utf-8", dir=path.parent,
prefix=f".{path.name}.", suffix=".tmp", delete=False,
) as handle:
temporary = Path(handle.name)
temporary = temporary_file(path)
with temporary.open("w", encoding="utf-8") as handle:
handle.write(text)
if durable:
handle.flush()
os.fsync(handle.fileno())
os.replace(temporary, path)
if durable:
directory_fd = os.open(path.parent, os.O_RDONLY | os.O_DIRECTORY)
try:
os.fsync(directory_fd)
finally:
os.close(directory_fd)
sync_directory(path.parent)
finally:
if temporary is not None:
with suppress(OSError):
temporary.unlink(missing_ok=True)
return path
def sanitize_path_component(name: str) -> str:
"""Convert arbitrary string into filesystem-safe component."""
cleaned = re.sub(r"[^A-Za-z0-9._-]+", "_", name.strip())
cleaned = cleaned.strip("._")
return cleaned or "snapshot"