Commit Graph

10 Commits

Author SHA1 Message Date
Garret Patti
7e284383b4 add ai descriptions and extracted text 2026-04-12 18:18:59 -04:00
Garret Patti
0238dbda7a Add AI-powered image tagging via local LLM
Adds automatic image tagging that runs as a post-scan phase, sending
thumbnails to an OpenAI-compatible vision API and applying matching
tags from the user-defined tag vocabulary.

- New ai-tagger module with batch processing, failure tolerance, and
  tag validation against existing vocabulary
- Admin settings page (Manage > AI Tagging) for endpoint, model, and
  enable toggle with connection testing
- DB migration for ai_tagged_at tracking column and AI config seeds
- Re-tag All support to queue items for reprocessing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 15:18:03 -04:00
Garret Patti
6f86750a99 Unify media_key and item_key — use item_key everywhere
media_key was a lossy shortening of item_key (libraryId:lastSegment) that
introduced a real collision bug: two TV episodes from different series with
the same filename would share the same media_key and each other's tags.

- DB migration converts existing media_tags rows from short format to full
  item_key by joining against media_items; ambiguous/orphaned rows are dropped
- media_tags column renamed media_key → item_key
- Removed itemKeyToMediaKey() from scanner; reconcileAndPrune now passes
  item_key directly to reKeyMediaItem
- DB reader functions (tv, movies, games) now expose item_key on returned
  entities; frontend components use entity.item_key instead of constructing
  the short libraryId:id form
- MixedView now constructs the full mixed_file: item_key format
- Tag API renamed mediaKey param → itemKey throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 18:04:29 -04:00
Garret Patti
38a6886863 Add file fingerprinting for move-resilient media item identity
Computes a SHA-256 partial-content fingerprint (file size + first 64 KB) for
movies, TV episodes, and mixed files during scans. When a file is moved or
renamed within a library, the scan detects the fingerprint match, renames the
media_items row in-place, and updates media_tags.media_key to match — so tags
and NFO metadata survive the move transparently.

- src/lib/fingerprint.ts: new computeFingerprint() using sync FS reads
- src/lib/db.ts: fingerprint TEXT column + index migration
- src/lib/tags.ts: reKeyMediaItem() to update media_tags on rename
- src/lib/scanner.ts: replace clear+upsert with detectMoves/reconcileAndPrune
  for movies, TV episodes, and mixed files; games retain clear+upsert (v1)
- TV scan restructured to a single filesystem pass (no double-scanning)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 18:35:02 -04:00
Garret Patti
819748d1ff DB-first library reads, mixed library indexing, and manual NFO refresh
- API reads now serve from media_items cache instead of scanning the filesystem
  on every request; scans (manual or scheduled) remain the write path
- NFO metadata is no longer parsed automatically during scans; title falls back
  to folder/filename — metadata can be refreshed per-item via the kabob menu
- Mixed libraries are now indexed in media_items (new mixed_file item type)
  with file_path stored; scanMixed walks recursively and upserts all files
- Added file_path column to media_items and migrated item_type CHECK constraint
  to include mixed_file via safe table-recreation migration
- New POST /api/nfo-refresh endpoint reads the .nfo for a single item and
  patches its DB row (supports movie, tv_series, tv_episode)
- Added "Refresh metadata" button to movie and TV series kabob menus

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 18:20:21 -04:00
Garret Patti
8829188c58 add scanning 2026-04-05 18:55:53 -04:00
Garret Patti
5b5503b7a6 add user settings 2026-04-05 18:15:08 -04:00
Garret Patti
eecee9bc5f add auth 2026-04-05 17:44:24 -04:00
Garret Patti
e8b317f99d add movies and tv show library types with Jellyfin NFO support
- Add `movies` type: per-movie folders with video files, poster/backdrop
  images, and optional Jellyfin NFO metadata (title, year, plot, rating,
  genres, runtime). Grid view with 2:3 poster art, detail modal with play
  and two-click delete of the movie folder.
- Add `tv` type: Series -> Season -> Episode hierarchy with lazy loading at
  each level. Reads tvshow.nfo and episodedetails NFO files for metadata.
  Episode grid with video thumbnails, streams via existing video player.
  Delete is limited to the entire series folder to avoid breaking Jellyfin.
- Add fast-xml-parser dependency for Kodi/Jellyfin NFO parsing (lib/nfo.ts)
- Migrate existing DB to expand the libraries CHECK constraint to include
  the two new types; migration is idempotent and preserves existing data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 11:36:05 -04:00
Garret Patti
de8ba04bd3 bring up to date with github 2026-04-05 10:01:34 -04:00