mirror of
https://github.com/fastogt/fastocloud_admin.git
synced 2025-03-09 23:38:52 +00:00
1106 lines
57 KiB
HTML
1106 lines
57 KiB
HTML
{% extends 'layouts/layout_user.html' %}
|
|
{% block title %}
|
|
Dashboard | {{ config['PUBLIC_CONFIG'].site.title }}
|
|
{% endblock %}
|
|
{% block styles %}
|
|
<style>
|
|
table {
|
|
table-layout: fixed;
|
|
}
|
|
th.stream_number {
|
|
width: 2%;
|
|
}
|
|
th.stream_name {
|
|
width: 18%;
|
|
}
|
|
th.stream_type {
|
|
width: 5%;
|
|
}
|
|
th.stream_status {
|
|
width: 5%;
|
|
}
|
|
th.stream_restarts {
|
|
width: 4%;
|
|
}
|
|
th.stream_cpu {
|
|
width: 5%;
|
|
}
|
|
th.stream_rss {
|
|
width: 5%;
|
|
}
|
|
th.stream_inbps {
|
|
width: 5%;
|
|
}
|
|
th.stream_outbps {
|
|
width: 6%;
|
|
}
|
|
th.stream_work_time {
|
|
width: 5%;
|
|
}
|
|
th.stream_live_time {
|
|
width: 5%;
|
|
}
|
|
th.stream_quality {
|
|
width: 5%;
|
|
}
|
|
th.stream_price {
|
|
width: 5%;
|
|
}
|
|
th.stream_actions {
|
|
width: 25%;
|
|
}
|
|
</style>
|
|
{{super()}}
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<h1 class="panel-title">
|
|
<div class="col-md-11">
|
|
<a href="{{ url_for('HomeView:index') }}">{{ config['PUBLIC_CONFIG'].site.title }}</a>
|
|
</div>
|
|
<div>Version: {{ config['PUBLIC_CONFIG'].project.version }}</div>
|
|
</h1>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="container-fluid">
|
|
<div class="row well">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<p>{% trans %}Welcome{% endtrans %} {{ current_user.email }}</p>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ProviderView:settings') }}" class="btn btn-info" role="button">
|
|
{% trans %}Settings{% endtrans %}
|
|
</a>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ProviderView:logout') }}" class="btn btn-warning" role="button">
|
|
{% trans %}Logout{% endtrans %}
|
|
</a>
|
|
</div>
|
|
{% if (current_user.type != 0) %}
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ProviderView:remove') }}" class="btn btn-danger" role="button">
|
|
{% trans %}Delete{% endtrans %}
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="row well">
|
|
<div class="row">
|
|
<div class="col-md-1">
|
|
<select class="form-control" name="servers" onchange=OnServerChanged(this.value);>
|
|
{% for server in servers %}
|
|
{% if (service.id == server.id | string) %}
|
|
<option value="{{ loop.index0 }}" selected>{{ server.name }}</option>
|
|
{% else %}
|
|
<option value="{{ loop.index0 }}">{{ server.name }}</option>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-md-1">
|
|
{% if (service.status == service.status.INIT) %}
|
|
<a href="{{ url_for('ServiceView:connect') }}" class="btn btn-info" role="button">
|
|
{% trans %}Connect{% endtrans %}
|
|
</a>
|
|
{% else %}
|
|
<a href="{{ url_for('ServiceView:disconnect') }}" class="btn btn-info" role="button">
|
|
{% trans %}Disconnect{% endtrans %}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:activate') }}" role="button"
|
|
{% if (service.status== service.status.INIT) %}
|
|
class="btn btn-info disabled"
|
|
{% else %}
|
|
class="btn btn-info"
|
|
{% endif %}>
|
|
{% trans %}Activate{% endtrans %}
|
|
</a>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:sync') }}" role="button"
|
|
{% if (service.status== service.status.INIT) %}
|
|
class="btn btn-info disabled"
|
|
{% else %}
|
|
class="btn btn-info"
|
|
{% endif %}>
|
|
{% trans %}Sync{% endtrans %}
|
|
</a>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:playlist', sid=service.id) }}" class="btn btn-success"
|
|
role="button">
|
|
{% trans %}Playlist{% endtrans %}
|
|
</a>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:upload_m3u') }}" role="button" class="btn btn-success">
|
|
{% trans %}Upload m3u{% endtrans %}
|
|
</a>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:ping') }}" role="button"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-info"
|
|
{% else %}
|
|
class="btn btn-info disabled"
|
|
{% endif %}>
|
|
{% trans %}Ping{% endtrans %}
|
|
</a>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:stop') }}" role="button"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-warning"
|
|
{% else %}
|
|
class="btn btn-warning disabled"
|
|
{% endif %}>
|
|
{% trans %}Stop{% endtrans %}
|
|
</a>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:providers', sid=service.id) }}" class="btn btn-success"
|
|
role="button">
|
|
{% trans %}Providers{% endtrans %}
|
|
</a>
|
|
</div>
|
|
{% if (config['SUBSCRIBERS_SUPPORT']) %}
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:subscribers', sid=service.id) }}" class="btn btn-success"
|
|
role="button">
|
|
{% trans %}Subscribers{% endtrans %}
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
{% if (role == 2) %}
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:get_log') }}" role="button"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success"
|
|
{% else %}
|
|
class="btn btn-success disabled"
|
|
{% endif %}>
|
|
{% trans %}Get log{% endtrans %}
|
|
</a>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<a href="{{ url_for('ServiceView:view_log') }}" role="button" class="btn btn-info">
|
|
{% trans %}View log{% endtrans %}
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</br>
|
|
<div class="row">
|
|
<div class="col-md-2">
|
|
<b>{% trans %}ID:{% endtrans %}</b>
|
|
<p id='service_id'>{{ service.id }}</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}Timestamp:{% endtrans %}</b>
|
|
<p id='service_timestamp'>{{ service.timestamp }}</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}Uptime:{% endtrans %}</b>
|
|
<p id='service_uptime'>{{ service.uptime }} Seconds</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}Load:{% endtrans %}</b>
|
|
<p id='service_load_average'>{{ service.load_average }}</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}State:{% endtrans %}</b>
|
|
<p id='service_status'>{{ ['INIT', 'CONNECTED', 'ACTIVE'][service.status] }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-2">
|
|
<b>{% trans %}CPU:{% endtrans %}</b>
|
|
<p id='service_cpu'>{{ service.cpu | round(2, 'floor') }} %</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}GPU:{% endtrans %}</b>
|
|
<p id='service_gpu'>{{ service.gpu }} %</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}Network in:{% endtrans %}</b>
|
|
<p id='service_bandwidth_in'>{{ service.bandwidth_in }} Mbps</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}Network out:{% endtrans %}</b>
|
|
<p id='service_bandwidth_out'>{{ service.bandwidth_out }} Mbps</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}OS:{% endtrans %}</b>
|
|
<p id='service_os'>{{ service.os }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-2">
|
|
<b>{% trans %}Memory total:{% endtrans %}</b>
|
|
<p id='service_memory_total'>{{ service.memory_total }} MB</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}Memory free:{% endtrans %}</b>
|
|
<p id='service_memory_free'>{{ service.memory_free }} MB</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}HDD total:{% endtrans %}</b>
|
|
<p id='service_hdd_total'>{{ service.hdd_total }} MB</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}HDD free:{% endtrans %}</b>
|
|
<p id='service_hdd_free'>{{ service.hdd_free }} MB</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}Online users:{% endtrans %}</b>
|
|
<p id='service_connections'>{{ service.online_users }}</p>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<b>{% trans %}Version:{% endtrans %}</b>
|
|
<p id='service_version'>{{ service.version }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row well with-nav-tabs">
|
|
<div class="panel-heading">
|
|
<ul class="nav nav-tabs">
|
|
<li class="active"><a href="#streams" data-toggle="tab">Streams</a></li>
|
|
<li><a href="#vods" data-toggle="tab">Video on demand</a></li>
|
|
<li><a href="#cods" data-toggle="tab">Channel on demand</a></li>
|
|
<li><a href="#proxy" data-toggle="tab">Proxy</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="tab-content">
|
|
<div class="tab-pane fade in active" id="streams">
|
|
<div class="row">
|
|
<table id='streams_table' class="table">
|
|
<thead>
|
|
<tr>
|
|
<th class="stream_number">#</th>
|
|
<th class="stream_name">{% trans %}Name{% endtrans %}</th>
|
|
<th class="stream_type">{% trans %}Type{% endtrans %}</th>
|
|
<th class="stream_status">{% trans %}Status{% endtrans %}</th>
|
|
<th class="stream_restarts">{% trans %}Restarts{% endtrans %}</th>
|
|
<th class="stream_cpu">{% trans %}CPU (%){% endtrans %}</th>
|
|
<th class="stream_rss">{% trans %}RSS (MB){% endtrans %}</th>
|
|
<th class="stream_inbps">{% trans %}In (Mbps){% endtrans %}</th>
|
|
<th class="stream_outbps">{% trans %}Out (Mbps){% endtrans %}</th>
|
|
<th class="stream_work_time">{% trans %}TTL (sec){% endtrans %}</th>
|
|
<th class="stream_live_time">{% trans %}RTL (sec){% endtrans %}</th>
|
|
<th class="stream_quality">{% trans %}Quality (%){% endtrans %}</th>
|
|
<th class="stream_price">{% trans %}Price ($){% endtrans %}</th>
|
|
<th class="stream_actions">{% trans %}Actions{% endtrans %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for rev in streams %}
|
|
{% if (rev.type != 7 and rev.type != 8 and rev.type != 9 and rev.type != 10 and
|
|
rev.type != 0) %}
|
|
<tr id='{{ rev.id }}'>
|
|
<td>{{ loop.index }}</td>
|
|
<td>
|
|
<img width="32px" height="32px" src="{{rev.icon}}"/>
|
|
{{ rev.name }}
|
|
</td>
|
|
<td>
|
|
{{ ['PROXY','RELAY', 'ENCODE', 'TIMESHIFT_PLAYER', 'TIMESHIFT_RECORDER',
|
|
'CATCHUP', 'TEST_LIFE', 'VOD_RELAY', 'VOD_ENCODE', 'COD_RELAY',
|
|
'COD_ENCODE'][rev.type] }}
|
|
</td>
|
|
<td>{{ ['NEW', 'INIT', 'STARTED', 'READY', 'PLAYING', 'FROZEN',
|
|
'WAITING'][rev.status] }}
|
|
</td>
|
|
<td>{{ rev.restarts }}</td>
|
|
<td>{{ rev.cpu | round(2, 'floor') }}</td>
|
|
<td>{{ (rev.rss / (1024 * 1024)) | round(4, 'floor') }}</td>
|
|
<td>{{ (rev.input_streams|sum(attribute='bps') / (1024 * 1024 / 8)) | round(4,
|
|
'floor') }}
|
|
</td>
|
|
<td>{{ (rev.output_streams|sum(attribute='bps') / (1024 * 1024 / 8))| round(4,
|
|
'floor') }}
|
|
</td>
|
|
<td>{{ (rev.timestamp - rev.start_time)/1000 }}</td>
|
|
<td>{{ (rev.timestamp - rev.loop_start_time)/1000 }}</td>
|
|
<td>{{ rev.quality | round(2, 'floor') }}
|
|
</td>
|
|
<td>{{ rev.price }}</td>
|
|
<td>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="start_stream(this, '{{ rev.id }}')">
|
|
{% trans %}Start{% endtrans %}
|
|
</button>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="stop_stream(this, '{{ rev.id }}')">
|
|
{% trans %}Stop{% endtrans %}
|
|
</button>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="restart_stream(this, '{{ rev.id }}')">
|
|
{% trans %}Restart{% endtrans %}
|
|
</button>
|
|
<a href="{{ url_for('StreamView:play', sid=rev.id) }}"
|
|
class="btn btn-info btn-xs"
|
|
role="button">
|
|
{% trans %}Play{% endtrans %}
|
|
</a>
|
|
<button type="submit" class="btn btn-success btn-xs"
|
|
onclick="edit_stream('{{ rev.id }}')">
|
|
{% trans %}Edit{% endtrans %}
|
|
</button>
|
|
<button type="submit" class="btn btn-danger btn-xs"
|
|
onclick="remove_stream('{{ rev.id }}')">
|
|
{% trans %}Remove{% endtrans %}
|
|
</button>
|
|
{% if (role == 2) %}
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="get_log_stream('{{ rev.id }}')">
|
|
{% trans %}Get log{% endtrans %}
|
|
</button>
|
|
<a href="{{ url_for('StreamView:view_log', sid=rev.id) }}"
|
|
class="btn btn-info btn-xs"
|
|
role="button">
|
|
{% trans %}View log{% endtrans %}
|
|
</a>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="get_pipeline_stream('{{ rev.id }}')">
|
|
{% trans %}GPL{% endtrans %}
|
|
</button>
|
|
<a href="{{ url_for('StreamView:view_pipeline', sid=rev.id) }}"
|
|
class="btn btn-info btn-xs"
|
|
role="button">
|
|
{% trans %}VPL{% endtrans %}
|
|
</a>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="row">
|
|
<button class="btn btn-success btn-send col-md-2" onclick="add_relay_stream()">
|
|
{% trans %}Add relay{% endtrans %}
|
|
</button>
|
|
<button class="btn btn-success btn-send col-md-2" onclick="add_encode_stream()">
|
|
{% trans %}Add encode{% endtrans %}
|
|
</button>
|
|
<button class="btn btn-success btn-send col-md-2"
|
|
onclick="add_timeshift_recorder_stream()">
|
|
{% trans %}Add timeshift recorder{% endtrans %}
|
|
</button>
|
|
<button class="btn btn-success btn-send col-md-2" onclick="add_catchup_stream()">
|
|
{% trans %}Add catchup{% endtrans %}
|
|
</button>
|
|
<button class="btn btn-success btn-send col-md-2"
|
|
onclick="add_timeshift_player_stream()">
|
|
{% trans %}Add timeshift player{% endtrans %}
|
|
</button>
|
|
<button class="btn btn-success btn-send col-md-2" onclick="add_test_life_stream()">
|
|
{% trans %}Add test life{% endtrans %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane fade" id="vods">
|
|
<div class="row">
|
|
<table id='vods_table' class="table">
|
|
<thead>
|
|
<tr>
|
|
<th class="stream_number">#</th>
|
|
<th class="stream_name">{% trans %}Name{% endtrans %}</th>
|
|
<th class="stream_type">{% trans %}Type{% endtrans %}</th>
|
|
<th class="stream_status">{% trans %}Status{% endtrans %}</th>
|
|
<th class="stream_restarts">{% trans %}Restarts{% endtrans %}</th>
|
|
<th class="stream_cpu">{% trans %}CPU (%){% endtrans %}</th>
|
|
<th class="stream_rss">{% trans %}RSS (MB){% endtrans %}</th>
|
|
<th class="stream_inbps">{% trans %}In (Mbps){% endtrans %}</th>
|
|
<th class="stream_outbps">{% trans %}Out (Mbps){% endtrans %}</th>
|
|
<th class="stream_work_time">{% trans %}TTL (sec){% endtrans %}</th>
|
|
<th class="stream_live_time">{% trans %}RTL (sec){% endtrans %}</th>
|
|
<th class="stream_quality">{% trans %}Quality (%){% endtrans %}</th>
|
|
<th class="stream_price">{% trans %}Price ($){% endtrans %}</th>
|
|
<th class="stream_actions">{% trans %}Actions{% endtrans %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for vod in streams %}
|
|
{% if (vod.type == 7 or vod.type == 8) %}
|
|
<tr id='{{ vod.id }}'>
|
|
<td>{{ loop.index }}</td>
|
|
<td>
|
|
<img width="32px" height="32px" src="{{vod.icon}}"/>
|
|
{{ vod.name }}
|
|
</td>
|
|
<td>
|
|
{{ ['PROXY','RELAY', 'ENCODE', 'TIMESHIFT_PLAYER', 'TIMESHIFT_RECORDER',
|
|
'CATCHUP',
|
|
'TEST_LIFE',
|
|
'VOD_RELAY', 'VOD_ENCODE'][vod.type] }}
|
|
</td>
|
|
<td>{{ ['NEW', 'INIT', 'STARTED', 'READY', 'PLAYING', 'FROZEN',
|
|
'WAITING'][vod.status] }}
|
|
</td>
|
|
<td>{{ vod.restarts }}</td>
|
|
<td>{{ vod.cpu | round(2, 'floor') }}</td>
|
|
<td>{{ (vod.rss / (1024 * 1024)) | round(4, 'floor') }}</td>
|
|
<td>{{ (vod.input_streams|sum(attribute='bps') / (1024 * 1024 / 8)) | round(4,
|
|
'floor')}}
|
|
</td>
|
|
<td>{{ (vod.output_streams|sum(attribute='bps') / (1024 * 1024 / 8)) | round(4,
|
|
'floor') }}
|
|
</td>
|
|
<td>{{ (vod.timestamp - vod.start_time)/1000 }}</td>
|
|
<td>{{ (vod.timestamp - vod.loop_start_time)/1000 }}</td>
|
|
<td>{{ vod.quality | round(2, 'floor') }}</td>
|
|
<td>{{ vod.price }}</td>
|
|
<td>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="start_stream(this, '{{ vod.id }}')">
|
|
{% trans %}Refresh{% endtrans %}
|
|
</button>
|
|
<a href="{{ url_for('StreamView:play', sid=vod.id) }}"
|
|
class="btn btn-info btn-xs"
|
|
role="button">
|
|
{% trans %}Play{% endtrans %}
|
|
</a>
|
|
<button type="submit" class="btn btn-success btn-xs"
|
|
onclick="edit_stream('{{ vod.id }}')">
|
|
{% trans %}Edit{% endtrans %}
|
|
</button>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="get_log_stream('{{ vod.id }}')">
|
|
{% trans %}Get log{% endtrans %}
|
|
</button>
|
|
<a href="{{ url_for('StreamView:view_log', sid=vod.id) }}"
|
|
class="btn btn-info btn-xs"
|
|
role="button">
|
|
{% trans %}View log{% endtrans %}
|
|
</a>
|
|
<button type="submit" class="btn btn-danger btn-xs"
|
|
onclick="remove_stream('{{ vod.id }}')">
|
|
{% trans %}Remove{% endtrans %}
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="row">
|
|
<button class="btn btn-info btn-send col-md-6" onclick="add_vod_relay_stream()">
|
|
{% trans %}Add vod relay{% endtrans %}
|
|
</button>
|
|
<button class="btn btn-info btn-send col-md-6" onclick="add_vod_encode_stream()">
|
|
{% trans %}Add vod encode{% endtrans %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane fade" id="cods">
|
|
<div class="row">
|
|
<table id='cods_table' class="table">
|
|
<thead>
|
|
<tr>
|
|
<th class="stream_number">#</th>
|
|
<th class="stream_name">{% trans %}Name{% endtrans %}</th>
|
|
<th class="stream_type">{% trans %}Type{% endtrans %}</th>
|
|
<th class="stream_status">{% trans %}Status{% endtrans %}</th>
|
|
<th class="stream_restarts">{% trans %}Restarts{% endtrans %}</th>
|
|
<th class="stream_cpu">{% trans %}CPU (%){% endtrans %}</th>
|
|
<th class="stream_rss">{% trans %}RSS (MB){% endtrans %}</th>
|
|
<th class="stream_inbps">{% trans %}In (Mbps){% endtrans %}</th>
|
|
<th class="stream_outbps">{% trans %}Out (Mbps){% endtrans %}</th>
|
|
<th class="stream_work_time">{% trans %}TTL (sec){% endtrans %}</th>
|
|
<th class="stream_live_time">{% trans %}RTL (sec){% endtrans %}</th>
|
|
<th class="stream_quality">{% trans %}Quality (%){% endtrans %}</th>
|
|
<th class="stream_price">{% trans %}Price ($){% endtrans %}</th>
|
|
<th class="stream_actions">{% trans %}Actions{% endtrans %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for cod in streams %}
|
|
{% if (cod.type == 9 or cod.type == 10) %}
|
|
<tr id='{{ cod.id }}'>
|
|
<td>{{ loop.index }}</td>
|
|
<td>
|
|
<img width="32px" height="32px" src="{{cod.icon}}"/>
|
|
{{ cod.name }}
|
|
</td>
|
|
<td>
|
|
{{ ['PROXY','RELAY', 'ENCODE', 'TIMESHIFT_PLAYER', 'TIMESHIFT_RECORDER',
|
|
'CATCHUP',
|
|
'TEST_LIFE',
|
|
'COD_RELAY', 'COD_ENCODE'][cod.type] }}
|
|
</td>
|
|
<td>{{ ['NEW', 'INIT', 'STARTED', 'READY', 'PLAYING', 'FROZEN',
|
|
'WAITING'][cod.status] }}
|
|
</td>
|
|
<td>{{ cod.restarts }}</td>
|
|
<td>{{ cod.cpu | round(2, 'floor') }}</td>
|
|
<td>{{ (cod.rss / (1024 * 1024)) | round(4, 'floor') }}</td>
|
|
<td>{{ (cod.input_streams|sum(attribute='bps') / (1024 * 1024 / 8)) | round(4,
|
|
'floor')}}
|
|
</td>
|
|
<td>{{ (cod.output_streams|sum(attribute='bps') / (1024 * 1024 / 8)) | round(4,
|
|
'floor') }}
|
|
</td>
|
|
<td>{{ (cod.timestamp - cod.start_time)/1000 }}</td>
|
|
<td>{{ (cod.timestamp - cod.loop_start_time)/1000 }}</td>
|
|
<td>{{ cod.quality | round(2, 'floor') }}</td>
|
|
<td>{{ cod.price }}</td>
|
|
<td>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="start_stream(this, '{{ cod.id }}')">
|
|
{% trans %}Start{% endtrans %}
|
|
</button>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="stop_stream(this, '{{ cod.id }}')">
|
|
{% trans %}Stop{% endtrans %}
|
|
</button>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="restart_stream(this, '{{ cod.id }}')">
|
|
{% trans %}Restart{% endtrans %}
|
|
</button>
|
|
<a href="{{ url_for('StreamView:play', sid=cod.id) }}"
|
|
class="btn btn-info btn-xs"
|
|
role="button">
|
|
{% trans %}Play{% endtrans %}
|
|
</a>
|
|
<button type="submit" class="btn btn-success btn-xs"
|
|
onclick="edit_stream('{{ cod.id }}')">
|
|
{% trans %}Edit{% endtrans %}
|
|
</button>
|
|
<button type="submit" class="btn btn-danger btn-xs"
|
|
onclick="remove_stream('{{ cod.id }}')">
|
|
{% trans %}Remove{% endtrans %}
|
|
</button>
|
|
{% if (role == 2) %}
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="get_log_stream('{{ cod.id }}')">
|
|
{% trans %}Get log{% endtrans %}
|
|
</button>
|
|
<a href="{{ url_for('StreamView:view_log', sid=cod.id) }}"
|
|
class="btn btn-info btn-xs"
|
|
role="button">
|
|
{% trans %}View log{% endtrans %}
|
|
</a>
|
|
<button type="submit"
|
|
{% if (service.status== service.status.ACTIVE) %}
|
|
class="btn btn-success btn-xs"
|
|
{% else %}
|
|
class="btn btn-success btn-xs" disabled
|
|
{% endif %}
|
|
onclick="get_pipeline_stream('{{ cod.id }}')">
|
|
{% trans %}GPL{% endtrans %}
|
|
</button>
|
|
<a href="{{ url_for('StreamView:view_pipeline', sid=cod.id) }}"
|
|
class="btn btn-info btn-xs"
|
|
role="button">
|
|
{% trans %}VPL{% endtrans %}
|
|
</a>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="row">
|
|
<button class="btn btn-info btn-send col-md-6" onclick="add_cod_relay_stream()">
|
|
{% trans %}Add cod relay{% endtrans %}
|
|
</button>
|
|
<button class="btn btn-info btn-send col-md-6" onclick="add_cod_encode_stream()">
|
|
{% trans %}Add cod encode{% endtrans %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane fade" id="proxy">
|
|
<div class="row">
|
|
<table id='proxy_table' class="table">
|
|
<thead>
|
|
<tr>
|
|
<th class="stream_number">#</th>
|
|
<th class="stream_name">{% trans %}Name{% endtrans %}</th>
|
|
<th class="stream_type">{% trans %}Type{% endtrans %}</th>
|
|
<th class="stream_price">{% trans %}Price ($){% endtrans %}</th>
|
|
<th class="stream_actions">{% trans %}Actions{% endtrans %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for proxy in streams %}
|
|
{% if (proxy.type == 0) %}
|
|
<tr id='{{ proxy.id }}'>
|
|
<td>{{ loop.index }}</td>
|
|
<td>
|
|
<img width="32px" height="32px" src="{{proxy.icon}}"/>
|
|
{{ proxy.name }}
|
|
</td>
|
|
<td>
|
|
{{ ['PROXY','RELAY', 'ENCODE', 'TIMESHIFT_PLAYER', 'TIMESHIFT_RECORDER',
|
|
'CATCHUP',
|
|
'TEST_LIFE',
|
|
'VOD_RELAY', 'VOD_ENCODE','COD_RELAY', 'COD_ENCODE'][proxy.type] }}
|
|
</td>
|
|
<td>{{ proxy.price }}</td>
|
|
<td>
|
|
<a href="{{ url_for('StreamView:play', sid=proxy.id) }}"
|
|
class="btn btn-info btn-xs"
|
|
role="button">
|
|
{% trans %}Play{% endtrans %}
|
|
</a>
|
|
<button type="submit" class="btn btn-success btn-xs"
|
|
onclick="edit_stream('{{ proxy.id }}')">
|
|
{% trans %}Edit{% endtrans %}
|
|
</button>
|
|
<button type="submit" class="btn btn-danger btn-xs"
|
|
onclick="remove_stream('{{ proxy.id }}')">
|
|
{% trans %}Remove{% endtrans %}
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="row">
|
|
<button class="btn btn-warning btn-send col-md-12" onclick="add_proxy_stream()">
|
|
{% trans %}Add proxy{% endtrans %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="stream_dialog" class="modal fade" tabindex=-1 role="dialog">
|
|
<div class="modal-dialog modal-lg" role="document">
|
|
<div class="modal-content">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
{{ super() }}
|
|
<script type="text/javascript"
|
|
src="{{ url_for('static', filename='assets/js/socket.io/1.7.4/socket.io.min.js') }}"></script>
|
|
<script type="text/javascript" charset="utf-8">
|
|
// service
|
|
function OnServerChanged(value){
|
|
var url = '/change_current_server/' + value;
|
|
$.get(url, function(data) {
|
|
window.location.reload();
|
|
});
|
|
}
|
|
|
|
var socket = io.connect('{{ config['PREFERRED_URL_SCHEME'] }}' + '://' + document.domain + ':' + location.port);
|
|
socket.on('connect', function() {
|
|
});
|
|
socket.on('stream_data_changed_{{ service.id }}', function(stream) {
|
|
const kStatuses = ['NEW', 'INIT', 'STARTED', 'READY', 'PLAYING', 'FROZEN', 'WAITING'];
|
|
var table = document.getElementById("streams_table");
|
|
var row = $('#' + stream.id + ' td');
|
|
row.eq(3).text(kStatuses[stream.status]);
|
|
row.eq(4).text(stream.restarts);
|
|
row.eq(5).text(stream.cpu.toFixed(2));
|
|
row.eq(6).text((stream.rss / (1024 * 1024)).toFixed(4));
|
|
var in_bps = 0;
|
|
for(var i in stream.input_streams) {
|
|
in_bps += stream.input_streams[i].bps;
|
|
}
|
|
row.eq(7).text((in_bps / (1024 * 1024 / 8)).toFixed(4));
|
|
var out_bps = 0;
|
|
for(var i in stream.output_streams) {
|
|
out_bps += stream.output_streams[i].bps;
|
|
}
|
|
row.eq(8).text((out_bps / (1024 * 1024 / 8)).toFixed(4));
|
|
max_work_time = (stream.timestamp - stream.start_time)
|
|
row.eq(9).text(max_work_time/1000);
|
|
loop_work_time = stream.timestamp - stream.loop_start_time
|
|
row.eq(10).text(loop_work_time/1000);
|
|
row.eq(11).text(stream.quality.toFixed(2));
|
|
row.eq(12).text(stream.price);
|
|
});
|
|
socket.on('service_data_changed_{{ service.id }}', function(service) {
|
|
var service_id = $('#service_id');
|
|
service_id.text(service.id);
|
|
var service_uptime = $('#service_uptime');
|
|
service_uptime.text(service.uptime + ' Seconds');
|
|
var service_load_average = $('#service_load_average');
|
|
service_load_average.text(service.load_average);
|
|
var service_cpu = $('#service_cpu');
|
|
service_cpu.text(service.cpu.toFixed(2) + ' %');
|
|
var service_gpu = $('#service_gpu');
|
|
service_gpu.text(service.gpu.toFixed(2) + ' %');
|
|
var service_bandwidth_in = $('#service_bandwidth_in');
|
|
service_bandwidth_in.text((service.bandwidth_in / (1024 * 1024 / 8)).toFixed(4) + ' Mbps');
|
|
var service_bandwidth_out = $('#service_bandwidth_out');
|
|
service_bandwidth_out.text((service.bandwidth_out / (1024 * 1024 / 8)).toFixed(4) + ' Mbps');
|
|
var service_os = $('#service_os');
|
|
service_os.text(service.os);
|
|
var service_version = $('#service_version');
|
|
service_version.text(service.version);
|
|
var service_status = $('#service_status');
|
|
const kStatuses = ['INIT', 'CONNECTED', 'ACTIVE'];
|
|
service_status.text(kStatuses[service.status]);
|
|
var service_memory_total = $('#service_memory_total');
|
|
service_memory_total.text((service.memory_total / (1024 * 1024)).toFixed(4) + ' MB');
|
|
var service_memory_free = $('#service_memory_free');
|
|
service_memory_free.text((service.memory_free / (1024 * 1024)).toFixed(4) + ' MB');
|
|
var service_hdd_total = $('#service_hdd_total');
|
|
service_hdd_total.text((service.hdd_total / (1024 * 1024)).toFixed(4) + ' MB');
|
|
var service_hdd_free = $('#service_hdd_free');
|
|
service_hdd_free.text((service.hdd_free / (1024 * 1024)).toFixed(4) + ' MB');
|
|
var service_timestamp = $('#service_timestamp');
|
|
var current_datetime = new Date(service.timestamp);
|
|
service_timestamp.text(current_datetime.toISOString());
|
|
|
|
var service_connections = $('#service_connections');
|
|
service_connections.text(service.online_users);
|
|
});
|
|
// stream
|
|
function add_stream_entry(url) {
|
|
$.ajax({
|
|
url: url,
|
|
type: "POST",
|
|
dataType: 'json',
|
|
data: $('#stream_entry_form').serialize(),
|
|
success: function (response) {
|
|
console.log(response);
|
|
$('#stream_dialog').modal('hide');
|
|
window.location.reload();
|
|
},
|
|
error: function (error) {
|
|
console.error(error);
|
|
$('#stream_dialog .modal-content').html(data);
|
|
}
|
|
});
|
|
}
|
|
|
|
function edit_stream_entry(url) {
|
|
var data_ser = $('#stream_entry_form').serialize();
|
|
$.ajax({
|
|
url: url,
|
|
type: "POST",
|
|
dataType: 'json',
|
|
data: data_ser,
|
|
success: function (response) {
|
|
console.log(response);
|
|
$('#stream_dialog').modal('hide');
|
|
window.location.reload();
|
|
},
|
|
error: function (error) {
|
|
console.error(error);
|
|
$('#stream_dialog .modal-content').html(data);
|
|
}
|
|
});
|
|
}
|
|
function add_relay_stream() {
|
|
var url = "{{ url_for('StreamView:add_relay') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_encode_stream() {
|
|
var url = "{{ url_for('StreamView:add_encode') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_timeshift_recorder_stream() {
|
|
var url = "{{ url_for('StreamView:add_timeshift_recorder') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_timeshift_player_stream() {
|
|
var url = "{{ url_for('StreamView:add_timeshift_player') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_catchup_stream() {
|
|
var url = "{{ url_for('StreamView:add_catchup') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_test_life_stream() {
|
|
var url = "{{ url_for('StreamView:add_test_life') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_vod_relay_stream() {
|
|
var url = "{{ url_for('StreamView:add_vod_relay') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_vod_encode_stream() {
|
|
var url = "{{ url_for('StreamView:add_vod_encode') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_cod_relay_stream() {
|
|
var url = "{{ url_for('StreamView:add_cod_relay') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_cod_encode_stream() {
|
|
var url = "{{ url_for('StreamView:add_cod_encode') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function add_proxy_stream() {
|
|
var url = "{{ url_for('StreamView:add_proxy') }}";
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
add_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
function edit_stream(sid) {
|
|
var url = "/stream/edit/" + sid;
|
|
$.get(url, function(data) {
|
|
$('#stream_dialog .modal-content').html(data);
|
|
$('#stream_dialog').modal();
|
|
|
|
$('#submit').click(function(event) {
|
|
event.preventDefault();
|
|
edit_stream_entry(url);
|
|
})
|
|
});
|
|
}
|
|
|
|
// functions without modal dialog
|
|
|
|
function remove_stream(sid) {
|
|
$.ajax({
|
|
url: "{{ url_for('StreamView:remove') }}",
|
|
type: "POST",
|
|
contentType : 'application/json',
|
|
data: JSON.stringify({sids: [sid]}),
|
|
success: function (response) {
|
|
console.log(response);
|
|
window.location.reload();
|
|
},
|
|
error: function (error) {
|
|
console.error(error);
|
|
}
|
|
});
|
|
}
|
|
function get_log_stream(sid) {
|
|
$.ajax({
|
|
url: "{{ url_for('StreamView:get_log') }}",
|
|
type: "POST",
|
|
dataType: 'json',
|
|
data: {"sid":sid},
|
|
success: function (response) {
|
|
console.log(response);
|
|
window.location.reload();
|
|
},
|
|
error: function (error) {
|
|
console.error(error);
|
|
}
|
|
});
|
|
}
|
|
function get_pipeline_stream(sid) {
|
|
$.ajax({
|
|
url: "{{ url_for('StreamView:get_pipeline') }}",
|
|
type: "POST",
|
|
dataType: 'json',
|
|
data: {"sid":sid},
|
|
success: function (response) {
|
|
console.log(response);
|
|
window.location.reload();
|
|
},
|
|
error: function (error) {
|
|
console.error(error);
|
|
}
|
|
});
|
|
}
|
|
function start_stream(button, sid) {
|
|
button.blur();
|
|
$.ajax({
|
|
url: "{{ url_for('StreamView:start') }}",
|
|
type: "POST",
|
|
contentType : 'application/json',
|
|
data: JSON.stringify({sids: [sid]}),
|
|
success: function (response) {
|
|
console.log(response);
|
|
// window.location.reload();
|
|
},
|
|
error: function (error) {
|
|
console.error(error);
|
|
}
|
|
});
|
|
}
|
|
function stop_stream(button, sid) {
|
|
button.blur();
|
|
$.ajax({
|
|
url: "{{ url_for('StreamView:stop') }}",
|
|
type: "POST",
|
|
contentType : 'application/json',
|
|
data: JSON.stringify({sids: [sid]}),
|
|
success: function (response) {
|
|
console.log(response);
|
|
// window.location.reload();
|
|
},
|
|
error: function (error) {
|
|
console.error(error);
|
|
}
|
|
});
|
|
}
|
|
function restart_stream(button, sid) {
|
|
button.blur();
|
|
$.ajax({
|
|
url: "{{ url_for('StreamView:restart') }}",
|
|
type: "POST",
|
|
contentType : 'application/json',
|
|
data: JSON.stringify({sids: [sid]}),
|
|
success: function (response) {
|
|
console.log(response);
|
|
// window.location.reload();
|
|
},
|
|
error: function (error) {
|
|
console.error(error);
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
{% endblock %}
|