fully working
This commit is contained in:
parent
2d955137d7
commit
3115897c92
File diff suppressed because one or more lines are too long
@ -2,23 +2,19 @@ jQuery(document).ready(function ($) {
|
||||
const $tableActive = $('table.active-slides');
|
||||
const $tableInactive = $('table.inactive-slides');
|
||||
|
||||
const getCronDateTime = function(cronExpression) {
|
||||
const [minutes, hours, day, month, _, year] = cronExpression.split(' ');
|
||||
return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')} ${hours.padStart(2, '0')}:${minutes.padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
const loadDateTimePicker = function($els) {
|
||||
const d = new Date();
|
||||
|
||||
$els.each(function() {
|
||||
var $el = $(this);
|
||||
if (!$el.val()) {
|
||||
$el.val(prettyTimestamp(Date.now()).slice(0, -4));
|
||||
}
|
||||
$el.flatpickr({
|
||||
enableTime: true,
|
||||
time_24hr: true,
|
||||
allowInput: false,
|
||||
allowInvalidPreload: false,
|
||||
dateFormat: 'Y-m-d H:i',
|
||||
defaultHour: d.getHours(),
|
||||
defaultMinute: d.getMinutes(),
|
||||
onChange: function(selectedDates, dateStr, instance) {
|
||||
const d = selectedDates[0];
|
||||
const $target = $el.parents('.widget:eq(0)').find('.target');
|
||||
@ -81,6 +77,7 @@ jQuery(document).ready(function ($) {
|
||||
const $scheduleStartGroup = $modal.find('.slide-schedule-group');
|
||||
const $scheduleEndGroup = $modal.find('.slide-schedule-end-group');
|
||||
const $durationGroup = $modal.find('.slide-duration-group');
|
||||
const $isNotificationGroup = $modal.find('.slide-notification-group');
|
||||
|
||||
const $triggerStart = $scheduleStartGroup.find('.trigger');
|
||||
const $triggerEnd = $scheduleEndGroup.find('.trigger');
|
||||
@ -90,42 +87,88 @@ jQuery(document).ready(function ($) {
|
||||
|
||||
const $datetimepickerStart = $scheduleStartGroup.find('.datetimepicker');
|
||||
const $datetimepickerEnd = $scheduleEndGroup.find('.datetimepicker');
|
||||
const $isNotification = $isNotificationGroup.find('.trigger');
|
||||
|
||||
const isNotification = $isNotification.prop('checked');
|
||||
let isLoopStart = $triggerStart.val() === 'loop';
|
||||
let isCronStart = $triggerStart.val() === 'cron';
|
||||
|
||||
function updateScheduleChoices(isNotification, isLoopStart, isCronStart) {
|
||||
let scheduleStartChoices = $.extend({}, schedule_start_choices);
|
||||
let scheduleEndChoices = $.extend({}, schedule_end_choices);
|
||||
|
||||
if (!isNotification || isLoopStart) {
|
||||
delete scheduleStartChoices['cron'];
|
||||
delete scheduleEndChoices['duration'];
|
||||
}
|
||||
|
||||
if (isNotification) {
|
||||
delete scheduleStartChoices['loop'];
|
||||
delete scheduleEndChoices['stayloop'];
|
||||
|
||||
if (isCronStart) {
|
||||
delete scheduleEndChoices['datetime'];
|
||||
}
|
||||
}
|
||||
|
||||
return { scheduleStartChoices, scheduleEndChoices };
|
||||
}
|
||||
|
||||
function applyChoices() {
|
||||
const { scheduleStartChoices, scheduleEndChoices } = updateScheduleChoices(isNotification, isLoopStart, isCronStart);
|
||||
recreateSelectOptions($triggerStart, scheduleStartChoices);
|
||||
recreateSelectOptions($triggerEnd, scheduleEndChoices);
|
||||
}
|
||||
|
||||
applyChoices();
|
||||
|
||||
isLoopStart = $triggerStart.val() === 'loop';
|
||||
isCronStart = $triggerStart.val() === 'cron';
|
||||
|
||||
const isCronStart = $triggerStart.val() === 'cron';
|
||||
const isCronEnd = $triggerEnd.val() === 'cron';
|
||||
const isDatetimeStart = $triggerStart.val() === 'datetime';
|
||||
const isDatetimeEnd = $triggerEnd.val() === 'datetime';
|
||||
const isLoopStart = $triggerStart.val() === 'loop';
|
||||
const isStayloopEnd = $triggerEnd.val() === 'stayloop';
|
||||
const isDurationEnd = $triggerEnd.val() === 'duration';
|
||||
|
||||
const flushValueStart = isLoopStart;
|
||||
const flushValueEnd = isLoopStart || isDurationEnd;
|
||||
const flushDuration = !isLoopStart && !isDurationEnd;
|
||||
const flushValueEnd = isLoopStart || isStayloopEnd || isDurationEnd;
|
||||
const flushDuration = isNotification && isDatetimeEnd;
|
||||
|
||||
$targetCronFieldStart.toggleClass('hidden', !isCronStart);
|
||||
$targetCronFieldEnd.toggleClass('hidden', !isCronEnd);
|
||||
$datetimepickerStart.toggleClass('hidden', !isDatetimeStart);
|
||||
$datetimepickerEnd.toggleClass('hidden', !isDatetimeEnd);
|
||||
function toggleVisibility() {
|
||||
$targetCronFieldStart.toggleClass('hidden', !isCronStart);
|
||||
$targetCronFieldEnd.toggleClass('hidden', !isCronEnd);
|
||||
$datetimepickerStart.toggleClass('hidden', !isDatetimeStart);
|
||||
$datetimepickerEnd.toggleClass('hidden', !isDatetimeEnd);
|
||||
|
||||
$durationGroup.toggleClass('hidden', !isLoopStart && !isDurationEnd);
|
||||
$scheduleEndGroup.toggleClass('hidden', isLoopStart);
|
||||
$durationGroup.toggleClass('hidden', isNotification && isDatetimeEnd);
|
||||
$scheduleEndGroup.toggleClass('hidden', isLoopStart);
|
||||
|
||||
$durationGroup.find('.widget input').prop('required', $durationGroup.is(':visible'));
|
||||
|
||||
if (flushValueStart) {
|
||||
$targetCronFieldStart.val('');
|
||||
$datetimepickerStart.val('');
|
||||
$durationGroup.find('.widget input').prop('required', $durationGroup.is(':visible'));
|
||||
}
|
||||
|
||||
if (flushValueEnd) {
|
||||
$targetCronFieldEnd.val('');
|
||||
$datetimepickerEnd.val('');
|
||||
function flushValues() {
|
||||
if (flushValueStart) {
|
||||
$targetCronFieldStart.val('');
|
||||
$datetimepickerStart.val('');
|
||||
}
|
||||
|
||||
if (flushValueEnd) {
|
||||
$targetCronFieldEnd.val('');
|
||||
$datetimepickerEnd.val('');
|
||||
}
|
||||
|
||||
if (flushDuration) {
|
||||
$targetDuration.val('1');
|
||||
}
|
||||
}
|
||||
|
||||
if (flushDuration) {
|
||||
$targetDuration.val('1');
|
||||
}
|
||||
toggleVisibility();
|
||||
flushValues();
|
||||
applyChoices();
|
||||
};
|
||||
|
||||
|
||||
const main = function () {
|
||||
$("table").tableDnD({
|
||||
dragHandle: 'td a.slide-sort',
|
||||
@ -156,7 +199,7 @@ jQuery(document).ready(function ($) {
|
||||
updateTable();
|
||||
});
|
||||
|
||||
$(document).on('change', '.modal-slide select.trigger', function () {
|
||||
$(document).on('change', '.modal-slide select.trigger, .modal-slide input.trigger', function () {
|
||||
inputSchedulerUpdate();
|
||||
});
|
||||
|
||||
@ -179,6 +222,7 @@ jQuery(document).ready(function ($) {
|
||||
|
||||
const hasCronEnd = slide.cron_schedule_end && slide.cron_schedule_end.length > 0;
|
||||
const hasDateTimeEnd = hasCronEnd && validateCronDateTime(slide.cron_schedule_end);
|
||||
const isNotification = slide.is_notification;
|
||||
|
||||
let location = slide.location;
|
||||
|
||||
@ -186,17 +230,19 @@ jQuery(document).ready(function ($) {
|
||||
location = 'https://www.youtube.com/watch?v=' + slide.location;
|
||||
}
|
||||
|
||||
console.log(slide)
|
||||
$('.modal-slide-edit input:visible:eq(0)').focus().select();
|
||||
$('#slide-edit-name').val(slide.name);
|
||||
$('#slide-edit-type').val(slide.type);
|
||||
$('#slide-edit-location').val(location).prop('disabled', !slide.is_editable);
|
||||
$('#slide-edit-duration').val(slide.duration);
|
||||
$('#slide-edit-is-notification').prop('checked', isNotification);
|
||||
|
||||
$('#slide-edit-cron-schedule').val(slide.cron_schedule).toggleClass('hidden', !hasCron || hasDateTime);
|
||||
$('#slide-edit-cron-schedule-trigger').val(hasDateTime ? 'datetime' : (hasCron ? 'cron' : 'loop'));
|
||||
|
||||
$('#slide-edit-cron-schedule-end').val(slide.cron_schedule_end).toggleClass('hidden', !hasCronEnd || hasDateTimeEnd);
|
||||
$('#slide-edit-cron-schedule-end-trigger').val(hasDateTimeEnd ? 'datetime' : (hasCronEnd ? 'cron' : 'duration'));
|
||||
$('#slide-edit-cron-schedule-end-trigger').val(hasDateTimeEnd ? 'datetime' : (hasCronEnd ? 'cron' : (isNotification ? 'duration' : 'stayloop')));
|
||||
|
||||
$('#slide-edit-cron-schedule-datetimepicker').toggleClass('hidden', !hasDateTime).val(
|
||||
hasDateTime ? getCronDateTime(slide.cron_schedule) : ''
|
||||
|
||||
@ -3,6 +3,11 @@ const prettyTimestamp = function(timestamp) {
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')} `
|
||||
};
|
||||
|
||||
const getCronDateTime = function(cronExpression) {
|
||||
const [minutes, hours, day, month, _, year] = cronExpression.split(' ');
|
||||
return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')} ${hours.padStart(2, '0')}:${minutes.padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
const validateCronDateTime = function(cronExpression) {
|
||||
const pattern = /^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\*\s+(\d+)$/;
|
||||
return pattern.test(cronExpression);
|
||||
@ -28,4 +33,26 @@ const modifyDate = function(date, seconds) {
|
||||
const clone = new Date(date.getTime());
|
||||
clone.setSeconds(clone.getSeconds() + seconds);
|
||||
return clone;
|
||||
};
|
||||
};
|
||||
|
||||
const recreateSelectOptions = function($selectElement, options) {
|
||||
if (!$selectElement.is('select')) {
|
||||
throw new Error("Element is not a <select>");
|
||||
}
|
||||
|
||||
const selectedValue = $selectElement.val();
|
||||
$selectElement.empty();
|
||||
|
||||
$.each(options, function(key, label) {
|
||||
$selectElement.append($('<option>', {
|
||||
value: key,
|
||||
html: label
|
||||
}));
|
||||
});
|
||||
|
||||
if ($selectElement.find(`option[value="${selectedValue}"]`).length > 0) {
|
||||
$selectElement.val(selectedValue);
|
||||
} else {
|
||||
$selectElement.prop('selectedIndex', 0);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
select.select-item-picker,
|
||||
a.btn,
|
||||
.btn,
|
||||
button {
|
||||
background-color: $white;
|
||||
border-radius: 5px;
|
||||
|
||||
@ -49,6 +49,12 @@
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.panel td .td-secondary {
|
||||
font-size: 14px;
|
||||
opacity: 0.6;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.panel td a.item.sort {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
// Import base styles
|
||||
@import 'base/html';
|
||||
|
||||
@import 'base/tachyons';
|
||||
|
||||
// Import layout styles
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
"slideshow_slide_panel_th_cron_scheduled": "Scheduled Start",
|
||||
"slideshow_slide_panel_th_activity": "Activity",
|
||||
"slideshow_slide_panel_td_cron_scheduled_loop": "Loop",
|
||||
"slideshow_slide_panel_td_cron_scheduled_notify": "Notify",
|
||||
"slideshow_slide_panel_td_cron_scheduled_bad_cron": "Bad cron value",
|
||||
"slideshow_slide_form_add_title": "Add Slide",
|
||||
"slideshow_slide_form_add_submit": "Add",
|
||||
@ -28,10 +29,12 @@
|
||||
"slideshow_slide_form_label_object": "Object",
|
||||
"slideshow_slide_form_label_duration": "Duration",
|
||||
"slideshow_slide_form_label_duration_unit": "seconds",
|
||||
"slideshow_slide_form_label_is_notification": "Act as notification",
|
||||
"slideshow_slide_form_label_cron_scheduled": "Start",
|
||||
"slideshow_slide_form_label_cron_scheduled_end": "End",
|
||||
"slideshow_slide_form_label_cron_scheduled_loop": "In the loop",
|
||||
"slideshow_slide_form_label_cron_scheduled_loop": "Always in loop",
|
||||
"slideshow_slide_form_label_cron_scheduled_duration": "Duration",
|
||||
"slideshow_slide_form_label_cron_scheduled_stayloop": "Follow the loop",
|
||||
"slideshow_slide_form_label_cron_scheduled_duration_unit": "seconds",
|
||||
"slideshow_slide_form_label_cron_scheduled_datetime": "Date & Time",
|
||||
"slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Set a date and time",
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
"slideshow_slide_panel_th_cron_scheduled": "Programmation",
|
||||
"slideshow_slide_panel_th_activity": "Options",
|
||||
"slideshow_slide_panel_td_cron_scheduled_loop": "En boucle",
|
||||
"slideshow_slide_panel_td_cron_scheduled_notify": "Notifie",
|
||||
"slideshow_slide_panel_td_cron_scheduled_bad_cron": "Mauvaise valeur cron",
|
||||
"slideshow_slide_form_add_title": "Ajout d'une slide",
|
||||
"slideshow_slide_form_add_submit": "Ajouter",
|
||||
@ -28,10 +29,12 @@
|
||||
"slideshow_slide_form_label_object": "Objet",
|
||||
"slideshow_slide_form_label_duration": "Durée",
|
||||
"slideshow_slide_form_label_duration_unit": "secondes",
|
||||
"slideshow_slide_form_label_is_notification": "Agit comme une notification",
|
||||
"slideshow_slide_form_label_cron_scheduled": "Début",
|
||||
"slideshow_slide_form_label_cron_scheduled_end": "Fin",
|
||||
"slideshow_slide_form_label_cron_scheduled_loop": "Dans la boucle",
|
||||
"slideshow_slide_form_label_cron_scheduled_loop": "Toujours en boucle",
|
||||
"slideshow_slide_form_label_cron_scheduled_duration": "Durée",
|
||||
"slideshow_slide_form_label_cron_scheduled_stayloop": "Suit la boucle",
|
||||
"slideshow_slide_form_label_cron_scheduled_duration_unit": "secondes",
|
||||
"slideshow_slide_form_label_cron_scheduled_datetime": "Date & Heure",
|
||||
"slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Choisir une date et une heure",
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
"slideshow_slide_panel_th_cron_scheduled": "Avvia programmazione",
|
||||
"slideshow_slide_panel_th_activity": "Attivita",
|
||||
"slideshow_slide_panel_td_cron_scheduled_loop": "Loop",
|
||||
"slideshow_slide_panel_td_cron_scheduled_notify": "Notificare",
|
||||
"slideshow_slide_panel_td_cron_scheduled_bad_cron": "Valore cron errato",
|
||||
"slideshow_slide_form_add_title": "Aggiungi Slide",
|
||||
"slideshow_slide_form_add_submit": "Aggiungi",
|
||||
@ -28,10 +29,12 @@
|
||||
"slideshow_slide_form_label_object": "Oggetto",
|
||||
"slideshow_slide_form_label_duration": "Durata",
|
||||
"slideshow_slide_form_label_duration_unit": "Secondi",
|
||||
"slideshow_slide_form_label_is_notification": "Agisce come una notifica",
|
||||
"slideshow_slide_form_label_cron_scheduled": "Inizio",
|
||||
"slideshow_slide_form_label_cron_scheduled_end": "Fine",
|
||||
"slideshow_slide_form_label_cron_scheduled_loop": "Ciclo continuo",
|
||||
"slideshow_slide_form_label_cron_scheduled_loop": "Sempre in loop",
|
||||
"slideshow_slide_form_label_cron_scheduled_duration": "Durata",
|
||||
"slideshow_slide_form_label_cron_scheduled_stayloop": "Seguire il ciclo",
|
||||
"slideshow_slide_form_label_cron_scheduled_duration_unit": "secondi",
|
||||
"slideshow_slide_form_label_cron_scheduled_datetime": "Data e ora",
|
||||
"slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Imposta Data e ora",
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from flask import Flask, render_template, redirect, request, url_for, send_from_directory, jsonify, abort
|
||||
|
||||
from src.service.ModelStore import ModelStore
|
||||
from src.interface.ObController import ObController
|
||||
from src.util.utils import get_safe_cron_descriptor
|
||||
from src.util.utils import get_safe_cron_descriptor, is_valid_cron_date_time, get_cron_date_time
|
||||
from src.util.UtilNetwork import get_ip_address, get_safe_remote_addr
|
||||
from src.model.enum.AnimationSpeed import animation_speed_duration
|
||||
|
||||
@ -22,15 +23,25 @@ class PlayerController(ObController):
|
||||
playlist_notifications = []
|
||||
|
||||
for slide in slides:
|
||||
has_valid_start_date = 'cron_schedule' in slide and slide['cron_schedule'] and get_safe_cron_descriptor(slide['cron_schedule'])
|
||||
has_valid_start_date = 'cron_schedule' in slide and slide['cron_schedule'] and get_safe_cron_descriptor(slide['cron_schedule']) and is_valid_cron_date_time(slide['cron_schedule'])
|
||||
has_valid_end_date = 'cron_schedule_end' in slide and slide['cron_schedule_end'] and get_safe_cron_descriptor(slide['cron_schedule_end']) and is_valid_cron_date_time(slide['cron_schedule_end'])
|
||||
|
||||
if slide['is_notification']:
|
||||
if slide['is_notification'] and has_valid_start_date:
|
||||
if has_valid_start_date:
|
||||
playlist_notifications.append(slide)
|
||||
else:
|
||||
logging.warn('Slide {} is notification but start date is invalid'.format(slide['name']))
|
||||
else:
|
||||
if has_valid_start_date:
|
||||
start_date = get_cron_date_time(slide['cron_schedule'], object=True)
|
||||
if datetime.now() <= start_date:
|
||||
continue
|
||||
|
||||
if has_valid_end_date:
|
||||
end_date = get_cron_date_time(slide['cron_schedule_end'], object=True)
|
||||
if datetime.now() >= end_date:
|
||||
continue
|
||||
|
||||
playlist_loop.append(slide)
|
||||
else:
|
||||
playlist_loop.append(slide)
|
||||
|
||||
@ -47,6 +47,7 @@ class SlideshowController(ObController):
|
||||
name=request.form['name'],
|
||||
type=str_to_enum(request.form['type'], SlideType),
|
||||
duration=request.form['duration'],
|
||||
is_notification=True if 'is_notification' in request.form else False,
|
||||
playlist_id=request.form['playlist_id'] if 'playlist_id' in request.form and request.form['playlist_id'] else None,
|
||||
cron_schedule=get_optional_string(request.form['cron_schedule']),
|
||||
cron_schedule_end=get_optional_string(request.form['cron_schedule_end']),
|
||||
@ -82,6 +83,7 @@ class SlideshowController(ObController):
|
||||
id=request.form['id'],
|
||||
name=request.form['name'],
|
||||
duration=request.form['duration'],
|
||||
is_notification=True if 'is_notification' in request.form else False,
|
||||
cron_schedule=request.form['cron_schedule'],
|
||||
cron_schedule_end=request.form['cron_schedule_end'],
|
||||
location=request.form['location'] if 'location' in request.form and request.form['location'] else None
|
||||
|
||||
@ -117,7 +117,7 @@ class SlideManager(ModelManager):
|
||||
for slide_id, slide_position in positions.items():
|
||||
self._db.update_by_id(self.TABLE_NAME, slide_id, {"position": slide_position})
|
||||
|
||||
def update_form(self, id: int, name: str, duration: int, cron_schedule: Optional[str] = '', cron_schedule_end: Optional[str] = '', location: Optional[str] = None) -> Slide:
|
||||
def update_form(self, id: int, name: str, duration: int, is_notification: bool = False, cron_schedule: Optional[str] = '', cron_schedule_end: Optional[str] = '', location: Optional[str] = None) -> Slide:
|
||||
slide = self.get(id)
|
||||
|
||||
if not slide:
|
||||
@ -126,6 +126,7 @@ class SlideManager(ModelManager):
|
||||
form = {
|
||||
"name": name,
|
||||
"duration": duration,
|
||||
"is_notification": True if is_notification else False,
|
||||
"cron_schedule": get_optional_string(cron_schedule),
|
||||
"cron_schedule_end": get_optional_string(cron_schedule_end)
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ from src.model.hook.HookRegistration import HookRegistration
|
||||
from src.model.hook.StaticHookRegistration import StaticHookRegistration
|
||||
from src.model.hook.FunctionalHookRegistration import FunctionalHookRegistration
|
||||
from src.constant.WebDirConstant import WebDirConstant
|
||||
from src.util.utils import get_safe_cron_descriptor, is_validate_cron_date_time, seconds_to_hhmmss, am_i_in_docker
|
||||
from src.util.utils import get_safe_cron_descriptor, is_valid_cron_date_time, seconds_to_hhmmss, am_i_in_docker
|
||||
|
||||
|
||||
class TemplateRenderer:
|
||||
@ -39,7 +39,7 @@ class TemplateRenderer:
|
||||
cron_descriptor=self.cron_descriptor,
|
||||
str=str,
|
||||
seconds_to_hhmmss=seconds_to_hhmmss,
|
||||
is_validate_cron_date_time=is_validate_cron_date_time,
|
||||
is_valid_cron_date_time=is_valid_cron_date_time,
|
||||
l=self._model_store.lang().map(),
|
||||
t=self._model_store.lang().translate,
|
||||
)
|
||||
|
||||
@ -8,6 +8,7 @@ import unicodedata
|
||||
import platform
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional, List, Dict
|
||||
from enum import Enum
|
||||
from cron_descriptor import ExpressionDescriptor
|
||||
@ -58,13 +59,19 @@ def camel_to_snake(camel: str) -> str:
|
||||
return CAMEL_CASE_TO_SNAKE_CASE_PATTERN.sub('_', camel).lower()
|
||||
|
||||
|
||||
def is_validate_cron_date_time(expression) -> bool:
|
||||
def is_valid_cron_date_time(expression: str) -> bool:
|
||||
pattern = re.compile(r'^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\*\s+(\d+)$')
|
||||
return bool(pattern.match(expression))
|
||||
|
||||
|
||||
def get_cron_date_time(cron_expression: str, object: bool) -> str:
|
||||
minutes, hours, day, month, _, year = cron_expression.split(' ')
|
||||
formatted_date_time = f"{year}-{month.zfill(2)}-{day.zfill(2)} {hours.zfill(2)}:{minutes.zfill(2)}"
|
||||
return datetime.strptime(formatted_date_time, '%Y-%m-%d %H:%M') if object else formatted_date_time
|
||||
|
||||
|
||||
def get_safe_cron_descriptor(expression: str, use_24hour_time_format=True, locale_code: Optional[str] = None) -> str:
|
||||
if is_validate_cron_date_time(expression):
|
||||
if is_valid_cron_date_time(expression):
|
||||
[minutes, hours, day, month, _, year] = expression.split(' ')
|
||||
return "{}-{}-{} at {}:{}".format(
|
||||
year,
|
||||
@ -233,4 +240,4 @@ def restart(debug: bool) -> None:
|
||||
pass
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@ -61,8 +61,12 @@
|
||||
{% if slide.cron_schedule %}
|
||||
{% set cron_desc = cron_descriptor(slide.cron_schedule) %}
|
||||
{% if cron_desc %}
|
||||
{% if is_validate_cron_date_time(slide.cron_schedule) %}
|
||||
📆 {{ cron_desc }}
|
||||
{% if is_valid_cron_date_time(slide.cron_schedule) %}
|
||||
{% if slide.is_notification %}
|
||||
🔔 {{ l.slideshow_slide_panel_td_cron_scheduled_notify }} <span class="td-secondary">{{ cron_desc }}</span>
|
||||
{% else %}
|
||||
🔄 {{ l.slideshow_slide_panel_td_cron_scheduled_loop }}<span class="td-secondary">{{ cron_desc }}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
⏳ {{ cron_desc }}
|
||||
{% endif %}
|
||||
@ -77,8 +81,12 @@
|
||||
{% if slide.cron_schedule_end %}
|
||||
{% set cron_desc_end = cron_descriptor(slide.cron_schedule_end) %}
|
||||
{% if cron_desc_end %}
|
||||
{% if is_validate_cron_date_time(slide.cron_schedule_end) %}
|
||||
📆 {{ cron_desc_end }}
|
||||
{% if is_valid_cron_date_time(slide.cron_schedule_end) %}
|
||||
{% if slide.is_notification %}
|
||||
📆<span class="td-secondary">{{ cron_desc_end }}</span>
|
||||
{% else %}
|
||||
⏱️ {{ slide.duration }} {{ l.slideshow_slide_panel_th_duration_unit }}<span class="td-secondary">{{ cron_desc_end }}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
⏳ {{ cron_desc_end }}
|
||||
{% endif %}
|
||||
|
||||
@ -10,6 +10,18 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block add_js %}
|
||||
<script type="text/javascript">
|
||||
var schedule_start_choices = {
|
||||
'loop': '{{ l.slideshow_slide_form_label_cron_scheduled_loop }}',
|
||||
'datetime': '{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}',
|
||||
'cron': '{{ l.slideshow_slide_form_label_cron_scheduled_cron }}',
|
||||
};
|
||||
var schedule_end_choices = {
|
||||
'duration': '{{ l.slideshow_slide_form_label_cron_scheduled_duration }}',
|
||||
'stayloop': '{{ l.slideshow_slide_form_label_cron_scheduled_stayloop }}',
|
||||
'datetime': '{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}',
|
||||
};
|
||||
</script>
|
||||
<script src="{{ STATIC_PREFIX }}js/lib/flatpickr.min.js"></script>
|
||||
<script src="{{ STATIC_PREFIX }}js/lib/tablednd-fixed.js"></script>
|
||||
<script src="{{ STATIC_PREFIX }}js/slideshow/slides.js"></script>
|
||||
@ -31,6 +43,7 @@
|
||||
<a href="{% if current_playlist %}{{ url_for('player_use', playlist_slug_or_id=current_playlist.slug) }}{% else %}{{ url_for('player') }}{% endif %}" target="_blank" class="btn" title="{{ l.slideshow_goto_player }}">
|
||||
<i class="fa fa-play"></i>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('slideshow_player_refresh') }}" class="btn" title="{{ l.slideshow_refresh_player }}">
|
||||
<i class="fa fa-refresh"></i>
|
||||
</a>
|
||||
@ -81,7 +94,6 @@
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modals hidden">
|
||||
<div class="modals-outer">
|
||||
|
||||
@ -45,6 +45,14 @@
|
||||
{{ l.slideshow_slide_form_section_scheduling }}
|
||||
</h3>
|
||||
|
||||
<div class="form-group slide-notification-group">
|
||||
<label for="slide-add-is-notification">{{ l.slideshow_slide_form_label_is_notification }}</label>
|
||||
<div class="widget">
|
||||
<input type="checkbox" class="trigger slide-is-notification" name="is_notification" id="slide-add-is-notification" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group slide-schedule-group">
|
||||
<label for="slide-add-cron-schedule">{{ l.slideshow_slide_form_label_cron_scheduled }}</label>
|
||||
<div class="widget">
|
||||
|
||||
@ -43,6 +43,13 @@
|
||||
{{ l.slideshow_slide_form_section_scheduling }}
|
||||
</h3>
|
||||
|
||||
<div class="form-group slide-notification-group">
|
||||
<label for="slide-edit-is-notification">{{ l.slideshow_slide_form_label_is_notification }}</label>
|
||||
<div class="widget">
|
||||
<input type="checkbox" class="trigger slide-is-notification" name="is_notification" id="slide-edit-is-notification" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group slide-schedule-group">
|
||||
<label for="slide-edit-cron-schedule">{{ l.slideshow_slide_form_label_cron_scheduled }}</label>
|
||||
<div class="widget">
|
||||
@ -62,7 +69,6 @@
|
||||
<select id="slide-edit-cron-schedule-end-trigger" class="trigger">
|
||||
<option value="duration">{{ l.slideshow_slide_form_label_cron_scheduled_duration }}</option>
|
||||
<option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option>
|
||||
<option value="cron">{{ l.slideshow_slide_form_label_cron_scheduled_cron }}</option>
|
||||
</select>
|
||||
<input type="text" id="slide-edit-cron-schedule-end-datetimepicker" class="datetimepicker" value="" placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}" />
|
||||
<input type="text" name="cron_schedule_end" id="slide-edit-cron-schedule-end" class="target hidden" placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}" />
|
||||
|
||||
Loading…
Reference in New Issue
Block a user