SergeantPanda
3435d77d20
feat(epg): enhance title search functionality with case-insensitivity and quoted phrases
...
Co-authored-by: Copilot <copilot@github.com>
2026-04-24 15:14:52 -05:00
SergeantPanda
f89df3284e
fix(epg): fix and clean up EPG program search API and tests
...
- Fix test user: set user_level=1 (STANDARD), REMOTE_ADDR="127.0.0.1" to
satisfy IsStandardUser + network_access_allowed checks; move user creation
to setUpTestData (1 DB write per class instead of per test)
- Fix parenthesis parser: group_result was computed then silently discarded;
rewrite parse_expression to recursively compose Q objects correctly so
queries like "(Newcastle OR NEW) AND (Villa OR AST)" work as documented
- Fix field selection performance: resolve allowed fields before serialization
and pass as context; get_channels/get_streams short-circuit when not requested
- Move import re to top of file; remove mid-file alias regex_module
- Convert ProgramSearchAPIView standalone APIView into @action(detail=False)
on ProgramViewSet so the router registers programs/search/ before
programs/{pk}/ automatically, eliminating the URL ordering dependency
- Scope permission to the action directly via permission_classes=[IsStandardUser]
rather than adding "search" to the global permission_classes_by_action dict
- Add test_title_parenthetical_grouping to cover the fixed parser path
- Tighten existing test assertions (case-insensitive, whole-word, description
AND, page_size cap) to catch regressions rather than passing vacuously
Co-authored-by: Copilot <copilot@github.com>
2026-04-24 14:37:12 -05:00
SergeantPanda
672f135b51
tests: Enhance program search API tests for case insensitivity and whole word matching
...
Co-authored-by: Copilot <copilot@github.com>
2026-04-24 13:31:04 -05:00
SergeantPanda
07f6c65ae7
refactor: Removed unneeded files and created a new test that uses django.
...
Co-authored-by: Copilot <copilot@github.com>
2026-04-24 11:34:41 -05:00
SergeantPanda
a85ea2cf01
Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into pr/northernpowerhouse/984
2026-04-24 11:05:19 -05:00
SergeantPanda
29739ede36
Enhancement: VOD start/stop notifications and system events.
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-04-23 18:03:02 -05:00
SergeantPanda
eb9dd391d5
Enhancement: Consolidate client connection notifications and update timestamp handling; replace 'connected_since' with 'connected_at' for improved accuracy in duration calculations.
2026-04-23 11:03:02 -05:00
SergeantPanda
29228612aa
perf/fix: eliminate per-tick DB queries in stats; fix channel notifications
...
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
- Write channel_name (and stream_name fallback) into Redis metadata at
channel init time; read directly from Redis in get_basic_channel_info,
removing Stream and M3UAccountProfile DB queries on every stats tick
- Pass channel.name from views.py into ChannelService.initialize_channel
via new optional channel_name param, skipping the redundant Channel DB
lookup on the normal streaming path
- Pass stream_name from get_stream_info_for_switch through change_stream_url
into _update_channel_metadata, skipping the Stream DB lookup on switches
- Resolve m3u_profile_name on the frontend from the playlists store instead
of querying the DB per tick; StreamConnectionCard builds an id→profile map
- Fix channel start notification showing no name and stop notification
showing UUID: both now use channel_name from the stats WebSocket payload
2026-04-21 18:55:38 -05:00
SergeantPanda
625dab0357
Enhancement: The default profile in the M3U profiles editor now exposes Search Pattern and Replace Pattern fields
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-04-21 17:20:45 -05:00
SergeantPanda
69e0cba86e
Bug Fix: EPG channel name vlaue too long for type character varying(255) ( Fixes #1134 )
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
2026-04-21 09:23:35 -05:00
SergeantPanda
452a493df3
Performance: Fixed N+1 UPDATE queries in the stream-order write path
2026-04-19 09:55:56 -05:00
SergeantPanda
d676903825
Enhancement: Cache channel names to reduce repeated DB queries in StreamManager and StreamGenerator. This improves performance by avoiding unnecessary database calls during retries and logging events. ( Fixes #1138 )
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
2026-04-17 10:55:41 -05:00
SergeantPanda
6cd6d3ef9a
Enhancement: - **Output bitrate DB persistence**: the ffmpeg_output_bitrate stat is no longer written to the database on every FFmpeg stats tick (~2/second). Instead, a local exponential moving average (EMA, α=0.1) accumulates readings continuously. The first 10 samples (~5 seconds) are discarded as warmup to avoid polluting the average with FFmpeg's unstable ramp-up values. After warmup, the smoothed value is flushed to the database at most once every 30 seconds, and a final flush occurs when the stream stops but only if the EMA has been seeded (i.e. the stream ran past warmup). Streams that stop during warmup leave the existing database value untouched, preserving previously accurate measurements when channel-hopping.
2026-04-16 17:15:54 -05:00
SergeantPanda
54ab3e8981
performance:
...
- Performance: `xc_get_epg` now uses `select_related('epg_data__epg_source')` on all three channel fetch paths. Previously each request triggered 2 additional queries to resolve `channel.epg_data` and `channel.epg_data.epg_source`.
- Performance: `generate_m3u` now uses `prefetch_related` for streams when `?direct=true` is requested, eliminating N+1 stream queries (one per channel) on that code path.
- Performance: `EPGGridAPIView` (`apps/epg/api_views.py`) now uses `select_related('epg_data__epg_source')` on the `channels_with_custom_dummy` queryset, eliminating 2 extra queries per channel (for `epg_data` and `epg_source`) in the dummy EPG generation loop.
2026-04-16 13:19:19 -05:00
SergeantPanda
16984bc386
performance:
...
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
- `generate_epg` now uses `select_related('epg_data__epg_source')` on all EPG channel querysets
- `generate_epg` now issues a single cross-channel `ProgramData` bulk query. `.values()` returns plain dicts
- `xc_get_live_streams` no longer calls `ChannelGroup.objects.get_or_create(name="Default Group")` once per null-group channel
2026-04-16 11:12:53 -05:00
SergeantPanda
04ce2dacd1
Merge pull request #1165 from xBOBxSAGETx:perf/select-related-channel-queries
...
CI Pipeline / prepare (push) Has been cancelled
Build and Push Multi-Arch Docker Image / build-and-push (push) Has been cancelled
Frontend Tests / test (push) Has been cancelled
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Has been cancelled
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Has been cancelled
CI Pipeline / create-manifest (push) Has been cancelled
Add select_related to Channel queries in output views
2026-04-14 17:50:10 -05:00
SergeantPanda
e603ff7a49
fix(migration): Fix plugin repo migration that specified AutoField for id instead of BigAutoField.
2026-04-14 16:36:16 -05:00
SergeantPanda
c4972f7dc9
fix: clear previous failure entries after successful logo fetch in LogoViewSet and VODLogoViewSet
2026-04-14 13:34:17 -05:00
SergeantPanda
978714a74d
fix: improve remote logo fetching with timeout and caching for failures
2026-04-14 13:04:45 -05:00
SergeantPanda
f98bb183da
Bug Fix: Fixed a provider TCP connection leak in the VOD proxy
2026-04-13 19:33:22 -05:00
SergeantPanda
55048b60e3
fix(vod-proxy): prevent double profile decrement and clean up stream counter naming
2026-04-13 18:40:33 -05:00
SergeantPanda
d73071b20f
Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into pr/firestaerter3/1125
2026-04-13 17:42:43 -05:00
SergeantPanda
f8407610c8
Bug Fix/Enhancement: Improve logic for get xc epg endpoint for short epgs. Also support epg_days from xc user for xc epg endpoint.
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Has been cancelled
2026-04-12 18:51:40 -05:00
SergeantPanda
9f3d4ff7ff
Enhancement: Improved the EPG response cache key
2026-04-12 18:19:19 -05:00
SergeantPanda
ba967f47d9
Enhancement: **EPG historical data window**: the EPG XML output and XC EPG API now support a prev_days URL parameter (e.g. &prev_days=3) to include past programs in the EPG response. This allows third-party players that request historical program schedules to receive the data they need. The EPG URL builder in the Channels page exposes "Days forward" and "Days back" controls. Per-user defaults for both values (epg_days / epg_prev_days) can be configured in the User settings modal and are applied automatically when no URL parameter is present. ( Closes #1154 )
2026-04-12 16:34:15 -05:00
SergeantPanda
a83b9fdf62
Enhancement: EPG channel scanning now automatically removes stale EPGData entries.
2026-04-12 15:37:28 -05:00
SergeantPanda
b629836b3d
Bug Fix: Fixed stream switch metadata (url, user_agent, stream_id, m3u_profile) being written to Redis before the switch was confirmed to succeed
2026-04-12 12:02:20 -05:00
SergeantPanda
65d14644b4
Bug Fix: Fixed the next_stream rotation endpoint applying the same class of bug
2026-04-12 11:36:08 -05:00
SergeantPanda
ef030b3da0
Bug Fix: Manual stream selection from the Stats page not enforcing M3U profile connection limits in multi-worker deployments
2026-04-12 10:03:46 -05:00
SergeantPanda
f1a82e8843
Bug Fix: Fixed several incorrect or incomplete OpenAPI (@extend_schema) schemas across the API
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-04-11 17:02:07 -05:00
SergeantPanda
1adbc70f53
Bug Fix: Fix bulk channel edit API when including streams array. ( Fixes #883 )
2026-04-11 16:11:45 -05:00
SergeantPanda
bfec229ca9
Enhancements:
...
- Rewrote the M3U line parser as an `iter_m3u_entries` generator that owns the full per-entry state machine. Intermediate directive lines between `#EXTINF` and the stream URL are now handled correctly rather than corrupting the pending entry or being silently misassigned. A `#EXTINF` with no following URL is discarded with a warning instead of carrying over a `url`-less entry into batch processing. Attribute keys are normalised to lowercase during parsing (provider attribute names remain case-insensitive end-to-end). The `#EXTINF` attribute regex is pre-compiled at module load, and attribute lookups use O(1) `dict.get()` instead of linear scans — approximately 10% faster parsing on large M3U files.
- Added support for the `#EXTGRP` directive in M3U files. When a `group-title` attribute is absent from the `#EXTINF` line, the value from a following `#EXTGRP:` line is used as the group. An explicit `group-title` attribute always takes priority. (Closes #1088 )
- Added accumulation of `#EXTVLCOPT` directives per entry. Options are stored as a list under `vlc_opts` inside the stream's `custom_properties`, available for downstream use (e.g. passing VLC-specific options to the player). This is for a planned future enhancement and can also be utlized with the API.
2026-04-11 14:57:52 -05:00
SergeantPanda
fd7ac0029d
Enhancement: M3U stream name parsing now uses the comma text (the canonical display title per the base #EXTINF spec) as the primary stream name, falling back to tvc-guide-title, then tvg-name, rather than preferring tvg-name first. Providers that use tvg-name as an EPG key and put the human-readable title after the comma will now display the correct name. Providers that duplicate the same value in both fields are unaffected. ( Fixes #1081 )
2026-04-11 12:46:36 -05:00
SergeantPanda
8afaa01184
security: Extended rate limiting to the session-auth login alias (POST /api/accounts/auth/login/). It now delegates entirely to TokenObtainPairView, inheriting its throttle, network access check, and audit logging, and returns JWT tokens instead of a session cookie (the session-based response was unusable since SessionAuthentication is not in DEFAULT_AUTHENTICATION_CLASSES). Both endpoints share the same "login" throttle scope, so attempts across either path count against the same per-IP limit.
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
2026-04-10 19:54:10 -05:00
SergeantPanda
e861fca092
Enhancement: Enhanced Swagger UI authorization dialog: registered a custom OpenApiAuthenticationExtension for ApiKeyAuthentication so drf-spectacular now generates an ApiKeyAuth (apiKey) entry alongside jwtAuth. Both entries include descriptive text linking to the relevant endpoints (/api/accounts/token/, /api/accounts/api-keys/generate/, /api/accounts/api-keys/revoke/).
2026-04-10 18:29:13 -05:00
Seth Van Niekerk
2573928e2a
enhance plugin installation and manifest fetching error handling with code review suggestions
2026-04-10 14:44:07 -04:00
Seth Van Niekerk
1cda7b9439
feat: plugin hub
2026-04-10 13:53:45 -04:00
SergeantPanda
c3fb9c0073
security: Fixed missing network_access_allowed checks in the VOD proxy. stream_vod, head_vod, stream_xc_movie, and stream_xc_episode were not checking the STREAMS network policy, unlike the equivalent TS proxy endpoints.
2026-04-10 11:09:27 -05:00
SergeantPanda
fa9a7868ff
security: proxy streaming endpoints (stream_ts, stream_xc, stream_vod, head_vod, stream_xc_movie, stream_xc_episode) use @permission_classes([AllowAny]) (access is controlled by the per-stream-type network allow-list inside the view body); the UserAgentViewSet, StreamProfileViewSet, CoreSettingsViewSet, and ProxySettingsViewSet gained get_permissions() methods mapping read actions to IsStandardUser and write actions to IsAdmin; and AuthViewSet.logout was updated to return [Authenticated()].
2026-04-10 10:47:50 -05:00
SergeantPanda
b535f28ac5
security: Added rate limiting to the login endpoint (POST /api/accounts/token/) using DRF's built-in throttling. A LoginRateThrottle (3 requests/minute per IP, sliding window) is applied to the TokenObtainPairView. Repeated failed attempts from the same IP receive 429 Too Many Requests.
2026-04-09 21:46:50 -05:00
SergeantPanda
47427d4b0f
security:
...
- Set `DEFAULT_PERMISSION_CLASSES` to `Authenticated` in the DRF configuration.
- Explicitly marked the HDHomeRun discovery endpoints (`DiscoverAPIView`, `LineupAPIView`, `LineupStatusAPIView`, `HDHRDeviceXMLAPIView`) and the version endpoint with `permission_classes = [AllowAny]` to document their intentionally public access now that the global default is `Authenticated`.
2026-04-09 21:36:51 -05:00
SergeantPanda
7083c512be
security: Fixed path traversal vulnerability in file uploads. The M3U account upload (apps/m3u/api_views.py), logo upload (apps/channels/api_views.py), and backup upload (apps/backups/api_views.py) all used the uploaded filename directly without sanitization. os.path.join() discards all preceding components when it encounters an absolute path segment, and pathlib's / operator behaves identically; a relative ../ sequence also escapes via OS path resolution at open() time. All three upload paths now strip directory components via Path(name).name and validate the resolved path remains within the intended upload directory. Exploiting any of these required admin credentials.
2026-04-09 21:32:36 -05:00
SergeantPanda
08545b8c92
security: Prevented users from setting xc_password (and other admin-managed keys) on their own account via the PATCH /api/accounts/users/me/ endpoint.
2026-04-09 21:31:38 -05:00
SergeantPanda
dcefc6541c
chore(cleanup): - Removed dead VODConnectionManager class (apps/proxy/vod_proxy/connection_manager.py) and its associated helpers, which had been superseded by MultiWorkerVODConnectionManager. All active code already used the multi-worker implementation. Removed the unused VODConnectionManager import from vod_proxy/views.py, the unscheduled cleanup_vod_connections task from apps/proxy/tasks.py, and the unscheduled cleanup_vod_persistent_connections task from core/tasks.py.
...
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
- Removed dead VOD URL routes: `VODPlaylistView` (playlist generation), `VODPositionView` (position tracking), and the class-based `VODStatsView` (replaced by the existing function-based `vod_stats` view).
- Removed dead `updateVODPosition()` API method from `frontend/src/api.js`, which called the now-removed position tracking endpoint.
2026-04-09 19:59:50 -05:00
SergeantPanda
7f64642003
security: Hardened the HLS proxy change_stream endpoint by converting it from a plain Django view to a DRF @api_view with @permission_classes([IsAdmin]), ensuring the endpoint actually enforces admin-only access. The previous decorator arrangement (@csrf_exempt + @permission_classes) had no effect on a plain Django view.
2026-04-09 19:58:40 -05:00
SergeantPanda
10582a3741
Enhancement: Improved the EPG BOM fix from v0.22.1: replaced the lstrip(b'\xef\xbb\xbf') / startswith approach with start.find(b'<?xml'), which locates the XML declaration regardless of any leading bytes BOM, whitespace, or other encoding markers without needing to know what those bytes are.
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
2026-04-09 11:16:04 -05:00
dwot
b01ec466f1
Fix for #1173 ErsatzTV EPG not populating / fix for UTF-8 BOM processing
2026-04-04 22:15:28 -04:00
xbobxsagetx
0d77884758
Add select_related to Channel queries in output views
2026-04-01 15:14:15 -07:00
SergeantPanda
6f8ca243af
fix: ensure PGSSL* environment variables are explicitly set by stripping inherited values
...
fix: use psycopg2.sql for safe database drop and create commands
fix: Also check POSTGRES_SSL is true before skipping default POSTGRES_PASSWORD
fix: update usage comment to reflect correct script path
fix: improve cleanup logic to conditionally remove certificate directory
2026-03-31 09:51:09 -05:00
None
763f42cfff
fix: pass TLS parameters to all external connection points in modular mode
...
- Add setup_pg_ssl_env() to export libpq PGSSL* env vars; all child psql/pg_dump/pg_isready commands inherit TLS automatically
- Move TLS client key permission fix before external PG connections (was running after, defeating the fix)
- Enhance key fix to trigger on ownership mismatch (root-owned 0600 key unreadable by app user)
- Extract key fix to shared script (docker/init/00-fix-pg-ssl-key.sh) sourced by both entrypoints
- Default POSTGRES_PASSWORD to empty in modular mode (cert-only auth sends no spurious password)
- Propagate TLS OPTIONS to backup pg_dump/pg_restore subprocess calls via _get_pg_env()
- Pass SSL kwargs to dropdb management command's psycopg2.connect()
- Add REDIS_SSL_PARAMS to VOD proxy Redis connections missed in original TLS PR
- Add 8-scenario TLS integration test suite (PG mTLS, Redis TLS, verify-full, key fix, Celery, regression)
- Add 6 unit tests for _get_pg_env() and dropdb TLS parameter passing
2026-03-30 20:19:27 -05:00