mirror of
https://gitlab.science.ru.nl/technicie/MarietjeDjango.git
synced 2025-12-10 10:22:20 +01:00
Marietje 4.1: Addition of Django REST framework, Swagger, Dark mode and updates to Django and Bootstrap
This commit is contained in:
68
marietje/songs/services.py
Normal file
68
marietje/songs/services.py
Normal file
@ -0,0 +1,68 @@
|
||||
from marietje.utils import send_to_bertha
|
||||
from queues.models import PlaylistSong
|
||||
from songs.models import Song
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.db.models import Sum, Value
|
||||
from django.db import transaction
|
||||
from mutagen import File
|
||||
|
||||
|
||||
class UploadException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
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.astimezone().weekday() <= 4:
|
||||
return False # Queued in the weekend
|
||||
if not 7 <= ps.played_at.astimezone().hour <= 22:
|
||||
# Because of timezone shit, I allow for an extra hour of leeway
|
||||
return False # Queued outside of regular opening hours
|
||||
return True
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def request_weight(ps):
|
||||
if is_regular_queue(ps):
|
||||
return float(ps.song.duration)
|
||||
# Count other requests for 10%
|
||||
return 0.10 * float(ps.song.duration)
|
||||
|
||||
|
||||
def get_upload_stats(user):
|
||||
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(x=Coalesce(Sum("duration"), Value(0)))["x"]
|
||||
return {"queued_score": queued_score, "upload_score": upload_score}
|
||||
|
||||
|
||||
def get_reputation(user) -> float:
|
||||
try:
|
||||
stats = get_upload_stats(user)
|
||||
ratio = stats["queued_score"] / (2.0 * stats["upload_score"])
|
||||
return ratio
|
||||
except ZeroDivisionError:
|
||||
return 99999.0 # high enough
|
||||
|
||||
|
||||
def check_upload_stats(user):
|
||||
# Allow upload if the user has a good reputation
|
||||
# Score function:
|
||||
# - U = duration * songs uploaded
|
||||
# - Q = duration * songs queued
|
||||
# - If 2*U < Q: allow upload (otherwise don't)
|
||||
if user.is_superuser:
|
||||
return True
|
||||
|
||||
ratio = get_reputation(user)
|
||||
return ratio >= 1.0
|
||||
|
||||
|
||||
def upload_file(file, artist, title, user):
|
||||
duration = File(file).info.length
|
||||
bertha_hash = send_to_bertha(file).decode("ascii")
|
||||
if not bertha_hash:
|
||||
raise UploadException("Files not uploaded correctly.")
|
||||
return Song.objects.create(user=user, artist=artist, title=title, hash=bertha_hash, duration=duration)
|
||||
Reference in New Issue
Block a user