clean utils
This commit is contained in:
@@ -3,56 +3,11 @@
|
|||||||
# mypy: disable-error-code=unused-awaitable
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Utility functions for analyzers modules."""
|
"""Utility functions for analyzers modules."""
|
||||||
|
|
||||||
import fcntl
|
|
||||||
import json
|
|
||||||
import math
|
import math
|
||||||
import os
|
|
||||||
import struct
|
import struct
|
||||||
import threading
|
|
||||||
import zlib
|
import zlib
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from pathlib import Path
|
from typing import Iterable, Self
|
||||||
from typing import Any, Iterable, Self
|
|
||||||
|
|
||||||
_thread_lock = threading.Lock()
|
|
||||||
|
|
||||||
MAX_PENDING_TIME = int(os.getenv("MAX_PENDING_TIME", "600")) # 10 minutes by default
|
|
||||||
|
|
||||||
|
|
||||||
def update_data(
|
|
||||||
output_dir: Path, new_data: dict[Any, Any], json_filename: str = "results.json"
|
|
||||||
) -> None:
|
|
||||||
"""Thread-safe and process-safe JSON update using lock file and atomic replace."""
|
|
||||||
json_file = Path(output_dir) / json_filename
|
|
||||||
lock_file = json_file.with_suffix(json_file.suffix + ".lock")
|
|
||||||
tmp_file = json_file.with_suffix(json_file.suffix + ".tmp")
|
|
||||||
|
|
||||||
json_file.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
with _thread_lock: # synchronizes across threads
|
|
||||||
with open(lock_file, "w", encoding="utf-8") as lock:
|
|
||||||
fcntl.flock(lock, fcntl.LOCK_EX) # synchronizes across processes
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Read existing JSON
|
|
||||||
data: dict[Any, Any] = {}
|
|
||||||
if json_file.exists():
|
|
||||||
try:
|
|
||||||
with open(json_file, "r", encoding="utf-8") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
except json.JSONDecodeError:
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
# Update with new data
|
|
||||||
data.update(new_data)
|
|
||||||
|
|
||||||
# Write safely to a temp file
|
|
||||||
with open(tmp_file, "w", encoding="utf-8") as f:
|
|
||||||
json.dump(data, f, sort_keys=False)
|
|
||||||
|
|
||||||
os.replace(tmp_file, json_file) # ensures file write is atomic
|
|
||||||
finally:
|
|
||||||
fcntl.flock(lock, fcntl.LOCK_UN)
|
|
||||||
|
|
||||||
|
|
||||||
def get_resolutions() -> list[tuple[int, int]]:
|
def get_resolutions() -> list[tuple[int, int]]:
|
||||||
@@ -291,9 +246,7 @@ class PNG:
|
|||||||
crc = struct.unpack(">I", data[offset : offset + 4])[0]
|
crc = struct.unpack(">I", data[offset : offset + 4])[0]
|
||||||
|
|
||||||
# Unpack IHDR fields
|
# Unpack IHDR fields
|
||||||
width, height, depth, color, _, _, interlace = struct.unpack(
|
width, height, depth, color, _, _, interlace = struct.unpack(">IIBBBBB", ihdr_data)
|
||||||
">IIBBBBB", ihdr_data
|
|
||||||
)
|
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
size=(width, height),
|
size=(width, height),
|
||||||
|
|||||||
Reference in New Issue
Block a user