From: Calin Crisan <ccrisan@gmail.com> Date: Sun, 24 Aug 2014 09:01:59 +0000 (+0300) Subject: enabled working schedule UI X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=71313a83c94eadcf9bc382ffd1ed17b90c2e5ac0;p=motioneye-debian enabled working schedule UI --- diff --git a/motioneye.py b/motioneye.py index 4d93d6b..a44ea58 100755 --- a/motioneye.py +++ b/motioneye.py @@ -301,7 +301,7 @@ def _start_motion(): if ioloop._stopped: return - if not motionctl.running() and motionctl.started() and config.has_enabled_cameras(): + if not motionctl.running() and motionctl.started() and config.has_local_enabled_cameras(): try: logging.error('motion not running, starting it') motionctl.start() @@ -324,6 +324,13 @@ def _start_cleanup(): logging.info('cleanup started') +def _start_wsswitch(): + import wsswitch + + wsswitch.start() + logging.info('wsswitch started') + + def _start_thumbnailer(): import thumbnailer @@ -341,6 +348,7 @@ if __name__ == '__main__': _configure_signals() _configure_logging() + if settings.SMB_SHARES: stop, start = smbctl.update_mounts() if start: @@ -350,6 +358,7 @@ if __name__ == '__main__': _start_motion() _start_cleanup() + _start_wsswitch() if settings.THUMBNAILER_INTERVAL: _start_thumbnailer() diff --git a/src/cleanup.py b/src/cleanup.py index 6e3a882..847c7fa 100644 --- a/src/cleanup.py +++ b/src/cleanup.py @@ -30,9 +30,6 @@ _process = None def start(): - if running(): - raise Exception('cleanup is already running') - _run_process() @@ -40,7 +37,8 @@ def stop(): global _process if not running(): - raise Exception('cleanup is not running') + _process = None + return if _process.is_alive(): _process.join(timeout=10) @@ -59,16 +57,16 @@ def running(): def _run_process(): global _process + # schedule the next call + ioloop = tornado.ioloop.IOLoop.instance() + ioloop.add_timeout(datetime.timedelta(seconds=settings.CLEANUP_INTERVAL), _run_process) + if not _process or not _process.is_alive(): # check that the previous process has finished logging.debug('running cleanup process...') _process = multiprocessing.Process(target=_do_cleanup) _process.start() - # schedule the next call - ioloop = tornado.ioloop.IOLoop.instance() - ioloop.add_timeout(datetime.timedelta(seconds=settings.CLEANUP_INTERVAL), _run_process) - def _do_cleanup(): # this will be executed in a separate subprocess diff --git a/src/config.py b/src/config.py index aa39b16..1e4b106 100644 --- a/src/config.py +++ b/src/config.py @@ -187,7 +187,7 @@ def get_camera_ids(): return filtered_camera_ids -def has_enabled_cameras(): +def has_local_enabled_cameras(): if not get_main().get('@enabled'): return False @@ -810,13 +810,13 @@ def camera_dict_to_ui(data): # working schedule 'working_schedule': False, - 'monday_from': '09:00', 'monday_to': '17:00', - 'tuesday_from': '09:00', 'tuesday_to': '17:00', - 'wednesday_from': '09:00', 'wednesday_to': '17:00', - 'thursday_from': '09:00', 'thursday_to': '17:00', - 'friday_from': '09:00', 'friday_to': '17:00', - 'saturday_from': '09:00', 'saturday_to': '17:00', - 'sunday_from': '09:00', 'sunday_to': '17:00' + 'monday_from': '', 'monday_to': '', + 'tuesday_from': '', 'tuesday_to': '', + 'wednesday_from': '', 'wednesday_to': '', + 'thursday_from': '', 'thursday_to': '', + 'friday_from': '', 'friday_to': '', + 'saturday_from': '', 'saturday_to': '', + 'sunday_from': '', 'sunday_to': '' } if utils.net_camera(data): diff --git a/src/motionctl.py b/src/motionctl.py index e62aa5c..9d681bf 100644 --- a/src/motionctl.py +++ b/src/motionctl.py @@ -61,7 +61,7 @@ def start(): _started = True - if running() or not config.has_enabled_cameras(): + if running() or not config.has_local_enabled_cameras(): return logging.debug('starting motion') diff --git a/src/thumbnailer.py b/src/thumbnailer.py index 1c8fded..c3b4809 100644 --- a/src/thumbnailer.py +++ b/src/thumbnailer.py @@ -30,9 +30,6 @@ _process = None def start(): - if running(): - raise Exception('thumbnailer is already running') - _run_process() @@ -40,7 +37,8 @@ def stop(): global _process if not running(): - raise Exception('thumbnailer is not running') + _process = None + return if _process.is_alive(): _process.join(timeout=10) @@ -59,16 +57,16 @@ def running(): def _run_process(): global _process + # schedule the next call + ioloop = tornado.ioloop.IOLoop.instance() + ioloop.add_timeout(datetime.timedelta(seconds=settings.THUMBNAILER_INTERVAL), _run_process) + if not _process or not _process.is_alive(): # check that the previous process has finished logging.debug('running thumbnailer process...') _process = multiprocessing.Process(target=_do_next_movie_thumbail) _process.start() - # schedule the next call - ioloop = tornado.ioloop.IOLoop.instance() - ioloop.add_timeout(datetime.timedelta(seconds=settings.THUMBNAILER_INTERVAL), _run_process) - def _do_next_movie_thumbail(): # this will be executed in a separate subprocess diff --git a/src/wsswitch.py b/src/wsswitch.py new file mode 100644 index 0000000..9a63d55 --- /dev/null +++ b/src/wsswitch.py @@ -0,0 +1,36 @@ + +# Copyright (c) 2013 Calin Crisan +# This file is part of motionEye. +# +# motionEye is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import datetime +import logging +import tornado + +import config +import motionctl + + +def start(): + pass + + +def _check_ws(): + # schedule the next call + ioloop = tornado.ioloop.IOLoop.instance() + ioloop.add_timeout(datetime.timedelta(seconds=60), _check_ws) + + if not motionctl.running(): + return diff --git a/static/css/ui.css b/static/css/ui.css index b0b555f..da85d83 100644 --- a/static/css/ui.css +++ b/static/css/ui.css @@ -157,7 +157,7 @@ input[type=text].styled:FOCUS { } input[type=text].number { - width: 100px; + width: 5em; } input[type=text].error, @@ -168,7 +168,7 @@ input[type=password].error { } input[type=text].time { - width: 75px; + width: 3.5em; } diff --git a/static/js/main.js b/static/js/main.js index ab77d63..ae9542e 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -244,20 +244,20 @@ function initUI() { makeNumberValidator($('#smtpPortEntry'), 1, 65535, false, false, true); /* time validators */ - makeTimeValidator($('#mondayFrom')); - makeTimeValidator($('#mondayTo')); - makeTimeValidator($('#tuesdayFrom')); - makeTimeValidator($('#tuesdayTo')); - makeTimeValidator($('#wednesdayFrom')); - makeTimeValidator($('#wednesdayTo')); - makeTimeValidator($('#thursdayFrom')); - makeTimeValidator($('#thursdayTo')); - makeTimeValidator($('#fridayFrom')); - makeTimeValidator($('#fridayTo')); - makeTimeValidator($('#saturdayFrom')); - makeTimeValidator($('#saturdayTo')); - makeTimeValidator($('#sundayFrom')); - makeTimeValidator($('#sundayTo')); + makeTimeValidator($('#mondayFromEntry')); + makeTimeValidator($('#mondayToEntry')); + makeTimeValidator($('#tuesdayFromEntry')); + makeTimeValidator($('#tuesdayToEntry')); + makeTimeValidator($('#wednesdayFromEntry')); + makeTimeValidator($('#wednesdayToEntry')); + makeTimeValidator($('#thursdayFromEntry')); + makeTimeValidator($('#thursdayToEntry')); + makeTimeValidator($('#fridayFromEntry')); + makeTimeValidator($('#fridayToEntry')); + makeTimeValidator($('#saturdayFromEntry')); + makeTimeValidator($('#saturdayToEntry')); + makeTimeValidator($('#sundayFromEntry')); + makeTimeValidator($('#sundayToEntry')); /* ui elements that enable/disable other ui elements */ $('#motionEyeSwitch').change(updateConfigUi); @@ -282,6 +282,14 @@ function initUI() { $('#commandNotificationsSwitch').change(updateConfigUi); $('#workingScheduleSwitch').change(updateConfigUi); + $('#mondayEnabledSwitch').change(updateConfigUi); + $('#tuesdayEnabledSwitch').change(updateConfigUi); + $('#wednesdayEnabledSwitch').change(updateConfigUi); + $('#thursdayEnabledSwitch').change(updateConfigUi); + $('#fridayEnabledSwitch').change(updateConfigUi); + $('#saturdayEnabledSwitch').change(updateConfigUi); + $('#sundayEnabledSwitch').change(updateConfigUi); + $('#storageDeviceSelect').change(function () { $('#rootDirectoryEntry').val('/'); }); @@ -502,7 +510,7 @@ function updateConfigUi() { $('#moviesLifetime').parents('tr:eq(0)').each(markHide); } - /* email notifications switch */ + /* event notifications */ if (!$('#emailNotificationsSwitch').get(0).checked) { $('#emailAddressesEntry').parents('tr:eq(0)').each(markHide); $('#smtpServerEntry').parents('tr:eq(0)').each(markHide); @@ -521,11 +529,22 @@ function updateConfigUi() { $('#commandNotificationsEntry').parents('tr:eq(0)').each(markHide); } - /* working schedule switch */ + /* working schedule */ if (!$('#workingScheduleSwitch').get(0).checked) { $('#workingScheduleSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide); } + var weekDays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']; + weekDays.forEach(function (weekDay) { + var check = $('#' + weekDay + 'EnabledSwitch'); + if (check.get(0).checked) { + check.parent().find('.time').show(); + } + else { + check.parent().find('.time').hide(); + } + }); + objs.each(function () { if (this._hide) { $(this).hide(200); @@ -688,20 +707,20 @@ function cameraUi2Dict() { /* working schedule */ 'working_schedule': $('#workingScheduleSwitch')[0].checked, - 'monday_from': $('#mondayFrom').val(), - 'monday_to':$('#mondayTo').val(), - 'tuesday_from': $('#tuesdayFrom').val(), - 'tuesday_to': $('#tuesdayTo').val(), - 'wednesday_from': $('#wednesdayFrom').val(), - 'wednesday_to': $('#wednesdayTo').val(), - 'thursday_from': $('#thursdayFrom').val(), - 'thursday_to': $('#thursdayTo').val(), - 'friday_from':$('#fridayFrom').val(), - 'friday_to': $('#fridayTo').val(), - 'saturday_from':$('#saturdayFrom').val(), - 'saturday_to': $('#saturdayTo').val(), - 'sunday_from': $('#sundayFrom').val(), - 'sunday_to': $('#sundayTo').val(), + 'monday_from': $('#mondayEnabledSwitch')[0].checked ? $('#mondayFromEntry').val() : '', + 'monday_to':$('#mondayEnabledSwitch')[0].checked ? $('#mondayToEntry').val() : '', + 'tuesday_from': $('#tuesdayEnabledSwitch')[0].checked ? $('#tuesdayFromEntry').val() : '', + 'tuesday_to': $('#tuesdayEnabledSwitch')[0].checked ? $('#tuesdayToEntry').val() : '', + 'wednesday_from': $('#wednesdayEnabledSwitch')[0].checked ? $('#wednesdayFromEntry').val() : '', + 'wednesday_to': $('#wednesdayEnabledSwitch')[0].checked ? $('#wednesdayToEntry').val() : '', + 'thursday_from': $('#thursdayEnabledSwitch')[0].checked ? $('#thursdayFromEntry').val() : '', + 'thursday_to': $('#thursdayEnabledSwitch')[0].checked ? $('#thursdayToEntry').val() : '', + 'friday_from': $('#fridayEnabledSwitch')[0].checked ? $('#fridayFromEntry').val() : '', + 'friday_to': $('#fridayEnabledSwitch')[0].checked ? $('#fridayToEntry').val() :'', + 'saturday_from': $('#saturdayEnabledSwitch')[0].checked ? $('#saturdayFromEntry').val() : '', + 'saturday_to': $('#saturdayEnabledSwitch')[0].checked ? $('#saturdayToEntry').val() : '', + 'sunday_from': $('#sundayEnabledSwitch')[0].checked ? $('#sundayFromEntry').val() : '', + 'sunday_to': $('#sundayEnabledSwitch')[0].checked ? $('#sundayToEntry').val() : '', }; if ($('#resolutionSelect')[0].selectedIndex != -1) { @@ -901,20 +920,27 @@ function dict2CameraUi(dict) { /* working schedule */ $('#workingScheduleSwitch')[0].checked = dict['working_schedule']; - $('#mondayFrom').val(dict['monday_from']); - $('#mondayTo').val(dict['monday_to']); - $('#tuesdayFrom').val(dict['tuesday_from']); - $('#tuesdayTo').val(dict['tuesday_to']); - $('#wednesdayFrom').val(dict['wednesday_from']); - $('#wednesdayTo').val(dict['wednesday_to']); - $('#thursdayFrom').val(dict['thursday_from']); - $('#thursdayTo').val(dict['thursday_to']); - $('#fridayFrom').val(dict['friday_from']); - $('#fridayTo').val(dict['friday_to']); - $('#saturdayFrom').val(dict['saturday_from']); - $('#saturdayTo').val(dict['saturday_to']); - $('#sundayFrom').val(dict['sunday_from']); - $('#sundayTo').val(dict['sunday_to']); + $('#mondayEnabledSwitch')[0].checked = Boolean(dict['monday_from'] && dict['monday_to']); + $('#mondayFromEntry').val(dict['monday_from']); + $('#mondayToEntry').val(dict['monday_to']); + $('#tuesdayEnabledSwitch')[0].checked = Boolean(dict['tuesday_from'] && dict['tuesday_to']); + $('#tuesdayFromEntry').val(dict['tuesday_from']); + $('#tuesdayToEntry').val(dict['tuesday_to']); + $('#wednesdayEnabledSwitch')[0].checked = Boolean(dict['wednesday_from'] && dict['wednesday_to']); + $('#wednesdayFromEntry').val(dict['wednesday_from']); + $('#wednesdayToEntry').val(dict['wednesday_to']); + $('#thursdayEnabledSwitch')[0].checked = Boolean(dict['thursday_from'] && dict['thursday_to']); + $('#thursdayFromEntry').val(dict['thursday_from']); + $('#thursdayToEntry').val(dict['thursday_to']); + $('#fridayEnabledSwitch')[0].checked = Boolean(dict['friday_from'] && dict['friday_to']); + $('#fridayFromEntry').val(dict['friday_from']); + $('#fridayToEntry').val(dict['friday_to']); + $('#saturdayEnabledSwitch')[0].checked = Boolean(dict['saturday_from'] && dict['saturday_to']); + $('#saturdayFromEntry').val(dict['saturday_from']); + $('#saturdayToEntry').val(dict['saturday_to']); + $('#sundayEnabledSwitch')[0].checked = Boolean(dict['sunday_from'] && dict['sunday_to']); + $('#sundayFromEntry').val(dict['sunday_from']); + $('#sundayToEntry').val(dict['sunday_to']); updateConfigUi(); } diff --git a/static/js/ui.js b/static/js/ui.js index 723697b..ede3317 100644 --- a/static/js/ui.js +++ b/static/js/ui.js @@ -306,7 +306,7 @@ function makeTextValidator($input, required) { } function isValid(strVal) { - if (!$input.parents('tr:eq(0)').is(':visible')) { + if (!$input.is(':visible')) { return true; /* an invisible element is considered always valid */ } @@ -350,7 +350,7 @@ function makeComboValidator($select, required) { } function isValid(strVal) { - if (!$select.parents('tr:eq(0)').is(':visible')) { + if (!$select.is(':visible')) { return true; /* an invisible element is considered always valid */ } @@ -406,7 +406,7 @@ function makeNumberValidator($input, minVal, maxVal, floating, sign, required) { } function isValid(strVal) { - if (!$input.parents('tr:eq(0)').is(':visible')) { + if (!$input.is(':visible')) { return true; /* an invisible element is considered always valid */ } @@ -484,16 +484,16 @@ function makeNumberValidator($input, minVal, maxVal, floating, sign, required) { function makeTimeValidator($input) { function isValid(strVal) { + if (!$input.is(':visible')) { + return true; /* an invisible element is considered always valid */ + } + return strVal.match(new RegExp('^[0-2][0-9]:[0-5][0-9]$')) != null; } var msg = 'enter a valid time in the following format: HH:MM'; function validate() { - if (!$input.parents('tr:eq(0)').is(':visible')) { - return true; /* an invisible element is considered always valid */ - } - var strVal = $input.val(); if (isValid(strVal)) { $input.attr('title', ''); @@ -525,58 +525,14 @@ function makeTimeValidator($input) { function makeUrlValidator($input) { function isValid(strVal) { - return strVal.match(new RegExp('^([a-zA-Z]+)://([\\w\-.]+)(:\\d+)?(/.*)?$')) != null; - } - - var msg = 'enter a valid URL (e.g. http://example.com:8080/cams/)'; - - function validate() { - if (!$input.parents('tr:eq(0)').is(':visible')) { + if (!$input.is(':visible')) { return true; /* an invisible element is considered always valid */ } - - var strVal = $input.val(); - if (isValid(strVal)) { - $input.attr('title', ''); - $input.removeClass('error'); - $input[0].invalid = false; - } - else { - $input.attr('title', msg); - $input.addClass('error'); - $input[0].invalid = true; - } - } - - $input.keyup(validate); - $input.blur(validate); - $input.change(validate).change(); - - $input.addClass('validator'); - $input.addClass('url-validator'); - $input.each(function () { - this.validate = validate; - }); -} -function makeRegexValidator($input, regex, required) { - if (required == null) { - required = true; - } - - function isValid(strVal) { - if (!$input.parents('tr:eq(0)').is(':visible')) { - return true; /* an invisible element is considered always valid */ - } - - if (strVal.length === 0 && !required) { - return true; - } - - return strVal.match(new RegExp(regex)) != null; + return strVal.match(new RegExp('^([a-zA-Z]+)://([\\w\-.]+)(:\\d+)?(/.*)?$')) != null; } - var msg = 'enter a valid value'; + var msg = 'enter a valid URL (e.g. http://example.com:8080/cams/)'; function validate() { var strVal = $input.val(); @@ -597,7 +553,7 @@ function makeRegexValidator($input, regex, required) { $input.change(validate).change(); $input.addClass('validator'); - $input.addClass('regex-validator'); + $input.addClass('url-validator'); $input.each(function () { this.validate = validate; }); diff --git a/templates/main.html b/templates/main.html index 8a0337a..c0a878f 100644 --- a/templates/main.html +++ b/templates/main.html @@ -386,7 +386,7 @@ <td><span class="help-mark" title="indicates the minimal percent of the image that must change between two successive frames in order for motion to be detected (smaller values give a more sensitive detection, but are prone to false positives)">?</span></td> </tr> <tr class="settings-item advanced-setting"> - <td class="settings-item-label"><span class="settings-item-label">Automatic Noise Detection</span></td> + <td class="settings-item-label"><span class="settings-item-label">Auto Noise Detection</span></td> <td class="settings-item-value"><input type="checkbox" class="styled motion-detection" id="autoNoiseDetectSwitch"></td> <td><span class="help-mark" title="enable this to automatically adjust the noise level">?</span></td> </tr> @@ -490,61 +490,68 @@ </tr> </table> - <div class="settings-section-title hidden"><input type="checkbox" class="styled section working-schedule" id="workingScheduleSwitch">Working Schedule</div> - <table class="settings hidden"> + <div class="settings-section-title"><input type="checkbox" class="styled section working-schedule" id="workingScheduleSwitch">Working Schedule</div> + <table class="settings"> <tr class="settings-item"> <td class="settings-item-label"><span class="settings-item-label">Monday</span></td> <td class="settings-item-value"> - <span class="settings-item-unit">from</span><input type="text" class="styled working-schedule time" id="mondayFrom"> - <span class="settings-item-unit">to</span><input type="text" class="styled working-schedule time" id="mondayTo"> + <input type="checkbox" class="styled working-schedule" id="mondayEnabledSwitch"> + <span class="settings-item-unit time">from</span><input type="text" class="styled working-schedule time" id="mondayFromEntry"> + <span class="settings-item-unit time">to</span><input type="text" class="styled working-schedule time" id="mondayToEntry"> </td> <td><span class="help-mark" title="sets the working schedule time interval for Mondays">?</span></td> </tr> <tr class="settings-item"> <td class="settings-item-label"><span class="settings-item-label">Tuesday</span></td> <td class="settings-item-value"> - <span class="settings-item-unit">from</span><input type="text" class="styled working-schedule time" id="tuesdayFrom"> - <span class="settings-item-unit">to</span><input type="text" class="styled working-schedule time" id="tuesdayTo"> + <input type="checkbox" class="styled working-schedule" id="tuesdayEnabledSwitch"> + <span class="settings-item-unit time">from</span><input type="text" class="styled working-schedule time" id="tuesdayFromEntry"> + <span class="settings-item-unit time">to</span><input type="text" class="styled working-schedule time" id="tuesdayToEntry"> </td> <td><span class="help-mark" title="sets the working schedule time interval for Tuesdays">?</span></td> </tr> <tr class="settings-item"> <td class="settings-item-label"><span class="settings-item-label">Wednesday</span></td> <td class="settings-item-value"> - <span class="settings-item-unit">from</span><input type="text" class="styled working-schedule time" id="wednesdayFrom"> - <span class="settings-item-unit">to</span><input type="text" class="styled working-schedule time" id="wednesdayTo"> + <input type="checkbox" class="styled working-schedule" id="wednesdayEnabledSwitch"> + <span class="settings-item-unit time">from</span><input type="text" class="styled working-schedule time" id="wednesdayFromEntry"> + <span class="settings-item-unit time">to</span><input type="text" class="styled working-schedule time" id="wednesdayToEntry"> </td> <td><span class="help-mark" title="sets the working schedule time interval for Wednesdays">?</span></td> </tr> <tr class="settings-item"> <td class="settings-item-label"><span class="settings-item-label">Thursday</span></td> <td class="settings-item-value"> - <span class="settings-item-unit">from</span><input type="text" class="styled working-schedule time" id="thursdayFrom"> - <span class="settings-item-unit">to</span><input type="text" class="styled working-schedule time" id="thursdayTo"> + <input type="checkbox" class="styled working-schedule" id="thursdayEnabledSwitch"> + <span class="settings-item-unit time">from</span><input type="text" class="styled working-schedule time" id="thursdayFromEntry"> + <span class="settings-item-unit time">to</span><input type="text" class="styled working-schedule time" id="thursdayToEntry"> </td> <td><span class="help-mark" title="sets the working schedule time interval for Thursdays">?</span></td> </tr> <tr class="settings-item"> <td class="settings-item-label"><span class="settings-item-label">Friday</span></td> <td class="settings-item-value"> - <span class="settings-item-unit">from</span><input type="text" class="styled working-schedule time" id="fridayFrom"> - <span class="settings-item-unit">to</span><input type="text" class="styled working-schedule time" id="fridayTo"> + <input type="checkbox" class="styled working-schedule" id="fridayEnabledSwitch"> + <span class="settings-item-unit time">from</span><input type="text" class="styled working-schedule time" id="fridayFromEntry"> + <span class="settings-item-unit time">to</span><input type="text" class="styled working-schedule time" id="fridayToEntry"> </td> <td><span class="help-mark" title="sets the working schedule time interval for Friday">?</span></td> </tr> <tr class="settings-item"> <td class="settings-item-label"><span class="settings-item-label">Saturday</span></td> <td class="settings-item-value"> - <span class="settings-item-unit">from</span><input type="text" class="styled working-schedule time" id="saturdayFrom"> - <span class="settings-item-unit">to</span><input type="text" class="styled working-schedule time" id="saturdayTo"> + <input type="checkbox" class="styled working-schedule" id="saturdayEnabledSwitch"> + <span class="settings-item-unit time">from</span><input type="text" class="styled working-schedule time" id="saturdayFromEntry"> + <span class="settings-item-unit time">to</span><input type="text" class="styled working-schedule time" id="saturdayToEntry"> </td> <td><span class="help-mark" title="sets the working schedule time interval for Saturday">?</span></td> </tr> <tr class="settings-item"> <td class="settings-item-label"><span class="settings-item-label">Sunday</span></td> <td class="settings-item-value"> - <span class="settings-item-unit">from</span><input type="text" class="styled working-schedule time" id="sundayFrom"> - <span class="settings-item-unit">to</span><input type="text" class="styled working-schedule time" id="sundayTo"> + <input type="checkbox" class="styled working-schedule" id="sundayEnabledSwitch"> + <span class="settings-item-unit time">from</span><input type="text" class="styled working-schedule time" id="sundayFromEntry"> + <span class="settings-item-unit time">to</span><input type="text" class="styled working-schedule time" id="sundayToEntry"> </td> <td><span class="help-mark" title="sets the working schedule time interval for Sunday">?</span></td> </tr>