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
* 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
- 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:

View file

@ -61,38 +61,6 @@ $CC_CONFIG = array(
'zendPath' => dirname(__FILE__).'/../../library/Zend',
'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
@ -119,11 +87,6 @@ $CC_CONFIG['permSequence'] = $CC_CONFIG['permTable'].'_id';
$CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_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
$old_include_path = get_include_path();
set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath']

View file

@ -104,8 +104,6 @@ class ApiController extends Zend_Controller_Action
}
public function liveInfoAction(){
global $CC_CONFIG;
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
@ -126,6 +124,22 @@ class ApiController extends Zend_Controller_Action
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()
{
global $CC_CONFIG;

View file

@ -466,6 +466,30 @@ class Schedule {
{
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"
." 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"
@ -473,6 +497,7 @@ class Schedule {
." AND st.instance_id = si.id"
." AND si.show_id = show.id"
." AND st.starts < si.ends";
*/
if ($timePeriod < 0){
$sql .= " AND st.ends < TIMESTAMP '$timeStamp'"
@ -628,16 +653,23 @@ class Schedule {
* @param string $p_toDateTime
* 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;
if (is_null($p_fromDateTime)) {
$t1 = new DateTime();
$range_start = $t1->format("Y-m-d H:i:s");
} else {
$range_start = Schedule::PypoTimeToAirtimeTime($p_fromDateTime);
}
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
$data = Schedule::GetItems($range_start, $range_end, true);

View file

@ -58,6 +58,24 @@ class Show {
$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)
{
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'))"
//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)"
." 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);
}

View file

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

View file

@ -24,13 +24,6 @@
<index-column name="token"/>
</index>
</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">
<column name="id" phpName="DbId" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
<column name="gunid" phpName="DbGunid" type="char" size="32" required="true"/>
@ -295,45 +288,4 @@
<unique-column name="login"/>
</unique>
</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>

View file

@ -52,9 +52,6 @@ AirtimeInstall::CreateSymlinks($CC_CONFIG["storageDir"]);
echo "* Importing sample audio clips".PHP_EOL;
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;
system("python ".__DIR__."/../python_apps/pypo/install/pypo-install.py");

View file

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

View file

@ -6,6 +6,7 @@
sourceDomain: "http://localhost/", //where to get show status from
};
var options = $.extend(defaults, options);
options.sourceDomain = addEndingBackslash(options.sourceDomain);
return this.each(function() {
var obj = $(this);
@ -58,7 +59,7 @@
$.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){
processData(data);
}, error:function(jqXHR, textStatus, errorThrown){}});
setTimeout(getServerData, defaults.updatePeriod*1000);
setTimeout(getServerData, options.updatePeriod*1000);
}
});
};
@ -71,9 +72,10 @@
var defaults = {
updatePeriod: 5, //seconds
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);
options.sourceDomain = addEndingBackslash(options.sourceDomain);
return this.each(function() {
var obj = $(this);
@ -106,7 +108,7 @@
}
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("<ul class='widget no-playing-bar'>" +
"<li class='current'>Current: "+currentShowName+
@ -129,12 +131,111 @@
$.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){
processData(data);
}, error:function(jqXHR, textStatus, errorThrown){}});
setTimeout(getServerData, defaults.updatePeriod*1000);
setTimeout(getServerData, options.updatePeriod*1000);
}
});
};
})(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 */
function ScheduleData(data){
this.data = data;

View file

@ -61,7 +61,7 @@ class ShowRecorder(Thread):
filename = self.filename.replace(" ", "-")
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(" ")
print "starting record"