예제 #1
0
class IVTSession(RPCSession):

    request_publish_rtmp_schame = Schema({
        'channel': IntVal(min=0),
        'quality': VideoQuality.schema,
        'url': Use(STRING),
        'stream_id': Use(STRING),
    })

    request_stop_rtmp_schema = Schema({
        'channel': IntVal(min=0),
        'stream_id': Use(STRING),
    })

    def __init__(self, ivt, transport):
        self._ivt = ivt
        super(IVTSession, self).__init__(transport)
        self._keepalive_greenlet = gevent.spawn(self._keepalive)

    def _keepalive(self):
        while True:
            try:
                data = {}
                for c in self._ivt.iter_cameras():
                    data[c.channel] = {'is_online': c.is_online}
                self._send_event('keepalive', data)
            except Exception:
                log.exception('Failed to send keepalive to IVC')
            finally:
                gevent.sleep(self._ivt.keepalive_interval)

    def on_close(self):
        try:
            gevent.kill(self._keepalive_greenlet)
        except Exception:
            log.exception('Failed to kill keepalive greenlet')
        super(IVTSession, self).on_close()
        self._ivt.session_closed()

    def rpc_getInfo(self):
        return {'id': self._ivt.id, 'cameras': self._ivt.cameras_info()}

    def rpc_RTMPPublish(self, params):
        params = self.request_publish_rtmp_schame.validate(params)
        self._ivt.rtmp_publish(params['channel'], params['quality'],
                               params['url'], params['stream_id'])

    def rpc_RTMPStopPublish(self, params):
        params = self.request_stop_rtmp_schema.validate(params)
        self._ivt.rtmp_stop_publish(params['channel'], params['stream_id'])
예제 #2
0
class DeviceWSConnectionManager(DeviceManager):

    login_params_schema = Schema({
        'project': Use(STRING),
        'login_code': Use(STRING),
        'login_passwd': Use(STRING)
    })

    def __init__(self, device_dao, device_ttl):
        super(DeviceWSConnectionManager, self).__init__(device_dao)
        self._device_ttl = device_ttl
        self._device_connections = {}

    def device_online(self, transport, params):
        params = self.login_params_schema.validate(params)
        project_name = params['project']
        login_code = params['login_code']
        login_passwd = params['login_passwd']
        device = self._dao.get_by_login_code(login_code)
        if not device:
            raise IVRError('Unknown device <{0}> try to login: {1}'.format(
                login_code, params))
        if device.project_name != project_name:
            raise IVRError(
                'Device <{0}> of project <{1}> attampts to login as project <{2}> device'
                .format(login_code, device.project_name, project_name))
        if device.login_passwd != login_passwd:
            raise IVRError(
                'Device login failed with wrong password: {0}'.format(params))
        device_conn = DeviceConn(self, project_name, device.uuid, transport,
                                 self._device_ttl)
        old_device_conn = self._device_connections.pop(device.uuid, None)
        if old_device_conn:
            log.warning('There is old {0}, disconnect it first'.format(
                old_device_conn))
            try:
                old_device_conn.force_shutdown()
            except Exception:
                log.exception(
                    'failed to force shutdown {0}'.format(old_device_conn))
        self._device_connections[device.uuid] = device_conn
        log.info('{0} online'.format(device))
        device.state = device.STATE_ONLINE
        device.ltime = datetime.datetime.now()
        self._dao.update(device)
        return device_conn

    def device_keepalive(self, device_id, params):
        device_conn = self._device_connections.get(device_id)
        if not device_conn:
            log.error(
                'BUG: device connection not found for keepalive device <{0}>'.
                format(device_id))
        device = self._dao.get_by_uuid(device_id)
        if not device:
            self._device_connections.pop(device_id, None)
            try:
                device_conn.force_shutdown()
            except Exception:
                log.exception(
                    'Failed to force shutdown {0}'.format(device_conn))
            raise IVRError('Unkonw device for {0}'.format(device_conn))
        device.is_online = device.STATE_ONLINE
        device.ltime = datetime.datetime.now()
        self._dao.update(device)
        for channel in params:
            self._camera_mngr.set_camera_state_by_device_channel(
                device.project_name, device.uuid, channel,
                params[channel]['is_online'])

    def conn_closed_cbk(self, conn):
        self._device_connections.pop(conn.device_id, None)
        device = self.get_device(conn.project_name, conn.device_id)
        device.is_online = device.STATE_ONLINE
        self.update_device(conn.project_name, device)

    def rtmp_publish_stream(self, project_name, device_id, channel, stream_id,
                            quality, publish_url):
        device_conn = self._device_connections.get(device_id)
        if not device_conn:
            raise IVRError(
                'Device <{0}> of project <{1}> is not online'.format(
                    device_id, project_name))
        device_conn.rtmp_publish_stream(channel, quality, publish_url,
                                        stream_id)

    def stop_rtmp_publish(self, project_name, device_id, channel, stream_id):
        device_conn = self._device_connections.get(device_id)
        if not device_conn:
            raise IVRError(
                'Device <{0}> of project <{1}> is not online'.format(
                    device_id, project_name))
        device_conn.stop_rtmp_publish(channel, stream_id)
예제 #3
0
파일: camera.py 프로젝트: dulton/IVR
    resp = {'total': total,
            'start': req['start'],
            'list': []}
    if limit > 0 and start < total:
        camera_list = request.registry.camera_mngr.get_camera_list(request.matchdict['project_name'],
                                                                   req['start'],
                                                                   req['limit'])
        resp['list'] = camera_list
    return resp


new_camera_request_schema = Schema({
    'name': StrVal(max_len=255),
    Optional('desc'): StrVal(max_len=255),
    Optional('long_desc'): StrVal(max_len=1024),
    'device_uuid': Use(unicode),
    'channel_index': IntVal(min=0),
    'flags': IntVal(),
    Optional('longitude'): Use(float),
    Optional('latitude'): Use(float),
    Optional('altitude'): Use(float),
})


@post_view(route_name='camera_list')
def new_camera(request):
    req = get_params_from_request(request, new_camera_request_schema)
    camera_id = request.registry.camera_mngr.add_camera(project_name=request.matchdict['project_name'], **req)
    return {'uuid': camera_id}

예제 #4
0
    IntVal(),
    Optional('login_code'):
    StrVal(max_len=64),
    'login_passwd':
    StrVal(max_len=64),
    Optional('firmware_model'):
    StrVal(max_len=255),
    Optional('hardware_model'):
    StrVal(max_len=255),
    # Optional('media_channel_num'): IntVal(),
    Optional('desc'):
    StrVal(max_len=255),
    Optional('long_desc'):
    StrVal(max_len=1024),
    Optional('longitude'):
    Use(float),
    Optional('latitude'):
    Use(float),
    Optional('altitude'):
    Use(float),
})


@post_view(route_name='device_list')
def new_device(request):
    req = get_params_from_request(request, new_device_request_schema)
    device_id = request.registry.device_mngr.add_device(
        project_name=request.matchdict['project_name'], **req)
    return {'uuid': device_id}

예제 #5
0
            'list': []}
    if limit > 0 and start < total:
        session_list = request.registry.user_session_mngr.get_running_session_list(
            request.matchdict['project_name'],
            camera_id=request.matchdict['camera_id'],
            start=req['start'],
            limit=req['limit']
        )
        resp['list'] = session_list
    return resp


get_stream_schema = Schema({'format': EnumVal(['hls', 'rtmp']),
                            Optional('quality'): Default(EnumVal(['ld', 'sd', 'hd']), default='ld'),
                            Optional('create'): Default(BoolVal(), default=True),
                            Optional('user'): Default(Use(STRING), default='')})


@post_view(route_name='user_session_list')
def request_user_session(request):
    req = get_params_from_request(request, get_stream_schema)
    url, session_id = request.registry.user_session_mngr.request_session(
        request.matchdict['project_name'],
        request.matchdict['camera_id'],
        stream_format=req['format'],
        stream_quality=req['quality'],
        create=req['create'],
        ip=request.client_addr or '',
        user_agent=request.user_agent,
        username='',
        subuser=req['user']
예제 #6
0
def includeme(config):
    # block device list resource
    # GET:    block device list
    config.add_route('access_key_list', '/access_keys')
    config.add_route('user_access_key_list', '/users/{username}/access_keys')
    config.add_route('access_key', '/access_keys/{key_id}')
    config.add_route('access_key_secret', '/access_keys/{key_id}/secret')


get_access_key_list_schema = Schema({
    Optional('username'): StrRe(r"^\w*$"),
    Optional('key_type'): IntVal(values=[AccessKey.KEY_TYPE_NORMAL,
                                         AccessKey.KEY_TYPE_PRIVILEGE]),
    Optional('start'): Default(IntVal(min=0), default=0),
    Optional('limit'): Default(IntVal(min=0, max=65535), default=65535),
    DoNotCare(Use(STRING)): object  # for all other key we don't care
})


@get_view(route_name='access_key_list')
def get_access_key_list(request):
    params = get_params_from_request(request, get_access_key_list_schema)
    total, access_key_list = request.registry.access_key_mngr.get_key_list_in_pages(
        username=params.get('username', None),
        key_type=params.get('key_type', None),
        start_index=params['start'],
        max_number=params['limit'])
    resp = {'total': total,
            'start': params['start'],
            'list': access_key_list}
    return resp
예제 #7
0
파일: main.py 프로젝트: dulton/IVR
from ivr.common.logger import default_config as default_log_config
from ivr.common.ws import WSServer
from ivr.common.schema import Schema, Use, IntVal, Default, Optional, BoolVal
from ivr.common.confparser import parse as parse_conf
from ivr.common.utils import STRING
from ivr.ivc.manager.camera import CameraManager
from ivr.ivc.manager.device_ws import DeviceWSConnectionManager
from ivr.ivc.manager.session import UserSessionManager
from ivr.ivc.manager.stream import StreamManager
from ivr.ivc.manager.project import ProjectManager
from ivr.ivc.manager.user import UserManager
from ivr.ivc.manager.sessionlog import UserSessionLogManager
from ivr.ivc.manager.access_key import AccessKeyManager

config_schema = Schema({
    'rest_listen': Use(STRING),
    'ws_listen': Use(STRING),
    'rtmp_publish_url_prefix': Use(STRING),
    'rtmp_url_prefix': Use(STRING),
    'hls_url_prefix': Use(STRING),
    'stream_ttl': IntVal(min=10, max=1800),
    'user_session_ttl': IntVal(min=10, max=1800),
    'device_ttl': IntVal(min=10, max=1800),
    Optional('sqlalchemy'): {
        'url': Use(STRING)
    },
    Optional('debug'): Default(BoolVal(), default=False),
})


def main():
예제 #8
0
파일: user_views.py 프로젝트: dulton/IVR
    # block device list resource
    # GET:    block device list
    config.add_route('user_list', '/users')
    config.add_route('project_user_list', '/projects/{project_name}/users')
    config.add_route('user', '/users/{username}')
    config.add_route('user_project_list', '/users/{username}/projects')
    config.add_route('user_password', '/users/{username}/password')
    config.add_route('user_password_reset', '/users/{username}/password_reset')


get_user_list_schema = Schema({
    Optional('filter_key'): StrRe(r"^\S*$"),
    Optional('filter_value'): StrRe(r"^\S*$"),
    Optional('start'): Default(IntVal(min=0), default=0),
    Optional('limit'): Default(IntVal(min=0, max=65535), default=65535),
    DoNotCare(Use(STRING)): object  # for all other key we don't care
})


@get_view(route_name='user_list')
def get_user_list(request):
    params = get_params_from_request(request, get_user_list_schema)
    total, user_list = request.registry.user_mngr.get_user_list_in_pages(
        params.get('filter_key', None),
        params.get('filter_value', ""),
        params['start'],
        params['limit'])
    resp = {'total': total,
            'start': params['start'],
            'list': user_list}
    return resp
예제 #9
0
import urllib

from ivr.common.logger import default_config as default_log_config
from ivr.common.ws import WSClientTransport
from ivr.common.schema import Schema, Use, EnumVal, IntVal, ListVal, DoNotCare, Optional
from ivr.ivt.ivt import IVT
from ivr.common.confparser import parse as parse_conf
from ivr.common.utils import STRING
from ivr.common.datatype import VideoQuality

from streamswitch.port_mngr import SubProcessPort
from streamswitch.ports.rtsp_port import RTSP_PORT_PROGRAM_NAME

config_schema = Schema({
    'ivc':
    Use(STRING),
    'project':
    Use(STRING),
    'login_code':
    Use(STRING),
    'login_passwd':
    Use(STRING),
    'keepalive_interval':
    IntVal(min=1, max=1800),
    Optional('preview_upload_server'):
    Use(STRING),
    'cameras':
    ListVal({
        'channel':
        IntVal(min=0),
        'type':