From 36ff409ff7cad2e38bcff16b13121b5069fb3aa7 Mon Sep 17 00:00:00 2001 From: Calin Crisan Date: Mon, 23 Jun 2014 21:17:24 +0300 Subject: [PATCH] added smbctl --- motioneye.py | 11 ++++ settings_default.py | 3 + src/handlers.py | 2 +- src/smbctl.py | 135 ++++++++++++++++++++++++++++++++++++++++++++ static/css/main.css | 4 +- templates/main.html | 18 +++--- 6 files changed, 161 insertions(+), 12 deletions(-) create mode 100644 src/smbctl.py diff --git a/motioneye.py b/motioneye.py index c5eee78..d42d881 100755 --- a/motioneye.py +++ b/motioneye.py @@ -47,6 +47,7 @@ def _configure_settings(): set_default_setting('LOG_LEVEL', logging.INFO) set_default_setting('LISTEN', '0.0.0.0') set_default_setting('PORT', 8765) + set_default_setting('SYS_SETTINGS', False) set_default_setting('MOTION_CHECK_INTERVAL', 10) set_default_setting('CLEANUP_INTERVAL', 43200) set_default_setting('THUMBNAILER_INTERVAL', 60) @@ -121,6 +122,9 @@ def _configure_settings(): def _test_requirements(): + if settings.SYS_SETTINGS and os.geteuid() != 0: + print('SYS_SETTINGS require root privileges') + return False try: import tornado # @UnusedImport @@ -152,6 +156,9 @@ def _test_requirements(): import v4l2ctl v4lutils = v4l2ctl.find_v4l2_ctl() is not None + import smbctl + mount_cifs = smbctl.find_mount_cifs() is not None + ok = True if not tornado: print('please install tornado (python-tornado)') @@ -177,6 +184,10 @@ def _test_requirements(): print('please install v4l-utils') ok = False + if settings.SYS_SETTINGS and not mount_cifs: + print('please install cifs-utils') + ok = False + return ok diff --git a/settings_default.py b/settings_default.py index c753921..c8e1ce0 100644 --- a/settings_default.py +++ b/settings_default.py @@ -29,6 +29,9 @@ LISTEN = '0.0.0.0' # change the port according to your requirements/restrictions PORT = 8765 +# enable system settings that require root (SMB shares, WiFI setup) +SYS_SETTINGS = False + # interval in seconds at which motionEye checks if motion is running MOTION_CHECK_INTERVAL = 10 diff --git a/src/handlers.py b/src/handlers.py index f454862..ffa4f3b 100644 --- a/src/handlers.py +++ b/src/handlers.py @@ -143,7 +143,7 @@ class NotFoundHandler(BaseHandler): class MainHandler(BaseHandler): @BaseHandler.auth() def get(self): - self.render('main.html') + self.render('main.html', sys_settings=getattr(settings, 'SYS_SETTINGS', False)) class ConfigHandler(BaseHandler): diff --git a/src/smbctl.py b/src/smbctl.py new file mode 100644 index 0000000..166c427 --- /dev/null +++ b/src/smbctl.py @@ -0,0 +1,135 @@ + +# 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 re +import subprocess + + +def find_mount_cifs(): + try: + return subprocess.check_output('which mount.cifs', shell=True).strip() + + except subprocess.CalledProcessError: # not found + return None + + +def _make_mount_point(server, share, username): + server = re.sub('[^a-zA-Z0-9]', '_', server).lower() + share = re.sub('[^a-zA-Z0-9]', '_', share).lower() + + if username: + mount_point = '/media/motioneye_%s_%s_%s' % (server, share, username) + + else: + mount_point = '/media/motioneye_%s_%s' % (server, share) + + logging.debug('making sure mount point "%s" exists' % mount_point) + os.makedirs(mount_point) + + return mount_point + + +def list_mounts(): + logging.debug('listing smb mounts...') + + mounts = [] + with open('/proc/mounts', 'r') as f: + for line in f: + line = line.strip() + if not line: + continue + + parts = line.split() + if len(parts) < 4: + continue + + target = parts[0] + mount_point = parts[1] + fstype = parts[2] + opts = parts[3] + + if fstype != 'cifs': + continue + + match = re.match('//([^/]+)/(.+)', target) + if not match: + continue + + if len(match.groups()) != 2: + continue + + server, share = match.groups() + + match = re.search('username=(\w+)', opts) + if match: + username = match.group(1) + + else: + username = None + + logging.debug('found smb mount "//%s/%s" at "%s"' % (server, share, mount_point)) + + mounts.append({ + 'server': server, + 'share': share, + 'username': username, + 'mount_point': mount_point + }) + + return mounts + + +def is_motioneye_mount(mount_point): + return bool(re.match('^/media/motioneye_\w+$', mount_point)) + + +def mount(server, share, username, password): + mount_point = _make_mount_point(server, share, username) + logging.debug('mounting "//%s/%s" at "%s"' % (server, share, mount_point)) + + if username: + opts = 'username=%s,password=%s' % (username, password) + + else: + opts = 'guest' + + try: + subprocess.check_call('mount.cifs //%s/%s %s -o %s' % (server, share, mount_point, opts), shell=True) + + return mount_point + + except subprocess.CalledProcessError: + logging.error('failed to mount smb share "//%s/%s" at "%s"' % (server, share, mount_point)) + + return False + + +def umount(server, share, username): + mount_point = _make_mount_point(server, share, username) + logging.debug('unmounting "//%s/%s" from "%s"' % (server, share, mount_point)) + + try: + subprocess.check_call('umount %s' % mount_point, shell=True) + + return True + + except subprocess.CalledProcessError: + logging.error('failed to unmount smb share "//%s/%s" from "%s"' % (server, share, mount_point)) + + return False diff --git a/static/css/main.css b/static/css/main.css index d541c61..fd89cf9 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -395,8 +395,8 @@ span.disk-usage-percent { position: relative; } -div.rpi, -tr.rpi { +div.hidden, +tr.hidden { display: none; } diff --git a/templates/main.html b/templates/main.html index 41a5e53..85e2a92 100644 --- a/templates/main.html +++ b/templates/main.html @@ -152,7 +152,7 @@
File Storage
- + - + - + - + - + @@ -396,17 +396,17 @@
Storage Device ?
Network Server ?
Share Name ?
Share Username ?
Share Password ?
-
Motion Notifications
+ - +
-
Working Schedule
- + +