"""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 """ from datetime import timezone import time from argparse import RawTextHelpFormatter 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(timezone.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()