Merge branch 'master' of dev.sourcefabric.org:airtime
This commit is contained in:
commit
c4b632e8ad
|
@ -109,6 +109,16 @@ class ApiController extends Zend_Controller_Action
|
||||||
$this->_helper->viewRenderer->setNoRender(true);
|
$this->_helper->viewRenderer->setNoRender(true);
|
||||||
|
|
||||||
$result = Schedule::GetPlayOrderRange(0, 1);
|
$result = Schedule::GetPlayOrderRange(0, 1);
|
||||||
|
|
||||||
|
$date = new Application_Model_DateHelper;
|
||||||
|
$timeNow = $date->getDate();
|
||||||
|
$result = array("env"=>APPLICATION_ENV,
|
||||||
|
"schedulerTime"=>gmdate("Y-m-d H:i:s"),
|
||||||
|
"currentShow"=>Show_DAL::GetCurrentShow($timeNow),
|
||||||
|
"nextShow"=>Show_DAL::GetNextShows($timeNow, 5),
|
||||||
|
"timezone"=> date("T"),
|
||||||
|
"timezoneOffset"=> date("Z"));
|
||||||
|
|
||||||
//echo json_encode($result);
|
//echo json_encode($result);
|
||||||
header("Content-type: text/javascript");
|
header("Content-type: text/javascript");
|
||||||
echo $_GET['callback'].'('.json_encode($result).')';
|
echo $_GET['callback'].'('.json_encode($result).')';
|
||||||
|
|
|
@ -24,41 +24,6 @@ class ScheduleGroup {
|
||||||
return $result != "0";
|
return $result != "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a date to an ID by stripping out all characters
|
|
||||||
* and padding with zeros.
|
|
||||||
*
|
|
||||||
* @param string $p_dateStr
|
|
||||||
*/
|
|
||||||
public static function dateToId($p_dateStr) {
|
|
||||||
$p_dateStr = str_replace(":", "", $p_dateStr);
|
|
||||||
$p_dateStr = str_replace(" ", "", $p_dateStr);
|
|
||||||
$p_dateStr = str_replace(".", "", $p_dateStr);
|
|
||||||
$p_dateStr = str_replace("-", "", $p_dateStr);
|
|
||||||
$p_dateStr = substr($p_dateStr, 0, 17);
|
|
||||||
$p_dateStr = str_pad($p_dateStr, 17, "0");
|
|
||||||
return $p_dateStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the two times together, return the result.
|
|
||||||
*
|
|
||||||
* @param string $p_baseTime
|
|
||||||
* Specified as YYYY-MM-DD HH:MM:SS
|
|
||||||
*
|
|
||||||
* @param string $p_addTime
|
|
||||||
* Specified as HH:MM:SS.nnnnnn
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
* The end time, to the nearest second.
|
|
||||||
*/
|
|
||||||
// protected function calculateEndTime($p_startTime, $p_trackTime) {
|
|
||||||
// $p_trackTime = substr($p_startTime, 0, );
|
|
||||||
// $start = new DateTime();
|
|
||||||
// $interval = new DateInterval()
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a music clip or playlist to the schedule.
|
* Add a music clip or playlist to the schedule.
|
||||||
*
|
*
|
||||||
|
@ -77,6 +42,7 @@ class ScheduleGroup {
|
||||||
*/
|
*/
|
||||||
public function add($show_instance, $p_datetime, $p_audioFileId = null, $p_playlistId = null, $p_options = null) {
|
public function add($show_instance, $p_datetime, $p_audioFileId = null, $p_playlistId = null, $p_options = null) {
|
||||||
global $CC_CONFIG, $CC_DBC;
|
global $CC_CONFIG, $CC_DBC;
|
||||||
|
|
||||||
if (!is_null($p_audioFileId)) {
|
if (!is_null($p_audioFileId)) {
|
||||||
// Schedule a single audio track
|
// Schedule a single audio track
|
||||||
|
|
||||||
|
@ -92,26 +58,24 @@ class ScheduleGroup {
|
||||||
if (empty($length)) {
|
if (empty($length)) {
|
||||||
return new PEAR_Error("Length is empty.");
|
return new PEAR_Error("Length is empty.");
|
||||||
}
|
}
|
||||||
if (!Schedule::isScheduleEmptyInRange($p_datetime, $length)) {
|
|
||||||
return new PEAR_Error("Schedule conflict.", 555);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert into the table
|
// Insert into the table
|
||||||
$this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')");
|
$this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')");
|
||||||
$id = $this->dateToId($p_datetime);
|
|
||||||
$sql = "INSERT INTO ".$CC_CONFIG["scheduleTable"]
|
$sql = "INSERT INTO ".$CC_CONFIG["scheduleTable"]
|
||||||
." (playlist_id, starts, ends, clip_length, group_id, file_id)"
|
." (instance_id, starts, ends, clip_length, group_id, file_id, cue_out)"
|
||||||
." VALUES (0, TIMESTAMP '$p_datetime', "
|
." VALUES ($show_instance, TIMESTAMP '$p_datetime', "
|
||||||
." (TIMESTAMP '$p_datetime' + INTERVAL '$length'),"
|
." (TIMESTAMP '$p_datetime' + INTERVAL '$length'),"
|
||||||
." '$length',"
|
." '$length',"
|
||||||
." {$this->groupId}, $p_audioFileId)";
|
." {$this->groupId}, $p_audioFileId, '$length')";
|
||||||
$result = $CC_DBC->query($sql);
|
$result = $CC_DBC->query($sql);
|
||||||
if (PEAR::isError($result)) {
|
if (PEAR::isError($result)) {
|
||||||
//var_dump($sql);
|
//var_dump($sql);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} elseif (!is_null($p_playlistId)){
|
}
|
||||||
|
elseif (!is_null($p_playlistId)){
|
||||||
// Schedule a whole playlist
|
// Schedule a whole playlist
|
||||||
|
|
||||||
// Load existing playlist
|
// Load existing playlist
|
||||||
|
@ -129,7 +93,6 @@ class ScheduleGroup {
|
||||||
|
|
||||||
// Insert all items into the schedule
|
// Insert all items into the schedule
|
||||||
$this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')");
|
$this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')");
|
||||||
$id = $this->dateToId($p_datetime);
|
|
||||||
$itemStartTime = $p_datetime;
|
$itemStartTime = $p_datetime;
|
||||||
|
|
||||||
$plItems = $playlist->getContents();
|
$plItems = $playlist->getContents();
|
||||||
|
@ -150,14 +113,13 @@ class ScheduleGroup {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
$itemStartTime = $CC_DBC->getOne("SELECT TIMESTAMP '$itemStartTime' + INTERVAL '$trackLength'");
|
$itemStartTime = $CC_DBC->getOne("SELECT TIMESTAMP '$itemStartTime' + INTERVAL '$trackLength'");
|
||||||
$id = $this->dateToId($itemStartTime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RabbitMq::PushSchedule();
|
RabbitMq::PushSchedule();
|
||||||
return $this->groupId;
|
return $this->groupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addAfter($show_instance, $p_groupId, $p_audioFileId) {
|
public function addFileAfter($show_instance, $p_groupId, $p_audioFileId) {
|
||||||
global $CC_CONFIG, $CC_DBC;
|
global $CC_CONFIG, $CC_DBC;
|
||||||
// Get the end time for the given entry
|
// Get the end time for the given entry
|
||||||
$sql = "SELECT MAX(ends) FROM ".$CC_CONFIG["scheduleTable"]
|
$sql = "SELECT MAX(ends) FROM ".$CC_CONFIG["scheduleTable"]
|
||||||
|
@ -471,7 +433,7 @@ class Schedule {
|
||||||
"current"=>Schedule::GetScheduledItemData($timeNow, 0),
|
"current"=>Schedule::GetScheduledItemData($timeNow, 0),
|
||||||
"next"=>Schedule::GetScheduledItemData($timeNow, 1, $next, "48 hours"),
|
"next"=>Schedule::GetScheduledItemData($timeNow, 1, $next, "48 hours"),
|
||||||
"currentShow"=>Show_DAL::GetCurrentShow($timeNow),
|
"currentShow"=>Show_DAL::GetCurrentShow($timeNow),
|
||||||
"nextShow"=>Show_DAL::GetNextShow($timeNow),
|
"nextShow"=>Show_DAL::GetNextShows($timeNow, 1),
|
||||||
"timezone"=> date("T"),
|
"timezone"=> date("T"),
|
||||||
"timezoneOffset"=> date("Z"),
|
"timezoneOffset"=> date("Z"),
|
||||||
"apiKey"=>$CC_CONFIG['apiKey'][0]);
|
"apiKey"=>$CC_CONFIG['apiKey'][0]);
|
||||||
|
|
|
@ -678,7 +678,7 @@ class ShowInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addPlaylistToShow($plId)
|
public function addPlaylistToShow($plId)
|
||||||
{
|
{
|
||||||
$sched = new ScheduleGroup();
|
$sched = new ScheduleGroup();
|
||||||
$lastGroupId = $this->getLastGroupId();
|
$lastGroupId = $this->getLastGroupId();
|
||||||
|
|
||||||
|
@ -692,12 +692,26 @@ class ShowInstance {
|
||||||
RabbitMq::PushSchedule();
|
RabbitMq::PushSchedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scheduleShow($plIds)
|
public function addFileToShow($file_id)
|
||||||
{
|
{
|
||||||
|
$sched = new ScheduleGroup();
|
||||||
|
$lastGroupId = $this->getLastGroupId();
|
||||||
|
|
||||||
|
if(is_null($lastGroupId)) {
|
||||||
|
|
||||||
|
$groupId = $sched->add($this->_instanceId, $this->getShowStart(), $file_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$groupId = $sched->addFileAfter($this->_instanceId, $lastGroupId, $file_id);
|
||||||
|
}
|
||||||
|
RabbitMq::PushSchedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scheduleShow($plIds) {
|
||||||
|
|
||||||
foreach($plIds as $plId) {
|
foreach($plIds as $plId) {
|
||||||
$this->addPlaylistToShow($plId);
|
$this->addPlaylistToShow($plId);
|
||||||
}
|
}
|
||||||
RabbitMq::PushSchedule();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeGroupFromShow($group_id)
|
public function removeGroupFromShow($group_id)
|
||||||
|
@ -744,6 +758,17 @@ class ShowInstance {
|
||||||
->findPK($this->_instanceId);
|
->findPK($this->_instanceId);
|
||||||
$showInstance->setDbRecordedFile($file_id)
|
$showInstance->setDbRecordedFile($file_id)
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
|
$rebroadcasts = CcShowInstancesQuery::create()
|
||||||
|
->filterByDbOriginalShow($this->_instanceId)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
foreach ($rebroadcasts as $rebroadcast) {
|
||||||
|
|
||||||
|
$rebroad = new ShowInstance($rebroadcast->getDbId());
|
||||||
|
$rebroad->addFileToShow($file_id);
|
||||||
|
RabbitMq::PushSchedule();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTimeScheduled()
|
public function getTimeScheduled()
|
||||||
|
@ -864,7 +889,7 @@ class Show_DAL {
|
||||||
return $rows;
|
return $rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetNextShow($timeNow)
|
public static function GetNextShows($timeNow, $limit)
|
||||||
{
|
{
|
||||||
global $CC_CONFIG, $CC_DBC;
|
global $CC_CONFIG, $CC_DBC;
|
||||||
|
|
||||||
|
@ -874,7 +899,7 @@ class Show_DAL {
|
||||||
." AND si.starts >= TIMESTAMP '$timeNow'"
|
." AND si.starts >= TIMESTAMP '$timeNow'"
|
||||||
." AND si.starts < TIMESTAMP '$timeNow' + INTERVAL '48 hours'"
|
." AND si.starts < TIMESTAMP '$timeNow' + INTERVAL '48 hours'"
|
||||||
." ORDER BY si.starts"
|
." ORDER BY si.starts"
|
||||||
." LIMIT 1";
|
." LIMIT $limit";
|
||||||
|
|
||||||
$rows = $CC_DBC->GetAll($sql);
|
$rows = $CC_DBC->GetAll($sql);
|
||||||
return $rows;
|
return $rows;
|
||||||
|
|
|
@ -39,7 +39,7 @@ class CcScheduleTableMap extends TableMap {
|
||||||
$this->setPrimaryKeyMethodInfo('cc_schedule_id_seq');
|
$this->setPrimaryKeyMethodInfo('cc_schedule_id_seq');
|
||||||
// columns
|
// columns
|
||||||
$this->addPrimaryKey('ID', 'DbId', 'INTEGER', true, null, null);
|
$this->addPrimaryKey('ID', 'DbId', 'INTEGER', true, null, null);
|
||||||
$this->addColumn('PLAYLIST_ID', 'DbPlaylistId', 'INTEGER', true, null, null);
|
$this->addColumn('PLAYLIST_ID', 'DbPlaylistId', 'INTEGER', false, null, null);
|
||||||
$this->addColumn('STARTS', 'DbStarts', 'TIMESTAMP', true, null, null);
|
$this->addColumn('STARTS', 'DbStarts', 'TIMESTAMP', true, null, null);
|
||||||
$this->addColumn('ENDS', 'DbEnds', 'TIMESTAMP', true, null, null);
|
$this->addColumn('ENDS', 'DbEnds', 'TIMESTAMP', true, null, null);
|
||||||
$this->addColumn('GROUP_ID', 'DbGroupId', 'INTEGER', false, null, null);
|
$this->addColumn('GROUP_ID', 'DbGroupId', 'INTEGER', false, null, null);
|
||||||
|
|
|
@ -234,7 +234,7 @@
|
||||||
</table>
|
</table>
|
||||||
<table name="cc_schedule" phpName="CcSchedule">
|
<table name="cc_schedule" phpName="CcSchedule">
|
||||||
<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="playlist_id" phpName="DbPlaylistId" type="INTEGER" required="true"/>
|
<column name="playlist_id" phpName="DbPlaylistId" type="INTEGER" required="false"/>
|
||||||
<column name="starts" phpName="DbStarts" type="TIMESTAMP" required="true"/>
|
<column name="starts" phpName="DbStarts" type="TIMESTAMP" required="true"/>
|
||||||
<column name="ends" phpName="DbEnds" type="TIMESTAMP" required="true"/>
|
<column name="ends" phpName="DbEnds" type="TIMESTAMP" required="true"/>
|
||||||
<column name="group_id" phpName="DbGroupId" type="INTEGER" required="false"/>
|
<column name="group_id" phpName="DbGroupId" type="INTEGER" required="false"/>
|
||||||
|
|
|
@ -345,7 +345,7 @@ DROP TABLE "cc_schedule" CASCADE;
|
||||||
CREATE TABLE "cc_schedule"
|
CREATE TABLE "cc_schedule"
|
||||||
(
|
(
|
||||||
"id" serial NOT NULL,
|
"id" serial NOT NULL,
|
||||||
"playlist_id" INTEGER NOT NULL,
|
"playlist_id" INTEGER,
|
||||||
"starts" TIMESTAMP NOT NULL,
|
"starts" TIMESTAMP NOT NULL,
|
||||||
"ends" TIMESTAMP NOT NULL,
|
"ends" TIMESTAMP NOT NULL,
|
||||||
"group_id" INTEGER,
|
"group_id" INTEGER,
|
||||||
|
|
|
@ -55,6 +55,9 @@ AirtimeInstall::SetUpPythonEggs();
|
||||||
echo PHP_EOL."*** Pypo Installation ***".PHP_EOL;
|
echo PHP_EOL."*** Pypo Installation ***".PHP_EOL;
|
||||||
system("python ".__DIR__."/../pypo/install/pypo-install.py");
|
system("python ".__DIR__."/../pypo/install/pypo-install.py");
|
||||||
|
|
||||||
|
echo PHP_EOL."*** Recorder Installation ***".PHP_EOL;
|
||||||
|
system("python ".__DIR__."/../python_apps/show-recorder/install/recorder-install.py");
|
||||||
|
|
||||||
|
|
||||||
echo "******************************* Install Complete *******************************".PHP_EOL;
|
echo "******************************* Install Complete *******************************".PHP_EOL;
|
||||||
|
|
||||||
|
|
|
@ -83,5 +83,8 @@ AirtimeInstall::DeleteFilesRecursive($CC_CONFIG['storageDir']);
|
||||||
|
|
||||||
$command = "python ".__DIR__."/../pypo/install/pypo-uninstall.py";
|
$command = "python ".__DIR__."/../pypo/install/pypo-uninstall.py";
|
||||||
system($command);
|
system($command);
|
||||||
|
|
||||||
|
$command = "python ".__DIR__."/../python_apps/show-recorder/install/recorder-uninstall.py";
|
||||||
|
system($command);
|
||||||
echo "****************************** Uninstall Complete ******************************".PHP_EOL;
|
echo "****************************** Uninstall Complete ******************************".PHP_EOL;
|
||||||
|
|
||||||
|
|
|
@ -2,25 +2,64 @@
|
||||||
$.fn.airtimeShowSchedule = function(options) {
|
$.fn.airtimeShowSchedule = function(options) {
|
||||||
|
|
||||||
var defaults = {
|
var defaults = {
|
||||||
updatePeriod: 5, //seconds
|
updatePeriod: 20, //seconds
|
||||||
|
sourceDomain: "http://localhost/", //where to get show status from
|
||||||
};
|
};
|
||||||
var options = $.extend(defaults, options);
|
var options = $.extend(defaults, options);
|
||||||
|
|
||||||
return this.each(function() {
|
return this.each(function() {
|
||||||
var obj = $(this);
|
var obj = $(this);
|
||||||
|
var sd;
|
||||||
|
|
||||||
obj.append("<h3>On air today</h3>");
|
getServerData();
|
||||||
obj.append(
|
|
||||||
"<table width='100%' border='0' cellspacing='0' cellpadding='0' class='widget widget no-playing-list small'>"+
|
function updateWidget(){
|
||||||
"<tbody><tr>" +
|
var currentShow = sd.getCurrentShow();
|
||||||
"<td class='time'>13:15 - 13:30</td>" +
|
var nextShows = sd.getNextShows();
|
||||||
"<td><a href='#'>Program name</a> <a href='#' class='listen'>Listen</a></td>" +
|
|
||||||
"</tr>"+
|
var currentShowName = "";
|
||||||
"<tr>"+
|
var nextShowName = ""
|
||||||
"<td class='time'>13:15 - 13:30</td>"+
|
|
||||||
"<td><a href='#'>Lorem ipsum dolor</a></td>"+
|
if (currentShow.length > 0){
|
||||||
"</tr>"+
|
currentShowName = currentShow[0].getName();
|
||||||
"</tbody></table>");
|
}
|
||||||
|
|
||||||
|
if (nextShows.length > 0){
|
||||||
|
nextShowName = nextShows[0].getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
tableString = "";
|
||||||
|
tableString += "<h3>On air today</h3>";
|
||||||
|
tableString += "<table width='100%' border='0' cellspacing='0' cellpadding='0' class='widget widget no-playing-list small'>"+
|
||||||
|
"<tbody>";
|
||||||
|
|
||||||
|
var shows=currentShow.concat(nextShows);
|
||||||
|
|
||||||
|
obj.empty();
|
||||||
|
for (var i=0; i<shows.length; i++){
|
||||||
|
tableString +=
|
||||||
|
"<tr>" +
|
||||||
|
"<td class='time'>"+shows[i].getRange()+"</td>" +
|
||||||
|
"<td><a href='#'>"+shows[i].getName()+"</a> <a href='#' class='listen'>Listen</a></td>" +
|
||||||
|
"</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
tableString += "</tbody></table>";
|
||||||
|
|
||||||
|
obj.append(tableString);
|
||||||
|
}
|
||||||
|
|
||||||
|
function processData(data){
|
||||||
|
sd = new ScheduleData(data);
|
||||||
|
updateWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getServerData(){
|
||||||
|
$.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){
|
||||||
|
processData(data);
|
||||||
|
}, error:function(jqXHR, textStatus, errorThrown){}});
|
||||||
|
setTimeout(getServerData, defaults.updatePeriod*1000);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
@ -42,24 +81,42 @@
|
||||||
getServerData();
|
getServerData();
|
||||||
|
|
||||||
function updateWidget(){
|
function updateWidget(){
|
||||||
var currentShow = sd.getCurrentShowName();
|
var currentShow = sd.getCurrentShow();
|
||||||
var timeRemaining = sd.getCurrentShowTimeRemaining();
|
var nextShows = sd.getNextShows();
|
||||||
var timeElapsed = sd.getCurrentShowTimeElapsed();
|
|
||||||
var showStatus = sd.getCurrentShowStatus();
|
|
||||||
|
|
||||||
var nextShow = sd.getNextShowName();
|
var showStatus = "Offline";
|
||||||
var nextShowRange = sd.getNextShowRange();
|
var currentShowName = "";
|
||||||
|
var timeElapsed = "";
|
||||||
|
var timeRemaining = "";
|
||||||
|
|
||||||
|
var nextShowName = "";
|
||||||
|
var nextShowRange = "";
|
||||||
|
|
||||||
|
if (currentShow.length > 0){
|
||||||
|
showStatus = "On Air Now";
|
||||||
|
currentShowName = currentShow[0].getName();
|
||||||
|
|
||||||
|
timeElapsed = sd.getShowTimeElapsed(currentShow[0]);
|
||||||
|
timeRemaining = sd.getShowTimeRemaining(currentShow[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextShows.length > 0){
|
||||||
|
nextShowName = nextShows[0].getName();
|
||||||
|
nextShowRange = nextShows[0].getRange();
|
||||||
|
}
|
||||||
|
|
||||||
obj.empty();
|
obj.empty();
|
||||||
obj.append("<a id='listenWadrLive'><span>Listen WADR Live</span></a>");
|
obj.append("<a id='listenWadrLive'><span>Listen WADR Live</span></a>");
|
||||||
obj.append("<h4>"+showStatus+" >></h4>");
|
obj.append("<h4>"+showStatus+" >></h4>");
|
||||||
obj.append("<ul class='widget no-playing-bar'>" +
|
obj.append("<ul class='widget no-playing-bar'>" +
|
||||||
"<li class='current'>"+currentShow+ "<span id='time-elapsed' class='time-elapsed'>"+timeElapsed+"</span>" +
|
"<li class='current'>Current: "+currentShowName+
|
||||||
"<span id='time-remaining' class='time-remaining'>"+timeRemaining+"</span></li>" +
|
"<span id='time-elapsed' class='time-elapsed'>"+timeElapsed+"</span>" +
|
||||||
"<li class='next'>"+nextShow+"<span>"+nextShowRange+"</span></li>" +
|
"<span id='time-remaining' class='time-remaining'>"+timeRemaining+"</span>"+
|
||||||
|
"</li>" +
|
||||||
|
"<li class='next'>Next: "+nextShowName+"<span>"+nextShowRange+"</span></li>" +
|
||||||
"</ul>");
|
"</ul>");
|
||||||
|
|
||||||
//refresh the UI
|
//refresh the UI to update the elapsed/remaining time
|
||||||
setTimeout(updateWidget, 1000);
|
setTimeout(updateWidget, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,12 +135,23 @@
|
||||||
};
|
};
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
||||||
/* The rest of this file is the ScheduleData class */
|
/* ScheduleData class BEGIN */
|
||||||
function ScheduleData(data){
|
function ScheduleData(data){
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.estimatedSchedulePosixTime;
|
this.estimatedSchedulePosixTime;
|
||||||
|
|
||||||
this.schedulePosixTime = this.convertDateToPosixTime(data.schedulerTime);
|
this.currentShow = new Array();
|
||||||
|
for (var i=0; i< data.currentShow.length; i++){
|
||||||
|
this.currentShow[i] = new Show(data.currentShow[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.nextShows = new Array();
|
||||||
|
for (var i=0; i< data.nextShow.length; i++){
|
||||||
|
this.nextShows[i] = new Show(data.nextShow[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.schedulePosixTime = convertDateToPosixTime(data.schedulerTime);
|
||||||
this.schedulePosixTime += parseInt(data.timezoneOffset)*1000;
|
this.schedulePosixTime += parseInt(data.timezoneOffset)*1000;
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
this.localRemoteTimeOffset = date.getTime() - this.schedulePosixTime;
|
this.localRemoteTimeOffset = date.getTime() - this.schedulePosixTime;
|
||||||
|
@ -95,72 +163,57 @@ ScheduleData.prototype.secondsTimer = function(){
|
||||||
this.estimatedSchedulePosixTime = date.getTime() - this.localRemoteTimeOffset;
|
this.estimatedSchedulePosixTime = date.getTime() - this.localRemoteTimeOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleData.prototype.getCurrentShowName = function() {
|
ScheduleData.prototype.getCurrentShow = function(){
|
||||||
var currentShow = this.data.currentShow;
|
return this.currentShow;
|
||||||
if (currentShow.length > 0){
|
}
|
||||||
return "Current: " + currentShow[0].name;
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ScheduleData.prototype.getCurrentShowStatus = function() {
|
ScheduleData.prototype.getNextShows = function() {
|
||||||
var currentShow = this.data.currentShow;
|
return this.nextShows;
|
||||||
if (currentShow.length > 0){
|
}
|
||||||
return "On Air Now";
|
|
||||||
} else {
|
|
||||||
return "Offline";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ScheduleData.prototype.getNextShowName = function() {
|
ScheduleData.prototype.getShowTimeElapsed = function(show) {
|
||||||
var nextShow = this.data.nextShow;
|
|
||||||
if (nextShow.length > 0){
|
|
||||||
return "Next: " + nextShow[0].name;
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ScheduleData.prototype.getNextShowRange = function() {
|
|
||||||
var nextShow = this.data.nextShow;
|
|
||||||
if (nextShow.length > 0){
|
|
||||||
return this.getTime(nextShow[0].start_timestamp) + " - " + this.getTime(nextShow[0].end_timestamp);
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ScheduleData.prototype.getCurrentShowTimeElapsed = function() {
|
|
||||||
this.secondsTimer();
|
this.secondsTimer();
|
||||||
var currentShow = this.data.currentShow;
|
|
||||||
if (currentShow.length > 0){
|
var showStart = convertDateToPosixTime(show.getStartTimestamp());
|
||||||
var showStart = this.convertDateToPosixTime(currentShow[0].start_timestamp);
|
return convertToHHMMSS(this.estimatedSchedulePosixTime - showStart);
|
||||||
return this.convertToHHMMSS(this.estimatedSchedulePosixTime - showStart);
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ScheduleData.prototype.getCurrentShowTimeRemaining = function() {
|
ScheduleData.prototype.getShowTimeRemaining = function(show) {
|
||||||
this.secondsTimer();
|
this.secondsTimer();
|
||||||
var currentShow = this.data.currentShow;
|
|
||||||
if (currentShow.length > 0){
|
|
||||||
var showEnd = this.convertDateToPosixTime(currentShow[0].end_timestamp);
|
|
||||||
return this.convertToHHMMSS(showEnd - this.estimatedSchedulePosixTime);
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ScheduleData.prototype.getTime = function(timestamp) {
|
var showEnd = convertDateToPosixTime(show.getEndTimestamp());
|
||||||
return timestamp.split(" ")[1];
|
return convertToHHMMSS(showEnd - this.estimatedSchedulePosixTime);
|
||||||
};
|
};
|
||||||
|
/* ScheduleData class END */
|
||||||
|
|
||||||
|
/* Show class BEGIN */
|
||||||
|
function Show(showData){
|
||||||
|
this.showData = showData;
|
||||||
|
}
|
||||||
|
|
||||||
|
Show.prototype.getName = function(){
|
||||||
|
return this.showData.name;
|
||||||
|
}
|
||||||
|
Show.prototype.getRange = function(){
|
||||||
|
return getTime(this.showData.start_timestamp) + " - " + getTime(this.showData.end_timestamp);
|
||||||
|
}
|
||||||
|
Show.prototype.getStartTimestamp = function(){
|
||||||
|
return this.showData.start_timestamp;
|
||||||
|
}
|
||||||
|
Show.prototype.getEndTimestamp = function(){
|
||||||
|
return this.showData.end_timestamp;
|
||||||
|
}
|
||||||
|
/* Show class END */
|
||||||
|
|
||||||
|
|
||||||
|
function getTime(timestamp) {
|
||||||
|
var time = timestamp.split(" ")[1].split(":");
|
||||||
|
return time[0] + ":" + time[1];
|
||||||
|
};
|
||||||
|
|
||||||
/* Takes an input parameter of milliseconds and converts these into
|
/* Takes an input parameter of milliseconds and converts these into
|
||||||
* the format HH:MM:SS */
|
* the format HH:MM:SS */
|
||||||
ScheduleData.prototype.convertToHHMMSS = function(timeInMS){
|
function convertToHHMMSS(timeInMS){
|
||||||
var time = parseInt(timeInMS);
|
var time = parseInt(timeInMS);
|
||||||
|
|
||||||
var hours = parseInt(time / 3600000);
|
var hours = parseInt(time / 3600000);
|
||||||
|
@ -189,7 +242,7 @@ ScheduleData.prototype.convertToHHMMSS = function(timeInMS){
|
||||||
|
|
||||||
/* Takes in a string of format similar to 2011-02-07 02:59:57,
|
/* Takes in a string of format similar to 2011-02-07 02:59:57,
|
||||||
* and converts this to epoch/posix time. */
|
* and converts this to epoch/posix time. */
|
||||||
ScheduleData.prototype.convertDateToPosixTime = function(s){
|
function convertDateToPosixTime(s){
|
||||||
var datetime = s.split(" ");
|
var datetime = s.split(" ");
|
||||||
|
|
||||||
var date = datetime[0].split("-");
|
var date = datetime[0].split("-");
|
||||||
|
|
|
@ -169,7 +169,7 @@ function updatePlaybar(){
|
||||||
$('#playlist').text(currentShow[0].name);
|
$('#playlist').text(currentShow[0].name);
|
||||||
|
|
||||||
var recElem = $('.recording-show');
|
var recElem = $('.recording-show');
|
||||||
currentShow[0].record ? recElem.show(): recElem.hide();
|
(currentShow[0].record == "1") ? recElem.show(): recElem.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#show-length').empty();
|
$('#show-length').empty();
|
||||||
|
|
|
@ -44,6 +44,8 @@ def create_user(username):
|
||||||
print "User already exists."
|
print "User already exists."
|
||||||
#add pypo to audio group
|
#add pypo to audio group
|
||||||
os.system("adduser " + username + " audio 1>/dev/null 2>&1")
|
os.system("adduser " + username + " audio 1>/dev/null 2>&1")
|
||||||
|
#add pypo to pulse-access group
|
||||||
|
#os.system("adduser " + username + " pulse-access 1>/dev/null 2>&1")
|
||||||
|
|
||||||
def copy_dir(src_dir, dest_dir):
|
def copy_dir(src_dir, dest_dir):
|
||||||
if (os.path.exists(dest_dir)) and (dest_dir != "/"):
|
if (os.path.exists(dest_dir)) and (dest_dir != "/"):
|
||||||
|
|
|
@ -6,4 +6,4 @@ show_schedule_url = 'Recorder/get-show-schedule/format/json'
|
||||||
upload_file_url = 'Plupload/upload-recorded/format/json'
|
upload_file_url = 'Plupload/upload-recorded/format/json'
|
||||||
|
|
||||||
# base path to store recordered shows at
|
# base path to store recordered shows at
|
||||||
base_recorded_files = '/home/naomi/Music/'
|
base_recorded_files = '/home/pypo/Music/'
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
exec setuidgid pypo multilog t ./main
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
recorder_user="pypo"
|
||||||
|
export HOME="/home/pypo/"
|
||||||
|
# Location of pypo_cli.py Python script
|
||||||
|
recorder_path="/opt/recorder/bin/"
|
||||||
|
recorder_script="testrecordscript.py"
|
||||||
|
echo "*** Daemontools: starting daemon"
|
||||||
|
cd ${recorder_path}
|
||||||
|
exec 2>&1
|
||||||
|
# Note the -u when calling python! we need it to get unbuffered binary stdout and stderr
|
||||||
|
exec sudo python -u ${recorder_path}${recorder_script} -f
|
||||||
|
# EOF
|
|
@ -0,0 +1,128 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import traceback
|
||||||
|
from optparse import *
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
import logging.config
|
||||||
|
import shutil
|
||||||
|
import string
|
||||||
|
import platform
|
||||||
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
|
if os.geteuid() != 0:
|
||||||
|
print "Please run this as root."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
BASE_PATH = '/opt/recorder/'
|
||||||
|
|
||||||
|
def create_path(path):
|
||||||
|
if not (os.path.exists(path)):
|
||||||
|
print "Creating directory " + path
|
||||||
|
os.makedirs(path)
|
||||||
|
|
||||||
|
def create_user(username):
|
||||||
|
print "Checking for user "+username
|
||||||
|
p = Popen('id '+username, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
|
||||||
|
output = p.stdout.read()
|
||||||
|
if (output[0:3] != "uid"):
|
||||||
|
# Make the pypo user
|
||||||
|
print "Creating user "+username
|
||||||
|
os.system("adduser --system --quiet --group --shell /bin/bash "+username)
|
||||||
|
|
||||||
|
#set pypo password
|
||||||
|
p = os.popen('/usr/bin/passwd pypo 1>/dev/null 2>&1', 'w')
|
||||||
|
p.write('pypo\n')
|
||||||
|
p.write('pypo\n')
|
||||||
|
p.close()
|
||||||
|
else:
|
||||||
|
print "User already exists."
|
||||||
|
#add pypo to audio group
|
||||||
|
os.system("adduser " + username + " audio 1>/dev/null 2>&1")
|
||||||
|
|
||||||
|
def copy_dir(src_dir, dest_dir):
|
||||||
|
if (os.path.exists(dest_dir)) and (dest_dir != "/"):
|
||||||
|
print "Removing old directory "+dest_dir
|
||||||
|
shutil.rmtree(dest_dir)
|
||||||
|
if not (os.path.exists(dest_dir)):
|
||||||
|
print "Copying directory "+src_dir+" to "+dest_dir
|
||||||
|
shutil.copytree(src_dir, dest_dir)
|
||||||
|
|
||||||
|
def get_current_script_dir():
|
||||||
|
current_script_dir = os.path.realpath(__file__)
|
||||||
|
index = current_script_dir.rindex('/')
|
||||||
|
print current_script_dir[0:index]
|
||||||
|
return current_script_dir[0:index]
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
current_script_dir = get_current_script_dir()
|
||||||
|
print "Checking and removing any existing recorder processes"
|
||||||
|
os.system("python %s/recorder-uninstall.py 1>/dev/null 2>&1"% current_script_dir)
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
# Create users
|
||||||
|
create_user("pypo")
|
||||||
|
|
||||||
|
print "Creating home directory"
|
||||||
|
create_path("/home/pypo")
|
||||||
|
os.system("chmod -R 755 /home/pypo")
|
||||||
|
os.system("chown -R pypo:pypo /home/pypo")
|
||||||
|
|
||||||
|
print "Creating home directory"
|
||||||
|
create_path("/home/pypo/Music")
|
||||||
|
os.system("chmod -R 755 /home/pypo/Music")
|
||||||
|
os.system("chown -R pypo:pypo /home/pypo/Music")
|
||||||
|
|
||||||
|
print "Creating log directories"
|
||||||
|
create_path("/var/log/recorder")
|
||||||
|
os.system("chmod -R 755 /var/log/recorder")
|
||||||
|
os.system("chown -R pypo:pypo /var/log/recorder")
|
||||||
|
|
||||||
|
create_path(BASE_PATH)
|
||||||
|
create_path(BASE_PATH+"bin")
|
||||||
|
create_path(BASE_PATH+"cache")
|
||||||
|
create_path(BASE_PATH+"files")
|
||||||
|
create_path(BASE_PATH+"tmp")
|
||||||
|
create_path(BASE_PATH+"archive")
|
||||||
|
|
||||||
|
copy_dir("%s/.."%current_script_dir, BASE_PATH+"bin/")
|
||||||
|
|
||||||
|
print "Setting permissions"
|
||||||
|
os.system("chmod -R 755 "+BASE_PATH)
|
||||||
|
os.system("chown -R pypo:pypo "+BASE_PATH)
|
||||||
|
|
||||||
|
print "Installing recorder daemon"
|
||||||
|
create_path("/etc/service/recorder")
|
||||||
|
create_path("/etc/service/recorder/log")
|
||||||
|
shutil.copy("%s/recorder-daemontools.sh"%current_script_dir, "/etc/service/recorder/run")
|
||||||
|
shutil.copy("%s/recorder-daemontools-logger.sh"%current_script_dir, "/etc/service/recorder/log/run")
|
||||||
|
os.system("chmod -R 755 /etc/service/recorder")
|
||||||
|
os.system("chown -R pypo:pypo /etc/service/recorder")
|
||||||
|
|
||||||
|
print "Waiting for processes to start..."
|
||||||
|
time.sleep(5)
|
||||||
|
os.system("python %s/recorder-start.py" % (get_current_script_dir()))
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
found = True
|
||||||
|
|
||||||
|
p = Popen('svstat /etc/service/recorder', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
|
||||||
|
output = p.stdout.read()
|
||||||
|
if (output.find("unable to open supervise/ok: file does not exist") >= 0):
|
||||||
|
found = False
|
||||||
|
print output
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
print "Recorder install has completed, but daemontools is not running, please make sure you have it installed and then reboot."
|
||||||
|
except Exception, e:
|
||||||
|
print "exception:" + str(e)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if os.geteuid() != 0:
|
||||||
|
print "Please run this as root."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
print "Starting daemontool script recorder"
|
||||||
|
os.system("svc -u /etc/service/recorder")
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print "exception:" + str(e)
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if os.geteuid() != 0:
|
||||||
|
print "Please run this as root."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
print "Stopping daemontool script pypo"
|
||||||
|
os.system("svc -dx /etc/service/pypo 1>/dev/null 2>&1")
|
||||||
|
|
||||||
|
if os.path.exists("/etc/service/pypo-fetch"):
|
||||||
|
os.system("svc -dx /etc/service/pypo-fetch 1>/dev/null 2>&1")
|
||||||
|
if os.path.exists("/etc/service/pypo-push"):
|
||||||
|
os.system("svc -dx /etc/service/pypo-push 1>/dev/null 2>&1")
|
||||||
|
|
||||||
|
print "Stopping daemontool script pypo-liquidsoap"
|
||||||
|
os.system("svc -dx /etc/service/pypo-liquidsoap 1>/dev/null 2>&1")
|
||||||
|
os.system("killall liquidsoap")
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print "exception:" + str(e)
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
if os.geteuid() != 0:
|
||||||
|
print "Please run this as root."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
BASE_PATH = '/opt/recorder/'
|
||||||
|
|
||||||
|
def remove_path(path):
|
||||||
|
os.system("rm -rf " + path)
|
||||||
|
|
||||||
|
def remove_user(username):
|
||||||
|
os.system("killall -u %s 1>/dev/null 2>&1" % username)
|
||||||
|
|
||||||
|
#allow all process to be completely closed before we attempt to delete user
|
||||||
|
print "Waiting for processes to close..."
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
os.system("deluser --remove-home " + username + " 1>/dev/null 2>&1")
|
||||||
|
|
||||||
|
def get_current_script_dir():
|
||||||
|
current_script_dir = os.path.realpath(__file__)
|
||||||
|
index = current_script_dir.rindex('/')
|
||||||
|
return current_script_dir[0:index]
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.system("python %s/recorder-stop.py" % get_current_script_dir())
|
||||||
|
|
||||||
|
print "Removing log directories"
|
||||||
|
remove_path("/var/log/recorder")
|
||||||
|
|
||||||
|
print "Removing recorder files"
|
||||||
|
remove_path(BASE_PATH)
|
||||||
|
|
||||||
|
print "Removing daemontool script recorder"
|
||||||
|
remove_path("rm -rf /etc/service/recorder")
|
||||||
|
|
||||||
|
remove_user("pypo")
|
||||||
|
print "Uninstall complete."
|
||||||
|
except Exception, e:
|
||||||
|
print "exception:" + str(e)
|
|
@ -1,59 +0,0 @@
|
||||||
import webbrowser
|
|
||||||
import scapi
|
|
||||||
|
|
||||||
# the host to connect to. Normally, this
|
|
||||||
# would be api.soundcloud.com
|
|
||||||
API_HOST = "api.soundcloud.com"
|
|
||||||
|
|
||||||
# This needs to be the consumer ID you got from
|
|
||||||
# http://soundcloud.com/settings/applications/new
|
|
||||||
CONSUMER = "2CLCxcSXYzx7QhhPVHN4A"
|
|
||||||
# This needs to be the consumer secret password you got from
|
|
||||||
# http://soundcloud.com/settings/applications/new
|
|
||||||
CONSUMER_SECRET = "pZ7beWmF06epXLHVUP1ufOg2oEnIt9XhE8l8xt0bBs"
|
|
||||||
|
|
||||||
# first, we create an OAuthAuthenticator that only knows about consumer
|
|
||||||
# credentials. This is done so that we can get an request-token as
|
|
||||||
# first step.
|
|
||||||
oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER,
|
|
||||||
CONSUMER_SECRET,
|
|
||||||
None,
|
|
||||||
None)
|
|
||||||
|
|
||||||
# The connector works with the authenticator to create and sign the requests. It
|
|
||||||
# has some helper-methods that allow us to do the OAuth-dance.
|
|
||||||
connector = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator)
|
|
||||||
|
|
||||||
# First step is to get a request-token, and to let the user authorize that
|
|
||||||
# via the browser.
|
|
||||||
token, secret = connector.fetch_request_token()
|
|
||||||
authorization_url = connector.get_request_token_authorization_url(token)
|
|
||||||
webbrowser.open(authorization_url)
|
|
||||||
oauth_verifier = raw_input("please enter verifier code as seen in the browser:")
|
|
||||||
|
|
||||||
# Now we create a new authenticator with the temporary token & secret we got from
|
|
||||||
# the request-token. This will give us the access-token
|
|
||||||
oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER,
|
|
||||||
CONSUMER_SECRET,
|
|
||||||
token,
|
|
||||||
secret)
|
|
||||||
|
|
||||||
# we need a new connector with the new authenticator!
|
|
||||||
connector = scapi.ApiConnector(API_HOST, authenticator=oauth_authenticator)
|
|
||||||
token, secret = connector.fetch_access_token(oauth_verifier)
|
|
||||||
|
|
||||||
|
|
||||||
# now we are finally ready to go - with all four parameters OAuth requires,
|
|
||||||
# we can setup an authenticator that allows for actual API-calls.
|
|
||||||
oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER,
|
|
||||||
CONSUMER_SECRET,
|
|
||||||
token,
|
|
||||||
secret)
|
|
||||||
|
|
||||||
# we pass the connector to a Scope - a Scope is essentially a path in the REST-url-space.
|
|
||||||
# Without any path-component, it's the root from which we can then query into the
|
|
||||||
# resources.
|
|
||||||
root = scapi.Scope(scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator))
|
|
||||||
|
|
||||||
# Hey, nice meeting you! Connected to SoundCloud using OAuth will allow you to access protected resources, like the current user's name.
|
|
||||||
print "Hello, %s" % root.me().username
|
|
Loading…
Reference in New Issue