diff --git a/gui_app.py b/gui_app.py index fd2a253..b6a63de 100644 --- a/gui_app.py +++ b/gui_app.py @@ -109,8 +109,11 @@ def reschedule_active_jobs(): ) elif schedule_type == 'monthly': hour, minute = (schedule_time.split(':') + ['00'])[:2] + day_val = monthly_day + if str(day_val).isdigit(): + day_val = max(1, min(28, int(day_val))) trigger = CronTrigger( - day=max(1, min(28, int(monthly_day or 1))), + day=day_val, hour=int(hour), minute=int(minute) ) elif schedule_type == 'interval': @@ -307,6 +310,8 @@ def job_to_display(jid, info): 'disks_count': len(disk_filter) if disk_filter is not None else None, 'retention_type': info.get('retention_type', 'keep_all'), 'retention_value': info.get('retention_value', 5), + 'monthly_day': info.get('monthly_day'), + 'weekly_day': info.get('weekly_day'), } @@ -490,8 +495,11 @@ def create_and_start_job( ) elif schedule_type == 'monthly': hour, minute = (schedule_time.split(':') + ['00'])[:2] + day_val = monthly_day + if str(day_val).isdigit(): + day_val = max(1, min(28, int(day_val))) trigger = CronTrigger( - day=max(1, min(28, int(monthly_day or 1))), + day=day_val, hour=int(hour), minute=int(minute) ) elif schedule_type == 'interval': @@ -629,8 +637,17 @@ def create_job(): daily_time = request.form.get('daily_time', '02:00') weekly_day = request.form.get('weekly_day', '0') weekly_time = request.form.get('weekly_time', '02:00') - monthly_day = request.form.get('monthly_day', '1') - monthly_time = request.form.get('monthly_time', '02:00') + + monthly_basis = request.form.get('monthly_basis', 'day_num') + if monthly_basis == 'weekday': + monthly_week_num = request.form.get('monthly_week_num', '1st') + monthly_day_of_week = request.form.get('monthly_day_of_week', 'sun') + monthly_day = f"{monthly_week_num} {monthly_day_of_week}" + monthly_time = request.form.get('monthly_time_2', '02:00') + else: + monthly_day = request.form.get('monthly_day', '1') + monthly_time = request.form.get('monthly_time_1', '02:00') + interval_hrs = request.form.get('interval_hours', '24') label = request.form.get('job_label', '').strip() @@ -726,8 +743,17 @@ def batch_jobs(): daily_time = request.form.get('daily_time', '02:00') weekly_day = request.form.get('weekly_day', '0') weekly_time = request.form.get('weekly_time', '02:00') - monthly_day = request.form.get('monthly_day', '1') - monthly_time = request.form.get('monthly_time', '02:00') + + monthly_basis = request.form.get('monthly_basis', 'day_num') + if monthly_basis == 'weekday': + monthly_week_num = request.form.get('monthly_week_num', '1st') + monthly_day_of_week = request.form.get('monthly_day_of_week', 'sun') + monthly_day = f"{monthly_week_num} {monthly_day_of_week}" + monthly_time = request.form.get('monthly_time_2', '02:00') + else: + monthly_day = request.form.get('monthly_day', '1') + monthly_time = request.form.get('monthly_time_1', '02:00') + interval_hrs = request.form.get('interval_hours', '24') label_prefix = request.form.get('job_label', '').strip() diff --git a/templates/batch_job.html b/templates/batch_job.html index 1689de3..b98e2a9 100644 --- a/templates/batch_job.html +++ b/templates/batch_job.html @@ -369,15 +369,54 @@
-
+
+
+ + +
+
+ +
- - + + +
+
+ +
@@ -497,6 +536,18 @@ hint.textContent = 'Backups older than N days will be deleted automatically.'; } } + + function onMonthlyBasisChange(val) { + const dayNumRow = document.getElementById('monthly_day_num_row'); + const weekdayRow = document.getElementById('monthly_weekday_row'); + if (val === 'day_num') { + dayNumRow.style.display = ''; + weekdayRow.style.display = 'none'; + } else { + dayNumRow.style.display = 'none'; + weekdayRow.style.display = ''; + } + } {% endblock %} diff --git a/templates/create_job.html b/templates/create_job.html index 16671a7..7b355e7 100644 --- a/templates/create_job.html +++ b/templates/create_job.html @@ -373,15 +373,54 @@
-
+
+
+ + +
+
+ +
- - + + +
+
+ +
@@ -578,5 +617,17 @@ hint.textContent = 'Backups older than N days will be deleted automatically.'; } } + + function onMonthlyBasisChange(val) { + const dayNumRow = document.getElementById('monthly_day_num_row'); + const weekdayRow = document.getElementById('monthly_weekday_row'); + if (val === 'day_num') { + dayNumRow.style.display = ''; + weekdayRow.style.display = 'none'; + } else { + dayNumRow.style.display = 'none'; + weekdayRow.style.display = ''; + } + } {% endblock %} diff --git a/templates/job_detail.html b/templates/job_detail.html index fb2b318..8b85038 100644 --- a/templates/job_detail.html +++ b/templates/job_detail.html @@ -167,6 +167,11 @@ {% if job.schedule_type and job.schedule_type != 'now' %} {{ job.schedule_type|capitalize }} + {% if job.schedule_type == 'monthly' and job.monthly_day is not none %} + (Day: {{ job.monthly_day }}) + {% elif job.schedule_type == 'weekly' and job.weekly_day is not none %} + (Day: {{ ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'][job.weekly_day|int] if (job.weekly_day|string).isdigit() else job.weekly_day }}) + {% endif %} {% if job.schedule_time %}at {{ job.schedule_time }}{% endif %} {% else %} One-time (Run Now)