Skip to content

Fix image selection to prefer promotional posters over screengrabs for VR and other scenes - #5

Merged
adeze merged 2 commits into
mainfrom
copilot/patch-image-selection-logic
Jul 21, 2026
Merged

Fix image selection to prefer promotional posters over screengrabs for VR and other scenes#5
adeze merged 2 commits into
mainfrom
copilot/patch-image-selection-logic

Conversation

Copilot AI commented Jul 21, 2026

Copy link
Copy Markdown

_get_scene_poster() and _get_scene_art() blindly returned the first extractable string from scene["images"], causing VR scenes (where the first list item is often a screengrab/still) to display frame captures instead of promotional artwork.

Changes

provider/mappers/tpdb_to_plex.py

  • Scoring system: _POSTER_KIND_SCORES / _ART_KIND_SCORES rank image kinds — poster/cover score 90–100 for the poster slot; screengrab/still/frame/gallery score 10; unknowns score 50.
  • _image_kind_from_key(key): Normalizes field names and inline type/category/label hint strings from TPDB payloads to a canonical kind.
  • _collect_image_candidates(scene): Replaces the scattered _get_first_image + _extract_string calls. Walks top-level fields and scene["images"] (dict or list), inspects type/category/name/label hints on list-of-dict payloads, deduplicates URLs, and returns (poster_score, art_score, url) tuples.
  • _get_scene_poster() / _get_scene_art(): Now max() over scored candidates instead of taking the first string — a {"url": "...", "type": "screengrab"} item can no longer displace a later {"url": "...", "type": "poster"}.
  • extract_scene_images(): Return type changed from dict[str, str] to list[dict]. Primary poster and art come first; additional candidates with score above the screengrab threshold are appended so Plex's image picker can surface alternatives.
  • map_scene_to_images(): Updated to iterate the new list return from extract_scene_images().

Example — VR payload that previously selected the wrong image:

scene = {
    "slug": "vr-scene-123",
    "images": [
        {"url": "https://cdn/frame.jpg",  "type": "screengrab"},  # was incorrectly chosen
        {"url": "https://cdn/poster.jpg", "type": "poster"},
        {"url": "https://cdn/bg.jpg",     "type": "fanart"},
    ],
}
map_scene_to_metadata(scene)["thumb"]  # → "https://cdn/poster.jpg"  ✓

tests/test_tpdb_enrichment.py

10 new test cases: VR screengrab ordering, explicit poster/background preference over stills, plain-string list fallback, top-level field beats list screengrab, multiple candidates emitted, URL deduplication, screengrab-only last-resort behaviour, legacy string fields, and extract_scene_images list-format contract.

…pecially for VR scenes)

- Add _POSTER_KIND_SCORES, _ART_KIND_SCORES, _SCREENGRAB_SCORE_THRESHOLD constants
- Add _image_kind_from_key() to classify field names/labels to image kinds
- Add _collect_image_candidates() that inspects all image fields with type hints,
  returning (poster_score, art_score, url) tuples
- Refactor _get_scene_poster() and _get_scene_art() to pick highest-scored candidate
  instead of blindly taking the first string found
- Update extract_scene_images() to return list[dict] with multiple candidates,
  enabling Plex to offer alternative image selections
- Update map_scene_to_images() for new list-based extract_scene_images() return
- Add 10 new tests covering: VR screengrab ordering, list type hints,
  deduplication, multiple candidates, screengrab fallback, legacy strings
Copilot AI changed the title [WIP] Update image selection logic for TPDB scene handling Fix image selection to prefer promotional posters over screengrabs for VR and other scenes Jul 21, 2026
Copilot AI requested a review from adeze July 21, 2026 01:35
Copilot finished work on behalf of adeze July 21, 2026 01:35
@adeze
adeze marked this pull request as ready for review July 21, 2026 01:40
Copilot AI review requested due to automatic review settings July 21, 2026 01:40
@adeze
adeze merged commit de5268b into main Jul 21, 2026
@adeze
adeze deleted the copilot/patch-image-selection-logic branch July 21, 2026 01:41

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bb57b2bfd4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +160 to +162
for key, value in images.items():
url = _extract_string(value)
_add(url, _image_kind_from_key(key))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle single-object image dictionaries before iterating keys

When scene["images"] is a single image object such as {"url": "https://...", "type": "poster"}, this loop treats both url and type as image entries. The type value ("poster") is then added as a generic candidate; after the real URL is selected as the primary poster, extract_scene_images() emits the literal string "poster" as an art URL. This makes the images endpoint return an invalid image entry for that valid dict-shaped payload.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves TPDB → Plex image selection so VR (and similar) scenes prefer promotional posters/background art over early screengrabs/stills, and expands the images payload to include multiple high-quality alternatives for Plex’s image picker.

Changes:

  • Introduces kind-based scoring and candidate collection to rank posters/art higher than screengrabs.
  • Updates scene image extraction to return a prioritized list of image entries (primary poster/art first, then additional candidates).
  • Adds targeted tests covering VR ordering, type-hint handling, fallback behavior, URL deduplication, and the new list-return contract.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
provider/mappers/tpdb_to_plex.py Adds scoring + candidate collection and updates extraction/mapping to prefer posters/art over screengrabs and emit multiple image candidates.
tests/test_tpdb_enrichment.py Adds test coverage for the new image ranking behavior and the updated extract_scene_images() return format.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +276 to 280
for entry in scene_images:
image_type = entry["type"]
image_url = entry["url"]
if image_url in seen_urls:
logger.debug(
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants