diff --git a/airtime_mvc/application/controllers/ShowbuilderController.php b/airtime_mvc/application/controllers/ShowbuilderController.php index 2c4fd4b16..ec34f68f2 100644 --- a/airtime_mvc/application/controllers/ShowbuilderController.php +++ b/airtime_mvc/application/controllers/ShowbuilderController.php @@ -264,12 +264,15 @@ class ShowbuilderController extends Zend_Controller_Action //default ends is 24 hours after starts. $ends_epoch = $request->getParam("end", $current_time + (60*60*24)); $show_filter = intval($request->getParam("showFilter", 0)); + $show_instance_filter = intval($request->getParam("showInstanceFilter", 0)); $my_shows = intval($request->getParam("myShows", 0)); $startsDT = DateTime::createFromFormat("U", $starts_epoch, new DateTimeZone("UTC")); $endsDT = DateTime::createFromFormat("U", $ends_epoch, new DateTimeZone("UTC")); - $opts = array("myShows" => $my_shows, "showFilter" => $show_filter); + $opts = array("myShows" => $my_shows, + "showFilter" => $show_filter, + "showInstanceFilter" => $show_instance_filter); $showBuilder = new Application_Model_ShowBuilder($startsDT, $endsDT, $opts); $data = $showBuilder->getItems(); diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php index 3759254d4..3ea36c099 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -309,13 +309,11 @@ SQL; * @return array $scheduledItems * */ - public static function GetScheduleDetailItems($p_start, $p_end, $p_shows) + public static function GetScheduleDetailItems($p_start, $p_end, $p_shows, $p_show_instances) { $p_start_str = $p_start->format("Y-m-d H:i:s"); $p_end_str = $p_end->format("Y-m-d H:i:s"); - $paramMap = array(); - //We need to search 24 hours before and after the show times so that that we //capture all of the show's contents. $p_track_start= $p_start->sub(new DateInterval("PT24H"))->format("Y-m-d H:i:s"); @@ -355,7 +353,7 @@ SQL; AND sched.ends >= :fj_ts_6)) ) SQL; - $map = array( + $paramMap = array( ":fj_ts_1" => $p_track_start, ":fj_ts_2" => $p_track_end, ":fj_ts_3" => $p_track_start, @@ -363,8 +361,6 @@ SQL; ":fj_ts_5" => $p_track_start, ":fj_ts_6" => $p_track_end, ); - $paramMap = $paramMap + $map; - $filesSql = str_replace("%%columns%%", $filesColumns, @@ -426,6 +422,8 @@ SQL; $showPredicate = " AND show_id IN (".implode(",", $params).")"; $paramMap = $paramMap + $map; + } else if (count($p_show_instances) > 0) { + $showPredicate = " AND si.id IN (".implode(",", $p_show_instances).")"; } $sql = <<getListOfFilesUnderLimit(); foreach ($dynamicFiles as $f) { $fileId = $f['id']; @@ -263,8 +265,8 @@ class Application_Model_Scheduler $data["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein); //fade is in format SS.uuuuuu - $data["fadein"] = Application_Model_Preference::GetDefaultFadeIn(); - $data["fadeout"] = Application_Model_Preference::GetDefaultFadeOut(); + $data["fadein"] = $defaultFadeIn; + $data["fadeout"] = $defaultFadeOut; $data["type"] = 0; $files[] = $data; @@ -306,6 +308,8 @@ class Application_Model_Scheduler $files[] = $data; } } else { + $defaultFadeIn = Application_Model_Preference::GetDefaultFadeIn(); + $defaultFadeOut = Application_Model_Preference::GetDefaultFadeOut(); $dynamicFiles = $bl->getListOfFilesUnderLimit(); foreach ($dynamicFiles as $f) { $fileId = $f['id']; @@ -320,8 +324,8 @@ class Application_Model_Scheduler $data["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein); //fade is in format SS.uuuuuu - $data["fadein"] = Application_Model_Preference::GetDefaultFadeIn(); - $data["fadeout"] = Application_Model_Preference::GetDefaultFadeOut(); + $data["fadein"] = $defaultFadeIn; + $data["fadeout"] = $defaultFadeOut; $data["type"] = 0; $files[] = $data; @@ -508,12 +512,15 @@ class Application_Model_Scheduler $temp = array(); $instance = null; + /* Items in shows are ordered by position number. We need to know * the position when adding/moving items in linked shows so they are * added or moved in the correct position */ $pos = 0; + $linked = false; + foreach ($scheduleItems as $schedule) { $id = intval($schedule["id"]); @@ -524,10 +531,11 @@ class Application_Model_Scheduler * of inserted items */ if ($id != 0) { - $ccSchedule = CcScheduleQuery::create()->findPk($schedule["id"]); + $ccSchedule = CcScheduleQuery::create()->findPk($id); $ccShowInstance = CcShowInstancesQuery::create()->findPk($ccSchedule->getDbInstanceId()); $ccShow = $ccShowInstance->getCcShow(); - if ($ccShow->isLinked()) { + $linked = $ccShow->isLinked(); + if ($linked) { $unique = $ccShow->getDbId() . $ccSchedule->getDbPosition(); if (!in_array($unique, $temp)) { $temp[] = $unique; @@ -538,7 +546,8 @@ class Application_Model_Scheduler } else { $ccShowInstance = CcShowInstancesQuery::create()->findPk($schedule["instance"]); $ccShow = $ccShowInstance->getccShow(); - if ($ccShow->isLinked()) { + $linked = $ccShow->isLinked(); + if ($linked) { $unique = $ccShow->getDbId() . "a"; if (!in_array($unique, $temp)) { $temp[] = $unique; @@ -552,23 +561,25 @@ class Application_Model_Scheduler * we need to insert the items for each linked instance belonging * to that show */ - $instances = $this->getInstances($schedule["instance"]); - foreach($instances as $instance) { - $linked = $instance->getCcShow()->isLinked(); + if ($linked) { + $instances = $ccShow->getCcShowInstancess(); + } else { + $instances = array($ccShowInstance); + } + foreach($instances as &$instance) { + $instanceId = $instance->getDbId(); if ($id !== 0) { - $schedItem = CcScheduleQuery::create()->findPK($id, $this->con); /* We use the selected cursor's position to find the same * positions in every other linked instance */ - $pos = $schedItem->getDbPosition(); + $pos = $ccSchedule->getDbPosition(); - $ccSchedule = CcScheduleQuery::create() - ->filterByDbInstanceId($instance->getDbId()) + $linkCcSchedule = CcScheduleQuery::create() + ->filterByDbInstanceId($instanceId) ->filterByDbPosition($pos) ->findOne(); - //$schedItemEndDT = $schedItem->getDbEnds(null); - $schedItemEndDT = $ccSchedule->getDbEnds(null); + $schedItemEndDT = $linkCcSchedule->getDbEnds(null); $nextStartDT = $this->findNextStartTime($schedItemEndDT, $instance); $pos++; @@ -583,7 +594,7 @@ class Application_Model_Scheduler } if (!in_array($instance->getDbId(), $affectedShowInstances)) { - $affectedShowInstances[] = $instance->getDbId(); + $affectedShowInstances[] = $instanceId; } /* @@ -604,11 +615,12 @@ class Application_Model_Scheduler if (is_null($filesToInsert)) { $filesToInsert = array(); foreach ($mediaItems as $media) { - $filesToInsert = array_merge($filesToInsert, $this->retrieveMediaFiles($media["id"], $media["type"])); + $filesToInsert = array_merge($filesToInsert, + $this->retrieveMediaFiles($media["id"], $media["type"])); } } - foreach ($filesToInsert as $file) { + foreach ($filesToInsert as &$file) { //item existed previously and is being moved. //need to keep same id for resources if we want REST. if (isset($file['sched_id'])) { @@ -628,7 +640,7 @@ class Application_Model_Scheduler */ if ($linked && $moveAction) { $sched = CcScheduleQuery::create() - ->filterByDbInstanceId($instance->getDbId()) + ->filterByDbInstanceId($instanceId) ->filterByDbPosition($originalPosition) ->findOne(); } @@ -657,9 +669,9 @@ class Application_Model_Scheduler ->setDbFadeOut($file['fadeout']) ->setDbClipLength($file['cliplength']) ->setDbPosition($pos); - //->setDbInstanceId($instance->getDbId()); + if (!$moveAction) { - $sched->setDbInstanceId($instance->getDbId()); + $sched->setDbInstanceId($instanceId); } switch ($file["type"]) { @@ -686,11 +698,17 @@ class Application_Model_Scheduler }//all files have been inserted/moved // update is_scheduled flag for each cc_file - foreach ($filesToInsert as $file) { - $db_file = CcFilesQuery::create()->findPk($file['id'], $this->con); - $db_file->setDbIsScheduled(true); - $db_file->save($this->con); + $fileIds = array(); + foreach ($filesToInsert as &$file) { + $fileIds[] = $file["id"]; } + $selectCriteria = new Criteria(); + $selectCriteria->add(CcFilesPeer::ID, $fileIds, Criteria::IN); + $selectCriteria->addAnd(CcFilesPeer::IS_SCHEDULED, false); + $updateCriteria = new Criteria(); + $updateCriteria->add(CcFilesPeer::IS_SCHEDULED, true); + BasePeer::doUpdate($selectCriteria, $updateCriteria, $this->con); + /* Reset files to insert so we can get a new set of files. We have * to do this in case we are inserting a dynamic block */ diff --git a/airtime_mvc/application/models/ShowBuilder.php b/airtime_mvc/application/models/ShowBuilder.php index cec8895f0..cd6af41e7 100644 --- a/airtime_mvc/application/models/ShowBuilder.php +++ b/airtime_mvc/application/models/ShowBuilder.php @@ -437,15 +437,18 @@ class Application_Model_ShowBuilder $display_items = array(); $shows = array(); + $showInstance = array(); if ($this->opts["myShows"] === 1) { $shows = $this->getUsersShows(); } elseif ($this->opts["showFilter"] !== 0) { $shows[] = $this->opts["showFilter"]; + } elseif ($this->opts["showInstanceFilter"] !== 0) { + $showInstance[] = $this->opts["showInstanceFilter"]; } $scheduled_items = Application_Model_Schedule::GetScheduleDetailItems( - $this->startDT, $this->endDT, $shows); + $this->startDT, $this->endDT, $shows, $showInstance); for ($i = 0, $rows = count($scheduled_items); $i < $rows; $i++) { diff --git a/airtime_mvc/application/services/SchedulerService.php b/airtime_mvc/application/services/SchedulerService.php index c5eb0a504..7cfac160d 100644 --- a/airtime_mvc/application/services/SchedulerService.php +++ b/airtime_mvc/application/services/SchedulerService.php @@ -289,23 +289,53 @@ class Application_Service_SchedulerService $ccShowInstance = CcShowInstancesQuery::create()->findPk($instanceId); $instances = array(); + $instanceIds = array(); if ($ccShowInstance->getCcShow()->isLinked()) { - $instanceIds = array(); foreach ($ccShowInstance->getCcShow()->getCcShowInstancess() as $instance) { $instanceIds[] = $instance->getDbId(); $instances[] = $instance; } - CcScheduleQuery::create() - ->filterByDbInstanceId($instanceIds, Criteria::IN) - ->delete(); } else { + $instanceIds[] = $ccShowInstance->getDbId(); $instances[] = $ccShowInstance; - CcScheduleQuery::create() - ->filterByDbInstanceId($ccShowInstance->getDbId()) - ->delete(); } + /* Get the file ids of the tracks we are about to delete + * from cc_schedule. We need these so we can update the + * is_scheduled flag in cc_files + */ + $ccSchedules = CcScheduleQuery::create() + ->filterByDbInstanceId($instanceIds, Criteria::IN) + ->setDistinct(CcSchedulePeer::FILE_ID) + ->find(); + $fileIds = array(); + foreach ($ccSchedules as $ccSchedule) { + $fileIds[] = $ccSchedule->getDbFileId(); + } + + /* Clear out the schedule */ + CcScheduleQuery::create() + ->filterByDbInstanceId($instanceIds, Criteria::IN) + ->delete(); + + /* Now that the schedule has been cleared we need to make + * sure we do not update the is_scheduled flag for tracks + * that are scheduled in other shows + */ + $futureScheduledFiles = Application_Model_Schedule::getAllFutureScheduledFiles(); + foreach ($fileIds as $k => $v) { + if (in_array($v, $futureScheduledFiles)) { + unset($fileIds[$k]); + } + } + + $selectCriteria = new Criteria(); + $selectCriteria->add(CcFilesPeer::ID, $fileIds, Criteria::IN); + $updateCriteria = new Criteria(); + $updateCriteria->add(CcFilesPeer::IS_SCHEDULED, false); + BasePeer::doUpdate($selectCriteria, $updateCriteria, Propel::getConnection()); + Application_Model_RabbitMq::PushSchedule(); $con = Propel::getConnection(CcShowInstancesPeer::DATABASE_NAME); foreach ($instances as $instance) { diff --git a/airtime_mvc/public/js/airtime/schedule/schedule.js b/airtime_mvc/public/js/airtime/schedule/schedule.js index ac5e2dcc1..82531a726 100644 --- a/airtime_mvc/public/js/airtime/schedule/schedule.js +++ b/airtime_mvc/public/js/airtime/schedule/schedule.js @@ -137,7 +137,7 @@ function findViewportDimensions() { }; } -function buildScheduleDialog (json) { +function buildScheduleDialog (json, instance_id) { var dialog = $(json.dialog), viewport = findViewportDimensions(), height = Math.floor(viewport.height * 0.96), @@ -179,6 +179,10 @@ function buildScheduleDialog (json) { //set the start end times so the builder datatables knows its time range. fnServer.start = json.start; fnServer.end = json.end; + fnServer.ops = {}; + fnServer.ops.showFilter = 0; + fnServer.ops.showInstanceFilter = instance_id; + fnServer.ops.myShows = 0; AIRTIME.library.libraryInit(); AIRTIME.showbuilder.builderDataTable(); @@ -352,7 +356,7 @@ $(document).ready(function() { callback = function() { $.post(oItems.schedule.url, {format: "json", id: data.id}, function(json){ - buildScheduleDialog(json); + buildScheduleDialog(json, data.id); }); }; diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index 65826d643..30076dd67 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -359,6 +359,7 @@ var AIRTIME = (function(AIRTIME){ if (mod.fnServerData.hasOwnProperty("ops")) { aoData.push( { name: "myShows", value: mod.fnServerData.ops.myShows} ); aoData.push( { name: "showFilter", value: mod.fnServerData.ops.showFilter} ); + aoData.push( { name: "showInstanceFilter", value: mod.fnServerData.ops.showInstanceFilter} ); } $.ajax({ diff --git a/airtime_mvc/public/js/airtime/showbuilder/main_builder.js b/airtime_mvc/public/js/airtime/showbuilder/main_builder.js index ee19e85fd..38c3ef05a 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/main_builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/main_builder.js @@ -266,6 +266,7 @@ AIRTIME = (function(AIRTIME) { if (fn.hasOwnProperty("ops")) { data["myShows"] = fn.ops.myShows; data["showFilter"] = fn.ops.showFilter; + data["showFilter"] = fn.ops.showInstanceFilter; } $.ajax( { diff --git a/gen-snapshot.sh b/gen-snapshot.sh index 682069e34..41e38cd22 100755 --- a/gen-snapshot.sh +++ b/gen-snapshot.sh @@ -2,7 +2,7 @@ # Script for generating nightly Airtime snapshot packages # Run from the directory containg the files checked out from git -VERSION=2.3.0~$(date "+%Y%m%d") +VERSION=2.4.0~$(date "+%Y%m%d") BUILDDEST=/tmp/airtime-${VERSION}/ DEBDIR=`pwd`/debian @@ -23,7 +23,7 @@ cd ${BUILDDEST} || exit # Set the version of the snapshot package -sed -i "1s:(2.3.0-1):(${VERSION}):g" debian/changelog +sed -i "1s:(2.4.0-1):(${VERSION}):g" debian/changelog # FIXES for 2.3.0 ############# diff --git a/python_apps/media-monitor2/media/monitor/metadata.py b/python_apps/media-monitor2/media/monitor/metadata.py index 09cec0750..bf5eb7333 100644 --- a/python_apps/media-monitor2/media/monitor/metadata.py +++ b/python_apps/media-monitor2/media/monitor/metadata.py @@ -49,6 +49,8 @@ airtime2mutagen = { "MDATA_KEY_CUE_OUT" : "cueout", } +#doesn't make sense for us to write these values to a track's metadata +mutagen_do_not_write = ["MDATA_KEY_CUE_IN", "MDATA_KEY_CUE_OUT"] # Some airtime attributes are special because they must use the mutagen object # itself to calculate the value that they need. The lambda associated with each @@ -113,7 +115,8 @@ class Metadata(Loggable): song_file = mutagen.File(path, easy=True) exceptions = [] # for bad keys for airtime_k, airtime_v in md.iteritems(): - if airtime_k in airtime2mutagen: + if airtime_k in airtime2mutagen and \ + airtime_k not in mutagen_do_not_write: # The unicode cast here is mostly for integers that need to be # strings if airtime_v is None: continue diff --git a/python_apps/pypo/airtime-liquidsoap b/python_apps/pypo/airtime-liquidsoap index 0812bd47d..def0aaae1 100755 --- a/python_apps/pypo/airtime-liquidsoap +++ b/python_apps/pypo/airtime-liquidsoap @@ -1,11 +1,38 @@ #!/bin/bash -e +debug="f" + +showhelp () { + echo "Usage: airtime-liquidsoap [options] +--help|-h Displays usage information. +--debug|-d Print error messages to console" +} + +set -- $(getopt -l help,debug "hd" "$@") +while [ $# -gt 0 ] +do + case "$1" in + (-h|--help) showhelp; exit 0;; + (-d|--debug) debug="t";; + + (--) shift; break;; + (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;; + (*) break;; + esac + shift +done + + virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/" . ${virtualenv_bin}activate export HOME="/var/tmp/airtime/pypo/" api_client_path="/usr/lib/airtime/" -ls_path="/usr/bin/airtime-liquidsoap --verbose -f -d" +if [ $debug = "t" ]; then + ls_path="/usr/bin/airtime-liquidsoap --verbose -f" +else + ls_path="/usr/bin/airtime-liquidsoap --verbose -f -d" +fi ls_param="/usr/lib/airtime/pypo/bin/liquidsoap_scripts/ls_script.liq" export PYTHONPATH=${api_client_path}