Add requestable functionality. Code cleanup.

This commit is contained in:
Josh Washburne 2018-03-28 12:42:28 -04:00
parent def413a74f
commit 4138015054
2 changed files with 79 additions and 15 deletions

View file

@ -1,6 +1,7 @@
from datetime import timedelta from datetime import timedelta
from decimal import * from decimal import getcontext, Decimal, ROUND_UP
from django.apps import apps
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
@ -17,9 +18,15 @@ class SongManager(models.Manager):
Custom object manager for filtering out common behaviors for a playlist. Custom object manager for filtering out common behaviors for a playlist.
""" """
def get_queryset(self): def get_queryset(self):
"""
Return customized default QuerySet for Songs.
"""
return SongQuerySet(self.model, using=self._db) return SongQuerySet(self.model, using=self._db)
def available(self): def available(self):
"""
Songs that are currently published and are enabled.
"""
return self.get_queryset().songs().enabled().published() return self.get_queryset().songs().enabled().published()
def playlist_length(self): def playlist_length(self):
@ -34,16 +41,33 @@ class SongManager(models.Manager):
based on the replay ratio set in the application settings. based on the replay ratio set in the application settings.
""" """
wait = self.playlist_length() * Decimal(get_setting('replay_ratio')) wait = self.playlist_length() * Decimal(get_setting('replay_ratio'))
return wait.quantize(Decimal('.01'), rounding=ROUND_UP) wait = wait.quantize(Decimal('.01'), rounding=ROUND_UP)
return timedelta(seconds=float(wait))
def datetime_from_wait(self): def datetime_from_wait(self):
""" """
Datetime of now minus the default wait time for played songs. Datetime of now minus the default wait time for played songs.
""" """
return timezone.now() - timedelta(seconds=float(self.wait_total())) return timezone.now() - self.wait_total()
def playable(self): 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().filter( return self.available().filter(
models.Q(last_played__lt=self.datetime_from_wait()) | models.Q(last_played__lt=self.datetime_from_wait()) |
models.Q(last_played__isnull=True) models.Q(last_played__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
SongRequest = apps.get_model(app_label='profiles',
model_name='SongRequest')
requests = SongRequest.music.unplayed().values_list('song__id',
flat=True)
return self.playable().exclude(id__in=requests)

View file

@ -1,4 +1,7 @@
from datetime import timedelta
from django.db import models from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from core.behaviors import Timestampable from core.behaviors import Timestampable
@ -42,15 +45,17 @@ class Artist(Disableable, Publishable, Timestampable, models.Model):
@property @property
def full_name(self): def full_name(self):
if not self.alias: """
return '{} {}'.format(self.first_name, self.last_name) String representing the artist's full name including an alias, if
else: available.
if not self.first_name or not self.last_name: """
return self.alias if self.alias:
else: if self.first_name or self.last_name:
return '{} "{}" {}'.format(self.first_name, return '{} "{}" {}'.format(self.first_name,
self.alias, self.alias,
self.last_name) self.last_name)
return self.alias
return '{} {}'.format(self.first_name, self.last_name)
def __str__(self): def __str__(self):
return self.full_name return self.full_name
@ -124,13 +129,48 @@ class Song(Disableable, Publishable, Timestampable, models.Model):
@property @property
def full_title(self): def full_title(self):
if self.song_type == 'J': """
return self.title String representing the entire song title, including the game and
else: artists involved.
"""
if self.song_type == 'S':
all_artists = ', '.join([a.full_name for a in self.artists.all()]) all_artists = ', '.join([a.full_name for a in self.artists.all()])
return '{} - {} ({})'.format(self.game.title, return '{} - {} [{}]'.format(self.game.title,
self.title, self.title,
all_artists) all_artists)
return self.title
def get_time_until_requestable(self):
"""
Length of time before a song can be requested again.
"""
if self.song_type == 'S':
if self.last_played:
allowed_datetime = Song.music.datetime_from_wait()
remaining_wait = self.last_played - allowed_datetime
if remaining_wait.total_seconds() > 0:
return remaining_wait
return timedelta(seconds=0)
return timedelta(seconds=0)
return None
def get_date_when_requestable(self):
"""
Datetime when a song can be requested again.
"""
if self.song_type == 'S':
return self.last_played + Song.music.wait_total()
return None
def _is_requestable(self):
"""
Can the song be requested or not?
"""
if self.song_type == 'S':
return self.get_date_when_requestable() <= timezone.now()
return False
_is_requestable.boolean = True
is_requestable = property(_is_requestable)
def __str__(self): def __str__(self):
return self.title return self.title