Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions API/Routes/Upload/UploadRoute.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import shutil
from flask import Blueprint, request, jsonify, send_file, after_this_request
from zipfile import ZipFile
from zipfile import ZipFile, ZIP_DEFLATED
from pathlib import Path, PurePosixPath
from werkzeug.utils import secure_filename
import os, time, json, glob
Expand Down Expand Up @@ -281,7 +281,13 @@ def backupCase():
zippedFile = Path(Config.validate_path(Config.DATA_STORAGE, f"{case}.zip"))

'''File system data storage'''
with ZipFile(zippedFile, 'w') as zipObj:
# DEFLATE rather than the ZipFile default of ZIP_STORED. Case backups are
# JSON/CSV/text (model inputs, solver results, pivot views) which compress
# ~15-30x; storing them uncompressed made the demo archive 48 MB and a real
# country case ~944 MB. Every standard reader (Python zipfile, unzip, OS
# archivers) handles DEFLATE, and the read/extract paths are unchanged, so
# existing STORED backups still restore.
with ZipFile(zippedFile, 'w', compression=ZIP_DEFLATED) as zipObj:
# Iterate over all the files in directory
for folderName, subfolders, filenames in os.walk(str(casePath)):

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ For setup options, use the "--help" flag:

The demo dataset (`CLEWs.Demo.zip`) is hosted as a [GitHub release asset](https://github.com/EAPD-DRB/MUIOGO/releases/tag/demo-data) and downloaded automatically during setup when not already cached locally.

- SHA-256: `facf4bda703f67b3c8b8697fea19d7d49be72bc2029fc05a68c61fd12ba7edde`
- SHA-256: `db92d380b0448f767c4ba56eea5c79b14bcae8fbf8e05a6a0d92d5345bb742c1`

Setup installs demo data by default. The archive is downloaded once, cached in `assets/demo-data/`, and reused on subsequent runs.

Expand Down
12 changes: 11 additions & 1 deletion scripts/setup_dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
MAX_PYTHON = (3, 13) # exclusive
DATA_STORAGE_DIR = PROJECT_ROOT / "WebAPP" / "DataStorage"
DEMO_DATA_ARCHIVE = PROJECT_ROOT / "assets" / "demo-data" / "CLEWs.Demo.zip"
DEMO_DATA_ARCHIVE_SHA256 = "facf4bda703f67b3c8b8697fea19d7d49be72bc2029fc05a68c61fd12ba7edde"
DEMO_DATA_ARCHIVE_SHA256 = "db92d380b0448f767c4ba56eea5c79b14bcae8fbf8e05a6a0d92d5345bb742c1"
DEMO_DATA_ARCHIVE_URL = (
"https://github.com/EAPD-DRB/MUIOGO/releases/download/demo-data/CLEWs.Demo.zip"
)
Expand Down Expand Up @@ -450,6 +450,16 @@ def install_demo_data(force: bool, yes: bool) -> bool:
_print_pass("Demo data already installed", str(DEMO_DATA_REQUIRED_DIRS[0]))
return True

# Self-heal a stale cache: if the cached archive exists but no longer matches
# the pinned hash (e.g. the release asset was recompressed/updated), drop it so
# the download path below re-fetches the current one. Without this a stale
# assets/demo-data/CLEWs.Demo.zip makes the checksum verification further down
# fail hard instead of recovering -- notably on --force-demo-data, which clears
# the extracted dirs but not the cached archive.
if DEMO_DATA_ARCHIVE.exists() and _sha256(DEMO_DATA_ARCHIVE) != DEMO_DATA_ARCHIVE_SHA256:
print(" Cached demo-data archive is stale (hash mismatch); re-downloading ...")
DEMO_DATA_ARCHIVE.unlink()

if not DEMO_DATA_ARCHIVE.exists():
print(" Demo-data archive not found locally; downloading from release asset ...")
DEMO_DATA_ARCHIVE.parent.mkdir(parents=True, exist_ok=True)
Expand Down
Loading