Merge branch '2.4.x' into 2.4.x-saas

Conflicts:
	python_apps/pypo/liquidsoap_scripts/ls_script.liq
	utils/phone_home_stat.php
This commit is contained in:
Naomi Aro 2013-06-26 01:25:26 -04:00
commit f2d5fa96da
114 changed files with 9850 additions and 9170 deletions

View file

@ -8,7 +8,7 @@ Common Non-linked Code
- Web site: https://github.com/torvalds/linux
- License: GPLv2
* RabbitMQ (works with version 1.7.2 and above)
* RabbitMQ
- What is it: Interprocess Message Passing with Queuing
- Web site: http://www.rabbitmq.com/
- License: Mozilla Public License (http://www.rabbitmq.com/mpl.html)
@ -63,7 +63,7 @@ Non-linked code:
- Web site: http://httpd.apache.org/
- License: Apache 2.0. See http://httpd.apache.org/docs/2.2/license.html
* PostgreSQL 8.4
* PostgreSQL 9.1
- Web site: http://www.postgresql.org/
- License: The PostgreSQL License. See http://www.postgresql.org/about/licence
@ -137,7 +137,7 @@ Linked code:
- License: MIT
Non-linked code:
* Python 2.6
* Python 2.7
- Web site: http://www.python.org/
- License: PSF License. See http://docs.python.org/license.html
@ -158,11 +158,11 @@ Linked code:
- Compatible with GPLv3? Yes.
Non-linked code:
* Python 2.6
* Python 2.7
- Web site: http://www.python.org/
- License: PSF License. See http://docs.python.org/license.html
* ecasound 2.7.2
* ecasound 2.8.1
- What is it: Records audio from line-in
- Web site: http://www.eca.cx/ecasound/
- License: GPLv2
@ -177,10 +177,10 @@ Linked code:
- Compatible with GPLv3? Yes.
Non-linked code:
* Python 2.6
* Python 2.7
- Web site: http://www.python.org/
- License: PSF License. See http://docs.python.org/license.html
* Liquidsoap 1.0.1
* Liquidsoap 1.1.1
- Web site: http://savonet.sourceforge.net/
- License: GPLv2

View file

@ -523,6 +523,15 @@ class ApiController extends Zend_Controller_Action
}
//Updating a metadata change.
else {
//CC-5207 - restart media-monitor causes it to reevaluate all
//files in watched directories, and reset their cue-in/cue-out
//values. Since media-monitor has nothing to do with cue points
//let's unset it here. Note that on mode == "create", we still
//want media-monitor sending info about cue_out which by default
//will be equal to length of track until silan can take over.
unset($md['MDATA_KEY_CUE_IN']);
unset($md['MDATA_KEY_CUE_OUT']);
$file->setMetadata($md);
}
} elseif ($mode == "moved") {

View file

@ -24,7 +24,7 @@ class ErrorController extends Zend_Controller_Action
}
// Log exception, if logger available
if ($log = $this->getLog()) {
if (($log = $this->getLog())) {
$log->crit($this->view->message, $errors->exception);
}

View file

@ -393,7 +393,8 @@ class LibraryController extends Zend_Controller_Action
}
$c[0] = $c['item_id'];
}
$newPl->addAudioClips($contents, null, 'begining');
$newPl->addAudioClips($contents, null, 'before');
$newPl->setCreator(Application_Model_User::getCurrentUser()->getId());
$newPl->setDescription($originalPl->getDescription());
@ -425,6 +426,9 @@ class LibraryController extends Zend_Controller_Action
$request = $this->getRequest();
$file_id = $this->_getParam('id', null);
$file = Application_Model_StoredFile::RecallById($file_id);
@ -437,7 +441,15 @@ class LibraryController extends Zend_Controller_Action
$form->populate($file->getDbColMetadata());
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$js = $this->_getParam('data');
$serialized = array();
//need to convert from serialized jQuery array.
foreach ($js as $j) {
$serialized[$j["name"]] = $j["value"];
}
if ($form->isValid($serialized)) {
$formValues = $this->_getParam('data', null);
$formdata = array();

View file

@ -70,12 +70,11 @@ class ListenerstatController extends Zend_Controller_Action
$starts_epoch = $request->getParam("startTimestamp", $current_time - (60*60*24));
$ends_epoch = $request->getParam("endTimestamp", $current_time);
$mountName = $request->getParam("mountName", null);
$startsDT = DateTime::createFromFormat("U", $starts_epoch, new DateTimeZone("UTC"));
$endsDT = DateTime::createFromFormat("U", $ends_epoch, new DateTimeZone("UTC"));
$data = Application_Model_ListenerStat::getDataPointsWithinRange($startsDT->format("Y-m-d H:i:s"), $endsDT->format("Y-m-d H:i:s"), $mountName);
$data = Application_Model_ListenerStat::getDataPointsWithinRange($startsDT->format("Y-m-d H:i:s"), $endsDT->format("Y-m-d H:i:s"));
$this->_helper->json->sendJson($data);
}
}

View file

@ -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?"),
"This path is currently not accessible." => _("This path is currently not accessible."),
//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"),
"The stream is disabled" => _("The stream is disabled"),
"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'."),
"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"),
"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
//already in schedule/add-show.js
//"The show instance doesn't exist anymore!" => _("The show instance doesn't exist anymore!"),

View file

@ -30,6 +30,7 @@ class PreferenceController extends Zend_Controller_Action
$this->view->statusMsg = "";
$form = new Application_Form_Preferences();
$values = array();
if ($request->isPost()) {
$params = $request->getPost();
@ -137,11 +138,12 @@ class PreferenceController extends Zend_Controller_Action
$setting[$t['keyname']] = $t['value'];
}
$name_map = array('ogg' => 'Ogg Vorbis',
'aacplus' => 'AAC+',
$name_map = array(
'ogg' => 'Ogg Vorbis',
'fdkaac' => 'AAC+',
'aac' => 'AAC',
'opus' => 'Opus',
'mp3' => 'MP3'
'mp3' => 'MP3',
);
// get predefined type and bitrate from pref table
@ -162,7 +164,7 @@ class PreferenceController extends Zend_Controller_Action
$stream_bitrates = array();
foreach ($temp_bitrate as $type) {
if (intval($type) <= $max_bitrate) {
$stream_bitrates[trim($type)] = strtoupper(trim($type))." Kbit/s";
$stream_bitrates[trim($type)] = strtoupper(trim($type))." kbit/s";
}
}
@ -193,6 +195,7 @@ class PreferenceController extends Zend_Controller_Action
$s1_data = array();
$s2_data = array();
$s3_data = array();
$values = array();
foreach($postData as $k=>$v) {
$v = explode('=', urldecode($v));
if (strpos($v[0], "s1_data") !== false) {

View file

@ -600,6 +600,7 @@ class ScheduleController extends Zend_Controller_Action
$baseUrl = $this->getRequest()->getBaseUrl();
$url = $file->getRelativeFileUrl($baseUrl).'download/true';
$menu = array();
$menu[] = array('action' => array('type' => 'gourl', 'url' => $url),
'title' => _('Download'));

View file

@ -41,6 +41,7 @@ class UserController extends Zend_Controller_Action
if ($request->isPost()) {
$params = $request->getPost();
$postData = explode('&', $params['data']);
$formData = array();
foreach($postData as $k=>$v) {
$v = explode('=', $v);
$formData[$v[0]] = urldecode($v[1]);

View file

@ -39,7 +39,7 @@ class Application_Form_EditAudioMD extends Zend_Form
$this->addElement('text', 'track_number', array(
'label' => _('Track:'),
'class' => 'input_text',
'filters' => array('StringTrim')
'filters' => array('StringTrim'),
));
// Add genre field
@ -50,16 +50,17 @@ class Application_Form_EditAudioMD extends Zend_Form
));
// Add year field
$this->addElement('text', 'year', array(
'label' => _('Year:'),
'class' => 'input_text',
'filters' => array('StringTrim'),
'validators' => array(
$year = new Zend_Form_Element_Text('year');
$year->class = 'input_text';
$year->setLabel(_('Year:'))
->setFilters(array('StringTrim'))
->setValidators(array(
new Zend_Validate_StringLength(array('max' => 10)),
Application_Form_Helper_ValidationTypes::overrrideDateValidator("YYYY-MM-DD"),
Application_Form_Helper_ValidationTypes::overrrideDateValidator("YYYY-MM"),
Application_Form_Helper_ValidationTypes::overrrideDateValidator("YYYY")
)
));
$this->addElement($year);
// Add label field
$this->addElement('text', 'label', array(

View file

@ -541,7 +541,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
$isValid = false;
}
// length check
if (intval($d['sp_criteria_value']) >= pow(2,31)) {
if ($d['sp_criteria_value'] >= pow(2,31)) {
$element->addError(_("The value should be less then 2147483648"));
$isValid = false;
}

View file

@ -36,6 +36,7 @@
<script id="tmpl-pl-cues" type="text/template">
<div class="waveform-cues">
<div class="playlist-time-scale"></div>
<div class="playlist-tracks"></div>
<div class="playlist-controls">
<a class="btn btn-small btn_play"><i class="icon-play icon-white"></i><?php echo _("Play"); ?></a>
@ -61,10 +62,12 @@
<script id="tmpl-pl-fades" type="text/template">
<div class="waveform-fades">
<div class="playlist-time-scale"></div>
<div class="playlist-tracks"></div>
<div class="playlist-controls left-floated">
<a class="btn btn-small btn_play"><i class="icon-play icon-white"></i><?php echo _("Play"); ?></a>
<a class="btn btn-small btn_stop"><i class="icon-stop icon-white"></i><?php echo _("Stop"); ?></a>
<label class="audio audio_pos">00:00:00.0</label>
</div>
<div class="set-fade left-floated">
<a type="button" class="btn btn-small btn_cursor" data-state="cursor"><?php echo _("Cursor"); ?></a>

View file

@ -330,7 +330,7 @@ SQL;
{
list($value, $modifier) = $this->getLimitValueAndModifier();
if ($modifier == "items") {
$length = $value." ".$modifier;
$length = $value." "._("items");
} else {
$hour = "00";
$mins = "00";
@ -687,6 +687,10 @@ SQL;
{
$this->con->beginTransaction();
if (!isset($offset)) {
$offset = Application_Model_Preference::GetDefaultCrossfadeDuration();
}
try {
if (isset($id1)) {
$this->changeFadeInfo($id1, null, $fadeOut);
@ -1350,6 +1354,21 @@ SQL;
"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"),
"is" => _("is"),
"is not" => _("is not"),
"is greater than" => _("is greater than"),
"is less than" => _("is less than"),
"is in the range" => _("is in the range")
);
// Load criteria from db
$out = CcBlockcriteriaQuery::create()->orderByDbCriteria()->findByDbBlockId($this->id);
$storedCrit = array();
@ -1361,11 +1380,20 @@ SQL;
$extra = $crit->getDbExtra();
if ($criteria == "limit") {
$storedCrit["limit"] = array("value"=>$value, "modifier"=>$modifier);
$storedCrit["limit"] = array(
"value"=>$value,
"modifier"=>$modifier,
"display_modifier"=>_($modifier));
} else if($criteria == "repeat_tracks") {
$storedCrit["repeat_tracks"] = array("value"=>$value);
} 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]);
}
}

View file

@ -4,6 +4,7 @@ class Application_Model_Datatables
{
private static function buildWhereClauseForAdvancedSearch($dbname2searchTerm)
{
$where = array();
$where['clause'] = array();
$where['params'] = array();
foreach ($dbname2searchTerm as $dbname=>$term) {

View file

@ -62,6 +62,13 @@ SQL;
if (isset($out[$enabledMountPoint])) {
$enabledOut[$enabledMountPoint] = $out[$enabledMountPoint];
}
else {
//TODO fix this hack (here for CC-5254)
//all shoutcast streams are automatically put under "shoutcast" mount point.
if (isset($out["shoutcast"])) {
$enabledOut["shoutcast"] = $out["shoutcast"];
}
}
}
return $enabledOut;

View file

@ -154,8 +154,6 @@ class Application_Model_Playlist implements Application_Model_LibraryEditable
*/
public function getContents($filterFiles=false)
{
Logging::info("Getting contents for playlist {$this->id}");
$sql = <<<SQL
SELECT *
FROM (
@ -415,22 +413,40 @@ SQL;
$entry["id"] = $obj->getDbId();
$entry["pos"] = $pos;
$entry["cliplength"] = $obj->getDbLength();
if ($obj instanceof CcFiles && $obj) {
$entry["cuein"] = $obj->getDbCuein();
$entry["cueout"] = $obj->getDbCueout();
$cue_out = Application_Common_DateHelper::calculateLengthInSeconds($entry['cueout']);
$cue_in = Application_Common_DateHelper::calculateLengthInSeconds($entry['cuein']);
$entry["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cue_out-$cue_in);
} elseif ($obj instanceof CcWebstream && $obj) {
if ($obj instanceof CcFiles && $obj) {
$entry["cuein"] = isset($p_item['cuein']) ?
$p_item['cuein'] : $obj->getDbCuein();
$entry["cueout"] = isset($p_item['cueout']) ?
$p_item['cueout'] : $obj->getDbCueout();
$cue_in = isset($p_item['cueInSec']) ?
$p_item['cueInSec'] : Application_Common_DateHelper::calculateLengthInSeconds($entry['cuein']);
$cue_out = isset($p_item['cueOutSec']) ?
$p_item['cueOutSec'] : Application_Common_DateHelper::calculateLengthInSeconds($entry['cueout']);
$entry["cliplength"] = isset($p_item['length']) ?
$p_item['length'] : Application_Common_DateHelper::secondsToPlaylistTime($cue_out-$cue_in);
}
elseif ($obj instanceof CcWebstream && $obj) {
$entry["cuein"] = "00:00:00";
$entry["cueout"] = $entry["cliplength"];
}
$entry["ftype"] = $objType;
$entry["fadein"] = isset($p_item['fadein']) ?
$p_item['fadein'] : $entry["fadein"];
$entry["fadeout"] = isset($p_item['fadeout']) ?
$p_item['fadeout'] : $entry["fadeout"];
}
return $entry;
} else {
}
else {
throw new Exception("trying to add a object that does not exist.");
}
}
@ -451,11 +467,10 @@ SQL;
try {
if (is_numeric($p_afterItem)) {
Logging::info("Finding playlist content item {$p_afterItem}");
$afterItem = CcPlaylistcontentsQuery::create()->findPK($p_afterItem);
$index = $afterItem->getDbPosition();
Logging::info("index is {$index}");
$pos = ($addType == 'after') ? $index + 1 : $index;
$contentsToUpdate = CcPlaylistcontentsQuery::create()
@ -488,9 +503,6 @@ SQL;
}
Logging::info("Adding to playlist");
Logging::info("at position {$pos}");
foreach ($p_items as $ac) {
$res = $this->insertPlaylistElement($this->buildEntry($ac, $pos));
@ -500,8 +512,6 @@ SQL;
$db_file->setDbIsPlaylist(true)->save($this->con);
$pos = $pos + 1;
Logging::info("Adding $ac[1] $ac[0]");
}
//reset the positions of the remaining items.
@ -673,6 +683,10 @@ SQL;
{
$this->con->beginTransaction();
if (!isset($offset)) {
$offset = Application_Model_Preference::GetDefaultCrossfadeDuration();
}
try {
if (isset($id1)) {
$this->changeFadeInfo($id1, null, $fadeOut);
@ -729,7 +743,6 @@ SQL;
if (!is_null($offset)) {
$row->setDbTrackOffset($offset);
Logging::info("Setting offset {$offset} on item {$id}");
$row->save($this->con);
}
}
@ -1071,8 +1084,7 @@ SQL;
$sql .= "END WHERE position IN ($currentPos) and playlist_id=:p1";
Application_Common_Database::prepareAndExecute($sql, array("p1"=>$this->id));
$result['result'] = 0;
return $result;
return array('result' => 0);
}
public static function getAllPlaylistFiles()

View file

@ -38,9 +38,11 @@ class Application_Model_Preference
$paramMap[':id'] = $userId;
}
Application_Common_Database::prepareAndExecute("LOCK TABLE cc_pref");
$result = Application_Common_Database::prepareAndExecute($sql,
$paramMap,
'column',
Application_Common_Database::COLUMN,
PDO::FETCH_ASSOC,
$con);

View file

@ -322,7 +322,8 @@ SQL;
ft.album_title AS file_album_title,
ft.length AS file_length,
ft.file_exists AS file_exists,
ft.mime AS file_mime
ft.mime AS file_mime,
ft.soundcloud_id AS soundcloud_id
SQL;
$filesJoin = <<<SQL
cc_schedule AS sched
@ -357,7 +358,8 @@ SQL;
ws.description AS file_album_title,
ws.length AS file_length,
't'::BOOL AS file_exists,
ws.mime as file_mime
ws.mime AS file_mime,
(SELECT NULL::integer AS soundcloud_id)
SQL;
$streamJoin = <<<SQL
cc_schedule AS sched
@ -396,7 +398,7 @@ SQL;
$map = array();
for ($i = 0, $len = count($p_shows); $i < $len; $i++) {
$holder = "show_".$i;
$holder = ":show_".$i;
$params[] = $holder;
$map[$holder] = $p_shows[$i];

View file

@ -85,6 +85,9 @@ class Application_Model_Scheduler
$nowEpoch = floatval($this->nowDT->format("U.u"));
$schedInfo = array();
$instanceInfo = array();
for ($i = 0; $i < count($items); $i++) {
$id = $items[$i]["id"];
@ -103,7 +106,7 @@ class Application_Model_Scheduler
}
$schedIds = array();
if (isset($schedInfo)) {
if (count($schedInfo) > 0) {
$schedIds = array_keys($schedInfo);
}
$schedItems = CcScheduleQuery::create()->findPKs($schedIds, $this->con);
@ -191,16 +194,18 @@ class Application_Model_Scheduler
if ($type === "audioclip") {
$file = CcFilesQuery::create()->findPK($id, $this->con);
$storedFile = new Application_Model_StoredFile($file, $this->con);
if (is_null($file) || !$file->visible()) {
throw new Exception(_("A selected File does not exist!"));
} else {
$data = $this->fileInfo;
$data["id"] = $id;
$data["cliplength"] = $storedFile->getRealClipLength(
$file->getDbCuein(),
$file->getDbCueout());
$cuein = Application_Common_DateHelper::playlistTimeToSeconds($file->getDbCuein());
$cueout = Application_Common_DateHelper::playlistTimeToSeconds($file->getDbCueout());
$row_length = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
$data["cliplength"] = $row_length;
$data["cuein"] = $file->getDbCuein();
$data["cueout"] = $file->getDbCueout();
@ -388,7 +393,7 @@ class Application_Model_Scheduler
return $dt;
}
private function findNextStartTime($DT, $instance)
private function findNextStartTime($DT, $instanceId)
{
$sEpoch = $DT->format("U.u");
$nEpoch = $this->epochNow;
@ -410,7 +415,7 @@ class Application_Model_Scheduler
->setDbCueIn('00:00:00')
->setDbCueOut('00:00:00')
->setDbPlayoutStatus(-1)
->setDbInstanceId($instance->getDbId())
->setDbInstanceId($instanceId)
->save($this->con);
} else {
$nextDT = $DT;
@ -424,33 +429,39 @@ class Application_Model_Scheduler
* This function recalculates the start/end times of items in a gapless show to
* account for crossfade durations.
*/
private function calculateCrossfades($showInstance)
private function calculateCrossfades($instanceId)
{
Logging::info("adjusting start, end times of scheduled items to account for crossfades show instance #".$showInstance);
Logging::info("adjusting start, end times of scheduled items to account for crossfades show instance #".$instanceId);
$sql = "SELECT * FROM cc_show_instances ".
"WHERE id = {$instanceId}";
$instance = Application_Common_Database::prepareAndExecute(
$sql, array(), Application_Common_Database::SINGLE);
$instance = CcShowInstancesQuery::create()->findPK($showInstance, $this->con);
if (is_null($instance)) {
throw new OutDatedScheduleException(_("The schedule you're viewing is out of date!"));
}
$itemStartDT = $instance->getDbStarts(null);
$itemStartDT = new DateTime($instance["starts"], new DateTimeZone("UTC"));
$itemEndDT = null;
$schedule = CcScheduleQuery::create()
->filterByDbInstanceId($showInstance)
->orderByDbStarts()
->find($this->con);
$schedule_sql = "SELECT * FROM cc_schedule ".
"WHERE instance_id = {$instanceId} ".
"ORDER BY starts";
$schedule = Application_Common_Database::prepareAndExecute($schedule_sql);
foreach ($schedule as $item) {
$itemEndDT = $this->findEndTime($itemStartDT, $item->getDbClipLength());
$itemEndDT = $this->findEndTime($itemStartDT, $item["clip_length"]);
$item->setDbStarts($itemStartDT)
->setDbEnds($itemEndDT);
$update_sql = "UPDATE cc_schedule SET ".
"starts = '{$itemStartDT->format("Y-m-d H:i:s")}', ".
"ends = '{$itemEndDT->format("Y-m-d H:i:s")}' ".
"WHERE id = {$item["id"]}";
Application_Common_Database::prepareAndExecute(
$update_sql, array(), Application_Common_Database::EXECUTE);
$itemStartDT = $this->findTimeDifference($itemEndDT, $this->crossfadeDuration);
}
$schedule->save($this->con);
}
/*
@ -531,12 +542,18 @@ class Application_Model_Scheduler
* of inserted items
*/
if ($id != 0) {
$ccSchedule = CcScheduleQuery::create()->findPk($id);
$ccShowInstance = CcShowInstancesQuery::create()->findPk($ccSchedule->getDbInstanceId());
$ccShow = $ccShowInstance->getCcShow();
$linked = $ccShow->isLinked();
$schedule_sql = "SELECT * FROM cc_schedule WHERE id = ".$id;
$ccSchedule = Application_Common_Database::prepareAndExecute(
$schedule_sql, array(), Application_Common_Database::SINGLE);
$show_sql = "SELECT * FROM cc_show WHERE id IN (".
"SELECT show_id FROM cc_show_instances WHERE id = ".$ccSchedule["instance_id"].")";
$ccShow = Application_Common_Database::prepareAndExecute(
$show_sql, array(), Application_Common_Database::SINGLE);
$linked = $ccShow["linked"];
if ($linked) {
$unique = $ccShow->getDbId() . $ccSchedule->getDbPosition();
$unique = $ccShow["id"] . $ccSchedule["position"];
if (!in_array($unique, $temp)) {
$temp[] = $unique;
} else {
@ -544,11 +561,14 @@ class Application_Model_Scheduler
}
}
} else {
$ccShowInstance = CcShowInstancesQuery::create()->findPk($schedule["instance"]);
$ccShow = $ccShowInstance->getccShow();
$linked = $ccShow->isLinked();
$show_sql = "SELECT * FROM cc_show WHERE id IN (".
"SELECT show_id FROM cc_show_instances WHERE id = ".$schedule["instance"].")";
$ccShow = Application_Common_Database::prepareAndExecute(
$show_sql, array(), Application_Common_Database::SINGLE);
$linked = $ccShow["linked"];
if ($linked) {
$unique = $ccShow->getDbId() . "a";
$unique = $ccShow["id"] . "a";
if (!in_array($unique, $temp)) {
$temp[] = $unique;
} else {
@ -562,38 +582,59 @@ class Application_Model_Scheduler
* to that show
*/
if ($linked) {
$instances = $ccShow->getCcShowInstancess();
$instance_sql = "SELECT * FROM cc_show_instances ".
"WHERE show_id = ".$ccShow["id"];
$instances = Application_Common_Database::prepareAndExecute(
$instance_sql);
} else {
$instances = array($ccShowInstance);
$instance_sql = "SELECT * FROM cc_show_instances ".
"WHERE id = ".$schedule["instance"];
$instances = Application_Common_Database::prepareAndExecute(
$instance_sql);
}
$excludePositions = array();
foreach($instances as &$instance) {
$instanceId = $instance->getDbId();
$instanceId = $instance["id"];
if ($id !== 0) {
/* We use the selected cursor's position to find the same
* positions in every other linked instance
*/
$pos = $ccSchedule->getDbPosition();
$pos = $ccSchedule["position"];
$linkCcSchedule = CcScheduleQuery::create()
->filterByDbInstanceId($instanceId)
->filterByDbPosition($pos)
->findOne();
$linkedItem_sql = "SELECT ends FROM cc_schedule ".
"WHERE instance_id = {$instanceId} ".
"AND position = {$pos} ".
"AND playout_status != -1";
$linkedItemEnds = Application_Common_Database::prepareAndExecute(
$linkedItem_sql, array(), Application_Common_Database::COLUMN);
$schedItemEndDT = $linkCcSchedule->getDbEnds(null);
$nextStartDT = $this->findNextStartTime($schedItemEndDT, $instance);
$nextStartDT = $this->findNextStartTime(
new DateTime($linkedItemEnds, new DateTimeZone("UTC")),
$instanceId);
$pos++;
/* Show is not empty so we need to apply crossfades
* for the first inserted item
*/
$applyCrossfades = true;
}
//selected empty row to add after
else {
$showStartDT = $instance->getDbStarts(null);
$nextStartDT = $this->findNextStartTime($showStartDT, $instance);
$showStartDT = new DateTime($instance["starts"], new DateTimeZone("UTC"));
$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;
/* Show is empty so we don't need to calculate crossfades
* for the first inserted item
*/
$applyCrossfades = false;
}
if (!in_array($instance->getDbId(), $affectedShowInstances)) {
if (!in_array($instanceId, $affectedShowInstances)) {
$affectedShowInstances[] = $instanceId;
}
@ -605,7 +646,12 @@ class Application_Model_Scheduler
$pstart = microtime(true);
if ($applyCrossfades) {
$initalStartDT = clone $this->findTimeDifference(
$nextStartDT, $this->crossfadeDuration);
} else {
$initalStartDT = clone $nextStartDT;
}
$pend = microtime(true);
Logging::debug("finding all following items.");
@ -620,83 +666,129 @@ class Application_Model_Scheduler
}
}
$doInsert = false;
$doUpdate = false;
$values = array();
foreach ($filesToInsert as &$file) {
//item existed previously and is being moved.
//need to keep same id for resources if we want REST.
if (isset($file['sched_id'])) {
$sched = CcScheduleQuery::create()->findPk($file["sched_id"]);
$adjustFromDT = clone $nextStartDT;
$doUpdate = true;
$movedItem_sql = "SELECT * FROM cc_schedule ".
"WHERE id = ".$file["sched_id"];
$sched = Application_Common_Database::prepareAndExecute(
$movedItem_sql, array(), Application_Common_Database::SINGLE);
/* We need to keep a record of the original positon a track
* is being moved from so we can use it to retrieve the correct
* items in linked instances
*/
if (!isset($originalPosition)) {
$originalPosition = $sched->getDbPosition();
$originalPosition = $sched["position"];
}
/* If we are moving an item in a linked show we need to get
* the relative item to move in each instance. We know what the
* relative item is by its position
*/
if ($linked && $moveAction) {
$sched = CcScheduleQuery::create()
->filterByDbInstanceId($instanceId)
->filterByDbPosition($originalPosition)
->findOne();
}
$excludeIds[] = intval($sched->getDbId());
if ($linked) {
$movedItem_sql = "SELECT * FROM cc_schedule ".
"WHERE position = {$originalPosition} ".
"AND instance_id = {$instanceId}";
$file["cliplength"] = $sched->getDbClipLength();
$file["cuein"] = $sched->getDbCueIn();
$file["cueout"] = $sched->getDbCueOut();
$file["fadein"] = $sched->getDbFadeIn();
$file["fadeout"] = $sched->getDbFadeOut();
$sched = Application_Common_Database::prepareAndExecute(
$movedItem_sql, array(), Application_Common_Database::SINGLE);
}
$excludeIds[] = intval($sched["id"]);
$file["cliplength"] = $sched["clip_length"];
$file["cuein"] = $sched["cue_in"];
$file["cueout"] = $sched["cue_out"];
$file["fadein"] = $sched["fade_in"];
$file["fadeout"] = $sched["fade_out"];
} else {
$sched = new CcSchedule();
$doInsert = true;
}
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
// default fades are in seconds
// we need to convert to '00:00:00' format
$file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']);
$file['fadeout'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadeout']);
$sched->setDbStarts($nextStartDT)
->setDbEnds($endTimeDT)
->setDbCueIn($file['cuein'])
->setDbCueOut($file['cueout'])
->setDbFadeIn($file['fadein'])
->setDbFadeOut($file['fadeout'])
->setDbClipLength($file['cliplength'])
->setDbPosition($pos);
if (!$moveAction) {
$sched->setDbInstanceId($instanceId);
}
switch ($file["type"]) {
case 0:
$sched->setDbFileId($file['id']);
$fileId = $file["id"];
$streamId = "null";
break;
case 1:
$sched->setDbStreamId($file['id']);
$streamId = $file["id"];
$fileId = "null";
break;
default: break;
}
$sched->save($this->con);
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;
}
$nextStartDT = $endTimeDT;
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
if ($doInsert) {
$values[] = "(".
"'{$nextStartDT->format("Y-m-d H:i:s")}', ".
"'{$endTimeDT->format("Y-m-d H:i:s")}', ".
"'{$file["cuein"]}', ".
"'{$file["cueout"]}', ".
"'{$file["fadein"]}', ".
"'{$file["fadeout"]}', ".
"'{$file["cliplength"]}', ".
"{$pos}, ".
"{$instanceId}, ".
"{$fileId}, ".
"{$streamId})";
} elseif ($doUpdate) {
$update_sql = "UPDATE cc_schedule SET ".
"starts = '{$nextStartDT->format("Y-m-d H:i:s")}', ".
"ends = '{$endTimeDT->format("Y-m-d H:i:s")}', ".
"cue_in = '{$file["cuein"]}', ".
"cue_out = '{$file["cueout"]}', ".
"fade_in = '{$file["fadein"]}', ".
"fade_out = '{$file["fadeout"]}', ".
"clip_length = '{$file["cliplength"]}', ".
"position = {$pos} ".
"WHERE id = {$sched["id"]}";
Application_Common_Database::prepareAndExecute(
$update_sql, array(), Application_Common_Database::EXECUTE);
}
$nextStartDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
$pos++;
/* If we are adjusting start and end times for items
* after the insert location, we need to exclude the
* schedule item we just inserted because it has correct
* start and end times*/
$excludeIds[] = $sched->getDbId();
}//all files have been inserted/moved
if ($doInsert) {
$insert_sql = "INSERT INTO cc_schedule ".
"(starts, ends, cue_in, cue_out, fade_in, fade_out, ".
"clip_length, position, instance_id, file_id, stream_id) VALUES ".
implode($values, ",")." RETURNING id";
$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
$fileIds = array();
foreach ($filesToInsert as &$file) {
@ -717,34 +809,43 @@ class Application_Model_Scheduler
}
if ($adjustSched === true) {
$followingSchedItems = CcScheduleQuery::create()
->filterByDBStarts($initalStartDT->format("Y-m-d H:i:s.u"), Criteria::GREATER_EQUAL)
->filterByDbInstanceId($instance->getDbId())
->filterByDbId($excludeIds, Criteria::NOT_IN)
->orderByDbStarts()
->find($this->con);
$followingItems_sql = "SELECT * FROM cc_schedule ".
"WHERE starts >= '{$initalStartDT->format("Y-m-d H:i:s.u")}' ".
"AND instance_id = {$instanceId} ";
if (count($excludeIds) > 0) {
$followingItems_sql .= "AND id NOT IN (". implode($excludeIds, ",").") ";
}
$followingItems_sql .= "ORDER BY starts";
$followingSchedItems = Application_Common_Database::prepareAndExecute(
$followingItems_sql);
$pstart = microtime(true);
//recalculate the start/end times after the inserted items.
foreach ($followingSchedItems as $item) {
$endTimeDT = $this->findEndTime($nextStartDT, $item->getDbClipLength());
$item->setDbStarts($nextStartDT);
$item->setDbEnds($endTimeDT);
$item->setDbPosition($pos);
$item->save($this->con);
$nextStartDT = $endTimeDT;
$endTimeDT = $this->findEndTime($nextStartDT, $item["clip_length"]);
$endTimeDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
$update_sql = "UPDATE cc_schedule SET ".
"starts = '{$nextStartDT->format("Y-m-d H:i:s")}', ".
"ends = '{$endTimeDT->format("Y-m-d H:i:s")}', ".
"position = {$pos} ".
"WHERE id = {$item["id"]}";
Application_Common_Database::prepareAndExecute(
$update_sql, array(), Application_Common_Database::EXECUTE);
$nextStartDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
$pos++;
}
$pend = microtime(true);
Logging::debug("adjusting all following items.");
Logging::debug(floatval($pend) - floatval($pstart));
$this->calculateCrossfades($instance->getDbId());
}
if ($moveAction) {
$this->calculateCrossfades($instanceId);
}
}//for each instance
}//for each schedule location
$endProfile = microtime(true);
@ -782,6 +883,11 @@ class Application_Model_Scheduler
}
}
private function updateMovedItem()
{
}
private function getInstances($instanceId)
{
$ccShowInstance = CcShowInstancesQuery::create()->findPk($instanceId);

View file

@ -388,6 +388,7 @@ class Application_Model_ShowBuilder
$outdated = false;
$shows = Application_Model_Show::getShows($this->startDT, $this->endDT);
$include = array();
if ($this->opts["showFilter"] !== 0) {
$include[] = $this->opts["showFilter"];
} elseif ($this->opts["myShows"] === 1) {

View file

@ -352,10 +352,10 @@ SQL;
);
//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"));
$utcEndDateTime = new DateTime($new_ends, new DateTimeZone("UTC"));
$utcEndDateTime = new DateTime($now_ends, new DateTimeZone("UTC"));
$overlap = Application_Model_Show::getShows($utcStartDateTime, $utcEndDateTime);
@ -381,7 +381,7 @@ SQL;
}
$this->setShowEnd($new_ends);
$this->setShowEnd($now_ends);
Application_Model_RabbitMq::PushSchedule();
}

View file

@ -528,8 +528,6 @@ SQL;
*/
public function getRelativeFileUrl($baseUrl)
{
Logging::debug("Zend base url: $baseUrl");
return $baseUrl."api/get-media/file/".$this->getId().".".$this->getFileExtension();
}
@ -780,8 +778,7 @@ SQL;
foreach ($results['aaData'] as &$row) {
$row['id'] = intval($row['id']);
$len_formatter = new LengthFormatter($row['length']);
$row['length'] = $len_formatter->format();
if ($row['ftype'] === "audioclip") {
$cuein_formatter = new LengthFormatter($row["cuein"]);
$row["cuein"] = $cuein_formatter->format();
@ -789,7 +786,10 @@ SQL;
$cueout_formatter = new LengthFormatter($row["cueout"]);
$row["cueout"] = $cueout_formatter->format();
if ($row['ftype'] === "audioclip") {
$cuein = Application_Common_DateHelper::playlistTimeToSeconds($row["cuein"]);
$cueout = Application_Common_DateHelper::playlistTimeToSeconds($row["cueout"]);
$row_length = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
$formatter = new SamplerateFormatter($row['sample_rate']);
$row['sample_rate'] = $formatter->format();
@ -798,13 +798,20 @@ SQL;
//soundcloud status
$file = Application_Model_StoredFile::RecallById($row['id']);
$row['soundcloud_status'] = $file->getSoundCloudId();
$row['soundcloud_id'] = $file->getSoundCloudId();
// for audio preview
$row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION);
} else {
$row['audioFile'] = $row['id'];
}
else {
$row['audioFile'] = $row['id'];
$row_length = $row['length'];
}
$len_formatter = new LengthFormatter($row_length);
$row['length'] = $len_formatter->format();
//convert mtime and utime to localtime
$row['mtime'] = new DateTime($row['mtime'], new DateTimeZone('UTC'));
@ -895,7 +902,7 @@ SQL;
$in = fopen($_FILES['file']['tmp_name'], "rb");
if ($in) {
while ($buff = fread($in, 4096))
while (($buff = fread($in, 4096)))
fwrite($out, $buff);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}');
@ -914,7 +921,7 @@ SQL;
$in = fopen("php://input", "rb");
if ($in) {
while ($buff = fread($in, 4096))
while (($buff = fread($in, 4096)))
fwrite($out, $buff);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}');
@ -963,6 +970,7 @@ SQL;
// Check if we have enough space before copying
if (!self::isEnoughDiskSpaceToCopy($stor, $audio_file)) {
$freeSpace = disk_free_space($stor);
$fileSize = filesize($audio_file);
return array("code" => 107,
"message" => sprintf(_("The file was not uploaded, there is "
@ -1257,7 +1265,7 @@ SQL;
$description = $file->getDbTrackTitle();
$tag = array();
$genre = $file->getDbGenre();
$release = $file->getDbYear();
$release = $file->getDbUtime();
try {
$soundcloud = new Application_Model_Soundcloud();
$soundcloud_res = $soundcloud->uploadTrack(
@ -1347,14 +1355,6 @@ SQL;
Application_Common_Database::prepareAndExecute($sql, array(),
Application_Common_Database::EXECUTE);
}
public function getRealClipLength($p_cuein, $p_cueout) {
$sql = "SELECT :cueout::INTERVAL - :cuein::INTERVAL";
return Application_Common_Database::prepareAndExecute($sql, array(
':cueout' => $p_cueout,
':cuein' => $p_cuein), 'column');
}
}
class DeleteScheduledFileException extends Exception {}

View file

@ -125,6 +125,7 @@ class Application_Model_Systemstatus
public static function GetPlatformInfo()
{
$keys = array("release", "machine", "memory", "swap");
$data = array();
foreach ($keys as $key) {
$data[$key] = "UNKNOWN";
}
@ -212,7 +213,7 @@ class Application_Model_Systemstatus
public static function GetDiskInfo()
{
$partions = array();
$partitions = array();
//connect to DB and find how much total space user has allocated.
$totalSpace = Application_Model_Preference::GetDiskQuota();

View file

@ -226,7 +226,7 @@ class Application_Model_User
public function deleteAllFiles()
{
$my_files = $this->getOwnedFiles();
foreach ($files as $file) {
foreach ($my_files as $file) {
$file->delete();
}
}

View file

@ -57,6 +57,14 @@ class CcFiles extends BaseCcFiles {
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
public function visible() {
return $this->getDbFileExists() && !$this->getDbHidden();

View file

@ -77,9 +77,9 @@ class Application_Service_CalendarService
//Show content can be modified from the calendar if:
// the show has not started,
// the user is admin or hosting the show,
// the show is not recorded or rebroadcasted
// the show is not recorded
if ($now < $start && ($isAdminOrPM || $isHostOfShow) &&
!$this->ccShowInstance->isRecorded() && !$this->ccShowInstance->isRebroadcast()) {
!$this->ccShowInstance->isRecorded() ) {
$menu["schedule"] = array(
"name"=> _("Add / Remove Content"),
@ -117,7 +117,7 @@ class Application_Service_CalendarService
}
$isRepeating = $this->ccShow->getFirstCcShowDay()->isRepeating();
if (!$this->ccShowInstance->isRebroadcast()) {
if (!$this->ccShowInstance->isRebroadcast() && $isAdminOrPM) {
if ($isRepeating) {
$menu["edit"] = array(
"name" => _("Edit"),

View file

@ -148,6 +148,24 @@ class Application_Service_SchedulerService
return $dt;
}
private static function findTimeDifference($p_startDT, $p_seconds)
{
$startEpoch = $p_startDT->format("U.u");
//add two float numbers to 6 subsecond precision
//DateTime::createFromFormat("U.u") will have a problem if there is no decimal in the resulting number.
$newEpoch = bcsub($startEpoch , (string) $p_seconds, 6);
$dt = DateTime::createFromFormat("U.u", $newEpoch, new DateTimeZone("UTC"));
if ($dt === false) {
//PHP 5.3.2 problem
$dt = DateTime::createFromFormat("U", intval($newEpoch), new DateTimeZone("UTC"));
}
return $dt;
}
public static function fillNewLinkedInstances($ccShow)
{
/* First check if any linked instances have content
@ -155,64 +173,98 @@ class Application_Service_SchedulerService
* any other instances with content
*/
$instanceIds = $ccShow->getInstanceIds();
$ccSchedules = CcScheduleQuery::create()
->filterByDbInstanceId($instanceIds, Criteria::IN)
->find();
if (!$ccSchedules->isEmpty()) {
$schedule_sql = "SELECT * FROM cc_schedule ".
"WHERE instance_id IN (".implode($instanceIds, ",").")";
$ccSchedules = Application_Common_Database::prepareAndExecute(
$schedule_sql);
if (count($ccSchedules) > 0) {
/* Find the show contents of just one of the instances. It doesn't
* matter which instance we use since all the content is the same
*/
$ccSchedule = $ccSchedules->getFirst();
$showStamp = CcScheduleQuery::create()
->filterByDbInstanceId($ccSchedule->getDbInstanceId())
->orderByDbStarts()
->find();
$ccSchedule = $ccSchedules[0];
$showStamp_sql = "SELECT * FROM cc_schedule ".
"WHERE instance_id = {$ccSchedule["instance_id"]} ".
"ORDER BY starts";
$showStamp = Application_Common_Database::prepareAndExecute(
$showStamp_sql);
//get time_filled so we can update cc_show_instances
$timeFilled = $ccSchedule->getCcShowInstances()->getDbTimeFilled();
$timeFilled_sql = "SELECT time_filled FROM cc_show_instances ".
"WHERE id = {$ccSchedule["instance_id"]}";
$timeFilled = Application_Common_Database::prepareAndExecute(
$timeFilled_sql, array(), Application_Common_Database::COLUMN);
//need to find out which linked instances are empty
foreach ($ccShow->getCcShowInstancess() as $ccShowInstance) {
$ccSchedules = CcScheduleQuery::create()
->filterByDbInstanceId($ccShowInstance->getDbId())
->find();
$values = array();
foreach ($instanceIds as $id) {
$instanceSched_sql = "SELECT * FROM cc_schedule ".
"WHERE instance_id = {$id} ".
"ORDER by starts";
$ccSchedules = Application_Common_Database::prepareAndExecute(
$instanceSched_sql);
/* If the show instance is empty OR it has different content than
* the first instance, we cant to fill/replace with the show stamp
* the first instance, we need to fill/replace with the show stamp
* (The show stamp is taken from the first show instance's content)
*/
if ($ccSchedules->isEmpty() ||
self::replaceInstanceContentCheck($ccShowInstance, $showStamp)) {
if (count($ccSchedules) < 1 ||
self::replaceInstanceContentCheck($ccSchedules, $showStamp)) {
$nextStartDT = $ccShowInstance->getDbStarts(null);
$instanceStart_sql = "SELECT starts FROM cc_show_instances ".
"WHERE id = {$id} ".
"ORDER BY starts";
$nextStartDT = new DateTime(
Application_Common_Database::prepareAndExecute(
$instanceStart_sql, array(), Application_Common_Database::COLUMN),
new DateTimeZone("UTC"));
foreach ($showStamp as $item) {
$endTimeDT = self::findEndTime($nextStartDT, $item->getDbClipLength());
$endTimeDT = self::findEndTime($nextStartDT, $item["clip_length"]);
$ccSchedule = new CcSchedule();
$ccSchedule
->setDbStarts($nextStartDT)
->setDbEnds($endTimeDT)
->setDbFileId($item->getDbFileId())
->setDbStreamId($item->getDbStreamId())
->setDbClipLength($item->getDbClipLength())
->setDbFadeIn($item->getDbFadeIn())
->setDbFadeOut($item->getDbFadeOut())
->setDbCuein($item->getDbCueIn())
->setDbCueOut($item->getDbCueOut())
->setDbInstanceId($ccShowInstance->getDbId())
->setDbPosition($item->getDbPosition())
->save();
if (is_null($item["file_id"])) {
$item["file_id"] = "null";
}
if (is_null($item["stream_id"])) {
$item["stream_id"] = "null";
}
$nextStartDT = $endTimeDT;
$values[] = "(".
"'{$nextStartDT->format("Y-m-d H:i:s")}', ".
"'{$endTimeDT->format("Y-m-d H:i:s")}', ".
"'{$item["clip_length"]}', ".
"'{$item["fade_in"]}', ".
"'{$item["fade_out"]}', ".
"'{$item["cue_in"]}', ".
"'{$item["cue_out"]}', ".
"{$item["file_id"]}, ".
"{$item["stream_id"]}, ".
"{$id}, ".
"{$item["position"]})";
$nextStartDT = self::findTimeDifference($endTimeDT,
Application_Model_Preference::GetDefaultCrossfadeDuration());
} //foreach show item
//update time_filled in cc_show_instances
$ccShowInstance
->setDbTimeFilled($timeFilled)
->setDbLastScheduled(gmdate("Y-m-d H:i:s"))
->save();
}
} //foreach linked instance
$insert_sql = "INSERT INTO cc_schedule (starts, ends, ".
"clip_length, fade_in, fade_out, cue_in, cue_out, ".
"file_id, stream_id, instance_id, position) VALUES ".
implode($values, ",");
Application_Common_Database::prepareAndExecute(
$insert_sql, array(), Application_Common_Database::EXECUTE);
//update time_filled in cc_show_instances
$now = gmdate("Y-m-d H:i:s");
$update_sql = "UPDATE cc_show_instances SET ".
"time_filled = '{$timeFilled}', ".
"last_scheduled = '{$now}' ".
"WHERE show_id = {$ccShow->getDbId()}";
Application_Common_Database::prepareAndExecute(
$update_sql, array(), Application_Common_Database::EXECUTE);
} //if at least one linked instance has content
}
@ -248,7 +300,8 @@ class Application_Service_SchedulerService
->setDbPosition($item->getDbPosition())
->save();
$nextStartDT = $endTimeDT;
$nextStartDT = self::findTimeDifference($endTimeDT,
Application_Model_Preference::GetDefaultCrossfadeDuration());
} //foreach show item
$ccShowInstance
@ -259,20 +312,24 @@ class Application_Service_SchedulerService
}
}
private static function replaceInstanceContentCheck($ccShowInstance, $showStamp)
private static function replaceInstanceContentCheck($currentShowStamp, $showStamp)
{
$currentShowStamp = CcScheduleQuery::create()
/*$currentShowStamp = CcScheduleQuery::create()
->filterByDbInstanceId($ccShowInstance->getDbId())
->orderByDbStarts()
->find();
->find();*/
$counter = 0;
foreach ($showStamp as $item) {
if ($item->getDbFileId() != $currentShowStamp[$counter]->getDbFileId() ||
$item->getDbStreamId() != $currentShowStamp[$counter]->getDbStreamId()) {
CcScheduleQuery::create()
if ($item["file_id"] != $currentShowStamp[$counter]["file_id"] ||
$item["stream_id"] != $currentShowStamp[$counter]["stream_id"]) {
/*CcScheduleQuery::create()
->filterByDbInstanceId($ccShowInstance->getDbId())
->delete();
->delete();*/
$delete_sql = "DELETE FROM cc_schedule ".
"WHERE instance_id = {$currentShowStamp[$counter]["instance_id"]}";
Application_Common_Database::prepareAndExecute(
$delete_sql, array(), Application_Common_Database::EXECUTE);
return true;
}
}

View file

@ -99,8 +99,9 @@ class Application_Service_ShowFormService
public function delegateShowFormPopulation($forms)
{
$this->populateFormWhat($forms["what"]);
$this->populateFormWhen($forms["when"]);
$this->populateFormRepeats($forms["repeats"]);
//local show start DT
$showStart = $this->populateFormWhen($forms["when"]);
$this->populateFormRepeats($forms["repeats"], $showStart);
$this->populateFormWho($forms["who"]);
$this->populateFormStyle($forms["style"]);
$this->populateFormLive($forms["live"]);
@ -136,6 +137,9 @@ class Application_Service_ShowFormService
$form->disableStartDateAndTime();
} else {
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_duration' => $ccShowDay->formatDuration(true),
'add_show_repeats' => $ccShowDay->isRepeating() ? 1 : 0));
return $showStart;
}
private function populateInstanceFormWhen($form)
@ -179,7 +185,13 @@ class Application_Service_ShowFormService
$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();
@ -219,6 +231,14 @@ class Application_Service_ShowFormService
if (!$this->ccShow->isLinkable() || $this->ccShow->isRecorded()) {
$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)
@ -295,6 +315,22 @@ class Application_Service_ShowFormService
$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

View file

@ -179,9 +179,6 @@ class Application_Service_ShowService
if (is_null($this->ccShow)) {
$ccShowDays = $this->getShowDaysInRange($populateUntil, $end);
if (count($ccShowDays) > 0) {
$this->ccShow = $ccShowDays[0]->getCcShow();
}
} else {
$ccShowDays = $this->ccShow->getCcShowDays();
}
@ -190,32 +187,43 @@ class Application_Service_ShowService
$populateUntil = $end;
}
/* In case the user is moving forward in the calendar and there are
* linked shows in the schedule we need to keep track of each cc_show
* so we know which shows need to be filled with content
*/
$ccShows = array();
foreach ($ccShowDays as $day) {
$this->ccShow = $day->getCcShow();
if (!isset($ccShows[$day->getDbShowId()])) {
$ccShows[$day->getDbShowId()] = $day->getccShow();
}
switch ($day->getDbRepeatType()) {
case NO_REPEAT:
$this->createNonRepeatingInstance($day, $populateUntil);
break;
case REPEAT_WEEKLY:
$this->createRepeatingInstances($day, $populateUntil, REPEAT_WEEKLY,
$this->createWeeklyRepeatInstances($day, $populateUntil, REPEAT_WEEKLY,
new DateInterval("P7D"), $daysAdded);
break;
case REPEAT_BI_WEEKLY:
$this->createRepeatingInstances($day, $populateUntil, REPEAT_BI_WEEKLY,
$this->createWeeklyRepeatInstances($day, $populateUntil, REPEAT_BI_WEEKLY,
new DateInterval("P14D"), $daysAdded);
break;
case REPEAT_MONTHLY_MONTHLY:
$this->createMonthlyMonthlyRepeatInstances($day, $populateUntil);
$this->createMonthlyRepeatInstances($day, $populateUntil);
break;
case REPEAT_MONTHLY_WEEKLY:
$this->createRepeatingInstances($day, $populateUntil, REPEAT_MONTHLY_WEEKLY,
null, $daysAdded);
$this->createMonthlyRepeatInstances($day, $populateUntil);
break;
}
}
if (isset($this->ccShow) && ($this->isUpdate || $fillInstances) &&
$this->ccShow->isLinked()) {
Application_Service_SchedulerService::fillNewLinkedInstances($this->ccShow);
foreach ($ccShows as $ccShow) {
if (($this->isUpdate || $fillInstances) && $ccShow->isLinked()) {
Application_Service_SchedulerService::fillNewLinkedInstances($ccShow);
}
}
if (isset($this->linkedShowContent)) {
@ -322,7 +330,7 @@ SQL;
$this->deleteAllRepeatInstances($currentShowDay, $showId);
//if repeat option was checked we need to treat the current show day
//as a new show day so the repeat instances get created properly
//in createRepeatingInstances()
//in createWeeklyRepeatInstances()
if ($showData['add_show_repeats']) {
array_push($daysAdded, $currentShowDay->getDbDay());
}
@ -619,29 +627,44 @@ SQL;
->filterByDbShowId($showId)
->filterByDbModifiedInstance(false)
->filterByDbRebroadcast(0)
->orderByDbStarts()
->find();
if ($ccShowInstances->isEmpty()) {
return true;
}
//only 1 show instance left of the show, make it non repeating.
else if (count($ccShowInstances) === 1) {
$ccShowInstance = $ccShowInstances[0];
/* We need to update the last_show in cc_show_days so the instances
* don't get recreated as the user moves forward in the calendar
*/
else if (count($ccShowInstances) >= 1) {
$lastShowDays = array();
/* Creates an array where the key is the day of the week (monday,
* tuesday, etc.) and the value is the last show date for each
* day of the week. We will use this array to update the last_show
* for each cc_show_days entry of a cc_show
*/
foreach ($ccShowInstances as $instance) {
$instanceStartDT = new DateTime($instance->getDbStarts(),
new DateTimeZone("UTC"));
$lastShowDays[$instanceStartDT->format("w")] = $instanceStartDT;
}
foreach ($lastShowDays as $dayOfWeek => $lastShowStartDT) {
$ccShowDay = CcShowDaysQuery::create()
->filterByDbShowId($showId)
->filterByDbDay($dayOfWeek)
->findOne();
$tz = $ccShowDay->getDbTimezone();
$startDate = new DateTime($ccShowInstance->getDbStarts(), new DateTimeZone("UTC"));
$startDate->setTimeZone(new DateTimeZone($tz));
$endDate = Application_Service_CalendarService::addDeltas($startDate, 1, 0);
$lastShowStartDT->setTimeZone(new DateTimeZone(
$ccShowDay->getDbTimezone()));
$lastShowEndDT = Application_Service_CalendarService::addDeltas(
$lastShowStartDT, 1, 0);
$ccShowDay->setDbFirstShow($startDate->format("Y-m-d"));
$ccShowDay->setDbLastShow($endDate->format("Y-m-d"));
$ccShowDay->setDbStartTime($startDate->format("H:i:s"));
$ccShowDay->setDbRepeatType(-1);
$ccShowDay->save();
$ccShowDay
->setDbLastShow($lastShowEndDT->format("Y-m-d"))
->save();
}
//remove the old repeating deleted instances.
CcShowInstancesQuery::create()
@ -846,7 +869,7 @@ SQL;
* @param unknown_type $repeatInterval
* @param unknown_type $isRebroadcast
*/
private function createRepeatingInstances($showDay, $populateUntil,
private function createWeeklyRepeatInstances($showDay, $populateUntil,
$repeatType, $repeatInterval, $daysAdded=null)
{
$show_id = $showDay->getDbShowId();
@ -872,7 +895,9 @@ SQL;
Application_Common_DateHelper::ConvertToUtcDateTime($last_show, $timezone) : null;
$utcStartDateTime = new DateTime("now");
$previousDate = clone $start;
foreach ($datePeriod as $date) {
list($utcStartDateTime, $utcEndDateTime) = $this->createUTCStartEndDateTime(
$date, $duration);
/*
@ -926,6 +951,7 @@ SQL;
$this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId());
}
}
$previousDate = clone $date;
}
/* Set UTC to local time before setting the next repeat date. If we don't
@ -936,7 +962,7 @@ SQL;
$this->setNextRepeatingShowDate($nextDate->format("Y-m-d"), $day, $show_id);
}
private function createMonthlyMonthlyRepeatInstances($showDay, $populateUntil)
private function createMonthlyRepeatInstances($showDay, $populateUntil)
{
$show_id = $showDay->getDbShowId();
$first_show = $showDay->getDbFirstShow(); //non-UTC
@ -954,6 +980,13 @@ SQL;
$end = $populateUntil;
}
// We will only need this if the repeat type is MONTHLY_WEEKLY
list($weekNumberOfMonth, $dayOfWeek) =
$this->getMonthlyWeeklyRepeatInterval(
new DateTime($first_show, new DateTimeZone($timezone)));
$this->repeatType = $showDay->getDbRepeatType();
$utcLastShowDateTime = $last_show ?
Application_Common_DateHelper::ConvertToUtcDateTime($last_show, $timezone) : null;
@ -999,10 +1032,23 @@ SQL;
}
if ($this->isRebroadcast) {
$this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId());
$this->createRebroadcastInstances($showDay, $start, $ccShowInstance->getDbId());
}
}
$start = $this->getNextMonthlyMonthlyRepeatDate($start, $timezone, $showDay->getDbStartTime());
if ($this->repeatType == REPEAT_MONTHLY_WEEKLY) {
$monthlyWeeklyStart = new DateTime($utcStartDateTime->format("Y-m"),
new DateTimeZone("UTC"));
$monthlyWeeklyStart->add(new DateInterval("P1M"));
$start = $this->getNextMonthlyWeeklyRepeatDate(
$monthlyWeeklyStart,
$timezone,
$showDay->getDbStartTime(),
$weekNumberOfMonth,
$dayOfWeek);
} else {
$start = $this->getNextMonthlyMonthlyRepeatDate(
$start, $timezone, $showDay->getDbStartTime());
}
}
$this->setNextRepeatingShowDate($start->format("Y-m-d"), $day, $show_id);
}
@ -1018,7 +1064,6 @@ SQL;
private function getMonthlyWeeklyRepeatInterval($showStart)
{
$start = clone $showStart;
$dayOfMonth = $start->format("j");
$dayOfWeek = $start->format("l");
$yearAndMonth = $start->format("Y-m");
@ -1047,22 +1092,24 @@ SQL;
$weekNumberOfMonth = "fourth";
break;
case 5:
$weekNumberOfMonth = "last";
$weekNumberOfMonth = "fifth";
break;
}
return DateInterval::createFromDateString(
$weekNumberOfMonth." ".$dayOfWeek." of next month");
/* return DateInterval::createFromDateString(
$weekNumberOfMonth." ".$dayOfWeek." of next month"); */
return array($weekNumberOfMonth, $dayOfWeek);
}
/**
*
* Enter description here ...
* @param $start
* @param $start user's local time
*/
private function getNextMonthlyMonthlyRepeatDate($start, $timezone, $startTime)
{
$dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone));
do {
$dt->add(new DateInterval("P1M"));
} while (!checkdate($dt->format("m"), $start->format("d"), $dt->format("Y")));
@ -1077,6 +1124,41 @@ SQL;
return $dt;
}
private function getNextMonthlyWeeklyRepeatDate(
$start,
$timezone,
$startTime,
$weekNumberOfMonth,
$dayOfWeek)
{
$dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone));
$tempDT = clone $dt;
$fifthWeekExists = false;
do {
$nextDT = date_create($weekNumberOfMonth." ".$dayOfWeek.
" of ".$tempDT->format("F")." ".$tempDT->format("Y"));
/* We have to check if the next date is in the same month in case
* the repeat day is in the fifth week of the month.
* If it's not in the same month we know that a fifth week of
* the next month does not exist. So let's skip it.
*/
if ($tempDT->format("F") == $nextDT->format("F")) {
$fifthWeekExists = true;
}
$tempDT->add(new DateInterval("P1M"));
} while (!$fifthWeekExists);
$dt = $nextDT;
$startTime = explode(":", $startTime);
$hours = isset($startTime[0]) ? $startTime[0] : "00";
$minutes = isset($startTime[1]) ? $startTime[1] : "00";
$seconds = isset($startTime[2]) ? $startTime[2] : "00";
$dt->setTime($hours, $minutes, $seconds);
return $dt;
}
private function getNextRepeatingPopulateStartDateTime($showDay)
{
$nextPopDate = $showDay->getDbNextPopDate();

View file

@ -18,18 +18,26 @@
<div class="jp-type-playlist">
<div class="jp-gui jp-interface">
<ul class="jp-controls">
<?php if ($this->type != "audioclip"): ?>
<li class="ui-state-default ui-corner-all jp-previous">
<span class="ui-icon ui-icon-seek-prev" tabindex="1"><? echo _("previous") ?></span>
</li>
<?php endif;?>
<li class="ui-state-default ui-corner-all jp-play">
<span class="ui-icon ui-icon-play" tabindex="1"><? echo _("play") ?></span>
</li>
<li class="ui-state-default ui-corner-all jp-pause">
<span class="ui-icon ui-icon-pause" tabindex="1"><? echo _("pause") ?></span>
</li>
<?php if ($this->type != "audioclip"): ?>
<li class="ui-state-default ui-corner-all jp-next">
<span class="ui-icon ui-icon-seek-next" tabindex="1"><? echo _("next") ?></span>
</li>
<?php endif;?>
<li class="ui-state-default ui-corner-all jp-stop">
<span class="ui-icon ui-icon-stop" tabindex="1"><? echo _("stop") ?></span>
</li>
@ -42,7 +50,9 @@
</div>
<div class="jp-time-holder">
<div class="jp-current-time"></div>
<?php if ($this->type == "audioclip"): ?><div class="jp-duration"></div><?php endif;?>
<?php if ($this->type == "audioclip"): ?>
<div class="jp-duration"></div>
<?php endif;?>
</div>
</div>
<div class="jp-volume-block">

View file

@ -74,7 +74,7 @@ $(document).ready(function(){
if ($type == "ogg")
$type = "oga";
$label = "(".$streamData["${id}_host"].") ".$streamData["${id}_description"]." - ".$streamData["${id}_bitrate"]." Kbit/s";
$label = "(".$streamData["${id}_host"].") ".$streamData["${id}_description"]." - ".$streamData["${id}_bitrate"]." kbit/s";
echo sprintf("<option class='stream' value='%s' data-url='%s' data-type='%s' server-type='%s'>%s</option>", $id, $url, $type, $serverType, $label);
}
?>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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

Before After
Before After

View file

@ -105,6 +105,10 @@ div.sb-timerange input#sb_date_start {
margin-left: 30px;
}
div.sb-timerange input.error {
background-color: rgba(255,0,0,0.2);
}
.sb-starts,
.sb-ends {
text-align: center;

View file

@ -125,7 +125,7 @@ select {
.airtime_auth_help_icon, .custom_auth_help_icon, .stream_username_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;
position: relative;
display:inline-block; zoom:1;

View file

@ -14,11 +14,36 @@
.btn-small {
/*line-height: 20px;*/
}
.playlist-time-scale {
position: absolute;
top: 5px;
left: 0;
right: 0;
height: 30px;
overflow: hidden;
}
.playlist-time-scale canvas {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 30px;
}
.playlist-time-scale div {
position: absolute;
}
.playlist-tracks {
margin: 8px 0;
position: relative;
top: 35px;
margin: 2px 0;
}
.playlist-controls {
margin: 0 0 16px 0;
margin: 40px 0 16px 0;
}
.channel-wrapper {
@ -30,6 +55,8 @@
margin: 0;
padding: 0;
background: #6e6e6e;
/*border-top: 1px solid #6e6e6e;*/
/*border-bottom: 1px solid #6e6e6e;*/
}
.state-select {
@ -41,6 +68,12 @@
overflow-y: hidden;
}
.playlist-tracks > .error {
height: 80px;
width: 300px;
background-color: rgba(255,0,0,0.5);
}
.playlist-fade {
position: absolute;
background-color: rgba(0,0,0,0.1);
@ -50,7 +83,7 @@
margin: 12px 0 16px 0;
}
.set-fade {
margin: 0 0 0 30px;
margin: 40px 0 0 30px;
}
.set-cue input[type="text"] {
vertical-align: middle;

View file

@ -260,16 +260,19 @@ function parseItems(obj){
calculateTimeToNextSong();
}
currentShow = new Array();
if (obj.currentShow.length > 0) {
calcAdditionalShowData(obj.currentShow);
currentShow = obj.currentShow;
}
nextShow = new Array();
if (obj.nextShow.length > 0) {
calcAdditionalShowData(obj.nextShow);
nextShow = obj.nextShow;
calculateTimeToNextShow();
}
currentShow = obj.currentShow;
nextShow = obj.nextShow;
var schedulePosixTime = convertDateToPosixTime(obj.schedulerTime);
var date = new Date();

View file

@ -391,7 +391,9 @@ var AIRTIME = (function(AIRTIME) {
$libTable = $libContent.find("table");
var tableHeight = $libContent.height() - 130;
function getTableHeight() {
return $libContent.height() - 175;
}
function setColumnFilter(oTable){
// TODO : remove this dirty hack once js is refactored
@ -454,6 +456,13 @@ var AIRTIME = (function(AIRTIME) {
} else {
$el.hide();
}
//resize to prevent double scroll bars.
var $fs = $el.parents("fieldset"),
tableHeight = getTableHeight(),
searchHeight = $fs.height();
$libContent.find(".dataTables_scrolling").css("max-height", tableHeight - searchHeight);
}
oTable = $libTable.dataTable( {
@ -593,12 +602,12 @@ var AIRTIME = (function(AIRTIME) {
"fnRowCallback": AIRTIME.library.fnRowCallback,
"fnCreatedRow": function( nRow, aData, iDataIndex ) {
//add soundcloud icon
if (aData.soundcloud_status !== undefined) {
if (aData.soundcloud_status === "-2") {
if (aData.soundcloud_id !== undefined) {
if (aData.soundcloud_id === "-2") {
$(nRow).find("td.library_title").append('<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"/>');
} else if (aData.soundcloud_status !== null) {
} else if (aData.soundcloud_id !== null) {
$(nRow).find("td.library_title").append('<span class="small-icon soundcloud"/>');
}
}
@ -784,10 +793,14 @@ var AIRTIME = (function(AIRTIME) {
$libContent.on("click", "legend", function(){
$simpleSearch = $libContent.find("#library_display_filter label");
var $fs = $(this).parents("fieldset");
var $fs = $(this).parents("fieldset"),
searchHeight,
tableHeight = getTableHeight(),
height;
if ($fs.hasClass("closed")) {
$fs.removeClass("closed");
searchHeight = $fs.height();
//keep value of simple search for when user switches back to it
simpleSearchText = $simpleSearch.find('input').val();
@ -796,6 +809,10 @@ var AIRTIME = (function(AIRTIME) {
$(".dataTables_filter input").val("").keyup();
$simpleSearch.addClass("sp-invisible");
//resize the library table to avoid a double scroll bar. CC-4504
height = tableHeight - searchHeight;
$libContent.find(".dataTables_scrolling").css("max-height", height);
}
else {
// clear the advanced search fields
@ -817,9 +834,13 @@ var AIRTIME = (function(AIRTIME) {
$simpleSearch.removeClass("sp-invisible");
$fs.addClass("closed");
//resize the library table to avoid a double scroll bar. CC-4504
$libContent.find(".dataTables_scrolling").css("max-height", tableHeight);
}
});
var tableHeight = getTableHeight();
$libContent.find(".dataTables_scrolling").css("max-height", tableHeight);
AIRTIME.library.setupLibraryToolbar(oTable);
@ -1069,13 +1090,13 @@ function buildEditMetadataDialog (json){
width: 460,
height: 660,
modal: true,
close: closeDialog
close: closeDialogLibrary
});
dialog.dialog('open');
}
function closeDialog(event, ui) {
function closeDialogLibrary(event, ui) {
$(this).remove();
}
@ -1126,7 +1147,6 @@ function checkLibrarySCUploadStatus(){
else if (json.sc_id == "-3") {
span.removeClass("progress").addClass("sc-error");
}
setTimeout(checkLibrarySCUploadStatus, 5000);
}
function checkSCUploadStatusRequest() {
@ -1138,12 +1158,16 @@ function checkLibrarySCUploadStatus(){
}
$("#library_display span.progress").each(checkSCUploadStatusRequest);
setTimeout(checkLibrarySCUploadStatus, 5000);
}
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")){
$(this).qtip({
@ -1163,24 +1187,15 @@ function addQtipToSCIcons(){
classes: "ui-tooltip-dark file-md-long"
},
show: {
ready: true // Needed to make it show on first mouseover
// event
ready: true // Needed to make it show on first mouseover event
}
});
}
else if ($(this).hasClass("soundcloud")){
var sc_id = $(this).parent().parent().data("aData").soundcloud_id;
$(this).qtip({
content: {
text: $.i18n._("Retrieving data from the server..."),
ajax: {
url: baseUrl+"Library/get-upload-to-soundcloud-status",
type: "post",
data: ({format: "json", id : id, type: "file"}),
success: function(json, status){
this.set('content.text', $.i18n._("The soundcloud id for this file is: ")+json.sc_id);
}
}
text: $.i18n._("The soundcloud id for this file is: ") + sc_id
},
position:{
adjust: {
@ -1195,11 +1210,11 @@ function addQtipToSCIcons(){
classes: "ui-tooltip-dark file-md-long"
},
show: {
ready: true // Needed to make it show on first mouseover
// event
ready: true // Needed to make it show on first mouseover event
}
});
}else if($(this).hasClass("sc-error")){
}
else if ($(this).hasClass("sc-error")) {
$(this).qtip({
content: {
text: $.i18n._("Retreiving data from the server..."),
@ -1227,8 +1242,7 @@ function addQtipToSCIcons(){
classes: "ui-tooltip-dark file-md-long"
},
show: {
ready: true // Needed to make it show on first mouseover
// event
ready: true // Needed to make it show on first mouseover event
}
});
}

View file

@ -209,12 +209,11 @@ var AIRTIME = (function(AIRTIME){
}
/* used from waveform pop-up */
function changeCrossfade($el, id1, id2, fadeIn, fadeOut, offset) {
function changeCrossfade($el, id1, id2, fadeIn, fadeOut, offset, id) {
var url = baseUrl+"Playlist/set-crossfade",
lastMod = getModified(),
type = $('#obj_type').val(),
li, id;
type = $('#obj_type').val();
$.post(url,
{format: "json", fadeIn: fadeIn, fadeOut: fadeOut, id1: id1, id2: id2, offset: offset, modified: lastMod, type: type},
@ -230,10 +229,9 @@ var AIRTIME = (function(AIRTIME){
setPlaylistContent(json);
id = id1 === undefined ? id2 : id1;
li = $('#side_playlist li[unqid='+id+']');
li.find('.crossfade').toggle();
highlightActive(li.find('.spl_fade_control'));
$li = $('#side_playlist li[unqid='+id+']');
$li.find('.crossfade').toggle();
highlightActive($li.find('.spl_fade_control'));
});
}
@ -589,13 +587,13 @@ var AIRTIME = (function(AIRTIME){
var extra = (ele['extra']==null)?"":"- "+ele['extra'];
$html += "<li>" +
"<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'>"+extra+"</span>" +
"</li>";
});
}
$html += "<li><br /><span class='block-item-title'>"+$.i18n._("Limit to: ")+data.limit.value+" "+data.limit.modifier+"</span></li>";
$html += "<li><br /><span class='block-item-title'>"+$.i18n._("Limit to: ")+data.limit.value+" "+data.limit.display_modifier+"</span></li>";
}
$pl.find("#block_"+id+"_info").html($html).show();
mod.enableUI();
@ -1179,13 +1177,16 @@ var AIRTIME = (function(AIRTIME){
mod.showFadesWaveform = function(e) {
var $el = $(e.target),
$parent = $el.parents("dl"),
$li = $el.parents("li"),
$fadeOut = $parent.find(".spl_fade_out"),
$fadeIn = $parent.find(".spl_fade_in"),
$html = $($("#tmpl-pl-fades").html()),
tracks = [],
dim = AIRTIME.utilities.findViewportDimensions(),
playlistEditor,
id1, id2;
id1, id2,
id = $li.attr("unqid");
function removeDialog() {
playlistEditor.stop();
@ -1246,7 +1247,7 @@ var AIRTIME = (function(AIRTIME){
show: 'clip',
hide: 'clip',
width: dim.width - 100,
height: dim.height - 100,
height: 350,
buttons: [
{text: $.i18n._("Cancel"), class: "btn btn-small", click: removeDialog},
{text: $.i18n._("Save"), class: "btn btn-small btn-inverse", click: function() {
@ -1257,15 +1258,22 @@ var AIRTIME = (function(AIRTIME){
playlistEditor.stop();
if (json.length === 1) {
if (json.length === 0)
{
id1 = undefined;
id2 = undefined;
}
else if (json.length === 1) {
fade = json[0]["fades"][0];
if (fade["type"] === "FadeOut") {
fadeOut = fade["end"] - fade["start"];
id2 = undefined; //incase of track decode error.
}
else {
fadeIn = fade["end"] - fade["start"];
id1 = undefined; //incase of track decode error.
}
}
else {
@ -1282,7 +1290,7 @@ var AIRTIME = (function(AIRTIME){
fadeIn = (fadeIn === undefined) ? undefined : fadeIn.toFixed(1);
fadeOut = (fadeOut === undefined) ? undefined : fadeOut.toFixed(1);
changeCrossfade($html, id1, id2, fadeIn, fadeOut, offset);
changeCrossfade($html, id1, id2, fadeIn, fadeOut, offset, id);
}}
],
open: function (event, ui) {
@ -1291,6 +1299,7 @@ var AIRTIME = (function(AIRTIME){
resolution: 15000,
state: "cursor",
mono: true,
timescale: true,
waveHeight: 80,
container: $html[0],
UITheme: "jQueryUI",
@ -1301,7 +1310,10 @@ var AIRTIME = (function(AIRTIME){
playlistEditor.setConfig(config);
playlistEditor.init(tracks);
},
close: removeDialog
close: removeDialog,
resizeStop: function(event, ui) {
playlistEditor.resize();
}
});
};
@ -1354,7 +1366,7 @@ var AIRTIME = (function(AIRTIME){
show: 'clip',
hide: 'clip',
width: dim.width - 100,
height: dim.height - 100,
height: 325,
buttons: [
{text: $.i18n._("Cancel"), class: "btn btn-small", click: removeDialog},
{text: $.i18n._("Save"), class: "btn btn-small btn-inverse", click: function() {
@ -1371,6 +1383,7 @@ var AIRTIME = (function(AIRTIME){
var config = new Config({
resolution: 15000,
mono: true,
timescale: true,
waveHeight: 80,
container: $html[0],
UITheme: "jQueryUI",
@ -1381,7 +1394,10 @@ var AIRTIME = (function(AIRTIME){
playlistEditor.setConfig(config);
playlistEditor.init(tracks);
},
close: removeDialog
close: removeDialog,
resizeStop: function(event, ui) {
playlistEditor.resize();
}
});
};
@ -1435,7 +1451,7 @@ var AIRTIME = (function(AIRTIME){
widgetHeight = viewport.height - 185;
width = Math.floor(viewport.width - 80);
var libTableHeight = widgetHeight - 130;
var libTableHeight = widgetHeight - 175;
if (!$pl.is(':hidden')) {
$lib.height(widgetHeight)
@ -1459,8 +1475,6 @@ var AIRTIME = (function(AIRTIME){
$lib = $("#library_content");
$pl = $("#side_playlist");
setWidgetSize();
AIRTIME.library.libraryInit();

View file

@ -193,6 +193,7 @@ function setAddShowEvents() {
}
});
form.find("#add_show_linked-label").before("<span class='show_linking_help_icon'></span>");
form.find("#add_show_record").click(function(){
$(this).blur();
@ -315,7 +316,26 @@ function setAddShowEvents() {
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(){
if(form.find("#add_show_no_end").is(':checked')){
form.find("#add_show_end_date").hide();

View file

@ -116,12 +116,19 @@ function dayClick(date, allDay, jsEvent, view){
// duration in milisec
var duration = (duration_h * 60 * 60 * 1000) + (duration_m * 60 * 1000);
var startTime_string, startTime
var startTime_string;
var startTime = 0;
// get start time value on the form
if(view.name === "month") {
startTime_string = $("#add_show_start_time").val();
var startTime_info = startTime_string.split(':');
startTime = (parseInt(startTime_info[0],10) * 60 * 60 * 1000) + (parseInt(startTime_info[1], 10) * 60 * 1000);
if (startTime_info.length == 2) {
var start_time_temp = (parseInt(startTime_info[0],10) * 60 * 60 * 1000)
+ (parseInt(startTime_info[1], 10) * 60 * 1000);
if (!isNaN(start_time_temp)) {
startTime = start_time_temp;
}
}
}else{
// if in day or week view, selected has all the time info as well
// so we don't ahve to calculate it explicitly
@ -210,7 +217,9 @@ function viewDisplay( view ) {
}
function eventRender(event, element, view) {
$(element).attr("id", "fc-show-instance-"+event.id);
$(element).attr("data-show-id", event.showId);
$(element).attr("data-show-linked", event.linked);
$(element).data("event", event);
//only put progress bar on shows that aren't being recorded.
@ -229,34 +238,27 @@ function eventRender(event, element, view) {
$(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
if (event.record === 1) {
if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
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) {
$(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) {
$(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) {
$(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') {
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) {
$(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) {
$(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) {
$(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 +269,27 @@ function eventRender(event, element, view) {
if (event.linked) {
$(element)
.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 {
$(element)
.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) {
if (event.linked) {
$(element)
.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 {
$(element)
.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 {
if (event.linked) {
$(element)
.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') {
@ -295,27 +297,27 @@ function eventRender(event, element, view) {
if (event.linked) {
$(element)
.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 {
$(element)
.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) {
if (event.linked) {
$(element)
.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 {
$(element)
.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 {
if (event.linked) {
$(element)
.find(".fc-event-title")
.after('<span id="'+event.id+'" class="small-icon linked"></span>');
.after('<span class="small-icon linked"></span>');
}
}
}
@ -324,9 +326,9 @@ function eventRender(event, element, view) {
//rebroadcast icon
if (event.rebroadcast === 1) {
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') {
$(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 +336,7 @@ function eventRender(event, element, view) {
function eventAfterRender( event, element, view ) {
$(element).find(".small-icon").live('mouseover',function(){
addQtipsToIcons($(this));
addQtipsToIcons($(this), event.id);
});
}
@ -403,15 +405,25 @@ function getFullCalendarEvents(start, end, callback) {
}
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(){
var id = $(this).attr("id");
id = $(this).parents("div.fc-event").data("event").id;
$.post(url, {format: "json", id: id, type:"show"}, function(json){
if (json.sc_id > 0){
$("span[id="+id+"]:not(.recording)").removeClass("progress").addClass("soundcloud");
}else if(json.sc_id == "-3"){
$("span[id="+id+"]:not(.recording)").removeClass("progress").addClass("sc-error");
$("#fc-show-instance-"+id)
.find(".progress")
.removeClass("progress")
.addClass("soundcloud");
}
else if (json.sc_id == "-3"){
$("#fc-show-instance-"+id)
.find(".progress")
.removeClass("progress")
.addClass("sc-error");
}
setTimeout(checkSCUploadStatus, 5000);
});
});
@ -425,7 +437,7 @@ function getCurrentShow(){
$el;
$.post(url, {format: "json"}, function(json) {
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') {
/* Need to remove now-playing class because if user
@ -440,38 +452,38 @@ function getCurrentShow(){
* icon will overwrite it.
*/
$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")) {
/* Without removing rebroadcast icon, the now playing
* icon will overwrite it.
*/
$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 {
$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') {
if (!$("span[class*=fc-event-title][id="+json.si_id+"]").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>');
if (!$("span[class*=fc-event-title]").siblings().hasClass("small-icon now-playing")) {
$("span[class*=fc-event-title]").after('<span class="small-icon now-playing"></span>');
}
}
}
//remove icon from shows that have ended
$(".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]");
}
});
setTimeout(getCurrentShow, 5000);
});
}
function addQtipsToIcons(ele){
var id = $(ele).attr("id");
function addQtipsToIcons(ele, id){
if ($(ele).hasClass("progress")){
$(ele).qtip({

View file

@ -12,8 +12,8 @@ var AIRTIME = (function(AIRTIME){
var serverTimezoneOffset = 0;
function closeDialog(event, ui) {
$("#schedule_calendar").fullCalendar( 'refetchEvents' );
function closeDialogCalendar(event, ui) {
//$("#schedule_calendar").fullCalendar( 'refetchEvents' );
$(this).remove();
}
@ -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 span = $(window.triggerElement).find(".recording");
var url = baseUrl+"Schedule/upload-to-sound-cloud",
$el = $(el),
$span = $el.find(".soundcloud");
$.post(url,
{id: show_instance_id, format: "json"},
function(json){
scheduleRefetchEvents(json);
});
$.post(url, {id: show_instance_id, format: "json"});
if(span.length == 0){
span = $(window.triggerElement).find(".soundcloud");
span.removeClass("soundcloud")
.addClass("progress");
}else{
span.removeClass("recording")
.addClass("progress");
//first upload to soundcloud.
if ($span.length === 0){
$span = $("<span/>", {"class": "progress"});
$el.find(".fc-event-title").after($span);
}
else {
$span.removeClass("soundcloud").addClass("progress");
}
}
@ -93,8 +91,6 @@ function checkCalendarSCUploadStatus(){
else if (json.sc_id == "-3") {
span.removeClass("progress").addClass("sc-error");
}
setTimeout(checkCalendarSCUploadStatus, 5000);
}
function checkSCUploadStatusRequest() {
@ -106,6 +102,7 @@ function checkCalendarSCUploadStatus(){
}
$("#schedule_calendar span.progress").each(checkSCUploadStatusRequest);
setTimeout(checkCalendarSCUploadStatus, 5000);
}
function findViewportDimensions() {
@ -164,7 +161,7 @@ function buildScheduleDialog (json, instance_id) {
resizable: false,
draggable: true,
modal: true,
close: closeDialog,
close: closeDialogCalendar,
buttons: [
{
text: $.i18n._("Ok"),
@ -189,10 +186,10 @@ function buildScheduleDialog (json, instance_id) {
//set max heights of datatables.
dialog.find(".lib-content .dataTables_scrolling")
.css("max-height", height - 90 - 155);
.css("max-height", height - 90 - 200);
dialog.find(".sb-content .dataTables_scrolling")
.css("max-height", height - 90 - 60);
.css("max-height", height - 90 - 65);
dialog.dialog('open');
}
@ -217,7 +214,7 @@ function buildContentDialog (json){
width: width,
height: height,
modal: true,
close: closeDialog,
close: closeDialogCalendar,
buttons: [
{
text: $.i18n._("Ok"),
@ -421,7 +418,7 @@ $(document).ready(function() {
if (oItems.soundcloud_upload !== undefined) {
callback = function() {
uploadToSoundCloud(data.id);
uploadToSoundCloud(data.id, this.context);
};
oItems.soundcloud_upload.callback = callback;
}

View file

@ -40,8 +40,6 @@ var AIRTIME = (function(AIRTIME){
};
mod.updateCalendarStatusIcon = function(json) {
//make sure we are only executing this code on the calendar view, not
//the Now Playing view.
if (window.location.pathname.toLowerCase().indexOf("schedule") < 0) {
@ -52,16 +50,24 @@ var AIRTIME = (function(AIRTIME){
var instance_id = json.schedule[0].instance;
var lastElem = json.schedule[json.schedule.length-1];
var $elem = $($(".fc-event-inner.fc-event-skin .fc-event-title#"+instance_id).parent());
$elem.find(".small-icon").remove();
var $elem = $("#fc-show-instance-"+instance_id);
//if the show is linked, then replace $elem to reference all linked
//instances
if ($elem.data("show-linked") == "1") {
var show_id = $elem.data("show-id");
$elem = $('*[data-show-id="'+show_id+'"]');
}
$elem.find(".show-empty, .show-partial-filled").remove();
if (json.schedule[1].empty) {
$elem
.find(".fc-event-title")
.after('<span id="'+instance_id+'" title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
.find(".fc-event-inner")
.append('<span id="'+instance_id+'" title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
} else if (lastElem["fRuntime"][0] == "-") {
$elem
.find(".fc-event-title")
.after('<span id="'+instance_id+'" title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
.find(".fc-event-inner")
.append('<span id="'+instance_id+'" title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
}
}
@ -546,7 +552,7 @@ var AIRTIME = (function(AIRTIME){
cl = 'sb-footer';
//check the show's content status.
if (aData.runtime > 0) {
if (aData.runtime >= 0) {
$node.html('<span class="ui-icon ui-icon-check"></span>');
cl = cl + ' ui-state-highlight';
}
@ -614,7 +620,7 @@ var AIRTIME = (function(AIRTIME){
}
$node = $(nRow.children[0]);
if (aData.allowed === true && aData.scheduled >= 1) {
if (aData.allowed === true && aData.scheduled >= 1 && aData.linked_allowed) {
$node.html('<input type="checkbox" name="'+aData.id+'"></input>');
}
else {

View file

@ -35,7 +35,8 @@ AIRTIME = (function(AIRTIME) {
dayNamesMin: i18n_days_short,
onClick: function(sDate, oDatePicker) {
$(this).datepicker( "setDate", sDate );
}
},
onClose: validateTimeRange
};
oBaseTimePickerSettings = {
@ -53,7 +54,7 @@ AIRTIME = (function(AIRTIME) {
widgetHeight = viewport.height - 180;
screenWidth = Math.floor(viewport.width - 40);
var libTableHeight = widgetHeight - 130,
var libTableHeight = widgetHeight - 175,
builderTableHeight = widgetHeight - 95,
oTable;
@ -90,20 +91,48 @@ AIRTIME = (function(AIRTIME) {
}
}
function validateTimeRange() {
var oRange,
inputs = $('.sb-timerange > input'),
start, end;
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, dateEndId, timeEndId);
start = oRange.start;
end = oRange.end;
if (end >= start) {
inputs.removeClass('error');
}
else {
if (!inputs.hasClass('error')) {
inputs.addClass('error');
}
}
return {
start: start,
end: end,
isValid: end >= start
};
}
function showSearchSubmit() {
var fn,
oRange,
op,
oTable = $('#show_builder_table').dataTable();
oTable = $('#show_builder_table').dataTable(),
check;
check = validateTimeRange();
if (check.isValid) {
//reset timestamp value since input values could have changed.
AIRTIME.showbuilder.resetTimestamp();
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, dateEndId, timeEndId);
fn = oTable.fnSettings().fnServerData;
fn.start = oRange.start;
fn.end = oRange.end;
fn.start = check.start;
fn.end = check.end;
op = $("div.sb-advanced-options");
if (op.is(":visible")) {
@ -117,6 +146,7 @@ AIRTIME = (function(AIRTIME) {
oTable.fnDraw();
}
}
mod.onReady = function() {
// define module vars.
@ -134,10 +164,22 @@ AIRTIME = (function(AIRTIME) {
$(this).removeClass("ui-state-hover");
});
$builder.find(dateStartId).datepicker(oBaseDatePickerSettings);
$builder.find(timeStartId).timepicker(oBaseTimePickerSettings);
$builder.find(dateEndId).datepicker(oBaseDatePickerSettings);
$builder.find(timeEndId).timepicker(oBaseTimePickerSettings);
$builder.find(dateStartId)
.datepicker(oBaseDatePickerSettings)
.blur(validateTimeRange);
$builder.find(timeStartId)
.timepicker(oBaseTimePickerSettings)
.blur(validateTimeRange);
$builder.find(dateEndId)
.datepicker(oBaseDatePickerSettings)
.blur(validateTimeRange);
$builder.find(timeEndId)
.timepicker(oBaseTimePickerSettings)
.blur(validateTimeRange);
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId,
dateEndId, timeEndId);

View file

@ -88,19 +88,13 @@ var AIRTIME = (function(AIRTIME){
mod.fnGetScheduleRange = function(dateStart, timeStart, dateEnd, timeEnd) {
var iStart,
iEnd,
iRange,
DEFAULT_RANGE = 60*60*24;
iRange;
iStart = AIRTIME.utilities.fnGetTimestamp(dateStart, timeStart);
iEnd = AIRTIME.utilities.fnGetTimestamp(dateEnd, timeEnd);
iRange = iEnd - iStart;
if (iEnd < iStart) {
iEnd = iStart + DEFAULT_RANGE;
iRange = DEFAULT_RANGE;
}
return {
start: iStart,
end: iEnd,

View file

@ -1,17 +1,23 @@
{
"sProcessing": "Bitte warten...",
"sLengthMenu": "_MENU_ Einträge anzeigen",
"sZeroRecords": "Keine Einträge vorhanden.",
"sEmptyTable": "Tabelle enthält keine Daten",
"sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen",
"sInfoEmpty": "0 bis 0 von 0 Einträgen",
"sInfoFiltered": "(gefiltert von _MAX_ Einträgen)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "_MENU_ Einträge anzeigen",
"sLoadingRecords": "Lade...",
"sProcessing": "Bitte warten...",
"sSearch": "",
"sUrl": "",
"sZeroRecords": "Keine Einträge vorhanden.",
"oAria": {
"sSortAscending": ": Spalte aufsteigend Sortieren",
"sSortDescending": ": Spalte absteigend Sortieren"
},
"oPaginate": {
"sFirst": "Erster",
"sFirst": "Erste",
"sPrevious": "Zurück",
"sNext": "Nächster",
"sLast": "Letzter"
"sNext": "Nächste",
"sLast": "Letzte"
}
}

View file

@ -1,25 +1,27 @@
// German
plupload.addI18n({
'Select files' : 'Dateien hochladen',
'Add files to the upload queue and click the start button.' : 'Dateien hinzuf&uuml;gen und auf \'Hochladen\' klicken.',
'Filename' : 'Dateiname',
'Status' : 'Status',
'Size' : 'Gr&ouml;&szlig;e',
'%d files queued': '%d Dateien in der Warteschlange',
'Add files to the upload queue and click the start button.' : '\'Dateien\' hinzuf&uuml;gen und auf \'Hochladen\' klicken.',
'Add files' : 'Dateien', // hinzuf&uuml;gen',
'Stop current upload' : 'Aktuelles Hochladen stoppen',
'Start uploading queue' : 'Hochladen starten',
'Uploaded %d/%d files': '%d/%d Dateien sind hochgeladen',
'N/A' : 'Nicht verf&uuml;gbar',
'Drag files here.' : 'Ziehen Sie die Dateien hier hin',
'Add Files': 'Dateien', // hinzuf&uuml;gen',
'Drag files here.' : 'Ziehe Dateien hier hin. (Drag &amp; Drop)',
'File extension error.': 'Fehler bei Dateiendung',
'File size error.': 'Fehler bei Dateigr&ouml;ße',
'Init error.': 'Initialisierungsfehler',
'HTTP Error.': 'HTTP-Fehler',
'Security error.': 'Sicherheitsfehler',
'Filename' : 'Dateiname',
'Generic error.': 'Typischer Fehler',
'HTTP Error.': 'HTTP-Fehler',
'Init error.': 'Initialisierungsfehler',
'IO error.': 'Ein/Ausgabe-Fehler',
'Stop Upload': 'Hochladen stoppen',
'N/A' : 'Nicht verf&uuml;gbar',
'Security error.': 'Sicherheitsfehler',
'Select files' : 'Dateien hochladen',
'Size' : 'Gr&ouml;&szlig;e',
'Start upload': 'Hochladen',
'%d files queued': '%d Dateien in der Warteschlange',
'Start Upload': 'Hochladen',
'Start uploading queue' : 'Hochladen starten',
'Status' : 'Status',
'Stop current upload' : 'Aktuelles Hochladen stoppen',
'Stop Upload': 'Hochladen stoppen',
'Uploaded %d/%d files': '%d/%d Dateien sind hochgeladen',
"Error: Invalid file extension: " : $.i18n._("Error: Invalid file extension: ")
});

View file

@ -56,6 +56,16 @@ PlaylistEditor.prototype.init = function(tracks) {
trackEditor.on("deactivateSelection", "onAudioDeselection", audioControls);
trackEditor.on("changecursor", "onCursorSelection", audioControls);
trackEditor.on("changecursor", "onSelectUpdate", this);
trackEditor.on("unregister", (function() {
var editor = this;
audioControls.remove("trackedit", "onTrackEdit", editor);
audioControls.remove("changeresolution", "onResolutionChange", editor);
that.removeTrack(editor);
}).bind(trackEditor));
}
div.innerHTML = '';
@ -82,6 +92,26 @@ PlaylistEditor.prototype.init = function(tracks) {
audioControls.on("changeselection", "onSelectionChange", this);
};
PlaylistEditor.prototype.removeTrack = function(trackEditor) {
var i,
len,
editor,
editors = this.trackEditors;
for (i = 0, len = editors.length; i < len; i++) {
editor = editors[i];
if (editor === trackEditor) {
editors.splice(i, 1);
return;
}
}
};
PlaylistEditor.prototype.resize = function() {
this.timeScale.onResize();
};
PlaylistEditor.prototype.onTrimAudio = function() {
var track = this.activeTrack,
selected = track.getSelectedArea(),

View file

@ -16,8 +16,6 @@ AudioPlayout.prototype.init = function(config) {
this.gainNode = undefined;
this.destination = this.ac.destination;
this.analyser = this.ac.createAnalyser();
this.analyser.connect(this.destination);
};
AudioPlayout.prototype.getBuffer = function() {
@ -41,7 +39,7 @@ AudioPlayout.prototype.applyFades = function(fades, relPos, now, delay) {
duration;
this.gainNode && this.gainNode.disconnect();
this.gainNode = this.ac.createGainNode();
this.gainNode = this.ac.createGain();
for (id in fades) {
@ -84,6 +82,7 @@ AudioPlayout.prototype.loadData = function (audioData, cb) {
},
function(err) {
console.log("err(decodeAudioData): "+err);
cb(null, err);
}
);
};
@ -136,7 +135,7 @@ AudioPlayout.prototype.setSource = function(source) {
this.source.buffer = this.buffer;
this.source.connect(this.gainNode);
this.gainNode.connect(this.analyser);
this.gainNode.connect(this.destination);
};
/*

View file

@ -8,7 +8,8 @@ TimeScale.prototype.init = function(config) {
var that = this,
canv,
div;
div,
resizeTimer;
makePublisher(this);
@ -36,6 +37,24 @@ TimeScale.prototype.init = function(config) {
this.prevScrollPos = 0; //checking the horizontal scroll (must update timeline above in case of change)
//TODO check scroll adjust.
function doneResizing() {
that.width = that.container.clientWidth;
that.height = that.container.clientHeight;
canv.setAttribute('width', that.width);
canv.setAttribute('height', that.height);
that.drawScale();
};
function onResize() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(doneResizing, 100);
};
TimeScale.prototype.onResize = onResize;
this.drawScale();
};

View file

@ -176,6 +176,7 @@ TrackEditor.prototype.loadBuffer = function(src) {
var that = this,
xhr = new XMLHttpRequest();
xhr.open('GET', src, true);
xhr.responseType = 'arraybuffer';
xhr.addEventListener('progress', function(e) {
@ -198,7 +199,6 @@ TrackEditor.prototype.loadBuffer = function(src) {
);
}, false);
xhr.open('GET', src, true);
xhr.send();
};
@ -208,11 +208,20 @@ TrackEditor.prototype.drawTrack = function(buffer) {
this.drawer.drawFades(this.fades);
};
TrackEditor.prototype.onTrackLoad = function(buffer) {
TrackEditor.prototype.onTrackLoad = function(buffer, err) {
var res,
startTime,
endTime;
if (err !== undefined) {
this.container.innerHTML = "";
this.container.classList.add("error");
this.fire('unregister');
return;
}
if (this.cues === undefined) {
this.setCuePoints(0, buffer.length - 1);
}
@ -282,6 +291,8 @@ TrackEditor.prototype.deactivate = function() {
/* start of state methods */
TrackEditor.prototype.timeShift = function(e) {
e.preventDefault();
var el = e.currentTarget, //want the events placed on the channel wrapper.
startX = e.pageX,
diffX = 0,
@ -296,6 +307,8 @@ TrackEditor.prototype.timeShift = function(e) {
//dynamically put an event on the element.
el.onmousemove = function(e) {
e.preventDefault();
var endX = e.pageX;
diffX = endX - startX;
@ -303,7 +316,9 @@ TrackEditor.prototype.timeShift = function(e) {
editor.drawer.setTimeShift(updatedX);
editor.leftOffset = editor.pixelsToSamples(updatedX);
};
el.onmouseup = function() {
el.onmouseup = function(e) {
e.preventDefault();
var delta;
el.onmousemove = el.onmouseup = null;
@ -453,6 +468,8 @@ TrackEditor.prototype.findLayerOffset = function(e) {
};
TrackEditor.prototype.selectStart = function(e) {
e.preventDefault();
var el = e.currentTarget, //want the events placed on the channel wrapper.
editor = this,
startX = e.layerX || e.offsetX, //relative to e.target (want the canvas).
@ -475,6 +492,8 @@ TrackEditor.prototype.selectStart = function(e) {
//dynamically put an event on the element.
el.onmousemove = function(e) {
e.preventDefault();
var currentX = layerOffset + (e.layerX || e.offsetX),
delta = currentX - prevX,
minX = Math.min(prevX, currentX, startX),
@ -500,6 +519,8 @@ TrackEditor.prototype.selectStart = function(e) {
prevX = currentX;
};
el.onmouseup = function(e) {
e.preventDefault();
var endX = layerOffset + (e.layerX || e.offsetX),
minX, maxX,
startTime, endTime;
@ -555,6 +576,8 @@ TrackEditor.prototype.selectCursorPos = function(e) {
};
TrackEditor.prototype.selectFadeIn = function(e) {
e.preventDefault();
var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas).
layerOffset,
FADETYPE = "FadeIn",
@ -572,6 +595,8 @@ TrackEditor.prototype.selectFadeIn = function(e) {
};
TrackEditor.prototype.selectFadeOut = function(e) {
e.preventDefault();
var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas).
layerOffset,
FADETYPE = "FadeOut",

View file

@ -365,6 +365,16 @@ def airtime_221_tar():
do_run('tar xfz airtime-2.2.1.tar.gz')
do_sudo('cd /home/martin/airtime-2.2.1/install_full/ubuntu && ./airtime-full-install')
def airtime_230_tar():
do_run('wget http://downloads.sourceforge.net/project/airtime/2.3.0/airtime-2.3.0.tar.gz')
do_run('tar xfz airtime-2.3.0.tar.gz')
do_sudo('cd /home/martin/airtime-2.3.0/install_full/ubuntu && ./airtime-full-install')
def airtime_231_tar():
do_run('wget http://downloads.sourceforge.net/project/airtime/2.3.1/airtime-2.3.1-ga.tar.gz')
do_run('tar xfz airtime-2.3.1-ga.tar.gz')
do_sudo('cd /home/martin/airtime-2.3.1/install_full/ubuntu && ./airtime-full-install')
def airtime_latest_deb():
append('/etc/apt/sources.list', "deb http://apt.sourcefabric.org/ lucid main", use_sudo=True)

View file

@ -2,11 +2,11 @@
exec 2>&1
target="airtime_git_branch:devel"
target="airtime_git_branch:2.4.x"
#target="airtime_git_branch:airtime-2.0.0-RC1"
airtime_versions=("")
airtime_versions=("airtime_231_tar")
#airtime_versions=("airtime_191_tar" "airtime_192_tar" "airtime_192_tar" "airtime_194_tar" "airtime_195_tar")
ubuntu_versions=("ubuntu_lucid_32" "ubuntu_lucid_64" "ubuntu_natty_32" "ubuntu_natty_64" "ubuntu_oneiric_32" "ubuntu_oneiric_64" "ubuntu_precise_32" "ubuntu_precise_64" "ubuntu_quantal_32" "ubuntu_quantal_64" "debian_squeeze_32" "debian_squeeze_64" "debian_wheezy_32" "debian_wheezy_64")
ubuntu_versions=("ubuntu_lucid_32" "ubuntu_lucid_64" "ubuntu_precise_32" "ubuntu_precise_64" "ubuntu_quantal_32" "ubuntu_quantal_64" "ubuntu_raring_32" "ubuntu_raring_64" "debian_squeeze_32" "debian_squeeze_64" "debian_wheezy_32" "debian_wheezy_64")
#ubuntu_versions=("debian_wheezy_32" "debian_wheezy_64")
num1=${#ubuntu_versions[@]}

View file

@ -6,7 +6,7 @@ VERSION=2.4.0~$(date "+%Y%m%d")
BUILDDEST=/tmp/airtime-${VERSION}/
DEBDIR=`pwd`/debian
git checkout master
git checkout $(git branch | grep "^*" | cut -d' ' -f 2)
git pull
echo "cleaning up previous build..."

View file

@ -0,0 +1,5 @@
[PHP]
memory_limit = 512M
magic_quotes_gpc = Off
file_uploads = On
upload_tmp_dir = /tmp

View file

@ -121,20 +121,42 @@ else
apt-get -y --force-yes install apache2 libapache2-mod-php5
# Apache Config File
echo "----------------------------------------------------"
echo "2. Apache Config File"
echo "2.1 Apache Config File"
echo "----------------------------------------------------"
if [ ! -f /etc/apache2/sites-available/airtime ]; then
echo "Creating Apache config for Airtime..."
cp $SCRIPTPATH/../apache/airtime-vhost /etc/apache2/sites-available/airtime
a2dissite default
a2ensite airtime
a2enmod rewrite php5
service apache2 restart
else
echo "Apache config for Airtime already exists..."
fi
if [ ! -d /usr/share/airtime/public ]; then
echo "Creating Apache web root directory..."
mkdir -p /usr/share/airtime/public/
else
echo "Airtime web root directory already exists..."
fi
# PHP Config File for Apache
echo "----------------------------------------------------"
echo "2.2 PHP Config File for Apache"
echo "----------------------------------------------------"
if [ ! -f /etc/php5/apache2/airtime.ini ]; then
echo "Creating Airtime PHP config for Apache..."
cp $SCRIPTPATH/../php5/airtime.ini /etc/php5/apache2/conf.d/airtime.ini
else
echo "Airtime PHP config for Apache already exists..."
fi
# Enable modules and restart Apache to enable any configuration changes
echo "----------------------------------------------------"
echo "2.3 Enable Apache Modules and Restart Apache"
echo "----------------------------------------------------"
a2enmod rewrite php5
service apache2 restart
fi
# Enable Icecast
echo "----------------------------------------------------"

View file

@ -0,0 +1,28 @@
<?php
/* This class deals with any modifications to config files in /etc/airtime
* as well as backups. All functions other than start() should be marked
* as private. */
class AirtimeConfigFileUpgrade{
public static function start(){
echo "* Updating configFiles".PHP_EOL;
self::UpdateIniFiles();
}
/**
* After the configuration files have been copied to /etc/airtime,
* this function will update them to values unique to this
* particular installation.
*/
private static function UpdateIniFiles()
{
$ini = parse_ini_file(UpgradeCommon::CONF_FILE_AIRTIME, true);
$ini['rabbitmq']['vhost'] = '/airtime';
$ini['rabbitmq']['user'] = 'airtime';
$ini['rabbitmq']['password'] = UpgradeCommon::GenerateRandomString();
UpgradeCommon::write_ini_file($ini, UpgradeCommon::CONF_FILE_AIRTIME, true);
}
}

View file

@ -1,8 +1,11 @@
<?php
require_once 'DbUpgrade.php';
require_once 'ConfFileUpgrade.php';
require_once 'common/UpgradeCommon.php';
$filename = "/etc/airtime/airtime.conf";
$values = parse_ini_file($filename, true);
AirtimeConfigFileUpgrade::start();
AirtimeDatabaseUpgrade::start($values);

View file

@ -0,0 +1,98 @@
<?php
/* These are helper functions that are common to each upgrade such as
* creating connections to a database, backing up config files etc.
*/
class UpgradeCommon{
const CONF_FILE_AIRTIME = "/etc/airtime/airtime.conf";
const CONF_FILE_PYPO = "/etc/airtime/pypo.cfg";
const CONF_FILE_LIQUIDSOAP = "/etc/airtime/liquidsoap.cfg";
const CONF_FILE_MEDIAMONITOR = "/etc/airtime/media-monitor.cfg";
const CONF_FILE_API_CLIENT = "/etc/airtime/api_client.cfg";
const CONF_PYPO_GRP = "pypo";
const CONF_WWW_DATA_GRP = "www-data";
const CONF_BACKUP_SUFFIX = "240";
const VERSION_NUMBER = "2.4.0";
private static function GetAirtimeSrcDir()
{
return __DIR__."/../../../../airtime_mvc";
}
/**
* This function generates a random string.
*
* The random string uses two parameters: $p_len and $p_chars. These
* parameters do not need to be provided, in which case defaults are
* used.
*
* @param string $p_len
* How long should the generated string be.
* @param string $p_chars
* String containing chars that should be used for generating.
* @return string
* The generated random string.
*/
public static function GenerateRandomString($p_len=20, $p_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
{
$string = '';
for ($i = 0; $i < $p_len; $i++)
{
$pos = mt_rand(0, strlen($p_chars)-1);
$string .= $p_chars{$pos};
}
return $string;
}
//stupid hack found on http://stackoverflow.com/a/1268642/276949
//with some modifications: 1) Spaces are inserted in between sections and
//2) values are not quoted.
public static function write_ini_file($assoc_arr, $path, $has_sections = false)
{
$content = "";
if ($has_sections) {
$first_line = true;
foreach ($assoc_arr as $key=>$elem) {
if ($first_line) {
$content .= "[".$key."]\n";
$first_line = false;
} else {
$content .= "\n[".$key."]\n";
}
foreach ($elem as $key2=>$elem2) {
if(is_array($elem2))
{
for($i=0;$i<count($elem2);$i++)
{
$content .= $key2."[] = \"".$elem2[$i]."\"\n";
}
}
else if($elem2=="") $content .= $key2." = \n";
else $content .= $key2." = ".$elem2."\n";
}
}
} else {
foreach ($assoc_arr as $key=>$elem) {
if(is_array($elem))
{
for($i=0;$i<count($elem);$i++)
{
$content .= $key."[] = \"".$elem[$i]."\"\n";
}
}
else if($elem=="") $content .= $key." = \n";
else $content .= $key." = ".$elem."\n";
}
}
if (!$handle = fopen($path, 'w')) {
return false;
}
if (!fwrite($handle, $content)) {
return false;
}
fclose($handle);
return true;
}
}

View file

@ -1,3 +1,16 @@
DELETE FROM cc_pref WHERE id IN (
SELECT cc_pref.id
FROM cc_pref
LEFT OUTER JOIN (
SELECT MAX(id) as id, keystr, subjid
FROM cc_pref
GROUP BY keystr, subjid
) as KeepRows ON
cc_pref.id = KeepRows.id
WHERE
KeepRows.id IS NULL
);
DELETE FROM cc_pref WHERE keystr = 'system_version';
INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '2.4.0');

View file

@ -138,8 +138,8 @@ class ApiRequest(object):
content_type = f.info().getheader('Content-Type')
response = f.read()
except Exception, e:
self.logger.error('Exception: %s', e)
self.logger.error("traceback: %s", traceback.format_exc())
#self.logger.error('Exception: %s', e)
#self.logger.error("traceback: %s", traceback.format_exc())
raise
try:
@ -149,8 +149,8 @@ class ApiRequest(object):
else:
raise InvalidContentType()
except Exception:
self.logger.error(response)
self.logger.error("traceback: %s", traceback.format_exc())
#self.logger.error(response)
#self.logger.error("traceback: %s", traceback.format_exc())
raise
def req(self, *args, **kwargs):

View file

@ -2,7 +2,7 @@
### BEGIN INIT INFO
# Provides: airtime-media-monitor
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Start: $local_fs $remote_fs $network $syslog $all
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6

View file

@ -1,5 +1,6 @@
import pyinotify
import time
import os
from pydispatch import dispatcher
from os.path import normpath
@ -186,13 +187,12 @@ class Manager(Loggable):
try: mmp.create_dir(path)
except mmp.FailedToCreateDir as e: self.unexpected_exception(e)
os.chmod(store_paths['organize'], 0775)
self.set_problem_files_path(store_paths['problem_files'])
self.set_imported_path(store_paths['imported'])
self.set_recorded_path(store_paths['recorded'])
self.set_organize_path(store_paths['organize'])
mmp.create_dir(store)
for p in store_paths.values():
mmp.create_dir(p)
def has_watch(self, path):
""" returns true if the path is being watched or not. Any kind

View file

@ -2,7 +2,7 @@
### BEGIN INIT INFO
# Provides: airtime-liquidsoap
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Start: $local_fs $remote_fs $network $syslog $all
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
@ -18,7 +18,6 @@ PIDFILE=/var/run/airtime-liquidsoap.pid
EXEC='/usr/bin/airtime-liquidsoap'
start () {
mkdir -p /var/log/airtime/pypo-liquidsoap
chown $USERID:$GROUPID /var/log/airtime/pypo-liquidsoap
@ -36,9 +35,19 @@ start () {
}
stop () {
timeout --version >/dev/null 2>&1
RESULT="$?"
#send term signal after 10 seconds
if [ "$RESULT" = "0" ]; then
timeout -s9 10s /usr/lib/airtime/airtime_virtualenv/bin/python \
/usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
else
#some earlier versions of Ubuntu (Lucid) had a different timeout
#command that takes different input parameters.
timeout 10 /usr/lib/airtime/airtime_virtualenv/bin/python \
/usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
fi
# Send TERM after 5 seconds, wait at most 30 seconds.
#start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --pidfile $PIDFILE
start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --exec $EXEC

View file

@ -2,7 +2,7 @@
### BEGIN INIT INFO
# Provides: airtime-playout
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Start: $local_fs $remote_fs $network $syslog $all
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6

View file

@ -88,8 +88,8 @@ try:
if "airtime_service_start" in os.environ and os.environ["airtime_service_start"] == "t":
print "* Waiting for pypo processes to start..."
subprocess.call("invoke-rc.d airtime-playout start > /dev/null 2>&1", shell=True)
subprocess.call("invoke-rc.d airtime-liquidsoap start > /dev/null 2>&1", shell=True)
subprocess.call("invoke-rc.d airtime-playout start > /dev/null 2>&1", shell=True)
except Exception, e:
print e

View file

@ -0,0 +1,24 @@
if bitrate == 24 then
ignore(output_stereo(%fdkaac(bitrate = 24, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 32 then
ignore(output_stereo(%fdkaac(bitrate = 32, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 48 then
ignore(output_stereo(%fdkaac(bitrate = 48, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 64 then
ignore(output_stereo(%fdkaac(bitrate = 64, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 96 then
ignore(output_stereo(%fdkaac(bitrate = 96, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 128 then
ignore(output_stereo(%fdkaac(bitrate = 128, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 160 then
ignore(output_stereo(%fdkaac(bitrate = 160, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 192 then
ignore(output_stereo(%fdkaac(bitrate = 192, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 224 then
ignore(output_stereo(%fdkaac(bitrate = 224, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 256 then
ignore(output_stereo(%fdkaac(bitrate = 256, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 320 then
ignore(output_stereo(%fdkaac(bitrate = 320, aot="mpeg4_he_aac_v2"), !source))
end

View file

@ -1,6 +1,7 @@
import logging
import sys
import time
import traceback
from api_clients.api_client import AirtimeApiClient
def generate_liquidsoap_config(ss):
@ -26,19 +27,21 @@ def generate_liquidsoap_config(ss):
fh.close()
logging.basicConfig(format='%(message)s')
ac = AirtimeApiClient(logging.getLogger())
attempts = 0
max_attempts = 5
max_attempts = 10
successful = False
while True:
while not successful:
try:
ac = AirtimeApiClient(logging.getLogger())
ss = ac.get_stream_setting()
generate_liquidsoap_config(ss)
break
successful = True
except Exception, e:
if attempts == max_attempts:
print "Unable to connect to the Airtime server."
logging.error(str(e))
logging.error("traceback: %s", traceback.format_exc())
sys.exit(1)
else:
time.sleep(3)

Some files were not shown because too many files have changed in this diff Show more