make stats work on streams
This commit is contained in:
		@ -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):
 | 
				
			||||||
 | 
				
			|||||||
@ -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 %}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										105
									
								
								aircox/views.py
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								aircox/views.py
									
									
									
									
									
								
							@ -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
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user