mirror of
https://github.com/safishamsi/graphify.git
synced 2026-07-22 15:21:34 +00:00
Rate-limit backup_if_protected to one folder per day via content hash
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
98100f3b35
commit
3efae3827f
+11
-4
@@ -1,5 +1,6 @@
|
||||
# write graph to HTML, JSON, SVG, GraphML, Obsidian vault, and Neo4j Cypher
|
||||
from __future__ import annotations
|
||||
import hashlib
|
||||
import html as _html
|
||||
import json
|
||||
import math
|
||||
@@ -62,10 +63,16 @@ def backup_if_protected(out_dir: Path) -> "Path | None":
|
||||
reason = "+".join(filter(None, ["semantic" if is_semantic else "", "curated" if is_curated else ""]))
|
||||
today = date.today().isoformat()
|
||||
backup_dir = out / today
|
||||
suffix = 2
|
||||
while backup_dir.exists():
|
||||
backup_dir = out / f"{today}_{suffix}"
|
||||
suffix += 1
|
||||
graph_src = out / "graph.json"
|
||||
|
||||
# Skip re-copying if today's backup already has identical graph.json content.
|
||||
# If content differs (graph changed since the last backup today), overwrite
|
||||
# the backup in place — one folder per day, always the latest pre-overwrite state.
|
||||
if backup_dir.exists() and (backup_dir / "graph.json").exists():
|
||||
src_hash = hashlib.sha256(graph_src.read_bytes()).hexdigest()
|
||||
bak_hash = hashlib.sha256((backup_dir / "graph.json").read_bytes()).hexdigest()
|
||||
if src_hash == bak_hash:
|
||||
return backup_dir # identical content, nothing to do
|
||||
|
||||
try:
|
||||
backup_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
+17
-4
@@ -228,8 +228,8 @@ def test_backup_default_labels_only(tmp_path):
|
||||
assert backup_if_protected(tmp_path) is None
|
||||
|
||||
|
||||
def test_backup_same_day_collision(tmp_path):
|
||||
"""Second backup on same day gets _2 suffix."""
|
||||
def test_backup_same_day_no_accumulation(tmp_path):
|
||||
"""Same content on same day returns existing backup dir without re-copying."""
|
||||
from graphify.export import backup_if_protected
|
||||
from datetime import date
|
||||
(tmp_path / "graph.json").write_text('{"nodes":[],"links":[]}')
|
||||
@@ -237,8 +237,21 @@ def test_backup_same_day_collision(tmp_path):
|
||||
b1 = backup_if_protected(tmp_path)
|
||||
b2 = backup_if_protected(tmp_path)
|
||||
assert b1 is not None and b2 is not None
|
||||
assert b1 != b2
|
||||
assert b2.name == f"{date.today().isoformat()}_2"
|
||||
assert b1 == b2 # same dir, no _2 accumulation
|
||||
assert b1.name == date.today().isoformat()
|
||||
|
||||
|
||||
def test_backup_same_day_changed_content(tmp_path):
|
||||
"""Changed graph.json on same day overwrites the existing backup in place."""
|
||||
from graphify.export import backup_if_protected
|
||||
from datetime import date
|
||||
(tmp_path / "graph.json").write_text('{"nodes":[],"links":[]}')
|
||||
(tmp_path / ".graphify_semantic_marker").write_text("{}")
|
||||
b1 = backup_if_protected(tmp_path)
|
||||
(tmp_path / "graph.json").write_text('{"nodes":[{"id":"x"}],"links":[]}')
|
||||
b2 = backup_if_protected(tmp_path)
|
||||
assert b1 == b2 # still one folder per day
|
||||
assert (b2 / "graph.json").read_text() == '{"nodes":[{"id":"x"}],"links":[]}'
|
||||
|
||||
|
||||
def test_backup_env_disable(tmp_path, monkeypatch):
|
||||
|
||||
Reference in New Issue
Block a user