Merge branch '2.1.x' of dev.sourcefabric.org:airtime into 2.1.x

This commit is contained in:
denise 2012-06-28 16:55:53 -04:00
commit 42ad8fe35d
2 changed files with 51 additions and 27 deletions

View File

@ -5,6 +5,8 @@ Python part of radio playout (pypo)
from optparse import OptionParser from optparse import OptionParser
from datetime import datetime from datetime import datetime
import telnetlib
import time import time
import sys import sys
import signal import signal
@ -50,6 +52,15 @@ parser.add_option("-c", "--check", help="Check the cached schedule and exit", de
#need to wait for Python 2.7 for this.. #need to wait for Python 2.7 for this..
#logging.captureWarnings(True) #logging.captureWarnings(True)
# configure logging
try:
logging.config.fileConfig("logging.cfg")
logger = logging.getLogger()
LogWriter.override_std_err(logger)
except Exception, e:
print "Couldn't configure logging"
sys.exit()
def configure_locale(): def configure_locale():
logger.debug("Before %s", locale.nl_langinfo(locale.CODESET)) logger.debug("Before %s", locale.nl_langinfo(locale.CODESET))
current_locale = locale.getlocale() current_locale = locale.getlocale()
@ -61,8 +72,8 @@ def configure_locale():
if default_locale[1] is None: if default_locale[1] is None:
logger.debug("No default locale exists. Let's try loading from /etc/default/locale") logger.debug("No default locale exists. Let's try loading from /etc/default/locale")
if os.path.exists("/etc/default/locale"): if os.path.exists("/etc/default/locale"):
config = ConfigObj('/etc/default/locale') locale_config = ConfigObj('/etc/default/locale')
lang = config.get('LANG') lang = locale_config.get('LANG')
new_locale = lang new_locale = lang
else: else:
logger.error("/etc/default/locale could not be found! Please run 'sudo update-locale' from command-line.") logger.error("/etc/default/locale could not be found! Please run 'sudo update-locale' from command-line.")
@ -84,14 +95,6 @@ def configure_locale():
logger.error("Need a UTF-8 locale. Currently '%s'. Exiting..." % current_locale_encoding) logger.error("Need a UTF-8 locale. Currently '%s'. Exiting..." % current_locale_encoding)
sys.exit(1) sys.exit(1)
# configure logging
try:
logging.config.fileConfig("logging.cfg")
logger = logging.getLogger()
LogWriter.override_std_err(logger)
except Exception, e:
print "Couldn't configure logging"
sys.exit()
configure_locale() configure_locale()
@ -118,9 +121,26 @@ def keyboardInterruptHandler(signum, frame):
logger.info('\nKeyboard Interrupt\n') logger.info('\nKeyboard Interrupt\n')
sys.exit(0) sys.exit(0)
def liquidsoap_running_test(telnet_lock, host, port, logger):
logger.debug("Checking to see if Liquidsoap is running")
success = True
try:
telnet_lock.acquire()
tn = telnetlib.Telnet(host, port)
msg = "version\n"
tn.write(msg)
tn.write("exit\n")
logger.info("Liquidsoap version %s", tn.read_all())
except Exception, e:
logger.error(str(e))
success = False
finally:
telnet_lock.release()
return success
if __name__ == '__main__': if __name__ == '__main__':
logger = logging.getLogger()
logger.info('###########################################') logger.info('###########################################')
logger.info('# *** pypo *** #') logger.info('# *** pypo *** #')
logger.info('# Liquidsoap Scheduled Playout System #') logger.info('# Liquidsoap Scheduled Playout System #')
@ -129,17 +149,24 @@ if __name__ == '__main__':
#Although all of our calculations are in UTC, it is useful to know what timezone #Although all of our calculations are in UTC, it is useful to know what timezone
#the local machine is, so that we have a reference for what time the actual #the local machine is, so that we have a reference for what time the actual
#log entries were made #log entries were made
logger.info("Timezone: %s" % time.tzname) logger.info("Timezone: %s" % str(time.tzname))
logger.info("UTC time: %s" % datetime.utcnow()) logger.info("UTC time: %s" % str(datetime.utcnow()))
signal.signal(signal.SIGINT, keyboardInterruptHandler) signal.signal(signal.SIGINT, keyboardInterruptHandler)
# initialize # initialize
g = Global() g = Global()
while not g.selfcheck(): time.sleep(5) while not g.selfcheck():
time.sleep(5)
logger = logging.getLogger() telnet_lock = Lock()
ls_host = config['ls_host']
ls_port = config['ls_port']
while not liquidsoap_running_test(telnet_lock, ls_host, ls_port, logger):
logger.warning("Liquidsoap not started yet. Sleeping one second and trying again")
time.sleep(1)
if options.test: if options.test:
g.test_api() g.test_api()
@ -152,7 +179,7 @@ if __name__ == '__main__':
recorder_q = Queue() recorder_q = Queue()
pypoPush_q = Queue() pypoPush_q = Queue()
telnet_lock = Lock()
""" """
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

View File

@ -71,7 +71,8 @@ class PypoPush(Thread):
#We get to the following lines only if a schedule was received. #We get to the following lines only if a schedule was received.
liquidsoap_queue_approx = self.get_queue_items_from_liquidsoap() liquidsoap_queue_approx = self.get_queue_items_from_liquidsoap()
current_event_chain, original_chain = self.get_current_chain(chains) tnow = datetime.utcnow()
current_event_chain, original_chain = self.get_current_chain(chains, tnow)
if len(current_event_chain) > 0 and len(liquidsoap_queue_approx) == 0: if len(current_event_chain) > 0 and len(liquidsoap_queue_approx) == 0:
#Something is scheduled but Liquidsoap is not playing anything! #Something is scheduled but Liquidsoap is not playing anything!
#Need to schedule it immediately..this might happen if Liquidsoap crashed. #Need to schedule it immediately..this might happen if Liquidsoap crashed.
@ -89,7 +90,7 @@ class PypoPush(Thread):
media_chain = filter(lambda item: (item["type"] == "file"), current_event_chain) media_chain = filter(lambda item: (item["type"] == "file"), current_event_chain)
self.handle_new_media_schedule(media_schedule, liquidsoap_queue_approx, media_chain) self.handle_new_media_schedule(media_schedule, liquidsoap_queue_approx, media_chain)
next_media_item_chain = self.get_next_schedule_chain(chains) next_media_item_chain = self.get_next_schedule_chain(chains, tnow)
self.logger.debug("Next schedule chain: %s", next_media_item_chain) self.logger.debug("Next schedule chain: %s", next_media_item_chain)
if next_media_item_chain is not None: if next_media_item_chain is not None:
@ -98,9 +99,8 @@ class PypoPush(Thread):
except ValueError, e: except ValueError, e:
self.logger.error(str(e)) self.logger.error(str(e))
tnow = datetime.utcnow()
chain_start = datetime.strptime(next_media_item_chain[0]['start'], "%Y-%m-%d-%H-%M-%S") chain_start = datetime.strptime(next_media_item_chain[0]['start'], "%Y-%m-%d-%H-%M-%S")
time_until_next_play = self.date_interval_to_seconds(chain_start - tnow) time_until_next_play = self.date_interval_to_seconds(chain_start - datetime.utcnow())
self.logger.debug("Blocking %s seconds until show start", time_until_next_play) self.logger.debug("Blocking %s seconds until show start", time_until_next_play)
else: else:
self.logger.debug("Blocking indefinitely since no show scheduled") self.logger.debug("Blocking indefinitely since no show scheduled")
@ -109,11 +109,10 @@ class PypoPush(Thread):
#We only get here when a new chain of tracks are ready to be played. #We only get here when a new chain of tracks are ready to be played.
self.push_to_liquidsoap(next_media_item_chain) self.push_to_liquidsoap(next_media_item_chain)
next_media_item_chain = self.get_next_schedule_chain(chains) next_media_item_chain = self.get_next_schedule_chain(chains, datetime.utcnow())
if next_media_item_chain is not None: if next_media_item_chain is not None:
tnow = datetime.utcnow()
chain_start = datetime.strptime(next_media_item_chain[0]['start'], "%Y-%m-%d-%H-%M-%S") chain_start = datetime.strptime(next_media_item_chain[0]['start'], "%Y-%m-%d-%H-%M-%S")
time_until_next_play = self.date_interval_to_seconds(chain_start - tnow) time_until_next_play = self.date_interval_to_seconds(chain_start - datetime.utcnow())
self.logger.debug("Blocking %s seconds until show start", time_until_next_play) self.logger.debug("Blocking %s seconds until show start", time_until_next_play)
else: else:
self.logger.debug("Blocking indefinitely since no show scheduled next") self.logger.debug("Blocking indefinitely since no show scheduled next")
@ -287,8 +286,7 @@ class PypoPush(Thread):
but but
chains.remove(original) won't chains.remove(original) won't
""" """
def get_current_chain(self, chains): def get_current_chain(self, chains, tnow):
tnow = datetime.utcnow()
current_chain = [] current_chain = []
original_chain = None original_chain = None
@ -313,10 +311,9 @@ class PypoPush(Thread):
of media_items where the end time of media_item 'n' is the start time of media_item of media_items where the end time of media_item 'n' is the start time of media_item
'n+1' 'n+1'
""" """
def get_next_schedule_chain(self, chains): def get_next_schedule_chain(self, chains, tnow):
#all media_items are now divided into chains. Let's find the one that #all media_items are now divided into chains. Let's find the one that
#starts closest in the future. #starts closest in the future.
tnow = datetime.utcnow()
closest_start = None closest_start = None
closest_chain = None closest_chain = None
for chain in chains: for chain in chains: