diff --git a/airtime_mvc/application/models/Scheduler.php b/airtime_mvc/application/models/Scheduler.php index 54622e8a7..bb2727feb 100644 --- a/airtime_mvc/application/models/Scheduler.php +++ b/airtime_mvc/application/models/Scheduler.php @@ -89,7 +89,7 @@ class Application_Model_Scheduler { * * @return DateTime endDT in UTC */ - public static function findEndTime($p_startDT, $p_duration) { + private static function findEndTime($p_startDT, $p_duration) { $startEpoch = $p_startDT->format("U.u"); $durationSeconds = Application_Model_Playlist::playlistTimeToSeconds($p_duration); @@ -109,6 +109,39 @@ class Application_Model_Scheduler { return $dt; } + + private function findNextStartTime($DT, $instance) { + + //check to see if the show has started. + $nowDT = new DateTime("now", new DateTimeZone("UTC")); + + $sEpoch = intval($DT->format("U")); + $nEpoch = intval($nowDT->format("U")); + + //check for if the show has started. + if ($nEpoch > $sEpoch) { + //need some kind of placeholder for cc_schedule. + //playout_status will be -1. + $nextDT = $nowDT; + + $length = $nEpoch - $sEpoch; + $cliplength = Application_Model_Playlist::secondsToPlaylistTime($length); + + //fillers are for only storing a chunk of time space that has already passed. + $filler = new CcSchedule(); + $filler->setDbStarts($DT) + ->setDbEnds($nowDT) + ->setDbClipLength($cliplength) + ->setDbPlayoutStatus(-1) + ->setDbInstanceId($instance->getDbId()) + ->save($this->con); + } + else { + $nextDT = $DT; + } + + return $nextDT; + } /* * @param array $scheduledIds @@ -145,12 +178,16 @@ class Application_Model_Scheduler { if (intval($schedule["instance"]) !== $instance->getDbId()) { throw new OutDatedScheduleException("The schedule you're viewing is out of date!"); } - $nextStartDT = $schedItem->getDbEnds(null); + $schedItemEndDT = $schedItem->getDbEnds(null); + $nextStartDT = $this->findNextStartTime($schedItemEndDT, $instance); } //selected empty row to add after else { $instance = CcShowInstancesQuery::create()->findPK($schedule["instance"], $this->con); - $nextStartDT = $instance->getDbStarts(null); + + //check to see if the show has started. + $showStartDT = $instance->getDbStarts(null); + $nextStartDT = $this->findNextStartTime($showStartDT, $instance); } $currTs = intval($instance->getDbLastScheduled("U")) ? : 0; @@ -244,6 +281,7 @@ class Application_Model_Scheduler { ->update(array('DbLastScheduled' => new DateTime("now", new DateTimeZone("UTC"))), $this->con); } catch (Exception $e) { + Logging::debug($e->getMessage()); throw $e; } } diff --git a/airtime_mvc/application/models/ShowBuilder.php b/airtime_mvc/application/models/ShowBuilder.php index b6343a433..7628f8923 100644 --- a/airtime_mvc/application/models/ShowBuilder.php +++ b/airtime_mvc/application/models/ShowBuilder.php @@ -54,7 +54,7 @@ class Application_Model_ShowBuilder { $this->epoch_now = time(); } - //check to see if this row should be editable. + //check to see if this row should be editable by the user. private function isAllowed($p_item, &$row) { //cannot schedule in a recorded show. @@ -62,17 +62,20 @@ class Application_Model_ShowBuilder { return; } + /* $showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC")); + $showEndDT = new DateTime($p_item["si_ends"], new DateTimeZone("UTC")); $schedStartDT = new DateTime($p_item["sched_starts"], new DateTimeZone("UTC")); $showStartEpoch = intval($showStartDT->format('U')); + $showEndEpoch = intval($showEndDT->format('U')); $schedStartEpoch = intval($schedStartDT->format('U')); + */ - //can only schedule the show if item hasn't started and you are allowed. - if ($this->epoch_now < max($showStartEpoch, $schedStartEpoch) - && $this->user->canSchedule($p_item["show_id"]) == true) { + if ($this->user->canSchedule($p_item["show_id"]) == true) { $row["allowed"] = true; } + } private function getItemColor($p_item, &$row) { @@ -154,7 +157,7 @@ class Application_Model_ShowBuilder { $row = $this->defaultRowArray; $this->isAllowed($p_item, $row); $this->getRowTimestamp($p_item, $row); - $this->getItemColor($p_item, &$row); + $this->getItemColor($p_item, $row); $showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC")); $showStartDT->setTimezone(new DateTimeZone($this->timezone)); @@ -182,10 +185,6 @@ class Application_Model_ShowBuilder { private function makeScheduledItemRow($p_item) { $row = $this->defaultRowArray; - $this->getItemColor($p_item, &$row); - $this->getRowTimestamp($p_item, $row); - $this->isAllowed($p_item, $row); - if (isset($p_item["sched_starts"])) { $schedStartDT = new DateTime($p_item["sched_starts"], new DateTimeZone("UTC")); @@ -235,6 +234,10 @@ class Application_Model_ShowBuilder { $row["instance"] = intval($p_item["si_id"]); $row["image"] = ''; } + + $this->getItemColor($p_item, $row); + $this->getRowTimestamp($p_item, $row); + $this->isAllowed($p_item, $row); return $row; } @@ -263,7 +266,8 @@ class Application_Model_ShowBuilder { $showEndDT->setTimezone(new DateTimeZone($this->timezone)); $endsEpoch = intval($showEndDT->format("U")); - $this->getScheduledStatus($startsEpoch, $endsEpoch, $row); + $this->getScheduledStatus($startsEpoch, $endsEpoch, $row); + $this->isAllowed($p_item, $row); return $row; } @@ -327,6 +331,11 @@ class Application_Model_ShowBuilder { for ($i = 0, $rows = count($scheduled_items); $i < $rows; $i++) { $item = $scheduled_items[$i]; + + //don't send back data for filler rows. + if (isset($item["playout_status"]) && $item["playout_status"] < 0) { + continue; + } //make a header row. if ($current_id !== $item["si_id"]) { diff --git a/airtime_mvc/application/models/airtime/CcShowInstances.php b/airtime_mvc/application/models/airtime/CcShowInstances.php index a0d4858ea..5c3536ebb 100644 --- a/airtime_mvc/application/models/airtime/CcShowInstances.php +++ b/airtime_mvc/application/models/airtime/CcShowInstances.php @@ -112,10 +112,13 @@ class CcShowInstances extends BaseCcShowInstances { public function updateScheduleStatus(PropelPDO $con) { Logging::log("in post save for showinstances"); + + $now = time(); //scheduled track is in the show CcScheduleQuery::create() ->filterByDbInstanceId($this->id) + ->filterByDbPlayoutStatus(0, Criteria::GREATER_EQUAL) ->filterByDbEnds($this->ends, Criteria::LESS_EQUAL) ->update(array('DbPlayoutStatus' => 1), $con); @@ -124,6 +127,7 @@ class CcShowInstances extends BaseCcShowInstances { //scheduled track is a boundary track CcScheduleQuery::create() ->filterByDbInstanceId($this->id) + ->filterByDbPlayoutStatus(0, Criteria::GREATER_EQUAL) ->filterByDbStarts($this->ends, Criteria::LESS_THAN) ->filterByDbEnds($this->ends, Criteria::GREATER_THAN) ->update(array('DbPlayoutStatus' => 2), $con); @@ -131,6 +135,7 @@ class CcShowInstances extends BaseCcShowInstances { //scheduled track is overbooked. CcScheduleQuery::create() ->filterByDbInstanceId($this->id) + ->filterByDbPlayoutStatus(0, Criteria::GREATER_EQUAL) ->filterByDbStarts($this->ends, Criteria::GREATER_THAN) ->update(array('DbPlayoutStatus' => 0), $con); diff --git a/airtime_mvc/application/models/airtime/om/BaseCcSchedule.php b/airtime_mvc/application/models/airtime/om/BaseCcSchedule.php index 41dcd22f5..989f12a98 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcSchedule.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcSchedule.php @@ -726,7 +726,9 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent if ($v !== null) { $v = (int) $v; } - + + Logging::log('$v status is '.$v); + if ($this->playout_status !== $v || $this->isNew()) { $this->playout_status = $v; $this->modifiedColumns[] = CcSchedulePeer::PLAYOUT_STATUS; diff --git a/airtime_mvc/public/css/showbuilder.css b/airtime_mvc/public/css/showbuilder.css index ce863be85..110868a0f 100644 --- a/airtime_mvc/public/css/showbuilder.css +++ b/airtime_mvc/public/css/showbuilder.css @@ -75,10 +75,6 @@ width:100px; } -table.datatable tr.cursor-selected-row td, table.datatable tr.cursor-selected-row th { - border-bottom: 1px solid rgba(215, 0, 0, 1) !important; -} - .sb-starts, .sb-ends { text-align: center; @@ -90,7 +86,7 @@ table.datatable tr.cursor-selected-row td, table.datatable tr.cursor-selected-ro } .marker { background: url(images/tl-arrow.png) no-repeat scroll 3px 4px; - bottom: -14px; + top: -14px; display: block; height: 9px; left: -17px; @@ -109,6 +105,10 @@ tr.cursor-selected-row .marker { background-color: rgba(215, 0, 0, 1); } +table.datatable tr.cursor-selected-row td, table.datatable tr.cursor-selected-row th { + border-top: 1px solid rgba(215, 0, 0, 1) !important; +} + .sb-content .sb-past { opacity: .6; } diff --git a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js index 6f5a4648c..9df134c35 100644 --- a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js +++ b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js @@ -109,7 +109,7 @@ var AIRTIME = (function(AIRTIME){ aData = []; $("#show_builder_table tr.cursor-selected-row").each(function(i, el){ - aData.push($(el).data("aData")); + aData.push($(el).prev().data("aData")); }); //process selected schedule rows to add media after. diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index d50e964bb..7f016cf66 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -323,7 +323,7 @@ var AIRTIME = (function(AIRTIME){ else { node = nRow.children[0]; - if (aData.allowed === true) { + if (aData.allowed === true && aData.scheduled === 2) { node.innerHTML = ''; } else { @@ -367,7 +367,7 @@ var AIRTIME = (function(AIRTIME){ if ($lib.length > 0 && $lib.filter(":visible").length > 0) { //create cursor arrows. - $sbTable.find("tr.sb-now-playing, tr:not(:first, .sb-footer, .sb-empty, .sb-not-allowed)").each(function(i, el) { + $sbTable.find("tr:not(:first, .sb-header, .sb-empty, .sb-now-playing, .sb-past, .sb-not-allowed)").each(function(i, el) { td = $(el).find("td:first"); if (td.hasClass("dataTables_empty")) { return false; @@ -404,7 +404,7 @@ var AIRTIME = (function(AIRTIME){ } //current song is not set, set a timeout to refresh when the first item on the timeline starts. else { - tr = $sbTable.find("tbody tr.sb-allowed.sb-header:first"); + tr = $sbTable.find("tbody tr.sb-future.sb-header:first"); if (tr.length > 0) { aData = tr.data("aData"); @@ -417,7 +417,7 @@ var AIRTIME = (function(AIRTIME){ } //check if there are any overbooked tracks on screen to enable the trim button. - tr = $sbTable.find("tr.sb-over"); + tr = $sbTable.find("tr.sb-over.sb-future"); if (tr.length > 0) { //enable deleting of overbooked tracks. @@ -457,7 +457,8 @@ var AIRTIME = (function(AIRTIME){ if ($(node).hasClass("sb-header") || $(node).hasClass("sb-footer") || $(node).hasClass("sb-empty") - || $(node).hasClass("sb-not-allowed")) { + || $(node).hasClass("sb-not-allowed") + || $(node).hasClass("sb-past")) { return false; } return true; @@ -466,7 +467,7 @@ var AIRTIME = (function(AIRTIME){ //seems to happen if everything is selected if ( node === null) { - oTable.find("input[type=checkbox]").attr("checked", true); + $sbTable.find("tbody input[type=checkbox]").attr("checked", true); } else { $(node).find("input[type=checkbox]").attr("checked", true); @@ -508,7 +509,7 @@ var AIRTIME = (function(AIRTIME){ if ($(this).is(":checked")) { var allowedNodes; - allowedNodes = oTable.find('tr:not(:first, .sb-header, .sb-empty, .sb-footer, .sb-not-allowed)'); + allowedNodes = oTable.find('tr:not(:first, .sb-header, .sb-empty, .sb-footer, .sb-not-allowed, .sb-past)'); allowedNodes.each(function(i, el){ oTT.fnSelect(el); @@ -658,7 +659,7 @@ var AIRTIME = (function(AIRTIME){ return draggingContainer; }, - items: 'tr:not(:first, :last, .sb-header, .sb-footer, .sb-not-allowed)', + items: 'tr:not(:first, :last, .sb-header, .sb-footer, .sb-not-allowed, .sb-past, .sb-now-playing)', receive: fnReceive, update: fnUpdate, start: function(event, ui) {