async def frame(self, camera_id): camera_config = config.get_camera(camera_id) if (utils.is_local_motion_camera(camera_config) or utils.is_simple_mjpeg_camera(camera_config) or self.get_argument('title', None) is not None): return self.render('main.html', frame=True, camera_id=camera_id, camera_config=camera_config, title=self.get_argument('title', camera_config.get('camera_name', '')), admin_username=config.get_main().get('@admin_username'), static_path='../../../static/') elif utils.is_remote_camera(camera_config): resp = await remote.get_config(camera_config) if resp.error: return self.render('main.html', frame=True, camera_id=camera_id, camera_config=camera_config, title=self.get_argument('title', '')) # issue a fake motion_camera_ui_to_dict() call to transform # the remote UI values into motion config directives remote_config = config.motion_camera_ui_to_dict(resp.remote_ui_config) return self.render('main.html', frame=True, camera_id=camera_id, camera_config=remote_config, title=self.get_argument('title', remote_config['camera_name']), admin_username=config.get_main().get('@admin_username'))
def get(self): # additional config main_sections = config.get_additional_structure(camera=False, separators=True)[0] camera_sections = config.get_additional_structure(camera=True, separators=True)[0] motion_info = motionctl.find_motion() os_version = update.get_os_version() self.render( 'main.html', frame=False, motion_version=motion_info[1] if motion_info else '(none)', os_version=' '.join(os_version), enable_update=settings.ENABLE_UPDATE, enable_reboot=settings.ENABLE_REBOOT, add_remove_cameras=settings.ADD_REMOVE_CAMERAS, main_sections=main_sections, camera_sections=camera_sections, hostname=settings.SERVER_NAME, title=self.get_argument('title', None), admin_username=config.get_main().get('@admin_username'), has_h264_omx_support=motionctl.has_h264_omx_support(), has_h264_v4l2m2m_support=motionctl.has_h264_v4l2m2m_support(), has_h264_nvenc_support=motionctl.has_h264_nvenc_support(), has_h264_nvmpi_support=motionctl.has_h264_nvmpi_support(), has_hevc_nvenc_support=motionctl.has_hevc_nvenc_support(), has_hevc_nvmpi_support=motionctl.has_hevc_nvmpi_support(), has_h264_qsv_support=motionctl.has_h264_qsv_support(), has_hevc_qsv_support=motionctl.has_hevc_qsv_support(), has_motion=bool(motionctl.find_motion()[0]), mask_width=utils.MASK_WIDTH)
def make_media_folders(): from motioneye import config config.get_main() # just to have main config already loaded camera_ids = config.get_camera_ids() for camera_id in camera_ids: camera_config = config.get_camera(camera_id) if 'target_dir' in camera_config: if not os.path.exists(camera_config['target_dir']): try: os.makedirs(camera_config['target_dir']) except Exception as e: logging.error( 'failed to create root media folder "%s" for camera with id %s: %s' % (camera_config['target_dir'], camera_id, e))
def get_current_user(self): main_config = config.get_main() username = self.get_argument('_username', None) signature = self.get_argument('_signature', None) login = self.get_argument('_login', None) == 'true' admin_username = main_config.get('@admin_username') normal_username = main_config.get('@normal_username') admin_password = main_config.get('@admin_password') normal_password = main_config.get('@normal_password') admin_hash = hashlib.sha1( main_config['@admin_password'].encode('utf-8')).hexdigest() normal_hash = hashlib.sha1( main_config['@normal_password'].encode('utf-8')).hexdigest() if settings.HTTP_BASIC_AUTH and 'Authorization' in self.request.headers: up = utils.parse_basic_header( self.request.headers['Authorization']) if up: if (up['username'] == admin_username and admin_password in (up['password'], hashlib.sha1( up['password'].encode('utf-8')).hexdigest())): return 'admin' if (up['username'] == normal_username and normal_password in (up['password'], hashlib.sha1( up['password'].encode('utf-8')).hexdigest())): return 'normal' if (username == admin_username and (signature == utils.compute_signature( self.request.method, self.request.uri, self.request.body, admin_password) or signature == utils.compute_signature( self.request.method, self.request.uri, self.request.body, admin_hash))): return 'admin' if not username and not normal_password: # no authentication required for normal user return 'normal' if (username == normal_username and (signature == utils.compute_signature( self.request.method, self.request.uri, self.request.body, normal_password) or signature == utils.compute_signature( self.request.method, self.request.uri, self.request.body, normal_hash))): return 'normal' if username and username != '_' and login: logging.error('authentication failed for user %(user)s' % {'user': username}) return None
def motion_camera_id_to_camera_id(motion_camera_id): from motioneye import config main_config = config.get_main() cameras = main_config.get('camera', []) try: return int( re.search(r'camera-(\d+).conf', cameras[int(motion_camera_id) - 1]).group(1)) except IndexError: return None
def camera_id_to_motion_camera_id(camera_id): from motioneye import config # find the corresponding motion camera_id # (which can be different from camera_id) main_config = config.get_main() cameras = main_config.get('camera', []) camera_filename = 'camera-%d.conf' % camera_id for i, camera in enumerate(cameras): if camera != camera_filename: continue return i + 1 return None
async def get_config(self, camera_id): if camera_id: logging.debug('getting config for camera %(id)s' % {'id': camera_id}) if camera_id not in config.get_camera_ids(): raise HTTPError(404, 'no such camera') local_config = config.get_camera(camera_id) if utils.is_local_motion_camera(local_config): ui_config = config.motion_camera_dict_to_ui(local_config) return self.finish_json(ui_config) elif utils.is_remote_camera(local_config): resp = await remote.get_config(local_config) if resp.error: msg = 'Failed to get remote camera configuration for %(url)s: %(msg)s.' % { 'url': remote.pretty_camera_url(local_config), 'msg': resp.error } return self.finish_json_with_error(msg) for key, value in list(local_config.items()): resp.remote_ui_config[key.replace('@', '')] = value # replace the real device url with the remote camera path resp.remote_ui_config['device_url'] = remote.pretty_camera_url( local_config) return self.finish_json(resp.remote_ui_config) else: # assuming simple mjpeg camera ui_config = config.simple_mjpeg_camera_dict_to_ui(local_config) return self.finish_json(ui_config) else: logging.debug('getting main config') ui_config = config.main_dict_to_ui(config.get_main()) return self.finish_json(ui_config)
async def list(self): logging.debug('listing cameras') proto = self.get_argument('proto') if proto == 'motioneye': # remote listing return self._handle_list_cameras_response( await remote.list_cameras(self.get_all_arguments())) elif proto == 'netcam': scheme = self.get_argument('scheme', 'http') if scheme in ['http', 'https', 'mjpeg']: resp = await test_mjpeg_url(self.get_all_arguments(), auth_modes=['basic'], allow_jpeg=True) return self._handle_list_cameras_response(resp) elif scheme == 'rtsp': resp = await test_rtsp_url(self.get_all_arguments()) return self._handle_list_cameras_response(resp) elif scheme == 'rtmp': resp = test_rtmp_url(self.get_all_arguments()) return self._handle_list_cameras_response(resp) else: return self.finish_json_with_error( f'protocol {scheme} not supported') elif proto == 'mjpeg': resp = await test_mjpeg_url(self.get_all_arguments(), auth_modes=['basic', 'digest'], allow_jpeg=False) return self._handle_list_cameras_response(resp) elif proto == 'v4l2': configured_devices = set() for camera_id in config.get_camera_ids(): data = config.get_camera(camera_id) if utils.is_v4l2_camera(data): configured_devices.add(data['videodevice']) cameras = [{ 'id': d[1], 'name': d[2] } for d in v4l2ctl.list_devices() if (d[0] not in configured_devices) and ( d[1] not in configured_devices)] return self.finish_json({'cameras': cameras}) elif proto == 'mmal': configured_devices = set() for camera_id in config.get_camera_ids(): data = config.get_camera(camera_id) if utils.is_mmal_camera(data): configured_devices.add(data['mmalcam_name']) cameras = [{ 'id': d[0], 'name': d[1] } for d in mmalctl.list_devices() if (d[0] not in configured_devices)] return self.finish_json({'cameras': cameras}) else: # assuming local motionEye camera listing cameras = [] camera_ids = config.get_camera_ids() if not config.get_main().get('@enabled'): camera_ids = [] length = [len(camera_ids)] for camera_id in camera_ids: local_config = config.get_camera(camera_id) if local_config is None: continue if utils.is_local_motion_camera(local_config): ui_config = config.motion_camera_dict_to_ui(local_config) cameras.append(ui_config) finished = self.check_finished(cameras, length) if finished: return elif utils.is_remote_camera(local_config): if local_config.get('@enabled') or self.get_argument( 'force', None) == 'true': resp = await remote.get_config(local_config) return self._handle_get_config_response( camera_id, local_config, resp, cameras, length) else: # don't try to reach the remote of the camera is disabled return self._handle_get_config_response( camera_id, local_config, utils.GetConfigResponse(None, error=True), cameras, length) else: # assuming simple mjpeg camera ui_config = config.simple_mjpeg_camera_dict_to_ui( local_config) cameras.append(ui_config) return self.check_finished(cameras, length) if length[0] == 0: return self.finish_json({'cameras': []})
def set_main_config(ui_config): logging.debug('setting main config...') old_main_config = config.get_main() old_admin_username = old_main_config.get('@admin_username') old_normal_username = old_main_config.get('@normal_username') main_config = config.main_ui_to_dict(ui_config) main_config.setdefault('camera', old_main_config.get('camera', [])) admin_username = main_config.get('@admin_username') admin_password = main_config.get('@admin_password') normal_username = main_config.get('@normal_username') normal_password = main_config.get('@normal_password') additional_configs = config.get_additional_structure( camera=False)[1] reboot_config_names = [('@_' + c['name']) for c in list(additional_configs.values()) if c.get('reboot')] reboot = bool([ k for k in reboot_config_names if old_main_config.get(k) != main_config.get(k) ]) config.set_main(main_config) reload = False restart = False if admin_username != old_admin_username or admin_password is not None: logging.debug('admin credentials changed, reload needed') reload = True if normal_username != old_normal_username or normal_password is not None: logging.debug( 'surveillance credentials changed, all camera configs must be updated' ) # reconfigure all local cameras to update the stream authentication options for camera_id in config.get_camera_ids(): local_config = config.get_camera(camera_id) if not utils.is_local_motion_camera(local_config): continue ui_config = config.motion_camera_dict_to_ui(local_config) local_config = config.motion_camera_ui_to_dict( ui_config, local_config) config.set_camera(camera_id, local_config) restart = True if reboot and settings.ENABLE_REBOOT: logging.debug('system settings changed, reboot needed') else: reboot = False return {'reload': reload, 'reboot': reboot, 'restart': restart}