aircox/aircox_streamer/management/commands/streamer.py
Thomas Kairos b453c821c7 #106: tests: aircox_streamer (#110)
- Writes tests for aircox streamer application;
- Add test utilities in aircox

Co-authored-by: bkfox <thomas bkfox net>
Reviewed-on: #110
2023-06-18 17:00:08 +02:00

122 lines
3.4 KiB
Python
Executable File

"""Handle the audio streamer and controls it as we want it to be. It is used
to:
- generate config files and playlists;
- monitor Liquidsoap, logs and scheduled programs;
- cancels Diffusions that have an archive but could not have been played;
- run Liquidsoap
"""
import time
from argparse import RawTextHelpFormatter
import pytz
from django.core.management.base import BaseCommand
from django.utils import timezone as tz
from aircox.models import Station
from aircox_streamer.controllers import Monitor, Streamer
# force using UTC
tz.activate(pytz.UTC)
class Command(BaseCommand):
help = __doc__
def add_arguments(self, parser):
parser.formatter_class = RawTextHelpFormatter
group = parser.add_argument_group("actions")
group.add_argument(
"-c",
"--config",
action="store_true",
help="generate configuration files for the stations",
)
group.add_argument(
"-m",
"--monitor",
action="store_true",
help="monitor the scheduled diffusions and log what happens",
)
group.add_argument(
"-r",
"--run",
action="store_true",
help="run the required applications for the stations",
)
group = parser.add_argument_group("options")
group.add_argument(
"-d",
"--delay",
type=int,
default=1000,
help="time to sleep in MILLISECONDS between two updates when we "
"monitor. This influence the delay before a diffusion is "
"launched.",
)
group.add_argument(
"-s",
"--station",
type=str,
action="append",
help="name of the station to monitor instead of monitoring "
"all stations",
)
group.add_argument(
"-t",
"--timeout",
type=float,
default=Monitor.cancel_timeout.total_seconds() / 60,
help="time to wait in MINUTES before canceling a diffusion that "
"should have ran but did not. ",
)
# TODO: sync-timeout, cancel-timeout
def handle(
self,
*args,
config=None,
run=None,
monitor=None,
station=[],
delay=1000,
timeout=600,
**options
):
stations = (
Station.objects.filter(name__in=station)
if station
else Station.objects.all()
)
streamers = [Streamer(station) for station in stations]
for streamer in streamers:
if not streamer.outputs:
raise RuntimeError(
"Streamer {} has no outputs".format(streamer.id)
)
if config:
streamer.make_config()
if run:
streamer.run_process()
if monitor:
delay = tz.timedelta(milliseconds=delay)
timeout = tz.timedelta(minutes=timeout)
monitors = [
Monitor(streamer, delay, cancel_timeout=timeout)
for streamer in streamers
]
while not run or streamer.is_running:
for monitor in monitors:
monitor.monitor()
time.sleep(delay.total_seconds())
if run:
for streamer in streamers:
streamer.wait_process()