make stats work on streams

This commit is contained in:
bkfox 2016-10-26 21:48:58 +02:00
parent 7804183413
commit 28597e470c
3 changed files with 86 additions and 40 deletions

View File

@ -132,7 +132,8 @@ class Monitor:
type = Log.Type.play, type = Log.Type.play,
source = log.source, source = log.source,
date = pos, date = pos,
related = track related = track,
comment = track,
) )
def sync_playlists(self): def sync_playlists(self):

View File

@ -18,21 +18,17 @@
{% for item in stats.items %} {% for item in stats.items %}
<tr class="log"> <tr class="log">
<td>{{ item.date|date:"H:i" }}</td> <th>{{ item.date|date:"H:i" }}</th>
{# TODO: logs #} <th>{{ item.name }}</th>
{% if 'program' in item %} <th>{% for tag,count in item.tags.items %}
<td>{{ item.program.name }}</td>
{% else %}
<td>{{ item.comment }}</td>
{% endif %}
<td>{% for tag,count in item.tags %}
{{ tag }}: {{ count }}; {{ tag }}: {{ count }};
{% endfor %}</td> {% endfor %}</th>
<th>{{ item.type }}</th>
</tr> </tr>
{% for track in item.tracks %} {% for track in item.tracks %}
<tr class="track"> <tr class="track">
<td></td> <td>{{ track.date|date:"H:i" }}</td>
<td>{{ track.artist }} -- <emph>{{ track.title }}</emph> {{ track.version }}</td> <td>{{ track.artist }} -- <emph>{{ track.title }}</emph> {{ track.version }}</td>
<td>{{ track.tags.all|join:', ' }}</td> <td>{{ track.tags.all|join:', ' }}</td>
</tr> </tr>
@ -42,7 +38,7 @@
<tr> <tr>
<td>{{ stats.date|date:'d/m/Y' }}</td> <td>{{ stats.date|date:'d/m/Y' }}</td>
{# TODO: translation block #} {# TODO: translation block #}
<td>{% trans "Total and average" %} ({{ stats.tracks_count }} tracks)</td> <td>{% trans "Total and average" %} ({{ stats.count }} tracks)</td>
<td>{% for tag, count, average in stats.tags %} <td>{% for tag, count, average in stats.tags %}
{{ tag }}: <b>{{ count }} / {{ average|floatformat }}%</b>; {{ tag }}: <b>{{ count }} / {{ average|floatformat }}%</b>;
{% endfor %} {% endfor %}

View File

@ -126,7 +126,38 @@ class Monitor(View,TemplateResponseMixin,LoginRequiredMixin):
class StatisticsView(View,TemplateResponseMixin,LoginRequiredMixin): class StatisticsView(View,TemplateResponseMixin,LoginRequiredMixin):
template_name = 'aircox/controllers/stats.html' template_name = 'aircox/controllers/stats.html'
class Stats: class Taggable:
tags = None
def add_tags(self, qs):
if not self.tags:
self.tags = {}
qs = qs.values('tags__name').annotate(count = Count('tags__name')) \
.order_by('tags__name')
for q in qs:
key = q['tags__name']
if not key:
continue
value = q['count']
if key not in self.tags:
self.tags[key] = value
else:
self.tags[key] += value
class Item (Taggable):
type = ''
date = None
name = None
related = None
tracks = None
tags = None
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
class Stats (Taggable):
station = None station = None
date = None date = None
items = None items = None
@ -136,48 +167,66 @@ class StatisticsView(View,TemplateResponseMixin,LoginRequiredMixin):
- tags: [ (tag_name, tag_count), ...] - tags: [ (tag_name, tag_count), ...]
- tracks_count: total count of tracks - tracks_count: total count of tracks
""" """
tags = None count = 0
"""
Total of played track's tags: [(tag_name, tag_count, tag_average), ...]
on the station for the given date. Note: tag_average is in %
"""
tracks_count = 0
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.items = [] self.items = []
self.tags = []
self.__dict__.update(kwargs) self.__dict__.update(kwargs)
def get_stats(self, station, date): def get_stats(self, station, date):
""" """
Return statistics for the given station and date. Return statistics for the given station and date.
""" """
items = station.on_air(date) stats = self.Stats(station = station, date = date,
stats = self.Stats(station = station, items = items, date = date) items = [], tags = {})
sums = {} last_item = None
total = 0 for elm in station.on_air(date):
qs = None
item = None
if type(elm) == models.Diffusion:
qs = models.Track.objects.get_for(elm)
item = self.Item(
type = _('Diffusion'),
date = elm.date,
name = elm.program.name,
related = elm,
tracks = qs[:]
)
item.add_tags(qs)
stats.items.append(item)
stats.count += len(item.tracks)
for item in items: else:
qs = models.Track.objects.get_for(item) # type is Track (related object of a track is a sound)
item.tracks = qs stream = elm.related.related
item.tracks_count = qs.count() qs = models.Track.objects.filter(pk = elm.related.pk)
qs = qs.values('tags__name').annotate(count = Count('tags__name')) \ if last_item and last_item.related == stream:
.order_by('tags__name') item = last_item
item.tags = [ else:
(q['tags__name'], q['count']) item = self.Item(
for q in qs if q['tags__name'] type = _('Stream'),
] date = elm.date,
for name, count in item.tags: name = stream.path,
sums[name] = (sums.get(name) or 0) + count related = stream,
tracks = []
)
stats.items.append(item)
total += item.tracks_count elm.related.date = elm.date
item.tracks.insert(0, elm.related)
item.date = min(elm.date, item.date)
item.add_tags(qs)
stats.count += 1
stats.tracks_count = total last_item = item
stats.add_tags(qs)
print(stats.tags)
stats.tags = [ stats.tags = [
(name, count, count / total * 100) (name, count, count / stats.count * 100)
for name, count in sums.items() for name, count in stats.tags.items()
] ]
stats.tags.sort(key=lambda s: s[0]) stats.tags.sort(key=lambda s: s[0])
return stats return stats