Commit graph

2297 commits

Author SHA1 Message Date
Jim McBride
8388152d79
Use system timezone for backup filenames
Updated create_backup to use the system's configured timezone for backup
filenames instead of always using UTC. This makes filenames more intuitive
and matches users' local time expectations.

Changes:
- Import pytz and CoreSettings
- Get system timezone from CoreSettings.get_system_time_zone()
- Convert current UTC time to system timezone for filename timestamp
- Fallback to UTC if timezone conversion fails
- Internal metadata timestamps remain UTC for consistency

Example:
- System timezone: America/New_York (EST)
- Created at 3:00 PM EST
- Old filename: dispatcharr-backup-2025.12.09.20.00.00.zip (UTC time)
- New filename: dispatcharr-backup-2025.12.09.15.00.00.zip (local time)

This aligns with the timezone-aware scheduling already implemented.
2025-12-09 09:06:22 -06:00
Jim McBride
795934dafe
Give Created column flexible width to prevent wrapping
Changed Created column from fixed size (160px) to flexible minSize (180px)
with whiteSpace: nowrap to ensure date/time displays on a single line.

The column can now expand as needed while maintaining readability of
timestamps in various date/time format combinations.
2025-12-09 08:58:38 -06:00
Jim McBride
70e574e25a
Add tests for cron expression functionality
Added comprehensive test coverage for cron expression support:

New tests in BackupSchedulerTestCase:
- test_cron_expression_stores_value: Verify cron_expression persists correctly
- test_cron_expression_creates_correct_schedule: Verify CrontabSchedule creation from cron
- test_cron_expression_invalid_format: Verify validation rejects malformed expressions
- test_cron_expression_empty_uses_simple_mode: Verify fallback to frequency/time mode
- test_cron_expression_overrides_simple_settings: Verify cron takes precedence

Updated existing tests to include cron_expression field:
- test_get_schedule_settings_defaults: Now checks cron_expression default
- test_get_schedule_success: Added cron_expression to mock response
- test_update_schedule_success: Added cron_expression to mock response

All tests verify the new cron functionality works correctly alongside
existing simple scheduling mode.
2025-12-09 08:54:23 -06:00
Jim McBride
3c76c72479
Add Enabled/Disabled label to Advanced toggle
Added dynamic label to the Advanced (Cron Expression) switch to match
the Scheduled Backups toggle above it.

Now displays:
  Scheduled Backups          [Enabled]
  Advanced (Cron Expression) [Enabled]

Provides consistent UI pattern and clearer status indication.
2025-12-09 08:38:57 -06:00
Jim McBride
53159bd420
Improve Advanced toggle layout alignment
Changed Advanced (Cron Expression) from a labeled switch to a proper
Group with space-between layout matching the Scheduled Backups row above.

Now displays as:
  Scheduled Backups          [Enabled toggle]
  Advanced (Cron Expression) [Toggle]

This creates consistent visual alignment with both text labels on the left
and toggle switches on the right.
2025-12-09 08:35:55 -06:00
Jim McBride
901cc09e38
Align Advanced toggle below Scheduled Backups header
Moved the Advanced (Cron Expression) switch outside the scheduleLoading
conditional and wrapped it in its own Group for proper alignment.

Layout is now:
- Scheduled Backups header with Enabled/Disabled switch
- Advanced (Cron Expression) toggle (aligned left)
- Schedule configuration inputs (conditional based on mode)

This provides clearer visual hierarchy and better UX.
2025-12-09 08:32:49 -06:00
Jim McBride
d4fbc9dc61
Honor user date/time format preferences for backup timestamps
- Import dayjs for date formatting
- Read date-format setting from localStorage ('mdy' or 'dmy')
- Move formatDate function into component to access user preferences
- Format dates according to user's date and time format settings:
  - MDY: MM/DD/YYYY
  - DMY: DD/MM/YYYY
  - 12h: h:mm:ss A
  - 24h: HH:mm:ss

The Created column now respects the same date/time format preferences
used throughout the app (Guide, Stats, DVR, SystemEvents, etc).
2025-12-09 08:29:28 -06:00
Jim McBride
1a350e79e0
Fix cron validation to support */N step notation
Updated regex to properly support step notation with asterisk (e.g., */2, */5).

Now supports all common cron patterns:
- * (wildcard)
- */2 (every 2 units - step notation)
- 5 (specific value)
- 1-5 (range)
- 1-5/2 (step within range)
- 1,3,5 (list)
- 10-20/5 (step within range)

Changed regex from:
  /^(\*|(\d+(-\d+)?(,\d+(-\d+)?)*)(\/\d+)?)$/
To:
  /^(\*\/\d+|\*|\d+(-\d+)?(\/\d+)?(,\d+(-\d+)?(\/\d+)?)*)$/

The key change is adding \*\/\d+ as the first alternative to explicitly
match step notation like */2, */5, */10, etc.

Backend already supports this via Django Celery Beat's CrontabSchedule,
which accepts standard cron syntax including step notation.
2025-12-09 08:22:20 -06:00
Jim McBride
e71e6bc3d7
Fix backup timestamp display to use UTC timezone
The list_backups function was creating timezone-naive datetime objects,
which caused the frontend to incorrectly interpret timestamps.

Now uses datetime.UTC when creating timestamps from file modification time
(consistent with other usage in this file on lines 186, 216), so the ISO
string includes timezone info (+00:00). This allows the browser to properly
convert UTC timestamps to the user's local timezone for display.

Before: Backend sends "2025-12-09T14:12:44" (ambiguous timezone)
After: Backend sends "2025-12-09T14:12:44+00:00" (explicit UTC)

The frontend's toLocaleString() will now correctly convert to local time.
2025-12-09 08:16:04 -06:00
Jim McBride
c65df2de89
Add real-time validation for cron expressions
- Add validateCronExpression function with comprehensive validation:
  - Checks for exactly 5 parts (minute hour day month weekday)
  - Validates cron syntax (*, ranges, lists, steps)
  - Validates numeric ranges (minute 0-59, hour 0-23, etc.)
  - Returns detailed error messages for each validation failure

- Add cronError state to track validation errors
- Validate on input change with handleScheduleChange
- Display error message below input field
- Disable Save button when cron expression is invalid
- Auto-validate when switching to advanced mode
- Clear errors when switching back to simple mode

User gets immediate feedback on cron syntax errors before attempting to save.
2025-12-09 08:09:56 -06:00
Jim McBride
5fbcaa91e0
Add custom cron expression support for backup scheduling
Frontend changes:
- Add advanced mode toggle switch for cron expressions
- Show cron expression input with helpful examples when enabled
- Display format hints: "minute hour day month weekday"
- Provide common examples (daily, weekly, every 6 hours, etc.)
- Conditionally render simple or advanced scheduling UI
- Support switching between simple and advanced modes

Backend changes:
- Add cron_expression to schedule settings (SETTING_KEYS, DEFAULTS)
- Update get_schedule_settings to include cron_expression
- Update update_schedule_settings to handle cron_expression
- Extend _sync_periodic_task to parse and use cron expressions
- Parse 5-part cron format: minute hour day_of_month month_of_year day_of_week
- Create CrontabSchedule from cron expression or simple frequency
- Add validation and error handling for invalid cron expressions

This addresses maintainer feedback for "custom scheduler (cron style) for more control".
Users can now schedule backups with full cron flexibility beyond daily/weekly.
2025-12-09 07:55:47 -06:00
Jim McBride
d718e5a142
Implement timezone-aware backup scheduling
- Add timezone conversion functions (utcToLocal, localToUtc)
- Use user's configured timezone from Settings (localStorage 'time-zone')
- Convert times to UTC when saving to backend
- Convert times from UTC to local when loading from backend
- Display timezone info showing user's timezone and scheduled time
- Helper text shows: "Timezone: America/New_York • Backup will run at 03:00"

This addresses maintainer feedback to handle timezone properly:
backend stores/schedules in UTC, frontend displays/edits in user's local time.
2025-12-09 07:52:53 -06:00
Jim McBride
806f78244d
Add proper ConfirmationDialog usage to BackupManager
- Import useWarningsStore from warnings store
- Add suppressWarning hook to component
- Add actionKey props to restore and delete confirmation dialogs
- Add onSuppressChange callback to enable "Don't ask again" functionality

This aligns BackupManager with the project's standard confirmation dialog pattern
used throughout the codebase (ChannelsTable, EPGsTable, etc).
2025-12-09 07:49:31 -06:00
DawtCom
e8fb01ebdd Removing unreachable code 2025-12-08 21:50:13 -06:00
SergeantPanda
514e7e06e4 Bug fix: EPG API now returns correct date/time format for start/end fields and proper string types for timestamps and channel_id 2025-12-08 20:50:50 -06:00
SergeantPanda
69f9ecd93c Bug Fix: Remove ipv6 binding from nginx config if ipv6 is not available. 2025-12-08 20:12:44 -06:00
GitHub Actions
4df4e5f963 Release v0.14.0 2025-12-09 00:01:50 +00:00
SergeantPanda
ecbef65891
Merge pull request #723 from Dispatcharr:dev
Version 0.14.0
2025-12-08 17:59:12 -06:00
SergeantPanda
98b29f97a1 changelog: Update verbiage 2025-12-08 17:49:40 -06:00
SergeantPanda
62f5c32609 Remove DJANGO_SECRET_KEY environment variable from uwsgi configuration files 2025-12-08 17:27:07 -06:00
dekzter
43b55e2d99 first run at hiding disabled channels in channel profiles 2025-12-08 08:38:39 -05:00
SergeantPanda
c03ddf60a0 Fixed verbiage for epg parsing status. 2025-12-07 21:28:04 -06:00
SergeantPanda
ce70b04097 changelog: update changelog 2025-12-07 20:56:59 -06:00
SergeantPanda
e2736babaa Reset umask after creating secret file. 2025-12-07 20:04:58 -06:00
SergeantPanda
2155229d7f Fix uwsgi command path in entrypoint script 2025-12-07 19:40:32 -06:00
SergeantPanda
cf37c6fd98 changelog: Updated changelog for 0.13.1 2025-12-07 19:06:45 -06:00
SergeantPanda
3512c3a623 Add DJANGO_SECRET_KEY environment variable to uwsgi configuration files 2025-12-07 19:05:31 -06:00
dekzter
d0edc3fa07 remove permission lines to see if this resolves lack of django secret key in environment profile.d 2025-12-07 07:54:30 -05:00
dekzter
b18bc62983 merged in from main 2025-12-06 14:13:06 -05:00
GitHub Actions
a912055255 Release v0.13.1 2025-12-06 18:43:16 +00:00
dekzter
10f329d673 release notes for built 2025-12-06 13:42:48 -05:00
dekzter
f3a901cb3a Security Fix - generate JWT on application init 2025-12-06 13:40:10 -05:00
SergeantPanda
759569b871 Enhancement: Add a priority field to EPGSource and prefer higher-priority sources when matching channels. Also ignore EPG sources where is_active is false during matching, and update serializers/forms/frontend accordingly.(Closes #603, #672) 2025-12-05 09:54:11 -06:00
SergeantPanda
c1d960138e Fix: Bulk channel editor confirmation dialog now shows the correct stream profile that will be set. 2025-12-05 09:02:03 -06:00
SergeantPanda
0d177e44f8 changelog: Change updated change to bug fix instead of change. 2025-12-04 15:45:09 -06:00
SergeantPanda
3b34fb11ef Fix: Fixes bug where Updated column wouldn't update in the EPG table without a webui refresh. 2025-12-04 15:43:33 -06:00
SergeantPanda
6c8270d0e5 Enhancement: Add support for 'extracting' status and display additional progress information in EPGsTable 2025-12-04 15:28:21 -06:00
SergeantPanda
5693ee7f9e perf: optimize EPG program parsing and implement atomic database updates to reduce I/O overhead and prevent partial data visibility 2025-12-04 14:57:57 -06:00
SergeantPanda
256ac2f55a Enhancement: Clean up orphaned programs for unmapped EPG entries 2025-12-04 14:25:44 -06:00
SergeantPanda
2a8ba9125c perf: optimize EPG program parsing for multi-channel sources
Dramatically improve EPG refresh performance by parsing the XML file once
per source instead of once per channel. The new implementation:

- Pre-filters to only process EPG entries mapped to actual channels
- Parses the entire XML file in a single pass
- Uses O(1) set lookups to skip unmapped channel programmes
- Skips non-mapped channels entirely with minimal overhead

For EPG sources with many channels but few mapped (e.g., 10,000 channels
with 100 mapped to channels), this provides approximately:
- 99% reduction in file open operations
- 99% reduction in XML file scans
- Proportional reduction in CPU and I/O overhead

The parse_programs_for_tvg_id() function is retained for single-channel
use cases (e.g., when a new channel is mapped via signals).

Fixes inefficient repeated file parsing that was occurring with large
EPG sources.
2025-12-04 14:07:28 -06:00
SergeantPanda
2de6ac5da1 changelog: Add sort buttons for 'Group' and 'M3U' columns in Streams table 2025-12-03 17:31:16 -06:00
SergeantPanda
6a96b6b485
Merge pull request #707 from bobey6/main
Enhancement: Add sort by 'Group' or 'M3U' buttons to Streams
2025-12-03 17:27:42 -06:00
SergeantPanda
5fce83fb51 style: Adjust table header and input components for consistent width 2025-12-03 17:13:50 -06:00
SergeantPanda
81b6570366 Fix name not sorting. 2025-12-03 17:03:58 -06:00
SergeantPanda
042612c677 Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into pr/bobey6/707 2025-12-03 16:49:21 -06:00
Jim McBride
e64002dfc4
Refactor BackupManager to match app table conventions 2025-12-02 22:19:20 -06:00
Jim McBride
70cf8928c4
Use CustomTable component for backup list 2025-12-02 22:01:59 -06:00
Jim McBride
3f9fd424e2
Update backup feature based on PR feedback
- Simplify to database-only backups (remove data directory backup)
- Update UI to match app styling patterns:
  - Use ActionIcon with transparent variant for table actions
  - Match icon/color conventions (SquareMinus/red.9, RotateCcw/yellow.5, Download/blue.5)
  - Use standard button bar layout with Paper/Box/Flex
  - Green "Create Backup" button matching "Add" pattern
  - Remove Card wrapper, Alert, and Divider for cleaner layout
  - Update to Mantine v8 Table syntax
- Use standard ConfirmationDialog (remove unused color prop)
- Update tests to remove get_data_dirs references
2025-12-02 19:33:27 -06:00
SergeantPanda
f38fb36eba Skip builds during documentation updates. 2025-12-02 15:03:34 -06:00
SergeantPanda
5e1ae23c4e docs: Update CHANGELOG 2025-12-02 14:58:22 -06:00