sintonia/playout/libretime_playout/pypoliqqueue.py

93 lines
3.0 KiB
Python
Raw Normal View History

import signal
import sys
import time
import traceback
from collections import deque
from datetime import datetime
2020-01-16 15:32:51 +01:00
from queue import Empty
from threading import Thread
2021-05-27 16:23:02 +02:00
def keyboardInterruptHandler(signum, frame):
logger = logging.getLogger()
2021-05-27 16:23:02 +02:00
logger.info("\nKeyboard Interrupt\n")
sys.exit(0)
2021-05-27 16:23:02 +02:00
signal.signal(signal.SIGINT, keyboardInterruptHandler)
2021-05-27 16:23:02 +02:00
class PypoLiqQueue(Thread):
def __init__(self, q, pypo_liquidsoap, logger):
Thread.__init__(self)
self.queue = q
self.logger = logger
self.pypo_liquidsoap = pypo_liquidsoap
def main(self):
time_until_next_play = None
schedule_deque = deque()
media_schedule = None
while True:
try:
if time_until_next_play is None:
self.logger.info("waiting indefinitely for schedule")
media_schedule = self.queue.get(block=True)
else:
2021-05-27 16:23:02 +02:00
self.logger.info(
"waiting %ss until next scheduled item" % time_until_next_play
)
media_schedule = self.queue.get(
block=True, timeout=time_until_next_play
)
2020-01-16 15:32:51 +01:00
except Empty as e:
2021-05-27 16:23:02 +02:00
# Time to push a scheduled item.
media_item = schedule_deque.popleft()
self.pypo_liquidsoap.play(media_item)
if len(schedule_deque):
2021-05-27 16:23:02 +02:00
time_until_next_play = self.date_interval_to_seconds(
schedule_deque[0]["start"] - datetime.utcnow()
)
if time_until_next_play < 0:
time_until_next_play = 0
else:
time_until_next_play = None
else:
self.logger.info("New schedule received: %s", media_schedule)
2021-05-27 16:23:02 +02:00
# new schedule received. Replace old one with this.
schedule_deque.clear()
keys = sorted(media_schedule.keys())
for i in keys:
schedule_deque.append(media_schedule[i])
if len(keys):
time_until_next_play = self.date_interval_to_seconds(
2021-05-27 16:23:02 +02:00
media_schedule[keys[0]]["start"] - datetime.utcnow()
)
else:
time_until_next_play = None
def date_interval_to_seconds(self, interval):
"""
Convert timedelta object into int representing the number of seconds. If
number of seconds is less than 0, then return 0.
"""
2021-05-27 16:23:02 +02:00
seconds = (
interval.microseconds
+ (interval.seconds + interval.days * 24 * 3600) * 10 ** 6
) / float(10 ** 6)
if seconds < 0:
seconds = 0
return seconds
def run(self):
2021-05-27 16:23:02 +02:00
try:
self.main()
2020-01-16 15:32:51 +01:00
except Exception as e:
2021-05-27 16:23:02 +02:00
self.logger.error("PypoLiqQueue Exception: %s", traceback.format_exc())