Skip to content

Added API endpoints for sports events - #3523

Draft
Sportarr wants to merge 7 commits into
morpheus65535:sportarrfrom
Sportarr:sportarr-api
Draft

Added API endpoints for sports events#3523
Sportarr wants to merge 7 commits into
morpheus65535:sportarrfrom
Sportarr:sportarr-api

Conversation

@Sportarr

Copy link
Copy Markdown

Exposes the sports data the previous PRs build, so a UI has something to read and act on. Five namespaces under sports, matching the shape of the episodes and series ones.

Leagues lists the library with a file count and a missing count, sets the languages profile, and runs the scan, search and sync actions. Events lists one row per playable file, ordered by part so the prelims stay above the main card. Wanted, history and blacklist mirror their episode equivalents.

The badges endpoint gains a sports count and the Sportarr stream state, next to the existing Sonarr and Radarr ones.

Blacklisting a sports subtitle deletes it and searches again, so delete_subtitles gets a sports branch. Sports events carry no media server ids, so there is nothing to refresh in Plex or Jellyfin, and the league rescan covers Sportarr.

History has no upgradable flag. Subtitle upgrades have no sports path yet, and a flag that always reads false is worse than no flag.

A fix that came out of testing

postprocess builds the image proxy URL by putting the Bazarr base URL in front of whatever poster or fanart holds. Sonarr and Radarr give a path, so that is right for them. Sportarr gives a complete URL, and the prefix produced /images/serieshttps://..., which no client can load. It now leaves an image alone when it already carries a scheme. Separate commit.

Testing

Ran every endpoint against a live instance with a two part event synced from a Sportarr built from current source.

  • Leagues, events, wanted, history and blacklist all return the expected rows, with the parts ordered and named
  • Clearing the languages profile empties both missing lists, restoring it recomputes them
  • Each league action runs, and an unknown action returns 400
  • Blacklisting deletes the subtitle from disk, writes the blacklist and history rows, and asks Sportarr to rescan
  • Deleting one blacklist entry and deleting all both work
  • Badges reports the sports count and the stream state
  • All five namespaces appear in swagger.json, and pytest tests/bazarr/ passes, 173 tests

Depends on

The subtitles search PR, for the tables and the search functions these call.

I used an AI coding assistant while building this, modeled closely on your existing Sonarr integration. I directed the design, reviewed every line, and tested it against a live Bazarr instance with real data. I can explain any part of it.

@morpheus65535 morpheus65535 added the PR on Standby PR waiting an action before it get merged. label Aug 15, 2026
Mirrors store_subtitles for sports events so embedded and external
subtitles are found and stored per playable file, then computes the
missing subtitles for each one against the league's language profile.

A row is one part, so a fight card's prelims and main card each get
their own subtitles rather than sharing a set.

parse_video_metadata gains a sports_event_id parameter. Sportarr file
IDs and Sonarr episode file IDs are unrelated sequences, so caching the
sports ffprobe result under episode_file_id would write over an
unrelated episode's cache. The sports cache goes to its own table.

Indexing runs when the events sync inserts a row, and again when the
file id or the path changes. Sportarr gives a new file id when it
replaces a file, and an upgrade can keep the same path, so the id is
what proves the media changed.

The full scan task uses the sportarr.full_update settings that already
exist but had nothing reading them.
Gives sports events the same wanted list and search that series and movies
already have. An event with missing subtitles is picked up by a scheduled
search, or by a search for one league, and the result is stored, logged to
history, and reported back to Sportarr.

A sports event is scored as an episode. Sportarr gives it a season and an
episode number, and get_video already builds it as an episode, so the
episode scores and the episode minimum score apply to it unchanged. The
post-processing threshold follows the same reasoning.

Sportarr has no per event notify endpoint, so a downloaded subtitle asks it
to rescan the league folder, which is the documented way to tell it a file
changed.

Two tables come with this. Sports history is separate from series history
because a sports event id is not an episode id, and the sports blacklist has
to be its own list so blocking a bad subtitle for an event does not touch an
episode.

Changes:
- Schema: table_history_sports and table_blacklist_sports, with a migration
- sportarr/history.py, sportarr/blacklist.py, sportarr/notify.py
- pool.py: pick the blacklist by media type instead of a two way branch
- download.py, processing.py, utils.py: a sports branch beside series and
  movies
- get_exclusion_clause: sports tags, monitored state and excluded sports
- subtitles/wanted/sports.py and subtitles/mass_download/sports.py
- scheduler: search for missing sports events subtitles
Exposes the sports data the previous PRs build, so a UI has something to
read and act on. Five namespaces under sports, matching the shape of the
episodes and series ones.

Leagues lists the library with a file count and a missing count, sets the
languages profile, and runs the scan, search and sync actions. Events lists
one row per playable file, ordered by part so the prelims stay above the
main card. Wanted, history and blacklist mirror their episode equivalents.

The badges endpoint gains a sports count and the Sportarr stream state,
next to the existing Sonarr and Radarr ones.

Blacklisting a sports subtitle deletes it and searches again, so
delete_subtitles gets a sports branch. Sports events carry no media server
ids, so there is nothing to refresh in Plex or Jellyfin. The league rescan
covers Sportarr.

History has no upgradable flag. Subtitle upgrades have no sports path yet,
and a flag that always reads false is worse than no flag.

Changes:
- api/sports: leagues, events, wanted, history, blacklist
- api/badges: sports wanted count and the Sportarr stream state
- subtitles/tools/delete.py: sports branch
postprocess builds an image proxy URL by putting the Bazarr base URL in
front of whatever the item holds. Sonarr and Radarr give a path, so that is
correct for them. Sportarr gives a complete URL, and the prefix produced
/images/serieshttps://..., which no client can load.

Leave an image alone when it already carries a scheme.
Mirrors the series/tags endpoint so the sports library view can feed its tags filter from the full set of tags in use, the same way the series and movies views do after the mass selection rework.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR on Standby PR waiting an action before it get merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants