CC-3174 : showbuilder

checking modification time before deleting items.
Throws a ScheduleOutdatedException
This commit is contained in:
Naomi Aro 2012-02-16 16:29:11 +01:00
parent f14ebce239
commit e1d5d6de73
7 changed files with 159 additions and 58 deletions

View file

@ -83,20 +83,19 @@ class ShowbuilderController extends Zend_Controller_Action
public function scheduleAddAction() { public function scheduleAddAction() {
$request = $this->getRequest(); $request = $this->getRequest();
$mediaItems = $request->getParam("mediaIds", null); $mediaItems = $request->getParam("mediaIds", null);
$scheduledIds = $request->getParam("schedIds", null); $scheduledIds = $request->getParam("schedIds", null);
$json = array();
try { try {
$scheduler = new Application_Model_Scheduler(); $scheduler = new Application_Model_Scheduler();
$scheduler->scheduleAfter($scheduledIds, $mediaItems); $scheduler->scheduleAfter($scheduledIds, $mediaItems);
}
$json["message"]="success... maybe"; catch (OutDatedScheduleException $e) {
$this->view->error = $e->getMessage();
Logging::log($e->getMessage());
} }
catch (Exception $e) { catch (Exception $e) {
$json["message"]=$e->getMessage(); $this->view->error = $e->getMessage();
Logging::log($e->getMessage()); Logging::log($e->getMessage());
} }
@ -106,42 +105,38 @@ class ShowbuilderController extends Zend_Controller_Action
public function scheduleRemoveAction() public function scheduleRemoveAction()
{ {
$request = $this->getRequest(); $request = $this->getRequest();
$items = $request->getParam("items", null); $items = $request->getParam("items", null);
$json = array();
try { try {
$scheduler = new Application_Model_Scheduler(); $scheduler = new Application_Model_Scheduler();
$scheduler->removeItems($items); $scheduler->removeItems($items);
$json["message"]="success... maybe";
} }
catch (Exception $e) { catch (OutDatedScheduleException $e) {
$json["message"]=$e->getMessage(); $this->view->error = $e->getMessage();
Logging::log($e->getMessage());
}
catch (Exception $e) {
$this->view->error = $e->getMessage();
Logging::log($e->getMessage()); Logging::log($e->getMessage());
} }
$this->view->data = $json;
} }
public function scheduleMoveAction() { public function scheduleMoveAction() {
$request = $this->getRequest(); $request = $this->getRequest();
$selectedItem = $request->getParam("selectedItem"); $selectedItem = $request->getParam("selectedItem");
$afterItem = $request->getParam("afterItem"); $afterItem = $request->getParam("afterItem");
$json = array();
try { try {
$scheduler = new Application_Model_Scheduler(); $scheduler = new Application_Model_Scheduler();
$scheduler->moveItem($selectedItem, $afterItem); $scheduler->moveItem($selectedItem, $afterItem);
}
$json["message"]="success... maybe"; catch (OutDatedScheduleException $e) {
$this->view->error = $e->getMessage();
Logging::log($e->getMessage());
} }
catch (Exception $e) { catch (Exception $e) {
$json["message"]=$e->getMessage(); $this->view->error = $e->getMessage();
Logging::log($e->getMessage()); Logging::log($e->getMessage());
} }

View file

@ -313,7 +313,7 @@ class Application_Model_Schedule {
showt.background_color AS show_background_colour, showt.id AS show_id, showt.background_color AS show_background_colour, showt.id AS show_id,
si.starts AS si_starts, si.ends AS si_ends, si.time_filled AS si_time_filled, si.starts AS si_starts, si.ends AS si_ends, si.time_filled AS si_time_filled,
si.record AS si_record, si.rebroadcast AS si_rebroadcast, si.id AS si_id, si.record AS si_record, si.rebroadcast AS si_rebroadcast, si.id AS si_id, si.last_scheduled AS si_last_scheduled,
sched.starts AS sched_starts, sched.ends AS sched_ends, sched.id AS sched_id, sched.starts AS sched_starts, sched.ends AS sched_ends, sched.id AS sched_id,

View file

@ -297,10 +297,23 @@ class Application_Model_Scheduler {
$scheduledIds = array(); $scheduledIds = array();
foreach ($scheduledItems as $item) { foreach ($scheduledItems as $item) {
$scheduledIds[] = $item["id"]; $scheduledIds[$item["id"]] = $item["timestamp"];
}
$removedItems = CcScheduleQuery::create()->findPks(array_keys($scheduledIds));
//check to make sure all items selected are up to date
foreach ($removedItems as $removedItem) {
$ts = $scheduledIds[$removedItem->getDbId()];
$instance = $removedItem->getCcShowInstances($this->con);
$currTs = intval($instance->getDbLastScheduled("U")) ? : 0;
if ($ts !== $currTs) {
$show = $instance->getCcShow($this->con);
throw new OutDatedScheduleException("The show {$show->getDbName()} is outdated!");
}
} }
$removedItems = CcScheduleQuery::create()->findPks($scheduledIds);
$removedItems->delete($this->con); $removedItems->delete($this->con);
if ($adjustSched === true) { if ($adjustSched === true) {
@ -338,6 +351,9 @@ class Application_Model_Scheduler {
Logging::log("removing gaps from show instance #".$showInstance); Logging::log("removing gaps from show instance #".$showInstance);
$instance = CcShowInstancesQuery::create()->findPK($showInstance, $this->con); $instance = CcShowInstancesQuery::create()->findPK($showInstance, $this->con);
$instance->setDbLastScheduled(new DateTime("now", new DateTimeZone("UTC")));
$instance->save($this->con);
$itemStartDT = $instance->getDbStarts(null); $itemStartDT = $instance->getDbStarts(null);
$schedule = CcScheduleQuery::create() $schedule = CcScheduleQuery::create()
@ -360,4 +376,6 @@ class Application_Model_Scheduler {
$itemStartDT = $itemEndDT; $itemStartDT = $itemEndDT;
} }
} }
} }
class OutDatedScheduleException extends Exception {}

View file

@ -22,7 +22,8 @@ class Application_Model_ShowBuilder {
"runtime" => "", "runtime" => "",
"title" => "", "title" => "",
"creator" => "", "creator" => "",
"album" => "" "album" => "",
"timestamp" => null
); );
/* /*
@ -100,9 +101,22 @@ class Application_Model_ShowBuilder {
return $row; return $row;
} }
private function getRowTimestamp($p_item, &$row) {
if (is_null($p_item["si_last_scheduled"])) {
$ts = 0;
}
else {
$dt = new DateTime($p_item["si_last_scheduled"], new DateTimeZone("UTC"));
$ts = intval($dt->format("U"));
}
$row["timestamp"] = $ts;
}
private function makeHeaderRow($p_item) { private function makeHeaderRow($p_item) {
$row = $this->defaultRowArray; $row = $this->defaultRowArray;
$this->getRowTimestamp($p_item, &$row);
$showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC")); $showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC"));
$showStartDT->setTimezone(new DateTimeZone($this->timezone)); $showStartDT->setTimezone(new DateTimeZone($this->timezone));
@ -126,6 +140,7 @@ class Application_Model_ShowBuilder {
$epoch_now = time(); $epoch_now = time();
$showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC")); $showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC"));
$this->getRowTimestamp($p_item, &$row);
//can only schedule the show if it hasn't started and you are allowed. //can only schedule the show if it hasn't started and you are allowed.
if ($epoch_now < $showStartDT->format('U') && $this->user->canSchedule($p_item["show_id"]) == true) { if ($epoch_now < $showStartDT->format('U') && $this->user->canSchedule($p_item["show_id"]) == true) {

View file

@ -76,4 +76,35 @@ class CcShowInstances extends BaseCcShowInstances {
return $dt->format($format); return $dt->format($format);
} }
} }
/**
* Get the [optionally formatted] temporal [last_scheduled] column value.
*
*
* @param string $format The date/time format string (either date()-style or strftime()-style).
* If format is NULL, then the raw DateTime object will be returned.
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
* @throws PropelException - if unable to parse/validate the date/time value.
*/
public function getDbLastScheduled($format = 'Y-m-d H:i:s')
{
if ($this->last_scheduled === null) {
return null;
}
try {
$dt = new DateTime($this->last_scheduled, new DateTimeZone("UTC"));
} catch (Exception $x) {
throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->last_scheduled, true), $x);
}
if ($format === null) {
// Because propel.useDateTimeClass is TRUE, we return a DateTime object.
return $dt;
} elseif (strpos($format, '%') !== false) {
return strftime($format, $dt->format('U'));
} else {
return $dt->format($format);
}
}
} // CcShowInstances } // CcShowInstances

View file

@ -31,18 +31,13 @@ var AIRTIME = (function(AIRTIME){
fnResetCol, fnResetCol,
fnAddSelectedItems, fnAddSelectedItems,
fnTest = function() {
alert("hi");
};
fnResetCol = function () { fnResetCol = function () {
ColReorder.fnReset( oLibTable ); ColReorder.fnReset( oLibTable );
return false; return false;
}; };
fnAddSelectedItems = function() { fnAddSelectedItems = function() {
var oSchedTable = $("#show_builder_table").dataTable(), var oLibTT = TableTools.fnGetInstance('library_display'),
oLibTT = TableTools.fnGetInstance('library_display'),
oSchedTT = TableTools.fnGetInstance('show_builder_table'), oSchedTT = TableTools.fnGetInstance('show_builder_table'),
aData = oLibTT.fnGetSelectedData(), aData = oLibTT.fnGetSelectedData(),
item, item,
@ -68,12 +63,10 @@ var AIRTIME = (function(AIRTIME){
} }
} }
$.post("/showbuilder/schedule-add", AIRTIME.showbuilder.fnAdd(aMediaIds, aSchedIds, function(){
{"format": "json", "mediaIds": aMediaIds, "schedIds": aSchedIds}, oLibTT.fnSelectNone();
function(json){ });
oLibTT.fnSelectNone();
oSchedTable.fnDraw();
});
}; };
//[0] = button text //[0] = button text
//[1] = id //[1] = id

View file

@ -1,3 +1,61 @@
var AIRTIME = (function(AIRTIME){
var mod,
oSchedTable;
if (AIRTIME.showbuilder === undefined) {
AIRTIME.showbuilder = {};
}
mod = AIRTIME.showbuilder;
function checkError(json) {
if (json.error !== undefined) {
alert(json.error);
}
}
mod.fnAdd = function(aMediaIds, aSchedIds, callback) {
$.post("/showbuilder/schedule-add",
{"format": "json", "mediaIds": aMediaIds, "schedIds": aSchedIds},
function(json){
checkError(json);
oSchedTable.fnDraw();
if ($.isFunction(callback)) {
callback();
}
});
};
mod.fnMove = function(aSelect, aAfter) {
$.post("/showbuilder/schedule-move",
{"format": "json", "selectedItem": aSelect, "afterItem": aAfter},
function(json){
checkError(json);
oSchedTable.fnDraw();
});
};
mod.fnRemove = function(aItems) {
$.post( "/showbuilder/schedule-remove",
{"items": aItems, "format": "json"},
function(json) {
checkError(json);
oSchedTable.fnDraw();
});
};
mod.init = function(oTable) {
oSchedTable = oTable;
};
return AIRTIME;
}(AIRTIME || {}));
$(document).ready(function() { $(document).ready(function() {
var tableDiv = $('#show_builder_table'), var tableDiv = $('#show_builder_table'),
oTable, oTable,
@ -201,15 +259,11 @@ $(document).ready(function() {
for (item in aData) { for (item in aData) {
temp = aData[item]; temp = aData[item];
if (temp !== null && temp.hasOwnProperty('id')) { if (temp !== null && temp.hasOwnProperty('id')) {
aItems.push({"id": temp.id, "instance": temp.instance}); aItems.push({"id": temp.id, "instance": temp.instance, "timestamp": temp.timestamp});
} }
} }
$.post( "/showbuilder/schedule-remove", AIRTIME.showbuilder.fnRemove(aItems);
{"items": aItems, "format": "json"},
function(data) {
oTable.fnDraw();
});
}; };
oTable = tableDiv.dataTable( { oTable = tableDiv.dataTable( {
@ -258,7 +312,7 @@ $(document).ready(function() {
//don't select separating rows, or shows without privileges. //don't select separating rows, or shows without privileges.
if ($(node).hasClass("sb-header") if ($(node).hasClass("sb-header")
|| $(node).hasClass("sb-footer") || $(node).hasClass("sb-footer")
|| $(node).hasClass("sb-not-allowed")){ || $(node).hasClass("sb-not-allowed")) {
return false; return false;
} }
return true; return true;
@ -352,28 +406,20 @@ $(document).ready(function() {
var aMediaIds = [], var aMediaIds = [],
aSchedIds = []; aSchedIds = [];
aSchedIds.push({"id": oPrevData.id, "instance": oPrevData.instance}); aSchedIds.push({"id": oPrevData.id, "instance": oPrevData.instance, "timestamp": oPrevData.timestamp});
aMediaIds.push({"id": oItemData.id, "type": oItemData.ftype}); aMediaIds.push({"id": oItemData.id, "type": oItemData.ftype});
$.post("/showbuilder/schedule-add", AIRTIME.showbuilder.fnAdd(aMediaIds, aSchedIds);
{"format": "json", "mediaIds": aMediaIds, "schedIds": aSchedIds},
function(json){
oTable.fnDraw();
});
}; };
fnMove = function() { fnMove = function() {
var aSelect = [], var aSelect = [],
aAfter = []; aAfter = [];
aSelect.push({"id": oItemData.id, "instance": oItemData.instance}); aSelect.push({"id": oItemData.id, "instance": oItemData.instance, "timestamp": oItemData.timestamp});
aAfter.push({"id": oPrevData.id, "instance": oPrevData.instance}); aAfter.push({"id": oPrevData.id, "instance": oPrevData.instance, "timestamp": oPrevData.timestamp});
$.post("/showbuilder/schedule-move", AIRTIME.showbuilder.fnMove(aSelect, aAfter);
{"format": "json", "selectedItem": aSelect, "afterItem": aAfter},
function(json){
oTable.fnDraw();
});
}; };
fnReceive = function(event, ui) { fnReceive = function(event, ui) {
@ -414,4 +460,7 @@ $(document).ready(function() {
.append('<div class="ColVis TableTools"><button class="ui-button ui-state-default"><span>Delete</span></button></div>') .append('<div class="ColVis TableTools"><button class="ui-button ui-state-default"><span>Delete</span></button></div>')
.click(fnRemoveSelectedItems); .click(fnRemoveSelectedItems);
//set things like a reference to the table.
AIRTIME.showbuilder.init(oTable);
}); });