sintonia/playout/libretime_playout/player/push.py

98 lines
2.8 KiB
Python
Raw Permalink Normal View History

2023-02-26 01:27:00 +01:00
import logging
import math
import time
from datetime import datetime
from queue import Queue
from threading import Thread
from typing import List, Tuple
2012-03-16 04:14:19 +01:00
from ..config import PUSH_INTERVAL, Config
from .events import AnyEvent, Events, FileEvent
from .liquidsoap import Liquidsoap
from .queue import PypoLiqQueue
2023-02-26 01:27:00 +01:00
logger = logging.getLogger(__name__)
class PypoPush(Thread):
2022-08-14 19:55:39 +02:00
name = "push"
daemon = True
2022-08-14 19:55:39 +02:00
def __init__(
self,
push_queue: "Queue[Events]",
liquidsoap: Liquidsoap,
config: Config,
):
Thread.__init__(self)
self.queue = push_queue
self.config = config
self.future_scheduled_queue: "Queue[Events]" = Queue()
self.liquidsoap = liquidsoap
self.plq = PypoLiqQueue(self.future_scheduled_queue, self.liquidsoap)
self.plq.start()
2023-03-01 20:27:27 +01:00
def main(self) -> None:
loops = 0
heartbeat_period = math.floor(30 / PUSH_INTERVAL)
events = None
2012-03-20 20:51:54 +01:00
while True:
try:
events = self.queue.get(block=True)
except Exception as exception: # pylint: disable=broad-exception-caught
logger.exception(exception)
raise exception
2023-03-01 17:13:02 +01:00
logger.debug(events)
# separate media_schedule list into currently_playing and
# scheduled_for_future lists
currently_playing, scheduled_for_future = self.separate_present_future(
events
)
self.liquidsoap.verify_correct_present_media(currently_playing)
2023-03-01 17:13:02 +01:00
self.future_scheduled_queue.put(scheduled_for_future)
if loops % heartbeat_period == 0:
feat(playout): enhance playout logging (#1495) Some initial work on modernizing the playout app. This replace any custom logger or logging based logger with the logging tools from libretime_shared.logging and loguru. Removed all the thread/function assigned logger (self.logger = ...), as this makes it part of the logic (passing logger though function args) as it should not. Of a dedicated logger is required for a specific task, it should use the create_task_logger function. - refactor: remove dead code - refactor: remove py2 specific fix - feat: remove unused test command - feat: setup shared cli and logging tools - feat: replace logging with loguru - feat: setup shared cli and logging tools for notify - fix: warn method deos not exist - feat: make cli setup the entrypoint - fix: install shared modules globally in production use extra_requires to load local packages in dev environement - feat: configure log path in systemd service - feat: default behavior is to log to console only - feat: create log dir during install - chore: add comment - fix: don't create useless dir in install - fix: move notify logs to /var/log/libretime dir - fix: update setup_logger attrs - style: linting - fix: replace verbosity flag with log-level flag - feat: use shared logging tool in liquidsoap - fix: pass logger down to api client - feat: allow custom log_filepath in liquidsoap config - chore: add pylintrc to playout - refactor: fix pylint errors - feat: set liquidsoap log filepath in systemd service - fix: missing setup entrypoint update BREAKING CHANGE: for playout and liquidsoap the default log file path changed to None and will only log to the console when developing / testing. Unless you are running the app as a systemd service (production) the default logs filepaths changed: from "/var/log/airtime/pypo/pypo.log" to "/var/log/libretime/playout.log" and from "/var/log/airtime/pypo-liquidsoap/ls_script.log" to "/var/log/libretime/liquidsoap.log" BREAKING CHANGE: for playout-notify the default log file path changed from "/var/log/airtime/pypo/notify.log" to "/var/log/libretime/playout-notify.log"
2022-01-13 16:11:37 +01:00
logger.info("heartbeat")
loops = 0
loops += 1
2012-03-20 20:51:54 +01:00
def separate_present_future(self, events: Events) -> Tuple[List[AnyEvent], Events]:
now = datetime.utcnow()
present: List[AnyEvent] = []
future: Events = {}
for key in sorted(events.keys()):
item = events[key]
# Ignore track that already ended
if isinstance(item, FileEvent) and item.end < now:
logger.debug("ignoring ended media_item: %s", item)
continue
diff_sec = (now - item.start).total_seconds()
if diff_sec >= 0:
logger.debug("adding media_item to present: %s", item)
present.append(item)
else:
logger.debug("adding media_item to future: %s", item)
future[key] = item
return present, future
2023-03-01 20:27:27 +01:00
def run(self) -> None:
while True:
2021-05-27 16:23:02 +02:00
try:
self.main()
except Exception as exception: # pylint: disable=broad-exception-caught
logger.exception(exception)
time.sleep(5)