ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證clg project2026
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗PrepAI is a full-stack Django platform for Indian students preparing for board examinations (CBSE, ICSE and state boards). Students pick their board, class, subject and chapter, then study notes, solve question papers and previous-year papers, take timed tests, track performance, scan questions with AI, and chat with an AI study assistant.
All educational content (boards, classes, subjects, chapters, topics, questions, papers, tests, materials) is data, managed in Django Admin. There are no hard-coded boards or subjects in the code.
| Layer | What it does | |---|---|the upcoming exam. The estimate uses a transparent formula (appearance rate 60%, recency 25%, concept rate 15%, +5 points if the pattern points to the upcoming year), is capped between 3% and 85%, and always shows the disclaimer. Its accuracy depends on how many real previous-year papers are loaded.
Python 3.12+ · Django 5.2/6.0 · Django REST Framework · django-filter · PostgreSQL (psycopg 3) · Bootstrap 5.3 + Bootstrap Icons · Chart.js · PDF.js · KaTeX · WhiteNoise · Anthropic Python SDK.
git clone <your-repo-url> prepai && cd prepai
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
pip install -r requirements.txt
-- psql -U postgres
CREATE DATABASE prepai;
CREATE USER prepai WITH PASSWORD 'change-me';
ALTER DATABASE prepai OWNER TO prepai;
Then set DATABASE_URL=postgres://prepai:change-me@localhost:5432/prepai in .env.
DATABASE_URL must point to a PostgreSQL database (a free one from https://neon.tech works).
cp .env.example .env # Windows: copy .env.example .env
| Variable | Purpose |
|---|---|
DEBUG | True locally, False in production |
SECRET_KEY | Required when DEBUG=False. Generate: `python -c "import secrets; |
| Django templates + Bootstrap 5.3 | Responsive UI with light/dark themes, reusable components |
| Django REST Framework | Versioned REST API at /api/v1/ (session + token auth) |
| PostgreSQL | Database (required) |
services/ai_service.py | Provider-agnostic AI layer (Anthropic Claude by default) |
services/ocr_service.py | Optional OCR step for the scanner (vision model or Tesseract) |
| Django Admin | Complete content workflow with publish/unpublish |
config/ settings, root URLs, API router, WSGI/ASGI
core/ base models, validators, permissions, home, error pages, template tags, seed command
accounts/ custom User (email login), Profile, auth views, auth API
boards/ Board → ClassLevel → Subject → Chapter → Topic + board explorer
questions/ Question bank, options, concepts, historical appearances, frequency analysis
papers/ Question papers, previous-year papers (proxy model), PDF viewer/download
content/ Study material library
testengine/ Tests, attempts, answers, grading, results (the spec's "tests" app*)
bookmarks/ Generic bookmarks
analytics/ Activity log, performance records, analytics queries
recommendations/ Rule-based recommendation engine
notifications/ Notifications + admin announcements
search/ Global search, suggestions, search history
scanner/ AI question scanner + scan history
assistant/ AI study assistant conversations
dashboard/ Student dashboard + analytics pages
services/ ai_service.py, ocr_service.py (no views; pure service layer)
templates/ static/ media/
* Named testengine because a top-level package called tests collides with Python/Django test discovery.
/questions/predictor/) — paste any question, or send one from the AI Scanner. PrepAI matches it to stored questions (exact repeats and reworded versions), shows how many times it appeared, in which years and in which papers (a year-by-year timeline), finds the recurrence pattern (e.g. "about every 2 years → next around 2027"), and gives a history-based likelihood estimate for print(secrets.token_urlsafe(50))"| |ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS| Comma-separated hostnames / origins | |DATABASE_URL| PostgreSQL URL (required) | |REDIS_URL| Optional cache (installredis) | | AI_PROVIDER|anthropic\|groq\|openrouter\|openai_compatible\|mock\|disabled| |AI_API_KEY, AI_MODELAI_VISION_MODELAI_BASE_URLAI_TIMEOUTAI_MAX_TOKENSAI_EFFORTAI_REFUSAL_FALLBACKOCR_BACKENDvision_llmtesseractnoneTHROTTLE_locals3EMAIL_*DEFAULT_FROM_EMAILGOOGLE_OAUTH_CLIENT_ID/SECRET` | Optional Google sign-in (see below) |No secret is hard-coded anywhere; all configuration is read in config/settings.py.
python manage.py migrate
python manage.py createsuperuser # asks for email, username and password
Admin is at /admin/.
python manage.py runserver
Open http://localhost:8000.
python manage.py seed_demo # idempotent
python manage.py seed_demo --reset # remove existing sample content first
This creates 9 boards (CBSE, ICSE, Maharashtra, Gujarat, Karnataka, Tamil Nadu, UP, Bihar, West Bengal), classes, subjects, chapters, topics, 30 questions, demo papers with generated PDFs, 8 tests, study material, an announcement, and a demo student:
[email protected]demo-student-2026The demo student has three completed attempts, so the dashboard, analytics and recommendations are populated.
All seeded content is flagged
is_sample=Trueand shows a "Sample" badge. Demo "previous-year" papers are titled[Demo] … (sample previous-year format), state that they are not official board papers, and exist only to demonstrate the frequency analysis. Do not present them as real examination statistics. Replace them with real papers before launch.
Put the PDFs in one folder per board → class → subject, named by year:
papers_import/
cbse/10/mathematics/2025.pdf
cbse/10/mathematics/2025-solutions.pdf # attached as the solution PDF
cbse/12/physics/2024-supplementary.pdf # also: term-1, term-2, pre-board, other
msbshse/class-10/science-and-technology-part-1/2023.pdf
Folder names match a board/class/subject slug, name, short name or class number. Subjects must already exist: python manage.py load_subjects creates every board's Class 10/12 subjects listed in boards/catalog.py (or add them in admin).
python manage.py load_subjects # classes + subjects from boards/catalog.py
python manage.py import_papers papers_import --dry-run # preview matches and skips
python manage.py import_papers papers_import # import (safe to re-run)
python manage.py import_papers papers_import --board cbse # only one board folder
python manage.py import_papers papers_import --unpublished # import hidden, review in admin
python manage.py import_papers papers_import --max-mb 120 # allow large scanned PDFs for this import
python manage.py import_papers papers_import_model --paper-type model # boards' official model papers
Existing PDFs are kept unless you pass --replace. Students aren't notified unless you pass --notify. Imported papers show up at /previous-year-papers/, where students filter by board → class → subject → chapter, year and exam, and see a grid of subjects × the last 5 exam years. The same year strip appears on every subject page. Choosing a chapter lists the previous-paper questions tagged to it.
CBSE papers can be fetched straight from cbse.gov.in each year (one set per subject and exam, read from CBSE's zips without downloading them whole):
python manage.py fetch_cbse_papers # → papers_import/cbse/<class>/<subject>/<year>[-supplementary].pdf
python manage.py import_papers papers_import --board cbse
What the other boards' official websites publish (checked October 2026):
| Board | Previous-year papers available officially |
|---|---|
| ICSE / ISC | No standalone papers. CISCE's "Analysis of Pupil Performance" (2023–2025) reproduces the exam questions with marking scheme; imported under that title |
| Maharashtra | 2024–2026, March and July/June exams |
| Gujarat | 2022 only (scanned) |
| Karnataka | SSLC 2022–2026 (all exams), II PUC 2025–2026 |
| Tamil Nadu | 2022–2026 main exams, one combined PDF per year (split per subject on import) |
| UP, Bihar | Model papers only (imported as model, never as previous-year papers) |
| West Bengal | Nothing published |
python manage.py test
63 tests cover the question predictor (matching, years, bounded estimates, patterns, API), grading (MCQ, multi-select, numeric, fill-in-the-blank, subjective), negative marking, deadlines and auto-submit, attempt limits, answer-leak prevention, per-user access control, frequency analysis correctness and disclaimers, AI failure handling (503 plus friendly message, rollback), the Anthropic and Groq/OpenRouter request shapes (mocked SDKs, no network), scanner upload validation, guest scans, accounts and token auth, bookmarks, search filters and recommendations.
All AI calls go through services/ai_service.py. Views never call an SDK directly.
AI_PROVIDER=anthropic
AI_API_KEY=sk-ant-... # or leave empty and set ANTHROPIC_API_KEY
AI_MODEL=claude-opus-5
AI_TIMEOUT=90
AI_EFFORT= # optional: low | medium | high | xhigh | max
AI_REFUSAL_FALLBACK=True
claude-opus-5. Any Claude model ID can be set in AI_MODEL.AI_PROVIDER=groq # or: openrouter
AI_API_KEY=your-provider-key
AI_MODEL= # optional: text model (empty = preset default)
AI_VISION_MODEL= # optional: model used by the scanner for images
groq and openrouter fill in the base URL and default Llama models. For another provider (Together, a self-hosted vLLM/Ollama server, etc.) use AI_PROVIDER=openai_compatible and set AI_BASE_URL. The scanner needs a model that accepts images, and these providers don't enforce the JSON schema, so the response is parsed and fitted to the expected fields. Model IDs change often, so check your provider's model list if you see "model not found".claude-opus-5 (and claude-fable-5-1), requests use the server-side fallback beta (fallbacks="default"), so a declined request is retried on a fallback model within the same call. Set AI_REFUSAL_FALLBACK=False to turn it off.output_config.format) and sends images as base64 content blocks, downscaled to at most 1568 px and EXIF-rotated.AIServiceError. The API returns HTTP 503 with "AI service is temporarily unavailable. Please try again." (or a more specific safe message), and the UI shows a retry button. The site never crashes because of the AI.AI_PROVIDER=mock returns clearly labelled placeholder responses, so every AI screen works without a key. disabled hides AI features behind a friendly notice.BaseAIProvider, implement complete(), and register it in _PROVIDERS.OCR_BACKEND=vision_llm (default) lets the vision model read the image. tesseract runs Tesseract first (install pytesseract and the binary) and passes the text as a hint.THROTTLE_AI_ASSISTANT and THROTTLE_AI_SCANNER cap AI usage per user/IP.%PDF-, and images must decode with Pillow (JPG/PNG/WEBP/GIF). Size limits come from MAX_*_UPLOAD_MB.media/. In development Django serves it; in production serve /media/ from your web server or use S3.pip install django-storages[s3], set STORAGE_BACKEND=s3 and the AWS_* variables. PDF downloads then redirect to signed URLs instead of streaming through Django./papers/<slug>/file/), which counts views and downloads.DEBUG=False, a strong SECRET_KEY, ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS, DATABASE_URL (PostgreSQL), REDIS_URL (recommended), email and AI settings.pip install -r requirements.txtpython manage.py migratepython manage.py collectstatic --noinput (WhiteNoise serves hashed, compressed assets)python manage.py check --deploy. Fix any prepai.W00x warnings: they flag console email, a missing REDIS_URL and unserved local media.gunicorn config.wsgi:application
gunicorn.conf.py sets threaded workers and a timeout above AI_TIMEOUT, because scanner and assistant requests wait for the AI. Set NUM_PROXIES to the number of proxies in front of the app so rate limits see real client IPs.DEBUG=False, HTTPS redirect, secure cookies and 1-year HSTS are on by default. Forward X-Forwarded-Proto from your proxy.GET /healthz/ (returns 503 if the database is unreachable).Google authentication (optional): the login page shows "Continue with Google" when GOOGLE_OAUTH_CLIENT_ID is set. To enable it, install django-allauth, add its apps, backend and URLs (/accounts/google/login/), and keep EmailOrUsernameBackend in AUTHENTICATION_BACKENDS. The rest of the app needs no changes because users are keyed by email.
notifications/services.py), recommendation regeneration and AI scans to Celery/RQ. Callers already go through service functions.search/services._text_filter can be swapped for PostgreSQL full-text search (SearchVector/SearchRank with GIN indexes), or for OpenSearch/Meilisearch, without changing views.reason per item. An ML ranker can replace generate_for_user behind the same interface.USE_I18N=True), and profiles already store a preferred language that the AI assistant respects./api/v1/auth/login/)./api/v1/)| Endpoint | Methods | Notes |
|---|---|---|
auth/register/, auth/login/, auth/logout/, auth/me/, auth/change-password/, auth/theme/ | POST / GET / PATCH | Token + session auth |
boards/, classes/, subjects/, chapters/, topics/ | GET (staff: write) | Filters e.g. ?board=, ?class_level= |
questions/, questions/{id}/frequency/ | GET | Historical frequency analysis |
questions/predict/ | POST {"text", "board"?, "class_level"?, "subject"?} | Times appeared, years, papers, pattern, likelihood estimate |
papers/, previous-year-papers/, …/{slug}/important-questions/ | GET | Filters: subject, year, type… |
materials/ | GET | |
tests/, tests/{slug}/start/ | GET / POST | |
attempts/, attempts/{id}/questions/, …/answer/, …/submit/, …/result/ | GET / POST | Owner only; no answers leaked before submit |
bookmarks/, bookmarks/toggle/ | GET / POST / DELETE | |
scanner/ | POST (multipart image or question), GET history | Throttled |
assistant/conversations/, …/{id}/messages/ | CRUD / POST | Throttled |
dashboard/, recommendations/, recommendations/{id}/dismiss/ | GET / POST | |
notifications/, …/{id}/read/, …/read-all/, …/unread-count/ | GET / POST | |
search/, search/suggestions/, |
Errors always look like {"error": {"message": "...", "code": "...", "details": ...}}.
, , , , , , | AI configuration (section 13) | ||\|\|| || API rate limits (e.g.60/hour) | | MAX_PDF_UPLOAD_MB, MAX_IMAGE_UPLOAD_MB| Upload limits | |STORAGE_BACKEND+AWS_|ormedia storage | |, | Email (password reset). The console backend prints emails to the terminal | |search/history/| GET / DELETE |