Skip to content

feat: new plugin — Jellyfin Now Playing (poster, title, progress) v1.0.0 - #219

Merged
ChuckBuilds merged 3 commits into
mainfrom
claude/jellyfin-now-playing-ledmatrix-rv3uyi
Jul 21, 2026
Merged

feat: new plugin — Jellyfin Now Playing (poster, title, progress) v1.0.0#219
ChuckBuilds merged 3 commits into
mainfrom
claude/jellyfin-now-playing-ledmatrix-rv3uyi

Conversation

@ChuckBuilds

@ChuckBuilds ChuckBuilds commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Pull Request

Summary

Adds a new jellyfin-now-playing plugin that polls a Jellyfin server's /Sessions API and shows the active session on the matrix: poster art fitted to the panel height (series poster for TV episodes, album art for music), marquee-scrolling title and subtitle, a paused indicator, and a playback progress bar that is extrapolated between polls so it moves smoothly with no background thread. Also adds the plugin's registry entry to plugins.json (a manual step, since update_registry.py only syncs entries that already exist).

Type of change

  • Bug fix in an existing plugin
  • New plugin (also fill out the SUBMISSION.md checklist below)
  • New feature for an existing plugin
  • Documentation only
  • Repo-wide change (registry script, hook, top-level docs)

Plugin(s) affected

jellyfin-now-playing (new)

Related issues

N/A

Test plan

  • Loaded the plugin in LEDMatrix on real hardware
  • Loaded the plugin in LEDMatrix emulator mode
    (EMULATOR=true python3 run.py)
  • Rendered the plugin in the dev preview server
    (scripts/dev_server.py)
  • Verified the web UI configuration form against the schema
  • N/A — repo-wide / docs-only change

Tested with a stubbed BasePlugin + mock display/cache managers and mocked Jellyfin responses, rendering every state (setup message, nothing playing, playing movie, paused episode, failed poster fetch) at all four panel sizes (64×32, 128×32, 128×64, 256×32) and eyeballing the output PNGs. Assertions covered: session selection (playing preferred over paused, username/content-type/paused filters), episode → series poster + series-name subtitle, tick→seconds conversion, progress extrapolation clamped to duration, anti-flash skip on identical static frames, and buffer size always matching the panel. Also ran python -m py_compile, JSON validation of all new files, scripts/check_module_collisions.py (clean), and update_registry.py --dry-run (new entry syncs as up-to-date at 1.0.0). Not yet run against a live Jellyfin server or real hardware — the core safety harness runs in CI, and test/harness.json renders the deterministic no-network setup screen.

Required for plugin changes

  • Bumped version in plugins/<id>/manifest.json (new plugin ships at 1.0.0)
  • class_name in manifest.json matches the actual class in manager.py exactly (JellyfinNowPlayingPlugin)
  • entry_point matches the real file (manager.py)
  • Updated the plugin's README.md if config keys changed (new README documents every key)
  • config_schema.json is the source of truth for the web UI form — every option has a default, description, and constraints
  • Pre-commit hook ran successfully (auto-syncs plugins.json)

SUBMISSION checklist (new plugins only)

  • Plugin id matches the directory name and is unique
  • manifest.json has all required fields (id, name, version, class_name, display_modes)
  • manager.py inherits from BasePlugin and implements update() and display()
  • config_schema.json exists and validates as JSON Schema Draft-7
  • requirements.txt lists all Python dependencies (requests, Pillow)
  • README.md documents what the plugin does, how to install, and the configuration options
  • LICENSE is GPL-3.0 (copied from clock-simple)
  • No hardcoded API keys or secrets — api_key is declared x-secret and sent only via the Authorization header to the user's own server
  • Tested on a real LEDMatrix setup (or in the emulator) — see test plan; mocked end-to-end only, needs a smoke test against a live Jellyfin server

Checklist

  • My commits follow the message convention in CONTRIBUTING.md
  • I read CONTRIBUTING.md and CODE_OF_CONDUCT.md
  • I've not committed any secrets

Notes for reviewer

  • No background thread (unlike ledmatrix-music): one /Sessions GET per update() tick; the progress bar position is extrapolated locally from PositionTicks + elapsed time while playing, clamped to the duration. Simpler lifecycle, nothing to tear down in cleanup().
  • Episodes intentionally show the series poster (SeriesId), not the episode still — a 2:3 poster reads far better at 21–42 px wide, and stills are landscape.
  • Session selection: filter (username, content types, optionally paused) → prefer playing over paused → keep server order. Documented in the README.
  • Golden images are not committed — the core repo isn't available in this checkout to generate them. test/harness.json makes the harness render the deterministic setup screen with zero network; a follow-up can add a mocked-sessions fixture + goldens once the harness's mock-injection mechanism for HTTP calls is confirmed.
  • plugins.json gained the new entry by hand since update_registry.py only updates existing entries; the pre-commit hook verified it stays in sync.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JCQxU7Rb7yEXBkJ2Pb8im8


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added the Jellyfin Now Playing plugin.
    • Displays currently playing movies, episodes, or audio with artwork, titles, playback status, progress, and scrolling text.
    • Supports configurable polling, filtering, paused playback behavior, fonts, colors, and progress display.
    • Shows setup, error, and “Nothing Playing” states directly on the display.
  • Documentation

    • Added setup instructions, configuration reference, troubleshooting guidance, and privacy details.

…+ progress (v1.0.0)

Polls the Jellyfin /Sessions API and shows the active session: poster art
fitted to the panel height (series poster for TV episodes, album art for
music), marquee-scrolling title and subtitle, a paused indicator, and a
progress bar extrapolated between polls so it moves smoothly without a
background thread.

- Session selection: username filter, content-type filter (Movie/Episode/
  Audio), optional hiding of paused sessions, playing preferred over paused
- API key sent via the Authorization header only, declared x-secret in the
  config schema; sessions cached through cache_manager keyed by plugin id
- On-panel states: setup hint when URL/key missing, "Update API Key" on
  401/403, "Unreachable" on network errors, "Nothing Playing" when idle —
  all anti-flash guarded
- Layouts for 64x32 / 128x32 / 128x64 / 256x32: time readout on wide and
  tall panels, poster placeholder when the image fetch fails
- test/harness.json renders the deterministic setup screen with no network;
  registry entry added to plugins.json (update_registry.py only syncs
  existing entries)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCQxU7Rb7yEXBkJ2Pb8im8
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@ChuckBuilds, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 54 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2f1b82e0-1554-4a88-b5e6-11be34011f57

📥 Commits

Reviewing files that changed from the base of the PR and between 03710a0 and 1963f97.

📒 Files selected for processing (2)
  • plugins/jellyfin-now-playing/manager.py
  • plugins/jellyfin-now-playing/requirements.txt
📝 Walkthrough

Walkthrough

Adds a Jellyfin Now Playing plugin that polls playback sessions, selects active media, caches posters, and renders playback details on an LEDMatrix display. It also adds configuration, manifest, dependencies, documentation, test harness data, and registry metadata updates.

Changes

Jellyfin Now Playing plugin

Layer / File(s) Summary
Plugin contract and registration
plugins/jellyfin-now-playing/config_schema.json, plugins/jellyfin-now-playing/manifest.json, plugins/jellyfin-now-playing/requirements.txt, plugins.json, plugins/jellyfin-now-playing/LICENSE, plugins/jellyfin-now-playing/README.md
Defines validated Jellyfin, display, polling, scrolling, and customization settings; registers the plugin, runtime dependencies, GPLv3 license, and setup documentation.
Session polling and state
plugins/jellyfin-now-playing/manager.py, plugins/jellyfin-now-playing/test/harness.json
Fetches and caches Jellyfin sessions, filters and selects playback, retrieves posters, tracks playback state, and provides deterministic setup-test configuration.
Now-playing display rendering
plugins/jellyfin-now-playing/manager.py
Renders setup, error, idle, paused, and active playback screens with posters, progress bars, time labels, placeholders, text fitting, and marquee scrolling.

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

Sequence Diagram(s)

sequenceDiagram
  participant DisplayManager
  participant JellyfinNowPlayingPlugin
  participant JellyfinServer
  participant CacheManager
  DisplayManager->>JellyfinNowPlayingPlugin: update()
  JellyfinNowPlayingPlugin->>CacheManager: read cached sessions
  JellyfinNowPlayingPlugin->>JellyfinServer: request /Sessions
  JellyfinServer-->>JellyfinNowPlayingPlugin: return playback sessions
  JellyfinNowPlayingPlugin->>CacheManager: cache session and poster data
  DisplayManager->>JellyfinNowPlayingPlugin: display()
  JellyfinNowPlayingPlugin-->>DisplayManager: render playback state
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding the new Jellyfin Now Playing plugin with poster, title, and progress display features.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
  • Commit unit tests in branch claude/jellyfin-now-playing-ledmatrix-rv3uyi

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.

@ChuckBuilds

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@plugins/jellyfin-now-playing/requirements.txt`:
- Around line 1-3: Update the Pillow dependency declaration in requirements.txt
from a minimum of 12.2.0 to 12.3.0, while leaving the requests requirement
unchanged.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fb04f2fd-da7a-498f-a871-5b74a9765d32

📥 Commits

Reviewing files that changed from the base of the PR and between 17db2d9 and 03710a0.

📒 Files selected for processing (8)
  • plugins.json
  • plugins/jellyfin-now-playing/LICENSE
  • plugins/jellyfin-now-playing/README.md
  • plugins/jellyfin-now-playing/config_schema.json
  • plugins/jellyfin-now-playing/manager.py
  • plugins/jellyfin-now-playing/manifest.json
  • plugins/jellyfin-now-playing/requirements.txt
  • plugins/jellyfin-now-playing/test/harness.json

Comment thread plugins/jellyfin-now-playing/requirements.txt Outdated
Pillow 12.2.0 is affected by several PYSEC advisories that are fixed in
12.3.0; the plugin has not shipped yet so this stays within v1.0.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCQxU7Rb7yEXBkJ2Pb8im8
@codacy-production

codacy-production Bot commented Jul 20, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 125 complexity

Metric Results
Complexity 125

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

…analysis

Codacy's credential-disclosure heuristic flagged the logger call because
the message text mentioned "API key"/"secrets", reading it as a hardcoded
secret being logged. Only the HTTP status code is ever logged; reword the
message so the heuristic no longer matches.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCQxU7Rb7yEXBkJ2Pb8im8
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

@ChuckBuilds
ChuckBuilds merged commit 32c40e4 into main Jul 21, 2026
4 checks passed
@ChuckBuilds
ChuckBuilds deleted the claude/jellyfin-now-playing-ledmatrix-rv3uyi branch July 21, 2026 12:04
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.

2 participants