CC-3336: Refactor schedule API used by pypo
This commit is contained in:
parent
057e377c5f
commit
a6413f2d1a
|
@ -29,7 +29,7 @@ class Application_Model_RabbitMq
|
||||||
$EXCHANGE = 'airtime-pypo';
|
$EXCHANGE = 'airtime-pypo';
|
||||||
$channel->exchange_declare($EXCHANGE, 'direct', false, true);
|
$channel->exchange_declare($EXCHANGE, 'direct', false, true);
|
||||||
|
|
||||||
$data = json_encode($md);
|
$data = json_encode($md, JSON_FORCE_OBJECT);
|
||||||
$msg = new AMQPMessage($data, array('content_type' => 'text/plain'));
|
$msg = new AMQPMessage($data, array('content_type' => 'text/plain'));
|
||||||
|
|
||||||
$channel->basic_publish($msg, $EXCHANGE);
|
$channel->basic_publish($msg, $EXCHANGE);
|
||||||
|
|
|
@ -423,8 +423,13 @@ class Application_Model_Schedule {
|
||||||
$rows = array();
|
$rows = array();
|
||||||
|
|
||||||
$sql = "SELECT st.file_id AS file_id,"
|
$sql = "SELECT st.file_id AS file_id,"
|
||||||
|
." st.id as id,"
|
||||||
." st.starts AS start,"
|
." st.starts AS start,"
|
||||||
." st.ends AS end,"
|
." st.ends AS end,"
|
||||||
|
." st.cue_in AS cue_in,"
|
||||||
|
." st.cue_out AS cue_out,"
|
||||||
|
." st.fade_in AS fade_in,"
|
||||||
|
." st.fade_out AS fade_out,"
|
||||||
." si.starts as show_start,"
|
." si.starts as show_start,"
|
||||||
." si.ends as show_end"
|
." si.ends as show_end"
|
||||||
." FROM $CC_CONFIG[scheduleTable] as st"
|
." FROM $CC_CONFIG[scheduleTable] as st"
|
||||||
|
@ -491,6 +496,7 @@ class Application_Model_Schedule {
|
||||||
$start = Application_Model_Schedule::AirtimeTimeToPypoTime($item["start"]);
|
$start = Application_Model_Schedule::AirtimeTimeToPypoTime($item["start"]);
|
||||||
$data["media"][$start] = array(
|
$data["media"][$start] = array(
|
||||||
'id' => $storedFile->getGunid(),
|
'id' => $storedFile->getGunid(),
|
||||||
|
'row_id' => $item["id"],
|
||||||
'uri' => $uri,
|
'uri' => $uri,
|
||||||
'fade_in' => Application_Model_Schedule::WallTimeToMillisecs($item["fade_in"]),
|
'fade_in' => Application_Model_Schedule::WallTimeToMillisecs($item["fade_in"]),
|
||||||
'fade_out' => Application_Model_Schedule::WallTimeToMillisecs($item["fade_out"]),
|
'fade_out' => Application_Model_Schedule::WallTimeToMillisecs($item["fade_out"]),
|
||||||
|
|
|
@ -141,8 +141,11 @@ if __name__ == '__main__':
|
||||||
recorder.daemon = True
|
recorder.daemon = True
|
||||||
recorder.start()
|
recorder.start()
|
||||||
|
|
||||||
#pp.join()
|
pmh.join()
|
||||||
|
pp.join()
|
||||||
pf.join()
|
pf.join()
|
||||||
|
recorder.join()
|
||||||
|
|
||||||
logger.info("pypo fetch exit")
|
logger.info("pypo fetch exit")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -45,7 +45,7 @@ class PypoFetch(Thread):
|
||||||
self.logger = logging.getLogger();
|
self.logger = logging.getLogger();
|
||||||
|
|
||||||
self.cache_dir = os.path.join(config["cache_dir"], "scheduler")
|
self.cache_dir = os.path.join(config["cache_dir"], "scheduler")
|
||||||
logger.debug("Cache dir %s", self.cache_dir)
|
self.logger.debug("Cache dir %s", self.cache_dir)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not os.path.isdir(dir):
|
if not os.path.isdir(dir):
|
||||||
|
@ -54,7 +54,7 @@ class PypoFetch(Thread):
|
||||||
is a file. We are not handling the second case, but don't
|
is a file. We are not handling the second case, but don't
|
||||||
think we actually care about handling it.
|
think we actually care about handling it.
|
||||||
"""
|
"""
|
||||||
logger.debug("Cache dir does not exist. Creating...")
|
self.logger.debug("Cache dir does not exist. Creating...")
|
||||||
os.makedirs(dir)
|
os.makedirs(dir)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
pass
|
pass
|
||||||
|
@ -210,6 +210,7 @@ class PypoFetch(Thread):
|
||||||
else:
|
else:
|
||||||
self.logger.info("No change detected in setting...")
|
self.logger.info("No change detected in setting...")
|
||||||
self.update_liquidsoap_connection_status()
|
self.update_liquidsoap_connection_status()
|
||||||
|
|
||||||
def update_liquidsoap_connection_status(self):
|
def update_liquidsoap_connection_status(self):
|
||||||
"""
|
"""
|
||||||
updates the status of liquidsoap connection to the streaming server
|
updates the status of liquidsoap connection to the streaming server
|
||||||
|
@ -315,7 +316,7 @@ class PypoFetch(Thread):
|
||||||
media_item = media[mkey]
|
media_item = media[mkey]
|
||||||
|
|
||||||
if bootstrapping:
|
if bootstrapping:
|
||||||
check_for_previous_crash(media_item)
|
self.check_for_previous_crash(media_item)
|
||||||
|
|
||||||
# create playlist directory
|
# create playlist directory
|
||||||
try:
|
try:
|
||||||
|
@ -323,15 +324,18 @@ class PypoFetch(Thread):
|
||||||
Extract year, month, date from mkey
|
Extract year, month, date from mkey
|
||||||
"""
|
"""
|
||||||
y_m_d = mkey[0:10]
|
y_m_d = mkey[0:10]
|
||||||
download_dir = os.mkdir(os.path.join(self.cache_dir, y_m_d))
|
download_dir = os.path.join(self.cache_dir, y_m_d)
|
||||||
|
try:
|
||||||
|
os.makedirs(os.path.join(self.cache_dir, y_m_d))
|
||||||
|
except Exception, e:
|
||||||
|
pass
|
||||||
fileExt = os.path.splitext(media_item['uri'])[1]
|
fileExt = os.path.splitext(media_item['uri'])[1]
|
||||||
dst = os.path.join(download_dir, media_item['id']+fileExt)
|
dst = os.path.join(download_dir, media_item['id']+fileExt)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.logger.warning(e)
|
self.logger.warning(e)
|
||||||
|
|
||||||
if self.handle_media_file(media_item, dst):
|
if self.handle_media_file(media_item, dst):
|
||||||
entry = create_liquidsoap_annotation(media_item, dst)
|
entry = self.create_liquidsoap_annotation(media_item, dst)
|
||||||
#entry['show_name'] = playlist['show_name']
|
|
||||||
entry['show_name'] = "TODO"
|
entry['show_name'] = "TODO"
|
||||||
media_item["annotation"] = entry
|
media_item["annotation"] = entry
|
||||||
|
|
||||||
|
@ -341,7 +345,7 @@ class PypoFetch(Thread):
|
||||||
return media
|
return media
|
||||||
|
|
||||||
|
|
||||||
def create_liquidsoap_annotation(media, dst):
|
def create_liquidsoap_annotation(self, media, dst):
|
||||||
pl_entry = \
|
pl_entry = \
|
||||||
'annotate:media_id="%s",liq_start_next="%s",liq_fade_in="%s",liq_fade_out="%s",liq_cue_in="%s",liq_cue_out="%s",schedule_table_id="%s":%s' \
|
'annotate:media_id="%s",liq_start_next="%s",liq_fade_in="%s",liq_fade_out="%s",liq_cue_in="%s",liq_cue_out="%s",schedule_table_id="%s":%s' \
|
||||||
% (media['id'], 0, \
|
% (media['id'], 0, \
|
||||||
|
@ -362,7 +366,7 @@ class PypoFetch(Thread):
|
||||||
entry['annotate'] = pl_entry
|
entry['annotate'] = pl_entry
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
def check_for_previous_crash(media_item):
|
def check_for_previous_crash(self, media_item):
|
||||||
start = media_item['start']
|
start = media_item['start']
|
||||||
end = media_item['end']
|
end = media_item['end']
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ class PypoPush(Thread):
|
||||||
|
|
||||||
self.liquidsoap_state_play = True
|
self.liquidsoap_state_play = True
|
||||||
self.push_ahead = 30
|
self.push_ahead = 30
|
||||||
|
self.last_end_time = 0
|
||||||
|
|
||||||
def push(self):
|
def push(self):
|
||||||
"""
|
"""
|
||||||
|
@ -68,15 +69,15 @@ class PypoPush(Thread):
|
||||||
str_tnow_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tnow[0], tnow[1], tnow[2], tnow[3], tnow[4], tnow[5])
|
str_tnow_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tnow[0], tnow[1], tnow[2], tnow[3], tnow[4], tnow[5])
|
||||||
str_tcoming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming[0], tcoming[1], tcoming[2], tcoming[3], tcoming[4], tcoming[5])
|
str_tcoming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming[0], tcoming[1], tcoming[2], tcoming[3], tcoming[4], tcoming[5])
|
||||||
|
|
||||||
|
for key in media:
|
||||||
for media_item in media:
|
media_item = media[key]
|
||||||
item_start = media_item['start'][0:19]
|
item_start = media_item['start'][0:19]
|
||||||
|
|
||||||
if str_tnow_s <= item_start and item_start < str_tcoming_s:
|
if str_tnow_s <= item_start and item_start < str_tcoming_s:
|
||||||
"""
|
"""
|
||||||
If the media item starts in the next 30 seconds, push it to the queue.
|
If the media item starts in the next 30 seconds, push it to the queue.
|
||||||
"""
|
"""
|
||||||
logger.debug('Preparing to push media item scheduled at: %s', pkey)
|
logger.debug('Preparing to push media item scheduled at: %s', key)
|
||||||
|
|
||||||
if self.push_to_liquidsoap(media_item):
|
if self.push_to_liquidsoap(media_item):
|
||||||
logger.debug("Pushed to liquidsoap, updating 'played' status.")
|
logger.debug("Pushed to liquidsoap, updating 'played' status.")
|
||||||
|
@ -86,7 +87,7 @@ class PypoPush(Thread):
|
||||||
|
|
||||||
# Call API to update schedule states
|
# Call API to update schedule states
|
||||||
logger.debug("Doing callback to server to update 'played' status.")
|
logger.debug("Doing callback to server to update 'played' status.")
|
||||||
self.api_client.notify_scheduled_item_start_playing(pkey, schedule)
|
self.api_client.notify_scheduled_item_start_playing(key, schedule)
|
||||||
|
|
||||||
def push_to_liquidsoap(self, media_item):
|
def push_to_liquidsoap(self, media_item):
|
||||||
"""
|
"""
|
||||||
|
@ -95,7 +96,7 @@ class PypoPush(Thread):
|
||||||
media item before pushing it.
|
media item before pushing it.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if media_item["starts"] == self.last_end_time:
|
if media_item["start"] == self.last_end_time:
|
||||||
"""
|
"""
|
||||||
this media item is attached to the end of the last
|
this media item is attached to the end of the last
|
||||||
track, so let's push it now so that Liquidsoap can start playing
|
track, so let's push it now so that Liquidsoap can start playing
|
||||||
|
@ -108,16 +109,16 @@ class PypoPush(Thread):
|
||||||
this media item does not start right after a current playing track.
|
this media item does not start right after a current playing track.
|
||||||
We need to sleep, and then wake up when this track starts.
|
We need to sleep, and then wake up when this track starts.
|
||||||
"""
|
"""
|
||||||
sleep_until_start(media_item)
|
self.sleep_until_start(media_item)
|
||||||
|
|
||||||
telnet_to_liquidsoap(media_item)
|
self.telnet_to_liquidsoap(media_item)
|
||||||
self.last_end_time = media_item["end"]
|
self.last_end_time = media_item["end"]
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def sleep_until_start(media_item):
|
def sleep_until_start(self, media_item):
|
||||||
"""
|
"""
|
||||||
The purpose of this function is to look at the difference between
|
The purpose of this function is to look at the difference between
|
||||||
"now" and when the media_item starts, and sleep for that period of time.
|
"now" and when the media_item starts, and sleep for that period of time.
|
||||||
|
@ -143,7 +144,7 @@ class PypoPush(Thread):
|
||||||
logger.debug('sleeping for %s s' % (sleep_time))
|
logger.debug('sleeping for %s s' % (sleep_time))
|
||||||
time.sleep(sleep_time)
|
time.sleep(sleep_time)
|
||||||
|
|
||||||
def telnet_to_liquidsoap(media_item):
|
def telnet_to_liquidsoap(self, media_item):
|
||||||
"""
|
"""
|
||||||
telnets to liquidsoap and pushes the media_item to its queue. Push the
|
telnets to liquidsoap and pushes the media_item to its queue. Push the
|
||||||
show name of every media_item as well, just to keep Liquidsoap up-to-date
|
show name of every media_item as well, just to keep Liquidsoap up-to-date
|
||||||
|
|
Loading…
Reference in New Issue