Personal watchlist app with TMDB collections, filters, and Meilisearch-backed library search.
  • JavaScript 39.9%
  • Python 28.4%
  • CSS 22.1%
  • HTML 8.2%
  • Shell 0.9%
  • Other 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
mrn 35c9550a45 feat(ui): single-scroll library layout with compact sticky header
- Sticky area is only the top app bar; filters live in main inside a toolbar card
- Toolbar uses row clusters for tabs, types, rating, tags, search, and tools
- Hero stats align to a tighter grid; main column uses consistent max-width and gap
- Footer sticks to bottom via flex shell; update collection-focus selectors
- VERSION 1.3.0

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-10 22:27:17 +03:00
static feat(ui): single-scroll library layout with compact sticky header 2026-05-10 22:27:17 +03:00
templates feat(ui): single-scroll library layout with compact sticky header 2026-05-10 22:27:17 +03:00
.dockerignore Release 1.1.0: Docker Compose web stack, UI shell, semantic version 2026-05-10 21:04:07 +03:00
.env.example Release 1.1.0: Docker Compose web stack, UI shell, semantic version 2026-05-10 21:04:07 +03:00
.gitignore Release 1.1.0: Docker Compose web stack, UI shell, semantic version 2026-05-10 21:04:07 +03:00
app.py chore: refresh stack to latest stable deps and simplify list filters 2026-05-10 21:17:34 +03:00
compose.yaml fix(compose): pin Meilisearch v1.42.1 to match existing meili_data 2026-05-10 22:20:58 +03:00
deploy.sh Wait for app readiness during deploy 2026-04-25 00:42:53 +03:00
docker-entrypoint.sh fix(docker): allow appuser to write bind-mounted SQLite db directory 2026-05-10 21:08:19 +03:00
Dockerfile chore: refresh stack to latest stable deps and simplify list filters 2026-05-10 21:17:34 +03:00
README.md Add simple deployment workflow 2026-04-25 00:42:05 +03:00
requirements.txt chore: refresh stack to latest stable deps and simplify list filters 2026-05-10 21:17:34 +03:00
update_tmdb.py chore: refresh stack to latest stable deps and simplify list filters 2026-05-10 21:17:34 +03:00
VERSION feat(ui): single-scroll library layout with compact sticky header 2026-05-10 22:27:17 +03:00

Watchlist

A self-hosted personal watchlist app for movies, series, anime, animation, and documentaries.

Built for a clean home-library workflow: quick TMDB search, rich filtering, collection tracking, recent additions, continuation suggestions, and fast local search.

Highlights

  • TMDB-powered add flow

    • Search and add movies, TV shows, anime, animation, and documentaries
    • Pulls posters, backdrops, overviews, runtime, ratings, languages, and collection info
  • Two main library views

    • watchlist
    • watched
  • Rich filters

    • Type
    • Rating
    • Genre
    • Language
    • Collection / series
    • Incomplete collections
  • Collection-aware experience

    • Open a full collection view
    • See owned vs missing parts
    • Bulk-add missing entries
    • Mark an entire collection as watched or watchlist
    • Hide owned entries while browsing a collection
  • Dashboard sections

    • Summary stats
    • “Continue these collections” suggestions
    • Recently added titles
  • Library search

    • Fast internal search across your existing library
    • Meilisearch support for better search quality and scalability
    • Automatic SQL fallback if Meilisearch is unavailable

Stack

  • Backend: Flask
  • Database: SQLite
  • Metadata: TMDB API
  • Search: Meilisearch (optional, recommended)
  • Frontend: Vanilla HTML / CSS / JavaScript

Project structure

.
├── app.py
├── update_tmdb.py
├── compose.yaml
├── static/
│   ├── css/style.css
│   └── js/app.js
├── templates/
│   └── index.html
└── db/
    └── watchlist.db

Requirements

  • Python 3
  • Flask
  • Requests
  • TMDB API key

The production service currently runs with:

  • python3 app.py
  • systemd service for app runtime
  • optional docker compose for Meilisearch

Environment variables

Required

  • TMDB_API_KEY

Optional

  • MEILI_URL — default: http://127.0.0.1:7700
  • MEILI_MASTER_KEY — optional if Meilisearch is protected
  • MEILI_INDEX — default: watchlist_items

Run locally

python3 app.py

By default the app listens on:

  • 0.0.0.0:8000

Run Meilisearch

docker compose up -d meilisearch

This starts Meilisearch on:

  • 127.0.0.1:7700

Search behavior

The app exposes a library search endpoint:

GET /api/library-search?q=QUERY&status=watchlist

Search uses:

  1. Meilisearch when available
  2. SQLite fallback when Meilisearch is unavailable

So the UI still works even if the search service is down.

Notes

  • SQLite database files are intentionally not committed
  • Cache / compiled Python files are ignored
  • Meilisearch data directory is ignored
  • This repo is meant for app source, not runtime data

Deployment workflow

Server setup

Production uses:

  • repo checkout in /home/mrn/watchlist
  • secrets in /home/mrn/watchlist/.env
  • systemd service: watchlist.service
  • Meilisearch via docker compose

Deploy update

cd /home/mrn/watchlist
git pull --ff-only
./deploy.sh

What deploy.sh does:

  • validates Python syntax
  • ensures Meilisearch is up
  • restarts watchlist.service

Future improvements

  • Better autocomplete UI
  • Auth / multi-user support
  • Better backup / restore helpers

Built for a private home setup on majlis.lab