How-to Guides
Task-oriented recipes for maintaining the app. If you want to understand why things are built this way, see Explanation instead. For the test suite specifically, see Run the Tests.
Regenerate the workout data
src/daily_dose/data/workouts.json and src/daily_dose/www/images/ are generated by scripts/build_workouts_data.py. Re-run it after editing the legacy Rmd source (kept at scripts/_rmd_src/) or the workout photos.
The original photos aren’t kept in this repo. They’re 325MB of raw phone photos, compressed down to ~21MB in www/. To regenerate from scratch:
Install the script’s one extra dependency (already in the
devextra):Pillow.Restore the original photos from the
rmarkdown-archivebranch, which still has them:git archive rmarkdown-archive -- images | tar -xRun the build script:
python3 scripts/build_workouts_data.pyIt parses all five Rmd files, matches dated photos in
images/, prefers the typed entry on any date that has both, and writes the deduplicated result toworkouts.json. Every photo it keeps is re-encoded as a downsized JPEG (~1600px max dimension, quality 82) intosrc/daily_dose/www/images/.If a date heading in the Rmd source is malformed in a way the parser can’t safely handle (wrong heading level, trailing text after the date, …), the script raises
ValueErrornaming the file and line instead of silently merging it into the previous entry. See Design Notes for why.Remove the restored source photos, which aren’t meant to be committed:
rm -rf images/Confirm the data is sane:
uv run pytest tests/test_data.py
Update the tutorial screenshots
The screenshots in Tutorials are checked-in PNGs, not generated at build time, so a UI change won’t update them on its own. To refresh them:
- Launch the app:
shiny run daily_dose.app:app - Install a headless browser once:
pip install playwright && playwright install chromium - Drive the running app with Playwright, screenshotting each state: initial load, after clicking Random Workout, and after clicking On This Day. Run Random Workout a few times to catch both a text and a photo entry.
- Save the results into
tutorials/assets/, overwriting the existing files by name.
Deploy to Posit Connect Cloud
Connect Cloud deploys straight from a public GitHub repo, but it has two fixed expectations that don’t match this project’s layout: the app object must be importable from an app.py at the repo root, and dependencies come from a requirements.txt, not pyproject.toml. Both files already exist here for exactly that reason, and you shouldn’t need to touch either:
requirements.txt(repo root) holds a plainshiny[theme]>=1.0.0, mirroringpyproject.toml’s[project.dependencies]by hand. It has to be a real dependency list: Connect Cloud’s resolver doesn’t runpip install -e ., so an editable-install line here just fails outright (Error determining requirements: / does not appear to be a Python project) instead of installing anything,daily_doseincluded.app.py(repo root) is a shim. Sincedaily_doseis never actually installed on Connect Cloud, it putssrc/onsys.pathbefore importingfrom daily_dose.app import app. Local development still usesdaily_dose.app:appdirectly (see the Tutorials launch command); this file exists only for Connect Cloud’s sake.
To deploy:
- Make sure the repo is public and the latest commit is pushed to
main. Connect Cloud deploys from GitHub, not a local push. - Sign in to Connect Cloud and click Publish.
- Choose Shiny as the app type and select this repository.
- Confirm the branch (
main) and the primary file:app.pyat the repo root, the shim, notsrc/daily_dose/app.py. - Click Publish.
To publish an update later, push to main and use the republish action in Connect Cloud’s content list. It re-clones the repo and reinstalls from requirements.txt, so there’s no separate build step on your end.
Rebuild the docs site
One command from the repo root rebuilds the whole site:
great-docs buildThat’s the homepage from README.md, this guide, Explanation, and the API Reference from daily_dose.core’s docstrings, all written into great-docs/_site/.