spradio-server-django/savepointradio/radio/managers.py

145 lines
4.2 KiB
Python
Raw Normal View History

'''
Django Model Managers for the Radio application.
'''
from datetime import timedelta
from decimal import getcontext, Decimal, ROUND_UP
from random import randint
from django.apps import apps
from django.db import models
from django.utils import timezone
from core.utils import get_setting
from .querysets import RadioQuerySet, SongQuerySet
# Set decimal precision
getcontext().prec = 16
class RadioManager(models.Manager):
'''
Custom object manager for filtering out common behaviors for radio
objects.
'''
def get_queryset(self):
'''
Return customized default QuerySet.
'''
return RadioQuerySet(self.model, using=self._db)
def disabled(self):
'''
Radio objects that are marked as disabled.
'''
return self.get_queryset().disabled()
def enabled(self):
'''
Radio objects that are marked as enabled.
'''
return self.get_queryset().enabled()
def published(self):
'''
Radio objects that are marked as published.
'''
return self.get_queryset().published()
def unpublished(self):
'''
Radio objects that are marked as unpublished.
'''
return self.get_queryset().unpublished()
def available(self):
'''
Radio objects that are enabled and published.
'''
return self.enabled().published()
class SongManager(RadioManager):
'''
Custom object manager for filtering out common behaviors for Song objects.
'''
def get_queryset(self):
'''
Return customized default QuerySet for Songs.
'''
return SongQuerySet(self.model, using=self._db)
def available_jingles(self):
'''
Jingles that are currently published and are enabled.
'''
2018-09-24 17:02:52 +00:00
return self.available().jingles()
def available_songs(self):
'''
Songs that are currently published and are enabled.
'''
2018-09-24 17:02:52 +00:00
return self.available().songs()
2018-03-27 19:58:26 +00:00
def playlist_length(self):
'''
Total length of available songs in the playlist (in seconds).
'''
a_songs = self.available_songs()
length = a_songs.aggregate(
total_time=models.Sum('active_store__length')
)
return length['total_time']
def wait_total(self, adjusted_ratio=0.0):
'''
Default length in seconds before a song can be played again. This is
based on the replay ratio set in the application settings.
'''
total_ratio = get_setting('replay_ratio') + adjusted_ratio
wait = self.playlist_length() * Decimal(total_ratio)
wait = wait.quantize(Decimal('.01'), rounding=ROUND_UP)
return timedelta(seconds=float(wait))
def datetime_from_wait(self):
'''
Datetime of now minus the default wait time for played songs.
'''
return timezone.now() - self.wait_total()
def playable(self):
'''
Songs that are playable because they are available (enabled &
published) and they have not been played within the default wait time
(or at all).
'''
return self.available_songs().filter(
models.Q(next_play__lt=timezone.now()) |
models.Q(next_play__isnull=True)
)
def requestable(self):
'''
Songs that can be placed in the request queue for playback.
'''
# Import SongRequest here to get rid of circular dependencies
song_request = apps.get_model(app_label='profiles',
model_name='SongRequest')
requests = song_request.music.unplayed().values_list('song__id',
flat=True)
return self.playable().exclude(id__in=requests)
def get_random_requestable_song(self):
'''
Pick a random requestable song and return it.
'''
return self.requestable()[randint(0, self.requestable().count() - 1)]
def get_random_jingle(self):
'''
Pick a random jingle and return it.
'''
random_index = randint(0, self.available_jingles().count() - 1)
return self.available_jingles()[random_index]