import collections
import datetime
import errno
+import glob
import logging
import os.path
import re
if len(os.listdir(settings.CONF_PATH)) > 100:
logging.debug('config path "%s" appears to be a system-wide config directory, performing a selective backup' % settings.CONF_PATH)
- cmd = 'cd "%s" && tar zc motion.conf thread-*.conf' % settings.CONF_PATH
+ cmd = ['tar', 'zc', 'motion.conf']
+ cmd += map(os.path.basename, glob.glob(os.path.join(settings.CONF_PATH, 'thread-*.conf')))
try:
- content = subprocess.check_output(cmd, shell=True)
+ content = subprocess.check_output(cmd, cwd=settings.CONF_PATH)
logging.debug('backup file created (%s bytes)' % len(content))
return content
else:
logging.debug('config path "%s" appears to be a motion-specific config directory, performing a full backup' % settings.CONF_PATH)
- cmd = 'cd "%s" && tar zc .' % settings.CONF_PATH
try:
- content = subprocess.check_output(cmd, shell=True)
+ content = subprocess.check_output(['tar', 'zc', '.'], cwd=settings.CONF_PATH)
logging.debug('backup file created (%s bytes)' % len(content))
return content
logging.info('restoring config from backup file')
- cmd = 'tar zxC "%s" || true' % settings.CONF_PATH
+ cmd = ['tar', 'zxC', settings.CONF_PATH]
try:
- p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
msg = p.communicate(content)[0]
if msg:
logging.error('failed to restore configuration: %s' % msg)
def _list_disks_fdisk():
try:
- output = subprocess.check_output('fdisk -l 2>/dev/null', shell=True)
+ output = subprocess.check_output(['fdisk', '-l'], stderr=open('/dev/null', 'w'))
except Exception as e:
logging.error('failed to list disks using "fdisk -l": %s' % e, exc_info=True)
@BaseHandler.auth(admin=True)
def backup(self):
content = config.backup()
+
+ if not content:
+ raise Exception('failed to create backup file')
filename = 'motioneye-config.tar.gz'
self.set_header('Content-Type', 'application/x-compressed')
self.run_command_bg(command)
def run_command_bg(self, command):
- self.p = subprocess.Popen(command, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
+ self.p = subprocess.Popen(command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
self.command = command
self.io_loop = IOLoop.instance()
logging.debug('serving log file "%s" from command "%s"' % (filename, path))
try:
- output = subprocess.check_output(path, shell=True)
-
+ output = subprocess.check_output(path.split())
+
except Exception as e:
output = 'failed to execute command: %s' % e
def find_ffmpeg():
try:
- return subprocess.check_output('which ffmpeg', stderr=open('/dev/null'), shell=True).strip()
+ return subprocess.check_output(['which', 'ffmpeg'], stderr=open('/dev/null', 'w')).strip()
except subprocess.CalledProcessError: # not found
return None
logging.debug('creating movie preview for %(path)s with an offset of %(offs)s seconds...' % {
'path': full_path, 'offs': offs})
- cmd = 'ffmpeg -i "%(path)s" -f mjpeg -vframes 1 -ss %(offs)s -y %(path)s.thumb'
+ cmd = 'ffmpeg -i %(path)s -f mjpeg -vframes 1 -ss %(offs)s -y %(path)s.thumb'
actual_cmd = cmd % {'path': full_path, 'offs': offs}
logging.debug('running command "%s"' % actual_cmd)
try:
- subprocess.check_output(actual_cmd, shell=True, stderr=subprocess.STDOUT)
+ subprocess.check_output(actual_cmd.split(), stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
logging.error('failed to create movie preview for %(path)s: %(msg)s' % {
# try again, this time grabbing the very first frame
try:
- subprocess.check_output(actual_cmd, shell=True, stderr=subprocess.STDOUT)
+ subprocess.check_output(actual_cmd.split(), stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
logging.error('failed to create movie preview for %(path)s: %(msg)s' % {
}
logging.debug('executing "%s"' % cmd)
-
+
_timelapse_process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
_timelapse_process.progress = 0.01 # 1%
else: # autodetect motion binary path
try:
- binary = subprocess.check_output('which motion', stderr=open('/dev/null'), shell=True).strip()
+ binary = subprocess.check_output(['which', 'motion'], stderr=open('/dev/null', 'w')).strip()
except subprocess.CalledProcessError: # not found
return None
def _find_prog(prog):
try:
- return subprocess.check_output('which %s' % prog, shell=True).strip()
+ return subprocess.check_output(['which', prog], stderr=open('/dev/null', 'w')).strip()
except subprocess.CalledProcessError: # not found
return None
def find_mount_cifs():
try:
- return subprocess.check_output('which mount.cifs', shell=True).strip()
+ return subprocess.check_output(['which', 'mount.cifs'], stderr=open('/dev/null', 'w')).strip()
except subprocess.CalledProcessError: # not found
return None
try:
logging.debug('mounting "//%s/%s" at "%s" (sec=%s)' % (server, share, mount_point, sec))
- subprocess.check_call('mount.cifs "//%s/%s" "%s" -o "%s"' % (server, share, mount_point, actual_opts), shell=True)
+ subprocess.check_call(['mount.cifs', '//%s/%s' % (server, share), mount_point, '-o', actual_opts])
break
except subprocess.CalledProcessError:
logging.debug('unmounting "//%s/%s" from "%s"' % (server, share, mount_point))
try:
- subprocess.check_call('umount "%s"' % mount_point, shell=True)
+ subprocess.check_call(['umount', mount_point])
except subprocess.CalledProcessError:
logging.error('failed to unmount smb share "//%s/%s" from "%s"' % (server, share, mount_point))
return None
try:
- output = subprocess.check_output('cd /usr/share/zoneinfo; find * -type f | xargs md5sum', shell=True)
+ output = subprocess.check_output('find * -type f | xargs md5sum', shell=True, cwd='/usr/share/zoneinfo')
except Exception as e:
logging.error('getting md5 of zoneinfo files failed: %s' % e)
import fcntl
import logging
import os.path
+import pipes
import re
import stat
import subprocess
def find_v4l2_ctl():
try:
- return subprocess.check_output('which v4l2-ctl', shell=True).strip()
+ return subprocess.check_output(['which', 'v4l2-ctl'], stderr=open('/dev/null', 'w')).strip()
except subprocess.CalledProcessError: # not found
return None
try:
output = ''
started = time.time()
- p = subprocess.Popen('v4l2-ctl --list-devices 2>/dev/null', shell=True, stdout=subprocess.PIPE, bufsize=1)
+ p = subprocess.Popen(['v4l2-ctl', '--list-devices'], stdout=subprocess.PIPE, bufsize=1)
fd = p.stdout.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
resolutions = set()
output = ''
started = time.time()
- p = subprocess.Popen('v4l2-ctl -d "%(device)s" --list-formats-ext | grep -vi stepwise | grep -oE "[0-9]+x[0-9]+" || true' % {
- 'device': device}, shell=True, stdout=subprocess.PIPE, bufsize=1)
+ p = subprocess.Popen('v4l2-ctl -d %(device)s --list-formats-ext | grep -vi stepwise | grep -oE "[0-9]+x[0-9]+" || true' % {
+ 'device': pipes.quote(device)}, shell=True, stdout=subprocess.PIPE, bufsize=1)
fd = p.stdout.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
output = ''
started = time.time()
- p = subprocess.Popen('v4l2-ctl -d "%(device)s" --set-ctrl %(control)s=%(value)s' % {
- 'device': device, 'control': control, 'value': value}, shell=True, stdout=subprocess.PIPE, bufsize=1)
+ p = subprocess.Popen('v4l2-ctl -d %(device)s --set-ctrl %(control)s=%(value)s' % {
+ 'device': pipes.quote(device), 'control': pipes.quote(control), 'value': pipes.quote(str(value))}, shell=True, stdout=subprocess.PIPE, bufsize=1)
fd = p.stdout.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
output = ''
started = time.time()
- p = subprocess.Popen('v4l2-ctl -d "%(device)s" --list-ctrls' % {
- 'device': device}, shell=True, stdout=subprocess.PIPE, bufsize=1)
+ p = subprocess.Popen('v4l2-ctl -d %(device)s --list-ctrls' % {
+ 'device': pipes.quote(device)}, shell=True, stdout=subprocess.PIPE, bufsize=1)
fd = p.stdout.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)