from datetime import datetime, timedelta from django.core.cache import caches from django.conf import settings from django.db.models import Count, Q from django.shortcuts import render from django.utils import timezone from queues.models import PlaylistSong from songs.models import Song def recache_stats(): new_stats = compute_stats() caches['default'].delete('stats') caches['default'].set('stats', new_stats, 7200) return new_stats def compute_stats(): # We want to grab the time now, because otherwise we would be reporting a minute too late last_updated = datetime.now() total_uploads = Song.objects.filter(deleted=False).exclude( user_id=None).count() upload_stats = Song.objects.filter(deleted=False).exclude( user_id=None).values( 'user__id', 'user__name').annotate(total=Count('id')).order_by( '-total', 'user__name')[:settings.STATS_TOP_COUNT] total_requests = PlaylistSong.objects.filter(state=2).exclude( Q(user_id=None) | Q(user_id__in=settings.STATS_REQUEST_IGNORE_USER_IDS)).count() request_stats = PlaylistSong.objects.filter(state=2).exclude( Q(user_id=None) | Q(user_id__in=settings.STATS_REQUEST_IGNORE_USER_IDS)).values( 'user__id', 'user__name').annotate(total=Count('id')).order_by( '-total', 'user__name')[:settings.STATS_TOP_COUNT] unique_request_stats = PlaylistSong.objects.filter(state=2).exclude( Q(user_id=None) | Q(user_id__in=settings.STATS_REQUEST_IGNORE_USER_IDS)).values( 'user__id', 'user__name').annotate( total=Count('song_id', distinct=True), ratio=Count('song_id', distinct=True) / Count('id') * 100).order_by('-total')[:settings.STATS_TOP_COUNT] most_played_songs = PlaylistSong.objects.filter(state=2).exclude( Q(user_id=None) | Q(user_id__in=settings.STATS_REQUEST_IGNORE_USER_IDS)).values( 'song__artist', 'song__title').annotate(total=Count('id')).order_by( '-total', 'song__artist')[:settings.STATS_TOP_COUNT] most_played_songs_14_days = PlaylistSong.objects.filter( state=2, played_at__gte=timezone.now() - timedelta(days=14)).exclude(user_id=None).values( 'song__artist', 'song__title').annotate(total=Count('id')).order_by( '-total', 'song__artist')[:settings.STATS_TOP_COUNT] return { 'last_updated': last_updated, 'total_uploads': total_uploads, 'upload_stats': list(upload_stats), 'total_requests': total_requests, 'request_stats': list(request_stats), 'unique_request_stats': list(unique_request_stats), 'most_played_songs': list(most_played_songs), 'most_played_songs_14_days': list(most_played_songs_14_days), 'stats_top_count': settings.STATS_TOP_COUNT, }