Merge branch 'master' of dev.sourcefabric.org:airtime

This commit is contained in:
Paul Baranowski 2011-03-29 17:32:20 -04:00
commit 45fe719ea6
11 changed files with 219 additions and 113 deletions

View file

@ -29,8 +29,19 @@ Linked code:
- License: LGPLv3 - License: LGPLv3
* Soundcloud php api wrapper * Soundcloud php api wrapper
- https://github.com/mptre/php-soundcloud/blob/master/Services/Soundcloud.php - Web site: https://github.com/mptre/php-soundcloud/blob/master/Services/Soundcloud.php
- License: MIT - License: MIT
- Compatible with the GPL: Yes. See http://www.gnu.org/licenses/license-list.html
* Kombu
- Web site: http://pypi.python.org/pypi/kombu/
- License: New BSD
- Compatible with GPLv3? Yes.
* PHP-AMQPLIB
- Web site: https://github.com/tnc/php-amqplib
- License: LGPLv2.1
- Compatible with GPLv3? Yes
---------------- ----------------
Non-linked code: Non-linked code:

View file

@ -61,38 +61,6 @@ $CC_CONFIG = array(
'zendPath' => dirname(__FILE__).'/../../library/Zend', 'zendPath' => dirname(__FILE__).'/../../library/Zend',
'phingPath' => dirname(__FILE__).'/../../library/phing', 'phingPath' => dirname(__FILE__).'/../../library/phing',
// name of admin group
//'AdminsGr' => 'Admins',
// name of station preferences group
// 'StationPrefsGr'=> 'StationPrefs',
// name of 'all users' group
//'AllGr' => 'All',
/* ==================================== application-specific configuration */
// 'objtypes' => array(
// 'Storage' => array(/*'Folder',*/ 'File' /*, 'Replica'*/),
// 'File' => array(),
// 'audioclip' => array(),
// 'playlist' => array(),
// ),
// 'allowedActions'=> array(
// 'File' => array('editPrivs', 'write', 'read'),
// 'audioclip' => array('editPrivs', 'write', 'read'),
// 'playlist' => array('editPrivs', 'write', 'read'),
// ),
// 'allActions' => array(
// 'editPrivs', 'write', 'read', 'subjects'
// ),
/* =================================================== cron configuration */
'cronUserName' => 'www-data',
# 'lockfile' => dirname(__FILE__).'/cron/cron.lock',
'lockfile' => dirname(__FILE__).'/stor/buffer/cron.lock',
'cronfile' => dirname(__FILE__).'/cron/croncall.php',
'paramdir' => dirname(__FILE__).'/cron/params',
// 'systemPrefId' => "0", // ID for system prefs in prefs table
); );
// Add database table names // Add database table names
@ -119,11 +87,6 @@ $CC_CONFIG['permSequence'] = $CC_CONFIG['permTable'].'_id';
$CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_id'; $CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_id';
$CC_CONFIG['smembSequence'] = $CC_CONFIG['smembTable'].'_id'; $CC_CONFIG['smembSequence'] = $CC_CONFIG['smembTable'].'_id';
// System users/groups - they cannot be deleted
//$CC_CONFIG['sysSubjs'] = array(
// 'root', /*$CC_CONFIG['AdminsGr'],*/ /*$CC_CONFIG['AllGr'],*/ $CC_CONFIG['StationPrefsGr']
//);
// Add libs to the PHP path // Add libs to the PHP path
$old_include_path = get_include_path(); $old_include_path = get_include_path();
set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath'] set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath']

View file

@ -104,8 +104,6 @@ class ApiController extends Zend_Controller_Action
} }
public function liveInfoAction(){ public function liveInfoAction(){
global $CC_CONFIG;
// disable the view and the layout // disable the view and the layout
$this->view->layout()->disableLayout(); $this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true); $this->_helper->viewRenderer->setNoRender(true);
@ -126,6 +124,22 @@ class ApiController extends Zend_Controller_Action
echo $_GET['callback'].'('.json_encode($result).')'; echo $_GET['callback'].'('.json_encode($result).')';
} }
public function weekInfoAction(){
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$dow = array("sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday");
$result = array();
for ($i=0; $i<7; $i++){
$result[$dow[$i]] = Show_DAL::GetShowsByDayOfWeek($i);
}
header("Content-type: text/javascript");
echo $_GET['callback'].'('.json_encode($result).')';
}
public function scheduleAction() public function scheduleAction()
{ {
global $CC_CONFIG; global $CC_CONFIG;

View file

@ -466,6 +466,30 @@ class Schedule {
{ {
global $CC_CONFIG, $CC_DBC; global $CC_CONFIG, $CC_DBC;
$sql = "SELECT DISTINCT"
." pt.name,"
." ft.track_title,"
." ft.artist_name,"
." ft.album_title,"
." st.starts,"
." st.ends,"
." st.clip_length,"
." st.media_item_played,"
." st.group_id,"
." show.name as show_name,"
." st.instance_id"
." FROM $CC_CONFIG[scheduleTable] st"
." LEFT JOIN $CC_CONFIG[filesTable] ft"
." ON st.file_id = ft.id"
." LEFT JOIN $CC_CONFIG[playListTable] pt"
." ON st.playlist_id = pt.id"
." LEFT JOIN $CC_CONFIG[showInstances] si"
." ON st.instance_id = si.id"
." LEFT JOIN $CC_CONFIG[showTable] show"
." ON si.show_id = show.id"
." WHERE st.starts < si.ends";
/*
$sql = "SELECT DISTINCT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, st.media_item_played, st.group_id, show.name as show_name, st.instance_id" $sql = "SELECT DISTINCT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, st.media_item_played, st.group_id, show.name as show_name, st.instance_id"
." FROM $CC_CONFIG[scheduleTable] st, $CC_CONFIG[filesTable] ft, $CC_CONFIG[playListTable] pt, $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] show" ." FROM $CC_CONFIG[scheduleTable] st, $CC_CONFIG[filesTable] ft, $CC_CONFIG[playListTable] pt, $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] show"
." WHERE st.playlist_id = pt.id" ." WHERE st.playlist_id = pt.id"
@ -473,6 +497,7 @@ class Schedule {
." AND st.instance_id = si.id" ." AND st.instance_id = si.id"
." AND si.show_id = show.id" ." AND si.show_id = show.id"
." AND st.starts < si.ends"; ." AND st.starts < si.ends";
*/
if ($timePeriod < 0){ if ($timePeriod < 0){
$sql .= " AND st.ends < TIMESTAMP '$timeStamp'" $sql .= " AND st.ends < TIMESTAMP '$timeStamp'"
@ -628,17 +653,24 @@ class Schedule {
* @param string $p_toDateTime * @param string $p_toDateTime
* In the format "YYYY-MM-DD-HH-mm-SS" * In the format "YYYY-MM-DD-HH-mm-SS"
*/ */
public static function GetScheduledPlaylists() public static function GetScheduledPlaylists($p_fromDateTime = null, $p_toDateTime = null)
{ {
global $CC_CONFIG, $CC_DBC; global $CC_CONFIG, $CC_DBC;
$t1 = new DateTime(); if (is_null($p_fromDateTime)) {
$range_start = $t1->format("Y-m-d H:i:s"); $t1 = new DateTime();
$range_start = $t1->format("Y-m-d H:i:s");
$t2 = new DateTime(); } else {
$t2->add(new DateInterval("PT24H")); $range_start = Schedule::PypoTimeToAirtimeTime($p_fromDateTime);
$range_end = $t2->format("Y-m-d H:i:s"); }
if (is_null($p_fromDateTime)) {
$t2 = new DateTime();
$t2->add(new DateInterval("PT24H"));
$range_end = $t2->format("Y-m-d H:i:s");
} else {
$range_end = Schedule::PypoTimeToAirtimeTime($p_toDateTime);
}
// Scheduler wants everything in a playlist // Scheduler wants everything in a playlist
$data = Schedule::GetItems($range_start, $range_end, true); $data = Schedule::GetItems($range_start, $range_end, true);
$playlists = array(); $playlists = array();

View file

@ -58,6 +58,24 @@ class Show {
$show->setDbBackgroundColor($backgroundColor); $show->setDbBackgroundColor($backgroundColor);
} }
public function getHosts()
{
global $CC_DBC;
$sql = "SELECT first_name, last_name
FROM cc_show_hosts LEFT JOIN cc_subjs ON cc_show_hosts.subjs_id = cc_subjs.id
WHERE show_id = {$this->_showId}";
$hosts = $CC_DBC->GetAll($sql);
$res = array();
foreach($hosts as $host) {
$res[] = $host['first_name']." ".$host['last_name'];
}
return $res;
}
public function cancelShow($day_timestamp) public function cancelShow($day_timestamp)
{ {
global $CC_DBC; global $CC_DBC;
@ -930,7 +948,31 @@ class Show_DAL {
." OR (si.starts < TIMESTAMP '$timeNow' + INTERVAL '$end seconds' AND si.ends > TIMESTAMP '$timeNow' + INTERVAL '$end seconds'))" ." OR (si.starts < TIMESTAMP '$timeNow' + INTERVAL '$end seconds' AND si.ends > TIMESTAMP '$timeNow' + INTERVAL '$end seconds'))"
//checking for st.starts IS NULL so that the query also returns shows that do not have any items scheduled. //checking for st.starts IS NULL so that the query also returns shows that do not have any items scheduled.
." AND (st.starts < si.ends OR st.starts IS NULL)" ." AND (st.starts < si.ends OR st.starts IS NULL)"
." ORDER BY st.starts"; ." ORDER BY si.starts, st.starts";
return $CC_DBC->GetAll($sql);
}
public static function GetShowsByDayOfWeek($day){
//DOW FROM TIMESTAMP
//The day of the week (0 - 6; Sunday is 0) (for timestamp values only)
//SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
//Result: 5
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT"
." si.starts as show_starts,"
." si.ends as show_ends,"
." s.name as show_name,"
." s.url as url"
." FROM $CC_CONFIG[showInstances] si"
." LEFT JOIN $CC_CONFIG[showTable] s"
." ON si.show_id = s.id"
." WHERE EXTRACT(DOW FROM si.starts) = $day"
." AND EXTRACT(WEEK FROM si.starts) = EXTRACT(WEEK FROM localtimestamp)";
//echo $sql;
return $CC_DBC->GetAll($sql); return $CC_DBC->GetAll($sql);
} }

View file

@ -1481,7 +1481,8 @@ class StoredFile {
public function getFileUrl() public function getFileUrl()
{ {
global $CC_CONFIG; global $CC_CONFIG;
return "http://".$CC_CONFIG["storageUrlHost"] return "http://$CC_CONFIG[storageUrlHost]"
.":$CC_CONFIG[storageUrlPort]"
.$CC_CONFIG["apiPath"]."get-media/file/" .$CC_CONFIG["apiPath"]."get-media/file/"
.$this->gunid.".".$this->getFileExtension(); .$this->gunid.".".$this->getFileExtension();
} }

View file

@ -24,13 +24,6 @@
<index-column name="token"/> <index-column name="token"/>
</index> </index>
</table> </table>
<table name="cc_backup" phpName="CcBackup">
<column name="token" phpName="Token" type="VARCHAR" size="64" primaryKey="true" required="true"/>
<column name="sessionid" phpName="Sessionid" type="VARCHAR" size="64" required="true"/>
<column name="status" phpName="Status" type="VARCHAR" size="32" required="true"/>
<column name="fromtime" phpName="Fromtime" type="TIMESTAMP" required="true"/>
<column name="totime" phpName="Totime" type="TIMESTAMP" required="true"/>
</table>
<table name="cc_files" phpName="CcFiles"> <table name="cc_files" phpName="CcFiles">
<column name="id" phpName="DbId" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/> <column name="id" phpName="DbId" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
<column name="gunid" phpName="DbGunid" type="char" size="32" required="true"/> <column name="gunid" phpName="DbGunid" type="char" size="32" required="true"/>
@ -295,45 +288,4 @@
<unique-column name="login"/> <unique-column name="login"/>
</unique> </unique>
</table> </table>
<table name="cc_trans" phpName="CcTrans">
<column name="id" phpName="Id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
<column name="trtok" phpName="Trtok" type="CHAR" size="16" required="true"/>
<column name="direction" phpName="Direction" type="VARCHAR" size="128" required="true"/>
<column name="state" phpName="State" type="VARCHAR" size="128" required="true"/>
<column name="trtype" phpName="Trtype" type="VARCHAR" size="128" required="true"/>
<column name="lock" phpName="Lock" type="CHAR" size="1" required="true" defaultValue="N"/>
<column name="target" phpName="Target" type="VARCHAR" size="255" required="false" defaultValue="NULL"/>
<column name="rtrtok" phpName="Rtrtok" type="CHAR" size="16" required="false" defaultValue="NULL"/>
<column name="mdtrtok" phpName="Mdtrtok" type="CHAR" size="16" required="false"/>
<column name="gunid" phpName="Gunid" type="char" size="32" required="false"/>
<column name="pdtoken" phpName="Pdtoken" type="BIGINT" required="false"/>
<column name="url" phpName="Url" type="VARCHAR" size="255" required="false"/>
<column name="localfile" phpName="Localfile" type="VARCHAR" size="255" required="false"/>
<column name="fname" phpName="Fname" type="VARCHAR" size="255" required="false"/>
<column name="title" phpName="Title" type="VARCHAR" size="255" required="false"/>
<column name="expectedsum" phpName="Expectedsum" type="CHAR" size="32" required="false"/>
<column name="realsum" phpName="Realsum" type="CHAR" size="32" required="false"/>
<column name="expectedsize" phpName="Expectedsize" type="INTEGER" required="false"/>
<column name="realsize" phpName="Realsize" type="INTEGER" required="false"/>
<column name="uid" phpName="Uid" type="INTEGER" required="false"/>
<column name="errmsg" phpName="Errmsg" type="VARCHAR" size="255" required="false"/>
<column name="jobpid" phpName="Jobpid" type="INTEGER" required="false"/>
<column name="start" phpName="Start" type="TIMESTAMP" required="false"/>
<column name="ts" phpName="Ts" type="TIMESTAMP" required="false"/>
<index name="cc_trans_gunid_idx">
<index-column name="gunid"/>
</index>
<unique name="cc_trans_id_idx">
<unique-column name="id"/>
</unique>
<index name="cc_trans_state_idx">
<index-column name="state"/>
</index>
<unique name="cc_trans_token_idx">
<unique-column name="pdtoken"/>
</unique>
<unique name="cc_trans_trtok_idx">
<unique-column name="trtok"/>
</unique>
</table>
</database> </database>

View file

@ -52,9 +52,6 @@ AirtimeInstall::CreateSymlinks($CC_CONFIG["storageDir"]);
echo "* Importing sample audio clips".PHP_EOL; echo "* Importing sample audio clips".PHP_EOL;
system(__DIR__."/../utils/airtime-import --copy ../audio_samples/ > /dev/null"); system(__DIR__."/../utils/airtime-import --copy ../audio_samples/ > /dev/null");
echo "* Python eggs Setup".PHP_EOL;
AirtimeInstall::SetUpPythonEggs();
echo PHP_EOL."*** Pypo Installation ***".PHP_EOL; echo PHP_EOL."*** Pypo Installation ***".PHP_EOL;
system("python ".__DIR__."/../python_apps/pypo/install/pypo-install.py"); system("python ".__DIR__."/../python_apps/pypo/install/pypo-install.py");

View file

@ -203,13 +203,6 @@ class AirtimeInstall {
system($command); system($command);
} }
public static function SetUpPythonEggs()
{
//install poster streaming upload
$command = "sudo easy_install poster";
@exec($command);
}
public static function DeleteFilesRecursive($p_path) public static function DeleteFilesRecursive($p_path)
{ {
$command = "rm -rf $p_path"; $command = "rm -rf $p_path";

View file

@ -6,6 +6,7 @@
sourceDomain: "http://localhost/", //where to get show status from sourceDomain: "http://localhost/", //where to get show status from
}; };
var options = $.extend(defaults, options); var options = $.extend(defaults, options);
options.sourceDomain = addEndingBackslash(options.sourceDomain);
return this.each(function() { return this.each(function() {
var obj = $(this); var obj = $(this);
@ -58,7 +59,7 @@
$.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){ $.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){
processData(data); processData(data);
}, error:function(jqXHR, textStatus, errorThrown){}}); }, error:function(jqXHR, textStatus, errorThrown){}});
setTimeout(getServerData, defaults.updatePeriod*1000); setTimeout(getServerData, options.updatePeriod*1000);
} }
}); });
}; };
@ -71,9 +72,10 @@
var defaults = { var defaults = {
updatePeriod: 5, //seconds updatePeriod: 5, //seconds
sourceDomain: "http://localhost/", //where to get show status from sourceDomain: "http://localhost/", //where to get show status from
audioStreamSource: "" //where to get audio stream from audioStreamSource: "http://localhost:8000/airtime.mp3" //where to get audio stream from
}; };
var options = $.extend(defaults, options); var options = $.extend(defaults, options);
options.sourceDomain = addEndingBackslash(options.sourceDomain);
return this.each(function() { return this.each(function() {
var obj = $(this); var obj = $(this);
@ -106,7 +108,7 @@
} }
obj.empty(); obj.empty();
obj.append("<a id='listenWadrLive'><span>Listen WADR Live</span></a>"); obj.append("<a id='listenWadrLive' href='"+options.audioStreamSource+"'><span>Listen WADR Live</span></a>");
obj.append("<h4>"+showStatus+" &gt;&gt;</h4>"); obj.append("<h4>"+showStatus+" &gt;&gt;</h4>");
obj.append("<ul class='widget no-playing-bar'>" + obj.append("<ul class='widget no-playing-bar'>" +
"<li class='current'>Current: "+currentShowName+ "<li class='current'>Current: "+currentShowName+
@ -129,12 +131,111 @@
$.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){ $.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){
processData(data); processData(data);
}, error:function(jqXHR, textStatus, errorThrown){}}); }, error:function(jqXHR, textStatus, errorThrown){}});
setTimeout(getServerData, defaults.updatePeriod*1000); setTimeout(getServerData, options.updatePeriod*1000);
} }
}); });
}; };
})(jQuery); })(jQuery);
(function($){
$.fn.airtimeWeekSchedule = function(options) {
var defaults = {
sourceDomain: "http://localhost/", //where to get show status from
updatePeriod: 600,
dowText: {monday:"Monday", tuesday:"Tuesday", wednesday:"Wednesday", thursday:"Thursday", friday:"Friday", saturday:"Saturday", sunday:"Sunday"},
miscText: {time:"Time", programName:"Program Name", details:"Details", readMore:"Read More"}
};
var options = $.extend(defaults, options);
options.sourceDomain = addEndingBackslash(options.sourceDomain);
return this.each(function() {
var obj = $(this);
obj.empty();
obj.attr("class", "ui-tabs");
var dow = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"];
var html = '<ul>';
for (var i=0; i<dow.length; i++){
html += '<li><a href="#'+dow[i]+'">'+options.dowText[dow[i]]+'</a></li>';
}
html += '</ul>';
for (var i=0; i<dow.length; i++){
html += '<div id="'+dow[i]+'" class="ui-tabs-hide"></div>'
}
obj.append(html);
getServerData();
function updateWidget(data){
for (var i=0; i<dow.length; i++){
var html =
'<table class="widget widget no-playing-list">'+
'<colgroup>'+
'<col width="150" />'+
'<col width="350" />'+
'<col width="240" />'+
'</colgroup>'+
'<thead>'+
'<tr>'+
'<td>'+options.miscText.time+'</td>'+
'<td>'+options.miscText.programName+'</td>'+
'<td>'+options.miscText.details+'</td>'+
'</tr>'+
'</thead>'+
'<tfoot>'+
'<tr>'+
'<td></td>'+
'</tr>'+
'</tfoot>'+
'<tbody>';
var daySchedule = data[dow[i]];
for (var j=0; j<daySchedule.length; j++){
var url = daySchedule[j].url;
html +=
'<tr>'+
'<td>'+getTime(daySchedule[j].show_starts)+ " - " + getTime(daySchedule[j].show_ends)+'</td>'+
'<td>'+
'<h4>'+daySchedule[j].show_name+'</h4>'+
'</td>'+
'<td>'+
'<ul>'+
'<li>'+(url.length > 0 ? '<a href="'+url+'">'+options.miscText.readMore+'</a>':'')+'</li>'+
'</ul>'+
'</td>'+
'</tr>';
}
html +=
'</tbody>'+
'</table>';
$("#"+dow[i]).empty();
$("#"+dow[i]).append(html);
}
}
function processData(data){
updateWidget(data);
}
function getServerData(){
$.ajax({ url: options.sourceDomain + "api/week-info/", dataType:"jsonp", success:function(data){
processData(data);
}, error:function(jqXHR, textStatus, errorThrown){}});
setTimeout(getServerData, options.updatePeriod*1000);
}
});
};
})(jQuery);
function addEndingBackslash(str){
if (str.charAt(str.length-1) != '/')
return str+'/';
else return str;
}
/* ScheduleData class BEGIN */ /* ScheduleData class BEGIN */
function ScheduleData(data){ function ScheduleData(data){
this.data = data; this.data = data;

View file

@ -61,7 +61,7 @@ class ShowRecorder(Thread):
filename = self.filename.replace(" ", "-") filename = self.filename.replace(" ", "-")
filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype) filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype)
command = "ecasound -i alsa -o %s -t:%s" % (filepath, length) command = "ecasound -i alsa -o %s -t:%s -ge:3,1,0,-1" % (filepath, length)
args = command.split(" ") args = command.split(" ")
print "starting record" print "starting record"