The module prepares the metadata of a book and expands a template as Calibre 9.2.1 does with its default tweaks. It takes fields, formats, indexes, and text before and after a field. It refuses template functions and the program modes.
4.2 KiB
4.2 KiB
Notes for coding agents
CWA Bindery is a Flask app. It downloads web fiction with a headless FanFicFare, stores each chapter in SQLite, and sends ePubs to Calibre-Web-Automated (CWA) through the CWA ingest folder.
Commands
uv sync
uv run pytest
uv run ruff check .
uv run ruff format .
node --test "tests/js/*.test.mjs"
Keep the quotes around the glob in the node command. Without them, node reads tests/js/ as a file and fails.
Start a development server with no CWA:
mkdir -p dev/ingest
CWA_ENABLED=false CONFIG_DIR=dev/config INGEST_DIR=dev/ingest TMP_DIR=dev/tmp uv run python -m bindery
The server has no reloader. If you change Python code, restart it. Flask reads bindery/static from disk on each request, so a server that is not restarted sends new JavaScript to old Python routes.
Layout
bindery/fff.pyis the only module that calls FanFicFare.bindery/cwa.pytalks to CWA through OPDS. Bindery never opens the CWA database.bindery/diffing.pyhashes and diffs text, not HTML.bindery/filename_template.pyexpands Calibre's file name templates. It never runs template text as code.bindery/jobs.pykeeps the job queue in SQLite, so jobs survive a restart.tests/fake_cwa.pyis a fake CWA server.
Rules
- Ask before assuming. If requirements are unclear, ask.
- Be brief. In code comments, commit messages, and responses: say what needs saying, nothing more.
- Succinct edits. Change only what is necessary. Don't reformat surrounding code or add unsolicited improvements.
- Unit tests. Always add unit tests for code changes, and vet your changes by running existing unit tests, assessing, and writing new unit tests, or, if necessary, modifying existing tests.
- Ruff before committing. Run
uv run ruff check .anduv run ruff format .before every commit, and commit what they change.
Rules for the code
- The store holds each chapter as the site sent it. When Bindery builds an ePub, rules and the line-break step run only on a copy. Do not write changed text back to the store.
- Bindery identifies a chapter by its URL, after
normalize_chapterurlfrom the FanFicFare adapter. - A chapter that the site removed stays in the book. Do not delete stored chapters in an update.
- A module reads each setting as
config.NAMEat the time it needs it, not at import. Tests change a setting withmonkeypatch.setattr(config, "NAME", value). - The store has no migrations. Add a new table with
CREATE TABLE IF NOT EXISTS. Do not add columns to an existing table unless you also add a migration. - A job must be safe to run again after a restart. Store each piece of work as soon as it is done, and keep progress in
job.result. - Tests for site updates replace
fff.fetch_story,fff.fetch_chapterandfff.collected_imageswithmonkeypatch. Tests never go to a story site. - The web interface builds DOM with
h()fromlib.js, so text is never parsed as HTML. It uses relative URLs and hash routes, so it works underURL_BASE. Each request that changes data sends the headerX-Requested-With: bindery. - Do not download or install browsers to test the web interface. Check the JavaScript with
node --checkand the Node tests, and ask the user to test it in a browser.
Further Notes
- Never use Tailwind CSS tags in generated HTML. Redundant tags like button.button and button.btn should not be needed.
- CSS and HTML should be native and up-to-date, using the latest language features without creating unnecessary HTML elements or complicated CSS.
- CSS should live in one or more dedicated files, never in the HTML.
- Always use vanilla JavaScript when writing frontend code, never a JavaScript framework. Code should, where possible, live in a dedicated JavaScript files.
Commits
- New features get new commits. Keep each commit focused on one logical change.
- Do not add AI attribution lines, such as
Co-Authored-Byor session links, to commit messages. - Each commit must pass the checks on its own.
- Push only at the request of the user.
Writing
Write the README, error messages and UI text in plain English. Use short sentences, active voice and simple tenses. Of the modal verbs, use only "must", "can" and "will". Do not use semicolons or em-dashes.