Commit graph

60 commits

Author SHA1 Message Date
SergeantPanda
843940f552 refactor(http headers): centralize User-Agent construction and streamline API requests
- Introduced `dispatcharr_user_agent`, `dispatcharr_dvr_user_agent`, and `dispatcharr_http_headers` functions in `core.utils` to standardize User-Agent strings and HTTP headers for outbound requests.
- Updated various components, including `LogoViewSet`, `EPGSourceViewSet`, and VOD proxy views, to utilize the new header functions, ensuring consistent User-Agent usage across the application.
- Enhanced the handling of Schedules Direct API requests by including proper User-Agent headers, addressing previous API compliance issues.
2026-06-11 09:45:35 -05:00
SergeantPanda
ed364a26c9 refactor(EPGSourceViewSet, frontend): streamline SD countries fetching and remove proxy endpoint
- Introduced a new method `_fetch_sd_countries` in `EPGSourceViewSet` to fetch SD countries directly from the backend, eliminating the need for a separate proxy endpoint.
- Updated the `sd_lineups` action to include the fetched countries in the response.
- Removed the `getSDCountries` method from the API and adjusted the frontend to fetch countries alongside lineups, improving efficiency
- Updated related components to handle the new data structure for countries.
2026-06-11 09:00:35 -05:00
Seth Van Niekerk
887a177581
proxy SD country list fetch through backend to fix CORS failure 2026-06-10 08:46:02 -04:00
SergeantPanda
3835954024 fix: enhance API request headers and improve cast handling in schedule fetching
Add User-Agent header to API requests in ProgramViewSet for better tracking. Update cast processing logic in fetch_schedules_direct to align with XMLTV standards, ensuring proper categorization of main cast and guest stars.
2026-06-04 21:30:05 -05:00
Shokkstokk
aa9e78f858 fix: allow unauthenticated access to SD poster proxy endpoint
ProgramViewSet.get_permissions() was falling through to Authenticated()
for the poster action since it wasn't in permission_classes_by_action.
Add explicit AllowAny check for the poster action.
2026-06-05 00:12:17 +00:00
SergeantPanda
8f060e8b3a feat: Output SD program poster images during xml output and enhance caching logic 2026-06-04 15:17:58 -05:00
Shokkstokk
4eec542ef8
Merge branch 'dev' into feature/schedules-direct-epg 2026-06-03 23:38:54 -04:00
SergeantPanda
5d2bc2606c fix(epg): add force refresh option for EPG data import and update related API methods 2026-05-31 11:22:04 -05:00
Five Boroughs
10d558f136
perf(epg): async index build, defer index column, tight build lock, channel-id canonicalization, retry-on-error 2026-05-31 17:13:11 +02:00
SergeantPanda
1e9fd28653
perf(epg): defer loading of programme_index in EPGSourceViewSet for performance improvement
Co-authored-by: Copilot <copilot@github.com>
2026-05-31 17:13:11 +02:00
SergeantPanda
690fa10be4
refactor(epg): remove redundant current time retrieval in CurrentProgramsAPIView 2026-05-31 17:13:11 +02:00
Five Boroughs
3c5032ee71
Batch ProgramData query and invalidate index on EPG refresh
- Replace per-entry ProgramData DB query with single batch fetch
- Pass pre-loaded EPGData objects to find_current_program_for_tvg_id
  to avoid redundant select_related re-fetch
- Delete Redis programme index before XMLTV download so stale byte
  offsets are never used during the refresh window
2026-05-31 17:13:11 +02:00
Five Boroughs
2bf4e8cd0f
WIP: EPG channel preview with byte-offset index lookup 2026-05-31 17:13:11 +02:00
FiveBoroughs
4594cce47a
Revert unintended linter style changes in api_views.py 2026-05-31 17:13:11 +02:00
FiveBoroughs
ef1518a8dd
Fix: Auto-parse EPG programs for unlinked channels on preview
When selecting an EPG channel in the channel form, if that EPG entry's
programs had never been parsed, the preview showed "No current program".
This was because parse_programs_for_tvg_id requires a linked channel.

- Add force parameter to parse_programs_for_tvg_id to bypass channel check
- Auto-trigger parsing from current-programs API when no programs exist
- Check Redis task lock to prevent duplicate parse tasks from concurrent requests
- Frontend retries up to 3 times with 10s delay to pick up parsed results
- Skip parsing for dummy EPG sources
2026-05-31 17:13:11 +02:00
FiveBoroughs
9367d76dac
Add EPG program preview to channel edit/create modal
- Extended CurrentProgramsAPIView to accept epg_data_ids parameter
- Added getCurrentProgramForEpg() API method in frontend
- Added UI in Channel form showing current program with tooltip
- Shows loading state, no program state, and program details
- Includes expandable description, progress bar with elapsed/remaining time
- Matches stats page 'Now Playing' feature behavior
2026-05-31 17:13:11 +02:00
SergeantPanda
7d2f0cdab3 fix(epg): update permission handling for sd_lineups actions in EPGSourceViewSet 2026-05-31 10:03:03 -05:00
mwhit
d8c0850fd8 fix(epg): address second round of reviewer feedback
- Fix NameError in sd_lineups_search: add dispatcharr_version import
- Fix DELETE handler: persist changesRemaining from SD response to custom_properties
- Fix lockout reset time: calculate next midnight UTC (00:00Z) instead of
  rolling now+24h, matching SD's documented reset behavior
- Remove redundant explicit index from SDProgramMD5: unique_together already
  creates this index in Postgres
2026-05-19 23:48:11 +00:00
mwhit
6f316977ad fix(epg): address reviewer feedback on SD integration
- Rename api_key to password (RemoveField + AddField) for clarity and reusability
- Move sd_changes_remaining/sd_changes_reset_at to custom_properties JSONField
  instead of nullable columns on all EPGSource rows
- Replace sd_program_md5 column on ProgramData with SDProgramMD5 relation table
  keyed by epg_source + program_id, fixing the key mismatch bug in program
  MD5 delta detection
- Fix total_changed counter: .items() -> .values() so len() returns date count
  not tuple length
- Add missing SD lineup management endpoints to api_views.py
  (sd_lineups GET/POST/DELETE, sd_lineups_search POST)
- Regenerate migration 0023_schedules_direct using Django to ensure correct
  index names and schema
2026-05-18 22:46:56 +00:00
SergeantPanda
5940efbddf feat: Enhance series rule evaluation and management
- Added support for customizable title and description matching modes in series rules.
- Implemented a preview feature for series rules to show matching upcoming programs.
- Created a new SeriesRuleEditorModal for editing series rules with improved UI.
- Refactored query parsing logic into reusable functions for better maintainability.
- Updated API to handle new parameters for series rule creation and evaluation.
- Enhanced the ProgramRecordingModal and SeriesRecordingModal to integrate the new rule editor.
- Added pagination for program search results in the API.
2026-05-04 20:45:40 -05:00
SergeantPanda
292a443a09 feat(epg): restrict program access based on user permissions and enhance channel filtering
Co-authored-by: Copilot <copilot@github.com>
2026-04-24 16:05:29 -05:00
SergeantPanda
c486f641a8 fix(epg): improve parameter descriptions and enhance title whole word matching tests. Fix bug with postgres whole words (they use \y not \b for regex)
Co-authored-by: Copilot <copilot@github.com>
2026-04-24 15:46:56 -05:00
SergeantPanda
dbbc2f5735 fix(api): update parameter descriptions for clarity and consistency in Program API
Co-authored-by: Copilot <copilot@github.com>
2026-04-24 15:28:28 -05:00
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
a85ea2cf01 Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into pr/northernpowerhouse/984 2026-04-24 11:05:19 -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
f1a82e8843 Bug Fix: Fixed several incorrect or incomplete OpenAPI (@extend_schema) schemas across the API
Some checks are pending
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
1f50217dbe perf(epg): speed up TV guide grid load 2k channels from 18s to ~8s
Replace DRF ModelSerializer with .values() + plain dict construction in
EPGGridAPIView, eliminating per-row serializer instantiation, field
object creation, and OrderedDict overhead across ~12k programs.

Pre-compute season/episode at import time instead of on every API request:
- Extract S/E from onscreen episode-num inline in extract_custom_properties()
  immediately after storing the raw value, rather than in a separate pass
- Add missing description-based S/E fallback to parse_programs_for_tvg_id(),
  bringing it in line with parse_programs_for_source()

Remove runtime extract_season_episode() call from ProgramDataSerializer and
EPGGridAPIView — values are now guaranteed to be in custom_properties after
import, so season/episode resolution is a plain dict lookup at request time.

Also remove unnecessary select_related("epg") JOIN and .count() query from
the grid endpoint.
2026-03-13 12:16:10 -05:00
None
79dc113a1c remove infer_is_live()
After discussion, decided to keep live badge inference deterministic
2026-03-12 16:01:35 -05:00
None
b72a9a870e feat(guide): redesign guide with detail modal, progress bars, and season/episode display
Replace expanded inline cards with a ProgramDetailModal for viewing full program
details. Add real-time progress bars to currently-airing programs using direct DOM manipulation. Extract and display season/episode info from EPG data with a 3-tier fallback (custom_properties → onscreen_episode → description text).

Backend:
- Add ProgramDetailSerializer for rich EPG data (categories, credits, ratings, images, external IDs) served on the detail endpoint
- Add infer_is_live() for status badges (live, new, premiere, finale)
- Add shared S/E extraction utilities in apps/epg/utils.py
- Optimize querysets with select_related("epg")

Frontend:
- ProgramDetailModal with conditional field rendering and image fallback chain
- Progress bars via scaleX transform updated every second
- Parallel data fetching with Promise.all for channels + programs
- Browser tab visibility recovery for progress bars
- Now-line with triangle marker and sub-millisecond precision
- Card layout: title, season/episode + subtitle, time + badges
- Shared formatSeasonEpisode() and external URL helpers
2026-03-10 10:53:19 -05:00
SergeantPanda
4aa0d3ae01 feat(epg): enhance EPGGridAPIView to include live and new tags for dummy programs. 2026-03-06 13:43:53 -06:00
None
a9c90059d6 feat: add status badges (live, new, premiere, finale) to guide cards
Add is_new, is_live, is_premiere, and is_finale fields to the EPG program API and render them as colored badges in the TV guide.

- Compact card: S/E, LIVE, and NEW badges on the title row
- Expanded card: all badges (S/E, LIVE, NEW, PREMIERE, FINALE) on the subtitle row, now moved directly after title for consistency
- PREMIERE/FINALE detected from premiere_text (case-insensitive)
- PREMIERE/FINALE only shown in expanded view to conserve space
- Badge order: S/E → LIVE → NEW → PREMIERE → FINALE
2026-03-06 12:19:00 -06:00
None
ee112de84a feat: add subtitle and season/episode to TV guide
Display sub_title (episode name) and season/episode badge on guide program cards. Extract season/episode from custom_properties with fallback parsing of onscreen_episode format (e.g. "S12 E6").

- Add season/episode SerializerMethodFields to ProgramDataSerializer
- Parse onscreen_episode string as fallback when xmltv_ns data absent
- Display sub_title with S/E badge on guide cards
- Show description for programs without sub_title (movies)
- Add formatSeasonEpisode utility with full test coverage
- Add 15 backend serializer tests and 12 frontend utility tests

Fulfills #1065
2026-03-05 23:41:16 -06:00
SergeantPanda
565d335403 Bug Fix: The EPG filter dropdown was showing all EPG sources regardless of whether they had any channels assigned, and the "No EPG" option was never displayed. Fixed by annotating EPGSource records with a has_channels flag (via a lightweight EXISTS subquery) so only EPG sources actually in use appear as filter options. "No EPG" now appears only when at least one channel has no EPG assigned, determined via a page_size=1 query against the existing channel filter endpoint.
Some checks are pending
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-03-01 16:54:05 -06:00
SergeantPanda
60c165f422 Enhancement: Stats page "Now Playing" EPG lookup updated to use channel_uuids directly (the proxy stats already key active channels by UUID), removing the need for a UUID→integer ID conversion step introduced alongside the lazy channel-fetch refactor. Stream preview sessions (which use a content hash rather than a UUID as their channel ID) are now filtered out before any API call is made, preventing a backend ValidationError on both the current-programs and by-uuids endpoints when a stream preview is active on the Stats page. 2026-02-26 12:00:29 -06:00
Northern Powerhouse
14fa187a4e Fix datetime validation and test timestamp format
- Add proper datetime validation in API with 400 error responses
- Fix test timestamp format (was creating invalid +00:00Z format)
- Time filters now properly validate and return errors on invalid input
- All 26 tests passing with correct filtering behavior
2026-02-14 16:05:23 +01:00
Northern Powerhouse
22978aa132 Add EPG program search API endpoint with advanced filtering
- Add ProgramSearchResultSerializer with nested channel/stream data
- Implement ProgramSearchAPIView with comprehensive filtering:
  * Text search with AND/OR operators and parenthetical grouping
  * Regex pattern matching support
  * Whole word matching to avoid partial matches
  * Time-based filtering (airing_at, start/end ranges)
  * Channel/stream/group filtering
  * Configurable field selection for response customization
  * Pagination (50 default, 500 max per page)
- Add /api/epg/programs/search/ endpoint
- Add comprehensive API documentation
- Enhanced Swagger/OpenAPI schema with examples

Examples:
  - Complex queries: (Newcastle OR NEW) AND (Villa OR AST)
  - Whole words: title=NEW&title_whole_words=true
  - Regex: title=^Premier&title_regex=true
  - Time filtering: airing_at=2026-02-14T20:00:00Z
2026-02-14 15:48:02 +01:00
SergeantPanda
890992a9f9 feat(scheduling): add cron builder and refactor scheduling components (Closes #165)
Add cron expression support for M3U and EPG refreshes with interactive
builder modal and quick reference examples. Refactor backup scheduling
to use shared ScheduleInput component for consistency.

- New CronBuilder modal with preset buttons and custom field editors
- Info popover with common cron expression examples
- Shared ScheduleInput component for interval/cron toggle
2026-02-12 18:08:13 -06:00
SergeantPanda
5364123745 - Swagger/OpenAPI Migration: Migrated from drf-yasg (OpenAPI 2.0) to drf-spectacular (OpenAPI 3.0) for API documentation. This provides:
- Native Bearer token authentication support in Swagger UI - users can now enter just the JWT token and the "Bearer " prefix is automatically added
  - Modern OpenAPI 3.0 specification compliance
  - Better auto-generation of request/response schemas
  - Improved documentation accuracy with serializer introspection
2026-01-27 13:33:33 -06:00
SergeantPanda
0e1db3e39c Enhancement: - Stats page enhancements: Added "Now Playing" program information for active streams with smart polling that only fetches EPG data when programs are about to change (not on every stats refresh). Features include:
- Currently playing program title displayed with live broadcast indicator (green Radio icon)
  - Expandable program descriptions via chevron button
  - Efficient POST-based API endpoint (`/api/epg/current-programs/`) supporting batch channel queries or fetching all channels
  - Smart scheduling that fetches new program data 5 seconds after current program ends
  - Only polls when active channel list changes, not on stats refresh
- Channel preview button: Added preview functionality to active stream cards on stats page
2026-01-20 13:37:40 -06:00
SergeantPanda
22fb0b3bdd Enhancement: Add Custom Dummy EPG with Dynamic Pattern Matching and Name Source Selection
This enhancement introduces a powerful custom dummy EPG system that allows users to generate EPG programs on-demand by parsing channel or stream names using configurable regex patterns.

Key Features:
- Custom Pattern Matching: Define regex patterns to extract information from channel/stream names (teams, leagues, times, dates, etc.)
- Flexible Name Source: Choose to parse either the channel name or a specific stream name (by index)
- Timezone-Aware Scheduling: Automatic DST handling using pytz timezone names (e.g., 'US/Eastern', 'Europe/London')
- Time Format Support: Parse both 12-hour (AM/PM) and 24-hour time formats
- Date Parsing: Extract dates from names with flexible month/day/year patterns
- Custom Templates: Format EPG titles and descriptions using captured groups with {placeholder} syntax
- Upcoming/Ended Customization: Define custom titles and descriptions for programs before and after scheduled events
- Live Preview: Test patterns and templates in real-time with sample input
- Smart Program Generation: Automatically creates "Upcoming" and "Ended" programs around scheduled events

Use Cases:
- Sports channels with event details in stream names (e.g., "NHL 01: Bruins VS Leafs @ 8:00PM ET")
- Movie channels with genre/title/year information
- Racing events with driver/track/series details
- Any scenario where EPG data is embedded in channel/stream naming conventions

Technical Implementation:
- Backend: Pattern matching engine with timezone conversion and program scheduling logic
- Frontend: Interactive form with validation, pattern testing, and visual group preview
- Name Source Options: Parse from channel name or selectable stream index (1-based)
- Fallback Behavior: Uses standard dummy EPG if patterns don't match
- Custom Properties: Stores all configuration in EPGSource.custom_properties JSON field

Configuration Options:
- Title Pattern: Extract primary information (required)
- Time Pattern: Extract hour/minute/AM-PM (optional)
- Date Pattern: Extract month/day/year (optional)
- Timezone: Event timezone with automatic DST support
- Program Duration: Length of generated programs in minutes
- Title Template: Format EPG title using captured groups
- Description Template: Format EPG description using captured groups
- Upcoming Title Template: Custom title for programs before event starts (optional)
- Upcoming Description Template: Custom description for programs before event starts (optional)
- Ended Title Template: Custom title for programs after event ends (optional)
- Ended Description Template: Custom description for programs after event ends (optional)
- Name Source: Channel name or stream name
- Stream Index: Which stream to use when parsing stream names (1, 2, 3, etc.)

Closes #293
2025-10-18 12:08:56 -05:00
dekzter
3f445607e0 looooots of updates for user-management, initial commit of access control 2025-05-31 18:01:46 -04:00
dekzter
74d58515d0 user management, user levels, user level channel access 2025-05-18 11:19:34 -04:00
SergeantPanda
eecf879119 Added random descriptions for dummy channels in tv guide. 2025-05-16 11:08:52 -05:00
SergeantPanda
e63a66bf57 Change status to disabled when epg or m3u disabled. Change to idle when enabled. 2025-05-07 13:50:10 -05:00
SergeantPanda
b713b516b4 Convert m3u accounts to a similar format to epg for status updates. Renamed DB field last_error to last_message so we can use it for more messaging. Migration to change updated_at field to not be updated everytime the m3u changes. It should only update the updated_at when we successfully update the m3u. 2025-05-04 17:51:57 -05:00
SergeantPanda
2f23909bed Fixed bug overwriting tvg-id when loading TV Guide. 2025-04-29 15:13:15 -05:00
SergeantPanda
e57c712943 Fixes dummy epg calculating hours above 24 2025-04-17 03:34:25 -05:00
SergeantPanda
b09a4baae4 Add dummy epg channels to tv guide. 2025-04-15 20:03:55 -05:00