Merge branch '2.4.x'
Conflicts: python_apps/pypo/pypopush.py python_apps/pypo/schedule/pypofetch.py python_apps/pypo/schedule/pypofile.py python_apps/pypo/schedule/pypoliqqueue.py
This commit is contained in:
commit
586bdf99e9
71 changed files with 5253 additions and 4614 deletions
|
@ -24,7 +24,7 @@ class ErrorController extends Zend_Controller_Action
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log exception, if logger available
|
// Log exception, if logger available
|
||||||
if ($log = $this->getLog()) {
|
if (($log = $this->getLog())) {
|
||||||
$log->crit($this->view->message, $errors->exception);
|
$log->crit($this->view->message, $errors->exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ class LocaleController extends Zend_Controller_Action
|
||||||
"Are you sure you want to remove the watched folder?" => _("Are you sure you want to remove the watched folder?"),
|
"Are you sure you want to remove the watched folder?" => _("Are you sure you want to remove the watched folder?"),
|
||||||
"This path is currently not accessible." => _("This path is currently not accessible."),
|
"This path is currently not accessible." => _("This path is currently not accessible."),
|
||||||
//preferences/streamsetting.js
|
//preferences/streamsetting.js
|
||||||
"Some steam types require extra configuration. Details about enabling %sAAC+ Support%s or %sOpus Support%s are provided." => _("Some steam types require extra configuration. Details about enabling %sAAC+ Support%s or %sOpus Support%s are provided."),
|
"Some stream types require extra configuration. Details about enabling %sAAC+ Support%s or %sOpus Support%s are provided." => _("Some stream types require extra configuration. Details about enabling %sAAC+ Support%s or %sOpus Support%s are provided."),
|
||||||
"Connected to the streaming server" => _("Connected to the streaming server"),
|
"Connected to the streaming server" => _("Connected to the streaming server"),
|
||||||
"The stream is disabled" => _("The stream is disabled"),
|
"The stream is disabled" => _("The stream is disabled"),
|
||||||
"Getting information from the server..." => _("Getting information from the server..."),
|
"Getting information from the server..." => _("Getting information from the server..."),
|
||||||
|
@ -193,6 +193,7 @@ class LocaleController extends Zend_Controller_Action
|
||||||
"If your live streaming client does not ask for a username, this field should be 'source'." => _("If your live streaming client does not ask for a username, this field should be 'source'."),
|
"If your live streaming client does not ask for a username, this field should be 'source'." => _("If your live streaming client does not ask for a username, this field should be 'source'."),
|
||||||
"The show instance doesn't exist anymore!" => _("The show instance doesn't exist anymore!"),
|
"The show instance doesn't exist anymore!" => _("The show instance doesn't exist anymore!"),
|
||||||
"Warning: Shows cannot be re-linked" => _("Warning: Shows cannot be re-linked"),
|
"Warning: Shows cannot be re-linked" => _("Warning: Shows cannot be re-linked"),
|
||||||
|
"By linking your repeating shows any media items scheduled in any repeat show will also get scheduled in the other repeat shows" => _("By linking your repeating shows any media items scheduled in any repeat show will also get scheduled in the other repeat shows"),
|
||||||
//schedule/full-calendar-functions
|
//schedule/full-calendar-functions
|
||||||
//already in schedule/add-show.js
|
//already in schedule/add-show.js
|
||||||
//"The show instance doesn't exist anymore!" => _("The show instance doesn't exist anymore!"),
|
//"The show instance doesn't exist anymore!" => _("The show instance doesn't exist anymore!"),
|
||||||
|
|
|
@ -32,6 +32,7 @@ class PreferenceController extends Zend_Controller_Action
|
||||||
$this->view->statusMsg = "";
|
$this->view->statusMsg = "";
|
||||||
|
|
||||||
$form = new Application_Form_Preferences();
|
$form = new Application_Form_Preferences();
|
||||||
|
$values = array();
|
||||||
|
|
||||||
if ($request->isPost()) {
|
if ($request->isPost()) {
|
||||||
$params = $request->getPost();
|
$params = $request->getPost();
|
||||||
|
@ -223,6 +224,7 @@ class PreferenceController extends Zend_Controller_Action
|
||||||
$s1_data = array();
|
$s1_data = array();
|
||||||
$s2_data = array();
|
$s2_data = array();
|
||||||
$s3_data = array();
|
$s3_data = array();
|
||||||
|
$values = array();
|
||||||
foreach($postData as $k=>$v) {
|
foreach($postData as $k=>$v) {
|
||||||
$v = explode('=', urldecode($v));
|
$v = explode('=', urldecode($v));
|
||||||
if (strpos($v[0], "s1_data") !== false) {
|
if (strpos($v[0], "s1_data") !== false) {
|
||||||
|
|
|
@ -600,6 +600,7 @@ class ScheduleController extends Zend_Controller_Action
|
||||||
|
|
||||||
$baseUrl = $this->getRequest()->getBaseUrl();
|
$baseUrl = $this->getRequest()->getBaseUrl();
|
||||||
$url = $file->getRelativeFileUrl($baseUrl).'download/true';
|
$url = $file->getRelativeFileUrl($baseUrl).'download/true';
|
||||||
|
$menu = array();
|
||||||
$menu[] = array('action' => array('type' => 'gourl', 'url' => $url),
|
$menu[] = array('action' => array('type' => 'gourl', 'url' => $url),
|
||||||
'title' => _('Download'));
|
'title' => _('Download'));
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ class UserController extends Zend_Controller_Action
|
||||||
if ($request->isPost()) {
|
if ($request->isPost()) {
|
||||||
$params = $request->getPost();
|
$params = $request->getPost();
|
||||||
$postData = explode('&', $params['data']);
|
$postData = explode('&', $params['data']);
|
||||||
|
$formData = array();
|
||||||
foreach($postData as $k=>$v) {
|
foreach($postData as $k=>$v) {
|
||||||
$v = explode('=', $v);
|
$v = explode('=', $v);
|
||||||
$formData[$v[0]] = urldecode($v[1]);
|
$formData[$v[0]] = urldecode($v[1]);
|
||||||
|
|
|
@ -330,7 +330,7 @@ SQL;
|
||||||
{
|
{
|
||||||
list($value, $modifier) = $this->getLimitValueAndModifier();
|
list($value, $modifier) = $this->getLimitValueAndModifier();
|
||||||
if ($modifier == "items") {
|
if ($modifier == "items") {
|
||||||
$length = $value." ".$modifier;
|
$length = $value." "._("items");
|
||||||
} else {
|
} else {
|
||||||
$hour = "00";
|
$hour = "00";
|
||||||
$mins = "00";
|
$mins = "00";
|
||||||
|
@ -1354,6 +1354,16 @@ SQL;
|
||||||
"year" => _("Year")
|
"year" => _("Year")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$modifierOptions = array(
|
||||||
|
"0" => _("Select modifier"),
|
||||||
|
"contains" => _("contains"),
|
||||||
|
"does not contain" => _("does not contain"),
|
||||||
|
"is" => _("is"),
|
||||||
|
"is not" => _("is not"),
|
||||||
|
"starts with" => _("starts with"),
|
||||||
|
"ends with" => _("ends with")
|
||||||
|
);
|
||||||
|
|
||||||
// Load criteria from db
|
// Load criteria from db
|
||||||
$out = CcBlockcriteriaQuery::create()->orderByDbCriteria()->findByDbBlockId($this->id);
|
$out = CcBlockcriteriaQuery::create()->orderByDbCriteria()->findByDbBlockId($this->id);
|
||||||
$storedCrit = array();
|
$storedCrit = array();
|
||||||
|
@ -1365,11 +1375,17 @@ SQL;
|
||||||
$extra = $crit->getDbExtra();
|
$extra = $crit->getDbExtra();
|
||||||
|
|
||||||
if ($criteria == "limit") {
|
if ($criteria == "limit") {
|
||||||
$storedCrit["limit"] = array("value"=>$value, "modifier"=>$modifier);
|
$storedCrit["limit"] = array("value"=>$value, "modifier"=>_($modifier));
|
||||||
} else if($criteria == "repeat_tracks") {
|
} else if($criteria == "repeat_tracks") {
|
||||||
$storedCrit["repeat_tracks"] = array("value"=>$value);
|
$storedCrit["repeat_tracks"] = array("value"=>$value);
|
||||||
} else {
|
} else {
|
||||||
$storedCrit["crit"][$criteria][] = array("criteria"=>$criteria, "value"=>$value, "modifier"=>$modifier, "extra"=>$extra, "display_name"=>$criteriaOptions[$criteria]);
|
$storedCrit["crit"][$criteria][] = array(
|
||||||
|
"criteria"=>$criteria,
|
||||||
|
"value"=>$value,
|
||||||
|
"modifier"=>$modifier,
|
||||||
|
"extra"=>$extra,
|
||||||
|
"display_name"=>$criteriaOptions[$criteria],
|
||||||
|
"display_modifier"=>$modifierOptions[$modifier]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ class Application_Model_Datatables
|
||||||
{
|
{
|
||||||
private static function buildWhereClauseForAdvancedSearch($dbname2searchTerm)
|
private static function buildWhereClauseForAdvancedSearch($dbname2searchTerm)
|
||||||
{
|
{
|
||||||
|
$where = array();
|
||||||
$where['clause'] = array();
|
$where['clause'] = array();
|
||||||
$where['params'] = array();
|
$where['params'] = array();
|
||||||
foreach ($dbname2searchTerm as $dbname=>$term) {
|
foreach ($dbname2searchTerm as $dbname=>$term) {
|
||||||
|
|
|
@ -1075,8 +1075,7 @@ SQL;
|
||||||
$sql .= "END WHERE position IN ($currentPos) and playlist_id=:p1";
|
$sql .= "END WHERE position IN ($currentPos) and playlist_id=:p1";
|
||||||
|
|
||||||
Application_Common_Database::prepareAndExecute($sql, array("p1"=>$this->id));
|
Application_Common_Database::prepareAndExecute($sql, array("p1"=>$this->id));
|
||||||
$result['result'] = 0;
|
return array('result' => 0);
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getAllPlaylistFiles()
|
public static function getAllPlaylistFiles()
|
||||||
|
|
|
@ -38,6 +38,8 @@ class Application_Model_Preference
|
||||||
$paramMap[':id'] = $userId;
|
$paramMap[':id'] = $userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Application_Common_Database::prepareAndExecute("LOCK TABLE cc_pref");
|
||||||
|
|
||||||
$result = Application_Common_Database::prepareAndExecute($sql,
|
$result = Application_Common_Database::prepareAndExecute($sql,
|
||||||
$paramMap,
|
$paramMap,
|
||||||
Application_Common_Database::COLUMN,
|
Application_Common_Database::COLUMN,
|
||||||
|
|
|
@ -30,7 +30,7 @@ AND file_id is not null
|
||||||
SQL;
|
SQL;
|
||||||
|
|
||||||
$files = Application_Common_Database::prepareAndExecute( $sql, array());
|
$files = Application_Common_Database::prepareAndExecute( $sql, array());
|
||||||
|
|
||||||
$real_files = array();
|
$real_files = array();
|
||||||
foreach ($files as $f) {
|
foreach ($files as $f) {
|
||||||
$real_files[] = $f['file_id'];
|
$real_files[] = $f['file_id'];
|
||||||
|
@ -48,7 +48,7 @@ WHERE ends > now() AT TIME ZONE 'UTC'
|
||||||
AND stream_id is not null
|
AND stream_id is not null
|
||||||
SQL;
|
SQL;
|
||||||
$streams = Application_Common_Database::prepareAndExecute( $sql, array());
|
$streams = Application_Common_Database::prepareAndExecute( $sql, array());
|
||||||
|
|
||||||
$real_streams = array();
|
$real_streams = array();
|
||||||
foreach ($streams as $s) {
|
foreach ($streams as $s) {
|
||||||
$real_streams[] = $s['stream_id'];
|
$real_streams[] = $s['stream_id'];
|
||||||
|
@ -322,7 +322,8 @@ SQL;
|
||||||
ft.album_title AS file_album_title,
|
ft.album_title AS file_album_title,
|
||||||
ft.length AS file_length,
|
ft.length AS file_length,
|
||||||
ft.file_exists AS file_exists,
|
ft.file_exists AS file_exists,
|
||||||
ft.mime AS file_mime
|
ft.mime AS file_mime,
|
||||||
|
ft.soundcloud_id AS soundcloud_id
|
||||||
SQL;
|
SQL;
|
||||||
$filesJoin = <<<SQL
|
$filesJoin = <<<SQL
|
||||||
cc_schedule AS sched
|
cc_schedule AS sched
|
||||||
|
@ -357,7 +358,8 @@ SQL;
|
||||||
ws.description AS file_album_title,
|
ws.description AS file_album_title,
|
||||||
ws.length AS file_length,
|
ws.length AS file_length,
|
||||||
't'::BOOL AS file_exists,
|
't'::BOOL AS file_exists,
|
||||||
ws.mime as file_mime
|
ws.mime AS file_mime,
|
||||||
|
(SELECT NULL::integer AS soundcloud_id)
|
||||||
SQL;
|
SQL;
|
||||||
$streamJoin = <<<SQL
|
$streamJoin = <<<SQL
|
||||||
cc_schedule AS sched
|
cc_schedule AS sched
|
||||||
|
@ -391,17 +393,17 @@ SQL;
|
||||||
|
|
||||||
$showPredicate = "";
|
$showPredicate = "";
|
||||||
if (count($p_shows) > 0) {
|
if (count($p_shows) > 0) {
|
||||||
|
|
||||||
$params = array();
|
$params = array();
|
||||||
$map = array();
|
$map = array();
|
||||||
|
|
||||||
for ($i = 0, $len = count($p_shows); $i < $len; $i++) {
|
for ($i = 0, $len = count($p_shows); $i < $len; $i++) {
|
||||||
$holder = "show_".$i;
|
$holder = ":show_".$i;
|
||||||
|
|
||||||
$params[] = $holder;
|
$params[] = $holder;
|
||||||
$map[$holder] = $p_shows[$i];
|
$map[$holder] = $p_shows[$i];
|
||||||
}
|
}
|
||||||
|
|
||||||
$showPredicate = " AND show_id IN (".implode(",", $params).")";
|
$showPredicate = " AND show_id IN (".implode(",", $params).")";
|
||||||
$paramMap = $paramMap + $map;
|
$paramMap = $paramMap + $map;
|
||||||
} else if (count($p_show_instances) > 0) {
|
} else if (count($p_show_instances) > 0) {
|
||||||
|
@ -448,13 +450,13 @@ SQL;
|
||||||
":ts_6" => $p_end_str,
|
":ts_6" => $p_end_str,
|
||||||
);
|
);
|
||||||
$paramMap = $paramMap + $map;
|
$paramMap = $paramMap + $map;
|
||||||
|
|
||||||
$rows = Application_Common_Database::prepareAndExecute(
|
$rows = Application_Common_Database::prepareAndExecute(
|
||||||
$sql,
|
$sql,
|
||||||
$paramMap,
|
$paramMap,
|
||||||
Application_Common_Database::ALL
|
Application_Common_Database::ALL
|
||||||
);
|
);
|
||||||
|
|
||||||
return $rows;
|
return $rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,7 +477,7 @@ SQL;
|
||||||
$sql .= " WHERE id=:pid";
|
$sql .= " WHERE id=:pid";
|
||||||
$map = array(":pid" => $p_id);
|
$map = array(":pid" => $p_id);
|
||||||
|
|
||||||
Application_Common_Database::prepareAndExecute($sql, $map,
|
Application_Common_Database::prepareAndExecute($sql, $map,
|
||||||
Application_Common_Database::EXECUTE);
|
Application_Common_Database::EXECUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,9 +503,9 @@ SQL;
|
||||||
{
|
{
|
||||||
$sql = "SELECT count(*) as cnt FROM cc_schedule";
|
$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);
|
Application_Common_Database::COLUMN);
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,7 +708,7 @@ SQL;
|
||||||
$key = "{$time}_{$i}";
|
$key = "{$time}_{$i}";
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data["media"][$key] = $item;
|
$data["media"][$key] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,7 +757,7 @@ SQL;
|
||||||
|
|
||||||
$replay_gain = is_null($item["replay_gain"]) ? "0": $item["replay_gain"];
|
$replay_gain = is_null($item["replay_gain"]) ? "0": $item["replay_gain"];
|
||||||
$replay_gain += Application_Model_Preference::getReplayGainModifier();
|
$replay_gain += Application_Model_Preference::getReplayGainModifier();
|
||||||
|
|
||||||
if ( !Application_Model_Preference::GetEnableReplayGain() ) {
|
if ( !Application_Model_Preference::GetEnableReplayGain() ) {
|
||||||
$replay_gain = 0;
|
$replay_gain = 0;
|
||||||
}
|
}
|
||||||
|
@ -775,7 +777,7 @@ SQL;
|
||||||
'replay_gain' => $replay_gain,
|
'replay_gain' => $replay_gain,
|
||||||
'independent_event' => $independent_event,
|
'independent_event' => $independent_event,
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($schedule_item['cue_in'] > $schedule_item['cue_out']) {
|
if ($schedule_item['cue_in'] > $schedule_item['cue_out']) {
|
||||||
$schedule_item['cue_in'] = $schedule_item['cue_out'];
|
$schedule_item['cue_in'] = $schedule_item['cue_out'];
|
||||||
}
|
}
|
||||||
|
@ -915,10 +917,10 @@ SQL;
|
||||||
} else {
|
} else {
|
||||||
throw new Exception("Unknown schedule type: ".print_r($item, true));
|
throw new Exception("Unknown schedule type: ".print_r($item, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if two events are less than or equal to 1 second apart
|
/* Check if two events are less than or equal to 1 second apart
|
||||||
*/
|
*/
|
||||||
public static function areEventsLinked($event1, $event2) {
|
public static function areEventsLinked($event1, $event2) {
|
||||||
|
@ -996,7 +998,7 @@ SQL;
|
||||||
public static function deleteAll()
|
public static function deleteAll()
|
||||||
{
|
{
|
||||||
$sql = "TRUNCATE TABLE cc_schedule";
|
$sql = "TRUNCATE TABLE cc_schedule";
|
||||||
Application_Common_Database::prepareAndExecute($sql, array(),
|
Application_Common_Database::prepareAndExecute($sql, array(),
|
||||||
Application_Common_Database::EXECUTE);
|
Application_Common_Database::EXECUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1279,14 +1281,14 @@ SQL;
|
||||||
$update=false, $instanceId=null, $showId=null)
|
$update=false, $instanceId=null, $showId=null)
|
||||||
{
|
{
|
||||||
$overlapping = false;
|
$overlapping = false;
|
||||||
|
|
||||||
$params = array(
|
$params = array(
|
||||||
':show_end1' => $show_end->format('Y-m-d H:i:s'),
|
':show_end1' => $show_end->format('Y-m-d H:i:s'),
|
||||||
':show_end2' => $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')
|
':show_end3' => $show_end->format('Y-m-d H:i:s')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/* If a show is being edited, exclude it from the query
|
/* If a show is being edited, exclude it from the query
|
||||||
* In both cases (new and edit) we only grab shows that
|
* In both cases (new and edit) we only grab shows that
|
||||||
* are scheduled 2 days prior
|
* are scheduled 2 days prior
|
||||||
|
@ -1357,18 +1359,18 @@ SQL;
|
||||||
return 'file';
|
return 'file';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetFileId($p_scheduleId)
|
public static function GetFileId($p_scheduleId)
|
||||||
{
|
{
|
||||||
$scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId);
|
$scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId);
|
||||||
|
|
||||||
return $scheduledItem->getDbFileId();
|
return $scheduledItem->getDbFileId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetStreamId($p_scheduleId)
|
public static function GetStreamId($p_scheduleId)
|
||||||
{
|
{
|
||||||
$scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId);
|
$scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId);
|
||||||
|
|
||||||
return $scheduledItem->getDbStreamId();
|
return $scheduledItem->getDbStreamId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,9 @@ class Application_Model_Scheduler
|
||||||
|
|
||||||
$nowEpoch = floatval($this->nowDT->format("U.u"));
|
$nowEpoch = floatval($this->nowDT->format("U.u"));
|
||||||
|
|
||||||
|
$schedInfo = array();
|
||||||
|
$instanceInfo = array();
|
||||||
|
|
||||||
for ($i = 0; $i < count($items); $i++) {
|
for ($i = 0; $i < count($items); $i++) {
|
||||||
$id = $items[$i]["id"];
|
$id = $items[$i]["id"];
|
||||||
|
|
||||||
|
@ -103,7 +106,7 @@ class Application_Model_Scheduler
|
||||||
}
|
}
|
||||||
|
|
||||||
$schedIds = array();
|
$schedIds = array();
|
||||||
if (isset($schedInfo)) {
|
if (count($schedInfo) > 0) {
|
||||||
$schedIds = array_keys($schedInfo);
|
$schedIds = array_keys($schedInfo);
|
||||||
}
|
}
|
||||||
$schedItems = CcScheduleQuery::create()->findPKs($schedIds, $this->con);
|
$schedItems = CcScheduleQuery::create()->findPKs($schedIds, $this->con);
|
||||||
|
@ -527,10 +530,6 @@ class Application_Model_Scheduler
|
||||||
|
|
||||||
$linked = false;
|
$linked = false;
|
||||||
|
|
||||||
$dropIndex_sql = "DROP INDEX cc_schedule_instance_id_idx";
|
|
||||||
Application_Common_Database::prepareAndExecute(
|
|
||||||
$dropIndex_sql, array(), Application_Common_Database::EXECUTE);
|
|
||||||
|
|
||||||
foreach ($scheduleItems as $schedule) {
|
foreach ($scheduleItems as $schedule) {
|
||||||
$id = intval($schedule["id"]);
|
$id = intval($schedule["id"]);
|
||||||
|
|
||||||
|
@ -592,6 +591,7 @@ class Application_Model_Scheduler
|
||||||
$instance_sql);
|
$instance_sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$excludePositions = array();
|
||||||
foreach($instances as &$instance) {
|
foreach($instances as &$instance) {
|
||||||
$instanceId = $instance["id"];
|
$instanceId = $instance["id"];
|
||||||
if ($id !== 0) {
|
if ($id !== 0) {
|
||||||
|
@ -612,15 +612,24 @@ class Application_Model_Scheduler
|
||||||
$instanceId);
|
$instanceId);
|
||||||
|
|
||||||
$pos++;
|
$pos++;
|
||||||
|
|
||||||
|
/* Show is not empty so we need to apply crossfades
|
||||||
|
* for the first inserted item
|
||||||
|
*/
|
||||||
|
$applyCrossfades = true;
|
||||||
}
|
}
|
||||||
//selected empty row to add after
|
//selected empty row to add after
|
||||||
else {
|
else {
|
||||||
$showStartDT = new DateTime($instance["starts"], new DateTimeZone("UTC"));
|
$showStartDT = new DateTime($instance["starts"], new DateTimeZone("UTC"));
|
||||||
$nextStartDT = $this->findNextStartTime($showStartDT, $instanceId);
|
$nextStartDT = $this->findNextStartTime($showStartDT, $instanceId);
|
||||||
|
|
||||||
//show is empty so start position counter at 0
|
//first item in show so start position counter at 0
|
||||||
$pos = 0;
|
$pos = 0;
|
||||||
$adjustSched = false;
|
|
||||||
|
/* Show is empty so we don't need to calculate crossfades
|
||||||
|
* for the first inserted item
|
||||||
|
*/
|
||||||
|
$applyCrossfades = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array($instanceId, $affectedShowInstances)) {
|
if (!in_array($instanceId, $affectedShowInstances)) {
|
||||||
|
@ -635,7 +644,12 @@ class Application_Model_Scheduler
|
||||||
|
|
||||||
$pstart = microtime(true);
|
$pstart = microtime(true);
|
||||||
|
|
||||||
$initalStartDT = clone $nextStartDT;
|
if ($applyCrossfades) {
|
||||||
|
$initalStartDT = clone $this->findTimeDifference(
|
||||||
|
$nextStartDT, $this->crossfadeDuration);
|
||||||
|
} else {
|
||||||
|
$initalStartDT = clone $nextStartDT;
|
||||||
|
}
|
||||||
|
|
||||||
$pend = microtime(true);
|
$pend = microtime(true);
|
||||||
Logging::debug("finding all following items.");
|
Logging::debug("finding all following items.");
|
||||||
|
@ -658,6 +672,7 @@ class Application_Model_Scheduler
|
||||||
//item existed previously and is being moved.
|
//item existed previously and is being moved.
|
||||||
//need to keep same id for resources if we want REST.
|
//need to keep same id for resources if we want REST.
|
||||||
if (isset($file['sched_id'])) {
|
if (isset($file['sched_id'])) {
|
||||||
|
$adjustFromDT = clone $nextStartDT;
|
||||||
$doUpdate = true;
|
$doUpdate = true;
|
||||||
|
|
||||||
$movedItem_sql = "SELECT * FROM cc_schedule ".
|
$movedItem_sql = "SELECT * FROM cc_schedule ".
|
||||||
|
@ -693,11 +708,9 @@ class Application_Model_Scheduler
|
||||||
$file["fadein"] = $sched["fade_in"];
|
$file["fadein"] = $sched["fade_in"];
|
||||||
$file["fadeout"] = $sched["fade_out"];
|
$file["fadeout"] = $sched["fade_out"];
|
||||||
} else {
|
} else {
|
||||||
//$sched = new CcSchedule();
|
|
||||||
$doInsert = true;
|
$doInsert = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
|
|
||||||
// default fades are in seconds
|
// default fades are in seconds
|
||||||
// we need to convert to '00:00:00' format
|
// we need to convert to '00:00:00' format
|
||||||
$file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']);
|
$file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']);
|
||||||
|
@ -715,6 +728,18 @@ class Application_Model_Scheduler
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($applyCrossfades) {
|
||||||
|
$nextStartDT = $this->findTimeDifference($nextStartDT,
|
||||||
|
$this->crossfadeDuration);
|
||||||
|
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
|
||||||
|
$endTimeDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
|
||||||
|
/* Set it to false because the rest of the crossfades
|
||||||
|
* will be applied after we insert each item
|
||||||
|
*/
|
||||||
|
$applyCrossfades = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
|
||||||
if ($doInsert) {
|
if ($doInsert) {
|
||||||
$values[] = "(".
|
$values[] = "(".
|
||||||
"'{$nextStartDT->format("Y-m-d H:i:s")}', ".
|
"'{$nextStartDT->format("Y-m-d H:i:s")}', ".
|
||||||
|
@ -753,12 +778,15 @@ class Application_Model_Scheduler
|
||||||
$insert_sql = "INSERT INTO cc_schedule ".
|
$insert_sql = "INSERT INTO cc_schedule ".
|
||||||
"(starts, ends, cue_in, cue_out, fade_in, fade_out, ".
|
"(starts, ends, cue_in, cue_out, fade_in, fade_out, ".
|
||||||
"clip_length, position, instance_id, file_id, stream_id) VALUES ".
|
"clip_length, position, instance_id, file_id, stream_id) VALUES ".
|
||||||
implode($values, ",");
|
implode($values, ",")." RETURNING id";
|
||||||
|
|
||||||
Application_Common_Database::prepareAndExecute(
|
|
||||||
$insert_sql, array(), Application_Common_Database::EXECUTE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$stmt = $this->con->prepare($insert_sql);
|
||||||
|
if ($stmt->execute()) {
|
||||||
|
foreach ($stmt->fetchAll() as $row) {
|
||||||
|
$excludeIds[] = $row["id"];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
// update is_scheduled flag for each cc_file
|
// update is_scheduled flag for each cc_file
|
||||||
$fileIds = array();
|
$fileIds = array();
|
||||||
foreach ($filesToInsert as &$file) {
|
foreach ($filesToInsert as &$file) {
|
||||||
|
@ -779,6 +807,7 @@ class Application_Model_Scheduler
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($adjustSched === true) {
|
if ($adjustSched === true) {
|
||||||
|
|
||||||
$followingItems_sql = "SELECT * FROM cc_schedule ".
|
$followingItems_sql = "SELECT * FROM cc_schedule ".
|
||||||
"WHERE starts >= '{$initalStartDT->format("Y-m-d H:i:s.u")}' ".
|
"WHERE starts >= '{$initalStartDT->format("Y-m-d H:i:s.u")}' ".
|
||||||
"AND instance_id = {$instanceId} ";
|
"AND instance_id = {$instanceId} ";
|
||||||
|
@ -786,7 +815,6 @@ class Application_Model_Scheduler
|
||||||
$followingItems_sql .= "AND id NOT IN (". implode($excludeIds, ",").") ";
|
$followingItems_sql .= "AND id NOT IN (". implode($excludeIds, ",").") ";
|
||||||
}
|
}
|
||||||
$followingItems_sql .= "ORDER BY starts";
|
$followingItems_sql .= "ORDER BY starts";
|
||||||
|
|
||||||
$followingSchedItems = Application_Common_Database::prepareAndExecute(
|
$followingSchedItems = Application_Common_Database::prepareAndExecute(
|
||||||
$followingItems_sql);
|
$followingItems_sql);
|
||||||
|
|
||||||
|
@ -795,6 +823,7 @@ class Application_Model_Scheduler
|
||||||
//recalculate the start/end times after the inserted items.
|
//recalculate the start/end times after the inserted items.
|
||||||
foreach ($followingSchedItems as $item) {
|
foreach ($followingSchedItems as $item) {
|
||||||
$endTimeDT = $this->findEndTime($nextStartDT, $item["clip_length"]);
|
$endTimeDT = $this->findEndTime($nextStartDT, $item["clip_length"]);
|
||||||
|
$endTimeDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
|
||||||
$update_sql = "UPDATE cc_schedule SET ".
|
$update_sql = "UPDATE cc_schedule SET ".
|
||||||
"starts = '{$nextStartDT->format("Y-m-d H:i:s")}', ".
|
"starts = '{$nextStartDT->format("Y-m-d H:i:s")}', ".
|
||||||
"ends = '{$endTimeDT->format("Y-m-d H:i:s")}', ".
|
"ends = '{$endTimeDT->format("Y-m-d H:i:s")}', ".
|
||||||
|
@ -814,11 +843,6 @@ class Application_Model_Scheduler
|
||||||
}//for each instance
|
}//for each instance
|
||||||
}//for each schedule location
|
}//for each schedule location
|
||||||
|
|
||||||
$createIndex_sql = "CREATE INDEX cc_schedule_instance_id_idx ".
|
|
||||||
"ON cc_schedule USING btree(instance_id)";
|
|
||||||
Application_Common_Database::prepareAndExecute(
|
|
||||||
$createIndex_sql, array(), Application_Common_Database::EXECUTE);
|
|
||||||
|
|
||||||
$endProfile = microtime(true);
|
$endProfile = microtime(true);
|
||||||
Logging::debug("finished adding scheduled items.");
|
Logging::debug("finished adding scheduled items.");
|
||||||
Logging::debug(floatval($endProfile) - floatval($startProfile));
|
Logging::debug(floatval($endProfile) - floatval($startProfile));
|
||||||
|
|
|
@ -388,6 +388,7 @@ class Application_Model_ShowBuilder
|
||||||
$outdated = false;
|
$outdated = false;
|
||||||
$shows = Application_Model_Show::getShows($this->startDT, $this->endDT);
|
$shows = Application_Model_Show::getShows($this->startDT, $this->endDT);
|
||||||
|
|
||||||
|
$include = array();
|
||||||
if ($this->opts["showFilter"] !== 0) {
|
if ($this->opts["showFilter"] !== 0) {
|
||||||
$include[] = $this->opts["showFilter"];
|
$include[] = $this->opts["showFilter"];
|
||||||
} elseif ($this->opts["myShows"] === 1) {
|
} elseif ($this->opts["myShows"] === 1) {
|
||||||
|
|
|
@ -352,10 +352,10 @@ SQL;
|
||||||
);
|
);
|
||||||
|
|
||||||
//only need to check overlap if show increased in size.
|
//only need to check overlap if show increased in size.
|
||||||
if (strtotime($new_ends) > strtotime($ends)) {
|
if (strtotime($now_ends) > strtotime($ends)) {
|
||||||
|
|
||||||
$utcStartDateTime = new DateTime($ends, new DateTimeZone("UTC"));
|
$utcStartDateTime = new DateTime($ends, new DateTimeZone("UTC"));
|
||||||
$utcEndDateTime = new DateTime($new_ends, new DateTimeZone("UTC"));
|
$utcEndDateTime = new DateTime($now_ends, new DateTimeZone("UTC"));
|
||||||
|
|
||||||
$overlap = Application_Model_Show::getShows($utcStartDateTime, $utcEndDateTime);
|
$overlap = Application_Model_Show::getShows($utcStartDateTime, $utcEndDateTime);
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ SQL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setShowEnd($new_ends);
|
$this->setShowEnd($now_ends);
|
||||||
Application_Model_RabbitMq::PushSchedule();
|
Application_Model_RabbitMq::PushSchedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ class Application_Model_StoredFile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$dbMd[constant($mdConst)] = $mdValue;
|
$dbMd[constant($mdConst)] = $mdValue;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->setDbColMetadata($dbMd);
|
$this->setDbColMetadata($dbMd);
|
||||||
|
@ -214,7 +214,7 @@ class Application_Model_StoredFile
|
||||||
if (isset($this->_dbMD[$dbColumn])) {
|
if (isset($this->_dbMD[$dbColumn])) {
|
||||||
$propelColumn = $this->_dbMD[$dbColumn];
|
$propelColumn = $this->_dbMD[$dbColumn];
|
||||||
$method = "set$propelColumn";
|
$method = "set$propelColumn";
|
||||||
|
|
||||||
/* We need to set track_number to null if it is an empty string
|
/* We need to set track_number to null if it is an empty string
|
||||||
* because propel defaults empty strings to zeros */
|
* because propel defaults empty strings to zeros */
|
||||||
if ($dbColumn == "track_number" && empty($mdValue)) $mdValue = null;
|
if ($dbColumn == "track_number" && empty($mdValue)) $mdValue = null;
|
||||||
|
@ -330,7 +330,7 @@ SQL;
|
||||||
|
|
||||||
$stmt = $con->prepare($sql);
|
$stmt = $con->prepare($sql);
|
||||||
$stmt->bindParam(':file_id', $this->id, PDO::PARAM_INT);
|
$stmt->bindParam(':file_id', $this->id, PDO::PARAM_INT);
|
||||||
|
|
||||||
if ($stmt->execute()) {
|
if ($stmt->execute()) {
|
||||||
$ids = $stmt->fetchAll();
|
$ids = $stmt->fetchAll();
|
||||||
} else {
|
} else {
|
||||||
|
@ -386,7 +386,7 @@ SQL;
|
||||||
// set hidden flag to true
|
// set hidden flag to true
|
||||||
$this->_file->setDbHidden(true);
|
$this->_file->setDbHidden(true);
|
||||||
$this->_file->save();
|
$this->_file->save();
|
||||||
|
|
||||||
// need to explicitly update any playlist's and block's length
|
// need to explicitly update any playlist's and block's length
|
||||||
// that contains the file getting deleted
|
// that contains the file getting deleted
|
||||||
$fileId = $this->_file->getDbId();
|
$fileId = $this->_file->getDbId();
|
||||||
|
@ -396,7 +396,7 @@ SQL;
|
||||||
$pl->setDbLength($pl->computeDbLength(Propel::getConnection(CcPlaylistPeer::DATABASE_NAME)));
|
$pl->setDbLength($pl->computeDbLength(Propel::getConnection(CcPlaylistPeer::DATABASE_NAME)));
|
||||||
$pl->save();
|
$pl->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$blRows = CcBlockcontentsQuery::create()->filterByDbFileId($fileId)->find();
|
$blRows = CcBlockcontentsQuery::create()->filterByDbFileId($fileId)->find();
|
||||||
foreach ($blRows as $row) {
|
foreach ($blRows as $row) {
|
||||||
$bl = CcBlockQuery::create()->filterByDbId($row->getDbBlockId())->findOne();
|
$bl = CcBlockQuery::create()->filterByDbId($row->getDbBlockId())->findOne();
|
||||||
|
@ -506,19 +506,19 @@ SQL;
|
||||||
public function getFileUrl()
|
public function getFileUrl()
|
||||||
{
|
{
|
||||||
$CC_CONFIG = Config::getConfig();
|
$CC_CONFIG = Config::getConfig();
|
||||||
|
|
||||||
$protocol = empty($_SERVER['HTTPS']) ? "http" : "https";
|
$protocol = empty($_SERVER['HTTPS']) ? "http" : "https";
|
||||||
|
|
||||||
$serverName = $_SERVER['SERVER_NAME'];
|
$serverName = $_SERVER['SERVER_NAME'];
|
||||||
$serverPort = $_SERVER['SERVER_PORT'];
|
$serverPort = $_SERVER['SERVER_PORT'];
|
||||||
$subDir = $CC_CONFIG['baseDir'];
|
$subDir = $CC_CONFIG['baseDir'];
|
||||||
|
|
||||||
if ($subDir[0] === "/") {
|
if ($subDir[0] === "/") {
|
||||||
$subDir = substr($subDir, 1, strlen($subDir) - 1);
|
$subDir = substr($subDir, 1, strlen($subDir) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$baseUrl = "{$protocol}://{$serverName}:{$serverPort}/{$subDir}";
|
$baseUrl = "{$protocol}://{$serverName}:{$serverPort}/{$subDir}";
|
||||||
|
|
||||||
return $this->getRelativeFileUrl($baseUrl);
|
return $this->getRelativeFileUrl($baseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +641,7 @@ SQL;
|
||||||
public static function searchLibraryFiles($datatables)
|
public static function searchLibraryFiles($datatables)
|
||||||
{
|
{
|
||||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||||
|
|
||||||
$con = Propel::getConnection(CcFilesPeer::DATABASE_NAME);
|
$con = Propel::getConnection(CcFilesPeer::DATABASE_NAME);
|
||||||
|
|
||||||
$displayColumns = self::getLibraryColumns();
|
$displayColumns = self::getLibraryColumns();
|
||||||
|
@ -796,7 +796,7 @@ SQL;
|
||||||
|
|
||||||
//soundcloud status
|
//soundcloud status
|
||||||
$file = Application_Model_StoredFile::RecallById($row['id']);
|
$file = Application_Model_StoredFile::RecallById($row['id']);
|
||||||
$row['soundcloud_status'] = $file->getSoundCloudId();
|
$row['soundcloud_id'] = $file->getSoundCloudId();
|
||||||
|
|
||||||
// for audio preview
|
// for audio preview
|
||||||
$row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION);
|
$row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION);
|
||||||
|
@ -893,7 +893,7 @@ SQL;
|
||||||
$in = fopen($_FILES['file']['tmp_name'], "rb");
|
$in = fopen($_FILES['file']['tmp_name'], "rb");
|
||||||
|
|
||||||
if ($in) {
|
if ($in) {
|
||||||
while ($buff = fread($in, 4096))
|
while (($buff = fread($in, 4096)))
|
||||||
fwrite($out, $buff);
|
fwrite($out, $buff);
|
||||||
} else
|
} else
|
||||||
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}');
|
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}');
|
||||||
|
@ -912,7 +912,7 @@ SQL;
|
||||||
$in = fopen("php://input", "rb");
|
$in = fopen("php://input", "rb");
|
||||||
|
|
||||||
if ($in) {
|
if ($in) {
|
||||||
while ($buff = fread($in, 4096))
|
while (($buff = fread($in, 4096)))
|
||||||
fwrite($out, $buff);
|
fwrite($out, $buff);
|
||||||
} else
|
} else
|
||||||
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}');
|
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}');
|
||||||
|
@ -961,6 +961,7 @@ SQL;
|
||||||
// Check if we have enough space before copying
|
// Check if we have enough space before copying
|
||||||
if (!self::isEnoughDiskSpaceToCopy($stor, $audio_file)) {
|
if (!self::isEnoughDiskSpaceToCopy($stor, $audio_file)) {
|
||||||
$freeSpace = disk_free_space($stor);
|
$freeSpace = disk_free_space($stor);
|
||||||
|
$fileSize = filesize($audio_file);
|
||||||
|
|
||||||
return array("code" => 107,
|
return array("code" => 107,
|
||||||
"message" => sprintf(_("The file was not uploaded, there is "
|
"message" => sprintf(_("The file was not uploaded, there is "
|
||||||
|
@ -1028,7 +1029,7 @@ SQL;
|
||||||
$LIQUIDSOAP_ERRORS = array('TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.');
|
$LIQUIDSOAP_ERRORS = array('TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.');
|
||||||
|
|
||||||
// Ask Liquidsoap if file is playable
|
// 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));
|
escapeshellarg($audio_file));
|
||||||
|
|
||||||
$command = "export PATH=/usr/local/bin:/usr/bin:/bin/usr/bin/ && $ls_command";
|
$command = "export PATH=/usr/local/bin:/usr/bin:/bin/usr/bin/ && $ls_command";
|
||||||
|
@ -1068,14 +1069,14 @@ SQL;
|
||||||
|
|
||||||
$stmt = $con->prepare($sql);
|
$stmt = $con->prepare($sql);
|
||||||
$stmt->bindParam(':dir_id', $dir_id);
|
$stmt->bindParam(':dir_id', $dir_id);
|
||||||
|
|
||||||
if ($stmt->execute()) {
|
if ($stmt->execute()) {
|
||||||
$rows = $stmt->fetchAll();
|
$rows = $stmt->fetchAll();
|
||||||
} else {
|
} else {
|
||||||
$msg = implode(',', $stmt->errorInfo());
|
$msg = implode(',', $stmt->errorInfo());
|
||||||
throw new Exception("Error: $msg");
|
throw new Exception("Error: $msg");
|
||||||
}
|
}
|
||||||
|
|
||||||
$results = array();
|
$results = array();
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$results[] = $row["fp"];
|
$results[] = $row["fp"];
|
||||||
|
@ -1111,10 +1112,10 @@ SQL;
|
||||||
|
|
||||||
return $rows;
|
return $rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getAllFilesWithoutSilan() {
|
public static function getAllFilesWithoutSilan() {
|
||||||
$con = Propel::getConnection();
|
$con = Propel::getConnection();
|
||||||
|
|
||||||
$sql = <<<SQL
|
$sql = <<<SQL
|
||||||
SELECT f.id,
|
SELECT f.id,
|
||||||
m.directory || f.filepath AS fp
|
m.directory || f.filepath AS fp
|
||||||
|
@ -1124,14 +1125,14 @@ WHERE file_exists = 'TRUE'
|
||||||
AND silan_check IS FALSE Limit 100
|
AND silan_check IS FALSE Limit 100
|
||||||
SQL;
|
SQL;
|
||||||
$stmt = $con->prepare($sql);
|
$stmt = $con->prepare($sql);
|
||||||
|
|
||||||
if ($stmt->execute()) {
|
if ($stmt->execute()) {
|
||||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
} else {
|
} else {
|
||||||
$msg = implode(',', $stmt->errorInfo());
|
$msg = implode(',', $stmt->errorInfo());
|
||||||
throw new Exception("Error: $msg");
|
throw new Exception("Error: $msg");
|
||||||
}
|
}
|
||||||
|
|
||||||
return $rows;
|
return $rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1227,7 +1228,7 @@ SQL;
|
||||||
->save();
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This method seems to be unsued everywhere so I've commented it out
|
// 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
|
// If it's absence does not have any effect then it will be completely
|
||||||
// removed soon
|
// removed soon
|
||||||
|
@ -1255,7 +1256,7 @@ SQL;
|
||||||
$description = $file->getDbTrackTitle();
|
$description = $file->getDbTrackTitle();
|
||||||
$tag = array();
|
$tag = array();
|
||||||
$genre = $file->getDbGenre();
|
$genre = $file->getDbGenre();
|
||||||
$release = $file->getDbYear();
|
$release = $file->getDbUtime();
|
||||||
try {
|
try {
|
||||||
$soundcloud = new Application_Model_Soundcloud();
|
$soundcloud = new Application_Model_Soundcloud();
|
||||||
$soundcloud_res = $soundcloud->uploadTrack(
|
$soundcloud_res = $soundcloud->uploadTrack(
|
||||||
|
@ -1284,7 +1285,7 @@ SQL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function setIsPlaylist($p_playlistItems, $p_type, $p_status) {
|
public static function setIsPlaylist($p_playlistItems, $p_type, $p_status) {
|
||||||
foreach ($p_playlistItems as $item) {
|
foreach ($p_playlistItems as $item) {
|
||||||
$file = self::RecallById($item->getDbFileId());
|
$file = self::RecallById($item->getDbFileId());
|
||||||
|
@ -1302,7 +1303,7 @@ SQL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function setIsScheduled($p_scheduleItem, $p_status,
|
public static function setIsScheduled($p_scheduleItem, $p_status,
|
||||||
$p_fileId=null) {
|
$p_fileId=null) {
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,7 @@ class Application_Model_Systemstatus
|
||||||
public static function GetPlatformInfo()
|
public static function GetPlatformInfo()
|
||||||
{
|
{
|
||||||
$keys = array("release", "machine", "memory", "swap");
|
$keys = array("release", "machine", "memory", "swap");
|
||||||
|
$data = array();
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
$data[$key] = "UNKNOWN";
|
$data[$key] = "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
@ -212,7 +213,7 @@ class Application_Model_Systemstatus
|
||||||
|
|
||||||
public static function GetDiskInfo()
|
public static function GetDiskInfo()
|
||||||
{
|
{
|
||||||
$partions = array();
|
$partitions = array();
|
||||||
|
|
||||||
/* First lets get all the watched directories. Then we can group them
|
/* First lets get all the watched directories. Then we can group them
|
||||||
* into the same partitions by comparing the partition sizes. */
|
* into the same partitions by comparing the partition sizes. */
|
||||||
|
|
|
@ -226,7 +226,7 @@ class Application_Model_User
|
||||||
public function deleteAllFiles()
|
public function deleteAllFiles()
|
||||||
{
|
{
|
||||||
$my_files = $this->getOwnedFiles();
|
$my_files = $this->getOwnedFiles();
|
||||||
foreach ($files as $file) {
|
foreach ($my_files as $file) {
|
||||||
$file->delete();
|
$file->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,14 @@ class CcFiles extends BaseCcFiles {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setDbTrackNumber($v)
|
||||||
|
{
|
||||||
|
$max = pow(2, 31)-1;
|
||||||
|
$v = ($v > $max) ? $max : $v;
|
||||||
|
|
||||||
|
return parent::setDbTrackNumber($v);
|
||||||
|
}
|
||||||
|
|
||||||
// returns true if the file exists and is not hidden
|
// returns true if the file exists and is not hidden
|
||||||
public function visible() {
|
public function visible() {
|
||||||
return $this->getDbFileExists() && !$this->getDbHidden();
|
return $this->getDbFileExists() && !$this->getDbHidden();
|
||||||
|
|
|
@ -177,10 +177,6 @@ class Application_Service_SchedulerService
|
||||||
$timeFilled = Application_Common_Database::prepareAndExecute(
|
$timeFilled = Application_Common_Database::prepareAndExecute(
|
||||||
$timeFilled_sql, array(), Application_Common_Database::COLUMN);
|
$timeFilled_sql, array(), Application_Common_Database::COLUMN);
|
||||||
|
|
||||||
$dropIndex_sql = "DROP INDEX cc_schedule_instance_id_idx";
|
|
||||||
Application_Common_Database::prepareAndExecute(
|
|
||||||
$dropIndex_sql, array(), Application_Common_Database::EXECUTE);
|
|
||||||
|
|
||||||
//need to find out which linked instances are empty
|
//need to find out which linked instances are empty
|
||||||
$values = array();
|
$values = array();
|
||||||
foreach ($instanceIds as $id) {
|
foreach ($instanceIds as $id) {
|
||||||
|
@ -210,7 +206,8 @@ class Application_Service_SchedulerService
|
||||||
|
|
||||||
if (is_null($item["file_id"])) {
|
if (is_null($item["file_id"])) {
|
||||||
$item["file_id"] = "null";
|
$item["file_id"] = "null";
|
||||||
} elseif (is_null($item["stream_id"])) {
|
}
|
||||||
|
if (is_null($item["stream_id"])) {
|
||||||
$item["stream_id"] = "null";
|
$item["stream_id"] = "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,11 +237,6 @@ class Application_Service_SchedulerService
|
||||||
Application_Common_Database::prepareAndExecute(
|
Application_Common_Database::prepareAndExecute(
|
||||||
$insert_sql, array(), Application_Common_Database::EXECUTE);
|
$insert_sql, array(), Application_Common_Database::EXECUTE);
|
||||||
|
|
||||||
$createIndex_sql = "CREATE INDEX cc_schedule_instance_id_idx ".
|
|
||||||
"ON cc_schedule USING btree(instance_id)";
|
|
||||||
Application_Common_Database::prepareAndExecute(
|
|
||||||
$createIndex_sql, array(), Application_Common_Database::EXECUTE);
|
|
||||||
|
|
||||||
//update time_filled in cc_show_instances
|
//update time_filled in cc_show_instances
|
||||||
$now = gmdate("Y-m-d H:i:s");
|
$now = gmdate("Y-m-d H:i:s");
|
||||||
$update_sql = "UPDATE cc_show_instances SET ".
|
$update_sql = "UPDATE cc_show_instances SET ".
|
||||||
|
|
|
@ -99,8 +99,9 @@ class Application_Service_ShowFormService
|
||||||
public function delegateShowFormPopulation($forms)
|
public function delegateShowFormPopulation($forms)
|
||||||
{
|
{
|
||||||
$this->populateFormWhat($forms["what"]);
|
$this->populateFormWhat($forms["what"]);
|
||||||
$this->populateFormWhen($forms["when"]);
|
//local show start DT
|
||||||
$this->populateFormRepeats($forms["repeats"]);
|
$showStart = $this->populateFormWhen($forms["when"]);
|
||||||
|
$this->populateFormRepeats($forms["repeats"], $showStart);
|
||||||
$this->populateFormWho($forms["who"]);
|
$this->populateFormWho($forms["who"]);
|
||||||
$this->populateFormStyle($forms["style"]);
|
$this->populateFormStyle($forms["style"]);
|
||||||
$this->populateFormLive($forms["live"]);
|
$this->populateFormLive($forms["live"]);
|
||||||
|
@ -136,6 +137,9 @@ class Application_Service_ShowFormService
|
||||||
$form->disableStartDateAndTime();
|
$form->disableStartDateAndTime();
|
||||||
} else {
|
} else {
|
||||||
list($showStart, $showEnd) = $this->getNextFutureRepeatShowTime();
|
list($showStart, $showEnd) = $this->getNextFutureRepeatShowTime();
|
||||||
|
if ($this->hasShowStarted($showStart)) {
|
||||||
|
$form->disableStartDateAndTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +151,8 @@ class Application_Service_ShowFormService
|
||||||
'add_show_end_time' => $showEnd->format("H:i"),
|
'add_show_end_time' => $showEnd->format("H:i"),
|
||||||
'add_show_duration' => $ccShowDay->formatDuration(true),
|
'add_show_duration' => $ccShowDay->formatDuration(true),
|
||||||
'add_show_repeats' => $ccShowDay->isRepeating() ? 1 : 0));
|
'add_show_repeats' => $ccShowDay->isRepeating() ? 1 : 0));
|
||||||
|
|
||||||
|
return $showStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function populateInstanceFormWhen($form)
|
private function populateInstanceFormWhen($form)
|
||||||
|
@ -179,7 +185,13 @@ class Application_Service_ShowFormService
|
||||||
$form->getElement('add_show_repeats')->setOptions(array("disabled" => true));
|
$form->getElement('add_show_repeats')->setOptions(array("disabled" => true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function populateFormRepeats($form)
|
/**
|
||||||
|
*
|
||||||
|
* Enter description here ...
|
||||||
|
* @param $form
|
||||||
|
* @param DateTime $nextFutureShowStart user's local timezone
|
||||||
|
*/
|
||||||
|
private function populateFormRepeats($form, $nextFutureShowStart)
|
||||||
{
|
{
|
||||||
$ccShowDays = $this->ccShow->getCcShowDays();
|
$ccShowDays = $this->ccShow->getCcShowDays();
|
||||||
|
|
||||||
|
@ -219,6 +231,14 @@ class Application_Service_ShowFormService
|
||||||
if (!$this->ccShow->isLinkable() || $this->ccShow->isRecorded()) {
|
if (!$this->ccShow->isLinkable() || $this->ccShow->isRecorded()) {
|
||||||
$form->getElement('add_show_linked')->setOptions(array('disabled' => true));
|
$form->getElement('add_show_linked')->setOptions(array('disabled' => true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Because live editing of a linked show is disabled, we will disable
|
||||||
|
* the linking option if the current show is being edited. We don't
|
||||||
|
* want the user to suddenly not be able to edit the current show
|
||||||
|
*/
|
||||||
|
if ($this->hasShowStarted($nextFutureShowStart)) {
|
||||||
|
$form->getElement('add_show_linked')->setOptions(array('disabled' => true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function populateFormWho($form)
|
private function populateFormWho($form)
|
||||||
|
@ -295,6 +315,22 @@ class Application_Service_ShowFormService
|
||||||
$form->populate($formValues);
|
$form->populate($formValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Enter description here ...
|
||||||
|
* @param DateTime $showStart user's local time
|
||||||
|
*/
|
||||||
|
private function hasShowStarted($p_showStart) {
|
||||||
|
$showStart = clone $p_showStart;
|
||||||
|
$showStart->setTimeZone(new DateTimeZone("UTC"));
|
||||||
|
|
||||||
|
if ($showStart->format("Y-m-d H:i:s") < gmdate("Y-m-d H:i:s")) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Before we send the form data in for validation, there
|
* Before we send the form data in for validation, there
|
||||||
|
|
|
@ -999,7 +999,7 @@ SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isRebroadcast) {
|
if ($this->isRebroadcast) {
|
||||||
$this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId());
|
$this->createRebroadcastInstances($showDay, $start, $ccShowInstance->getDbId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$start = $this->getNextMonthlyMonthlyRepeatDate($start, $timezone, $showDay->getDbStartTime());
|
$start = $this->getNextMonthlyMonthlyRepeatDate($start, $timezone, $showDay->getDbStartTime());
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 801 B After Width: | Height: | Size: 481 B |
|
@ -125,7 +125,7 @@ select {
|
||||||
|
|
||||||
.airtime_auth_help_icon, .custom_auth_help_icon, .stream_username_help_icon,
|
.airtime_auth_help_icon, .custom_auth_help_icon, .stream_username_help_icon,
|
||||||
.playlist_type_help_icon, .master_username_help_icon, .repeat_tracks_help_icon,
|
.playlist_type_help_icon, .master_username_help_icon, .repeat_tracks_help_icon,
|
||||||
.admin_username_help_icon, .stream_type_help_icon {
|
.admin_username_help_icon, .stream_type_help_icon, .show_linking_help_icon {
|
||||||
cursor: help;
|
cursor: help;
|
||||||
position: relative;
|
position: relative;
|
||||||
display:inline-block; zoom:1;
|
display:inline-block; zoom:1;
|
||||||
|
|
|
@ -262,14 +262,14 @@ function parseItems(obj){
|
||||||
|
|
||||||
if (obj.currentShow.length > 0) {
|
if (obj.currentShow.length > 0) {
|
||||||
calcAdditionalShowData(obj.currentShow);
|
calcAdditionalShowData(obj.currentShow);
|
||||||
|
currentShow = obj.currentShow;
|
||||||
}
|
}
|
||||||
if (obj.nextShow.length > 0) {
|
if (obj.nextShow.length > 0) {
|
||||||
calcAdditionalShowData(obj.nextShow);
|
calcAdditionalShowData(obj.nextShow);
|
||||||
|
nextShow = obj.nextShow;
|
||||||
calculateTimeToNextShow();
|
calculateTimeToNextShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
currentShow = obj.currentShow;
|
|
||||||
nextShow = obj.nextShow;
|
|
||||||
|
|
||||||
var schedulePosixTime = convertDateToPosixTime(obj.schedulerTime);
|
var schedulePosixTime = convertDateToPosixTime(obj.schedulerTime);
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
|
|
|
@ -593,12 +593,12 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
"fnRowCallback": AIRTIME.library.fnRowCallback,
|
"fnRowCallback": AIRTIME.library.fnRowCallback,
|
||||||
"fnCreatedRow": function( nRow, aData, iDataIndex ) {
|
"fnCreatedRow": function( nRow, aData, iDataIndex ) {
|
||||||
//add soundcloud icon
|
//add soundcloud icon
|
||||||
if (aData.soundcloud_status !== undefined) {
|
if (aData.soundcloud_id !== undefined) {
|
||||||
if (aData.soundcloud_status === "-2") {
|
if (aData.soundcloud_id === "-2") {
|
||||||
$(nRow).find("td.library_title").append('<span class="small-icon progress"/>');
|
$(nRow).find("td.library_title").append('<span class="small-icon progress"/>');
|
||||||
} else if (aData.soundcloud_status === "-3") {
|
} else if (aData.soundcloud_id === "-3") {
|
||||||
$(nRow).find("td.library_title").append('<span class="small-icon sc-error"/>');
|
$(nRow).find("td.library_title").append('<span class="small-icon sc-error"/>');
|
||||||
} else if (aData.soundcloud_status !== null) {
|
} else if (aData.soundcloud_id !== null) {
|
||||||
$(nRow).find("td.library_title").append('<span class="small-icon soundcloud"/>');
|
$(nRow).find("td.library_title").append('<span class="small-icon soundcloud"/>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1126,7 +1126,6 @@ function checkLibrarySCUploadStatus(){
|
||||||
else if (json.sc_id == "-3") {
|
else if (json.sc_id == "-3") {
|
||||||
span.removeClass("progress").addClass("sc-error");
|
span.removeClass("progress").addClass("sc-error");
|
||||||
}
|
}
|
||||||
setTimeout(checkLibrarySCUploadStatus, 5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSCUploadStatusRequest() {
|
function checkSCUploadStatusRequest() {
|
||||||
|
@ -1138,12 +1137,16 @@ function checkLibrarySCUploadStatus(){
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#library_display span.progress").each(checkSCUploadStatusRequest);
|
$("#library_display span.progress").each(checkSCUploadStatusRequest);
|
||||||
|
setTimeout(checkLibrarySCUploadStatus, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addQtipToSCIcons(){
|
function addQtipToSCIcons() {
|
||||||
$(".progress, .soundcloud, .sc-error").live('mouseover', function(){
|
$("#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")){
|
if ($(this).hasClass("progress")){
|
||||||
$(this).qtip({
|
$(this).qtip({
|
||||||
|
@ -1163,24 +1166,15 @@ function addQtipToSCIcons(){
|
||||||
classes: "ui-tooltip-dark file-md-long"
|
classes: "ui-tooltip-dark file-md-long"
|
||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
ready: true // Needed to make it show on first mouseover
|
ready: true // Needed to make it show on first mouseover event
|
||||||
// event
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if($(this).hasClass("soundcloud")){
|
else if ($(this).hasClass("soundcloud")){
|
||||||
var sc_id = $(this).parent().parent().data("aData").soundcloud_id;
|
|
||||||
$(this).qtip({
|
$(this).qtip({
|
||||||
content: {
|
content: {
|
||||||
text: $.i18n._("Retrieving data from the server..."),
|
text: $.i18n._("The soundcloud id for this file is: ") + sc_id
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
position:{
|
position:{
|
||||||
adjust: {
|
adjust: {
|
||||||
|
@ -1195,11 +1189,11 @@ function addQtipToSCIcons(){
|
||||||
classes: "ui-tooltip-dark file-md-long"
|
classes: "ui-tooltip-dark file-md-long"
|
||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
ready: true // Needed to make it show on first mouseover
|
ready: true // Needed to make it show on first mouseover event
|
||||||
// event
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else if($(this).hasClass("sc-error")){
|
}
|
||||||
|
else if ($(this).hasClass("sc-error")) {
|
||||||
$(this).qtip({
|
$(this).qtip({
|
||||||
content: {
|
content: {
|
||||||
text: $.i18n._("Retreiving data from the server..."),
|
text: $.i18n._("Retreiving data from the server..."),
|
||||||
|
@ -1227,8 +1221,7 @@ function addQtipToSCIcons(){
|
||||||
classes: "ui-tooltip-dark file-md-long"
|
classes: "ui-tooltip-dark file-md-long"
|
||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
ready: true // Needed to make it show on first mouseover
|
ready: true // Needed to make it show on first mouseover event
|
||||||
// event
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -587,7 +587,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
var extra = (ele['extra']==null)?"":"- "+ele['extra'];
|
var extra = (ele['extra']==null)?"":"- "+ele['extra'];
|
||||||
$html += "<li>" +
|
$html += "<li>" +
|
||||||
"<span class='block-item-title'>"+ele['display_name']+"</span>" +
|
"<span class='block-item-title'>"+ele['display_name']+"</span>" +
|
||||||
"<span class='block-item-criteria'>"+ele['modifier']+"</span>" +
|
"<span class='block-item-criteria'>"+ele['display_modifier']+"</span>" +
|
||||||
"<span class='block-item-criteria'>"+ele['value']+"</span>" +
|
"<span class='block-item-criteria'>"+ele['value']+"</span>" +
|
||||||
"<span class='block-item-criteria'>"+extra+"</span>" +
|
"<span class='block-item-criteria'>"+extra+"</span>" +
|
||||||
"</li>";
|
"</li>";
|
||||||
|
|
|
@ -192,7 +192,8 @@ function setAddShowEvents() {
|
||||||
$(this).parent().after("<ul id='show-link-warning' class='errors'><li>"+$.i18n._("Warning: Shows cannot be re-linked")+"</li></ul>");
|
$(this).parent().after("<ul id='show-link-warning' class='errors'><li>"+$.i18n._("Warning: Shows cannot be re-linked")+"</li></ul>");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
form.find("#add_show_linked-label").before("<span class='show_linking_help_icon'></span>");
|
||||||
|
|
||||||
form.find("#add_show_record").click(function(){
|
form.find("#add_show_record").click(function(){
|
||||||
$(this).blur();
|
$(this).blur();
|
||||||
|
@ -315,7 +316,26 @@ function setAddShowEvents() {
|
||||||
at: "right center"
|
at: "right center"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
form.find(".show_linking_help_icon").qtip({
|
||||||
|
content: {
|
||||||
|
text: $.i18n._("By linking your repeating shows any media items scheduled in any repeat show will also get scheduled in the other repeat shows")
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
delay: 500,
|
||||||
|
fixed: true
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
border: {
|
||||||
|
width: 0,
|
||||||
|
radius: 4
|
||||||
|
},
|
||||||
|
classes: "ui-tooltip-dark ui-tooltip-rounded"
|
||||||
|
},
|
||||||
|
position: {
|
||||||
|
my: "left bottom",
|
||||||
|
at: "right center"
|
||||||
|
}
|
||||||
|
});
|
||||||
function endDateVisibility(){
|
function endDateVisibility(){
|
||||||
if(form.find("#add_show_no_end").is(':checked')){
|
if(form.find("#add_show_no_end").is(':checked')){
|
||||||
form.find("#add_show_end_date").hide();
|
form.find("#add_show_end_date").hide();
|
||||||
|
|
|
@ -211,6 +211,7 @@ function viewDisplay( view ) {
|
||||||
|
|
||||||
function eventRender(event, element, view) {
|
function eventRender(event, element, view) {
|
||||||
|
|
||||||
|
$(element).attr("id", "fc-show-instance-"+event.id);
|
||||||
$(element).data("event", event);
|
$(element).data("event", event);
|
||||||
|
|
||||||
//only put progress bar on shows that aren't being recorded.
|
//only put progress bar on shows that aren't being recorded.
|
||||||
|
@ -228,35 +229,28 @@ function eventRender(event, element, view) {
|
||||||
|
|
||||||
$(element).find(".fc-event-content").append(div);
|
$(element).find(".fc-event-content").append(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
//need to add id for every event to find the current show
|
|
||||||
if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
|
|
||||||
$(element).find(".fc-event-time").attr("id", event.id);
|
|
||||||
} else if (view.name === 'month') {
|
|
||||||
$(element).find(".fc-event-title").attr("id", event.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//add the record/rebroadcast/soundcloud icons if needed
|
//add the record/rebroadcast/soundcloud icons if needed
|
||||||
if (event.record === 1) {
|
if (event.record === 1) {
|
||||||
if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
|
if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
|
||||||
if (event.soundcloud_id === -1) {
|
if (event.soundcloud_id === -1) {
|
||||||
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon recording"></span>');
|
$(element).find(".fc-event-time").before('<span class="small-icon recording"></span>');
|
||||||
} else if ( event.soundcloud_id > 0) {
|
} else if ( event.soundcloud_id > 0) {
|
||||||
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon soundcloud"></span>');
|
$(element).find(".fc-event-time").before('<span class="small-icon recording"></span><span class="small-icon soundcloud"></span>');
|
||||||
} else if (event.soundcloud_id === -2) {
|
} else if (event.soundcloud_id === -2) {
|
||||||
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon progress"></span>');
|
$(element).find(".fc-event-time").before('<span class="small-icon recording"></span><span class="small-icon progress"></span>');
|
||||||
} else if (event.soundcloud_id === -3) {
|
} else if (event.soundcloud_id === -3) {
|
||||||
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon sc-error"></span>');
|
$(element).find(".fc-event-time").before('<span class="small-icon recording"></span><span class="small-icon sc-error"></span>');
|
||||||
}
|
}
|
||||||
} else if (view.name === 'month') {
|
} else if (view.name === 'month') {
|
||||||
if(event.soundcloud_id === -1) {
|
if(event.soundcloud_id === -1) {
|
||||||
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon recording"></span>');
|
$(element).find(".fc-event-title").after('<span class="small-icon recording"></span>');
|
||||||
} else if (event.soundcloud_id > 0) {
|
} else if (event.soundcloud_id > 0) {
|
||||||
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon soundcloud"></span>');
|
$(element).find(".fc-event-title").after('<span class="small-icon recording"></span><span class="small-icon soundcloud"></span>');
|
||||||
} else if (event.soundcloud_id === -2) {
|
} else if (event.soundcloud_id === -2) {
|
||||||
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon progress"></span>');
|
$(element).find(".fc-event-title").after('<span class="small-icon recording"></span><span class="small-icon progress"></span>');
|
||||||
} else if (event.soundcloud_id === -3) {
|
} else if (event.soundcloud_id === -3) {
|
||||||
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon sc-error"></span>');
|
$(element).find(".fc-event-title").after('<span class="small-icon recording"></span><span class="small-icon sc-error"></span>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,27 +261,27 @@ function eventRender(event, element, view) {
|
||||||
if (event.linked) {
|
if (event.linked) {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-time")
|
.find(".fc-event-time")
|
||||||
.before('<span id="'+event.id+'" class="small-icon linked"></span><span id="'+event.id+'" class="small-icon show-empty"></span>');
|
.before('<span class="small-icon linked"></span><span class="small-icon show-empty"></span>');
|
||||||
} else {
|
} else {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-time")
|
.find(".fc-event-time")
|
||||||
.before('<span id="'+event.id+'" class="small-icon show-empty"></span>');
|
.before('<span class="small-icon show-empty"></span>');
|
||||||
}
|
}
|
||||||
} else if (event.show_partial_filled === true) {
|
} else if (event.show_partial_filled === true) {
|
||||||
if (event.linked) {
|
if (event.linked) {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-time")
|
.find(".fc-event-time")
|
||||||
.before('<span id="'+event.id+'" class="small-icon linked"></span><span id="'+event.id+'" class="small-icon show-partial-filled"></span>');
|
.before('<span class="small-icon linked"></span><span class="small-icon show-partial-filled"></span>');
|
||||||
} else {
|
} else {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-time")
|
.find(".fc-event-time")
|
||||||
.before('<span id="'+event.id+'" class="small-icon show-partial-filled"></span>');
|
.before('<span class="small-icon show-partial-filled"></span>');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (event.linked) {
|
if (event.linked) {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-time")
|
.find(".fc-event-time")
|
||||||
.before('<span id="'+event.id+'" class="small-icon linked"></span>');
|
.before('<span class="small-icon linked"></span>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (view.name === 'month') {
|
} else if (view.name === 'month') {
|
||||||
|
@ -295,27 +289,27 @@ function eventRender(event, element, view) {
|
||||||
if (event.linked) {
|
if (event.linked) {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-title")
|
.find(".fc-event-title")
|
||||||
.after('<span id="'+event.id+'" class="small-icon linked"></span><span id="'+event.id+'" title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
|
.after('<span class="small-icon linked"></span><span title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
|
||||||
} else {
|
} else {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-title")
|
.find(".fc-event-title")
|
||||||
.after('<span id="'+event.id+'" title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
|
.after('<span title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
|
||||||
}
|
}
|
||||||
} else if (event.show_partial_filled === true) {
|
} else if (event.show_partial_filled === true) {
|
||||||
if (event.linked) {
|
if (event.linked) {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-title")
|
.find(".fc-event-title")
|
||||||
.after('<span id="'+event.id+'" class="small-icon linked"></span><span id="'+event.id+'" title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
|
.after('<span class="small-icon linked"></span><span title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
|
||||||
} else {
|
} else {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-title")
|
.find(".fc-event-title")
|
||||||
.after('<span id="'+event.id+'" title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
|
.after('<span title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (event.linked) {
|
if (event.linked) {
|
||||||
$(element)
|
$(element)
|
||||||
.find(".fc-event-title")
|
.find(".fc-event-title")
|
||||||
.after('<span id="'+event.id+'" class="small-icon linked"></span>');
|
.after('<span class="small-icon linked"></span>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,9 +318,9 @@ function eventRender(event, element, view) {
|
||||||
//rebroadcast icon
|
//rebroadcast icon
|
||||||
if (event.rebroadcast === 1) {
|
if (event.rebroadcast === 1) {
|
||||||
if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
|
if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
|
||||||
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon rebroadcast"></span>');
|
$(element).find(".fc-event-time").before('<span class="small-icon rebroadcast"></span>');
|
||||||
} else if (view.name === 'month') {
|
} else if (view.name === 'month') {
|
||||||
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon rebroadcast"></span>');
|
$(element).find(".fc-event-title").after('<span class="small-icon rebroadcast"></span>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,7 +328,7 @@ function eventRender(event, element, view) {
|
||||||
function eventAfterRender( event, element, view ) {
|
function eventAfterRender( event, element, view ) {
|
||||||
|
|
||||||
$(element).find(".small-icon").live('mouseover',function(){
|
$(element).find(".small-icon").live('mouseover',function(){
|
||||||
addQtipsToIcons($(this));
|
addQtipsToIcons($(this), event.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,15 +397,25 @@ function getFullCalendarEvents(start, end, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSCUploadStatus(){
|
function checkSCUploadStatus(){
|
||||||
var url = baseUrl+'Library/get-upload-to-soundcloud-status/format/json';
|
var url = baseUrl+'Library/get-upload-to-soundcloud-status/format/json',
|
||||||
|
id;
|
||||||
$("span[class*=progress]").each(function(){
|
$("span[class*=progress]").each(function(){
|
||||||
var id = $(this).attr("id");
|
id = $(this).parents("div.fc-event").data("event").id;
|
||||||
|
|
||||||
$.post(url, {format: "json", id: id, type:"show"}, function(json){
|
$.post(url, {format: "json", id: id, type:"show"}, function(json){
|
||||||
if(json.sc_id > 0){
|
if (json.sc_id > 0){
|
||||||
$("span[id="+id+"]:not(.recording)").removeClass("progress").addClass("soundcloud");
|
$("#fc-show-instance-"+id)
|
||||||
}else if(json.sc_id == "-3"){
|
.find(".progress")
|
||||||
$("span[id="+id+"]:not(.recording)").removeClass("progress").addClass("sc-error");
|
.removeClass("progress")
|
||||||
|
.addClass("soundcloud");
|
||||||
}
|
}
|
||||||
|
else if (json.sc_id == "-3"){
|
||||||
|
$("#fc-show-instance-"+id)
|
||||||
|
.find(".progress")
|
||||||
|
.removeClass("progress")
|
||||||
|
.addClass("sc-error");
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(checkSCUploadStatus, 5000);
|
setTimeout(checkSCUploadStatus, 5000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -425,7 +429,7 @@ function getCurrentShow(){
|
||||||
$el;
|
$el;
|
||||||
$.post(url, {format: "json"}, function(json) {
|
$.post(url, {format: "json"}, function(json) {
|
||||||
if (json.current_show === true) {
|
if (json.current_show === true) {
|
||||||
$el = $("div[class*=fc-event-time][id="+json.si_id+"]");
|
$el = $("div[class*=fc-event-time]");
|
||||||
if (view_name === 'agendaDay' || view_name === 'agendaWeek') {
|
if (view_name === 'agendaDay' || view_name === 'agendaWeek') {
|
||||||
|
|
||||||
/* Need to remove now-playing class because if user
|
/* Need to remove now-playing class because if user
|
||||||
|
@ -440,40 +444,40 @@ function getCurrentShow(){
|
||||||
* icon will overwrite it.
|
* icon will overwrite it.
|
||||||
*/
|
*/
|
||||||
$el.siblings().remove("span[class=small-icon recording]");
|
$el.siblings().remove("span[class=small-icon recording]");
|
||||||
$el.before('<span id="'+json.si_id+'" class="small-icon now-playing"></span><span id="'+json.si_id+'" class="small-icon recording"></span>');
|
$el.before('<span class="small-icon now-playing"></span><span class="small-icon recording"></span>');
|
||||||
} else if ($el.siblings().hasClass("small-icon rebroadcast")) {
|
} else if ($el.siblings().hasClass("small-icon rebroadcast")) {
|
||||||
|
|
||||||
/* Without removing rebroadcast icon, the now playing
|
/* Without removing rebroadcast icon, the now playing
|
||||||
* icon will overwrite it.
|
* icon will overwrite it.
|
||||||
*/
|
*/
|
||||||
$el.siblings().remove("span[class=small-icon rebroadcast]");
|
$el.siblings().remove("span[class=small-icon rebroadcast]");
|
||||||
$el.before('<span id="'+json.si_id+'" class="small-icon now-playing"></span><span id="'+json.si_id+'" class="small-icon rebroadcast"></span>');
|
$el.before('<span class="small-icon now-playing"></span><span class="small-icon rebroadcast"></span>');
|
||||||
} else {
|
} else {
|
||||||
$el.before('<span id="'+json.si_id+'" class="small-icon now-playing"></span>');
|
$el.before('<span class="small-icon now-playing"></span>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (view_name === 'month') {
|
} else if (view_name === 'month') {
|
||||||
if (!$("span[class*=fc-event-title][id="+json.si_id+"]").siblings().hasClass("small-icon now-playing")) {
|
if (!$("span[class*=fc-event-title]").siblings().hasClass("small-icon now-playing")) {
|
||||||
$("span[class*=fc-event-title][id="+json.si_id+"]").after('<span id="'+json.si_id+'" class="small-icon now-playing"></span>');
|
$("span[class*=fc-event-title]").after('<span class="small-icon now-playing"></span>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//remove icon from shows that have ended
|
//remove icon from shows that have ended
|
||||||
$(".now-playing").each(function(){
|
$(".now-playing").each(function(){
|
||||||
id = $(this).attr("id");
|
id = $(this).parents("div.fc-event").data("event").id;
|
||||||
if (id != json.si_id) {
|
|
||||||
$(this).remove("span[small-icon now-playing]");
|
if (id != json.si_id) {
|
||||||
}
|
$(this).remove("span[small-icon now-playing]");
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setTimeout(getCurrentShow, 5000);
|
setTimeout(getCurrentShow, 5000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addQtipsToIcons(ele, id){
|
||||||
function addQtipsToIcons(ele){
|
|
||||||
var id = $(ele).attr("id");
|
if ($(ele).hasClass("progress")){
|
||||||
|
|
||||||
if($(ele).hasClass("progress")){
|
|
||||||
$(ele).qtip({
|
$(ele).qtip({
|
||||||
content: {
|
content: {
|
||||||
text: $.i18n._("Uploading in progress...")
|
text: $.i18n._("Uploading in progress...")
|
||||||
|
|
|
@ -58,24 +58,22 @@ function confirmCancelRecordedShow(show_instance_id){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadToSoundCloud(show_instance_id){
|
function uploadToSoundCloud(show_instance_id, el){
|
||||||
|
|
||||||
var url = baseUrl+"Schedule/upload-to-sound-cloud";
|
var url = baseUrl+"Schedule/upload-to-sound-cloud",
|
||||||
var span = $(window.triggerElement).find(".recording");
|
$el = $(el),
|
||||||
|
$span = $el.find(".soundcloud");
|
||||||
|
|
||||||
$.post(url,
|
$.post(url, {id: show_instance_id, format: "json"});
|
||||||
{id: show_instance_id, format: "json"},
|
|
||||||
function(json){
|
|
||||||
scheduleRefetchEvents(json);
|
|
||||||
});
|
|
||||||
|
|
||||||
if(span.length == 0){
|
//first upload to soundcloud.
|
||||||
span = $(window.triggerElement).find(".soundcloud");
|
if ($span.length === 0){
|
||||||
span.removeClass("soundcloud")
|
$span = $("<span/>", {"class": "progress"});
|
||||||
.addClass("progress");
|
|
||||||
}else{
|
$el.find(".fc-event-title").after($span);
|
||||||
span.removeClass("recording")
|
}
|
||||||
.addClass("progress");
|
else {
|
||||||
|
$span.removeClass("soundcloud").addClass("progress");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +91,6 @@ function checkCalendarSCUploadStatus(){
|
||||||
else if (json.sc_id == "-3") {
|
else if (json.sc_id == "-3") {
|
||||||
span.removeClass("progress").addClass("sc-error");
|
span.removeClass("progress").addClass("sc-error");
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(checkCalendarSCUploadStatus, 5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSCUploadStatusRequest() {
|
function checkSCUploadStatusRequest() {
|
||||||
|
@ -106,6 +102,7 @@ function checkCalendarSCUploadStatus(){
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#schedule_calendar span.progress").each(checkSCUploadStatusRequest);
|
$("#schedule_calendar span.progress").each(checkSCUploadStatusRequest);
|
||||||
|
setTimeout(checkCalendarSCUploadStatus, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function findViewportDimensions() {
|
function findViewportDimensions() {
|
||||||
|
@ -421,7 +418,7 @@ $(document).ready(function() {
|
||||||
if (oItems.soundcloud_upload !== undefined) {
|
if (oItems.soundcloud_upload !== undefined) {
|
||||||
|
|
||||||
callback = function() {
|
callback = function() {
|
||||||
uploadToSoundCloud(data.id);
|
uploadToSoundCloud(data.id, this.context);
|
||||||
};
|
};
|
||||||
oItems.soundcloud_upload.callback = callback;
|
oItems.soundcloud_upload.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
|
@ -546,7 +546,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
cl = 'sb-footer';
|
cl = 'sb-footer';
|
||||||
|
|
||||||
//check the show's content status.
|
//check the show's content status.
|
||||||
if (aData.runtime > 0) {
|
if (aData.runtime >= 0) {
|
||||||
$node.html('<span class="ui-icon ui-icon-check"></span>');
|
$node.html('<span class="ui-icon ui-icon-check"></span>');
|
||||||
cl = cl + ' ui-state-highlight';
|
cl = cl + ' ui-state-highlight';
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ VERSION=2.4.0~$(date "+%Y%m%d")
|
||||||
BUILDDEST=/tmp/airtime-${VERSION}/
|
BUILDDEST=/tmp/airtime-${VERSION}/
|
||||||
DEBDIR=`pwd`/debian
|
DEBDIR=`pwd`/debian
|
||||||
|
|
||||||
git checkout master
|
git checkout 2.4.x
|
||||||
git pull
|
git pull
|
||||||
|
|
||||||
echo "cleaning up previous build..."
|
echo "cleaning up previous build..."
|
||||||
|
|
|
@ -18,7 +18,6 @@ PIDFILE=/var/run/airtime-liquidsoap.pid
|
||||||
EXEC='/usr/bin/airtime-liquidsoap'
|
EXEC='/usr/bin/airtime-liquidsoap'
|
||||||
|
|
||||||
start () {
|
start () {
|
||||||
|
|
||||||
mkdir -p /var/log/airtime/pypo-liquidsoap
|
mkdir -p /var/log/airtime/pypo-liquidsoap
|
||||||
chown $USERID:$GROUPID /var/log/airtime/pypo-liquidsoap
|
chown $USERID:$GROUPID /var/log/airtime/pypo-liquidsoap
|
||||||
|
|
||||||
|
@ -36,9 +35,19 @@ start () {
|
||||||
}
|
}
|
||||||
|
|
||||||
stop () {
|
stop () {
|
||||||
|
timeout --version >/dev/null 2>&1
|
||||||
|
RESULT="$?"
|
||||||
|
|
||||||
#send term signal after 10 seconds
|
#send term signal after 10 seconds
|
||||||
timeout -s9 10s /usr/lib/airtime/airtime_virtualenv/bin/python \
|
if [ "$RESULT" = "0" ]; then
|
||||||
/usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
|
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.
|
# 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 --pidfile $PIDFILE
|
||||||
start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --exec $EXEC
|
start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --exec $EXEC
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
set httpd port 2812
|
set httpd port 2812
|
||||||
|
|
||||||
check process airtime-liquidsoap matching "airtime-liquidsoap.*airtime.*ls_script"
|
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
|
start program = "/etc/init.d/airtime-liquidsoap start" with timeout 30 seconds
|
||||||
stop program = "/etc/init.d/airtime-liquidsoap stop"
|
stop program = "/etc/init.d/airtime-liquidsoap stop"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
set httpd port 2812
|
set httpd port 2812
|
||||||
|
|
||||||
check process airtime-liquidsoap
|
check process airtime-liquidsoap with pidfile "/var/run/airtime-liquidsoap.pid"
|
||||||
with pidfile "/var/run/airtime-liquidsoap.pid"
|
if does not exist for 3 cycles then restart
|
||||||
start program = "/etc/init.d/airtime-liquidsoap start" with timeout 5 seconds
|
start program = "/etc/init.d/airtime-liquidsoap start" with timeout 5 seconds
|
||||||
stop program = "/etc/init.d/airtime-liquidsoap stop"
|
stop program = "/etc/init.d/airtime-liquidsoap stop"
|
||||||
|
|
196
python_apps/pypo/pypopush.py
Normal file
196
python_apps/pypo/pypopush.py
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import logging.config
|
||||||
|
import telnetlib
|
||||||
|
import calendar
|
||||||
|
import math
|
||||||
|
import traceback
|
||||||
|
import os
|
||||||
|
|
||||||
|
from pypofetch import PypoFetch
|
||||||
|
from pypoliqqueue import PypoLiqQueue
|
||||||
|
|
||||||
|
from Queue import Empty, Queue
|
||||||
|
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
from api_clients import api_client
|
||||||
|
from std_err_override import LogWriter
|
||||||
|
from configobj import ConfigObj
|
||||||
|
|
||||||
|
|
||||||
|
# configure logging
|
||||||
|
logging_cfg = os.path.join(os.path.dirname(__file__), "logging.cfg")
|
||||||
|
logging.config.fileConfig(logging_cfg)
|
||||||
|
logger = logging.getLogger()
|
||||||
|
LogWriter.override_std_err(logger)
|
||||||
|
|
||||||
|
#need to wait for Python 2.7 for this..
|
||||||
|
#logging.captureWarnings(True)
|
||||||
|
|
||||||
|
PUSH_INTERVAL = 2
|
||||||
|
|
||||||
|
|
||||||
|
def is_stream(media_item):
|
||||||
|
return media_item['type'] == 'stream_output_start'
|
||||||
|
|
||||||
|
def is_file(media_item):
|
||||||
|
return media_item['type'] == 'file'
|
||||||
|
|
||||||
|
class PypoPush(Thread):
|
||||||
|
def __init__(self, q, telnet_lock, pypo_liquidsoap, config):
|
||||||
|
Thread.__init__(self)
|
||||||
|
self.api_client = api_client.AirtimeApiClient()
|
||||||
|
self.queue = q
|
||||||
|
|
||||||
|
self.telnet_lock = telnet_lock
|
||||||
|
self.config = config
|
||||||
|
|
||||||
|
self.pushed_objects = {}
|
||||||
|
self.logger = logging.getLogger('push')
|
||||||
|
self.current_prebuffering_stream_id = None
|
||||||
|
self.queue_id = 0
|
||||||
|
|
||||||
|
self.future_scheduled_queue = Queue()
|
||||||
|
self.pypo_liquidsoap = pypo_liquidsoap
|
||||||
|
|
||||||
|
self.plq = PypoLiqQueue(self.future_scheduled_queue, \
|
||||||
|
self.pypo_liquidsoap, \
|
||||||
|
self.logger)
|
||||||
|
self.plq.daemon = True
|
||||||
|
self.plq.start()
|
||||||
|
|
||||||
|
|
||||||
|
def main(self):
|
||||||
|
loops = 0
|
||||||
|
heartbeat_period = math.floor(30 / PUSH_INTERVAL)
|
||||||
|
|
||||||
|
media_schedule = None
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
media_schedule = self.queue.get(block=True)
|
||||||
|
except Exception, e:
|
||||||
|
self.logger.error(str(e))
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
self.logger.debug(media_schedule)
|
||||||
|
#separate media_schedule list into currently_playing and
|
||||||
|
#scheduled_for_future lists
|
||||||
|
currently_playing, scheduled_for_future = \
|
||||||
|
self.separate_present_future(media_schedule)
|
||||||
|
|
||||||
|
self.pypo_liquidsoap.verify_correct_present_media(currently_playing)
|
||||||
|
self.future_scheduled_queue.put(scheduled_for_future)
|
||||||
|
|
||||||
|
if loops % heartbeat_period == 0:
|
||||||
|
self.logger.info("heartbeat")
|
||||||
|
loops = 0
|
||||||
|
loops += 1
|
||||||
|
|
||||||
|
|
||||||
|
def separate_present_future(self, media_schedule):
|
||||||
|
tnow = datetime.utcnow()
|
||||||
|
|
||||||
|
present = []
|
||||||
|
future = {}
|
||||||
|
|
||||||
|
sorted_keys = sorted(media_schedule.keys())
|
||||||
|
for mkey in sorted_keys:
|
||||||
|
media_item = media_schedule[mkey]
|
||||||
|
|
||||||
|
diff_td = tnow - media_item['start']
|
||||||
|
diff_sec = self.date_interval_to_seconds(diff_td)
|
||||||
|
|
||||||
|
if diff_sec >= 0:
|
||||||
|
present.append(media_item)
|
||||||
|
else:
|
||||||
|
future[mkey] = media_item
|
||||||
|
|
||||||
|
return present, future
|
||||||
|
|
||||||
|
def get_current_stream_id_from_liquidsoap(self):
|
||||||
|
response = "-1"
|
||||||
|
try:
|
||||||
|
self.telnet_lock.acquire()
|
||||||
|
tn = telnetlib.Telnet(self.config['ls_host'], self.config['ls_port'])
|
||||||
|
|
||||||
|
msg = 'dynamic_source.get_id\n'
|
||||||
|
tn.write(msg)
|
||||||
|
response = tn.read_until("\r\n").strip(" \r\n")
|
||||||
|
tn.write('exit\n')
|
||||||
|
tn.read_all()
|
||||||
|
except Exception, e:
|
||||||
|
self.logger.error("Error connecting to Liquidsoap: %s", e)
|
||||||
|
response = []
|
||||||
|
finally:
|
||||||
|
self.telnet_lock.release()
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
#def is_correct_current_item(self, media_item, liquidsoap_queue_approx, liquidsoap_stream_id):
|
||||||
|
#correct = False
|
||||||
|
#if media_item is None:
|
||||||
|
#correct = (len(liquidsoap_queue_approx) == 0 and liquidsoap_stream_id == "-1")
|
||||||
|
#else:
|
||||||
|
#if is_file(media_item):
|
||||||
|
#if len(liquidsoap_queue_approx) == 0:
|
||||||
|
#correct = False
|
||||||
|
#else:
|
||||||
|
#correct = liquidsoap_queue_approx[0]['start'] == media_item['start'] and \
|
||||||
|
#liquidsoap_queue_approx[0]['row_id'] == media_item['row_id'] and \
|
||||||
|
#liquidsoap_queue_approx[0]['end'] == media_item['end'] and \
|
||||||
|
#liquidsoap_queue_approx[0]['replay_gain'] == media_item['replay_gain']
|
||||||
|
#elif is_stream(media_item):
|
||||||
|
#correct = liquidsoap_stream_id == str(media_item['row_id'])
|
||||||
|
|
||||||
|
#self.logger.debug("Is current item correct?: %s", str(correct))
|
||||||
|
#return correct
|
||||||
|
|
||||||
|
def date_interval_to_seconds(self, interval):
|
||||||
|
"""
|
||||||
|
Convert timedelta object into int representing the number of seconds. If
|
||||||
|
number of seconds is less than 0, then return 0.
|
||||||
|
"""
|
||||||
|
seconds = (interval.microseconds + \
|
||||||
|
(interval.seconds + interval.days * 24 * 3600) * 10 ** 6) / float(10 ** 6)
|
||||||
|
|
||||||
|
return seconds
|
||||||
|
|
||||||
|
def stop_web_stream_all(self):
|
||||||
|
try:
|
||||||
|
self.telnet_lock.acquire()
|
||||||
|
tn = telnetlib.Telnet(self.config['LS_HOST'], self.config['LS_PORT'])
|
||||||
|
|
||||||
|
#msg = 'dynamic_source.read_stop_all xxx\n'
|
||||||
|
msg = 'http.stop\n'
|
||||||
|
self.logger.debug(msg)
|
||||||
|
tn.write(msg)
|
||||||
|
|
||||||
|
msg = 'dynamic_source.output_stop\n'
|
||||||
|
self.logger.debug(msg)
|
||||||
|
tn.write(msg)
|
||||||
|
|
||||||
|
msg = 'dynamic_source.id -1\n'
|
||||||
|
self.logger.debug(msg)
|
||||||
|
tn.write(msg)
|
||||||
|
|
||||||
|
tn.write("exit\n")
|
||||||
|
self.logger.debug(tn.read_all())
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
self.logger.error(str(e))
|
||||||
|
finally:
|
||||||
|
self.telnet_lock.release()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try: self.main()
|
||||||
|
except Exception, e:
|
||||||
|
top = traceback.format_exc()
|
||||||
|
self.logger.error('Pypo Push Exception: %s', top)
|
||||||
|
|
|
@ -378,11 +378,11 @@ class PypoFetch(Thread):
|
||||||
media_item['file_ready'] = False
|
media_item['file_ready'] = False
|
||||||
media_filtered[key] = media_item
|
media_filtered[key] = media_item
|
||||||
|
|
||||||
media_item['start'] = datetime.strptime(media_item['start'],
|
media_item['start'] = datetime.strptime(media_item['start'],
|
||||||
"%Y-%m-%d-%H-%M-%S")
|
"%Y-%m-%d-%H-%M-%S")
|
||||||
media_item['end'] = datetime.strptime(media_item['end'],
|
media_item['end'] = datetime.strptime(media_item['end'],
|
||||||
"%Y-%m-%d-%H-%M-%S")
|
"%Y-%m-%d-%H-%M-%S")
|
||||||
media_copy[media_item['start']] = media_item
|
media_copy[key] = media_item
|
||||||
|
|
||||||
self.media_prepare_queue.put(copy.copy(media_filtered))
|
self.media_prepare_queue.put(copy.copy(media_filtered))
|
||||||
except Exception, e: self.logger.error("%s", e)
|
except Exception, e: self.logger.error("%s", e)
|
||||||
|
|
|
@ -76,14 +76,6 @@ class PypoFile(Thread):
|
||||||
self.logger.debug("copying from %s to local cache %s" % (src, dst))
|
self.logger.debug("copying from %s to local cache %s" % (src, dst))
|
||||||
try:
|
try:
|
||||||
|
|
||||||
"""
|
|
||||||
List file as "ready" before it starts copying because by the
|
|
||||||
time Liquidsoap is ready to play this file, it should have at
|
|
||||||
least started copying (and can continue copying while
|
|
||||||
Liquidsoap reads from the beginning of the file)
|
|
||||||
"""
|
|
||||||
media_item['file_ready'] = True
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
copy will overwrite dst if it already exists
|
copy will overwrite dst if it already exists
|
||||||
"""
|
"""
|
||||||
|
@ -91,6 +83,8 @@ class PypoFile(Thread):
|
||||||
|
|
||||||
#make file world readable
|
#make file world readable
|
||||||
os.chmod(dst, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
|
os.chmod(dst, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
|
||||||
|
|
||||||
|
media_item['file_ready'] = True
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.logger.error("Could not copy from %s to %s" % (src, dst))
|
self.logger.error("Could not copy from %s to %s" % (src, dst))
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
|
|
@ -74,8 +74,9 @@ class PypoLiqQueue(Thread):
|
||||||
schedule_deque.append(media_schedule[i])
|
schedule_deque.append(media_schedule[i])
|
||||||
|
|
||||||
if len(keys):
|
if len(keys):
|
||||||
time_until_next_play = pure.date_interval_to_seconds(\
|
time_until_next_play = self.date_interval_to_seconds(
|
||||||
keys[0] - datetime.utcnow())
|
media_schedule[keys[0]]['start'] -
|
||||||
|
datetime.utcnow())
|
||||||
else:
|
else:
|
||||||
time_until_next_play = None
|
time_until_next_play = None
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ set_include_path(implode(PATH_SEPARATOR, array(
|
||||||
realpath($CC_CONFIG['phpDir'] . '/library')
|
realpath($CC_CONFIG['phpDir'] . '/library')
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
require_once($CC_CONFIG['phpDir'].'/application/common/Database.php');
|
||||||
require_once($CC_CONFIG['phpDir'].'/application/models/StoredFile.php');
|
require_once($CC_CONFIG['phpDir'].'/application/models/StoredFile.php');
|
||||||
require_once($CC_CONFIG['phpDir'].'/application/models/Preference.php');
|
require_once($CC_CONFIG['phpDir'].'/application/models/Preference.php');
|
||||||
require_once($CC_CONFIG['phpDir'].'/application/models/MusicDir.php');
|
require_once($CC_CONFIG['phpDir'].'/application/models/MusicDir.php');
|
||||||
|
@ -52,7 +53,8 @@ if(count($argv) != 2){
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $argv[1];
|
$id = $argv[1];
|
||||||
$file = Application_Model_StoredFile::Recall($id);
|
|
||||||
|
$file = Application_Model_StoredFile::RecallById($id);
|
||||||
// set id with -2 which is indicator for processing
|
// set id with -2 which is indicator for processing
|
||||||
$file->setSoundCloudFileId(SOUNDCLOUD_PROGRESS);
|
$file->setSoundCloudFileId(SOUNDCLOUD_PROGRESS);
|
||||||
$file->uploadToSoundCloud();
|
$file->uploadToSoundCloud();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue