Commit Graph

116 Commits

Author SHA1 Message Date
kennethreitz d44bdeb36c Add oEmbed proxy route to Responder engine (production server)
The Flask blueprints aren't used in production — engine.py with
Responder is what Fly actually runs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 10:01:18 -04:00
kennethreitz 8f19cd63c0 Only include /api routes in OpenAPI schema
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:33:47 -04:00
kennethreitz 9b5e430b9c Add response definitions and query params to OpenAPI schema
Swagger UI Execute needs responses defined to display results.
Auto-detect search query params for /api/search routes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:32:49 -04:00
kennethreitz 51238dcddb Switch API docs to Swagger UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:31:36 -04:00
kennethreitz 9d98ca4be6 Auto-generate OpenAPI schema from registered routes
Schema at /api/schema now introspects api.router.routes for paths
and docstrings instead of maintaining a static dict. Skips catch-all
and internal routes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:30:34 -04:00
kennethreitz cde3097b02 Switch API docs to RapiDoc — dark theme, focused layout
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:29:36 -04:00
kennethreitz a80e0c81a8 Redoc API docs with separate schema endpoint
Schema served as JSON at /api/schema, docs rendered with Redoc at /api.
No more inline YAML — clean separation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:29:20 -04:00
kennethreitz eb8bdc76d7 Self-hosted API docs at /api with Stoplight Elements
Inline OpenAPI spec avoids catch-all route conflict. Elements UI
with sidebar layout, no external schema fetch needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:27:16 -04:00
kennethreitz 69554471d3 Switch to Elements theme, serve docs at /api
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:25:28 -04:00
kennethreitz 29b290cb4c Move OpenAPI schema and docs under /api/ prefix
Avoids catch-all route intercepting /schema.yml.
Swagger UI at /api/docs, schema at /api/schema.yml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:24:49 -04:00
kennethreitz 11dd894555 Add Swagger UI at /api via responder's built-in OpenAPI support
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 05:23:19 -04:00
kennethreitz 02930ccff6 Fix icon API route — use path parameter to capture slashes
/api/icon/{article_path} didn't match paths with slashes like
essays/2026-03-25-foo. Changed to {article_path:path}.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 20:52:07 -04:00
kennethreitz bda48b9c25 Bump rate limit to 600/min for load testing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 03:58:20 -04:00
kennethreitz 8f1fc2a366 Add rate limiting — 120 requests per minute per IP
Uses responder's built-in RateLimiter. Returns 429 with Retry-After
header when exceeded. Adds X-RateLimit-Limit and X-RateLimit-Remaining
headers to all responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 03:36:47 -04:00
kennethreitz e15b83e316 Remove unused find_adjacent_posts, add markdown render cache
find_adjacent_posts result was never used in template (like
find_related_posts before it). Added _cached_render() to cache
parsed markdown in memory — content only changes on deploy so
there's no reason to re-parse on every request.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 03:28:38 -04:00
kennethreitz f8d807fe9e Remove unused find_related_posts — 5.6x essay speedup
find_related_posts was doing TF-IDF comparison against all 250+ essays
on every request (1 second each) but the result was never rendered in
the template. Essays now serve at 105 req/s instead of 19.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 03:24:50 -04:00
kennethreitz 93f6a4be29 Sort theme groups alphabetically instead of by size
More stable ordering — won't shuffle when new essays are tagged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:29:56 -04:00
kennethreitz 2b2553c9d1 Restore theme badges on essay pages
The catch-all route wasn't passing article_themes to the post template.
Now looks up detected themes from the themes cache for each essay.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:26:25 -04:00
kennethreitz 9d297988e4 Search overhaul, AI index files, Lumina poetry index cleanup
Search:
- Build search index at startup instead of scanning 727 files per query
- Add /api/search/autocomplete for whole-site title matching
- Autocomplete now server-side, covers all content not just essays
- Remove client-side /api/blog preload from search page

AI section:
- Create 5 missing index.md files for navigational orphan directories
- Update "277 file" count to actual 352 across all references
- Tone down Lumina poetry index to match actual content quality

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:19:50 -04:00
kennethreitz cc1c585c57 Security, performance, and quality improvements across the site
Security:
- Add path traversal protection to serve_data_file and og_image routes
- Bound OG image cache to 256 entries to prevent memory growth

Performance:
- Pre-build legacy URL lookup tables at startup instead of rglob on every 404
- Extract _generate_pdf helper, eliminating duplicate PDF code

Templates:
- Add dark mode support to graph.html and error.html

Content:
- Remove third-person sidenotes from yoga-meditation.md, great-music.md,
  and idea_amplification essay
- Fix sidenote formatting in yoga-meditation.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:45:56 -04:00
kennethreitz 4fd4e65c7e Warm up homepage — dynamic posts, cleaner layout, muted accents
- Recent writing now pulls 5 latest posts dynamically with icons
- Collapsed theme/beyond sections into flowing Threads paragraph
- Added .muted class for subtle text styling with dark mode support
- Removed redundant footer nav links
- Simplified subtitle styling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:39:26 -04:00
kennethreitz 9442a4275b Use folder icons for index.md results in search
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:04:01 -04:00
kennethreitz 8181bba75d Add unique icons to search results
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:03:14 -04:00
kennethreitz ba85249cbb Expand search to cover entire site, not just essays
- Search endpoint now scans all markdown files in data/ directory
- Results show section labels (Essays, Software, Themes, etc.) instead
  of hardcoded "Essay" type
- Updated placeholder text to reflect whole-site search

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:02:19 -04:00
kennethreitz 1ce6b8712a Add Themes and Search to top nav, Themes as dropdown with icons
- Themes dropdown mirrors Browse structure with tree-item icons
- Populated from data/themes/ directory via /api/themes endpoint
- Search link added between Archive and Themes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:53:58 -04:00
kennethreitz 9908c6e184 Suppress static asset access logs and fontTools.subset noise
Keep logs focused on meaningful requests — static assets (.js, .css,
.ico, .png, .woff2) and fontTools subset chatter are filtered out.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:45:07 -04:00
kennethreitz 20c2ea2f7b Add structured logging, legacy URL redirects, bot detection, and 404 page
- Enable responder 3.6 structured logging with request-scoped context
- Replace print() calls with api.log in cache warming
- Add logging across key routes (content serving, PDFs, search, redirects)
- Add legacy URL resolver for old date-path patterns and bare slugs (301 redirects)
- Add bot/scraper detection with logging on robots.txt and content routes
- Fix 404 page template variable mismatch and add helpful navigation links
- Bump responder dependency to >=3.6.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:38:02 -04:00
kennethreitz 0bf0e5d823 Use Responder startup event for cache warming
Warms all caches (blog, sidenotes, outlines, quotes, connections,
terms, themes) in background thread on startup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:40:07 -04:00
kennethreitz ffdfbfada3 Fix .md and .pdf routes, add pdf_available to template context
Handle .md and .pdf extensions inside catch-all since path:path
is greedy. Add WeasyPrint availability check for PDF button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:36:19 -04:00
kennethreitz efced60c35 Serve raw files (images, etc.) from data directory in catch-all
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:20:35 -04:00
kennethreitz dd751105ec Fix data file serving for nested paths (images in galleries)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:18:58 -04:00
kennethreitz 029083d526 Fix static file serving — add explicit route before catch-all
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:10:35 -04:00
kennethreitz 5cd48abb90 Port site to Responder (#8)
* Initial Responder port — core content serving working

Homepage, markdown pages, directory listings, image galleries
all rendering. Flask template compatibility via RequestWrapper
and FakeConfig shims.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Complete Responder port — all routes working

Ported all routes from Flask blueprints: archive, search, OG images,
RSS, sitemap, robots.txt, API endpoints, directory browser.
All 25+ routes returning 200.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update Dockerfile for Responder, warm caches on import

CMD now runs engine_responder:api via uvicorn.
Cache warming happens on module import for production.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Rename engine_responder.py to engine.py

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update colophon for Responder

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix essay pages, OG images, and PDF export

- Fix find_related_posts and find_adjacent_posts call signatures
- Fix OG image route to use path:path for nested paths
- Add PDF export route with WeasyPrint
- All test plan items passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:03:05 -04:00
kennethreitz f50dad4574 Switch to uvicorn, fix breadcrumbs for all content pages
- Replace gunicorn/gevent with uvicorn for ASGI support
- Add asgiref to wrap Flask WSGI app for uvicorn compatibility
- Enable auto-reload in docker-compose for development
- Add current_path to all content render_template calls
- Simplify breadcrumb template to exclude current page
- Only show breadcrumbs for nested paths (> 1 segment)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:58:17 -05:00
kennethreitz 60f1046204 Refactor search functionality and enhance caching mechanisms
- Removed the engine_new.py file as part of restructuring.
- Implemented actual search functionality in api.py, allowing for searching through blog posts with relevance scoring and snippet extraction.
- Enhanced caching in cache.py with a clear_cache function and improved content cleaning for search indexing.
- Deleted outdated homepage-revised.html template and ensured search.html template displays search results with additional metadata such as date and matches found.
2025-09-26 13:05:29 -04:00
kennethreitz c677b8fc98 all working / black 2025-09-26 12:34:57 -04:00
kennethreitz a353ccfaa7 Add folder icon support for directory links in icon API
- Detect directory paths (ending with / or pointing to directories)
- Use generate_folder_icon() for directories instead of regular article icons
- Read index.md files for directory titles when available
- Fallback to directory name for folder icon generation
- Fixes AI personalities link and other directory links to show proper folder icons

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-18 15:06:05 -04:00
kennethreitz bd62ba8550 Enhance icon system for themes and improve positioning
- Add themes directory to content cache for proper icon generation
- Remove colored dots from themes/index.md to enable icon display
- Fix JavaScript to handle links wrapped in strong tags
- Improve icon positioning with refined margins and alignment
- Prevent icons from loading on index/archive pages
- Fix navigation link to point to /themes instead of /themes/
- Optimize icon spacing and vertical alignment across devices

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-18 14:45:14 -04:00
kennethreitz 5f126491f9 Fix article link icons and improve icon generation system
- Fix data URL display issue by using inline SVG instead of img src
- Add LRU cache to icon API for better performance
- Expand icon coverage to all internal links (not just essays)
- Add software, poetry, and talks directories to content cache
- Implement fallback logic to read files directly when not in blog cache
- Fix Requests icon to use full title "Requests: HTTP for Humans"
- Improve icon positioning with negative margins and vertical alignment
- Add graceful fallback icons for missing content

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-18 14:18:00 -04:00
kennethreitz e4fb17097a Fix archive excerpts - remove all markdown images and improve filtering
- Enhanced simple_extract_excerpt() function to filter markdown images
- Added support for linked images [![](url)](url)
- Improved line-by-line filtering to find meaningful content
- Reduced excerpt length to 150 characters for better display
- Removed prebuild cache system to simplify architecture
- Fixed markdown filtering in all excerpt generation functions
2025-09-17 10:32:00 -04:00
kennethreitz 77e5ef9623 Fix major performance bottleneck in directory listings
- Add cached markdown title extraction with @lru_cache(maxsize=1000)
- Replace expensive render_markdown_file() calls with fast regex title extraction
- Only read first 1000 chars instead of full file content for title extraction
- Essays directory and other large directories now load significantly faster
- First load: fast title extraction, subsequent loads: instant cache lookup

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-17 10:07:03 -04:00
kennethreitz 6491c26ac1 Add memoization to SVG icon generation for significant performance improvement
- Add @lru_cache(maxsize=1000) to generate_unique_svg_icon() in svg_icon_generator.py
- Add @lru_cache(maxsize=500) to generate_folder_icon() in engine.py
- Import functools.lru_cache in both files
- Directory pages with many items (like /essays) now load much faster on repeat visits
- Icons generated once per unique title, then served from memory cache

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-17 10:00:57 -04:00
kennethreitz 7f51a2a028 Add support for .bak files in directory structure filtering 2025-09-17 09:25:29 -04:00
kennethreitz 3640827e5b Add folder icon generation for themes and update navigation links 2025-09-17 09:15:19 -04:00
kennethreitz 37f580a345 Add performance optimizations: lazy loading and caching
- Implement lazy loading for images using IntersectionObserver
- Add HTTP caching headers for static assets (images: 7 days, others: 1 hour)
- Preload critical CSS resources for faster initial page load

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-17 08:37:44 -04:00
kennethreitz 2cce051bc8 Add reading progress indicator and enhance search with result highlighting
- Add reading progress bar for longer essays with smooth animation
- Implement search result snippets with highlighted query terms
- Tighten directory listing styles for better compactness
- Add back-to-parent navigation links in directory views

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-17 08:36:43 -04:00
kennethreitz 3287eed5ac Add parent directory navigation with icon in directory view 2025-09-17 08:31:25 -04:00
kennethreitz 16cf23a11d Add unique icons for articles and adjust layout in search results and templates 2025-09-17 08:18:00 -04:00
kennethreitz b4e7ec873d Enhance directory and archive layouts with unique icons and responsive styles
- Added a new SVG icon generator to create unique procedural icons for posts and directories.
- Implemented a grid layout for directory contents with hover effects and responsive adjustments.
- Updated archive and connections templates to display unique icons alongside article titles.
- Improved styling for archive posts, including flexbox layout for better alignment.
- Enhanced directory listing with icons and improved visual hierarchy.
- Refactored post template to include an icon next to the post title and added parent navigation links.
- Updated styles across templates for consistent icon sizes and responsive behavior.
2025-09-17 08:11:32 -04:00
kennethreitz d64bee05e9 Fix missing page titles on directory pages
- Use actual title from index.md content instead of directory name
- Falls back to directory name if no index.md or title exists
- Fixes issue where pages like /talks/#major-talks showed no title
- Now "Conference Talks" will properly display instead of generic "Talks"

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-17 06:48:47 -04:00