From 79b6d13c168d7b9292e551f7221a1c5c2fbcc0a7 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Thu, 30 Aug 2012 17:52:39 -0400 Subject: [PATCH 1/8] CC-4321: NowPlaying: Cancelling Webstream has no effect and results in OnAir being grayed out -set DbEnds to 1 second in the past when cancelling stream --- airtime_mvc/application/models/Schedule.php | 2 +- airtime_mvc/application/models/Scheduler.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php index a5c532c34..fdbec24b7 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -605,7 +605,7 @@ SQL; } // Scheduler wants everything in a playlist - $items = Application_Model_Schedule::GetItems($range_start, $range_end); + $items = self::GetItems($range_start, $range_end); $data = array(); $utcTimeZone = new DateTimeZone("UTC"); diff --git a/airtime_mvc/application/models/Scheduler.php b/airtime_mvc/application/models/Scheduler.php index b47e2ad38..1944cbd58 100644 --- a/airtime_mvc/application/models/Scheduler.php +++ b/airtime_mvc/application/models/Scheduler.php @@ -660,9 +660,12 @@ class Application_Model_Scheduler $cueOutSec = bcadd($cueinSec , $length, 6); $cueout = Application_Common_DateHelper::secondsToPlaylistTime($cueOutSec); + //Set DbEnds - 1 second because otherwise there can be a timing issue + //when sending the new schedule to Pypo where Pypo thinks the track is still + //playing. $removedItem->setDbCueOut($cueout) ->setDbClipLength($cliplength) - ->setDbEnds($this->nowDT) + ->setDbEnds($this->nowDT->sub(new DateInteval("PT1S"))) ->save($this->con); } else { $removedItem->delete($this->con); From 1fe5a0446f2c60738bba1fbd2fde2aed0ff1495b Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 31 Aug 2012 12:57:59 +0100 Subject: [PATCH 2/8] Fix lines disabling symlink installation --- gen-snapshot.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gen-snapshot.sh b/gen-snapshot.sh index d98899993..4fd667aa1 100755 --- a/gen-snapshot.sh +++ b/gen-snapshot.sh @@ -47,10 +47,10 @@ sed -i '91s:tr:#tr:g' airtime/python_apps/pypo/install/pypo-initialize.py sed -i '92s:os.unlink:#os.unlink:g' airtime/python_apps/pypo/install/pypo-initialize.py sed -i '93s:except:#except:g' airtime/python_apps/pypo/install/pypo-initialize.py sed -i '95s:pass:#pass:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '98s:os.symlink:#os.symlink:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '99s:else:#else:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '100s:print:#print:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '101s:sys.exit:#sys.exit:g' airtime/python_apps/pypo/install/pypo-initialize.py +sed -i '97s:os.symlink:#os.symlink:g' airtime/python_apps/pypo/install/pypo-initialize.py +sed -i '98s:else:#else:g' airtime/python_apps/pypo/install/pypo-initialize.py +sed -i '99s:print:#print:g' airtime/python_apps/pypo/install/pypo-initialize.py +sed -i '100s:sys.exit:#sys.exit:g' airtime/python_apps/pypo/install/pypo-initialize.py #Remove phing library rm -r airtime/airtime_mvc/library/phing/ From ea816a4310b1d8db8945ce723dae54dc47329ccb Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 31 Aug 2012 12:59:26 +0100 Subject: [PATCH 3/8] Don't upload by default, we have a script installed on the apt server now --- gen-snapshot.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gen-snapshot.sh b/gen-snapshot.sh index 4fd667aa1..ea791e2f5 100755 --- a/gen-snapshot.sh +++ b/gen-snapshot.sh @@ -71,7 +71,7 @@ echo "running the build..." debuild -b -uc -us $@ || exit # copy the new package to the public server -scp /tmp/airtime_${VERSION}_all.deb apt.sourcefabric.org:/var/www/apt/snapshots/ +# scp /tmp/airtime_${VERSION}_all.deb apt.sourcefabric.org:/var/www/apt/snapshots/ # copy the build log too -scp /tmp/airtime_${VERSION}_amd64.build apt.sourcefabric.org:/var/www/apt/snapshots/ +# scp /tmp/airtime_${VERSION}_amd64.build apt.sourcefabric.org:/var/www/apt/snapshots/ From 4ffbbfa164cd9c45a93a58ebc201115fce76d3f9 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 31 Aug 2012 14:36:05 +0100 Subject: [PATCH 4/8] Update the text sent to the console, since binary is no longer installed here --- python_apps/pypo/install/pypo-initialize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/pypo/install/pypo-initialize.py b/python_apps/pypo/install/pypo-initialize.py index ebf49a65c..af12ff02e 100644 --- a/python_apps/pypo/install/pypo-initialize.py +++ b/python_apps/pypo/install/pypo-initialize.py @@ -81,7 +81,7 @@ try: (codename, fullname) = get_os_codename() print " Found %s (%s) on %s architecture" % (fullname, codename, arch) - print " * Installing Liquidsoap binary" + print " * Creating symlink to Liquidsoap binary" p = Popen("which liquidsoap", shell=True, stdout=PIPE) liq_path = p.communicate()[0].strip() From d02deac38d66e3c716b1c1a432368b2e279fc2fc Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 31 Aug 2012 14:38:42 +0100 Subject: [PATCH 5/8] We no longer need to comment out symlink creation --- gen-snapshot.sh | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/gen-snapshot.sh b/gen-snapshot.sh index ea791e2f5..5224daf53 100755 --- a/gen-snapshot.sh +++ b/gen-snapshot.sh @@ -37,21 +37,6 @@ rm airtime/airtime_mvc/library/soundcloud-api/README.md # Remove Liquidsoap binaries rm -r airtime/python_apps/pypo/liquidsoap_bin/ -# Disable installation of Liquidsoap symlink -sed -i '84s:print:#print:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '86s:p = Popen:#p = Popen:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '87s:liq_path:#liq_path:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '88s:symlink_path:#symlink_path:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '90s:if p.returncode:#if p.returncode:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '91s:tr:#tr:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '92s:os.unlink:#os.unlink:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '93s:except:#except:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '95s:pass:#pass:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '97s:os.symlink:#os.symlink:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '98s:else:#else:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '99s:print:#print:g' airtime/python_apps/pypo/install/pypo-initialize.py -sed -i '100s:sys.exit:#sys.exit:g' airtime/python_apps/pypo/install/pypo-initialize.py - #Remove phing library rm -r airtime/airtime_mvc/library/phing/ From c043053407dc4daaf8b8b6eb046d00b145b64408 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 31 Aug 2012 12:18:37 -0400 Subject: [PATCH 6/8] CC-4321: NowPlaying: Cancelling Webstream has no effect and results in OnAir being grayed out -fixed --- airtime_mvc/application/models/Schedule.php | 7 +-- airtime_mvc/application/models/Scheduler.php | 10 +++- python_apps/pypo/pypopush.py | 58 +++++++++++--------- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php index fdbec24b7..176c88f3c 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -14,11 +14,8 @@ class Application_Model_Schedule $sql = "SELECT COUNT(*) FROM ".$CC_CONFIG["scheduleTable"] ." WHERE file_id = {$p_fileId} AND ends > NOW() AT TIME ZONE 'UTC'"; $count = $con->query($sql)->fetchColumn(0); - if (is_numeric($count) && ($count != '0')) { - return TRUE; - } else { - return FALSE; - } + + return (is_numeric($count) && ($count != '0')); } /** diff --git a/airtime_mvc/application/models/Scheduler.php b/airtime_mvc/application/models/Scheduler.php index 1944cbd58..68e8bf8ad 100644 --- a/airtime_mvc/application/models/Scheduler.php +++ b/airtime_mvc/application/models/Scheduler.php @@ -24,7 +24,11 @@ class Application_Model_Scheduler { $this->con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME); - $this->epochNow = microtime(true); + //subtracting one because sometimes when we cancel a track, we set its end time + //to epochNow and then send the new schedule to pypo. Sometimes the currently cancelled + //track can still be included in the new schedule because it may have a few ms left to play. + //subtracting 1 second from epochNow resolves this issue. + $this->epochNow = microtime(true)-1; $this->nowDT = DateTime::createFromFormat("U.u", $this->epochNow, new DateTimeZone("UTC")); if ($this->nowDT === false) { @@ -324,6 +328,8 @@ class Application_Model_Scheduler * @param int $showInstance * @param array $exclude * ids of sched items to remove from the calulation. + * This function squeezes all items of a show together so that + * there are no gaps between them. */ private function removeGaps($showInstance, $exclude=null) { @@ -665,7 +671,7 @@ class Application_Model_Scheduler //playing. $removedItem->setDbCueOut($cueout) ->setDbClipLength($cliplength) - ->setDbEnds($this->nowDT->sub(new DateInteval("PT1S"))) + ->setDbEnds($this->nowDT) ->save($this->con); } else { $removedItem->delete($this->con); diff --git a/python_apps/pypo/pypopush.py b/python_apps/pypo/pypopush.py index 87e651fab..f57a8c468 100644 --- a/python_apps/pypo/pypopush.py +++ b/python_apps/pypo/pypopush.py @@ -81,27 +81,29 @@ class PypoPush(Thread): chains.remove(original_chain) except ValueError, e: self.logger.error(str(e)) - if len(liquidsoap_queue_approx) == 0 and current_event_chain[0]['type'] == 'file': - #Something is scheduled but Liquidsoap is not playing anything! - #Need to schedule it immediately..this might happen if Liquidsoap crashed. - self.modify_cue_point(current_event_chain[0]) - next_media_item_chain = current_event_chain - time_until_next_play = 0 - #sleep for 0.2 seconds to give pypo-file time to copy. - time.sleep(0.2) - continue - if not self.current_stream_info and current_event_chain[0]['type'] == 'stream': - #a stream is schedule but Liquidsoap is not playing it. Need to start it. - next_media_item_chain = current_event_chain - time_until_next_play = 0 - continue + + if len(liquidsoap_queue_approx) == 0 and not self.current_stream_info: + #Nothing is currently being playing by Liquidsoap + if current_event_chain[0]['type'] == 'file': + #Something is scheduled but Liquidsoap is not playing anything! + #Need to schedule it immediately..this might happen if Liquidsoap crashed. + self.modify_cue_point(current_event_chain[0]) + next_media_item_chain = current_event_chain + time_until_next_play = 0 + #sleep for 0.2 seconds to give pypo-file time to copy. + time.sleep(0.2) + continue + if current_event_chain[0]['type'] == 'stream': + #a stream is schedule but Liquidsoap is not playing it. Need to start it. + next_media_item_chain = current_event_chain + time_until_next_play = 0 + continue #At this point we know that Liquidsoap is playing something, and that something #is scheduled. We need to verify whether the schedule we just received matches #what Liquidsoap is playing, and if not, correct it. - media_chain = filter(lambda item: (item["type"] == "file"), current_event_chain) - stream_chain = filter(lambda item: (item["type"] == "stream"), current_event_chain) - self.handle_new_schedule(media_schedule, liquidsoap_queue_approx, media_chain, stream_chain) + + self.handle_new_schedule(media_schedule, liquidsoap_queue_approx, current_event_chain) #At this point everything in the present has been taken care of and Liquidsoap @@ -184,7 +186,7 @@ class PypoPush(Thread): return liquidsoap_queue_approx - def handle_new_schedule(self, media_schedule, liquidsoap_queue_approx, media_chain, stream_chain): + def handle_new_schedule(self, media_schedule, liquidsoap_queue_approx, current_event_chain): """ This function's purpose is to gracefully handle situations where Liquidsoap already has a track in its queue, but the schedule @@ -192,18 +194,24 @@ class PypoPush(Thread): call other functions that will connect to Liquidsoap and alter its queue. """ + media_chain = filter(lambda item: (item["type"] == "file"), current_event_chain) + stream_chain = filter(lambda item: (item["type"] == "stream"), current_event_chain) + + self.logger.debug(self.current_stream_info) + self.logger.debug(current_event_chain) + if self.current_stream_info: - if len(stream_chain) == 0: + if current_event_chain[0]['type'] == "stream": + if self.current_stream_info['uri'] != stream_chain[0]['uri']: + #Liquidsoap is rebroadcasting a webstream and a webstream is scheduled + #to play, but they are not the same! + self.stop_web_stream(self.current_stream_info) + self.start_web_stream(stream_chain[0]) + else: #Liquidsoap is rebroadcasting a webstream, but there is no stream #in the schedule. Let's stop streaming. self.stop_web_stream(self.current_stream_info) - elif self.current_stream_info['uri'] != stream_chain[0]['uri']: - #Liquidsoap is rebroadcasting a webstream and a webstream is scheduled - #to play, but they are not the same! - self.stop_web_stream(self.current_stream_info) - self.start_web_stream(stream_chain[0]) - problem_at_iteration = self.find_removed_items(media_schedule, liquidsoap_queue_approx) From 61537c550ec0e133166cc1615cfbff7632fd975b Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 31 Aug 2012 12:49:35 -0400 Subject: [PATCH 7/8] CC-4321: NowPlaying: Cancelling Webstream has no effect and results in OnAir being grayed out -fix out of bounds error --- python_apps/pypo/pypopush.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/pypo/pypopush.py b/python_apps/pypo/pypopush.py index f57a8c468..f8278d0f3 100644 --- a/python_apps/pypo/pypopush.py +++ b/python_apps/pypo/pypopush.py @@ -202,7 +202,7 @@ class PypoPush(Thread): if self.current_stream_info: - if current_event_chain[0]['type'] == "stream": + if len(current_event_chain) > 0 && current_event_chain[0]['type'] == "stream": if self.current_stream_info['uri'] != stream_chain[0]['uri']: #Liquidsoap is rebroadcasting a webstream and a webstream is scheduled #to play, but they are not the same! From 1aa73c73470d7f13922a306b11bb9c22d2a77644 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 31 Aug 2012 12:52:07 -0400 Subject: [PATCH 8/8] CC-4321: NowPlaying: Cancelling Webstream has no effect and results in OnAir being grayed out -syntax error :/ --- python_apps/pypo/pypopush.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/pypo/pypopush.py b/python_apps/pypo/pypopush.py index f8278d0f3..9fa508aa5 100644 --- a/python_apps/pypo/pypopush.py +++ b/python_apps/pypo/pypopush.py @@ -202,7 +202,7 @@ class PypoPush(Thread): if self.current_stream_info: - if len(current_event_chain) > 0 && current_event_chain[0]['type'] == "stream": + if len(current_event_chain) > 0 and current_event_chain[0]['type'] == "stream": if self.current_stream_info['uri'] != stream_chain[0]['uri']: #Liquidsoap is rebroadcasting a webstream and a webstream is scheduled #to play, but they are not the same!