diff --git a/marietje/api/views.py b/marietje/api/views.py index fe25e86..98040c5 100644 --- a/marietje/api/views.py +++ b/marietje/api/views.py @@ -258,14 +258,14 @@ def upload(request): # - If 3*U < Q: allow upload (otherwise don't) try: stats = upload_stats(request.user) - ratio = stats['minutes_queued'] / (3.0 * stats['minutes_upload']) + ratio = stats['queued_score'] / (3.0 * stats['upload_score']) ratiostr = '{:.2f}'.format(ratio) except ZeroDivisionError: ratio = 99999.0 # high enough ratiostr = "∞" if not request.user.is_superuser and ratio < 1.0: - msg = 'Queue-to-upload ratio too high. Please queue some more before uploading. ({})' + msg = 'Queue-to-upload ratio too low. Please queue more during regular opening hours to improve the ratio. (Ratio: {} ≱ 1.00)' return JsonResponse({'success': False, 'errorMessage': msg.format(ratiostr)}) for i, file in enumerate(files): @@ -282,7 +282,6 @@ def upload(request): upload_counter.inc() return JsonResponse({'success': True}) - @require_http_methods(["POST"]) @api_auth_required def volume_down(request): @@ -312,10 +311,28 @@ def mute(request): command.save() return JsonResponse({}) -@transaction.atomic def upload_stats(user): - q = PlaylistSong.objects.filter(user=user, state=2, song__deleted=False).aggregate( - minutes_queued=Coalesce(Sum('song__duration'), Value(0))) - q.update(Song.objects.filter(user=user, deleted=False).aggregate( - minutes_upload=Coalesce(Sum('duration'), Value(0)))) - return q + songs_queued = PlaylistSong.objects.select_related('song').filter( + user=user, state=2, song__deleted=False) + queued_score = sum(_request_weight(x) for x in songs_queued) + upload_score = Song.objects.filter( + user=user, deleted=False).aggregate( + minutes_upload=Coalesce(Sum('duration'), Value(0))) + return {'queued_score': queued_score, 'upload_score': upload_score} + +@transaction.atomic +def _request_weight(ps): + def _is_regular_queue(ps): + if not ps.played_at: + # Request is from the old times, assume good + return True + if not 0 < ps.played_at.weekday() <= 4: + return False # Queued in the weekend + if not 8 <= ps.played_at.hour <= 21: + return False # Queued outside of regular opening hours + return True + + if _is_regular_queue(ps): + return float(ps.song.duration) + # Count other requests for 10% + return 0.10 * float(ps.song.duration)