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

203 lines
6.4 KiB
Python

from datetime import timedelta
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from core.behaviors import Disableable, Publishable, Timestampable
from .managers import RadioManager, SongManager
class Album(Disableable, Publishable, Timestampable, models.Model):
"""
A model for a music album.
"""
title = models.CharField(_('title'), max_length=255, unique=True)
sorted_title = models.CharField(_('naturalized title'),
db_index=True,
editable=False,
max_length=255)
objects = models.Manager()
music = RadioManager()
class Meta:
ordering = ['sorted_title', ]
def __str__(self):
return self.title
class Artist(Disableable, Publishable, Timestampable, models.Model):
"""
A model for a music artist.
"""
alias = models.CharField(_('alias'), max_length=127, blank=True)
first_name = models.CharField(_('first name'), max_length=127, blank=True)
last_name = models.CharField(_('last name'), max_length=127, blank=True)
sorted_full_name = models.CharField(_('naturalized full name'),
db_index=True,
editable=False,
max_length=255)
objects = models.Manager()
music = RadioManager()
class Meta:
ordering = ['sorted_full_name', ]
@property
def full_name(self):
"""
String representing the artist's full name including an alias, if
available.
"""
if self.alias:
if self.first_name or self.last_name:
return '{} "{}" {}'.format(self.first_name,
self.alias,
self.last_name)
return self.alias
return '{} {}'.format(self.first_name, self.last_name)
def __str__(self):
return self.full_name
class Game(Disableable, Publishable, Timestampable, models.Model):
"""
A model for a game.
"""
title = models.CharField(_('title'), max_length=255, unique=True)
sorted_title = models.CharField(_('naturalized title'),
db_index=True,
editable=False,
max_length=255)
objects = models.Manager()
music = RadioManager()
class Meta:
ordering = ['sorted_title', ]
def __str__(self):
return self.title
class Song(Disableable, Publishable, Timestampable, models.Model):
"""
A model for a song.
"""
JINGLE = 'J'
SONG = 'S'
TYPE_CHOICES = (
(JINGLE, 'Jingle'),
(SONG, 'Song'),
)
album = models.ForeignKey(Album,
on_delete=models.SET_NULL,
null=True,
blank=True)
artists = models.ManyToManyField(Artist)
game = models.ForeignKey(Game,
on_delete=models.SET_NULL,
null=True,
blank=True)
song_type = models.CharField(_('song type'),
max_length=1,
choices=TYPE_CHOICES,
default=SONG)
title = models.CharField(_('title'), max_length=255)
num_played = models.PositiveIntegerField(_('number of times played'),
default=0)
last_played = models.DateTimeField(_('was last played'),
null=True,
blank=True,
editable=False)
length = models.DecimalField(_('song length (in seconds)'),
max_digits=8,
decimal_places=2,
null=True,
blank=True)
path = models.TextField(_('absolute path to song file'))
sorted_title = models.CharField(_('naturalized title'),
db_index=True,
editable=False,
max_length=255)
objects = models.Manager()
music = SongManager()
class Meta:
ordering = ['sorted_title', ]
def _is_jingle(self):
"""
Is the object a jingle?
"""
return self.song_type == 'J'
_is_jingle.boolean = True
is_jingle = property(_is_jingle)
def _is_song(self):
"""
Is the object a song?
"""
return self.song_type == 'S'
_is_song.boolean = True
is_song = property(_is_song)
def _full_title(self):
"""
String representing the entire song title, including the game and
artists involved.
"""
if self._is_song():
enabled_artists = self.artists.all().filter(disabled=False)
all_artists = ', '.join([a.full_name for a in enabled_artists])
return '{} - {} [{}]'.format(self.game.title,
self.title,
all_artists)
return self.title
full_title = property(_full_title)
def get_time_until_requestable(self):
"""
Length of time before a song can be requested again.
"""
if self._is_song():
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._is_song():
if self.last_played:
return self.last_played + Song.music.wait_total()
return timezone.now()
return None
def _is_requestable(self):
"""
Can the song be requested or not?
"""
if self._is_song():
return self.get_date_when_requestable() <= timezone.now()
return False
_is_requestable.boolean = True
is_requestable = property(_is_requestable)
def __str__(self):
return self.title