diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php index d6032eae6..a73fbd149 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -30,7 +30,7 @@ AND file_id is not null SQL; $files = Application_Common_Database::prepareAndExecute( $sql, array()); - + $real_files = array(); foreach ($files as $f) { $real_files[] = $f['file_id']; @@ -48,7 +48,7 @@ WHERE ends > now() AT TIME ZONE 'UTC' AND stream_id is not null SQL; $streams = Application_Common_Database::prepareAndExecute( $sql, array()); - + $real_streams = array(); foreach ($streams as $s) { $real_streams[] = $s['stream_id']; @@ -322,7 +322,8 @@ SQL; ft.album_title AS file_album_title, ft.length AS file_length, ft.file_exists AS file_exists, - ft.mime AS file_mime + ft.mime AS file_mime, + ft.soundcloud_id AS soundcloud_id SQL; $filesJoin = << 0) { - + $params = array(); $map = array(); - + for ($i = 0, $len = count($p_shows); $i < $len; $i++) { $holder = "show_".$i; - + $params[] = $holder; $map[$holder] = $p_shows[$i]; } - + $showPredicate = " AND show_id IN (".implode(",", $params).")"; $paramMap = $paramMap + $map; } else if (count($p_show_instances) > 0) { @@ -448,13 +450,13 @@ SQL; ":ts_6" => $p_end_str, ); $paramMap = $paramMap + $map; - + $rows = Application_Common_Database::prepareAndExecute( $sql, $paramMap, Application_Common_Database::ALL ); - + return $rows; } @@ -475,7 +477,7 @@ SQL; $sql .= " WHERE id=:pid"; $map = array(":pid" => $p_id); - Application_Common_Database::prepareAndExecute($sql, $map, + Application_Common_Database::prepareAndExecute($sql, $map, Application_Common_Database::EXECUTE); } @@ -501,9 +503,9 @@ SQL; { $sql = "SELECT count(*) as cnt FROM cc_schedule"; - $res = Application_Common_Database::prepareAndExecute($sql, array(), + $res = Application_Common_Database::prepareAndExecute($sql, array(), Application_Common_Database::COLUMN); - + return $res; } @@ -706,7 +708,7 @@ SQL; $key = "{$time}_{$i}"; $i++; } - + $data["media"][$key] = $item; } @@ -755,7 +757,7 @@ SQL; $replay_gain = is_null($item["replay_gain"]) ? "0": $item["replay_gain"]; $replay_gain += Application_Model_Preference::getReplayGainModifier(); - + if ( !Application_Model_Preference::GetEnableReplayGain() ) { $replay_gain = 0; } @@ -775,7 +777,7 @@ SQL; 'replay_gain' => $replay_gain, 'independent_event' => $independent_event, ); - + if ($schedule_item['cue_in'] > $schedule_item['cue_out']) { $schedule_item['cue_in'] = $schedule_item['cue_out']; } @@ -915,10 +917,10 @@ SQL; } else { throw new Exception("Unknown schedule type: ".print_r($item, true)); } - + } } - + /* Check if two events are less than or equal to 1 second apart */ public static function areEventsLinked($event1, $event2) { @@ -996,7 +998,7 @@ SQL; public static function deleteAll() { $sql = "TRUNCATE TABLE cc_schedule"; - Application_Common_Database::prepareAndExecute($sql, array(), + Application_Common_Database::prepareAndExecute($sql, array(), Application_Common_Database::EXECUTE); } @@ -1279,14 +1281,14 @@ SQL; $update=false, $instanceId=null, $showId=null) { $overlapping = false; - + $params = array( ':show_end1' => $show_end->format('Y-m-d H:i:s'), ':show_end2' => $show_end->format('Y-m-d H:i:s'), ':show_end3' => $show_end->format('Y-m-d H:i:s') ); - - + + /* If a show is being edited, exclude it from the query * In both cases (new and edit) we only grab shows that * are scheduled 2 days prior @@ -1357,18 +1359,18 @@ SQL; return 'file'; } } - + public static function GetFileId($p_scheduleId) { $scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId); return $scheduledItem->getDbFileId(); } - + public static function GetStreamId($p_scheduleId) { $scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId); - + return $scheduledItem->getDbStreamId(); } } diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index 98f06b16a..b8f84b26d 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -150,7 +150,7 @@ class Application_Model_StoredFile } } $dbMd[constant($mdConst)] = $mdValue; - + } } $this->setDbColMetadata($dbMd); @@ -214,7 +214,7 @@ class Application_Model_StoredFile if (isset($this->_dbMD[$dbColumn])) { $propelColumn = $this->_dbMD[$dbColumn]; $method = "set$propelColumn"; - + /* We need to set track_number to null if it is an empty string * because propel defaults empty strings to zeros */ if ($dbColumn == "track_number" && empty($mdValue)) $mdValue = null; @@ -330,7 +330,7 @@ SQL; $stmt = $con->prepare($sql); $stmt->bindParam(':file_id', $this->id, PDO::PARAM_INT); - + if ($stmt->execute()) { $ids = $stmt->fetchAll(); } else { @@ -386,7 +386,7 @@ SQL; // set hidden flag to true $this->_file->setDbHidden(true); $this->_file->save(); - + // need to explicitly update any playlist's and block's length // that contains the file getting deleted $fileId = $this->_file->getDbId(); @@ -396,7 +396,7 @@ SQL; $pl->setDbLength($pl->computeDbLength(Propel::getConnection(CcPlaylistPeer::DATABASE_NAME))); $pl->save(); } - + $blRows = CcBlockcontentsQuery::create()->filterByDbFileId($fileId)->find(); foreach ($blRows as $row) { $bl = CcBlockQuery::create()->filterByDbId($row->getDbBlockId())->findOne(); @@ -506,19 +506,19 @@ SQL; public function getFileUrl() { $CC_CONFIG = Config::getConfig(); - + $protocol = empty($_SERVER['HTTPS']) ? "http" : "https"; - + $serverName = $_SERVER['SERVER_NAME']; $serverPort = $_SERVER['SERVER_PORT']; $subDir = $CC_CONFIG['baseDir']; - + if ($subDir[0] === "/") { $subDir = substr($subDir, 1, strlen($subDir) - 1); } - + $baseUrl = "{$protocol}://{$serverName}:{$serverPort}/{$subDir}"; - + return $this->getRelativeFileUrl($baseUrl); } @@ -641,7 +641,7 @@ SQL; public static function searchLibraryFiles($datatables) { $baseUrl = Application_Common_OsPath::getBaseDir(); - + $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME); $displayColumns = self::getLibraryColumns(); @@ -796,7 +796,7 @@ SQL; //soundcloud status $file = Application_Model_StoredFile::RecallById($row['id']); - $row['soundcloud_status'] = $file->getSoundCloudId(); + $row['soundcloud_id'] = $file->getSoundCloudId(); // for audio preview $row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION); @@ -1028,7 +1028,7 @@ SQL; $LIQUIDSOAP_ERRORS = array('TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.'); // Ask Liquidsoap if file is playable - $ls_command = sprintf('/usr/bin/airtime-liquidsoap -v -c "output.dummy(audio_to_stereo(single(%s)))" 2>&1', + $ls_command = sprintf('/usr/bin/airtime-liquidsoap -v -c "output.dummy(audio_to_stereo(single(%s)))" 2>&1', escapeshellarg($audio_file)); $command = "export PATH=/usr/local/bin:/usr/bin:/bin/usr/bin/ && $ls_command"; @@ -1068,14 +1068,14 @@ SQL; $stmt = $con->prepare($sql); $stmt->bindParam(':dir_id', $dir_id); - + if ($stmt->execute()) { $rows = $stmt->fetchAll(); } else { $msg = implode(',', $stmt->errorInfo()); throw new Exception("Error: $msg"); } - + $results = array(); foreach ($rows as $row) { $results[] = $row["fp"]; @@ -1111,10 +1111,10 @@ SQL; return $rows; } - + public static function getAllFilesWithoutSilan() { $con = Propel::getConnection(); - + $sql = <<prepare($sql); - + if ($stmt->execute()) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); } else { $msg = implode(',', $stmt->errorInfo()); throw new Exception("Error: $msg"); } - + return $rows; } @@ -1227,7 +1227,7 @@ SQL; ->save(); } - + // This method seems to be unsued everywhere so I've commented it out // If it's absence does not have any effect then it will be completely // removed soon @@ -1284,7 +1284,7 @@ SQL; } } } - + public static function setIsPlaylist($p_playlistItems, $p_type, $p_status) { foreach ($p_playlistItems as $item) { $file = self::RecallById($item->getDbFileId()); @@ -1302,7 +1302,7 @@ SQL; } } } - + public static function setIsScheduled($p_scheduleItem, $p_status, $p_fileId=null) { diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index 7fdbe041e..e59d16751 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -593,12 +593,12 @@ var AIRTIME = (function(AIRTIME) { "fnRowCallback": AIRTIME.library.fnRowCallback, "fnCreatedRow": function( nRow, aData, iDataIndex ) { //add soundcloud icon - if (aData.soundcloud_status !== undefined) { - if (aData.soundcloud_status === "-2") { + if (aData.soundcloud_id !== undefined) { + if (aData.soundcloud_id === "-2") { $(nRow).find("td.library_title").append(''); - } else if (aData.soundcloud_status === "-3") { + } else if (aData.soundcloud_id === "-3") { $(nRow).find("td.library_title").append(''); - } else if (aData.soundcloud_status !== null) { + } else if (aData.soundcloud_id !== null) { $(nRow).find("td.library_title").append(''); } } @@ -1140,10 +1140,13 @@ function checkLibrarySCUploadStatus(){ setTimeout(checkLibrarySCUploadStatus, 5000); } -function addQtipToSCIcons(){ - $(".progress, .soundcloud, .sc-error").live('mouseover', function(){ +function addQtipToSCIcons() { + $("#content") + .on('mouseover', ".progress, .soundcloud, .sc-error", function() { - var id = $(this).parent().parent().data("aData").id; + var aData = $(this).parents("tr").data("aData"), + id = aData.id, + sc_id = aData.soundcloud_id; if ($(this).hasClass("progress")){ $(this).qtip({ @@ -1163,24 +1166,15 @@ function addQtipToSCIcons(){ classes: "ui-tooltip-dark file-md-long" }, show: { - ready: true // Needed to make it show on first mouseover - // event + ready: true // Needed to make it show on first mouseover event } }); } - else if($(this).hasClass("soundcloud")){ - var sc_id = $(this).parent().parent().data("aData").soundcloud_id; + else if ($(this).hasClass("soundcloud")){ + $(this).qtip({ content: { - text: $.i18n._("Retrieving data from the server..."), - ajax: { - url: baseUrl+"Library/get-upload-to-soundcloud-status", - type: "post", - data: ({format: "json", id : id, type: "file"}), - success: function(json, status){ - this.set('content.text', $.i18n._("The soundcloud id for this file is: ")+json.sc_id); - } - } + text: $.i18n._("The soundcloud id for this file is: ") + sc_id }, position:{ adjust: { @@ -1195,11 +1189,11 @@ function addQtipToSCIcons(){ classes: "ui-tooltip-dark file-md-long" }, show: { - ready: true // Needed to make it show on first mouseover - // event + ready: true // Needed to make it show on first mouseover event } }); - }else if($(this).hasClass("sc-error")){ + } + else if ($(this).hasClass("sc-error")) { $(this).qtip({ content: { text: $.i18n._("Retreiving data from the server..."), @@ -1227,8 +1221,7 @@ function addQtipToSCIcons(){ classes: "ui-tooltip-dark file-md-long" }, show: { - ready: true // Needed to make it show on first mouseover - // event + ready: true // Needed to make it show on first mouseover event } }); } diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index 28de74cf9..af5a3a80d 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -546,7 +546,7 @@ var AIRTIME = (function(AIRTIME){ cl = 'sb-footer'; //check the show's content status. - if (aData.runtime > 0) { + if (aData.runtime >= 0) { $node.html(''); cl = cl + ' ui-state-highlight'; } diff --git a/python_apps/pypo/airtime-liquidsoap-init-d b/python_apps/pypo/airtime-liquidsoap-init-d index 2fc791ffa..0d4d827bf 100755 --- a/python_apps/pypo/airtime-liquidsoap-init-d +++ b/python_apps/pypo/airtime-liquidsoap-init-d @@ -18,7 +18,6 @@ PIDFILE=/var/run/airtime-liquidsoap.pid EXEC='/usr/bin/airtime-liquidsoap' start () { - mkdir -p /var/log/airtime/pypo-liquidsoap chown $USERID:$GROUPID /var/log/airtime/pypo-liquidsoap @@ -37,8 +36,17 @@ start () { stop () { #send term signal after 10 seconds - timeout -s9 10s /usr/lib/airtime/airtime_virtualenv/bin/python \ - /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py + timeout --version + $RESULT="$?" + if [ "$RESULT" = "0" ]; then + timeout -s9 10s /usr/lib/airtime/airtime_virtualenv/bin/python \ + /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py + else + #some earlier versions of Ubuntu (Lucid) had a different timeout + #command that takes different input parameters. + timeout 10 /usr/lib/airtime/airtime_virtualenv/bin/python \ + /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py + fi # Send TERM after 5 seconds, wait at most 30 seconds. #start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --pidfile $PIDFILE start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --exec $EXEC diff --git a/python_apps/pypo/monit-airtime-liquidsoap.cfg b/python_apps/pypo/monit-airtime-liquidsoap.cfg index 8688251ea..ac5031c27 100644 --- a/python_apps/pypo/monit-airtime-liquidsoap.cfg +++ b/python_apps/pypo/monit-airtime-liquidsoap.cfg @@ -4,6 +4,8 @@ set httpd port 2812 check process airtime-liquidsoap matching "airtime-liquidsoap.*airtime.*ls_script" + if does not exist for 3 cycles then restart + start program = "/etc/init.d/airtime-liquidsoap start" with timeout 30 seconds stop program = "/etc/init.d/airtime-liquidsoap stop" diff --git a/python_apps/pypo/monit-pre530-airtime-liquidsoap.cfg b/python_apps/pypo/monit-pre530-airtime-liquidsoap.cfg index 972edd46f..40c0b8338 100644 --- a/python_apps/pypo/monit-pre530-airtime-liquidsoap.cfg +++ b/python_apps/pypo/monit-pre530-airtime-liquidsoap.cfg @@ -5,5 +5,5 @@ check process airtime-liquidsoap with pidfile "/var/run/airtime-liquidsoap.pid" - start program = "/etc/init.d/airtime-liquidsoap start" with timeout 5 seconds - stop program = "/etc/init.d/airtime-liquidsoap stop" + start program = "/etc/init.d/airtime-liquidsoap start-with-monit" with timeout 5 seconds + stop program = "/etc/init.d/airtime-liquidsoap stop-with-monit"