Skip to content

feat(images): add larger TV image variants - #336

Closed
raiden202 wants to merge 3 commits into
Silo-Server:mainfrom
raiden202:pr/tv-image-variants
Closed

feat(images): add larger TV image variants#336
raiden202 wants to merge 3 commits into
Silo-Server:mainfrom
raiden202:pr/tv-image-variants

Conversation

@raiden202

@raiden202 raiden202 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

feat(images): add larger TV image variants

Problem

Large TV detail surfaces can upscale the existing small still/logo variants, which is especially noticeable on 4K displays. Episode stills also reuse a smaller card thumbnail path where a TV-sized still variant is more appropriate.

Approach

Add larger generated variants for TV-sized still and logo surfaces, use a still-specific episode image variant where needed, and preserve fallback behavior for cached images whose larger variants have not been generated yet. Fallback presigned URLs are cached only for the short missing-variant window, so a refresh-generated larger object is picked up promptly. Focused tests cover variant selection, generated variant ladders, and S3 resolver fallback from new keys to older cached variants.

Verification

go test ./internal/api/handlers ./internal/catalog ./internal/imagecache ./internal/metadata
git diff --check

Risks & follow-up

Moderate risk. The change is additive and keeps existing small card surfaces on smaller variants, but operators should expect extra S3/storage and cache-warm bandwidth once images refresh: logos add w1280 alongside existing logo variants, and stills add w780 alongside existing still variants. Existing cached media can continue to fall back when larger variants are unavailable, and missing larger variants are filled only when refresh/upload runs.

AI-use disclosure

Implemented with a combination of Claude Code and Codex assistance, with human oversight.

Summary by CodeRabbit

  • Improvements
    • Episode still images now use larger, dedicated variants (including consistent w780 scaling), while backdrops follow safer cached limits.
    • Episode artwork fallback now selects the most appropriate card-sized variant (poster/backdrop/card-thumbnail behavior remains correct).
    • Image resizing has updated variant ladders for logo, still, poster, and profile for better consistency.
    • When an image variant isn’t available, the system automatically falls back to the nearest supported lower-size version and refreshes sooner for missing variants.
    • Logos can now be delivered in higher-resolution variants.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds w780 episode still variants and w1280 logo variants, updates API and catalog path selection, expands image-cache ladders, and adds cached S3 existence checks with fallback presigning for missing new variants.

Changes

Episode still w780 variant support

Layer / File(s) Summary
Image variant ladders
internal/artworkkey/artworkkey.go, internal/artworkkey/artworkkey_test.go, internal/imagecache/imagecache_test.go
Still ladders now include w780, w500, and w300; logo ladders include w1280 and w500, with updated tests.
Catalog variant clamping updates
internal/catalog/detail.go, internal/catalog/image_variants_test.go
Catalog variant mapping clamps large still requests to w780 and large logo requests to w1280, with updated documentation and tests.
Episode response still path resolution
internal/api/handlers/items.go, internal/api/handlers/episode_image_variant_test.go, internal/api/handlers/sections_test.go
Episode responses use w780 for own stills and w300 card variants for fallback artwork, with centralized path rewriting and updated tests.
S3 presign fallback for missing new variants
internal/metadata/image_resolver.go, internal/metadata/image_resolver_test.go
The resolver checks and caches new variant existence, presigns configured fallback keys when missing, shortens fallback expiry, and preserves requested keys on check errors.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PluginImageResolver
  participant variantExistsCache
  participant S3Presigner

  PluginImageResolver->>variantExistsCache: look up variant existence
  alt cache miss
    PluginImageResolver->>S3Presigner: ObjectExists(requested key)
    S3Presigner-->>PluginImageResolver: existence result
    PluginImageResolver->>variantExistsCache: cache successful result
  end
  alt requested variant missing
    PluginImageResolver->>S3Presigner: PresignGetURL(fallback key)
  else requested variant exists or check errors
    PluginImageResolver->>S3Presigner: PresignGetURL(requested key)
  end
  S3Presigner-->>PluginImageResolver: presigned URL
Loading

Suggested labels: v1

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding larger TV image variants.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@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: 66f8ab4cc9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread internal/metadata/image_resolver.go Outdated
@raiden202
raiden202 force-pushed the pr/tv-image-variants branch from 66f8ab4 to c2f220a Compare July 8, 2026 18:03
@raiden202

Copy link
Copy Markdown
Contributor Author

Addressed the fallback caching review in c2f220a. Missing new-variant S3 fallbacks now cap their resolved-URL cache window to the same short missing-variant TTL, so refreshed w780/w1280 objects are picked up promptly instead of waiting on the full presign cache window. Added a regression test for the fallback URL cache TTL and reran the relevant Go package tests.

@raiden202
raiden202 force-pushed the pr/tv-image-variants branch from c2f220a to e0b6247 Compare July 9, 2026 13:47
@coderabbitai coderabbitai Bot added the v1 Silo v1 scope - auto-adds to the Silo v1 project label Jul 9, 2026

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
internal/metadata/image_resolver_test.go (1)

379-424: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider covering the exists and ObjectExists error branches.

The tests validate the missing-variant fallback and its TTL well, but existingVariantKey has two untested branches: object-exists (presign w780 directly, cache true for 24h) and the optimistic error path (presign requested key, no caching). Adding cases via existing[...]=true and an ObjectExists error would lock in the no-fallback behavior and prevent regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/metadata/image_resolver_test.go` around lines 379 - 424, Add tests
in TestPluginImageResolverS3... to cover the remaining existingVariantKey
branches: one where fakeS3ImagePresigner reports ObjectExists true for the
requested w780 key so ResolveImageURLWithExpiry returns the direct w780 presign
and caches it with the existing-variant TTL, and another where ObjectExists
returns an error so the resolver still presigns the requested key but does not
cache the existence result. Use the existing PluginImageResolver,
SetS3Presigner, and fakeS3ImagePresigner helpers to assert both the returned URL
and the presigner call counts/keys.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/metadata/image_resolver_test.go`:
- Around line 379-424: Add tests in TestPluginImageResolverS3... to cover the
remaining existingVariantKey branches: one where fakeS3ImagePresigner reports
ObjectExists true for the requested w780 key so ResolveImageURLWithExpiry
returns the direct w780 presign and caches it with the existing-variant TTL, and
another where ObjectExists returns an error so the resolver still presigns the
requested key but does not cache the existence result. Use the existing
PluginImageResolver, SetS3Presigner, and fakeS3ImagePresigner helpers to assert
both the returned URL and the presigner call counts/keys.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2fa57f2c-1aa6-4b72-937a-861b0fb44ba5

📥 Commits

Reviewing files that changed from the base of the PR and between 581f39b and e0b6247.

📒 Files selected for processing (9)
  • internal/api/handlers/episode_image_variant_test.go
  • internal/api/handlers/items.go
  • internal/api/handlers/sections_test.go
  • internal/catalog/detail.go
  • internal/catalog/image_variants_test.go
  • internal/imagecache/imagecache.go
  • internal/imagecache/imagecache_test.go
  • internal/metadata/image_resolver.go
  • internal/metadata/image_resolver_test.go

@raiden202
raiden202 force-pushed the pr/tv-image-variants branch 2 times, most recently from db61955 to e019603 Compare July 9, 2026 19:01
@raiden202
raiden202 force-pushed the pr/tv-image-variants branch 2 times, most recently from 0849a58 to cdc62dd Compare July 16, 2026 08:23

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
internal/catalog/detail.go (1)

3691-3701: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove redundant poster case.

The poster case is identical in behavior to the default case. It can be removed to simplify the switch statement.

♻️ Proposed refactor
-	case "poster":
-		if size == "small" {
-			return "w300"
-		}
-		return "w500"
 	default:
 		if size == "small" {
 			return "w300"
 		}
 		return "w500"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/catalog/detail.go` around lines 3691 - 3701, Remove the redundant
"poster" branch from the switch, leaving the existing default branch to handle
it and preserve the current size-to-dimension behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/catalog/detail.go`:
- Around line 3691-3701: Remove the redundant "poster" branch from the switch,
leaving the existing default branch to handle it and preserve the current
size-to-dimension behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a83db50a-bbaf-459d-871d-66026cc6ebb3

📥 Commits

Reviewing files that changed from the base of the PR and between db61955 and cdc62dd.

📒 Files selected for processing (5)
  • internal/api/handlers/episode_image_variant_test.go
  • internal/api/handlers/items.go
  • internal/api/handlers/sections_test.go
  • internal/catalog/detail.go
  • internal/catalog/image_variants_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • internal/api/handlers/episode_image_variant_test.go
  • internal/catalog/image_variants_test.go
  • internal/api/handlers/sections_test.go
  • internal/api/handlers/items.go

@raiden202
raiden202 force-pushed the pr/tv-image-variants branch 2 times, most recently from d189b08 to dcbff12 Compare July 23, 2026 23:27
@raiden202
raiden202 force-pushed the pr/tv-image-variants branch from dcbff12 to 2d46aa5 Compare August 17, 2026 11:13
Silo Contributor and others added 3 commits August 17, 2026 17:18
Add larger generated variants for TV-sized still and logo surfaces, while preserving existing fallbacks for cached images that have not yet been refreshed. Episode still responses use a still-specific variant path instead of the small card thumbnail path.
@Quick104

Copy link
Copy Markdown
Contributor

Thanks @raiden202 — this PR correctly identified both the missing large TV variants and the need for an S3 existence-check fallback while older libraries catch up, and that design is carried forward with credit in #742, which supersedes this PR. #742 extends the same idea to posters (the most visible blur on 4K TVs), adds a client-facing image_size request parameter with a capability endpoint, and an automatic one-shot backfill so existing libraries regenerate the new rungs without operator action. Closing in favor of #742; your groundwork here is appreciated.

@Quick104 Quick104 closed this Aug 24, 2026
@github-project-automation github-project-automation Bot moved this to Done in Silo v1 Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v1 Silo v1 scope - auto-adds to the Silo v1 project

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants