feat(playout): integrate new liquisoap client

This commit is contained in:
jo 2022-08-16 13:34:02 +02:00 committed by Kyle Robbertze
parent 624a60c4af
commit da6458caea
5 changed files with 97 additions and 387 deletions

View File

@ -4,13 +4,11 @@ Python part of radio playout (pypo)
import signal import signal
import sys import sys
import telnetlib
import time import time
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from queue import Queue from queue import Queue
from threading import Lock from typing import Optional
from typing import Optional, Tuple
import click import click
from libretime_api_client.v1 import ApiClient as LegacyClient from libretime_api_client.v1 import ApiClient as LegacyClient
@ -22,14 +20,14 @@ from loguru import logger
from .config import CACHE_DIR, RECORD_DIR, Config from .config import CACHE_DIR, RECORD_DIR, Config
from .history.stats import StatsCollectorThread from .history.stats import StatsCollectorThread
from .liquidsoap.version import LIQUIDSOAP_MIN_VERSION, parse_liquidsoap_version from .liquidsoap.client import LiquidsoapClient
from .liquidsoap.version import LIQUIDSOAP_MIN_VERSION
from .message_handler import PypoMessageHandler from .message_handler import PypoMessageHandler
from .player.fetch import PypoFetch from .player.fetch import PypoFetch
from .player.file import PypoFile from .player.file import PypoFile
from .player.liquidsoap import PypoLiquidsoap from .player.liquidsoap import PypoLiquidsoap
from .player.push import PypoPush from .player.push import PypoPush
from .recorder import Recorder from .recorder import Recorder
from .timeout import ls_timeout
class Global: class Global:
@ -45,56 +43,6 @@ def keyboardInterruptHandler(signum, frame):
sys.exit(0) sys.exit(0)
@ls_timeout
def liquidsoap_get_info(telnet_lock, host, port) -> Optional[Tuple[int, int, int]]:
logger.debug("Checking to see if Liquidsoap is running")
try:
telnet_lock.acquire()
tn = telnetlib.Telnet(host, port)
msg = "version\n"
tn.write(msg.encode("utf-8"))
tn.write(b"exit\n")
response = tn.read_all().decode("utf-8")
except Exception as e:
logger.error(e)
return None
finally:
telnet_lock.release()
return parse_liquidsoap_version(response)
def liquidsoap_startup_test(telnet_lock, liquidsoap_host, liquidsoap_port):
liquidsoap_version = liquidsoap_get_info(
telnet_lock,
liquidsoap_host,
liquidsoap_port,
)
while not liquidsoap_version:
logger.warning("Liquidsoap doesn't appear to be running! Trying again later...")
time.sleep(1)
liquidsoap_version = liquidsoap_get_info(
telnet_lock,
liquidsoap_host,
liquidsoap_port,
)
while not LIQUIDSOAP_MIN_VERSION <= liquidsoap_version:
logger.warning(
f"Found invalid Liquidsoap version! "
f"Liquidsoap<={LIQUIDSOAP_MIN_VERSION} is required!"
)
time.sleep(5)
liquidsoap_version = liquidsoap_get_info(
telnet_lock,
liquidsoap_host,
liquidsoap_port,
)
logger.info(f"Liquidsoap version {liquidsoap_version}")
@click.command(context_settings={"auto_envvar_prefix": DEFAULT_ENV_PREFIX}) @click.command(context_settings={"auto_envvar_prefix": DEFAULT_ENV_PREFIX})
@cli_logging_options() @cli_logging_options()
@cli_config_options() @cli_config_options()
@ -144,18 +92,21 @@ def cli(log_level: str, log_filepath: Optional[Path], config_filepath: Optional[
logger.exception(exception) logger.exception(exception)
time.sleep(10) time.sleep(10)
telnet_lock = Lock() liq_client = LiquidsoapClient(
host=config.playout.liquidsoap_host,
port=config.playout.liquidsoap_port,
)
liquidsoap_host = config.playout.liquidsoap_host logger.debug("Checking if Liquidsoap is running")
liquidsoap_port = config.playout.liquidsoap_port liq_version = liq_client.wait_for_version()
if not LIQUIDSOAP_MIN_VERSION <= liq_version:
liquidsoap_startup_test(telnet_lock, liquidsoap_host, liquidsoap_port) raise Exception(f"Invalid liquidsoap version {liq_version}")
pypoFetch_q = Queue() pypoFetch_q = Queue()
recorder_q = Queue() recorder_q = Queue()
pypoPush_q = Queue() pypoPush_q = Queue()
pypo_liquidsoap = PypoLiquidsoap(telnet_lock, liquidsoap_host, liquidsoap_port) pypo_liquidsoap = PypoLiquidsoap(liq_client)
# This queue is shared between pypo-fetch and pypo-file, where pypo-file # This queue is shared between pypo-fetch and pypo-file, where pypo-file
# is the consumer. Pypo-fetch will send every schedule it gets to pypo-file # is the consumer. Pypo-fetch will send every schedule it gets to pypo-file
@ -176,7 +127,7 @@ def cli(log_level: str, log_filepath: Optional[Path], config_filepath: Optional[
pypoFetch_q, pypoFetch_q,
pypoPush_q, pypoPush_q,
media_q, media_q,
telnet_lock, liq_client,
pypo_liquidsoap, pypo_liquidsoap,
config, config,
api_client, api_client,
@ -185,7 +136,7 @@ def cli(log_level: str, log_filepath: Optional[Path], config_filepath: Optional[
pf.daemon = True pf.daemon = True
pf.start() pf.start()
pp = PypoPush(pypoPush_q, telnet_lock, pypo_liquidsoap, config) pp = PypoPush(pypoPush_q, pypo_liquidsoap, config)
pp.daemon = True pp.daemon = True
pp.start() pp.start()

View File

@ -3,9 +3,7 @@ import json
import mimetypes import mimetypes
import os import os
import signal import signal
import subprocess
import sys import sys
import telnetlib
import time import time
from datetime import datetime from datetime import datetime
from queue import Empty from queue import Empty
@ -17,7 +15,9 @@ from libretime_api_client.v2 import ApiClient
from loguru import logger from loguru import logger
from ..config import CACHE_DIR, POLL_INTERVAL, Config from ..config import CACHE_DIR, POLL_INTERVAL, Config
from ..liquidsoap.client import LiquidsoapClient
from ..timeout import ls_timeout from ..timeout import ls_timeout
from .liquidsoap import PypoLiquidsoap
from .schedule import get_schedule from .schedule import get_schedule
@ -37,8 +37,8 @@ class PypoFetch(Thread):
pypoFetch_q, pypoFetch_q,
pypoPush_q, pypoPush_q,
media_q, media_q,
telnet_lock, liq_client: LiquidsoapClient,
pypo_liquidsoap, pypo_liquidsoap: PypoLiquidsoap,
config: Config, config: Config,
api_client: ApiClient, api_client: ApiClient,
legacy_client: LegacyClient, legacy_client: LegacyClient,
@ -57,8 +57,7 @@ class PypoFetch(Thread):
self.config = config self.config = config
self.listener_timeout = POLL_INTERVAL self.listener_timeout = POLL_INTERVAL
self.telnet_lock = telnet_lock self.liq_client = liq_client
self.pypo_liquidsoap = pypo_liquidsoap self.pypo_liquidsoap = pypo_liquidsoap
self.cache_dir = CACHE_DIR self.cache_dir = CACHE_DIR
@ -101,12 +100,12 @@ class PypoFetch(Thread):
self.update_liquidsoap_transition_fade(m["transition_fade"]) self.update_liquidsoap_transition_fade(m["transition_fade"])
elif command == "switch_source": elif command == "switch_source":
logger.info("switch_on_source show command received...") logger.info("switch_on_source show command received...")
self.pypo_liquidsoap.get_telnet_dispatcher().switch_source( self.pypo_liquidsoap.telnet_liquidsoap.switch_source(
m["sourcename"], m["status"] m["sourcename"], m["status"]
) )
elif command == "disconnect_source": elif command == "disconnect_source":
logger.info("disconnect_on_source show command received...") logger.info("disconnect_on_source show command received...")
self.pypo_liquidsoap.get_telnet_dispatcher().disconnect_source( self.pypo_liquidsoap.telnet_liquidsoap.disconnect_source(
m["sourcename"] m["sourcename"]
) )
else: else:
@ -125,25 +124,7 @@ class PypoFetch(Thread):
except Exception as exception: except Exception as exception:
logger.exception(exception) logger.exception(exception)
def switch_source_temp(self, sourcename, status):
logger.debug('Switching source: %s to "%s" status', sourcename, status)
command = "streams."
if sourcename == "master_dj":
command += "master_dj_"
elif sourcename == "live_dj":
command += "live_dj_"
elif sourcename == "scheduled_play":
command += "scheduled_play_"
if status == "on":
command += "start\n"
else:
command += "stop\n"
return command
# Initialize Liquidsoap environment # Initialize Liquidsoap environment
def set_bootstrap_variables(self): def set_bootstrap_variables(self):
logger.debug("Getting information needed on bootstrap from Airtime") logger.debug("Getting information needed on bootstrap from Airtime")
try: try:
@ -152,59 +133,33 @@ class PypoFetch(Thread):
logger.exception(f"Unable to get bootstrap info: {exception}") logger.exception(f"Unable to get bootstrap info: {exception}")
logger.debug("info:%s", info) logger.debug("info:%s", info)
commands = []
for k, v in info["switch_status"].items():
commands.append(self.switch_source_temp(k, v))
stream_format = info["stream_label"] try:
station_name = info["station_name"] for source_name, source_status in info["switch_status"].items():
fade = info["transition_fade"] self.pypo_liquidsoap.liq_client.source_switch_status(
name=source_name,
streaming=source_status == "on",
)
commands.append( self.pypo_liquidsoap.liq_client.settings_update(
("vars.stream_metadata_type %s\n" % stream_format).encode("utf-8") station_name=info["station_name"],
) message_format=info["stream_label"],
commands.append(("vars.station_name %s\n" % station_name).encode("utf-8")) input_fade_transition=info["transition_fade"],
commands.append(("vars.default_dj_fade %s\n" % fade).encode("utf-8")) )
self.pypo_liquidsoap.get_telnet_dispatcher().telnet_send(commands) except (ConnectionError, TimeoutError) as exception:
logger.exception(exception)
self.pypo_liquidsoap.clear_all_queues() self.pypo_liquidsoap.clear_all_queues()
self.pypo_liquidsoap.clear_queue_tracker() self.pypo_liquidsoap.clear_queue_tracker()
def restart_liquidsoap(self): def restart_liquidsoap(self):
try: try:
# do not block - if we receive the lock then good - no other thread
# will try communicating with Liquidsoap. If we don't receive, it may
# mean some thread blocked and is still holding the lock. Restarting
# Liquidsoap will cause that thread to release the lock as an Exception
# will be thrown.
self.telnet_lock.acquire(False)
logger.info("Restarting Liquidsoap") logger.info("Restarting Liquidsoap")
subprocess.call( self.liq_client.restart()
"kill -9 `pidof libretime-liquidsoap`", shell=True, close_fds=True logger.info("Liquidsoap is up and running")
)
# Wait here and poll Liquidsoap until it has started up
logger.info("Waiting for Liquidsoap to start")
while True:
try:
tn = telnetlib.Telnet(
self.config.playout.liquidsoap_host,
self.config.playout.liquidsoap_port,
)
tn.write(b"exit\n")
tn.read_all()
logger.info("Liquidsoap is up and running")
break
except Exception:
# sleep 0.5 seconds and try again
time.sleep(0.5)
except Exception as exception: except Exception as exception:
logger.exception(exception) logger.exception(exception)
finally:
if self.telnet_lock.locked():
self.telnet_lock.release()
# NOTE: This function is quite short after it was refactored. # NOTE: This function is quite short after it was refactored.
@ -220,35 +175,18 @@ class PypoFetch(Thread):
""" """
try: try:
self.telnet_lock.acquire() with self.liq_client.conn:
tn = telnetlib.Telnet( # update the boot up time of Liquidsoap. Since Liquidsoap is not restarting,
self.config.playout.liquidsoap_host, # we are manually adjusting the bootup time variable so the status msg will get
self.config.playout.liquidsoap_port, # updated.
) current_time = time.time()
# update the boot up time of Liquidsoap. Since Liquidsoap is not restarting, self.liq_client.conn.write(f"vars.bootup_time {str(current_time)}")
# we are manually adjusting the bootup time variable so the status msg will get self.liq_client.conn.read()
# updated.
current_time = time.time()
boot_up_time_command = (
"vars.bootup_time " + str(current_time) + "\n"
).encode("utf-8")
logger.info(boot_up_time_command)
tn.write(boot_up_time_command)
connection_status = b"streams.connection_status\n" self.liq_client.conn.write("streams.connection_status")
logger.info(connection_status) stream_info = self.liq_client.conn.read().splitlines()[0]
tn.write(connection_status) except (ConnectionError, TimeoutError) as exception:
tn.write(b"exit\n")
output = tn.read_all()
except Exception as exception:
logger.exception(exception) logger.exception(exception)
finally:
self.telnet_lock.release()
output_list = output.split("\r\n")
stream_info = output_list[2]
# streamin info is in the form of: # streamin info is in the form of:
# eg. s1:true,2:true,3:false # eg. s1:true,2:true,3:false
@ -267,65 +205,23 @@ class PypoFetch(Thread):
@ls_timeout @ls_timeout
def update_liquidsoap_stream_format(self, stream_format): def update_liquidsoap_stream_format(self, stream_format):
# Push stream metadata to liquidsoap
# TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!!
try: try:
self.telnet_lock.acquire() self.liq_client.settings_update(message_format=stream_format)
tn = telnetlib.Telnet( except (ConnectionError, TimeoutError) as exception:
self.config.playout.liquidsoap_host,
self.config.playout.liquidsoap_port,
)
command = ("vars.stream_metadata_type %s\n" % stream_format).encode("utf-8")
logger.info(command)
tn.write(command)
tn.write(b"exit\n")
tn.read_all()
except Exception as exception:
logger.exception(exception) logger.exception(exception)
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def update_liquidsoap_transition_fade(self, fade): def update_liquidsoap_transition_fade(self, fade):
# Push stream metadata to liquidsoap
# TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!!
try: try:
self.telnet_lock.acquire() self.liq_client.settings_update(input_fade_transition=fade)
tn = telnetlib.Telnet( except (ConnectionError, TimeoutError) as exception:
self.config.playout.liquidsoap_host,
self.config.playout.liquidsoap_port,
)
command = ("vars.default_dj_fade %s\n" % fade).encode("utf-8")
logger.info(command)
tn.write(command)
tn.write(b"exit\n")
tn.read_all()
except Exception as exception:
logger.exception(exception) logger.exception(exception)
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def update_liquidsoap_station_name(self, station_name): def update_liquidsoap_station_name(self, station_name):
# Push stream metadata to liquidsoap
# TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!!
try: try:
try: self.liq_client.settings_update(station_name=station_name)
self.telnet_lock.acquire() except (ConnectionError, TimeoutError) as exception:
tn = telnetlib.Telnet(
self.config.playout.liquidsoap_host,
self.config.playout.liquidsoap_port,
)
command = ("vars.station_name %s\n" % station_name).encode("utf-8")
logger.info(command)
tn.write(command)
tn.write(b"exit\n")
tn.read_all()
except Exception as exception:
logger.exception(exception)
finally:
self.telnet_lock.release()
except Exception as exception:
logger.exception(exception) logger.exception(exception)
# Process the schedule # Process the schedule

View File

@ -3,13 +3,14 @@ from datetime import datetime, timedelta
from loguru import logger from loguru import logger
from ..liquidsoap.client import LiquidsoapClient
from ..utils import seconds_between from ..utils import seconds_between
from .events import EventKind from .events import EventKind
from .liquidsoap_gateway import TelnetLiquidsoap from .liquidsoap_gateway import TelnetLiquidsoap
class PypoLiquidsoap: class PypoLiquidsoap:
def __init__(self, telnet_lock, host, port): def __init__(self, liq_client: LiquidsoapClient):
self.liq_queue_tracker = { self.liq_queue_tracker = {
"s0": None, "s0": None,
"s1": None, "s1": None,
@ -18,13 +19,12 @@ class PypoLiquidsoap:
"s4": None, "s4": None,
} }
self.liq_client = liq_client
self.telnet_liquidsoap = TelnetLiquidsoap( self.telnet_liquidsoap = TelnetLiquidsoap(
telnet_lock, host, port, list(self.liq_queue_tracker.keys()) liq_client,
list(self.liq_queue_tracker.keys()),
) )
def get_telnet_dispatcher(self):
return self.telnet_liquidsoap
def play(self, media_item): def play(self, media_item):
if media_item["type"] == EventKind.FILE: if media_item["type"] == EventKind.FILE:
self.handle_file_type(media_item) self.handle_file_type(media_item)

View File

@ -1,7 +1,8 @@
import telnetlib from typing import List
from loguru import logger from loguru import logger
from ..liquidsoap.client import LiquidsoapClient
from ..timeout import ls_timeout from ..timeout import ls_timeout
@ -43,229 +44,91 @@ def create_liquidsoap_annotation(media):
class TelnetLiquidsoap: class TelnetLiquidsoap:
def __init__(self, telnet_lock, ls_host, ls_port, queues): def __init__(self, liq_client: LiquidsoapClient, queues: List[str]):
self.telnet_lock = telnet_lock self.liq_client = liq_client
self.ls_host = ls_host
self.ls_port = ls_port
self.queues = queues self.queues = queues
self.current_prebuffering_stream_id = None self.current_prebuffering_stream_id = None
def __connect(self):
return telnetlib.Telnet(self.ls_host, self.ls_port)
@ls_timeout @ls_timeout
def queue_clear_all(self): def queue_clear_all(self):
try: try:
self.telnet_lock.acquire() self.liq_client.queues_remove(*self.queues)
connection = self.__connect() except (ConnectionError, TimeoutError) as exception:
logger.exception(exception)
for i in self.queues:
msg = "queues.%s_skip\n" % i
logger.debug(msg)
connection.write(msg.encode("utf-8"))
connection.write(b"exit\n")
logger.debug(connection.read_all().decode("utf-8"))
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def queue_remove(self, queue_id): def queue_remove(self, queue_id):
try: try:
self.telnet_lock.acquire() self.liq_client.queues_remove(queue_id)
connection = self.__connect() except (ConnectionError, TimeoutError) as exception:
logger.exception(exception)
msg = "queues.%s_skip\n" % queue_id
logger.debug(msg)
connection.write(msg.encode("utf-8"))
connection.write(b"exit\n")
logger.debug(connection.read_all().decode("utf-8"))
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def queue_push(self, queue_id, media_item): def queue_push(self, queue_id, media_item):
try: try:
self.telnet_lock.acquire()
connection = self.__connect()
annotation = create_liquidsoap_annotation(media_item) annotation = create_liquidsoap_annotation(media_item)
msg = f"{queue_id}.push {annotation}\n" self.liq_client.queue_push(queue_id, annotation, media_item["show_name"])
logger.debug(msg) except (ConnectionError, TimeoutError) as exception:
connection.write(msg.encode("utf-8")) logger.exception(exception)
show_name = media_item["show_name"]
msg = "vars.show_name %s\n" % show_name
connection.write(msg.encode("utf-8"))
logger.debug(msg)
connection.write(b"exit\n")
logger.debug(connection.read_all().decode("utf-8"))
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def stop_web_stream_buffer(self): def stop_web_stream_buffer(self):
try: try:
self.telnet_lock.acquire() self.liq_client.web_stream_stop_buffer()
connection = telnetlib.Telnet(self.ls_host, self.ls_port) except (ConnectionError, TimeoutError) as exception:
# dynamic_source.stop http://87.230.101.24:80/top100station.mp3
msg = "http.stop\n"
logger.debug(msg)
connection.write(msg.encode("utf-8"))
msg = "dynamic_source.id -1\n"
logger.debug(msg)
connection.write(msg.encode("utf-8"))
connection.write(b"exit\n")
logger.debug(connection.read_all().decode("utf-8"))
except Exception as exception:
logger.exception(exception) logger.exception(exception)
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def stop_web_stream_output(self): def stop_web_stream_output(self):
try: try:
self.telnet_lock.acquire() self.liq_client.web_stream_stop()
connection = telnetlib.Telnet(self.ls_host, self.ls_port) except (ConnectionError, TimeoutError) as exception:
# dynamic_source.stop http://87.230.101.24:80/top100station.mp3
msg = "dynamic_source.output_stop\n"
logger.debug(msg)
connection.write(msg.encode("utf-8"))
connection.write(b"exit\n")
logger.debug(connection.read_all().decode("utf-8"))
except Exception as exception:
logger.exception(exception) logger.exception(exception)
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def start_web_stream(self, media_item): def start_web_stream(self, media_item):
try: try:
self.telnet_lock.acquire() self.liq_client.web_stream_start()
connection = telnetlib.Telnet(self.ls_host, self.ls_port)
# TODO: DO we need this?
msg = "streams.scheduled_play_start\n"
connection.write(msg.encode("utf-8"))
msg = "dynamic_source.output_start\n"
logger.debug(msg)
connection.write(msg.encode("utf-8"))
connection.write(b"exit\n")
logger.debug(connection.read_all().decode("utf-8"))
self.current_prebuffering_stream_id = None self.current_prebuffering_stream_id = None
except Exception as exception: except (ConnectionError, TimeoutError) as exception:
logger.exception(exception) logger.exception(exception)
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def start_web_stream_buffer(self, media_item): def start_web_stream_buffer(self, media_item):
try: try:
self.telnet_lock.acquire() self.liq_client.web_stream_start_buffer(
connection = telnetlib.Telnet(self.ls_host, self.ls_port) media_item["row_id"],
media_item["uri"],
msg = "dynamic_source.id %s\n" % media_item["row_id"] )
logger.debug(msg)
connection.write(msg.encode("utf-8"))
msg = "http.restart %s\n" % media_item["uri"]
logger.debug(msg)
connection.write(msg.encode("utf-8"))
connection.write(b"exit\n")
logger.debug(connection.read_all().decode("utf-8"))
self.current_prebuffering_stream_id = media_item["row_id"] self.current_prebuffering_stream_id = media_item["row_id"]
except Exception as exception: except (ConnectionError, TimeoutError) as exception:
logger.exception(exception) logger.exception(exception)
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def get_current_stream_id(self): def get_current_stream_id(self):
try: try:
self.telnet_lock.acquire() return self.liq_client.web_stream_get_id()
connection = telnetlib.Telnet(self.ls_host, self.ls_port) except (ConnectionError, TimeoutError) as exception:
msg = "dynamic_source.get_id\n"
logger.debug(msg)
connection.write(msg.encode("utf-8"))
connection.write(b"exit\n")
stream_id = connection.read_all().decode("utf-8").splitlines()[0]
logger.debug("stream_id: %s" % stream_id)
return stream_id
except Exception as exception:
logger.exception(exception) logger.exception(exception)
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def disconnect_source(self, sourcename): def disconnect_source(self, sourcename):
logger.debug("Disconnecting source: %s", sourcename) if sourcename not in ("master_dj", "live_dj"):
command = "" raise ValueError(f"invalid source name: {sourcename}")
if sourcename == "master_dj":
command += "master_harbor.stop\n"
elif sourcename == "live_dj":
command += "live_dj_harbor.stop\n"
try: try:
self.telnet_lock.acquire() logger.debug("Disconnecting source: %s", sourcename)
connection = telnetlib.Telnet(self.ls_host, self.ls_port) self.liq_client.source_disconnect(sourcename)
logger.info(command) except (ConnectionError, TimeoutError) as exception:
connection.write(command.encode("utf-8"))
connection.write(b"exit\n")
connection.read_all().decode("utf-8")
except Exception as exception:
logger.exception(exception) logger.exception(exception)
finally:
self.telnet_lock.release()
@ls_timeout @ls_timeout
def telnet_send(self, commands):
try:
self.telnet_lock.acquire()
connection = telnetlib.Telnet(self.ls_host, self.ls_port)
for line in commands:
logger.info(line)
if type(line) is str:
line = line.encode("utf-8")
connection.write(line)
connection.write(b"exit\n")
connection.read_all().decode("utf-8")
except Exception as exception:
logger.exception(exception)
finally:
self.telnet_lock.release()
def switch_source(self, sourcename, status): def switch_source(self, sourcename, status):
logger.debug('Switching source: %s to "%s" status', sourcename, status) if sourcename not in ("master_dj", "live_dj", "scheduled_play"):
command = "streams." raise ValueError(f"invalid source name: {sourcename}")
if sourcename == "master_dj":
command += "master_dj_"
elif sourcename == "live_dj":
command += "live_dj_"
elif sourcename == "scheduled_play":
command += "scheduled_play_"
if status == "on": try:
command += "start\n" logger.debug('Switching source: %s to "%s" status', sourcename, status)
else: self.liq_client.source_switch_status(sourcename, status == "on")
command += "stop\n" except (ConnectionError, TimeoutError) as exception:
logger.exception(exception)
self.telnet_send([command])

View File

@ -7,6 +7,7 @@ from threading import Thread
from loguru import logger from loguru import logger
from ..config import PUSH_INTERVAL, Config from ..config import PUSH_INTERVAL, Config
from .liquidsoap import PypoLiquidsoap
from .queue import PypoLiqQueue from .queue import PypoLiqQueue
@ -21,11 +22,10 @@ def is_file(media_item):
class PypoPush(Thread): class PypoPush(Thread):
name = "push" name = "push"
def __init__(self, q, telnet_lock, pypo_liquidsoap, config: Config): def __init__(self, q, pypo_liquidsoap: PypoLiquidsoap, config: Config):
Thread.__init__(self) Thread.__init__(self)
self.queue = q self.queue = q
self.telnet_lock = telnet_lock
self.config = config self.config = config
self.pushed_objects = {} self.pushed_objects = {}