Refactor: Project structure to MVVM. Add: Basic scaffolding for data service and gui. Add: Build and Utility scripts.

This commit is contained in:
2025-12-06 17:39:27 +01:00
parent 204f50f2df
commit 1695590346
37 changed files with 1094 additions and 121 deletions
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
# Source this script to keep Python bytecode caches outside the source tree.
# source scripts/activate-pycache.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-${0}}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
CACHE_DIR="${PROJECT_ROOT}/bin/pycache"
mkdir -p "${CACHE_DIR}"
export PYTHONPYCACHEPREFIX="${CACHE_DIR}"
echo "PYTHONPYCACHEPREFIX=${PYTHONPYCACHEPREFIX}"
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Prepare the virtual environment and install dependencies.
# Usage: bash scripts/bootstrap.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-${0}}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
VENV_DIR="${PROJECT_ROOT}/.venv"
PYTHON_BIN="${PYTHON_BIN:-python3}"
if ! command -v "${PYTHON_BIN}" >/dev/null 2>&1; then
echo "Python interpreter '${PYTHON_BIN}' not found. Set PYTHON_BIN to override." >&2
exit 1
fi
if [ ! -d "${VENV_DIR}" ]; then
echo "Creating virtual environment at ${VENV_DIR}"
"${PYTHON_BIN}" -m venv "${VENV_DIR}"
else
echo "Reusing existing virtual environment at ${VENV_DIR}"
fi
"${VENV_DIR}/bin/python" -m pip install --upgrade pip
REQ_FILE="${PROJECT_ROOT}/requirements.txt"
if [ -f "${REQ_FILE}" ]; then
"${VENV_DIR}/bin/pip" install -r "${REQ_FILE}"
else
echo "requirements.txt not found at ${REQ_FILE}" >&2
fi
cat <<'EOF'
Virtual environment ready.
Use the helper scripts in scripts/ to run the app, tests, or build artefacts.
EOF
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Build the PySide deployment artefacts into bin/deploy via the provided spec.
# Usage: bash scripts/build.sh [extra deploy args]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-${0}}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
VENV_DIR="${PROJECT_ROOT}/.venv"
PYTHON_BIN="${VENV_DIR}/bin/python"
if [ ! -x "${PYTHON_BIN}" ]; then
echo "Virtualenv not found. Run 'bash scripts/bootstrap.sh' first." >&2
exit 1
fi
SPEC_FILE="${PROJECT_ROOT}/deploy/pysidedeploy.spec"
if [ ! -f "${SPEC_FILE}" ]; then
echo "Deploy spec missing at ${SPEC_FILE}" >&2
exit 1
fi
CACHE_DIR="${PROJECT_ROOT}/bin/pycache"
DEPLOY_DIR="${PROJECT_ROOT}/bin/deploy"
mkdir -p "${CACHE_DIR}" "${DEPLOY_DIR}"
pushd "${PROJECT_ROOT}" >/dev/null
PYTHONPATH="${PROJECT_ROOT}/src${PYTHONPATH:+:${PYTHONPATH}}" \
PYTHONPYCACHEPREFIX="${CACHE_DIR}" \
"${PYTHON_BIN}" -m PySide6.scripts.deploy \
-c "${SPEC_FILE}" \
"src/study_dashboard/main.py" \
"$@"
popd >/dev/null
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Remove stray Python bytecode caches that may have leaked into tracked sources.
# Usage: bash scripts/clean.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-${0}}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
TARGETS=("${PROJECT_ROOT}/src" "${PROJECT_ROOT}/tests")
removed_any=false
remove_pycache_dirs() {
local target="$1"
if [ -d "${target}" ]; then
while IFS= read -r -d '' dir; do
removed_any=true
echo "Removing directory: ${dir#${PROJECT_ROOT}/}"
rm -rf "${dir}"
done < <(find "${target}" -type d -name "__pycache__" -print0)
fi
}
remove_pyc_files() {
local target="$1"
if [ -d "${target}" ]; then
while IFS= read -r -d '' file; do
removed_any=true
echo "Removing file: ${file#${PROJECT_ROOT}/}"
rm -f "${file}"
done < <(find "${target}" -type f \( -name "*.pyc" -o -name "*.pyo" -o -name "*.pyd" \) -print0)
fi
}
for target in "${TARGETS[@]}"; do
remove_pycache_dirs "${target}"
remove_pyc_files "${target}"
done
if [ "${removed_any}" = false ]; then
echo "No cached artefacts found under src/ or tests/."
else
echo "Source tree cleaned. Future commands should run via scripts/ to keep it tidy."
fi
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Run the Study Dashboard application with the configured virtualenv and cache prefix.
# Usage: bash scripts/run-app.sh [--args passed to main]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-${0}}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
VENV_DIR="${PROJECT_ROOT}/.venv"
PYTHON_BIN="${VENV_DIR}/bin/python"
if [ ! -x "${PYTHON_BIN}" ]; then
echo "Virtualenv not found. Run 'bash scripts/bootstrap.sh' first." >&2
exit 1
fi
CACHE_DIR="${PROJECT_ROOT}/bin/pycache"
mkdir -p "${CACHE_DIR}"
PYTHONPATH="${PROJECT_ROOT}/src${PYTHONPATH:+:${PYTHONPATH}}" \
PYTHONPYCACHEPREFIX="${CACHE_DIR}" \
"${PYTHON_BIN}" -m study_dashboard.main "$@"
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Run the default QA suite (pytest, mypy, flake8, black --check).
# Additional arguments are forwarded to pytest.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-${0}}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
VENV_DIR="${PROJECT_ROOT}/.venv"
PYTHON_BIN="${VENV_DIR}/bin/python"
if [ ! -x "${PYTHON_BIN}" ]; then
echo "Virtualenv not found. Run 'bash scripts/bootstrap.sh' first." >&2
exit 1
fi
CACHE_DIR="${PROJECT_ROOT}/bin/pycache"
mkdir -p "${CACHE_DIR}"
export PYTHONPYCACHEPREFIX="${CACHE_DIR}"
export PYTHONPATH="${PROJECT_ROOT}/src${PYTHONPATH:+:${PYTHONPATH}}"
PYTEST_ARGS=("$@")
"${PYTHON_BIN}" -m pytest "${PYTEST_ARGS[@]}"
"${PYTHON_BIN}" -m mypy src
"${VENV_DIR}/bin/flake8" src tests
"${VENV_DIR}/bin/black" --check src tests