Example #1
0
class Service(IStreamHandler):
    SERVER_ID = 'server_id'
    STREAM_DATA_CHANGED = 'stream_data_changed'
    SERVICE_DATA_CHANGED = 'service_data_changed'
    INIT_VALUE = 0
    CALCULATE_VALUE = None

    # runtime
    _cpu = INIT_VALUE
    _gpu = INIT_VALUE
    _load_average = CALCULATE_VALUE
    _memory_total = INIT_VALUE
    _memory_free = INIT_VALUE
    _hdd_total = INIT_VALUE
    _hdd_free = INIT_VALUE
    _bandwidth_in = INIT_VALUE
    _bandwidth_out = INIT_VALUE
    _uptime = CALCULATE_VALUE
    _timestamp = CALCULATE_VALUE
    _streams = []
    _online_users = None
    _os = OperationSystem()

    def __init__(self, host, port, socketio, settings: ServiceSettings):
        self._settings = settings
        self.__reload_from_db()
        # other fields
        self._client = ServiceClient(settings.id, settings.host.host,
                                     settings.host.port, self)
        self._host = host
        self._port = port
        self._socketio = socketio

    def connect(self):
        return self._client.connect()

    def is_connected(self):
        return self._client.is_connected()

    def disconnect(self):
        return self._client.disconnect()

    def socket(self):
        return self._client.socket()

    def recv_data(self):
        return self._client.recv_data()

    def stop(self, delay: int):
        return self._client.stop_service(delay)

    def get_log_service(self):
        return self._client.get_log_service(self._host, self._port)

    def ping(self):
        return self._client.ping_service()

    def activate(self, license_key: str):
        return self._client.activate(license_key)

    def sync(self, prepare=False):
        settings = self._settings.reload()
        if prepare:
            self._client.prepare_service(settings)
        return self._client.sync_service(settings)

    def get_log_stream(self, sid: str):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.get_log_stream(self._host, self._port, sid,
                                        stream.generate_feedback_dir())

    def get_pipeline_stream(self, sid):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.get_pipeline_stream(self._host, self._port, sid,
                                             stream.generate_feedback_dir())

    def start_stream(self, sid: str):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.start_stream(stream.config())

    def stop_stream(self, sid: str):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.stop_stream(sid)

    def restart_stream(self, sid: str):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.restart_stream(sid)

    def get_vods_in(self) -> list:
        return self._client.get_vods_in()

    @property
    def host(self) -> str:
        return self._host

    @property
    def id(self) -> ObjectId:
        return self._settings.id

    @property
    def status(self) -> ClientStatus:
        return self._client.status()

    @property
    def cpu(self):
        return self._cpu

    @property
    def gpu(self):
        return self._gpu

    @property
    def load_average(self):
        return self._load_average

    @property
    def memory_total(self):
        return self._memory_total

    @property
    def memory_free(self):
        return self._memory_free

    @property
    def hdd_total(self):
        return self._hdd_total

    @property
    def hdd_free(self):
        return self._hdd_free

    @property
    def bandwidth_in(self):
        return self._bandwidth_in

    @property
    def bandwidth_out(self):
        return self._bandwidth_out

    @property
    def uptime(self):
        return self._uptime

    @property
    def timestamp(self):
        return self._timestamp

    @property
    def version(self) -> str:
        return self._client.get_version()

    @property
    def os(self) -> OperationSystem:
        return self._client.get_os()

    @property
    def online_users(self) -> OnlineUsers:
        return self._online_users

    def get_streams(self):
        return self._streams

    def find_stream_by_id(self, sid: str):
        for stream in self._streams:
            if stream.id == ObjectId(sid):
                return stream

        return None

    def get_user_role_by_id(self, uid: ObjectId) -> ProviderPair.Roles:
        for user in self._settings.providers:
            if user.user.id == uid:
                return user.role

        return ProviderPair.Roles.READ

    def add_stream(self, stream):
        self.__init_stream_runtime_fields(stream)
        self._streams.append(stream)
        self._settings.streams.append(stream)
        self._settings.save()

    def add_streams(self, streams):
        for stream in streams:
            self.__init_stream_runtime_fields(stream)
            self._streams.append(stream)
            self._settings.streams.append(stream)
        self._settings.save()

    def update_stream(self, stream):
        stream.save()

    def remove_stream(self, sid: str):
        for stream in self._streams:
            if stream.id == ObjectId(sid):
                self._streams.remove(stream)
                self._settings.streams.remove(stream)
                break

    def to_front(self) -> dict:
        return {
            ServiceFields.ID: str(self.id),
            ServiceFields.CPU: self._cpu,
            ServiceFields.GPU: self._gpu,
            ServiceFields.LOAD_AVERAGE: self._load_average,
            ServiceFields.MEMORY_TOTAL: self._memory_total,
            ServiceFields.MEMORY_FREE: self._memory_free,
            ServiceFields.HDD_TOTAL: self._hdd_total,
            ServiceFields.HDD_FREE: self._hdd_free,
            ServiceFields.BANDWIDTH_IN: self._bandwidth_in,
            ServiceFields.BANDWIDTH_OUT: self._bandwidth_out,
            ServiceFields.VERSION: self.version,
            ServiceFields.UPTIME: self._uptime,
            ServiceFields.TIMESTAMP: self._timestamp,
            ServiceFields.STATUS: self.status,
            ServiceFields.ONLINE_USERS: str(self.online_users),
            ServiceFields.OS: str(self.os)
        }

    def make_proxy_stream(self) -> ProxyStream:
        return ProxyStream.make_stream(self._settings)

    def make_relay_stream(self) -> RelayStream:
        return RelayStream.make_stream(self._settings)

    def make_vod_relay_stream(self) -> VodRelayStream:
        return VodRelayStream.make_stream(self._settings)

    def make_cod_relay_stream(self) -> CodRelayStream:
        return CodRelayStream.make_stream(self._settings)

    def make_encode_stream(self) -> EncodeStream:
        return EncodeStream.make_stream(self._settings)

    def make_vod_encode_stream(self) -> VodEncodeStream:
        return VodEncodeStream.make_stream(self._settings)

    def make_cod_encode_stream(self) -> CodEncodeStream:
        return CodEncodeStream.make_stream(self._settings)

    def make_timeshift_recorder_stream(self) -> TimeshiftRecorderStream:
        return TimeshiftRecorderStream.make_stream(self._settings)

    def make_catchup_stream(self) -> CatchupStream:
        return CatchupStream.make_stream(self._settings)

    def make_timeshift_player_stream(self) -> TimeshiftPlayerStream:
        return TimeshiftPlayerStream.make_stream(self._settings)

    def make_test_life_stream(self) -> TestLifeStream:
        return TestLifeStream.make_stream(self._settings)

    # handler
    def on_stream_statistic_received(self, params: dict):
        sid = params['id']
        stream = self.find_stream_by_id(sid)
        if stream:
            stream.update_runtime_fields(params)
            self.__notify_front(Service.STREAM_DATA_CHANGED, stream.to_front())

    def on_stream_sources_changed(self, params: dict):
        pass

    def on_service_statistic_received(self, params: dict):
        # nid = params['id']
        self.__refresh_stats(params)
        self.__notify_front(Service.SERVICE_DATA_CHANGED, self.to_front())

    def on_quit_status_stream(self, params: dict):
        sid = params['id']
        stream = self.find_stream_by_id(sid)
        if stream:
            stream.reset()
            self.__notify_front(Service.STREAM_DATA_CHANGED, stream.to_front())

    def on_client_state_changed(self, status: ClientStatus):
        if status == ClientStatus.ACTIVE:
            self.sync(True)
        else:
            self.__reset()
            for stream in self._streams:
                stream.reset()

    def on_ping_received(self, params: dict):
        self.sync()

    # private
    def __notify_front(self, channel: str, params: dict):
        unique_channel = channel + '_' + str(self.id)
        self._socketio.emit(unique_channel, params)

    def __reset(self):
        self._cpu = Service.INIT_VALUE
        self._gpu = Service.INIT_VALUE
        self._load_average = Service.CALCULATE_VALUE
        self._memory_total = Service.INIT_VALUE
        self._memory_free = Service.INIT_VALUE
        self._hdd_total = Service.INIT_VALUE
        self._hdd_free = Service.INIT_VALUE
        self._bandwidth_in = Service.INIT_VALUE
        self._bandwidth_out = Service.INIT_VALUE
        self._uptime = Service.CALCULATE_VALUE
        self._timestamp = Service.CALCULATE_VALUE
        self._online_users = None

    def __refresh_stats(self, stats: dict):
        self._cpu = stats[ServiceFields.CPU]
        self._gpu = stats[ServiceFields.GPU]
        self._load_average = stats[ServiceFields.LOAD_AVERAGE]
        self._memory_total = stats[ServiceFields.MEMORY_TOTAL]
        self._memory_free = stats[ServiceFields.MEMORY_FREE]
        self._hdd_total = stats[ServiceFields.HDD_TOTAL]
        self._hdd_free = stats[ServiceFields.HDD_FREE]
        self._bandwidth_in = stats[ServiceFields.BANDWIDTH_IN]
        self._bandwidth_out = stats[ServiceFields.BANDWIDTH_OUT]
        self._uptime = stats[ServiceFields.UPTIME]
        self._timestamp = stats[ServiceFields.TIMESTAMP]
        self._online_users = OnlineUsers(**stats[ServiceFields.ONLINE_USERS])

    def __init_stream_runtime_fields(self, stream: IStream):
        stream.set_server_settings(self._settings)

    def __reload_from_db(self):
        self._streams = []
        streams = self._settings.streams
        for stream in streams:
            self.__init_stream_runtime_fields(stream)
            self._streams.append(stream)
Example #2
0
class Service(IStreamHandler):
    SERVER_ID = 'server_id'
    STREAM_DATA_CHANGED = 'stream_data_changed'
    SERVICE_DATA_CHANGED = 'service_data_changed'
    INIT_VALUE = 0
    CALCULATE_VALUE = None

    # runtime
    _cpu = INIT_VALUE
    _gpu = INIT_VALUE
    _load_average = CALCULATE_VALUE
    _memory_total = INIT_VALUE
    _memory_free = INIT_VALUE
    _hdd_total = INIT_VALUE
    _hdd_free = INIT_VALUE
    _bandwidth_in = INIT_VALUE
    _bandwidth_out = INIT_VALUE
    _uptime = CALCULATE_VALUE
    _sync_time = CALCULATE_VALUE
    _timestamp = CALCULATE_VALUE
    _streams = []
    _online_users = None
    _os = OperationSystem()

    def __init__(self, host, port, socketio, settings: ServiceSettings):
        self._settings = settings
        # other fields
        self._client = ServiceClient(settings.id, settings.host.host,
                                     settings.host.port, self)
        self._host = host
        self._port = port
        self._socketio = socketio
        self.__reload_from_db()

    def connect(self):
        return self._client.connect()

    def is_connected(self):
        return self._client.is_connected()

    def disconnect(self):
        return self._client.disconnect()

    def socket(self):
        return self._client.socket()

    def recv_data(self):
        return self._client.recv_data()

    def stop(self, delay: int):
        return self._client.stop_service(delay)

    def get_log_service(self):
        return self._client.get_log_service(self._host, self._port)

    def ping(self):
        return self._client.ping_service()

    def activate(self, license_key: str):
        return self._client.activate(license_key)

    def sync(self, prepare=False):
        if prepare:
            self._client.prepare_service(self._settings)
        res = self._client.sync_service(self._streams)
        self.__refresh_catchups()
        if res:
            self._sync_time = datetime.now()
        return res

    def get_log_stream(self, sid: ObjectId):
        stream = self.find_stream_by_id(sid)
        if stream:
            stream.get_log_request(self._host, self._port)

    def get_pipeline_stream(self, sid: ObjectId):
        stream = self.find_stream_by_id(sid)
        if stream:
            stream.get_pipeline_request(self._host, self._port)

    def start_stream(self, sid: ObjectId):
        stream = self.find_stream_by_id(sid)
        if stream:
            stream.start_request()

    def stop_stream(self, sid: ObjectId):
        stream = self.find_stream_by_id(sid)
        if stream:
            stream.stop_request()

    def restart_stream(self, sid: ObjectId):
        stream = self.find_stream_by_id(sid)
        if stream:
            stream.restart_request()

    def get_vods_in(self) -> list:
        return self._client.get_vods_in()

    @property
    def host(self) -> str:
        return self._host

    @property
    def id(self) -> ObjectId:
        return self._settings.id

    @property
    def status(self) -> ClientStatus:
        return self._client.status()

    @property
    def cpu(self):
        return self._cpu

    @property
    def gpu(self):
        return self._gpu

    @property
    def load_average(self):
        return self._load_average

    @property
    def memory_total(self):
        return self._memory_total

    @property
    def memory_free(self):
        return self._memory_free

    @property
    def hdd_total(self):
        return self._hdd_total

    @property
    def hdd_free(self):
        return self._hdd_free

    @property
    def bandwidth_in(self):
        return self._bandwidth_in

    @property
    def bandwidth_out(self):
        return self._bandwidth_out

    @property
    def uptime(self):
        return self._uptime

    @property
    def synctime(self):
        if not self._sync_time:
            return None
        return date_to_utc_msec(self._sync_time)

    @property
    def timestamp(self):
        return self._timestamp

    @property
    def version(self) -> str:
        return self._client.get_version()

    @property
    def exp_time(self):
        return self._client.get_exp_time()

    @property
    def os(self) -> OperationSystem:
        return self._client.get_os()

    @property
    def online_users(self) -> OnlineUsers:
        return self._online_users

    def get_streams(self):
        return self._streams

    def find_stream_by_id(self, sid: ObjectId) -> IStreamObject:
        for stream in self._streams:
            if stream.id == sid:
                return stream

        return None  #

    def get_user_role_by_id(self, uid: ObjectId) -> ProviderPair.Roles:
        for user in self._settings.providers:
            if user.user.id == uid:
                return user.role

        return ProviderPair.Roles.READ

    def add_serial(self, serial):
        self._settings.series.append(serial)
        self._settings.save()

    def remove_serial(self, sid: str):
        for ser in self._settings.series:
            if ser.id == ObjectId(sid):
                ser.delete()

    def add_stream(self, stream: IStream):
        if stream:
            stream_object = self.__convert_stream(stream)
            stream_object.stable()
            self._streams.append(stream_object)
            self._settings.add_stream(stream)

    def add_streams(self, streams: [IStream]):
        for stream in streams:
            if stream:
                stream_object = self.__convert_stream(stream)
                stream_object.stable()
                self._streams.append(stream_object)
        self._settings.add_streams(streams)  #

    def update_stream(self, stream: IStream):
        stream.save()
        stream_object = self.find_stream_by_id(stream.id)
        if stream_object:
            stream_object.stable()

    def remove_stream(self, sid: ObjectId):
        for stream in list(self._streams):
            if stream.id == sid:
                stream.stop_request()
                self._streams.remove(stream)
                self._settings.remove_stream(stream.stream())

    def remove_all_streams(self):
        for stream in self._streams:
            self._client.stop_stream(stream.get_id())
        self._streams = []
        self._settings.remove_all_streams()  #

    def stop_all_streams(self):
        for stream in self._streams:
            self._client.stop_stream(stream.get_id())

    def start_all_streams(self):
        for stream in self._streams:
            self._client.start_stream(stream.config())

    def to_dict(self) -> dict:
        return {
            ServiceFields.ID: str(self.id),
            ServiceFields.CPU: self._cpu,
            ServiceFields.GPU: self._gpu,
            ServiceFields.LOAD_AVERAGE: self._load_average,
            ServiceFields.MEMORY_TOTAL: self._memory_total,
            ServiceFields.MEMORY_FREE: self._memory_free,
            ServiceFields.HDD_TOTAL: self._hdd_total,
            ServiceFields.HDD_FREE: self._hdd_free,
            ServiceFields.BANDWIDTH_IN: self._bandwidth_in,
            ServiceFields.BANDWIDTH_OUT: self._bandwidth_out,
            ServiceFields.VERSION: self.version,
            ServiceFields.EXP_TIME: self.exp_time,
            ServiceFields.UPTIME: self._uptime,
            ServiceFields.SYNCTIME: self.synctime,
            ServiceFields.TIMESTAMP: self._timestamp,
            ServiceFields.STATUS: self.status,
            ServiceFields.ONLINE_USERS: str(self.online_users),
            ServiceFields.OS: str(self.os)
        }

    def make_serial(self) -> Serial:
        return Serial()

    def make_proxy_stream(self) -> ProxyStreamObject:
        return ProxyStreamObject.make_stream(self._settings)

    def make_proxy_vod(self) -> ProxyStreamObject:
        return ProxyVodStreamObject.make_stream(self._settings)

    def make_relay_stream(self) -> RelayStreamObject:
        return RelayStreamObject.make_stream(self._settings, self._client)

    def make_vod_relay_stream(self) -> VodRelayStreamObject:
        return VodRelayStreamObject.make_stream(self._settings, self._client)

    def make_cod_relay_stream(self) -> CodRelayStreamObject:
        return CodRelayStreamObject.make_stream(self._settings, self._client)

    def make_encode_stream(self) -> EncodeStreamObject:
        return EncodeStreamObject.make_stream(self._settings, self._client)

    def make_vod_encode_stream(self) -> VodEncodeStreamObject:
        return VodEncodeStreamObject.make_stream(self._settings, self._client)

    def make_event_stream(self) -> VodEncodeStreamObject:
        return EventStreamObject.make_stream(self._settings, self._client)

    def make_cod_encode_stream(self) -> CodEncodeStreamObject:
        return CodEncodeStreamObject.make_stream(self._settings, self._client)

    def make_timeshift_recorder_stream(self) -> TimeshiftRecorderStreamObject:
        return TimeshiftRecorderStreamObject.make_stream(
            self._settings, self._client)

    def make_catchup_stream(self) -> CatchupStreamObject:
        return CatchupStreamObject.make_stream(self._settings, self._client)

    def make_timeshift_player_stream(self) -> TimeshiftPlayerStreamObject:
        return TimeshiftPlayerStreamObject.make_stream(self._settings,
                                                       self._client)

    def make_test_life_stream(self) -> TestLifeStreamObject:
        return TestLifeStreamObject.make_stream(self._settings, self._client)

    # handler
    def on_stream_statistic_received(self, params: dict):
        sid = params['id']
        stream = self.find_stream_by_id(ObjectId(sid))
        if stream:
            stream.update_runtime_fields(params)
            self.__notify_front(Service.STREAM_DATA_CHANGED, stream.to_dict())

    def on_stream_sources_changed(self, params: dict):
        pass

    def on_stream_ml_notification(self, params: dict):
        pass

    def on_service_statistic_received(self, params: dict):
        # nid = params['id']
        self.__refresh_stats(params)
        self.__notify_front(Service.SERVICE_DATA_CHANGED, self.to_dict())

    def on_quit_status_stream(self, params: dict):
        sid = params['id']
        stream = self.find_stream_by_id(ObjectId(sid))
        if stream:
            stream.reset()
            self.__notify_front(Service.STREAM_DATA_CHANGED, stream.to_dict())

    def on_client_state_changed(self, status: ClientStatus):
        if status == ClientStatus.ACTIVE:
            self.sync(True)
        else:
            self.__reset()
            for stream in self._streams:
                stream.reset()

    def on_ping_received(self, params: dict):
        self.sync()

    # private
    def __notify_front(self, channel: str, params: dict):
        unique_channel = channel + '_' + str(self.id)
        self._socketio.emit(unique_channel, params)

    def __reset(self):
        self._cpu = Service.INIT_VALUE
        self._gpu = Service.INIT_VALUE
        self._load_average = Service.CALCULATE_VALUE
        self._memory_total = Service.INIT_VALUE
        self._memory_free = Service.INIT_VALUE
        self._hdd_total = Service.INIT_VALUE
        self._hdd_free = Service.INIT_VALUE
        self._bandwidth_in = Service.INIT_VALUE
        self._bandwidth_out = Service.INIT_VALUE
        self._uptime = Service.CALCULATE_VALUE
        self._sync_time = Service.CALCULATE_VALUE
        self._timestamp = Service.CALCULATE_VALUE
        self._online_users = None

    def __refresh_stats(self, stats: dict):
        self._cpu = stats[ServiceFields.CPU]
        self._gpu = stats[ServiceFields.GPU]
        self._load_average = stats[ServiceFields.LOAD_AVERAGE]
        self._memory_total = stats[ServiceFields.MEMORY_TOTAL]
        self._memory_free = stats[ServiceFields.MEMORY_FREE]
        self._hdd_total = stats[ServiceFields.HDD_TOTAL]
        self._hdd_free = stats[ServiceFields.HDD_FREE]
        self._bandwidth_in = stats[ServiceFields.BANDWIDTH_IN]
        self._bandwidth_out = stats[ServiceFields.BANDWIDTH_OUT]
        self._uptime = stats[ServiceFields.UPTIME]
        self._timestamp = stats[ServiceFields.TIMESTAMP]
        self._online_users = OnlineUsers(**stats[ServiceFields.ONLINE_USERS])

    def __reload_from_db(self):
        self._streams = []
        for stream in self._settings.streams:
            stream_object = self.__convert_stream(stream)
            if stream_object:
                self._streams.append(stream_object)

    def __refresh_catchups(self):
        self._settings.refresh_from_db()
        # FIXME workaround, need to listen load balance
        for stream in self._settings.streams:
            if stream and stream.get_type() == constants.StreamType.CATCHUP:
                if not self.find_stream_by_id(stream.pk):
                    stream_object = self.__convert_stream(stream)
                    if stream_object:
                        self._streams.append(stream_object)

        for stream in self._streams:
            if stream.type == constants.StreamType.CATCHUP:
                stream.start_request()

    def __convert_stream(self, stream: IStream) -> IStreamObject:
        if not stream:
            return

        stream_type = stream.get_type()
        if stream_type == constants.StreamType.PROXY:
            return ProxyStreamObject(stream, self._settings)
        elif stream_type == constants.StreamType.VOD_PROXY:
            return ProxyVodStreamObject(stream, self._settings)
        elif stream_type == constants.StreamType.RELAY:
            return RelayStreamObject(stream, self._settings, self._client)
        elif stream_type == constants.StreamType.ENCODE:
            return EncodeStreamObject(stream, self._settings, self._client)
        elif stream_type == constants.StreamType.TIMESHIFT_PLAYER:
            return TimeshiftPlayerStreamObject(stream, self._settings,
                                               self._client)
        elif stream_type == constants.StreamType.TIMESHIFT_RECORDER:
            return TimeshiftRecorderStreamObject(stream, self._settings,
                                                 self._client)
        elif stream_type == constants.StreamType.CATCHUP:
            return CatchupStreamObject(stream, self._settings, self._client)
        elif stream_type == constants.StreamType.TEST_LIFE:
            return TestLifeStreamObject(stream, self._settings, self._client)
        elif stream_type == constants.StreamType.VOD_RELAY:
            return VodRelayStreamObject(stream, self._settings, self._client)
        elif stream_type == constants.StreamType.VOD_ENCODE:
            return VodEncodeStreamObject(stream, self._settings, self._client)
        elif stream_type == constants.StreamType.COD_RELAY:
            return CodRelayStreamObject(stream, self._settings, self._client)
        elif stream_type == constants.StreamType.COD_ENCODE:
            return CodEncodeStreamObject(stream, self._settings, self._client)
        elif stream_type == constants.StreamType.EVENT:
            return EventStreamObject(stream, self._settings, self._client)
        else:
            return None  #
Example #3
0
class Service(IStreamHandler):
    STREAM_DATA_CHANGED = 'stream_data_changed'
    SERVICE_DATA_CHANGED = 'service_data_changed'
    CALCULATE_VALUE = None

    # runtime
    _cpu = CALCULATE_VALUE
    _gpu = CALCULATE_VALUE
    _load_average = CALCULATE_VALUE
    _memory_total = CALCULATE_VALUE
    _memory_free = CALCULATE_VALUE
    _memory_available = CALCULATE_VALUE
    _hdd_total = CALCULATE_VALUE
    _hdd_free = CALCULATE_VALUE
    _bandwidth_in = CALCULATE_VALUE
    _bandwidth_out = CALCULATE_VALUE
    _uptime = CALCULATE_VALUE
    _timestamp = CALCULATE_VALUE
    _streams = []

    def __init__(self, host, port, socketio, settings: ServiceSettings):
        self._settings = settings
        self.__reload_from_db()
        # other fields
        self._client = ServiceClient(self, settings)
        self._host = host
        self._port = port
        self._socketio = socketio

    def connect(self):
        return self._client.connect()

    def disconnect(self):
        return self._client.disconnect()

    def stop(self, delay: int):
        return self._client.stop_service(delay)

    def get_log_service(self):
        return self._client.get_log_service(self._host, self._port, self.id)

    def view_playlist(self) -> str:
        return self._settings.generate_playlist()

    def ping(self):
        return self._client.ping_service()

    def activate(self, license_key: str):
        return self._client.activate(license_key)

    def sync(self):
        return self._client.sync_service()

    def get_log_stream(self, sid: str):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.get_log_stream(self._host, self._port, sid,
                                        stream.generate_feedback_dir())

    def get_pipeline_stream(self, sid):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.get_pipeline_stream(self._host, self._port, sid,
                                             stream.generate_feedback_dir())

    def start_stream(self, sid: str):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.start_stream(stream.config())

    def stop_stream(self, sid: str):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.stop_stream(sid)

    def restart_stream(self, sid: str):
        stream = self.find_stream_by_id(sid)
        if stream:
            self._client.restart_stream(sid)

    def get_vods_in(self) -> list:
        return self._client.get_vods_in()

    @property
    def id(self) -> str:
        return str(self._settings.id)

    @property
    def status(self) -> ClientStatus:
        return self._client.status()

    @property
    def cpu(self):
        return self._cpu

    @property
    def gpu(self):
        return self._gpu

    @property
    def load_average(self):
        return self._load_average

    @property
    def memory_total(self):
        return self._memory_total

    @property
    def memory_free(self):
        return self._memory_free

    @property
    def memory_available(self):
        return self._memory_available

    @property
    def hdd_total(self):
        return self._hdd_total

    @property
    def hdd_free(self):
        return self._hdd_free

    @property
    def bandwidth_in(self):
        return self._bandwidth_in

    @property
    def bandwidth_out(self):
        return self._bandwidth_out

    @property
    def uptime(self):
        return self._uptime

    @property
    def timestamp(self):
        return self._timestamp

    @property
    def version(self):
        return self._client.get_version()

    def get_streams(self):
        return self._streams

    def find_stream_by_id(self, sid: str):
        for stream in self._streams:
            if stream.id == ObjectId(sid):
                return stream

        return None

    def get_user_role_by_id(self, uid: ObjectId) -> constants.Roles:
        for user in self._settings.users:
            if user.user.id == uid:
                return user.role

        return constants.Roles.READ

    def add_stream(self, stream):
        self.__init_stream_runtime_fields(stream)
        stream.fixup_output_urls()
        self._streams.append(stream)
        self._settings.streams.append(stream)
        self._settings.save()

    def update_stream(self, stream):
        stream.fixup_output_urls()
        stream.save()

    def remove_stream(self, sid: str):
        for stream in self._streams:
            if stream.id == ObjectId(sid):
                for set_stream in self._settings.streams:
                    if set_stream.id == stream.id:
                        self._settings.streams.remove(set_stream)
                        break
                self._settings.save()
                self._streams.remove(stream)
                break

    def to_front(self) -> dict:
        return {
            ServiceFields.ID: self.id,
            ServiceFields.CPU: self._cpu,
            ServiceFields.GPU: self._gpu,
            ServiceFields.LOAD_AVERAGE: self._load_average,
            ServiceFields.MEMORY_TOTAL: self._memory_total,
            ServiceFields.MEMORY_FREE: self._memory_free,
            ServiceFields.MEMORY_AVAILABLE: self._memory_available,
            ServiceFields.HDD_TOTAL: self._hdd_total,
            ServiceFields.HDD_FREE: self._hdd_free,
            ServiceFields.BANDWIDTH_IN: self._bandwidth_in,
            ServiceFields.BANDWIDTH_OUT: self._bandwidth_out,
            ServiceFields.VERSION: self.version,
            ServiceFields.UPTIME: self._uptime,
            ServiceFields.TIMESTAMP: self._timestamp,
            ServiceFields.STATUS: self.status
        }

    def make_relay_stream(self) -> RelayStream:
        return make_relay_stream(self._settings)

    def make_vod_relay_stream(self) -> RelayStream:
        return make_vod_relay_stream(self._settings)

    def make_encode_stream(self) -> EncodeStream:
        return make_encode_stream(self._settings)

    def make_vod_encode_stream(self) -> EncodeStream:
        return make_vod_encode_stream(self._settings)

    def make_timeshift_recorder_stream(self) -> TimeshiftRecorderStream:
        return make_timeshift_recorder_stream(self._settings)

    def make_catchup_stream(self) -> CatchupStream:
        return make_catchup_stream(self._settings)

    def make_timeshift_player_stream(self) -> TimeshiftPlayerStream:
        return make_timeshift_player_stream(self._settings)

    def make_test_life_stream(self) -> TestLifeStream:
        return make_test_life_stream(self._settings)

    # handler
    def on_stream_statistic_received(self, params: dict):
        sid = params['id']
        stream = self.find_stream_by_id(sid)
        if stream:
            stream.update_runtime_fields(params)
            self.__notify_front(Service.STREAM_DATA_CHANGED, stream.to_front())

    def on_stream_sources_changed(self, params: dict):
        pass

    def on_service_statistic_received(self, params: dict):
        # nid = params['id']
        self.__refresh_stats(params)
        self.__notify_front(Service.SERVICE_DATA_CHANGED, self.to_front())

    def on_quit_status_stream(self, params: dict):
        sid = params['id']
        stream = self.find_stream_by_id(sid)
        if stream:
            stream.reset()
            self.__notify_front(Service.STREAM_DATA_CHANGED, stream.to_front())

    def on_client_state_changed(self, status: ClientStatus):
        if status == ClientStatus.ACTIVE:
            pass
        else:
            self.__reset()
            for stream in self._streams:
                stream.reset()

    # private
    def __notify_front(self, channel: str, params: dict):
        self._socketio.emit(channel, params)

    def __reset(self):
        self._cpu = Service.CALCULATE_VALUE
        self._gpu = Service.CALCULATE_VALUE
        self._load_average = Service.CALCULATE_VALUE
        self._memory_total = Service.CALCULATE_VALUE
        self._memory_free = Service.CALCULATE_VALUE
        self._memory_available = Service.CALCULATE_VALUE
        self._hdd_total = Service.CALCULATE_VALUE
        self._hdd_free = Service.CALCULATE_VALUE
        self._bandwidth_in = Service.CALCULATE_VALUE
        self._bandwidth_out = Service.CALCULATE_VALUE
        self._uptime = Service.CALCULATE_VALUE
        self._timestamp = Service.CALCULATE_VALUE

    def __refresh_stats(self, stats: dict):
        self._cpu = stats[ServiceFields.CPU]
        self._gpu = stats[ServiceFields.GPU]
        self._load_average = stats[ServiceFields.LOAD_AVERAGE]
        self._memory_total = stats[ServiceFields.MEMORY_TOTAL]
        self._memory_free = stats[ServiceFields.MEMORY_FREE]
        self._memory_available = stats[ServiceFields.MEMORY_AVAILABLE]
        self._hdd_total = stats[ServiceFields.MEMORY_TOTAL]
        self._hdd_free = stats[ServiceFields.MEMORY_FREE]
        self._bandwidth_in = stats[ServiceFields.BANDWIDTH_IN]
        self._bandwidth_out = stats[ServiceFields.BANDWIDTH_OUT]
        self._uptime = stats[ServiceFields.UPTIME]
        self._timestamp = stats[ServiceFields.TIMESTAMP]

    def __init_stream_runtime_fields(self, stream: Stream):
        stream.set_server_settings(self._settings)

    def __reload_from_db(self):
        self._streams = []
        streams = self._settings.streams
        for stream in streams:
            self.__init_stream_runtime_fields(stream)
            self._streams.append(stream)