From 1f9594b63c3b6474a0c87208700af194ed5c2388 Mon Sep 17 00:00:00 2001 From: Calin Crisan Date: Wed, 24 Sep 2014 17:28:16 +0300 Subject: [PATCH] added shut down and reboot buttons --- settings_default.py | 2 +- src/handlers.py | 12 +++++++ src/powerctl.py | 78 +++++++++++++++++++++++++++++++++++++++++++++ src/server.py | 1 + static/css/main.css | 41 +++++++++++++++++++++--- static/js/main.js | 22 +++++++++++++ templates/main.html | 10 ++++++ 7 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 src/powerctl.py diff --git a/settings_default.py b/settings_default.py index b9990d6..c2d34fd 100644 --- a/settings_default.py +++ b/settings_default.py @@ -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 diff --git a/src/handlers.py b/src/handlers.py index 225ae1b..f01f253 100644 --- a/src/handlers.py +++ b/src/handlers.py @@ -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 index 0000000..3b82ab7 --- /dev/null +++ b/src/powerctl.py @@ -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 . + +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 diff --git a/src/server.py b/src/server.py index 209c0a1..ec35fbb 100644 --- a/src/server.py +++ b/src/server.py @@ -49,6 +49,7 @@ application = Application( (r'^/movie/(?P\d+)/(?Plist)/?$', handlers.MovieHandler), (r'^/movie/(?P\d+)/(?Pdownload|preview)/(?P.+)/?$', handlers.MovieHandler), (r'^/update/?$', handlers.UpdateHandler), + (r'^/power/(?Pshutdown|reboot)/?$', handlers.PowerHandler), (r'^/version/?$', handlers.VersionHandler), (r'^.*$', handlers.NotFoundHandler), ], diff --git a/static/css/main.css b/static/css/main.css index 33eff94..abe2a14 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -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 { diff --git a/static/js/main.js b/static/js/main.js index 6370bd8..950ce12 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -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!'); diff --git a/templates/main.html b/templates/main.html index 62bce53..021ce8c 100644 --- a/templates/main.html +++ b/templates/main.html @@ -92,6 +92,16 @@
Check
? + + Power +
Shut Down
+ ? + + + +
Reboot
+ ? +
Wireless Network
-- 2.39.5