From 8f3dc83543d66478b8908d57e9165edf2b37fa8a Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Thu, 25 Jun 2026 13:37:29 -0500 Subject: [PATCH] fix(api): Correct OpenAPI schema paths for nested M3U profiles and filters by removing escaped slashes, ensuring proper serialization and compatibility with client generators. Updated related API URL patterns for consistency. (Fixes #1384) --- CHANGELOG.md | 1 + apps/m3u/api_urls.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbfe159f..ac28b41a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **`POST /api/epg/import/` no longer loads the full EPG source row.** The dummy-source guard uses a narrow existence query instead of `objects.get()`, keeping the import trigger lightweight. Request/response shape is unchanged for the UI, plugins, and external importers. - **XC live playback URL building now normalizes account server URLs.** On-demand live URLs (introduced for Server Group profile rotation in 0.27.0) rebuild `/live/{user}/{pass}/{stream_id}.ts` from current credentials instead of reusing the synced `stream.url`. That path now runs `normalize_server_url()` so pasted API URLs (e.g. `/player_api.php` with query params) are stripped while sub-paths like `/server1` are preserved. `get_transformed_credentials()` normalizes the base URL at the source; VOD movie and episode relations use the same helper instead of constructing a throwaway `XCClient` (which also avoided per-request HTTP session setup). (Fixes #1363) - **Live proxy now releases geventpool DB connections on more paths.** `stream_ts()` calls `close_old_connections()` before `StreamingHttpResponse` so clients waiting on channel init do not keep a pool slot while the generator polls Redis. `generate_stream_url()`, `get_stream_info_for_switch()`, `get_alternate_streams()`, and `get_connections_left()` release in `finally` blocks after ORM work on stream-manager failover paths that run outside Django's request cycle. TS client disconnect cleanup matches fMP4, and `ChannelService` metadata helpers release after their ORM lookups. +- **OpenAPI schema paths for nested M3U profiles and filters no longer contain escaped slashes.** Router regex prefixes used unnecessary `\/`, which drf-spectacular serialized literally into the schema and broke client generators (e.g. oapi-codegen). Runtime URL matching is unchanged. (Fixes #1384) - **Auto-sync range conflict warning no longer flags a group's own channels when using a channel-group override.** The M3U group settings "Range conflict" check compared occupant channel groups against the source group being configured. Auto-sync with `group_override` creates channels in the override target group, so those channels were misclassified as conflicts. The frontend now resolves the effective target group (override target when set, otherwise the source group) for classification. Genuine conflicts—manual channels, other accounts, different groups, or user-pinned numbers—still surface. (Fixes #1331) — Thanks [@CodeBormen](https://github.com/CodeBormen) ## [0.27.0] - 2026-06-16 diff --git a/apps/m3u/api_urls.py b/apps/m3u/api_urls.py index 6a80a1fe..6b007447 100644 --- a/apps/m3u/api_urls.py +++ b/apps/m3u/api_urls.py @@ -16,12 +16,12 @@ app_name = "m3u" router = DefaultRouter() router.register(r"accounts", M3UAccountViewSet, basename="m3u-account") router.register( - r"accounts\/(?P\d+)\/profiles", + r"accounts/(?P\d+)/profiles", M3UAccountProfileViewSet, basename="m3u-account-profiles", ) router.register( - r"accounts\/(?P\d+)\/filters", + r"accounts/(?P\d+)/filters", M3UFilterViewSet, basename="m3u-filters", )