How johnwarne/upvote-rss works
Purpose and Entry Points
Upvote RSS is a PHP 8.2+ service that turns popular posts from Reddit, Lemmy, Hacker News, Lobsters, PieFed, Mbin, and GitHub into enriched RSS feeds. index.php serves the feed-builder/preview UI; app.php is the likely request orchestration bootstrap; ajax.php supports UI-driven operations. Feed consumers request parameterized URLs and receive RSS through views/rss.php.
Paths: index.php, app.php, ajax.php, views/rss.php
Request and Presentation Layer
The browser UI collects platform, filtering, enrichment, and output options. Client JavaScript drives interactive controls and likely asynchronous preview/progress behavior. HTML previews and RSS are separate rendering targets, allowing the same assembled posts to be viewed in-browser or consumed by feed readers.
Paths: views/html.php, js/script.js, progress-sse.php
Platform Abstraction and Ingestion
community.php and post.php define the common domain boundary for source-specific implementations. Per-platform community adapters fetch listings/history and apply source semantics; post adapters normalize items, media, links, comments, and metadata into the shared feed model. Reddit authentication is isolated from community retrieval.
Paths: classes/community.php, classes/post.php, classes/communities/reddit.php, classes/posts/github.php, classes/auth/reddit.php
Filtering and Feed Assembly
The orchestration layer uses normalized posts to apply score, threshold, average-posts-per-day, age, NSFW, and pinned-comment options. rss.php represents the feed-generation boundary, combining selected/enriched posts into the RSS response. Query-string options make feed generation stateless from the consumer perspective, except for caches and authentication state.
Paths: classes/rss.php, classes/parser.php, functions.php
Article Enrichment Pipeline
When requested, external article URLs are fetched and converted into clean article content plus featured media. The parser abstraction selects built-in Readability.php or configured Readability.js/Mercury services; Browserless can sit upstream for JavaScript-dependent pages. Enriched webpage results are cacheable and become input to summaries and RSS rendering.
Paths: classes/webpage-analyzer.php, classes/parsers/readability-php.php, classes/parsers/readability-js.php, classes/parsers/mercury.php
AI Summarization Boundary
A factory chooses from configured LLM providers and supports provider fallback. The summarizer interface separates article-content preparation from vendor HTTP/API implementations. Providers include local Ollama and hosted OpenAI, Gemini, Anthropic, Mistral, DeepSeek, and generic OpenAI-compatible endpoints.
Paths: classes/summarizer-factory.php, classes/summarizer.php, classes/summarizers/ollama.php, classes/summarizers/openai-compatible.php
Runtime, Caching, and Operations
The primary runtime is PHP, packaged as a Docker image served by Caddy. Caching abstracts filesystem defaults with optional Redis; APCu is used where available for fast local state such as auth/progress. Docker entrypoint configuration handles container startup and mounted /app/cache persistence. External dependencies include source platform APIs, Reddit OAuth, parser services, Browserless, Redis, and LLM APIs.
Paths: classes/cache.php, docker/Dockerfile, docker/Caddyfile, docker/entrypoint.sh
Main entry points: rss.php Feed assembly · app.php Request bootstrap · webpage-analyzer.php Webpage analyzer · script.js Interactive controls
Components 22
Request & Rendering
- Feed builder UI · Collects feed and enrichment options.
index.php - Interactive controls
js/script.js - Request bootstrap
app.php - AJAX operations
ajax.php - Progress stream
progress-sse.php - HTML preview
views/html.php - RSS output
views/rss.php
Feed Core
- Feed assembly · Applies request filters and produces selected feed posts.
classes/rss.php - Option parsing
classes/parser.php - Shared functions
functions.php
Source Ingestion
- Community & post model · Shared boundary for platform listings and normalized posts.
classes/community.php - Reddit community adapter
classes/communities/reddit.php - GitHub post adapter · Represents one of the source-specific normalizers.
classes/posts/github.php - Reddit OAuth
classes/auth/reddit.php
Enrichment & AI
- Webpage analyzer · Fetches articles and extracts clean content and featured media.
classes/webpage-analyzer.php - Article parsers · Selects Readability PHP, Readability JS, or Mercury extraction.
classes/parsers/readability-php.php - Summarizer selection · Chooses configured LLM provider and fallback.
classes/summarizer-factory.php - Summarizer interface
classes/summarizer.php - Ollama provider
classes/summarizers/ollama.php - OpenAI-compatible provider · Covers compatible hosted LLM endpoints.
classes/summarizers/openai-compatible.php
Runtime & Operations
- Cache layer · Uses filesystem by default with optional Redis and local fast state.
classes/cache.php - PHP/Caddy container · Serves the PHP application and persists mounted cache data.
docker/Dockerfile
Connections 23
- Feed builder UI → Interactive controls: enhanced by
- Interactive controls → AJAX operations: async requests
- Interactive controls → Progress stream: progress updates
- Feed builder UI → Request bootstrap: feed request
- AJAX operations → Request bootstrap: operations
- Request bootstrap → Option parsing: parses options
- Option parsing → Feed assembly: filter settings
- Request bootstrap → Feed assembly: builds feed
- Feed assembly → HTML preview: preview posts
- Feed assembly → RSS output: RSS posts
- Feed assembly → Community & post model: loads normalized posts
- Reddit community adapter → Community & post model: implements
- GitHub post adapter → Community & post model: implements
- Reddit community adapter → Reddit OAuth: authenticated access
- Feed assembly → Webpage analyzer: enriches articles
- Webpage analyzer → Article parsers: extracts content
- Webpage analyzer → Summarizer selection: article content
- Summarizer selection → Summarizer interface: selects
- Summarizer interface → Ollama provider: provider
- Summarizer interface → OpenAI-compatible provider: provider
- Feed assembly → Cache layer: cached results
- Webpage analyzer → Cache layer: cached webpages
- PHP/Caddy container → Request bootstrap: serves