From 6e12099f3acb7e7f1451d80d48a5077eb27b4740 Mon Sep 17 00:00:00 2001 From: Daan Sprenkels Date: Thu, 2 Nov 2017 18:45:33 +0100 Subject: [PATCH] Add queue/upload restriction --- marietje/api/views.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/marietje/api/views.py b/marietje/api/views.py index 8b63d53..58816ab 100644 --- a/marietje/api/views.py +++ b/marietje/api/views.py @@ -4,7 +4,9 @@ from functools import wraps import django.middleware.csrf as csrf from django.contrib.auth import authenticate, login from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger -from django.db.models import Q +from django.db import transaction +from django.db.models import Q, Sum, Value +from django.db.models.functions import Coalesce from django.http import JsonResponse, HttpResponseForbidden from django.shortcuts import get_object_or_404 from django.views.decorators.http import require_http_methods @@ -238,6 +240,17 @@ def upload(request): if not title: return JsonResponse({'success': False, 'errorMessage': 'Please enter titles which are not empty.'}) + # Allow upload if the user has a good reputation + # Score function: + # - U = duration * songs uploaded + # - Q = duration * songs queued + # - If 3*U < Q: allow upload (otherwise don't) + stats = upload_stats(request.user) + ratio = stats['minutes_queued'] / (3.0 * stats['minutes_upload']) + if not request.user.is_superuser and ratio < 1.0: + msg = 'Queue-to-upload ratio too high. Please queue some more before uploading. ({:.2f})' + return JsonResponse({'success': False, 'errorMessage': msg.format(ratio)}) + for i, file in enumerate(files): duration = File(file).info.length hash = send_to_bertha(file) @@ -277,3 +290,11 @@ def mute(request): command = QueueCommand(queue=request.user.queue, command='mute') command.save() return JsonResponse({}) + +@transaction.atomic +def upload_stats(user): + q = PlaylistSong.objects.filter(user=user, 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