ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Summra Plain English Book Reader
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
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.查看完整 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.