if __name__ == '__main__':
-# _configure_signals()
-# _configure_logging()
-# _start_server()
+ _configure_signals()
+ _configure_logging()
+ _start_server()
# import config
# main_config = config.get_main()
# #config.set_camera(1, data)
# config.rem_camera(1)
- import motionctl
-
- motionctl.start()
+# import motionctl
+# motionctl.start()
data.setdefault('@network_share_name', '')
data.setdefault('@network_username', '')
data.setdefault('@network_password', '')
- data.setdefault('target_dir', '.')
+ data.setdefault('target_dir', settings.RUN_PATH)
data.setdefault('webcam_localhost', False)
data.setdefault('webcam_port', 8080)
log_file = open(motion_log_path, 'w')
process = subprocess.Popen(args, stdout=log_file, stderr=log_file, close_fds=True,
- cwd=settings.RUN_PATH)
+ cwd=settings.CONF_PATH)
# wait 2 seconds to see that the process has successfully started
for i in xrange(20): # @UnusedVariable
+++ /dev/null
-
-
- /* fonts */
-
-@font-face {
- font-family: 'Maven Pro';
- src: url('../fnt/mavenpro-regular-webfont.eot');
- src: url('../fnt/mavenpro-regular-webfont.eot?#iefix') format('embedded-opentype'),
- url('../fnt/mavenpro-regular-webfont.woff') format('woff'),
- url('../fnt/mavenpro-regular-webfont.ttf') format('truetype'),
- url('../fnt/mavenpro-regular-webfont.svg#maven_proregular') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
-@font-face {
- font-family: 'Maven Pro';
- src: url('../fnt/mavenpro-bold-webfont.eot');
- src: url('../fnt/mavenpro-bold-webfont.eot?#iefix') format('embedded-opentype'),
- url('../fnt/mavenpro-bold-webfont.woff') format('woff'),
- url('../fnt/mavenpro-bold-webfont.ttf') format('truetype'),
- url('../fnt/mavenpro-bold-webfont.svg#maven_probold') format('svg');
- font-weight: bold;
- font-style: normal;
-}
-
-
- /* layout */
-
-html {
- font-family: 'Maven Pro';
-}
-
-div.page,
-div.header-container {
- position: relative;
- min-width: 320px;
- width: 100%;
-}
-
-div.page {
- margin-top: 50px;
- padding-bottom: 20px;
- font-size: 1em;
- transition: all 0.5s linear;
-}
-
-div.header {
- background-color: rgba(64, 64, 64, 0.5);
- top: 0px;
- width: 100%;
- height: 50px;
- position: fixed;
- overflow: hidden;
- z-index: 10000;
-}
-
-div.header-container {
- transition: all 0.5s linear;
-}
-
-div.footer {
- position: absolute;
- bottom: 0px;
- width: 100%;
- height: 20px;
- font-size: 0.5em;
- color: #aaa;
- text-align: center;
-}
-
-div.page-container {
- transition: all 0.2s linear;
- padding: 5px;
-}
-
-div.page-container.stretched {
- margin-left: 40%;
-}
-
-
- /* settings */
-
-div.settings {
- background-color: #313131;
- position: fixed;
- z-index: 1;
- top: 50px;
- left: 0px;
- width: 0px;
- height: 100%;
- transition: all 0.2s linear;
- overflow: auto;
-}
-
-div.settings.open {
- width: 40%;
- min-width: 320px;
-}
-
-div.settings-container {
- padding-top: 10px;
- padding-bottom: 60px;
- display: none;
- white-space: nowrap;
-}
-
-div.settings.open div.settings-container {
- display: block;
-}
-
-div.settings-top-bar {
- position: relative;
- display: inline-block;
- width: 40%;
- height: 50px;
-}
-
-div.settings-top-bar.open {
- background-color: #414141;
- min-width: 320px;
-}
-
-div.settings-section-title {
- position: relative;
- text-align: right;
- background-color: rgba(100, 100, 100, 0.3);
- padding: 5px;
-}
-
-table.settings {
- width: 100%;
- padding: 0.5em 0.5em 1em 0.5em;
-}
-
-td.settings-item-label {
- width: 50%;
- text-align: right;
- padding-right: 5px;
-}
-
-td.settings-item-value {
- width: 50%;
- text-align: left;
- padding-left: 5px;
-}
-
-span.settings-item-label {
- font-size: 0.9em;
-}
-
-span.settings-item-unit {
- font-size: 0.6em;
- padding: 0px 0.2em;
-}
-
-div.settings-item-separator {
- height: 1px;
- border-top: 1px solid #414141;
- margin: 5px 0px;
-}
-
-select.video-device {
- display: none;
- padding: 4px 1.5em 4px 4px;
- vertical-align: middle;
- font-size: 20px;
- width: auto;
- max-width: 40%;
-}
-
-div.apply-button {
- position: relative;
- display: none;
- opacity: 0;
- float: right;
- width: 80px;
- height: 30px;
- line-height: 30px;
- text-align: center;
- margin: 10px;
- color: white;
- font-weight: bold;
- font-size: 17px;
- background-color: #FF6F00;
- border-radius: 3px;
- transition: all 0.1s linear;
-}
-
-div.apply-button:HOVER {
- background-color: #FF7D19;
-}
-
-div.apply-button:ACTIVE {
- background-color: #F06800;
-}
-
-div.apply-button.progress {
- background-color: #FF6F00;
-}
-
-img.apply-progress {
- margin-top: 3px;
-}
-
-div.settings-top-bar.open select.video-device {
- display: inline;
-}
-
-div.check-box.section {
- margin: 0px;
- float: left;
-}
-
-div.check-box.section div.check-box-button {
- background-color: #515151;
-}
-
-div.check-box.on.section div.check-box-button {
- background-color: #3498db;
-}
-
-input[type=text].working-schedule.number {
- width: 50px;
-}
-
-
- /* media queries */
-
-@media all and (max-width: 1440px) {
- /* smaller screens */
-
- body {
- font-size: 17px;
- }
-}
-
-@media all and (max-width: 1000px) {
- /* small screens (mobile devices) */
-
- div.page-container.stretched {
- margin-left: 0px;
- }
-
- div.settings.open {
- box-shadow: 0px 0px 10px rgba(0,0,0,0.5);
- background-color: rgba(40, 40, 40, 0.9);
- }
-}
-
-@media all and (max-width: 400px) {
- /* very small screens */
-
- body {
- font-size: 13px;
- }
-}
-
-
- /* links */
-
-a {
- color: inherit;
- text-decoration: inherit;
-}
-
-
- /* icons */
-
-img.settings-button {
- margin: 2px;
- cursor: pointer;
- vertical-align: middle;
-}
-
-div.logo {
- float: right;
- display: inline-block;
- white-space: nowrap;
- opacity: 0.86;
-}
-
-span.logo {
- vertical-align: middle;
- font-size: 27px;
- font-weight: bold;
- position: relative;
- top: 3px;
-}
-
-img.logo {
- width: 48px;
- height: 48px;
- vertical-align: middle;
-}
+
+ /* fonts */
+
+@font-face {
+ font-family: 'Maven Pro';
+ src: url('../fnt/mavenpro-regular-webfont.eot');
+ src: url('../fnt/mavenpro-regular-webfont.eot?#iefix') format('embedded-opentype'),
+ url('../fnt/mavenpro-regular-webfont.woff') format('woff'),
+ url('../fnt/mavenpro-regular-webfont.ttf') format('truetype'),
+ url('../fnt/mavenpro-regular-webfont.svg#maven_proregular') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Maven Pro';
+ src: url('../fnt/mavenpro-bold-webfont.eot');
+ src: url('../fnt/mavenpro-bold-webfont.eot?#iefix') format('embedded-opentype'),
+ url('../fnt/mavenpro-bold-webfont.woff') format('woff'),
+ url('../fnt/mavenpro-bold-webfont.ttf') format('truetype'),
+ url('../fnt/mavenpro-bold-webfont.svg#maven_probold') format('svg');
+ font-weight: bold;
+ font-style: normal;
+}
+
+
+ /* layout */
+
+html {
+ font-family: 'Maven Pro';
+}
+
+div.page,
+div.header-container {
+ position: relative;
+ min-width: 320px;
+ width: 100%;
+}
+
+div.page {
+ margin-top: 50px;
+ padding-bottom: 20px;
+ font-size: 1em;
+ transition: all 0.5s linear;
+}
+
+div.header {
+ background-color: rgba(64, 64, 64, 0.5);
+ top: 0px;
+ width: 100%;
+ height: 50px;
+ position: fixed;
+ overflow: hidden;
+ z-index: 10000;
+}
+
+div.header-container {
+ transition: all 0.5s linear;
+}
+
+div.footer {
+ position: absolute;
+ bottom: 0px;
+ width: 100%;
+ height: 20px;
+ font-size: 0.5em;
+ color: #aaa;
+ text-align: center;
+}
+
+div.page-container {
+ transition: all 0.2s linear;
+ padding: 5px;
+}
+
+div.page-container.stretched {
+ margin-left: 40%;
+}
+
+
+ /* settings */
+
+div.settings {
+ background-color: #313131;
+ position: fixed;
+ z-index: 1;
+ top: 50px;
+ left: 0px;
+ width: 0px;
+ height: 100%;
+ transition: all 0.2s linear;
+ overflow: auto;
+}
+
+div.settings.open {
+ width: 40%;
+ min-width: 320px;
+}
+
+div.settings-container {
+ padding-top: 10px;
+ padding-bottom: 60px;
+ display: none;
+ white-space: nowrap;
+}
+
+div.settings.open div.settings-container {
+ display: block;
+}
+
+div.settings-top-bar {
+ position: relative;
+ display: inline-block;
+ width: 40%;
+ height: 50px;
+}
+
+div.settings-top-bar.open {
+ background-color: #414141;
+ min-width: 320px;
+}
+
+div.settings-section-title {
+ position: relative;
+ text-align: right;
+ background-color: rgba(100, 100, 100, 0.3);
+ padding: 5px;
+}
+
+table.settings {
+ width: 100%;
+ padding: 0.5em 0.5em 1em 0.5em;
+}
+
+td.settings-item-label {
+ width: 50%;
+ text-align: right;
+ padding-right: 5px;
+}
+
+td.settings-item-value {
+ width: 50%;
+ text-align: left;
+ padding-left: 5px;
+}
+
+span.settings-item-label {
+ font-size: 0.9em;
+}
+
+span.settings-item-unit {
+ font-size: 0.6em;
+ padding: 0px 0.2em;
+}
+
+div.settings-item-separator {
+ height: 1px;
+ border-top: 1px solid #414141;
+ margin: 5px 0px;
+}
+
+select.video-device {
+ display: none;
+ padding: 4px 1.5em 4px 4px;
+ vertical-align: middle;
+ font-size: 20px;
+ width: auto;
+ max-width: 40%;
+}
+
+div.apply-button {
+ position: relative;
+ display: none;
+ opacity: 0;
+ float: right;
+ width: 80px;
+ height: 30px;
+ line-height: 30px;
+ text-align: center;
+ margin: 10px;
+ color: white;
+ font-weight: bold;
+ font-size: 17px;
+ background-color: #FF6F00;
+ border-radius: 3px;
+ transition: all 0.1s linear;
+}
+
+div.apply-button:HOVER {
+ background-color: #FF7D19;
+}
+
+div.apply-button:ACTIVE {
+ background-color: #F06800;
+}
+
+div.apply-button.progress {
+ background-color: #FF6F00;
+}
+
+img.apply-progress {
+ margin-top: 3px;
+}
+
+div.settings-top-bar.open select.video-device {
+ display: inline;
+}
+
+div.check-box.section {
+ margin: 0px;
+ float: left;
+}
+
+div.check-box.section div.check-box-button {
+ background-color: #515151;
+}
+
+div.check-box.on.section div.check-box-button {
+ background-color: #3498db;
+}
+
+input[type=text].working-schedule.number {
+ width: 50px;
+}
+
+
+ /* camera frames */
+
div.video-list {
text-align: center;
}
/* media queries */
+@media all and (max-width: 1440px) {
+ /* smaller screens */
+
+ body {
+ font-size: 17px;
+ }
+}
+
+@media all and (max-width: 1000px) {
+ /* small screens (mobile devices) */
+
+ div.page-container.stretched {
+ margin-left: 0px;
+ }
+
+ div.settings.open {
+ box-shadow: 0px 0px 10px rgba(0,0,0,0.5);
+ background-color: rgba(40, 40, 40, 0.9);
+ }
+}
+
+@media all and (max-width: 400px) {
+ /* very small screens */
+
+ body {
+ font-size: 13px;
+ }
+}
+
@media all and (max-width: 1900px) {
/* a bit smaller screens */
width: 98%;
}
}
+
+
+ /* links */
+
+a {
+ color: inherit;
+ text-decoration: inherit;
+}
+
+
+ /* icons */
+
+img.settings-button {
+ margin: 2px;
+ cursor: pointer;
+ vertical-align: middle;
+}
+
+div.logo {
+ float: right;
+ display: inline-block;
+ white-space: nowrap;
+ opacity: 0.86;
+}
+
+span.logo {
+ vertical-align: middle;
+ font-size: 27px;
+ font-weight: bold;
+ position: relative;
+ top: 3px;
+}
+
+img.logo {
+ width: 48px;
+ height: 48px;
+ vertical-align: middle;
+}
+++ /dev/null
-
-var pushConfigs = {};
-
-
- /* utils */
-
-function ajax(method, url, data, callback) {
- var options = {
- type: method,
- url: url,
- data: data,
- cache: false,
- success: callback,
- error: function (request, options, error) {
- alert('Request failed with code: ' + request.status);
- if (callback) {
- callback();
- }
- }
- };
-
- if (data && typeof data === 'object') {
- options['contentType'] = 'application/json';
- options['data'] = JSON.stringify(options['data']);
- }
-
- $.ajax(options);
-}
-
-Object.keys = Object.keys || (function () {
- var hasOwnProperty = Object.prototype.hasOwnProperty;
- var hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString');
- var dontEnums = [
- 'toString',
- 'toLocaleString',
- 'valueOf',
- 'hasOwnProperty',
- 'isPrototypeOf',
- 'propertyIsEnumerable',
- 'constructor'
- ];
- var dontEnumsLength = dontEnums.length;
-
- return function (obj) {
- if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) {
- return [];
- }
-
- var result = [];
- for (var prop in obj) {
- if (hasOwnProperty.call(obj, prop)) {
- result.push(prop);
- }
- }
-
- if (hasDontEnumBug) {
- for (var i = 0; i < dontEnumsLength; i++) {
- if (hasOwnProperty.call(obj, dontEnums[i])) {
- result.push(dontEnums[i]);
- }
- }
- }
-
- return result;
- };
-})();
-
-
- /* UI */
-
-function initUI() {
- /* checkboxes */
- $('input[type=checkbox].styled').each(function () {
- makeCheckBox($(this));
- });
-
- /* sliders */
- makeSlider($('#brightnessSlider'), 0, 100, 0, null, 5, 0, '%');
- makeSlider($('#contrastSlider'), 0, 100, 0, null, 5, 0, '%');
- makeSlider($('#saturationSlider'), 0, 100, 0, null, 5, 0, '%');
- makeSlider($('#hueSlider'), 0, 100, 0, null, 5, 0, '%');
- makeSlider($('#framerateSlider'), 1, 30, 0, [
- {value: 1, label: '1'},
- {value: 5, label: '5'},
- {value: 10, label: '10'},
- {value: 15, label: '15'},
- {value: 20, label: '20'},
- {value: 25, label: '25'},
- {value: 30, label: '30'}
- ], null, 0);
- makeSlider($('#streamingFramerateSlider'), 1, 30, 0, [
- {value: 1, label: '1'},
- {value: 5, label: '5'},
- {value: 10, label: '10'},
- {value: 15, label: '15'},
- {value: 20, label: '20'},
- {value: 25, label: '25'},
- {value: 30, label: '30'}
- ], null, 0);
- makeSlider($('#streamingQualitySlider'), 0, 100, 0, null, 5, 0, '%');
- makeSlider($('#imageQualitySlider'), 0, 100, 0, null, 5, 0, '%');
- makeSlider($('#movieQualitySlider'), 0, 100, 0, null, 5, 0, '%');
- makeSlider($('#frameChangeThresholdSlider'), 0, 10000, 0, null, 3, 0, 'px');
- makeSlider($('#noiseLevelSlider'), 0, 100, 0, null, 5, 0, '%');
-
- /* text validators */
- makeTextValidator($('#adminUsernameEntry'), true);
- makeTextValidator($('#adminPasswordEntry'), true);
- makeTextValidator($('#normalUsernameEntry'), true);
- makeTextValidator($('#normalPasswordEntry'), true);
- makeTextValidator($('#deviceNameEntry'), true);
- makeTextValidator($('#networkServerEntry'), true);
- makeTextValidator($('#networkShareNameEntry'), true);
- makeTextValidator($('#networkUsernameEntry'), false);
- makeTextValidator($('#networkPasswordEntry'), false);
- makeTextValidator($('#rootDirectoryEntry'), true);
- makeTextValidator($('#leftTextEntry'), true);
- makeTextValidator($('#rightTextEntry'), true);
- makeTextValidator($('#imageFileNameEntry'), true);
- makeTextValidator($('#movieFileNameEntry'), true);
- makeTextValidator($('#emailAddressesEntry'), true);
-
- /* number validators */
- makeNumberValidator($('#streamingPortEntry'), 1024, 65535, false, false, true);
- makeNumberValidator($('#snapshotIntervalEntry'), 1, 86400, false, false, true);
- makeNumberValidator($('#gapEntry'), 1, 86400, false, false, true);
- makeNumberValidator($('#preCaptureEntry'), 0, 100, false, false, true);
- makeNumberValidator($('#postCaptureEntry'), 0, 100, 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'));
-
- /* ui elements that enable/disable other ui elements */
- $('#motionEyeSwitch').change(updateConfigUi);
- $('#showAdvancedSwitch').change(updateConfigUi);
- $('#storageDeviceSelect').change(updateConfigUi);
- $('#autoBrightnessSwitch').change(updateConfigUi);
- $('#leftTextSelect').change(updateConfigUi);
- $('#rightTextSelect').change(updateConfigUi);
- $('#captureModeSelect').change(updateConfigUi);
- $('#autoNoiseDetectSwitch').change(updateConfigUi);
- $('#videoDeviceSwitch').change(updateConfigUi);
- $('#textOverlaySwitch').change(updateConfigUi);
- $('#videoStreamingSwitch').change(updateConfigUi);
- $('#stillImagesSwitch').change(updateConfigUi);
- $('#motionMoviesSwitch').change(updateConfigUi);
- $('#motionNotificationsSwitch').change(updateConfigUi);
- $('#workingScheduleSwitch').change(updateConfigUi);
-
- /* fetch & push handlers */
- $('#videoDeviceSelect').change(fetchCameraConfig);
- $('input.general').change(pushMainConfig);
- $('input.device, select.device, ' +
- 'input.storage, select.storage, ' +
- 'input.text-overlay, select.text-overlay, ' +
- 'input.streaming, select.streaming, ' +
- 'input.still-images, select.still-images, ' +
- 'input.motion-movies, select.motion-movies, ' +
- 'input.motion-detection, select.motion-detection, ' +
- 'input.notifications, select.notifications, ' +
- 'input.working-schedule, select.working-schedule').change(pushCameraConfig);
-
- /* apply button */
- $('#applyButton').click(function () {
- if ($(this).hasClass('progress')) {
- return; /* in progress */
- }
-
- doApply();
- });
-}
-
-function updateConfigUi() {
- var objs = $('tr.settings-item, div.advanced-setting, table.advanced-setting, div.settings-section-title, table.settings');
-
- function markHide() {
- this._hide = true;
- }
-
- function unmarkHide() {
- this._hide = false;
- }
-
- objs.each(unmarkHide);
-
- /* general enable switch */
- var motionEyeEnabled = $('#motionEyeSwitch').get(0).checked;
- if (!motionEyeEnabled) {
- objs.not($('#motionEyeSwitch').parents('div').get(0)).each(markHide);
- }
-
- /* advanced settings */
- var showAdvanced = $('#showAdvancedSwitch').get(0).checked;
- if (!showAdvanced) {
- $('tr.advanced-setting, div.advanced-setting, table.advanced-setting').each(markHide);
- }
-
- /* storage device */
- if ($('#storageDeviceSelect').val() === 'local-disk') {
- $('#networkServerEntry').parents('tr:eq(0)').each(markHide);
- $('#networkUsernameEntry').parents('tr:eq(0)').each(markHide);
- $('#networkPasswordEntry').parents('tr:eq(0)').each(markHide);
- $('#networkShareNameEntry').parents('tr:eq(0)').each(markHide);
- }
-
- /* auto brightness */
- if ($('#autoBrightnessSwitch').get(0).checked) {
- $('#brightnessSlider').parents('tr:eq(0)').each(markHide);
- }
-
- /* text */
- if ($('#leftTextSelect').val() !== 'custom-text') {
- $('#leftTextEntry').parents('tr:eq(0)').each(markHide);
- }
- if ($('#rightTextSelect').val() !== 'custom-text') {
- $('#rightTextEntry').parents('tr:eq(0)').each(markHide);
- }
-
- /* still images capture mode */
- if ($('#captureModeSelect').val() !== 'interval-snapshots') {
- $('#snapshotIntervalEntry').parents('tr:eq(0)').each(markHide);
- }
-
- /* auto noise level */
- if ($('#autoNoiseDetectSwitch').get(0).checked) {
- $('#noiseLevelSlider').parents('tr:eq(0)').each(markHide);
- }
-
- /* video device switch */
- if (!$('#videoDeviceSwitch').get(0).checked) {
- $('#videoDeviceSwitch').parent().nextAll('div.settings-section-title, table.settings').each(markHide);
- }
-
- /* text overlay switch */
- if (!$('#textOverlaySwitch').get(0).checked) {
- $('#textOverlaySwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
- }
-
- /* video streaming switch */
- if (!$('#videoStreamingSwitch').get(0).checked) {
- $('#videoStreamingSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
- }
-
- /* still images switch */
- if (!$('#stillImagesSwitch').get(0).checked) {
- $('#stillImagesSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
- }
-
- /* motion movies switch */
- if (!$('#motionMoviesSwitch').get(0).checked) {
- $('#motionMoviesSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
- }
-
- /* motion notifications switch */
- if (!$('#motionNotificationsSwitch').get(0).checked) {
- $('#motionNotificationsSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
- }
-
- /* working schedule switch */
- if (!$('#workingScheduleSwitch').get(0).checked) {
- $('#workingScheduleSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
- }
-
- objs.each(function () {
- if (this._hide) {
- $(this).hide(200);
- }
- else {
- $(this).show(200);
- }
- });
-
- /* re-validate all the input validators */
- $('div.settings').find('input.text-validator, input.number-validator, input.time-validator').each(function () {
- this.validate();
- });
-
- /* update all checkboxes and sliders */
- $('div.settings').find('input[type=checkbox], input.range').each(function () {
- this.update();
- });
-
- /* select the first option for the selects with no current selection */
- $('div.settings').find('select').each(function () {
- if (this.selectedIndex === -1) {
- this.selectedIndex = 0;
- }
- });
-}
-
-function configUiValid() {
- var valid = true;
- $('div.settings input, select').each(function () {
- if (this.invalid) {
- valid = false;
- return false;
- }
- });
-
- return valid;
-}
-
-function mainUi2Dict() {
- return {
- 'enabled': $('#motionEyeSwitch')[0].checked,
- 'show_advanced': $('#showAdvancedSwitch')[0].checked,
- 'admin_username': $('#adminUsernameEntry').val(),
- 'admin_password': $('#adminPasswordEntry').val(),
- 'normal_username': $('#normalUsernameEntry').val(),
- 'normal_password': $('#normalPasswordEntry').val()
- };
-}
-
-function dict2MainUi(dict) {
- $('#motionEyeSwitch')[0].checked = dict['enabled'];
- $('#showAdvancedSwitch')[0].checked = dict['show_advanced'];
- $('#adminUsernameEntry').val(dict['admin_username']);
- $('#adminPasswordEntry').val(dict['admin_password']);
- $('#normalUsernameEntry').val(dict['normal_username']);
- $('#normalPasswordEntry').val(dict['normal_password']);
-
- updateConfigUi();
-}
-
-function cameraUi2Dict() {
- return {
- /* video device */
- 'enabled': $('#videoDeviceSwitch')[0].checked,
- 'name': $('#deviceNameEntry').val(),
- 'device': $('#deviceEntry').val(),
- 'light_switch_detect': $('#lightSwitchDetectSwitch')[0].checked,
- 'auto_brightness': $('#autoBrightnessSwitch')[0].checked,
- 'brightness': $('#brightnessSlider').val(),
- 'contrast': $('#contrastSlider').val(),
- 'saturation': $('#saturationSlider').val(),
- 'hue': $('#hueSlider').val(),
- 'resolution': $('#resolutionSelect').val(),
- 'rotation': $('#rotationSelect').val(),
- 'framerate': $('#framerateSlider').val(),
-
- /* file storage */
- 'storage_device': $('#storageDeviceSelect').val(),
- 'network_server': $('#networkServerEntry').val(),
- 'network_share_name': $('#networkShareNameEntry').val(),
- 'network_username': $('#networkUsernameEntry').val(),
- 'network_password': $('#networkPasswordEntry').val(),
- 'root_directory': $('#rootDirectoryEntry').val(),
-
- /* text overlay */
- 'text_overlay': $('#textOverlaySwitch')[0].checked,
- 'left_text': $('#leftTextSelect').val(),
- 'custom_left_text': $('#leftTextEntry').val(),
- 'right_text': $('#rightTextSelect').val(),
- 'custom_right_text': $('#rightTextEntry').val(),
-
- /* video streaming */
- 'video_streaming': $('#videoStreamingSwitch')[0].checked,
- 'streaming_port': $('#streamingPortEntry').val(),
- 'streaming_framerate': $('#streamingFramerateSlider').val(),
- 'streaming_quality': $('#streamingQualitySlider').val(),
- 'streaming_motion': $('#streamingMotion')[0].checked,
-
- /* still images */
- 'still_images': $('#stillImagesSwitch')[0].checked,
- 'image_file_name': $('#imageFileNameEntry').val(),
- 'image_quality': $('#imageQualitySlider').val(),
- 'capture_mode': $('#captureModeSelect').val(),
- 'snapshot_interval': $('#snapshotIntervalEntry').val(),
- 'preserve_images': $('#preserveImagesSelect').val(),
-
- /* motion movies */
- 'motion_movies': $('#motionMoviesSwitch')[0].checked,
- 'movie_file_name': $('#movieFileNameEntry').val(),
- 'movie_quality': $('#movieQualitySlider').val(),
- 'preserve_movies': $('#preserveMoviesSelect').val(),
-
- /* motion detection */
- 'show_frame_changes': $('#showFrameChangesSwitch')[0].checked,
- 'frame_change_threshold': $('#frameChangeThresholdSlider').val(),
- 'auto_noise_detect': $('#autoNoiseDetectSwitch')[0].checked,
- 'noise_level': $('#noiseLevelSlider').val(),
- 'gap': $('#gapEntry').val(),
- 'pre_capture': $('#preCaptureEntry').val(),
- 'post_capture': $('#postCaptureEntry').val(),
-
- /* motion notifications */
- 'motion_notifications': $('#motionNotificationsSwitch')[0].checked,
- 'motion_notifications_emails': $('#emailAddressesEntry').val(),
-
- /* 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(),
- };
-}
-
-function dict2CameraUi(dict) {
- /* video device */
- $('#videoDeviceSwitch')[0].checked = dict['enabled'];
- $('#deviceNameEntry').val(dict['name']);
- $('#deviceEntry').val(dict['device']);
- $('#lightSwitchDetectSwitch')[0].checked = dict['light_switch_detect'];
- $('#autoBrightnessSwitch')[0].checked = dict['auto_brightness'];
- $('#brightnessSlider').val(dict['brightness']);
- $('#contrastSlider').val(dict['contrast']);
- $('#saturationSlider').val(dict['saturation']);
- $('#hueSlider').val(dict['hue']);
- $('#resolutionSelect').val(dict['resolution']);
- $('#rotationSelect').val(dict['rotation']);
- $('#framerateSlider').val(dict['framerate']);
-
- /* file storage */
- $('#storageDeviceSelect').val(dict['storage_device']);
- $('#networkServerEntry').val(dict['network_server']);
- $('#networkShareNameEntry').val(dict['network_share_name']);
- $('#networkUsernameEntry').val(dict['network_username']);
- $('#networkPasswordEntry').val(dict['network_password']);
- $('#rootDirectoryEntry').val(dict['root_directory']);
-
- /* text overlay */
- $('#textOverlaySwitch')[0].checked = dict['text_overlay'];
- $('#leftTextSelect').val(dict['left_text']);
- $('#leftTextEntry').val(dict['custom_left_text']);
- $('#rightTextSelect').val(dict['right_text']);
- $('#rightTextEntry').val(dict['custom_right_text']);
-
- /* video streaming */
- $('#videoStreamingSwitch')[0].checked = dict['video_streaming'];
- $('#streamingPortEntry').val(dict['streaming_port']);
- $('#streamingFramerateSlider').val(dict['streaming_framerate']);
- $('#streamingQualitySlider').val(dict['streaming_quality']);
- $('#streamingMotion')[0].checked = dict['streaming_motion'];
-
- /* still images */
- $('#stillImagesSwitch')[0].checked = dict['still_images'];
- $('#imageFileNameEntry').val(dict['image_file_name']);
- $('#imageQualitySlider').val(dict['image_quality']);
- $('#captureModeSelect').val(dict['capture_mode']);
- $('#snapshotIntervalEntry').val(dict['snapshot_interval']);
- $('#preserveImagesSelect').val(dict['preserve_images']);
-
- /* motion movies */
- $('#motionMoviesSwitch')[0].checked = dict['motion_movies'];
- $('#movieFileNameEntry').val(dict['movie_file_name']);
- $('#movieQualitySlider').val(dict['movie_quality']);
- $('#preserveMoviesSelect').val(dict['preserve_movies']);
-
- /* motion detection */
- $('#showFrameChangesSwitch')[0].checked = dict['show_frame_changes'];
- $('#frameChangeThresholdSlider').val(dict['frame_change_threshold']);
- $('#autoNoiseDetectSwitch')[0].checked = dict['auto_noise_detect'];
- $('#noiseLevelSlider').val(dict['noise_level']);
- $('#gapEntry').val(dict['gap']);
- $('#preCaptureEntry').val(dict['pre_capture']);
- $('#postCaptureEntry').val(dict['post_capture']);
-
- /* motion notifications */
- $('#motionNotificationsSwitch')[0].checked = dict['motion_notifications'];
- $('#emailAddressesEntry').val(dict['motion_notifications_emails']);
-
- /* 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']);
-
- updateConfigUi();
-}
-
-
- /* apply button */
-
-function showApply() {
- if (!$('div.settings-container').is(':visible')) {
- return; /* settings panel is not open */
- }
-
- var applyButton = $('#applyButton');
-
- applyButton.html('Apply');
- applyButton.css('display', 'inline-block');
- applyButton.animate({'opacity': '1'}, 100);
- applyButton.removeClass('progress');
-}
-
-function showProgress() {
- if (!$('div.settings-container').is(':visible')) {
- return; /* settings panel is not open */
- }
-
- var applyButton = $('#applyButton');
-
- if (applyButton.hasClass('progress')) {
- return; /* progress already visible */
- }
-
- applyButton.html('<img class="apply-progress" src="' + staticUrl + 'img/progress.gif">');
- applyButton.css('display', 'inline-block');
- applyButton.animate({'opacity': '1'}, 100);
- applyButton.addClass('progress');
-}
-
-function hideApply() {
- if (!$('div.settings-container').is(':visible')) {
- return; /* settings panel is not open */
- }
-
- var applyButton = $('#applyButton');
-
- applyButton.animate({'opacity': '0'}, 200, function () {
- applyButton.removeClass('progress');
- applyButton.css('display', 'none');
- });
-}
-
-function isProgress() {
- var applyButton = $('#applyButton');
-
- return applyButton.hasClass('progress');
-}
-
-function isApplyVisible() {
- var applyButton = $('#applyButton');
-
- return applyButton.is(':visible');
-}
-
-function doApply() {
- var finishedCount = 0;
- var configs = [];
-
- function testReady() {
- if (finishedCount >= configs.length) {
- if (Object.keys(pushConfigs).length === 0) {
- hideApply();
- }
- else {
- showApply();
- }
- }
- }
-
- for (var key in pushConfigs) {
- if (pushConfigs.hasOwnProperty(key)) {
- configs.push({key: key, config: pushConfigs[key]});
- }
- }
-
- if (configs.length === 0) {
- return;
- }
-
- showProgress();
-
- for (var i = 0; i < configs.length; i++) {
- var config = configs[i];
- ajax('POST', '/config/' + config.key + '/set/', config.config, function () {
- finishedCount++;
- testReady();
- });
-
- /* update the camera name in the device select */
- if (config.key !== 'main') {
- $('#videoDeviceSelect').find('option[value=' + config.key + ']').html(config.config.name);
- }
- }
-
- pushConfigs = {};
-}
-
-function fetchCurrentConfig() {
- /* fetch the main configuration */
- ajax('GET', '/config/main/get/', null, function (data) {
- dict2MainUi(data);
- });
-
- /* fetch the camera list */
- ajax('GET', '/config/list/', null, function (data) {
- var i, cameras = data.cameras;
- var videoDeviceSelect = $('#videoDeviceSelect');
- videoDeviceSelect.html('');
- for (i = 0; i < cameras.length; i++) {
- var camera = cameras[i];
- videoDeviceSelect.append('<option value="' + camera['@id'] + '">' + camera['@name'] + '</option>');
- }
-
- if (cameras.length) {
- videoDeviceSelect[0].selectedIndex = 0;
- fetchCameraConfig();
- }
- });
-}
-
-function fetchCameraConfig() {
- var cameraId = $('#videoDeviceSelect').val();
- if (cameraId != null) {
- ajax('GET', '/config/' + cameraId + '/get/', null, function (data) {
- dict2CameraUi(data);
- });
- }
- else {
- dict2CameraUi({});
- }
-}
-
-function pushMainConfig() {
- var mainConfig = mainUi2Dict();
-
- pushConfigs['main'] = mainConfig;
- if (!isApplyVisible()) {
- showApply();
- }
-}
-
-function pushCameraConfig() {
- var cameraConfig = cameraUi2Dict();
- var cameraId = $('#videoDeviceSelect').val();
-
- pushConfigs[cameraId] = cameraConfig;
- if (!isApplyVisible()) {
- showApply();
- }
-}
-
-$(document).ready(function () {
- /* open/close settings */
- $('img.settings-button').click(function () {
- if ($('div.settings').hasClass('open')) {
- $('div.settings').removeClass('open');
- $('div.page-container').removeClass('stretched');
- $('div.settings-top-bar').removeClass('open');
- }
- else {
- $('div.settings').addClass('open');
- $('div.page-container').addClass('stretched');
- $('div.settings-top-bar').addClass('open');
-
- updateConfigUi();
- }
- });
-
- /* prevent scroll events on settings div from propagating */
- $('div.settings').mousewheel(function (e, d) {
- var t = $(this);
- if (d > 0 && t.scrollTop() === 0) {
- e.preventDefault();
- }
- else if (d < 0 && (t.scrollTop() === t.get(0).scrollHeight - t.innerHeight())) {
- e.preventDefault();
- }
- });
-
- initUI();
- fetchCurrentConfig();
-});
--- /dev/null
+
+var pushConfigs = {};
+
+
+ /* utils */
+
+function ajax(method, url, data, callback) {
+ var options = {
+ type: method,
+ url: url,
+ data: data,
+ cache: false,
+ success: callback,
+ error: function (request, options, error) {
+ alert('Request failed with code: ' + request.status);
+ if (callback) {
+ callback();
+ }
+ }
+ };
+
+ if (data && typeof data === 'object') {
+ options['contentType'] = 'application/json';
+ options['data'] = JSON.stringify(options['data']);
+ }
+
+ $.ajax(options);
+}
+
+Object.keys = Object.keys || (function () {
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
+ var hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString');
+ var dontEnums = [
+ 'toString',
+ 'toLocaleString',
+ 'valueOf',
+ 'hasOwnProperty',
+ 'isPrototypeOf',
+ 'propertyIsEnumerable',
+ 'constructor'
+ ];
+ var dontEnumsLength = dontEnums.length;
+
+ return function (obj) {
+ if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) {
+ return [];
+ }
+
+ var result = [];
+ for (var prop in obj) {
+ if (hasOwnProperty.call(obj, prop)) {
+ result.push(prop);
+ }
+ }
+
+ if (hasDontEnumBug) {
+ for (var i = 0; i < dontEnumsLength; i++) {
+ if (hasOwnProperty.call(obj, dontEnums[i])) {
+ result.push(dontEnums[i]);
+ }
+ }
+ }
+
+ return result;
+ };
+})();
+
+
+ /* UI */
+
+function initUI() {
+ /* checkboxes */
+ $('input[type=checkbox].styled').each(function () {
+ makeCheckBox($(this));
+ });
+
+ /* sliders */
+ makeSlider($('#brightnessSlider'), 0, 100, 0, null, 5, 0, '%');
+ makeSlider($('#contrastSlider'), 0, 100, 0, null, 5, 0, '%');
+ makeSlider($('#saturationSlider'), 0, 100, 0, null, 5, 0, '%');
+ makeSlider($('#hueSlider'), 0, 100, 0, null, 5, 0, '%');
+ makeSlider($('#framerateSlider'), 1, 30, 0, [
+ {value: 1, label: '1'},
+ {value: 5, label: '5'},
+ {value: 10, label: '10'},
+ {value: 15, label: '15'},
+ {value: 20, label: '20'},
+ {value: 25, label: '25'},
+ {value: 30, label: '30'}
+ ], null, 0);
+ makeSlider($('#streamingFramerateSlider'), 1, 30, 0, [
+ {value: 1, label: '1'},
+ {value: 5, label: '5'},
+ {value: 10, label: '10'},
+ {value: 15, label: '15'},
+ {value: 20, label: '20'},
+ {value: 25, label: '25'},
+ {value: 30, label: '30'}
+ ], null, 0);
+ makeSlider($('#streamingQualitySlider'), 0, 100, 0, null, 5, 0, '%');
+ makeSlider($('#imageQualitySlider'), 0, 100, 0, null, 5, 0, '%');
+ makeSlider($('#movieQualitySlider'), 0, 100, 0, null, 5, 0, '%');
+ makeSlider($('#frameChangeThresholdSlider'), 0, 10000, 0, null, 3, 0, 'px');
+ makeSlider($('#noiseLevelSlider'), 0, 100, 0, null, 5, 0, '%');
+
+ /* text validators */
+ makeTextValidator($('#adminUsernameEntry'), true);
+ makeTextValidator($('#adminPasswordEntry'), true);
+ makeTextValidator($('#normalUsernameEntry'), true);
+ makeTextValidator($('#normalPasswordEntry'), true);
+ makeTextValidator($('#deviceNameEntry'), true);
+ makeTextValidator($('#networkServerEntry'), true);
+ makeTextValidator($('#networkShareNameEntry'), true);
+ makeTextValidator($('#networkUsernameEntry'), false);
+ makeTextValidator($('#networkPasswordEntry'), false);
+ makeTextValidator($('#rootDirectoryEntry'), true);
+ makeTextValidator($('#leftTextEntry'), true);
+ makeTextValidator($('#rightTextEntry'), true);
+ makeTextValidator($('#imageFileNameEntry'), true);
+ makeTextValidator($('#movieFileNameEntry'), true);
+ makeTextValidator($('#emailAddressesEntry'), true);
+
+ /* number validators */
+ makeNumberValidator($('#streamingPortEntry'), 1024, 65535, false, false, true);
+ makeNumberValidator($('#snapshotIntervalEntry'), 1, 86400, false, false, true);
+ makeNumberValidator($('#gapEntry'), 1, 86400, false, false, true);
+ makeNumberValidator($('#preCaptureEntry'), 0, 100, false, false, true);
+ makeNumberValidator($('#postCaptureEntry'), 0, 100, 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'));
+
+ /* ui elements that enable/disable other ui elements */
+ $('#motionEyeSwitch').change(updateConfigUi);
+ $('#showAdvancedSwitch').change(updateConfigUi);
+ $('#storageDeviceSelect').change(updateConfigUi);
+ $('#autoBrightnessSwitch').change(updateConfigUi);
+ $('#leftTextSelect').change(updateConfigUi);
+ $('#rightTextSelect').change(updateConfigUi);
+ $('#captureModeSelect').change(updateConfigUi);
+ $('#autoNoiseDetectSwitch').change(updateConfigUi);
+ $('#videoDeviceSwitch').change(updateConfigUi);
+ $('#textOverlaySwitch').change(updateConfigUi);
+ $('#videoStreamingSwitch').change(updateConfigUi);
+ $('#stillImagesSwitch').change(updateConfigUi);
+ $('#motionMoviesSwitch').change(updateConfigUi);
+ $('#motionNotificationsSwitch').change(updateConfigUi);
+ $('#workingScheduleSwitch').change(updateConfigUi);
+
+ /* fetch & push handlers */
+ $('#videoDeviceSelect').change(fetchCameraConfig);
+ $('input.general').change(pushMainConfig);
+ $('input.device, select.device, ' +
+ 'input.storage, select.storage, ' +
+ 'input.text-overlay, select.text-overlay, ' +
+ 'input.streaming, select.streaming, ' +
+ 'input.still-images, select.still-images, ' +
+ 'input.motion-movies, select.motion-movies, ' +
+ 'input.motion-detection, select.motion-detection, ' +
+ 'input.notifications, select.notifications, ' +
+ 'input.working-schedule, select.working-schedule').change(pushCameraConfig);
+
+ /* apply button */
+ $('#applyButton').click(function () {
+ if ($(this).hasClass('progress')) {
+ return; /* in progress */
+ }
+
+ doApply();
+ });
+}
+
+function updateConfigUi() {
+ var objs = $('tr.settings-item, div.advanced-setting, table.advanced-setting, div.settings-section-title, table.settings');
+
+ function markHide() {
+ this._hide = true;
+ }
+
+ function unmarkHide() {
+ this._hide = false;
+ }
+
+ objs.each(unmarkHide);
+
+ /* general enable switch */
+ var motionEyeEnabled = $('#motionEyeSwitch').get(0).checked;
+ if (!motionEyeEnabled) {
+ objs.not($('#motionEyeSwitch').parents('div').get(0)).each(markHide);
+ }
+
+ /* advanced settings */
+ var showAdvanced = $('#showAdvancedSwitch').get(0).checked;
+ if (!showAdvanced) {
+ $('tr.advanced-setting, div.advanced-setting, table.advanced-setting').each(markHide);
+ }
+
+ /* storage device */
+ if ($('#storageDeviceSelect').val() === 'local-disk') {
+ $('#networkServerEntry').parents('tr:eq(0)').each(markHide);
+ $('#networkUsernameEntry').parents('tr:eq(0)').each(markHide);
+ $('#networkPasswordEntry').parents('tr:eq(0)').each(markHide);
+ $('#networkShareNameEntry').parents('tr:eq(0)').each(markHide);
+ }
+
+ /* auto brightness */
+ if ($('#autoBrightnessSwitch').get(0).checked) {
+ $('#brightnessSlider').parents('tr:eq(0)').each(markHide);
+ }
+
+ /* text */
+ if ($('#leftTextSelect').val() !== 'custom-text') {
+ $('#leftTextEntry').parents('tr:eq(0)').each(markHide);
+ }
+ if ($('#rightTextSelect').val() !== 'custom-text') {
+ $('#rightTextEntry').parents('tr:eq(0)').each(markHide);
+ }
+
+ /* still images capture mode */
+ if ($('#captureModeSelect').val() !== 'interval-snapshots') {
+ $('#snapshotIntervalEntry').parents('tr:eq(0)').each(markHide);
+ }
+
+ /* auto noise level */
+ if ($('#autoNoiseDetectSwitch').get(0).checked) {
+ $('#noiseLevelSlider').parents('tr:eq(0)').each(markHide);
+ }
+
+ /* video device switch */
+ if (!$('#videoDeviceSwitch').get(0).checked) {
+ $('#videoDeviceSwitch').parent().nextAll('div.settings-section-title, table.settings').each(markHide);
+ }
+
+ /* text overlay switch */
+ if (!$('#textOverlaySwitch').get(0).checked) {
+ $('#textOverlaySwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
+ }
+
+ /* video streaming switch */
+ if (!$('#videoStreamingSwitch').get(0).checked) {
+ $('#videoStreamingSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
+ }
+
+ /* still images switch */
+ if (!$('#stillImagesSwitch').get(0).checked) {
+ $('#stillImagesSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
+ }
+
+ /* motion movies switch */
+ if (!$('#motionMoviesSwitch').get(0).checked) {
+ $('#motionMoviesSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
+ }
+
+ /* motion notifications switch */
+ if (!$('#motionNotificationsSwitch').get(0).checked) {
+ $('#motionNotificationsSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
+ }
+
+ /* working schedule switch */
+ if (!$('#workingScheduleSwitch').get(0).checked) {
+ $('#workingScheduleSwitch').parent().next('table.settings').find('tr.settings-item').each(markHide);
+ }
+
+ objs.each(function () {
+ if (this._hide) {
+ $(this).hide(200);
+ }
+ else {
+ $(this).show(200);
+ }
+ });
+
+ /* re-validate all the input validators */
+ $('div.settings').find('input.text-validator, input.number-validator, input.time-validator').each(function () {
+ this.validate();
+ });
+
+ /* update all checkboxes and sliders */
+ $('div.settings').find('input[type=checkbox], input.range').each(function () {
+ this.update();
+ });
+
+ /* select the first option for the selects with no current selection */
+ $('div.settings').find('select').each(function () {
+ if (this.selectedIndex === -1) {
+ this.selectedIndex = 0;
+ }
+ });
+}
+
+function configUiValid() {
+ var valid = true;
+ $('div.settings input, select').each(function () {
+ if (this.invalid) {
+ valid = false;
+ return false;
+ }
+ });
+
+ return valid;
+}
+
+function mainUi2Dict() {
+ return {
+ 'enabled': $('#motionEyeSwitch')[0].checked,
+ 'show_advanced': $('#showAdvancedSwitch')[0].checked,
+ 'admin_username': $('#adminUsernameEntry').val(),
+ 'admin_password': $('#adminPasswordEntry').val(),
+ 'normal_username': $('#normalUsernameEntry').val(),
+ 'normal_password': $('#normalPasswordEntry').val()
+ };
+}
+
+function dict2MainUi(dict) {
+ $('#motionEyeSwitch')[0].checked = dict['enabled'];
+ $('#showAdvancedSwitch')[0].checked = dict['show_advanced'];
+ $('#adminUsernameEntry').val(dict['admin_username']);
+ $('#adminPasswordEntry').val(dict['admin_password']);
+ $('#normalUsernameEntry').val(dict['normal_username']);
+ $('#normalPasswordEntry').val(dict['normal_password']);
+
+ updateConfigUi();
+}
+
+function cameraUi2Dict() {
+ return {
+ /* video device */
+ 'enabled': $('#videoDeviceSwitch')[0].checked,
+ 'name': $('#deviceNameEntry').val(),
+ 'device': $('#deviceEntry').val(),
+ 'light_switch_detect': $('#lightSwitchDetectSwitch')[0].checked,
+ 'auto_brightness': $('#autoBrightnessSwitch')[0].checked,
+ 'brightness': $('#brightnessSlider').val(),
+ 'contrast': $('#contrastSlider').val(),
+ 'saturation': $('#saturationSlider').val(),
+ 'hue': $('#hueSlider').val(),
+ 'resolution': $('#resolutionSelect').val(),
+ 'rotation': $('#rotationSelect').val(),
+ 'framerate': $('#framerateSlider').val(),
+
+ /* file storage */
+ 'storage_device': $('#storageDeviceSelect').val(),
+ 'network_server': $('#networkServerEntry').val(),
+ 'network_share_name': $('#networkShareNameEntry').val(),
+ 'network_username': $('#networkUsernameEntry').val(),
+ 'network_password': $('#networkPasswordEntry').val(),
+ 'root_directory': $('#rootDirectoryEntry').val(),
+
+ /* text overlay */
+ 'text_overlay': $('#textOverlaySwitch')[0].checked,
+ 'left_text': $('#leftTextSelect').val(),
+ 'custom_left_text': $('#leftTextEntry').val(),
+ 'right_text': $('#rightTextSelect').val(),
+ 'custom_right_text': $('#rightTextEntry').val(),
+
+ /* video streaming */
+ 'video_streaming': $('#videoStreamingSwitch')[0].checked,
+ 'streaming_port': $('#streamingPortEntry').val(),
+ 'streaming_framerate': $('#streamingFramerateSlider').val(),
+ 'streaming_quality': $('#streamingQualitySlider').val(),
+ 'streaming_motion': $('#streamingMotion')[0].checked,
+
+ /* still images */
+ 'still_images': $('#stillImagesSwitch')[0].checked,
+ 'image_file_name': $('#imageFileNameEntry').val(),
+ 'image_quality': $('#imageQualitySlider').val(),
+ 'capture_mode': $('#captureModeSelect').val(),
+ 'snapshot_interval': $('#snapshotIntervalEntry').val(),
+ 'preserve_images': $('#preserveImagesSelect').val(),
+
+ /* motion movies */
+ 'motion_movies': $('#motionMoviesSwitch')[0].checked,
+ 'movie_file_name': $('#movieFileNameEntry').val(),
+ 'movie_quality': $('#movieQualitySlider').val(),
+ 'preserve_movies': $('#preserveMoviesSelect').val(),
+
+ /* motion detection */
+ 'show_frame_changes': $('#showFrameChangesSwitch')[0].checked,
+ 'frame_change_threshold': $('#frameChangeThresholdSlider').val(),
+ 'auto_noise_detect': $('#autoNoiseDetectSwitch')[0].checked,
+ 'noise_level': $('#noiseLevelSlider').val(),
+ 'gap': $('#gapEntry').val(),
+ 'pre_capture': $('#preCaptureEntry').val(),
+ 'post_capture': $('#postCaptureEntry').val(),
+
+ /* motion notifications */
+ 'motion_notifications': $('#motionNotificationsSwitch')[0].checked,
+ 'motion_notifications_emails': $('#emailAddressesEntry').val(),
+
+ /* 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(),
+ };
+}
+
+function dict2CameraUi(dict) {
+ /* video device */
+ $('#videoDeviceSwitch')[0].checked = dict['enabled'];
+ $('#deviceNameEntry').val(dict['name']);
+ $('#deviceEntry').val(dict['device']);
+ $('#lightSwitchDetectSwitch')[0].checked = dict['light_switch_detect'];
+ $('#autoBrightnessSwitch')[0].checked = dict['auto_brightness'];
+ $('#brightnessSlider').val(dict['brightness']);
+ $('#contrastSlider').val(dict['contrast']);
+ $('#saturationSlider').val(dict['saturation']);
+ $('#hueSlider').val(dict['hue']);
+ $('#resolutionSelect').val(dict['resolution']);
+ $('#rotationSelect').val(dict['rotation']);
+ $('#framerateSlider').val(dict['framerate']);
+
+ /* file storage */
+ $('#storageDeviceSelect').val(dict['storage_device']);
+ $('#networkServerEntry').val(dict['network_server']);
+ $('#networkShareNameEntry').val(dict['network_share_name']);
+ $('#networkUsernameEntry').val(dict['network_username']);
+ $('#networkPasswordEntry').val(dict['network_password']);
+ $('#rootDirectoryEntry').val(dict['root_directory']);
+
+ /* text overlay */
+ $('#textOverlaySwitch')[0].checked = dict['text_overlay'];
+ $('#leftTextSelect').val(dict['left_text']);
+ $('#leftTextEntry').val(dict['custom_left_text']);
+ $('#rightTextSelect').val(dict['right_text']);
+ $('#rightTextEntry').val(dict['custom_right_text']);
+
+ /* video streaming */
+ $('#videoStreamingSwitch')[0].checked = dict['video_streaming'];
+ $('#streamingPortEntry').val(dict['streaming_port']);
+ $('#streamingFramerateSlider').val(dict['streaming_framerate']);
+ $('#streamingQualitySlider').val(dict['streaming_quality']);
+ $('#streamingMotion')[0].checked = dict['streaming_motion'];
+
+ /* still images */
+ $('#stillImagesSwitch')[0].checked = dict['still_images'];
+ $('#imageFileNameEntry').val(dict['image_file_name']);
+ $('#imageQualitySlider').val(dict['image_quality']);
+ $('#captureModeSelect').val(dict['capture_mode']);
+ $('#snapshotIntervalEntry').val(dict['snapshot_interval']);
+ $('#preserveImagesSelect').val(dict['preserve_images']);
+
+ /* motion movies */
+ $('#motionMoviesSwitch')[0].checked = dict['motion_movies'];
+ $('#movieFileNameEntry').val(dict['movie_file_name']);
+ $('#movieQualitySlider').val(dict['movie_quality']);
+ $('#preserveMoviesSelect').val(dict['preserve_movies']);
+
+ /* motion detection */
+ $('#showFrameChangesSwitch')[0].checked = dict['show_frame_changes'];
+ $('#frameChangeThresholdSlider').val(dict['frame_change_threshold']);
+ $('#autoNoiseDetectSwitch')[0].checked = dict['auto_noise_detect'];
+ $('#noiseLevelSlider').val(dict['noise_level']);
+ $('#gapEntry').val(dict['gap']);
+ $('#preCaptureEntry').val(dict['pre_capture']);
+ $('#postCaptureEntry').val(dict['post_capture']);
+
+ /* motion notifications */
+ $('#motionNotificationsSwitch')[0].checked = dict['motion_notifications'];
+ $('#emailAddressesEntry').val(dict['motion_notifications_emails']);
+
+ /* 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']);
+
+ updateConfigUi();
+}
+
+
+ /* apply button */
+
+function showApply() {
+ if (!$('div.settings-container').is(':visible')) {
+ return; /* settings panel is not open */
+ }
+
+ var applyButton = $('#applyButton');
+
+ applyButton.html('Apply');
+ applyButton.css('display', 'inline-block');
+ applyButton.animate({'opacity': '1'}, 100);
+ applyButton.removeClass('progress');
+}
+
+function showProgress() {
+ if (!$('div.settings-container').is(':visible')) {
+ return; /* settings panel is not open */
+ }
+
+ var applyButton = $('#applyButton');
+
+ if (applyButton.hasClass('progress')) {
+ return; /* progress already visible */
+ }
+
+ applyButton.html('<img class="apply-progress" src="' + staticUrl + 'img/progress.gif">');
+ applyButton.css('display', 'inline-block');
+ applyButton.animate({'opacity': '1'}, 100);
+ applyButton.addClass('progress');
+}
+
+function hideApply() {
+ if (!$('div.settings-container').is(':visible')) {
+ return; /* settings panel is not open */
+ }
+
+ var applyButton = $('#applyButton');
+
+ applyButton.animate({'opacity': '0'}, 200, function () {
+ applyButton.removeClass('progress');
+ applyButton.css('display', 'none');
+ });
+}
+
+function isProgress() {
+ var applyButton = $('#applyButton');
+
+ return applyButton.hasClass('progress');
+}
+
+function isApplyVisible() {
+ var applyButton = $('#applyButton');
+
+ return applyButton.is(':visible');
+}
+
+function doApply() {
+ var finishedCount = 0;
+ var configs = [];
+
+ function testReady() {
+ if (finishedCount >= configs.length) {
+ if (Object.keys(pushConfigs).length === 0) {
+ hideApply();
+ }
+ else {
+ showApply();
+ }
+ }
+ }
+
+ for (var key in pushConfigs) {
+ if (pushConfigs.hasOwnProperty(key)) {
+ configs.push({key: key, config: pushConfigs[key]});
+ }
+ }
+
+ if (configs.length === 0) {
+ return;
+ }
+
+ showProgress();
+
+ for (var i = 0; i < configs.length; i++) {
+ var config = configs[i];
+ ajax('POST', '/config/' + config.key + '/set/', config.config, function () {
+ finishedCount++;
+ testReady();
+ });
+
+ /* update the camera name in the device select */
+ if (config.key !== 'main') {
+ $('#videoDeviceSelect').find('option[value=' + config.key + ']').html(config.config.name);
+ }
+ }
+
+ pushConfigs = {};
+}
+
+function fetchCurrentConfig() {
+ /* fetch the main configuration */
+ ajax('GET', '/config/main/get/', null, function (data) {
+ dict2MainUi(data);
+ });
+
+ /* fetch the camera list */
+ ajax('GET', '/config/list/', null, function (data) {
+ var i, cameras = data.cameras;
+ var videoDeviceSelect = $('#videoDeviceSelect');
+ videoDeviceSelect.html('');
+ for (i = 0; i < cameras.length; i++) {
+ var camera = cameras[i];
+ videoDeviceSelect.append('<option value="' + camera['@id'] + '">' + camera['@name'] + '</option>');
+ }
+
+ if (cameras.length) {
+ videoDeviceSelect[0].selectedIndex = 0;
+ fetchCameraConfig();
+ }
+ });
+}
+
+function fetchCameraConfig() {
+ var cameraId = $('#videoDeviceSelect').val();
+ if (cameraId != null) {
+ ajax('GET', '/config/' + cameraId + '/get/', null, function (data) {
+ dict2CameraUi(data);
+ });
+ }
+ else {
+ dict2CameraUi({});
+ }
+}
+
+function pushMainConfig() {
+ var mainConfig = mainUi2Dict();
+
+ pushConfigs['main'] = mainConfig;
+ if (!isApplyVisible()) {
+ showApply();
+ }
+}
+
+function pushCameraConfig() {
+ var cameraConfig = cameraUi2Dict();
+ var cameraId = $('#videoDeviceSelect').val();
+
+ pushConfigs[cameraId] = cameraConfig;
+ if (!isApplyVisible()) {
+ showApply();
+ }
+}
+
+$(document).ready(function () {
+ /* open/close settings */
+ $('img.settings-button').click(function () {
+ if ($('div.settings').hasClass('open')) {
+ $('div.settings').removeClass('open');
+ $('div.page-container').removeClass('stretched');
+ $('div.settings-top-bar').removeClass('open');
+ }
+ else {
+ $('div.settings').addClass('open');
+ $('div.page-container').addClass('stretched');
+ $('div.settings-top-bar').addClass('open');
+
+ updateConfigUi();
+ }
+ });
+
+ /* prevent scroll events on settings div from propagating */
+ $('div.settings').mousewheel(function (e, d) {
+ var t = $(this);
+ if (d > 0 && t.scrollTop() === 0) {
+ e.preventDefault();
+ }
+ else if (d < 0 && (t.scrollTop() === t.get(0).scrollHeight - t.innerHeight())) {
+ e.preventDefault();
+ }
+ });
+
+ initUI();
+ fetchCurrentConfig();
+});
+++ /dev/null
-{% extends "base.html" %}
-
-{% block style %}
- {{super()}}
- <link rel="stylesheet" type="text/css" href="{{STATIC_URL}}css/ui.css" />
- <link rel="stylesheet" type="text/css" href="{{STATIC_URL}}css/base-site.css" />
-{% endblock %}
-
-{% block script %}
- {{super()}}
- <script type="text/javascript" src="{{STATIC_URL}}js/ui.js"></script>
- <script type="text/javascript" src="{{STATIC_URL}}js/base-site.js"></script>
-{% endblock %}
-
-{% block body %}
- <div class="header">
- <div class="header-container">
- <div class="settings-top-bar">
- <img class="settings-button" src="{{STATIC_URL}}img/settings.png" title="settings">
- <select class="video-device styled" id="videoDeviceSelect"></select>
- <div class="button apply-button" id="applyButton">Apply</div>
- </div>
- <div class="logo">
- <a href="/">
- <span class="logo">motionEye</span>
- <img class="logo" src="{{STATIC_URL}}img/motioneye.png">
- </a>
- </div>
- </div>
- </div>
- <div class="page">
- <div class="settings">
- <div class="settings-container">
- <div class="settings-section-title"><input type="checkbox" class="styled section general" id="motionEyeSwitch">General Settings</div>
- <table class="settings">
- <tr class="settings-item">
- <td class="settings-item-label"><span class="settings-item-label">Show Advanced Settings</span></td>
- <td class="settings-item-value"><input type="checkbox" class="styled general" id="showAdvancedSwitch"></td>
- <td><span class="help-mark" title="enable this to be able to access all the advanced settings">?</span></td>
- </tr>
- <tr class="settings-item">
- <td class="settings-item-label"><span class="settings-item-label">Administrator Username</span></td>
- <td class="settings-item-value"><input type="text" class="styled general" id="adminUsernameEntry"></td>
- <td><span class="help-mark" title="the username supplied to configure motionEye">?</span></td>
- </tr>
- <tr class="settings-item">
- <td class="settings-item-label"><span class="settings-item-label">Administrator Password</span></td>
- <td class="settings-item-value"><input type="password" class="styled general" id="adminPasswordEntry"></td>
- <td><span class="help-mark" title="administrator's password">?</span></td>
- </tr>
- <tr class="settings-item">
- <td class="settings-item-label"><span class="settings-item-label">Surveillance Username</span></td>
- <td class="settings-item-value"><input type="text" class="styled general" id="normalUsernameEntry"></td>
- <td><span class="help-mark" title="the username supplied for video surveillance">?</span></td>
- </tr>
- <tr class="settings-item">
- <td class="settings-item-label"><span class="settings-item-label">Surveillance Password</span></td>
- <td class="settings-item-value"><input type="password" class="styled general" id="normalPasswordEntry"></td>
- <td><span class="help-mark" title="the password for the surveillance user">?</span></td>
- </tr>
- </table>
-
- <div class="settings-section-title"><input type="checkbox" class="styled section device" id="videoDeviceSwitch">Video Device</div>
- <table class="settings">
- <tr class="settings-item">
- <td class="settings-item-label"><span class="settings-item-label">Camera Name</span></td>
- <td class="settings-item-value"><input type="text" class="styled device" id="deviceNameEntry" placeholder="camera name..."></td>
- <td><span class="help-mark" title="an alias for this camera device">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Camera Device</span></td>
- <td class="settings-item-value"><input type="text" class="styled device" id="deviceEntry" disabled="disabled"></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td colspan="100"><div class="settings-item-separator"></div></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Light Switch Detection</span></td>
- <td class="settings-item-value"><input type="checkbox" class="styled device" id="lightSwitchDetectSwitch"></td>
- <td><span class="help-mark" title="enable this if you want sudden changes in light to not be treated as motion">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Automatic Brightness</span></td>
- <td class="settings-item-value"><input type="checkbox" class="styled device" id="autoBrightnessSwitch"></td>
- <td><span class="help-mark" title="enables software automatic brightness (not needed for most cameras)">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Brightness</span></td>
- <td class="settings-item-value"><input type="text" class="range styled device" id="brightnessSlider"></td>
- <td><span class="help-mark" title="sets a desired brightness level for this camera">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Contrast</span></td>
- <td class="settings-item-value"><input type="text" class="range styled device" id="contrastSlider"></td>
- <td><span class="help-mark" title="sets a desired contrast level for this camera">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Saturation</span></td>
- <td class="settings-item-value"><input type="text" class="range styled device" id="saturationSlider"></td>
- <td><span class="help-mark" title="sets a desired saturation (color) level for this camera">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Hue</span></td>
- <td class="settings-item-value"><input type="text" class="range styled device" id="hueSlider"></td>
- <td><span class="help-mark" title="sets a desired hue (color) for this camera">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td colspan="100"><div class="settings-item-separator"></div></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Video Resolution</span></td>
- <td class="settings-item-value">
- <select class="video-resolution styled device" id="resolutionSelect">
- </select>
- </td>
- <td><span class="help-mark" title="the video resolution (larger values yield better quality but require larger storage space and bandwidth)">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Video Rotation</span></td>
- <td class="settings-item-value">
- <select class="video-resolution styled device" id="rotationSelect">
- <option>0°</option>
- <option>90°</option>
- <option>180°</option>
- <option>270°</option>
- </select>
- <td><span class="help-mark" title="use this to rotate the captured image, if your camera is not positioned correctly">?</span></td>
- </td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Frame Rate</span></td>
- <td class="settings-item-value"><input type="text" class="range styled device" id="framerateSlider"></td>
- <td><span class="help-mark" title="sets the number of frames captured by the camera every second (higher values yield smoother videos but require larger storage space and bandwidth)">?</span></td>
- </tr>
- </table>
-
- <div class="settings-section-title advanced-setting">File Storage</div>
- <table class="settings advanced-setting">
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Storage Device</span></td>
- <td class="settings-item-value">
- <select class="styled storage" id="storageDeviceSelect">
- <option value="local-disk">Local Disk</option>
- <option value="network-share">Network Share</option>
- </select>
- </td>
- <td><span class="help-mark" title="indicates the storage device where the image and video files will be saved">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Network Server</span></td>
- <td class="settings-item-value"><input type="text" class="styled storage" id="networkServerEntry"></td>
- <td><span class="help-mark" title="the address of the network server (IP address or hostname)">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Share Name</span></td>
- <td class="settings-item-value"><input type="text" class="styled storage" id="networkShareNameEntry"></td>
- <td><span class="help-mark" title="the name of the network share">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Share Username</span></td>
- <td class="settings-item-value"><input type="text" class="styled storage" id="networkUsernameEntry"></td>
- <td><span class="help-mark" title="the username to be supplied when accessing the network share (leave empty if no username is required)">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Share Password</span></td>
- <td class="settings-item-value"><input type="password" class="styled storage" id="networkPasswordEntry"></td>
- <td><span class="help-mark" title="the password required by the network share (leave empty if no password is required)">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Root Directory</span></td>
- <td class="settings-item-value"><input type="text" class="styled storage" id="rootDirectoryEntry"></td>
- <td><span class="help-mark" title="the root path (on the selected storage device) where the files will be saved">?</span></td>
- </tr>
- </table>
-
- <div class="settings-section-title advanced-setting"><input type="checkbox" class="styled section text-overlay" id="textOverlaySwitch">Text Overlay</div>
- <table class="settings advanced-setting">
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Left Text</span></td>
- <td class="settings-item-value">
- <select class="styled text-overlay" id="leftTextSelect">
- <option value="camera-name">Camera Name</option>
- <option value="timestamp">Timestamp</option>
- <option value="custom-text">Custom Text</option>
- </select>
- </td>
- <td><span class="help-mark" title="sets the text displayed on the movies and images, on the lower left corner">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"></td>
- <td class="settings-item-value"><input type="text" class="styled text-overlay" id="leftTextEntry" placeholder="custom text..."></td>
- <td><span class="help-mark" title="sets a custom left text; the following special tokens are accepted: %Y = year, %m = month, %d = date, %H = hour, %M = minute, %S = second, %T = HH:MM:SS, %q = frame number, \n = new line">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Right Text</span></td>
- <td class="settings-item-value">
- <select class="styled text-overlay" id="rightTextSelect">
- <option value="camera-name">Camera Name</option>
- <option value="timestamp">Timestamp</option>
- <option value="custom-text">Custom Text</option>
- </select>
- </td>
- <td><span class="help-mark" title="sets the text displayed on the movies and images, on the lower right corner">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"></td>
- <td class="settings-item-value"><input type="text" class="styled text-overlay" id="rightTextEntry" placeholder="custom text..."></td>
- <td><span class="help-mark" title="sets a custom right text; the following special tokens are accepted: %Y = year, %m = month, %d = date, %H = hour, %M = minute, %S = second, %T = HH:MM:SS, %q = frame number, \n = new line">?</span></td>
- </tr>
- </table>
-
- <div class="settings-section-title"><input type="checkbox" class="styled section streaming" id="videoStreamingSwitch">Video Streaming</div>
- <table class="settings">
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Streaming Frame Rate</span></td>
- <td class="settings-item-value"><input type="text" class="range styled streaming" id="streamingFramerateSlider"></td>
- <td><span class="help-mark" title="sets the number of frames transmitted every second on the live streaming">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Streaming Quality</span></td>
- <td class="settings-item-value"><input type="text" class="range styled streaming" id="streamingQualitySlider"></td>
- <td><span class="help-mark" title="sets the live streaming quality (higher values yield a better video quality but require more bandwidth)">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Streaming Port</span></td>
- <td class="settings-item-value"><input type="text" class="styled streaming" id="streamingPortEntry"></td>
- <td><span class="help-mark" title="sets the TCP port on which the webcam streaming server listens">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Motion Optimization</span></td>
- <td class="settings-item-value"><input type="checkbox" class="styled streaming" id="streamingMotion"></td>
- <td><span class="help-mark" title="enable this if you want a lower frame rate for the live streaming when no motion is detected">?</span></td>
- </tr>
- </table>
-
- <div class="settings-section-title"><input type="checkbox" class="styled section still-images" id="stillImagesSwitch">Still Images</div>
- <table class="settings">
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Image File Name</span></td>
- <td class="settings-item-value"><input type="text" class="styled still-images" id="imageFileNameEntry" placeholder="file name pattern..."></td>
- <td><span class="help-mark" title="sets the name pattern for the image (JPEG) files; the following special tokens are accepted: %Y = year, %m = month, %d = date, %H = hour, %M = minute, %S = second, %q = frame number, / = subfolder">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Image Quality</span></td>
- <td class="settings-item-value"><input type="text" class="range styled still-images" id="imageQualitySlider"></td>
- <td><span class="help-mark" title="sets the JPEG image quality (higher values yield a better image quality but require more storage space)">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Capture Mode</span></td>
- <td class="settings-item-value">
- <select class="styled still-images" id="captureModeSelect">
- <option value="motion-triggered">Motion Triggered</option>
- <option value="interval-snapshots">Interval Snapshots</option>
- <option value="all-frames">All Frames</option>
- </select>
- </td>
- <td><span class="help-mark" title="sets the image capture mode: Motion Triggered = an image captured whenever motion is detected, Automated Snapshots = an image captured every x seconds, All Frames = saves each frame into an image file">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Snapshot Interval</span></td>
- <td class="settings-item-value"><input type="text" class="styled number still-images" id="snapshotIntervalEntry"><span class="settings-item-unit">seconds</span></td>
- <td><span class="help-mark" title="sets the interval (in seconds) for the automated snapshots">?</span></td>
- </tr>
- <tr class="settings-item">
- <td class="settings-item-label"><span class="settings-item-label">Preserve Images</span></td>
- <td class="settings-item-value">
- <select class="styled still-images" id="preserveImagesSelect">
- <option value="1">For One Day</option>
- <option value="7">For One Week</option>
- <option value="30">For One Month</option>
- <option value="365">For One Year</option>
- <option value="0">Forever</option>
- </select>
- </td>
- <td><span class="help-mark" title="images older than the specified duration are automatically deleted to free storage space">?</span></td>
- </tr>
- </table>
-
- <div class="settings-section-title"><input type="checkbox" class="styled section motion-movies" id="motionMoviesSwitch">Motion Movies</div>
- <table class="settings">
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Movie File Name</span></td>
- <td class="settings-item-value"><input type="text" class="styled motion-movies" id="movieFileNameEntry" placeholder="file name pattern..."></td>
- <td><span class="help-mark" title="sets the name pattern for the movie (MPEG) files; the following special tokens are accepted: %Y = year, %m = month, %d = date, %H = hour, %M = minute, %S = second, %q = frame number, / = subfolder">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Movie Quality</span></td>
- <td class="settings-item-value"><input type="text" class="range styled motion-movies" id="movieQualitySlider"></td>
- <td><span class="help-mark" title="sets the MPEG video quality (higher values yield a better video quality but require more storage space)">?</span></td>
- </tr>
- <tr class="settings-item">
- <td class="settings-item-label"><span class="settings-item-label">Preserve Movies</span></td>
- <td class="settings-item-value">
- <select class="styled motion-movies" id="preserveMoviesSelect">
- <option value="1">For One Day</option>
- <option value="7">For One Week</option>
- <option value="30">For One Month</option>
- <option value="365">For One Year</option>
- <option value="0">Forever</option>
- </select>
- </td>
- <td><span class="help-mark" title="movies older than the specified duration are automatically deleted to free storage space">?</span></td>
- </tr>
- </table>
-
- <div class="settings-section-title advanced-setting">Motion Detection</div>
- <table class="settings advanced-setting">
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Show Frame Changes</span></td>
- <td class="settings-item-value"><input type="checkbox" class="styled motion-detection" id="showFrameChangesSwitch"></td>
- <td><span class="help-mark" title="if this is enabled, frame changes (number of pixels as well as the changed area) are shown on the video; temporarily enable this option to help adjust the motion detection parameters">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Frame Change Threshold</span></td>
- <td class="settings-item-value"><input type="text" class="range styled motion-detection" id="frameChangeThresholdSlider"></td>
- <td><span class="help-mark" title="indicates the minimal number of pixels that must change between to 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-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>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Noise Level</span></td>
- <td class="settings-item-value"><input type="text" class="range styled motion-detection" id="noiseLevelSlider"></td>
- <td><span class="help-mark" title="manually sets the noise level to a fixed value">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td colspan="100"><div class="settings-item-separator"></div></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Motion Gap</span></td>
- <td class="settings-item-value"><input type="text" class="number styled motion-detection" id="gapEntry"><span class="settings-item-unit">seconds</span></td>
- <td><span class="help-mark" title="sets the number of seconds of silence (i.e. no motion) that mark the end of a motion event">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Captured Before</span></td>
- <td class="settings-item-value"><input type="text" class="number styled motion-detection" id="preCaptureEntry"><span class="settings-item-unit">frames</span></td>
- <td><span class="help-mark" title="sets the number of frames to be captured (and included in the movie) before a motion event is detected">?</span></td>
- </tr>
- <tr class="settings-item advanced-setting">
- <td class="settings-item-label"><span class="settings-item-label">Captured After</span></td>
- <td class="settings-item-value"><input type="text" class="number styled motion-detection" id="postCaptureEntry"><span class="settings-item-unit">frames</span></td>
- <td><span class="help-mark" title="sets the number of frames to be captured (and included in the movie) after a motion event is detected">?</span></td>
- </tr>
- </table>
-
- <div class="settings-section-title"><input type="checkbox" class="styled section notifications" id="motionNotificationsSwitch">Motion Notifications</div>
- <table class="settings">
- <tr class="settings-item">
- <td class="settings-item-label"><span class="settings-item-label">Email Addresses</span></td>
- <td class="settings-item-value"><input type="text" class="styled notifications" id="emailAddressesEntry" placeholder="email addresses..."></td>
- <td><span class="help-mark" title="email addresses (separated by comma) that are added here will receive notifications whenever a motion event is detected (leave empty to disable email notifications)">?</span></td>
- </tr>
- </table>
-
- <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">
- </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">
- </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">
- </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">
- </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">
- </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">
- </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">
- </td>
- <td><span class="help-mark" title="sets the working schedule time interval for Sunday">?</span></td>
- </tr>
- </table>
- </div>
- </div>
- <div class="page-container">
- {% block page_content %}{% endblock %}
- </div>
- <div class="footer">
- copyright © Calin Crisan 2013
- </div>
- </div>
-{% endblock %}
-{% extends "base-site.html" %}
-{% import "macros.html" as macros %}
+{% extends "base.html" %}
{% block style %}
{{super()}}
+ <link rel="stylesheet" type="text/css" href="{{STATIC_URL}}css/ui.css" />
<link rel="stylesheet" type="text/css" href="{{STATIC_URL}}css/main.css" />
{% endblock %}
-{% block page_content %}
- <div class="video-list">
- {{macros.video("/static/img/video1.jpg")}}
- {{macros.video("/static/img/video2.jpg")}}
- {{macros.video("/static/img/video1.jpg")}}
- {{macros.video("/static/img/video2.jpg")}}
+{% block script %}
+ {{super()}}
+ <script type="text/javascript" src="{{STATIC_URL}}js/ui.js"></script>
+ <script type="text/javascript" src="{{STATIC_URL}}js/main.js"></script>
+{% endblock %}
+
+{% block body %}
+ <div class="header">
+ <div class="header-container">
+ <div class="settings-top-bar">
+ <img class="settings-button" src="{{STATIC_URL}}img/settings.png" title="settings">
+ <select class="video-device styled" id="videoDeviceSelect"></select>
+ <div class="button apply-button" id="applyButton">Apply</div>
+ </div>
+ <div class="logo">
+ <a href="/">
+ <span class="logo">motionEye</span>
+ <img class="logo" src="{{STATIC_URL}}img/motioneye.png">
+ </a>
+ </div>
+ </div>
+ </div>
+ <div class="page">
+ <div class="settings">
+ <div class="settings-container">
+ <div class="settings-section-title"><input type="checkbox" class="styled section general" id="motionEyeSwitch">General Settings</div>
+ <table class="settings">
+ <tr class="settings-item">
+ <td class="settings-item-label"><span class="settings-item-label">Show Advanced Settings</span></td>
+ <td class="settings-item-value"><input type="checkbox" class="styled general" id="showAdvancedSwitch"></td>
+ <td><span class="help-mark" title="enable this to be able to access all the advanced settings">?</span></td>
+ </tr>
+ <tr class="settings-item">
+ <td class="settings-item-label"><span class="settings-item-label">Administrator Username</span></td>
+ <td class="settings-item-value"><input type="text" class="styled general" id="adminUsernameEntry"></td>
+ <td><span class="help-mark" title="the username supplied to configure motionEye">?</span></td>
+ </tr>
+ <tr class="settings-item">
+ <td class="settings-item-label"><span class="settings-item-label">Administrator Password</span></td>
+ <td class="settings-item-value"><input type="password" class="styled general" id="adminPasswordEntry"></td>
+ <td><span class="help-mark" title="administrator's password">?</span></td>
+ </tr>
+ <tr class="settings-item">
+ <td class="settings-item-label"><span class="settings-item-label">Surveillance Username</span></td>
+ <td class="settings-item-value"><input type="text" class="styled general" id="normalUsernameEntry"></td>
+ <td><span class="help-mark" title="the username supplied for video surveillance">?</span></td>
+ </tr>
+ <tr class="settings-item">
+ <td class="settings-item-label"><span class="settings-item-label">Surveillance Password</span></td>
+ <td class="settings-item-value"><input type="password" class="styled general" id="normalPasswordEntry"></td>
+ <td><span class="help-mark" title="the password for the surveillance user">?</span></td>
+ </tr>
+ </table>
+
+ <div class="settings-section-title"><input type="checkbox" class="styled section device" id="videoDeviceSwitch">Video Device</div>
+ <table class="settings">
+ <tr class="settings-item">
+ <td class="settings-item-label"><span class="settings-item-label">Camera Name</span></td>
+ <td class="settings-item-value"><input type="text" class="styled device" id="deviceNameEntry" placeholder="camera name..."></td>
+ <td><span class="help-mark" title="an alias for this camera device">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Camera Device</span></td>
+ <td class="settings-item-value"><input type="text" class="styled device" id="deviceEntry" disabled="disabled"></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td colspan="100"><div class="settings-item-separator"></div></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Light Switch Detection</span></td>
+ <td class="settings-item-value"><input type="checkbox" class="styled device" id="lightSwitchDetectSwitch"></td>
+ <td><span class="help-mark" title="enable this if you want sudden changes in light to not be treated as motion">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Automatic Brightness</span></td>
+ <td class="settings-item-value"><input type="checkbox" class="styled device" id="autoBrightnessSwitch"></td>
+ <td><span class="help-mark" title="enables software automatic brightness (not needed for most cameras)">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Brightness</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled device" id="brightnessSlider"></td>
+ <td><span class="help-mark" title="sets a desired brightness level for this camera">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Contrast</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled device" id="contrastSlider"></td>
+ <td><span class="help-mark" title="sets a desired contrast level for this camera">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Saturation</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled device" id="saturationSlider"></td>
+ <td><span class="help-mark" title="sets a desired saturation (color) level for this camera">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Hue</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled device" id="hueSlider"></td>
+ <td><span class="help-mark" title="sets a desired hue (color) for this camera">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td colspan="100"><div class="settings-item-separator"></div></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Video Resolution</span></td>
+ <td class="settings-item-value">
+ <select class="video-resolution styled device" id="resolutionSelect">
+ </select>
+ </td>
+ <td><span class="help-mark" title="the video resolution (larger values yield better quality but require larger storage space and bandwidth)">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Video Rotation</span></td>
+ <td class="settings-item-value">
+ <select class="video-resolution styled device" id="rotationSelect">
+ <option>0°</option>
+ <option>90°</option>
+ <option>180°</option>
+ <option>270°</option>
+ </select>
+ <td><span class="help-mark" title="use this to rotate the captured image, if your camera is not positioned correctly">?</span></td>
+ </td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Frame Rate</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled device" id="framerateSlider"></td>
+ <td><span class="help-mark" title="sets the number of frames captured by the camera every second (higher values yield smoother videos but require larger storage space and bandwidth)">?</span></td>
+ </tr>
+ </table>
+
+ <div class="settings-section-title advanced-setting">File Storage</div>
+ <table class="settings advanced-setting">
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Storage Device</span></td>
+ <td class="settings-item-value">
+ <select class="styled storage" id="storageDeviceSelect">
+ <option value="local-disk">Local Disk</option>
+ <option value="network-share">Network Share</option>
+ </select>
+ </td>
+ <td><span class="help-mark" title="indicates the storage device where the image and video files will be saved">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Network Server</span></td>
+ <td class="settings-item-value"><input type="text" class="styled storage" id="networkServerEntry"></td>
+ <td><span class="help-mark" title="the address of the network server (IP address or hostname)">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Share Name</span></td>
+ <td class="settings-item-value"><input type="text" class="styled storage" id="networkShareNameEntry"></td>
+ <td><span class="help-mark" title="the name of the network share">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Share Username</span></td>
+ <td class="settings-item-value"><input type="text" class="styled storage" id="networkUsernameEntry"></td>
+ <td><span class="help-mark" title="the username to be supplied when accessing the network share (leave empty if no username is required)">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Share Password</span></td>
+ <td class="settings-item-value"><input type="password" class="styled storage" id="networkPasswordEntry"></td>
+ <td><span class="help-mark" title="the password required by the network share (leave empty if no password is required)">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Root Directory</span></td>
+ <td class="settings-item-value"><input type="text" class="styled storage" id="rootDirectoryEntry"></td>
+ <td><span class="help-mark" title="the root path (on the selected storage device) where the files will be saved">?</span></td>
+ </tr>
+ </table>
+
+ <div class="settings-section-title advanced-setting"><input type="checkbox" class="styled section text-overlay" id="textOverlaySwitch">Text Overlay</div>
+ <table class="settings advanced-setting">
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Left Text</span></td>
+ <td class="settings-item-value">
+ <select class="styled text-overlay" id="leftTextSelect">
+ <option value="camera-name">Camera Name</option>
+ <option value="timestamp">Timestamp</option>
+ <option value="custom-text">Custom Text</option>
+ </select>
+ </td>
+ <td><span class="help-mark" title="sets the text displayed on the movies and images, on the lower left corner">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"></td>
+ <td class="settings-item-value"><input type="text" class="styled text-overlay" id="leftTextEntry" placeholder="custom text..."></td>
+ <td><span class="help-mark" title="sets a custom left text; the following special tokens are accepted: %Y = year, %m = month, %d = date, %H = hour, %M = minute, %S = second, %T = HH:MM:SS, %q = frame number, \n = new line">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Right Text</span></td>
+ <td class="settings-item-value">
+ <select class="styled text-overlay" id="rightTextSelect">
+ <option value="camera-name">Camera Name</option>
+ <option value="timestamp">Timestamp</option>
+ <option value="custom-text">Custom Text</option>
+ </select>
+ </td>
+ <td><span class="help-mark" title="sets the text displayed on the movies and images, on the lower right corner">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"></td>
+ <td class="settings-item-value"><input type="text" class="styled text-overlay" id="rightTextEntry" placeholder="custom text..."></td>
+ <td><span class="help-mark" title="sets a custom right text; the following special tokens are accepted: %Y = year, %m = month, %d = date, %H = hour, %M = minute, %S = second, %T = HH:MM:SS, %q = frame number, \n = new line">?</span></td>
+ </tr>
+ </table>
+
+ <div class="settings-section-title"><input type="checkbox" class="styled section streaming" id="videoStreamingSwitch">Video Streaming</div>
+ <table class="settings">
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Streaming Frame Rate</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled streaming" id="streamingFramerateSlider"></td>
+ <td><span class="help-mark" title="sets the number of frames transmitted every second on the live streaming">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Streaming Quality</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled streaming" id="streamingQualitySlider"></td>
+ <td><span class="help-mark" title="sets the live streaming quality (higher values yield a better video quality but require more bandwidth)">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Streaming Port</span></td>
+ <td class="settings-item-value"><input type="text" class="styled streaming" id="streamingPortEntry"></td>
+ <td><span class="help-mark" title="sets the TCP port on which the webcam streaming server listens">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Motion Optimization</span></td>
+ <td class="settings-item-value"><input type="checkbox" class="styled streaming" id="streamingMotion"></td>
+ <td><span class="help-mark" title="enable this if you want a lower frame rate for the live streaming when no motion is detected">?</span></td>
+ </tr>
+ </table>
+
+ <div class="settings-section-title"><input type="checkbox" class="styled section still-images" id="stillImagesSwitch">Still Images</div>
+ <table class="settings">
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Image File Name</span></td>
+ <td class="settings-item-value"><input type="text" class="styled still-images" id="imageFileNameEntry" placeholder="file name pattern..."></td>
+ <td><span class="help-mark" title="sets the name pattern for the image (JPEG) files; the following special tokens are accepted: %Y = year, %m = month, %d = date, %H = hour, %M = minute, %S = second, %q = frame number, / = subfolder">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Image Quality</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled still-images" id="imageQualitySlider"></td>
+ <td><span class="help-mark" title="sets the JPEG image quality (higher values yield a better image quality but require more storage space)">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Capture Mode</span></td>
+ <td class="settings-item-value">
+ <select class="styled still-images" id="captureModeSelect">
+ <option value="motion-triggered">Motion Triggered</option>
+ <option value="interval-snapshots">Interval Snapshots</option>
+ <option value="all-frames">All Frames</option>
+ </select>
+ </td>
+ <td><span class="help-mark" title="sets the image capture mode: Motion Triggered = an image captured whenever motion is detected, Automated Snapshots = an image captured every x seconds, All Frames = saves each frame into an image file">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Snapshot Interval</span></td>
+ <td class="settings-item-value"><input type="text" class="styled number still-images" id="snapshotIntervalEntry"><span class="settings-item-unit">seconds</span></td>
+ <td><span class="help-mark" title="sets the interval (in seconds) for the automated snapshots">?</span></td>
+ </tr>
+ <tr class="settings-item">
+ <td class="settings-item-label"><span class="settings-item-label">Preserve Images</span></td>
+ <td class="settings-item-value">
+ <select class="styled still-images" id="preserveImagesSelect">
+ <option value="1">For One Day</option>
+ <option value="7">For One Week</option>
+ <option value="30">For One Month</option>
+ <option value="365">For One Year</option>
+ <option value="0">Forever</option>
+ </select>
+ </td>
+ <td><span class="help-mark" title="images older than the specified duration are automatically deleted to free storage space">?</span></td>
+ </tr>
+ </table>
+
+ <div class="settings-section-title"><input type="checkbox" class="styled section motion-movies" id="motionMoviesSwitch">Motion Movies</div>
+ <table class="settings">
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Movie File Name</span></td>
+ <td class="settings-item-value"><input type="text" class="styled motion-movies" id="movieFileNameEntry" placeholder="file name pattern..."></td>
+ <td><span class="help-mark" title="sets the name pattern for the movie (MPEG) files; the following special tokens are accepted: %Y = year, %m = month, %d = date, %H = hour, %M = minute, %S = second, %q = frame number, / = subfolder">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Movie Quality</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled motion-movies" id="movieQualitySlider"></td>
+ <td><span class="help-mark" title="sets the MPEG video quality (higher values yield a better video quality but require more storage space)">?</span></td>
+ </tr>
+ <tr class="settings-item">
+ <td class="settings-item-label"><span class="settings-item-label">Preserve Movies</span></td>
+ <td class="settings-item-value">
+ <select class="styled motion-movies" id="preserveMoviesSelect">
+ <option value="1">For One Day</option>
+ <option value="7">For One Week</option>
+ <option value="30">For One Month</option>
+ <option value="365">For One Year</option>
+ <option value="0">Forever</option>
+ </select>
+ </td>
+ <td><span class="help-mark" title="movies older than the specified duration are automatically deleted to free storage space">?</span></td>
+ </tr>
+ </table>
+
+ <div class="settings-section-title advanced-setting">Motion Detection</div>
+ <table class="settings advanced-setting">
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Show Frame Changes</span></td>
+ <td class="settings-item-value"><input type="checkbox" class="styled motion-detection" id="showFrameChangesSwitch"></td>
+ <td><span class="help-mark" title="if this is enabled, frame changes (number of pixels as well as the changed area) are shown on the video; temporarily enable this option to help adjust the motion detection parameters">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Frame Change Threshold</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled motion-detection" id="frameChangeThresholdSlider"></td>
+ <td><span class="help-mark" title="indicates the minimal number of pixels that must change between to 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-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>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Noise Level</span></td>
+ <td class="settings-item-value"><input type="text" class="range styled motion-detection" id="noiseLevelSlider"></td>
+ <td><span class="help-mark" title="manually sets the noise level to a fixed value">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td colspan="100"><div class="settings-item-separator"></div></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Motion Gap</span></td>
+ <td class="settings-item-value"><input type="text" class="number styled motion-detection" id="gapEntry"><span class="settings-item-unit">seconds</span></td>
+ <td><span class="help-mark" title="sets the number of seconds of silence (i.e. no motion) that mark the end of a motion event">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Captured Before</span></td>
+ <td class="settings-item-value"><input type="text" class="number styled motion-detection" id="preCaptureEntry"><span class="settings-item-unit">frames</span></td>
+ <td><span class="help-mark" title="sets the number of frames to be captured (and included in the movie) before a motion event is detected">?</span></td>
+ </tr>
+ <tr class="settings-item advanced-setting">
+ <td class="settings-item-label"><span class="settings-item-label">Captured After</span></td>
+ <td class="settings-item-value"><input type="text" class="number styled motion-detection" id="postCaptureEntry"><span class="settings-item-unit">frames</span></td>
+ <td><span class="help-mark" title="sets the number of frames to be captured (and included in the movie) after a motion event is detected">?</span></td>
+ </tr>
+ </table>
+
+ <div class="settings-section-title"><input type="checkbox" class="styled section notifications" id="motionNotificationsSwitch">Motion Notifications</div>
+ <table class="settings">
+ <tr class="settings-item">
+ <td class="settings-item-label"><span class="settings-item-label">Email Addresses</span></td>
+ <td class="settings-item-value"><input type="text" class="styled notifications" id="emailAddressesEntry" placeholder="email addresses..."></td>
+ <td><span class="help-mark" title="email addresses (separated by comma) that are added here will receive notifications whenever a motion event is detected (leave empty to disable email notifications)">?</span></td>
+ </tr>
+ </table>
+
+ <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">
+ </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">
+ </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">
+ </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">
+ </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">
+ </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">
+ </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">
+ </td>
+ <td><span class="help-mark" title="sets the working schedule time interval for Sunday">?</span></td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ <div class="page-container">
+ {% block page_content %}{% endblock %}
+ </div>
+ <div class="footer">
+ copyright © Calin Crisan 2013
+ </div>
</div>
{% endblock %}