feat: add news sanitize CLI command and upload static file serving with content-disposition

This commit is contained in:
2026-05-22 23:50:31 +00:00
parent 92c1bfca47
commit 8eea7cc0c9
33 changed files with 947 additions and 765 deletions
+12 -12
View File
@@ -1,4 +1,4 @@
# DevPlace The Developer Social Network
# DevPlace - The Developer Social Network
Server-rendered social network for developers. FastAPI backend serving Jinja2 templates with ES6 interactivity. Avatar generation via Multiavatar (local, no network). SQLite via `dataset` with WAL mode and concurrency tuning.
@@ -81,9 +81,9 @@ devplacepy/
### Service framework
- **`BaseService`** abstract class with async run loop, `deque(maxlen=20)` log buffer, `name`, `interval_seconds`
- **`ServiceManager`** singleton that registers, starts, and stops all services
- **`NewsService`** fetches news from `news.app.molodetz.nl/api`, grades with AI, stores articles >= threshold
- **`BaseService`** - abstract class with async run loop, `deque(maxlen=20)` log buffer, `name`, `interval_seconds`
- **`ServiceManager`** - singleton that registers, starts, and stops all services
- **`NewsService`** - fetches news from `news.app.molodetz.nl/api`, grades with AI, stores articles >= threshold
### Adding a service
@@ -108,7 +108,7 @@ Configuration via admin site settings:
News articles have detail pages at `/news/{slug}` with full comment support (same component as posts/projects). The landing page can display curated articles toggled from admin.
CLI: `devplace news clear` delete all news from local database.
CLI: `devplace news clear` - delete all news from local database.
## Database
@@ -123,12 +123,12 @@ PRAGMA temp_store=MEMORY; -- temp tables in memory
PRAGMA mmap_size=268435456; -- 256MB memory map for reads
```
All indexes are created via `CREATE INDEX IF NOT EXISTS` wrapped in try/except safe to run on every startup regardless of table state.
All indexes are created via `CREATE INDEX IF NOT EXISTS` wrapped in try/except - safe to run on every startup regardless of table state.
## Testing
- **148 tests** across 14 files: Playwright integration + unit tests
- Playwright (NOT pytest-playwright plugin conflicts, uninstall it)
- Playwright (NOT pytest-playwright plugin - conflicts, uninstall it)
- Server starts as subprocess on port 10501 with isolated temp database
- Test users `alice_test` / `bob_test` seeded via HTTP at session start
- Tests stop at first failure (`-x` flag)
@@ -137,13 +137,13 @@ All indexes are created via `CREATE INDEX IF NOT EXISTS` wrapped in try/except
### Key test patterns
- Every `page.goto()` and `page.wait_for_url()` uses `wait_until="domcontentloaded"` avatar images don't block test execution
- Every `page.goto()` and `page.wait_for_url()` uses `wait_until="domcontentloaded"` - avatar images don't block test execution
- Session-scoped browser context with per-test cookie clearing
- `page.locator(...).wait_for(state="visible")` preferred over bare selectors
## Avatars
Uses [Multiavatar](https://github.com/multiavatar/multiavatar-python) generates deterministic SVG avatars locally from a seed string (the username). No external API calls, no network dependency. Generation takes <5ms. Results are cached in-memory (cleared on server restart).
Uses [Multiavatar](https://github.com/multiavatar/multiavatar-python) - generates deterministic SVG avatars locally from a seed string (the username). No external API calls, no network dependency. Generation takes <5ms. Results are cached in-memory (cleared on server restart).
Avatar URL format: `/avatar/multiavatar/{username}?size={size}`
@@ -159,12 +159,12 @@ Gitea Actions workflow at `.gitea/workflows/test.yaml`:
## Feature workflow
1. Implement the feature (router + template + CSS + JS)
2. `hawk .` validate all source files
3. `make test` run all tests (fail-fast)
2. `hawk .` - validate all source files
3. `make test` - run all tests (fail-fast)
4. Add Playwright tests in `tests/test_*.py` for new functionality
5. For visual features: `falcon take --output /tmp/verify.png && falcon describe /tmp/verify.png`
6. Update `AGENTS.md` and `README.md` if new conventions were introduced
## License
MIT DevPlace
MIT - DevPlace