self._seek_content_length()
+def start():
+ # schedule the garbage collector
+ io_loop = ioloop.IOLoop.instance()
+ io_loop.add_timeout(datetime.timedelta(seconds=settings.MJPG_CLIENT_TIMEOUT), _garbage_collector)
+
+
+def get_jpg(camera_id):
+ if camera_id not in MjpgClient.clients:
+ # mjpg client not started yet for this camera
+
+ logging.debug('creating mjpg client for camera %(camera_id)s' % {
+ 'camera_id': camera_id})
+
+ camera_config = config.get_camera(camera_id)
+ if not camera_config['@enabled'] or not utils.local_motion_camera(camera_config):
+ logging.error('could not start mjpg client for camera id %(camera_id)s: not enabled or not local' % {
+ 'camera_id': camera_id})
+
+ return None
+
+ port = camera_config['stream_port']
+ username, password = None, None
+ if camera_config.get('stream_auth_method') > 0:
+ username, password = camera_config.get('stream_authentication', ':').split(':')
+
+ client = MjpgClient(camera_id, port, username, password)
+ client.connect()
+
+ MjpgClient.last_access[camera_id] = datetime.datetime.utcnow()
+
+ return MjpgClient.last_jpgs.get(camera_id)
+
+
+def close_all(invalidate=False):
+ for client in MjpgClient.clients.values():
+ client.close()
+
+ if invalidate:
+ MjpgClient.clients = {}
+ MjpgClient.last_jpgs = {}
+ MjpgClient.last_jpg_moment = {}
+ MjpgClient.last_access = {}
+ MjpgClient.last_erroneous_close_time = 0
+
+
def _garbage_collector():
logging.debug('running garbage collector for mjpg clients...')
client.close()
continue
-
-
-def get_jpg(camera_id):
- if camera_id not in MjpgClient.clients:
- # mjpg client not started yet for this camera
-
- logging.debug('creating mjpg client for camera %(camera_id)s' % {
- 'camera_id': camera_id})
-
- camera_config = config.get_camera(camera_id)
- if not camera_config['@enabled'] or not utils.local_motion_camera(camera_config):
- logging.error('could not start mjpg client for camera id %(camera_id)s: not enabled or not local' % {
- 'camera_id': camera_id})
-
- return None
-
- port = camera_config['stream_port']
- username, password = None, None
- if camera_config.get('stream_auth_method') > 0:
- username, password = camera_config.get('stream_authentication', ':').split(':')
-
- client = MjpgClient(camera_id, port, username, password)
- client.connect()
-
- MjpgClient.last_access[camera_id] = datetime.datetime.utcnow()
-
- return MjpgClient.last_jpgs.get(camera_id)
-
-
-def close_all(invalidate=False):
- for client in MjpgClient.clients.values():
- client.close()
-
- if invalidate:
- MjpgClient.clients = {}
- MjpgClient.last_jpgs = {}
- MjpgClient.last_jpg_moment = {}
- MjpgClient.last_access = {}
- MjpgClient.last_erroneous_close_time = 0
-
-
-def start_gc():
- # schedule the garbage collector
- io_loop = ioloop.IOLoop.instance()
- io_loop.add_timeout(datetime.timedelta(seconds=settings.MJPG_CLIENT_TIMEOUT), _garbage_collector)
return _motion_binary_cache
-def _disable_initial_motion_detection():
- for camera_id in config.get_camera_ids():
- camera_config = config.get_camera(camera_id)
- if not utils.local_motion_camera(camera_config):
- continue
-
- if not camera_config['@motion_detection']:
- logging.debug('motion detection disabled by config for camera with id %s' % camera_id)
- set_motion_detection(camera_id, False)
-
-
def start(deferred=False):
if deferred:
return IOLoop.instance().add_callback(start, deferred=False)
return None
+def _disable_initial_motion_detection():
+ for camera_id in config.get_camera_ids():
+ camera_config = config.get_camera(camera_id)
+ if not utils.local_motion_camera(camera_config):
+ continue
+
+ if not camera_config['@motion_detection']:
+ logging.debug('motion detection disabled by config for camera with id %s' % camera_id)
+ set_motion_detection(camera_id, False)
+
+
def _get_pid():
motion_pid_path = os.path.join(settings.RUN_PATH, 'motion.pid')
import time
from tornado.web import Application
+from tornado.ioloop import IOLoop
import handlers
import settings
def configure_signals():
def bye_handler(signal, frame):
- import tornado.ioloop
-
logging.info('interrupt signal received, shutting down...')
# shut down the IO loop if it has been started
- ioloop = tornado.ioloop.IOLoop.instance()
- ioloop.stop()
+ io_loop = IOLoop.instance()
+ io_loop.stop()
def child_handler(signal, frame):
# this is required for the multiprocessing mechanism to work
if os.geteuid() != 0:
if settings.SMB_SHARES:
- print('SMB_SHARES require root privileges')
- return False
+ logging.fatal('smb shares require root privileges')
+ sys.exit(-1)
if settings.ENABLE_REBOOT:
- print('reboot requires root privileges')
- return False
+ logging.fatal('reboot requires root privileges')
+ sys.exit(-1)
try:
import tornado # @UnusedImport
ioloop.add_timeout(datetime.timedelta(seconds=settings.MOTION_CHECK_INTERVAL), checker)
-def start_cleanup():
- import cleanup
-
- cleanup.start()
- logging.info('cleanup started')
-
-
-def start_wsswitch():
- import wsswitch
-
- wsswitch.start()
- logging.info('wsswitch started')
-
-
-def start_thumbnailer():
- import thumbnailer
-
- thumbnailer.start()
- logging.info('thumbnailer started')
-
-
-def start_mjpg_client_gc():
- import mjpgclient
-
- mjpgclient.start_gc()
- logging.info('mjpg client garbage collector started')
-
-
def parse_options(parser, args):
parser.add_argument('-b', help='start the server in background (daemonize)',
action='store_true', dest='background', default=False)
def run():
import cleanup
+ import mjpgclient
import motionctl
import motioneye
import smbctl
import thumbnailer
- import tornado.ioloop
+ import wsswitch
configure_signals()
logging.info('hello! this is motionEye server %s' % motioneye.VERSION)
test_requirements()
if settings.SMB_SHARES:
-
stop, start = smbctl.update_mounts() # @UnusedVariable
if start:
start_motion()
start_motion()
if settings.CLEANUP_INTERVAL:
- start_cleanup()
+ cleanup.start()
+ logging.info('cleanup started')
- start_wsswitch()
+ wsswitch.start()
+ logging.info('wsswitch started')
if settings.THUMBNAILER_INTERVAL:
- start_thumbnailer()
+ thumbnailer.start()
+ logging.info('thumbnailer started')
if settings.MJPG_CLIENT_TIMEOUT:
- start_mjpg_client_gc()
+ mjpgclient.start()
+ logging.info('mjpg client garbage collector started')
+
+ if settings.SMB_SHARES:
+ smbctl.start()
+ logging.info('smb mounts started')
template.add_context('static_path', settings.BASE_PATH + '/static/')
application.listen(settings.PORT, settings.LISTEN)
logging.info('server started')
- tornado.ioloop.IOLoop.instance().start()
+ IOLoop.instance().start()
logging.info('server stopped')
logging.info('motion stopped')
if settings.SMB_SHARES:
- smbctl.umount_all()
- logging.info('SMB shares unmounted')
+ smbctl.stop()
+ logging.info('smb mounts stopped')
logging.info('bye!')
import settings
+def start():
+ io_loop = ioloop.IOLoop.instance()
+ io_loop.add_timeout(datetime.timedelta(seconds=settings.MOUNT_CHECK_INTERVAL), _check_mounts)
+
+
+def stop():
+ _umount_all()
+
+
def find_mount_cifs():
try:
return subprocess.check_output('which mount.cifs', shell=True).strip()
return mount_point
-def _is_motioneye_mount(mount_point):
- mount_point_root = os.path.join(settings.SMB_MOUNT_ROOT, 'motioneye_')
- return bool(re.match('^' + mount_point_root + '\w+$', mount_point))
-
-
def list_mounts():
logging.debug('listing smb mounts...')
return mounts
-def mount(server, share, username, password):
+def update_mounts():
+ network_shares = config.get_network_shares()
+
+ mounts = list_mounts()
+ mounts = dict(((m['server'], m['share'], m['username'] or ''), False) for m in mounts)
+
+ should_stop = False # indicates that motion should be stopped immediately
+ should_start = True # indicates that motion can be started afterwards
+ for network_share in network_shares:
+ key = (network_share['server'], network_share['share'], network_share['username'] or '')
+ if key in mounts: # found
+ mounts[key] = True
+
+ else: # needs to be mounted
+ should_stop = True
+ if not _mount(network_share['server'], network_share['share'], network_share['username'], network_share['password']):
+ should_start = False
+
+ # unmount the no longer necessary mounts
+ for (server, share, username), required in mounts.items():
+ if not required:
+ _umount(server, share, username)
+ should_stop = True
+
+ return (should_stop, should_start)
+
+
+def _mount(server, share, username, password):
mount_point = make_mount_point(server, share, username)
logging.debug('making sure mount point "%s" exists' % mount_point)
return mount_point
-def umount(server, share, username):
+def _umount(server, share, username):
mount_point = make_mount_point(server, share, username)
logging.debug('unmounting "//%s/%s" from "%s"' % (server, share, mount_point))
return True
-def update_mounts():
- network_shares = config.get_network_shares()
-
- mounts = list_mounts()
- mounts = dict(((m['server'], m['share'], m['username'] or ''), False) for m in mounts)
-
- should_stop = False # indicates that motion should be stopped immediately
- should_start = True # indicates that motion can be started afterwards
- for network_share in network_shares:
- key = (network_share['server'], network_share['share'], network_share['username'] or '')
- if key in mounts: # found
- mounts[key] = True
-
- else: # needs to be mounted
- should_stop = True
- if not mount(network_share['server'], network_share['share'], network_share['username'], network_share['password']):
- should_start = False
-
- # unmount the no longer necessary mounts
- for (server, share, username), required in mounts.items():
- if not required:
- umount(server, share, username)
- should_stop = True
-
- return (should_stop, should_start)
+def _is_motioneye_mount(mount_point):
+ mount_point_root = os.path.join(settings.SMB_MOUNT_ROOT, 'motioneye_')
+ return bool(re.match('^' + mount_point_root + '\w+$', mount_point))
-def umount_all():
+def _umount_all():
for mount in list_mounts():
- umount(mount['server'], mount['share'], mount['username'])
+ _umount(mount['server'], mount['share'], mount['username'])
def _check_mounts():
io_loop = ioloop.IOLoop.instance()
io_loop.add_timeout(datetime.timedelta(seconds=settings.MOUNT_CHECK_INTERVAL), _check_mounts)
-
-if settings.SMB_SHARES:
- # schedule the mount checker
- io_loop = ioloop.IOLoop.instance()
- io_loop.add_timeout(datetime.timedelta(seconds=settings.MOUNT_CHECK_INTERVAL), _check_mounts)