ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
Every classic, rewritten sentence-by-sentence into modern English. Read side-by-side with the original, or just the plain version. Free.
EducationPython · JavaScriptGitHub @pengyaocOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Summra Plain English Book Reader
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Summra — Read the Classics in Plain English
Summra is a web app that makes public-domain classics easier to read. Every book is paired with two AI-generated summaries (a short overview and a fuller summary), chapter-by-chapter summaries, AI-generated chapter illustrations, optional audio narration, and — most importantly — a sentence-by-sentence rewrite of the original text in modern English, viewable side-by-side with the original.Read the full README ↗Generated book audio/images are deployment data and are intentionally absent from Git (including history). Existing VM files are preserved; see media deployment before provisioning a fresh clone.
Kindle fullscreen launcher scripts, covers and setup: deploy/kindle/README.md.
Summra is a web app that makes public-domain classics easier to read. Every book is paired with two AI-generated summaries (a short overview and a fuller summary), chapter-by-chapter summaries, AI-generated chapter illustrations, optional audio narration, and — most importantly — a sentence-by-sentence rewrite of the original text in modern English, viewable side-by-side with the original.
Currently ships with ~90 books from Project Gutenberg covering Dickens, Austen, Doyle, Tolstoy, Twain, Hardy, Dostoyevsky, the Greek classics, philosophy, and more.
summra/
├── shared/ # Code both apps use: web basics, Kindle detection, reader index
│ ├── auth/ # Auth blueprint + user DB models (gated by FEATURE_AUTH)
│ ├── progress/ # Reading-progress blueprint (gated by FEATURE_AUTH)
│ └── reader/ # Continuous-reader index mixin
├── plainly/ # The Plainly app
│ ├── app_base.py # Shared Flask setup (used by dev + prod)
│ ├── app.py # Dev entry point — registers live Gemini TTS generation
│ ├── app_prod.py # Prod entry point — TTS serves pre-generated files only
│ ├── config.py # Models, rate limits, feature flags, paths
│ ├── models.py # Content DB (books, chapters, summaries, categories, authors, blog…)
│ ├── routes/ # Page + API blueprints
│ ├── gemini_tts_handler.py# Gemini 2.5 Flash TTS client
│ ├── tts_utils.py # Provider-agnostic chunking, stitching, cache lookup
│ ├── frontend/
│ │ ├── templates/ # index.html (SPA shell), manifest.json, sitemap.xml
│ │ └── static/ # css/, js/, covers/, illustrations/, audio/, guides/, images/
│ └── scripts/
│ ├── content/ # generate_summaries.py (main ingestion), modern-English rewrite, slugs, chapter cleanup, author bios
│ ├── audio/ # Offline TTS batches, audio backfill, filename migration
│ ├── images/ # Cover download, chapter illustrations, hero images, app icon, resize helpers
│ ├── categorization/ # Category assignment + master-category generation
│ ├── migrations/ # One-shot schema migrations
│ ├── backfills/ # Idempotent backfills after schema/field changes
│ ├── audits/ # Read-only inspections (chapter-text audit, validate_chapter_split, etc.)
│ ├── book_fixes/ # Per-book one-shot fixes (mostly historical)
│ ├── blog/ # Blog import + Unsplash header-image assignment
│ ├── archive/ # Dead-end or destructive scripts — read before running
│ └── README.md # Per-folder index
├── distill/ # Second app (placeholder package, built later)
├── data/
│ ├── books/ # Source .txt files (Project Gutenberg)
│ ├── character_briefs/ # Per-book character/style briefs for illustration consistency
│ └── database.db # Content SQLite database (gitignored)
├── summra.db # User SQLite database (gitignored, project root)
├── deploy/ # nginx, systemd, gunicorn, GCP setup scripts (e2-micro + e2-small)
├── docs/ # PRD.md, ERD.md, USAGE.md, marketing/, archive/
├── tests/ # pytest unit suite + e2e/ Playwright harness
├── CLAUDE.md # Instructions for Claude Code sessions (work log, TDD, parser quirks)
├── WORK_LOG.md # Append-only log of completed and in-progress work
├── requirements-prod.txt # Prod deps (no TTS model)
├── plainly/requirements.txt # Dev deps
└── .env.example
Two databases are intentional: content lives in data/database.db (large, regeneratable from data/books/); user accounts and reading progress live in summra.db at the project root (small, irreplaceable).
UNSPLASH_ACCESS_KEY) if you want to use plainly/scripts/blog/assign_blog_header_images.pygit clone <repo>
cd summra
./setup.sh # creates venv, installs deps, copies .env.example
# then edit .env and set GEMINI_API_KEY
Or manually:
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r plainly/requirements.txt
cp .env.example .env # then add GEMINI_API_KEY
python plainly/app.py
The server binds http://localhost:5001 (port 5000 is reserved by macOS ControlCenter). Override with PORT=5002 python plainly/app.py if needed.
The repository ships without data/database.db (it's gitignored). To get a working app, either restore your own DB or ingest books — see below.
venv/bin/python -m plainly.scripts.content.generate_summaries data/books/your_book.txt
Common options:
# Just parse chapters, no LLM calls (free, fast — useful for verifying chapter detection):
... generate_summaries.py data/books/pg1342.txt --parse-only
# Inspect detected chapter boundaries without writing to the DB:
... generate_summaries.py data/books/pg1342.txt --dry-run
# Batch a directory:
... generate_summaries.py data/books/ --batch
# Override metadata:
... generate_summaries.py data/books/pg1342.txt --title "Pride and Prejudice" --author "Jane Austen"
The script auto-detects chapters, generates a combined short + full summary in a single Gemini call, optionally generates per-chapter summaries, and persists raw LLM responses to data/llm_responses/ so a parser bug doesn't force a re-call.
Always dry-run first. The chapter parser is tuned for prose novels with CHAPTER I/II/III style markers (and the two-level PART I → CHAPTER I variant). It does not handle anthologies, aphoristic non-chaptered works, or non-English structural conventions — see CLAUDE.md "Book Ingestion Workflow" for the dry-run / validate workflow and the canonical list of known-bad book classes.
Real-time TTS via the dev server (plainly/app.py) uses the Gemini 2.5 Flash TTS API and caches the resulting WAV files under plainly/frontend/static/audio/. For pre-generating audio in bulk:
# All concise summaries in the DB:
venv/bin/python -m plainly.scripts.audio.batch_generate_concise_audio
# All medium summaries:
venv/bin/python -m plainly.scripts.audio.batch_generate_medium_audio
# Per-chapter audio for a specific book:
venv/bin/python -m plainly.scripts.audio.generate_gemini_audio_batch_offline --book-id 47
Production (plainly/app_prod.py) does not generate TTS on demand — it only serves files pre-generated by these scripts. The TTS pipeline is split this way so the production VM can stay small (e2-small or even e2-micro).
plainly/config.py is the single source of truth:
DATABASE_PATH — data/database.dbGEMINI_API_KEY — read from envSUMMARY_CONFIGS — model + word-count target per summary typePLAIN_TEXT_MODEL — model used for modern-English rewrites (currently gemini-3.1-flash-lite)GEMINI_TTS_MODEL, GEMINI_TTS_VOICE — TTS model + voice (Kore by default; options: Puck, Charon, Kore, Fenrir, Aoede, Sulafat)MAX_REQUESTS_PER_MINUTE / MAX_TOKENS_PER_MINUTE — Gemini rate-limiter capsFLASK_HOST, FLASK_PORT, FLASK_DEBUGFEATURE_AUTH — gate auth, reading-progress, active Save-for-Offline (default False)FEATURE_BLOG — gate the editorial blog (default False)Both feature flags default off so the routes return clean 404s and the relevant frontend buttons are server-stripped from the SPA shell.
The default suite runs without Gemini credentials or the curated content database.
To audit the locally provisioned hero content explicitly, run
venv/bin/python -m pytest tests/test_home_redesign.py -m content -v.
An empty database created by app startup is insufficient for this audit.
venv/bin/python -m pytest tests/ -v
40+ test files cover chapter detection, the LLM client + rate limiter, the bulk-summary parser, validators, the database layer, and several specific historical bugs (preface detection, two-level TOC, multi-line titles, dotted abbreviations).
cd tests/e2e && npm install && npx playwright install chromium # one-time
python plainly/app.py & # in another terminal
cd tests/e2e && node smoke.mjs
smoke.mjs visits a configurable set of routes (override with PATHS=/,/book/104,/explore), screenshots each one, and exits non-zero on any non-200, console error, or failed first-party request. See tests/e2e/README.md for the full flag set.
venv/bin/python -m plainly.scripts.audits.validate_chapter_split --book-id <id> --llm-digest
Deterministic checks (chapter count, monotonic numbering, coverage) plus an optional LLM digest spot-check.
If you run multiple Claude Code sessions on this repo simultaneously, give each its own worktree — never share a working directory.
git worktree add .claude/worktrees/<name> -b <branch>
git worktree list
git worktree remove .claude/worktrees/<name>
Per-session isolation requirements (Flask port, venv/, tests/e2e/node_modules/, data/database.db) are documented in detail in CLAUDE.md under "Parallel Sessions".
Page routes (server-rendered shell + hash-based SPA):
GET / — Home (Discover carousels)GET /discover — Discover pageGET /books — All books gridGET /books/<slug> — Book detailGET /books/<slug>/summary — Full summary pageGET /books/<slug>/chapters/<n> — Chapter pageGET /categories, GET /categories/<id> — Category index + detailGET /authors/<author_slug> — Author hubGET /blog, GET /blog/<slug> — Blog (FEATURE_BLOG)GET /manifest.json, GET /robots.txt, GET /sitemap.xml — PWA installability + SEOJSON API:
GET /api/books — List booksGET /api/books/<id> — Book detailGET /api/books/<id>/summary/<type> — Summary (concise | medium | comprehensive)GET /api/books/<id>/chapters — Chapter listGET /api/books/<id>/chapters/<n> — Single chapter (incl. modern-English text, illustration URL)GET /api/books/<id>/categories, GET /api/books/<id>/relatedGET /api/categories, GET /api/categories/<id>, GET /api/categories/<id>/booksGET /api/authors/<slug>, GET /api/authors/<slug>/booksGET /api/books/by-author/<name>GET /api/discover/carousels — Curated carousels for the Discover pageGET /api/summary-configs — Summary config for the frontendPOST /api/tts/generate — Generate (dev) or fetch (prod) TTS audio for a given text idAuth + progress endpoints register under blueprints when FEATURE_AUTH=True — see shared/auth/ and shared/progress/routes.py.
deploy/DEPLOY.md walks through the GCP path: e2-micro (free tier, no on-demand TTS) or e2-small (~$13/mo, full TTS). The directory ships nginx configs, systemd unit files, gunicorn configs, and a setup-e2small.sh automation script.
"no such table: books" — data/database.db is empty or missing. Either restore a database, or ingest at least one book with plainly/scripts/content/generate_summaries.py.
Port 5000 already in use — That's macOS ControlCenter (AirPlay Receiver). Use 5001 (the default) or pick another with PORT=.
Gemini rate-limit errors — The rate limiter caps at MAX_REQUESTS_PER_MINUTE (10) and MAX_TOKENS_PER_MINUTE (250 000). Ingesting many books in parallel will hit these. The script pauses automatically; if you hit a hard 429 you may need a paid tier.
Chapter detection looks wrong — Run generate_summaries.py … --dry-run and read the CHAPTER BREAKDOWN block. The parser handles standard prose novels; see CLAUDE.md for known-bad book classes (anthologies, aphoristic works) that should be skipped.
TTS isn't generating in production — That's by design. app_prod.py only serves pre-generated audio. Run the offline batch scripts (plainly/scripts/audio/) and deploy the resulting WAV files.
For personal and educational use. Source texts must be in the public domain or you must hold appropriate rights.