forked from rc/aircox
124 lines
3.4 KiB
Python
124 lines
3.4 KiB
Python
import os
|
|
import subprocess
|
|
import atexit
|
|
|
|
import aircox.controllers.plugins.plugins as plugins
|
|
from aircox.controllers.plugins.connector import Connector
|
|
|
|
|
|
class LiquidSoap(plugins.Plugin):
|
|
@staticmethod
|
|
def init_station(station):
|
|
return StationController(station = station)
|
|
|
|
@staticmethod
|
|
def init_source(source):
|
|
return SourceController(source = source)
|
|
|
|
|
|
class StationController(plugins.StationController):
|
|
template_name = 'aircox/controllers/liquidsoap.liq'
|
|
socket_path = ''
|
|
connector = None
|
|
|
|
def __init__(self, station, **kwargs):
|
|
super().__init__(
|
|
station = station,
|
|
path = os.path.join(station.path, 'station.liq'),
|
|
socket_path = os.path.join(station.path, 'station.sock'),
|
|
**kwargs
|
|
)
|
|
self.connector = Connector(self.socket_path)
|
|
|
|
def _send(self, *args, **kwargs):
|
|
return self.connector.send(*args, **kwargs)
|
|
|
|
def __get_process_args(self):
|
|
return ['liquidsoap', '-v', self.path]
|
|
|
|
def ready(self):
|
|
return self._send('var.list') != ''
|
|
|
|
def fetch(self):
|
|
super().fetch()
|
|
|
|
rid = self._send('request.on_air').split(' ')[0]
|
|
if ' ' in rid:
|
|
rid = rid[:rid.index(' ')]
|
|
if not rid:
|
|
return
|
|
|
|
data = self._send('request.metadata ', rid, parse = True)
|
|
if not data:
|
|
return
|
|
|
|
self.current_sound = data.get('initial_uri')
|
|
try:
|
|
self.current_source = next(
|
|
source for source in self.station.get_sources(dealer = True)
|
|
if source.controller.rid == rid
|
|
)
|
|
except:
|
|
self.current_source = None
|
|
|
|
def skip(self):
|
|
"""
|
|
Skip a given source. If no source, use master.
|
|
"""
|
|
self._send(self.station.id_, '.skip')
|
|
|
|
|
|
class SourceController(plugins.SourceController):
|
|
rid = None
|
|
connector = None
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(**kwargs)
|
|
self.connector = self.source.station.controller.connector
|
|
|
|
def _send(self, *args, **kwargs):
|
|
return self.connector.send(*args, **kwargs)
|
|
|
|
@property
|
|
def active(self):
|
|
return self._send('var.get ', self.source.id_, '_active') == 'true'
|
|
|
|
@active.setter
|
|
def active(self, value):
|
|
self._send('var.set ', self.source.id_, '_active', '=',
|
|
'true' if value else 'false')
|
|
|
|
def skip(self):
|
|
"""
|
|
Skip a given source. If no source, use master.
|
|
"""
|
|
self._send(self.source.id_, '.skip')
|
|
|
|
def fetch(self):
|
|
data = self._send(self.source.id_, '.get', parse = True)
|
|
if not data or type(data) != dict:
|
|
return
|
|
|
|
self.rid = data.get('rid')
|
|
self.current_sound = data.get('initial_uri')
|
|
|
|
def stream(self):
|
|
"""
|
|
Return a dict with stream info for a Stream program, or None if there
|
|
is not. Used in the template.
|
|
"""
|
|
stream = self.source.stream
|
|
if not stream or (not stream.begin and not stream.delay):
|
|
return
|
|
|
|
def to_seconds(time):
|
|
return 3600 * time.hour + 60 * time.minute + time.second
|
|
|
|
return {
|
|
'begin': stream.begin.strftime('%Hh%M') if stream.begin else None,
|
|
'end': stream.end.strftime('%Hh%M') if stream.end else None,
|
|
'delay': to_seconds(stream.delay) if stream.delay else 0
|
|
}
|
|
|
|
|