]> www.vanbest.org Git - motioneye-debian/commitdiff
added shut down and reboot buttons
authorCalin Crisan <ccrisan@gmail.com>
Wed, 24 Sep 2014 14:28:16 +0000 (17:28 +0300)
committerCalin Crisan <ccrisan@gmail.com>
Wed, 24 Sep 2014 14:30:27 +0000 (17:30 +0300)
settings_default.py
src/handlers.py
src/powerctl.py [new file with mode: 0644]
src/server.py
static/css/main.css
static/js/main.js
templates/main.html

index b9990d64608678682d68d8a19a2fe690d4159c49..c2d34fd8c555a681d06e572defd5761d33d0c2e1 100644 (file)
@@ -68,7 +68,7 @@ WPA_SUPPLICANT_CONF = None
 # path to a localtime file if time zone settings UI is desired
 LOCAL_TIME_FILE = None
 
-# enables rebooting after changing system settings (such as wifi settings or system updates)
+# enables shutdown and rebooting after changing system settings (such as wifi settings or system updates)
 ENABLE_REBOOT = False
 
 # the timeout in seconds to use when talking to a SMTP server
index 225ae1b45aef737c1964a5a49edb7a0b969fbcc1..f01f2532cad63742f5a0f44bc31c8ab18ca7d257 100644 (file)
@@ -28,6 +28,7 @@ from tornado.ioloop import IOLoop
 import config
 import mediafiles
 import motionctl
+import powerctl
 import remote
 import settings
 import smbctl
@@ -155,6 +156,7 @@ class MainHandler(BaseHandler):
 
         self.render('main.html',
                 wpa_supplicant=settings.WPA_SUPPLICANT_CONF,
+                enable_reboot=settings.ENABLE_REBOOT,
                 timezones=timezones,
                 hostname=socket.gethostname())
 
@@ -949,6 +951,16 @@ class UpdateHandler(BaseHandler):
         self.finish_json(result)
 
 
+class PowerHandler(BaseHandler):
+    @BaseHandler.auth(admin=True)
+    def post(self, op):
+        if op == 'shutdown':
+            powerctl.shut_down()
+            
+        elif op == 'reboot':
+            powerctl.reboot()
+
+
 class VersionHandler(BaseHandler):
     def get(self):
         self.render('version.html',
diff --git a/src/powerctl.py b/src/powerctl.py
new file mode 100644 (file)
index 0000000..3b82ab7
--- /dev/null
@@ -0,0 +1,78 @@
+
+# Copyright (c) 2013 Calin Crisan
+# This file is part of motionEye.
+#
+# motionEye is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>. 
+
+import logging
+import os
+import subprocess
+
+
+def _find_prog(prog):
+    try:
+        return subprocess.check_output('which %s' % prog, shell=True).strip()
+    
+    except subprocess.CalledProcessError: # not found
+        return None
+
+
+def _exec_prog(prog):
+    logging.info('executing "%s"' % prog)
+    
+    return os.system(prog) == 0
+
+
+def shut_down():
+    logging.info('shutting down')
+    
+    prog = _find_prog('poweroff')
+    if prog:
+        return _exec_prog(prog)
+    
+    prog = _find_prog('shutdown')
+    if prog:
+        return _exec_prog(prog + ' -h now')
+    
+    prog = _find_prog('systemctl')
+    if prog:
+        return _exec_prog(prog + ' poweroff')
+    
+    prog = _find_prog('init')
+    if prog:
+        return _exec_prog(prog + ' 0')
+    
+    return False
+
+
+def reboot():
+    logging.info('rebooting')
+    
+    prog = _find_prog('reboot')
+    if prog:
+        return _exec_prog(prog)
+    
+    prog = _find_prog('shutdown')
+    if prog:
+        return _exec_prog(prog + ' -r now')
+    
+    prog = _find_prog('systemctl')
+    if prog:
+        return _exec_prog(prog + ' reboot')
+    
+    prog = _find_prog('init')
+    if prog:
+        return _exec_prog(prog + ' 6')
+    
+    return False
index 209c0a102bd3815cc18bc95d8917e4278bfd3451..ec35fbbeefbdadbe1d6c62ff32abdb01a010e30d 100644 (file)
@@ -49,6 +49,7 @@ application = Application(
         (r'^/movie/(?P<camera_id>\d+)/(?P<op>list)/?$', handlers.MovieHandler),
         (r'^/movie/(?P<camera_id>\d+)/(?P<op>download|preview)/(?P<filename>.+)/?$', handlers.MovieHandler),
         (r'^/update/?$', handlers.UpdateHandler),
+        (r'^/power/(?P<op>shutdown|reboot)/?$', handlers.PowerHandler),
         (r'^/version/?$', handlers.VersionHandler),
         (r'^.*$', handlers.NotFoundHandler),
     ],
index 33eff945d1c198f4f943d6767fc403ec47edcb4d..abe2a14e96af2a0001868a677ae4e8043d6f0c02 100644 (file)
@@ -338,26 +338,57 @@ img.apply-progress {
     margin-top: 3px;
 }
 
-div.update-button {
+div.update-button,
+div.shut-down-button,
+div.reboot-button {
     position: relative;
-    width: 4em;
     height: 1.5em;
     line-height: 1.5em;
     text-align: center;
     margin: 2px 0px;
     color: white;
     font-size: 1em;
-    background-color: #317CAD;
     border-radius: 3px;
     transition: all 0.1s linear;
 }
 
+div.update-button {
+    width: 4em;
+    background: #317CAD;
+}
+
+div.shut-down-button {
+    width: 8em;
+    background: #c0392b;
+}
+
+div.reboot-button {
+    width: 8em;
+    background: #c0392b;
+}
+
 div.update-button:HOVER {
-    background-color: #3498db;
+    background: #3498db;
+}
+
+div.shut-down-button:HOVER {
+    background: #D43F2F;
+}
+
+div.reboot-button:HOVER {
+    background: #D43F2F;
 }
 
 div.update-button:ACTIVE {
-    background-color: #317CAD;
+    background: #317CAD;
+}
+
+div.shut-down-button:ACTIVE {
+    background: #B03427;
+}
+
+div.reboot-button:ACTIVE {
+    background: #B03427;
 }
 
 div.settings-top-bar.open #cameraSelect {
index 6370bd836e2c7f25c3437d7813701c1d90286398..950ce126bd853f2ae138994f54686d4626b2f1b7 100644 (file)
@@ -366,6 +366,16 @@ function initUI() {
         doApply();
     });
     
+    /* shut down button */
+    $('#shutDownButton').click(function () {
+        doShutDown();
+    });
+    
+    /* reboot button */
+    $('#rebootButton').click(function () {
+        doReboot();
+    });
+    
     /* whenever the window is resized,
      * if a modal dialog is visible, it should be repositioned */
     $(window).resize(updateModalDialogPosition);
@@ -1213,6 +1223,18 @@ function doApply() {
     });
 }
 
+function doShutDown() {
+    runConfirmDialog('Really shut down?', function () {
+        ajax('POST', '/power/shutdown/');    
+    });
+}
+
+function doReboot() {
+    runConfirmDialog('Really reboot?', function () {
+        ajax('POST', '/power/reboot/');
+    });
+}
+
 function doRemCamera() {
     if (Object.keys(pushConfigs).length) {
         return runAlertDialog('Please apply the modified settings first!');
index 62bce53323aac0c25ed22e577e09cbf28439e63c..021ce8c2c52268f643979cc3b2f8d8ecfc9dfc22 100644 (file)
                         <td class="settings-item-value"><div class="button update-button" id="updateButton">Check</div></td>
                         <td><span class="help-mark" title="checks for new versions and performs updates">?</span></td>
                     </tr>
+                    <tr class="settings-item advanced-setting{% if not enable_reboot %} hidden{% endif %}">
+                        <td class="settings-item-label"><span class="settings-item-label">Power</span></td>
+                        <td class="settings-item-value"><div class="button shut-down-button" id="shutDownButton">Shut Down</div></td>
+                        <td><span class="help-mark" title="shuts down the system">?</span></td>
+                    </tr>
+                    <tr class="settings-item advanced-settingg{% if not enable_reboot %} hidden{% endif %}">
+                        <td class="settings-item-label"></td>
+                        <td class="settings-item-value"><div class="button reboot-button" id="rebootButton">Reboot</div></td>
+                        <td><span class="help-mark" title="reboots the system">?</span></td>
+                    </tr>
                 </table>
                 
                 <div class="settings-section-title advanced-setting{% if not wpa_supplicant %} hidden{% endif %}"><input type="checkbox" class="styled section wifi" id="wifiSwitch">Wireless Network</div>