91 lines
2.8 KiB
Python
91 lines
2.8 KiB
Python
"""
|
|
schedule.pypoliqqueue
|
|
~~~~~~~~~
|
|
|
|
This module takes a collection of media_items scheduled in the near future
|
|
and fires off a start event when the item's start time begins.
|
|
|
|
:author: (c) 2012 by Martin Konecny.
|
|
:license: GPLv3, see LICENSE for more details.
|
|
"""
|
|
|
|
from threading import Thread
|
|
from collections import deque
|
|
from datetime import datetime
|
|
|
|
from schedule import pure
|
|
|
|
import traceback
|
|
import sys
|
|
import time
|
|
|
|
|
|
from Queue import Empty
|
|
|
|
import signal
|
|
def keyboardInterruptHandler(signum, frame):
|
|
logger = logging.getLogger()
|
|
logger.info('\nKeyboard Interrupt\n')
|
|
sys.exit(0)
|
|
signal.signal(signal.SIGINT, keyboardInterruptHandler)
|
|
|
|
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:
|
|
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)
|
|
except Empty, e:
|
|
#Time to push a scheduled item.
|
|
media_item = schedule_deque.popleft()
|
|
self.pypo_liquidsoap.play(media_item)
|
|
if len(schedule_deque):
|
|
time_until_next_play = \
|
|
pure.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)
|
|
|
|
#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(
|
|
media_schedule[keys[0]]['start'] -
|
|
datetime.utcnow())
|
|
else:
|
|
time_until_next_play = None
|
|
|
|
def run(self):
|
|
try: self.main()
|
|
except Exception, e:
|
|
self.logger.error('PypoLiqQueue Exception: %s',
|
|
traceback.format_exc())
|
|
|
|
|
|
|