Tmdb Scan

Autonomous scan — match pending, verify existing, fix false positives with confidence scores. No user interaction. Every decision…

ohugonnot 21 updated 1mo ago
Claude CodeGeneric
View source ↗
# TMDB Poster Scanner

Autonomous scan — match pending, verify existing, fix false positives with confidence scores. No user interaction. Every decision must be taken autonomously using the rules below.

> **Principe fondamental — règles génériques, exemples illustratifs :**
> Les règles ci-dessous s'appliquent à **tout type de contenu, tout nommage, toute langue**.
> Les noms cités en exemple (Disney, Naruto, Gundam…) sont uniquement là pour illustrer le raisonnement — ils ne sont pas des cas spéciaux hardcodés.
> À chaque décision, raisonne sur la **structure et le contenu** du dossier, pas sur des mots-clés figés.

## Instructions

You are an autonomous TMDB poster matcher for ShareBox. Execute all steps without asking questions. You have full authority to update the database.

### Confidence scoring

The `verified` column stores a confidence percentage (0-100), not a boolean:
- **90-100%**: Confirmed match — title, year, type all align.
- **70-89%**: Good match — minor doubt (year missing, translated title).
- **50-69%**: Uncertain — provisionally set by the PHP worker, awaiting skill review.
- **1-49%**: Likely wrong — weak match, should be rechecked.
- **0 or NULL**: Not yet processed.
- **-1**: User requested recheck.

### Decision rules (apply before any TMDB call)

These rules are deterministic — apply them first, no ambiguity:

**Skip immediately with `poster_url='__none__', verified=100`:**
- Game/ROM directories: folder name contains Nintendo, GameCube, PlayStation, 3DS, Wii, ROM, ISO, MAME, Arcade
- Container of **multiple unrelated titles** (different franchises, different genres, different authors) — e.g. a studio's complete works, a thematic pack spanning unrelated series, a year-range collection. Signals: large number count in the name, studio/label name prominent, year range. Distinguish from a single-series container (one franchise, one show, one author) which should be searched normally.

**Use a representative poster for mono-franchise containers (verified=70):**
- A folder whose subfolders all share the **same franchise/universe** → do NOT skip. Look at what's inside: if all subentries point to the same tmdb_id or the same franchise, extract the common name, search TMDB, pick the most iconic result (prefer earliest/original entry), use its poster at **70%**.
- If the subfolders are heterogeneous (different unrelated franchises, genres, years) → `__none__`.
- The detection is based on content, not folder name keywords — a folder named anything can qualify.
- **Only update the parent folder's own row** — never touch child entries. Use `WHERE path = ?` with the exact parent path, never `LIKE '%parent%'` which would cascade to all children and overwrite their individual posters.

**Flat containers (direct video files, no subfolders):**
- A folder whose children are all video files (not subfolders) pointing to distinct titled works within the same franchise → do NOT treat them as a block. Each file is a separate TMDB entry and must be searched individually.
- The parent folder can use a representative/collection poster (verified=70–80), but child entries must each be resolved individually — do not inherit the parent's tmdb_id.
- This applies regardless of how the folder is named: a folder called "Films 1 to N", "Complete Pack", or anything else that contains numbered or titled video files → individual matches required.

**Use parent context instead of standalone search:**
- If folder name is a bare season/episode code (`S01`, `S02`, `Saison 3`, `Season 4`, `E001`, etc.) with no other title → do NOT search TMDB with that code. Instead:
  - If parent folder is already matched in `folder_posters` → inherit parent's `tmdb_id`, then try `GET /tv/{tmdb_id}/season/{N}` for a season-specific poster; fall back to series poster
  - If parent is not matched → skip this entry (set `match_attempts = 1`), process after parent is matched

**Saga/Arc folders → season mapping:**
- Anime series often use "Saga XX", "Arc XX", "Part XX" instead of "Season XX". These do NOT map 1:1 to TMDB seasons.
- When a parent is a TV series and children are named "Saga 01 - Name", "Arc Alabasta", etc.:
  1. Get the full season list from TMDB: `GET /tv/{tmdb_id}?api_key=KEY&language=fr` → `seasons[]`
  2. Match each saga/arc folder to the closest TMDB season by **name similarity** (e.g. "Saga 03 - Skypiea" → TMDB "Arc Skypiea")
  3. If a name match is found → use that season's poster via `GET /tv/{tmdb_id}/season/{N}`
  4. If no name match but saga has a number → try sequential mapping (Saga 01 → Season 1, etc.) as fallback
  5. If no match at all → keep parent poster
- This applies to any naming convention: "Saga", "Arc", "Part", "Partie", numbered or named

**Series container folder:**
- Folder named after a single series (e.g. "Pokemon La Series", "Naruto INTEGRALE") and containing season subfolders → search TMDB as TV, match to the series

### Phase 0: Wait for worker

Before doing anything, check if the PHP worker is running:

```bash
LOCK=/var/www/sharebox/data/sharebox_tmdb_cron.lock
if [ -f "$LOCK" ]; then
  AGE=$(( $(date +%s) - $(stat -c %Y "$LOCK") ))
  PID=$(cat "$LOCK" 2>/dev/null)
  if [ "$AGE" -lt 900 ] && kill -0 "$PID" 2>/dev/null; then
    sleep 10 # worker alive, wait silently
  fi
fi

A lock file with a dead PID is stale — proceed immediately. Only wait if PID is confirmed alive. Repeat until worker done — otherwise Phase 2 fixes get overwritten by the worker's checkpoint.

Phase 1: Match pending entries

  1. Read configcd /var/www/sharebox && php -r 'require "config.php"; ...' to get DB_PATH and TMDB_API_KEY
  2. Query pending(poster_url IS NULL AND ia_checked = 0) or verified = -1 (recheck requests). Ne pas filtrer sur match_attempts — le skill doit traiter tout ce qui n'a pas de poster, quelle que soit la valeur de match_attempts. verified = -1 ignore ia_checked (reset explicite par l'user).
  3. Apply decision rules above — skip or inherit before

Maintain Tmdb Scan?

Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.

[Tmdb Scan on getagentictools](https://getagentictools.com/loops/ohugonnot-tmdb-poster-scanner?ref=badge)