Milestone 1.
This commit is contained in:
40
app/utils/paths.py
Normal file
40
app/utils/paths.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def atomic_write(path: str, data: bytes, mode: int = 0o644) -> None:
|
||||
"""
|
||||
Atomically write bytes to path by writing to a temp file in the same dir and then replacing.
|
||||
"""
|
||||
directory = os.path.dirname(path)
|
||||
os.makedirs(directory, exist_ok=True)
|
||||
fd, tmp_path = tempfile.mkstemp(prefix=".tmp-", dir=directory)
|
||||
try:
|
||||
with os.fdopen(fd, "wb") as tmp_file:
|
||||
tmp_file.write(data)
|
||||
os.chmod(tmp_path, mode)
|
||||
os.replace(tmp_path, path)
|
||||
finally:
|
||||
try:
|
||||
if os.path.exists(tmp_path):
|
||||
os.remove(tmp_path)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def ensure_unique_path(path: str) -> str:
|
||||
"""
|
||||
If path exists, append -2, -3, ... before extension to avoid collision.
|
||||
"""
|
||||
if not os.path.exists(path):
|
||||
return path
|
||||
base, ext = os.path.splitext(path)
|
||||
i = 2
|
||||
while True:
|
||||
candidate = f"{base}-{i}{ext}"
|
||||
if not os.path.exists(candidate):
|
||||
return candidate
|
||||
i += 1
|
Reference in New Issue
Block a user