code quality

This commit is contained in:
bkfox
2023-03-13 17:47:00 +01:00
parent 934817da8a
commit 112770eddf
162 changed files with 4798 additions and 4069 deletions

View File

@ -1,25 +1,20 @@
import os
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from filer.fields.image import FilerImageField
from .. import settings
__all__ = ('Station', 'StationQuerySet', 'Port')
__all__ = ("Station", "StationQuerySet", "Port")
class StationQuerySet(models.QuerySet):
def default(self, station=None):
"""
Return station model instance, using defaults or
given one.
"""
"""Return station model instance, using defaults or given one."""
if station is None:
return self.order_by('-default', 'pk').first()
return self.order_by("-default", "pk").first()
return self.filter(pk=station).first()
def active(self):
@ -27,66 +22,79 @@ class StationQuerySet(models.QuerySet):
class Station(models.Model):
"""
Represents a radio station, to which multiple programs are attached
and that is used as the top object for everything.
"""Represents a radio station, to which multiple programs are attached and
that is used as the top object for everything.
A Station holds controllers for the audio stream generation too.
Theses are set up when needed (at the first access to these elements)
then cached.
Theses are set up when needed (at the first access to these
elements) then cached.
"""
name = models.CharField(_('name'), max_length=64)
slug = models.SlugField(_('slug'), max_length=64, unique=True)
name = models.CharField(_("name"), max_length=64)
slug = models.SlugField(_("slug"), max_length=64, unique=True)
# FIXME: remove - should be decided only by Streamer controller + settings
path = models.CharField(
_('path'),
help_text=_('path to the working directory'),
_("path"),
help_text=_("path to the working directory"),
max_length=256,
blank=True,
)
default = models.BooleanField(
_('default station'),
_("default station"),
default=False,
help_text=_('use this station as the main one.')
help_text=_("use this station as the main one."),
)
active = models.BooleanField(
_('active'),
_("active"),
default=True,
help_text=_('whether this station is still active or not.')
help_text=_("whether this station is still active or not."),
)
logo = FilerImageField(
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name=_('Logo'),
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name=_("Logo"),
)
hosts = models.TextField(
_("website's urls"), max_length=512, null=True, blank=True,
help_text=_('specify one url per line')
_("website's urls"),
max_length=512,
null=True,
blank=True,
help_text=_("specify one url per line"),
)
audio_streams = models.TextField(
_("audio streams"), max_length=2048, null=True, blank=True,
help_text=_("Audio streams urls used by station's player. One url "
"a line.")
_("audio streams"),
max_length=2048,
null=True,
blank=True,
help_text=_(
"Audio streams urls used by station's player. One url " "a line."
),
)
default_cover = FilerImageField(
on_delete=models.SET_NULL,
verbose_name=_('Default pages\' cover'), null=True, blank=True,
related_name='+',
verbose_name=_("Default pages' cover"),
null=True,
blank=True,
related_name="+",
)
objects = StationQuerySet.as_manager()
@cached_property
def streams(self):
""" Audio streams as list of urls. """
return self.audio_streams.split('\n') if self.audio_streams else []
"""Audio streams as list of urls."""
return self.audio_streams.split("\n") if self.audio_streams else []
def __str__(self):
return self.name
def save(self, make_sources=True, *args, **kwargs):
if not self.path:
self.path = os.path.join(settings.AIRCOX_CONTROLLERS_WORKING_DIR,
self.slug.replace('-', '_'))
self.path = os.path.join(
settings.AIRCOX_CONTROLLERS_WORKING_DIR,
self.slug.replace("-", "_"),
)
if self.default:
qs = Station.objects.filter(default=True)
@ -99,22 +107,20 @@ class Station(models.Model):
class PortQuerySet(models.QuerySet):
def active(self, value=True):
""" Active ports """
"""Active ports."""
return self.filter(active=value)
def output(self):
""" Filter in output ports """
"""Filter in output ports."""
return self.filter(direction=Port.DIRECTION_OUTPUT)
def input(self):
""" Fitler in input ports """
"""Fitler in input ports."""
return self.filter(direction=Port.DIRECTION_INPUT)
class Port(models.Model):
"""
Represent an audio input/output for the audio stream
generation.
"""Represent an audio input/output for the audio stream generation.
You might want to take a look to LiquidSoap's documentation
for the options available for each kind of input/output.
@ -122,10 +128,13 @@ class Port(models.Model):
Some port types may be not available depending on the
direction of the port.
"""
DIRECTION_INPUT = 0x00
DIRECTION_OUTPUT = 0x01
DIRECTION_CHOICES = ((DIRECTION_INPUT, _('input')),
(DIRECTION_OUTPUT, _('output')))
DIRECTION_CHOICES = (
(DIRECTION_INPUT, _("input")),
(DIRECTION_OUTPUT, _("output")),
)
TYPE_JACK = 0x00
TYPE_ALSA = 0x01
@ -135,27 +144,34 @@ class Port(models.Model):
TYPE_HTTPS = 0x05
TYPE_FILE = 0x06
TYPE_CHOICES = (
(TYPE_JACK, 'jack'), (TYPE_ALSA, 'alsa'),
(TYPE_PULSEAUDIO, 'pulseaudio'), (TYPE_ICECAST, 'icecast'),
(TYPE_HTTP, 'http'), (TYPE_HTTPS, 'https'),
(TYPE_FILE, _('file'))
(TYPE_JACK, "jack"),
(TYPE_ALSA, "alsa"),
(TYPE_PULSEAUDIO, "pulseaudio"),
(TYPE_ICECAST, "icecast"),
(TYPE_HTTP, "http"),
(TYPE_HTTPS, "https"),
(TYPE_FILE, _("file")),
)
station = models.ForeignKey(
Station, models.CASCADE, verbose_name=_('station'))
Station, models.CASCADE, verbose_name=_("station")
)
direction = models.SmallIntegerField(
_('direction'), choices=DIRECTION_CHOICES)
type = models.SmallIntegerField(_('type'), choices=TYPE_CHOICES)
_("direction"), choices=DIRECTION_CHOICES
)
type = models.SmallIntegerField(_("type"), choices=TYPE_CHOICES)
active = models.BooleanField(
_('active'), default=True,
help_text=_('this port is active')
_("active"), default=True, help_text=_("this port is active")
)
settings = models.TextField(
_('port settings'),
help_text=_('list of comma separated params available; '
'this is put in the output config file as raw code; '
'plugin related'),
blank=True, null=True
_("port settings"),
help_text=_(
"list of comma separated params available; "
"this is put in the output config file as raw code; "
"plugin related"
),
blank=True,
null=True,
)
objects = PortQuerySet.as_manager()
@ -163,22 +179,17 @@ class Port(models.Model):
def __str__(self):
return "{direction}: {type} #{id}".format(
direction=self.get_direction_display(),
type=self.get_type_display(), id=self.pk or ''
type=self.get_type_display(),
id=self.pk or "",
)
def is_valid_type(self):
"""
Return True if the type is available for the given direction.
"""
"""Return True if the type is available for the given direction."""
if self.direction == self.DIRECTION_INPUT:
return self.type not in (
self.TYPE_ICECAST, self.TYPE_FILE
)
return self.type not in (self.TYPE_ICECAST, self.TYPE_FILE)
return self.type not in (
self.TYPE_HTTP, self.TYPE_HTTPS
)
return self.type not in (self.TYPE_HTTP, self.TYPE_HTTPS)
def save(self, *args, **kwargs):
if not self.is_valid_type():
@ -187,4 +198,3 @@ class Port(models.Model):
)
return super().save(*args, **kwargs)