Harden JSON storage (atomic writes + crash-safe loads) + suggestions lightbulb
- storage.py: atomic save_json (temp+fsync+os.replace) and load_json that survives missing/corrupt files (moves corrupt aside). Closes #11/#12. - route all data modules + app.py helpers through storage (closes #31 core); fixes mutable DEFAULT_FUNDS/DEFAULT_CARS return (#23). - gunicorn --workers 1 --threads 4 to remove the write race (#13); strip Dockerfile template scaffolding (#40). - base.html: 💡 suggestions link in the shared nav (shows on every page). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
23
assets.py
23
assets.py
@@ -1,5 +1,7 @@
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
from storage import load_json, save_json
|
||||
|
||||
DATA_DIR = os.environ.get("DATA_DIR", os.path.join(os.path.dirname(__file__), "data"))
|
||||
ASSETS_FILE = os.path.join(DATA_DIR, "assets.json")
|
||||
@@ -44,20 +46,19 @@ ASSET_CATEGORIES = ["Investments", "Real Estate", "Equipment", "Other Valuables"
|
||||
|
||||
|
||||
def load_assets():
|
||||
if os.path.exists(ASSETS_FILE):
|
||||
with open(ASSETS_FILE) as f:
|
||||
data = json.load(f)
|
||||
# migrate old format if needed
|
||||
if "other_assets" not in data:
|
||||
data["other_assets"] = []
|
||||
return data
|
||||
save_assets({"personal": DEFAULT_CARS, "flips": [], "other_assets": []})
|
||||
return {"personal": DEFAULT_CARS, "flips": [], "other_assets": []}
|
||||
data = load_json(ASSETS_FILE, None)
|
||||
if data is None:
|
||||
data = {"personal": copy.deepcopy(DEFAULT_CARS), "flips": [], "other_assets": []}
|
||||
save_assets(data)
|
||||
return data
|
||||
# migrate old format if needed
|
||||
if "other_assets" not in data:
|
||||
data["other_assets"] = []
|
||||
return data
|
||||
|
||||
|
||||
def save_assets(data):
|
||||
with open(ASSETS_FILE, "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
save_json(ASSETS_FILE, data)
|
||||
|
||||
|
||||
def car_display_name(car):
|
||||
|
||||
Reference in New Issue
Block a user