work on monitor

This commit is contained in:
jeffrey
2016-11-26 17:32:30 +01:00
parent 7e571a6794
commit aa1c21a8c8
38 changed files with 412 additions and 160 deletions

View File

@ -5,6 +5,7 @@ Base configuration file to configure a station on liquidsoap.
# Interactive elements:
An interactive element is accessible to the people, in order to:
- get metadata
- seek
- skip the current sound
- enable/disable it
@ -21,13 +22,47 @@ put station specific configuration in the template itself.
{% block functions %}
{% comment %}
Seek function
{% endcomment %}
def seek(source, t) =
t = float_of_string(default=0.,t)
ret = source.seek(source,t)
log("seek #{ret} seconds.")
"#{ret}"
end
{% comment %}
Transition to live sources
{% endcomment %}
def to_live(stream,live)
stream = fade.final(duration=2., type='log', stream)
live = fade.initial(duration=2., type='log', live)
add(normalize=false, [stream,live])
end
{% comment %}
Transition to stream sources
{% endcomment %}
def to_stream(live,stream)
source.skip(stream)
add(normalize=false, [live,stream])
end
{% comment %}
An interactive source is a source that:
- is skippable through the given id on external interfaces
- is seekable through the given id and amount of seconds on e.i.
- can be disabled
- store metadata
{% endcomment %}
def interactive_source (id, s, ~active=true, ~disable_switch=false) =
server.register(namespace=id,
description="Seek to a relative position",
usage="seek <duration>",
"seek", fun (x) -> begin seek(s, x) end)
s = store_metadata(id=id, size=1, s)
add_skip_command(s)
if disable_switch then
@ -88,7 +123,7 @@ stream = fallback([
{% elif stream.begin and stream.end %}
at({ {{stream.begin}}-{{stream.end}} },
stream("{{ source.id }}", "{{ source.path }}")),
{% elif not stream %}
{% else %}
stream("{{ source.id }}", "{{ source.path }}"),
{% endif %}
{% endwith %}
@ -104,19 +139,6 @@ stream = fallback([
{% block sources_extras %}
{% endblock %}
def to_live(stream,live)
stream = fade.final(duration=2., type='log', stream)
live = fade.initial(duration=2., type='log', live)
add(normalize=false, [stream,live])
end
def to_stream(live,stream)
source.skip(stream)
add(normalize=false, [live,stream])
end
{% block station %}
{{ station.streamer.id }} = interactive_source (
"{{ station.streamer.id }}",

View File

@ -1,47 +1,60 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
{% load static %}
{% block title %}
{% trans "Monitoring streamer" %}
{% endblock %}
{% block content %}
<style>
.actions button {
padding: 0em;
margin: 0.2em;
text-align: center;
}
.actions button img {
max-width: 2em;
max-height: 2em;
}
.sources img {
max-width: 2.5em;
max-height: 2em;
}
.float_right {
float: right;
}
.table_section_header {
font-style: italic;
}
section.station {
padding: 0.4em;
font-size: 0.9em;
}
section.station header {
margin: 0.4em 0em;
}
section.station header > * {
margin: 0em 0.2em;
}
section.station h1 {
display: inline;
margin: 0px;
font-size: 1.4em;
}
section.station button {
float: right;
}
section.station .sources {
border: 1px grey solid;
width: 100%;
}
section.station .source {
margin: 0.2em 0em;
section.station .name {
width: 15em;
}
section.station .name {
display: inline-block;
width: 10em;
}
section.station .file {
color: #007EDF;
section.station .file {
color: #007EDF;
}
}
section.station .source.current:before {
section.station .actions {
width: 4em;
text-align: right;
}
section.station .sources .current:before {
content: '▶';
color: red;
margin: 0em 1em;
@ -54,7 +67,7 @@ var Monitor = {
return document.cookie.replace(/.*csrftoken=([^;]+)(;.*|$)/, '$1');
},
post: function(station, source, action) {
run: function(action, station, source) {
var params = 'station=' + station + '&&action=' + action;
if(source)
params += '&&source=' + source;
@ -69,10 +82,6 @@ var Monitor = {
this.update();
},
skip: function(station, source) {
this.post(station, source, 'skip');
},
update: function(timeout) {
var req = new XMLHttpRequest()
req.open('GET', '{% url 'aircox.monitor' %}', true);
@ -96,30 +105,89 @@ var Monitor = {
},
}
Monitor.update(1000);
Monitor.update(50000);
</script>
<header>
<h1>{% trans "Monitor Streamer" %}</h1>
<input type="button" onclick="Monitor.update();"
value="{% trans "refresh" %}">
</header>
<div id='stations'>
{% for station in stations %}
<section class="station">
<header>
<h1>{{ station.name }}</h1>
<button onclick="Monitor.skip('{{ station.name }}');">{% trans "skip" %}</button>
<button onclick="Monitor.update();">{% trans "update" %}</button>
<h2>{{ station.name }}</h2>
</header>
<div class="sources">
{% for source in station.all_sources %}
{% if source.controller.current_sound %}
<div class="source{% if source == station.controller.current_source %} current{% endif %}">
<span class="name">{{ source.name }}</span>
<span class="file">{{ source.controller.current_sound }}</span>
<button onclick="Monitor.skip('{{ station.name }}','{{ source.name }}');">
{% trans "skip" %}</button>
</div>
{% endif %}
<table cellspacing="0" cellpadding="0" class="sources object">
<tr>
<th class="name" colspan=2>{{ station.name }}</th>
<td>
{% with station.streamer.current_source.name as current_source %}
{% blocktrans %}
Current source: {{ current_source }}
{% endblocktrans %}
{% endwith %}
</td>
<td class="actions">
<button onclick="Monitor.run('restart', '{{ station.name }}');">
<img src="{% static "aircox/images/redo.png" %}" alt="{% trans "restart" %}"></button>
<button onclick="Monitor.run('skip', '{{ station.name }}');">
<img src="{% static "aircox/images/playback_next.png" %}" alt="{% trans "skip" %}"></button>
</td>
</tr>
<tr class="table_section_header">
<td colspan=2>{% trans "Source" %}</td>
<td>{% trans "File" %}</td>
<td>{% trans "Actions*" %}</td>
</tr>
{% for source in station.sources %}
<tr class="source">
<td class="name">
{% if source.is_dealer %}
{% trans "Diffusions" %}
{% else %}
{{ source.name }}
{% endif %}
</td>
<td class="source_info">
{% if source.name == station.streamer.current_source.name %}
<img src="{% static "aircox/images/play.png" %}" alt="{% trans "current" %}">
{% endif %}
{% if source.is_dealer %}
<img src="{% static "aircox/images/calendar_month.png" %}" alt="{% trans "diffusions" %}">
{% elif not source.program.is_show %}
<img src="{% static "aircox/images/schuffle.png" %}" alt="{% trans "stream" %}">
{% endif %}
</td>
<td class="file">
{% if source.is_dealer %}
{{ source.playlist|join:"<br>" }}
{% else %}
{{ source.current_sound }}
{% endif %}
</td>
<td class="actions">
<button onclick="Monitor.run('restart', '{{ station.name }}', '{{ source.name }}');">
<img src="{% static "aircox/images/redo.png" %}" alt="{% trans "restart" %}"></button>
<button onclick="Monitor.run('skip', '{{ station.name }}', '{{ source.name }}');">
<img src="{% static "aircox/images/playback_next.png" %}" alt="{% trans "skip" %}"></button>
</td>
</tr>
{% endfor %}
</div>
</table>
</section>
{% endfor %}
</div>
<div class="info small">
{% blocktrans %}
*: Due to some technical issues, it might take up to 30 seconds to execute the given action.
{% endblocktrans %}
</div>
</div>
{% endblock %}

View File

@ -7,80 +7,79 @@
{% endblock %}
{% block content %}
<div id='content'>
<h1>{% trans "Statistics of the stations" %}</h1>
<header>
<h1>{% trans "Statistics of the stations" %}</h1>
{# TODO here #}
<form action="?" method="GET">
Go to this date:
<input name="day" type="number" placeholder="{% trans "day" %}"
value="{{ statistics.0.date.day }}"></input>
<input name="month" type="number" placeholder="{% trans "month" %}"
value="{{ statistics.0.date.month }}"></input>
<input name="year" type="number" placeholder="{% trans "year" %}"
value="{{ statistics.0.date.year }}"></input>
<button type="submit">Show</button>
</form>
{# TODO here #}
<form action="?" method="GET">
Go to this date:
<input name="day" type="number" placeholder="{% trans "day" %}"
value="{{ statistics.0.date.day }}"></input>
<input name="month" type="number" placeholder="{% trans "month" %}"
value="{{ statistics.0.date.month }}"></input>
<input name="year" type="number" placeholder="{% trans "year" %}"
value="{{ statistics.0.date.year }}"></input>
<input type="submit" value="{% trans "Show" %}">
</form>
</header>
{% for stats in statistics %}
<section class="station">
<header>
<h2>{{ stats.station.name }},
{{ stats.date|date:'l d F Y' }}</h2>
</header>
{% for stats in statistics %}
<section class="station">
<header>
<h2>{{ stats.station.name }},
{{ stats.date|date:'l d F Y' }}</h2>
</header>
<table cellspacing="0" cellpading="0" class="object">
<tr class="header">
<th>{% trans "Date" %}</th>
<th width="10%">{% trans "Type" %}
{# Translators "Header for statistics view" #}
<th width="50%">{% trans "Diffusion or sound played" %}
<th width="30%">{% trans "Tags" %}</th>
<table cellspacing="0" cellpadding="0" class="object">
<tr class="header">
<th>{% trans "Date" %}</th>
<th width="10%">{% trans "Type" %}
{# Translators "Header for statistics view" #}
<th width="50%">{% trans "Diffusion or sound played" %}
<th width="30%">{% trans "Tags" %}</th>
</tr>
{% for item in stats.items %}
<tr>
<th>{{ item.date|time:"H:i" }}</th>
<th>{{ item.type }}</th>
<th>{{ item.name }}</th>
<th>{% for tag,count in item.tags.items %}
{{ tag }}: {{ count }};
{% endfor %}</th>
</tr>
{% for item in stats.items %}
<tr>
<th>{{ item.date|time:"H:i" }}</th>
<th>{{ item.type }}</th>
<th>{{ item.name }}</th>
<th>{% for tag,count in item.tags.items %}
{{ tag }}: {{ count }};
{% endfor %}</th>
</tr>
{% for track in item.tracks %}
<tr class="subdata">
<td>{{ track.date|time:"H:i" }}</td>
<td>{% trans "Track" %}</td>
<td>{{ track.artist }} -- <emph>{{ track.title }}</emph> {{ track.version }}</td>
<td>{{ track.tags.all|join:', ' }}</td>
</tr>
{% endfor %}
{% for track in item.tracks %}
<tr class="subdata">
<td>{{ track.date|time:"H:i" }}</td>
<td>{% trans "Track" %}</td>
<td>{{ track.artist }} -- <emph>{{ track.title }}</emph> {{ track.version }}</td>
<td>{{ track.tags.all|join:', ' }}</td>
</tr>
{% endfor %}
{% endfor %}
<tr class="bottom">
<th>{{ stats.date|date:'d/m/Y' }}</th>
<th>{% trans "Total" %}</th>
{# TODO: translation block #}
<th>
{% with stats.items|length as items_count %}
{% with stats.count as tracks_count %}
{% blocktrans %}
{{ items_count }} items, with a total of {{ tracks_count }} tracks
{% endblocktrans %}
{% endwith %}
{% endwith %}
</th>
<th>{% for tag, count, average in stats.tags %}
<span>{{ tag }}: <b>{{ average|floatformat }}%</b> ({{ count }})<br>
{% endfor %}
</th>
</tr>
</table>
</section>
{% endfor %}
</div>
<tr class="bottom">
<th>{{ stats.date|date:'d/m/Y' }}</th>
<th>{% trans "Total" %}</th>
<th>
{% with stats.items|length as items_count %}
{% with stats.count as tracks_count %}
{% blocktrans %}
{{ items_count }} items, with a total of {{ tracks_count }} tracks
{% endblocktrans %}
{% endwith %}
{% endwith %}
</th>
<th>{% for tag, count, average in stats.tags %}
<span>{{ tag }}: <b>{{ average|floatformat }}%</b> ({{ count }})<br>
{% endfor %}
</th>
</tr>
</table>
</section>
{% endfor %}
{% endblock %}