- C# 81.6%
- HTML 12.9%
- CSS 5.2%
- Dockerfile 0.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| .github/workflows | ||
| CheapWrapped.Tests | ||
| Components | ||
| Content | ||
| Data | ||
| Migrations | ||
| Models | ||
| Properties | ||
| Services | ||
| wwwroot | ||
| .dockerignore | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| appsettings.Development.json | ||
| appsettings.json | ||
| AppVersion.cs | ||
| CheapWrapped.csproj | ||
| CheapWrapped.slnx | ||
| docker-compose.yml | ||
| Dockerfile | ||
| LICENSE | ||
| Program.cs | ||
| README.md | ||
| TODO.md | ||
CheapWrapped
Your year in Plex, wrapped — a playful "Spotify Wrapped"-style recap of your watch history, built from Tautulli stats with zero runtime AI cost.
Status: early development / README-driven. See TODO.md for the full build plan.
What it is
An end-of-year (and on-demand) viewing recap for Plex users: total watch time, top shows and movies, genres, binges, night-owl patterns, streaks — presented as a scrollable, animated, shareable story of cards, badges, and witty one-liners.
The fun does not come from a live LLM call per user. It comes from a large, hand-authored content library — a badge taxonomy, viewer archetypes, and a categorized copy bank with interpolation — that gets selected and filled by each user's real stats. No per-user API bill, no user-supplied API keys, no external dependency at run time. Deterministic, tunable, and every line is reviewable before it ships.
Inspired by Wrapperr (the data model) and plexwrap (the fun), but replacing plexwrap's runtime ChatGPT dependency with a build-time content engine.
Features (planned)
- The Wrapped story — Spotify-Wrapped-style card sequence: totals → top titles → genres → archetype → badges → shareable summary
- Badge / achievement system — dozens of stat-triggered badges (Night Owl, The Completionist, Serial Abandoner, Threat Level Midnight…)
- Viewer archetypes — a "personality" assigned from watch behaviour (genre mix, time-of-day, binge/abandon patterns), no LLM
- Witty copy engine — categorized, interpolated one-liners filled from real stats
- Plex SSO — sign in with Plex, restricted to server friends (PIN-based, same pattern as CheapNights)
- Shareable cards — export/permalink a card or the full wrapped
- Per-user + server-wide recaps, any date range (not just year-end)
Tech Stack
- C# 15 / .NET 11 — Blazor Server, interactive rendering
- MudBlazor — component library + theming (the pretty cards)
- EF Core — SQLite (dev) / PostgreSQL (prod)
- CheapHelpers — EF repos, Blazor selectors, caching, Plex auth
- Tautulli API — watch-history source
- Docker — built and published to the Forgejo container registry
Repo & sync topology
Forgejo is the forge, and everything runs there — source, CI, container registry and deploy. This matches Voltiq and CheapFleet; the ecosystem's other model is GitHub-primary with a Forgejo mirror (CheapTasks, CheapNights).
- Source of truth, build/test/PR-review, image registry and deploy: Forgejo (
.forgejo/workflows, SINK act_runner) - No GitHub repo exists for this project. The two
.github/workflowsfiles are inert until one does — see TODO if a backup mirror is still wanted
Development
dotnet run # SQLite, auto-creates the dev db
dotnet user-secrets set "Plex:AdminToken" "…"
dotnet user-secrets set "Tautulli:ApiKey" "…"
CI/CD
- .forgejo/build.yml — build + test on pull requests and pushes to
master - .forgejo/deploy.yml — on a
v*.*.*tag: build + test, push the image to the Forgejo registry, then deploy over SSH. Tagging is the release action; merging deploys nothing - .forgejo/pr-review.yml — automated PR review
- .github/codeql.yml / dependency-review.yml — only run if a GitHub mirror is ever set up
License
See LICENSE.