Merge branch 'saas-dev' into saas-installer-albert
Conflicts: python_apps/api_clients/api_clients/api_client.py
This commit is contained in:
commit
01ea6f27ae
|
@ -17,12 +17,20 @@ class Application_Common_TuneIn
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||||
|
|
||||||
curl_exec($ch);
|
$xmlResponse = curl_exec($ch);
|
||||||
if (curl_error($ch)) {
|
if (curl_error($ch)) {
|
||||||
Logging::error("Failed to reach TuneIn: ". curl_errno($ch)." - ". curl_error($ch) . " - " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
Logging::error("Failed to reach TuneIn: ". curl_errno($ch)." - ". curl_error($ch) . " - " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
||||||
}
|
}
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
|
$xmlObj = new SimpleXMLElement($xmlResponse);
|
||||||
|
if (!$xmlObj || $xmlObj->head->status != "200") {
|
||||||
|
Logging::info("Error occurred pushing metadata to TuneIn:");
|
||||||
|
Logging::info($xmlResponse);
|
||||||
|
} else if ($xmlObj->head->status == "200") {
|
||||||
|
Application_Model_Preference::setLastTuneinMetadataUpdate(time());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getCredentialsQueryString() {
|
private static function getCredentialsQueryString() {
|
||||||
|
@ -33,20 +41,4 @@ class Application_Common_TuneIn
|
||||||
return "?partnerId=".$tuneInPartnerID."&partnerKey=".$tuneInPartnerKey."&id=".$tuneInStationID;
|
return "?partnerId=".$tuneInPartnerID."&partnerKey=".$tuneInPartnerKey."&id=".$tuneInStationID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function updateOfflineMetadata() {
|
|
||||||
$credQryStr = self::getCredentialsQueryString();
|
|
||||||
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $credQryStr . "&commercial=true");
|
|
||||||
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
|
||||||
|
|
||||||
curl_exec($ch);
|
|
||||||
if (curl_error($ch)) {
|
|
||||||
Logging::error("Failed to reach TuneIn: ". curl_errno($ch)." - ". curl_error($ch) . " - " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
|
||||||
}
|
|
||||||
curl_close($ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ class ApiController extends Zend_Controller_Action
|
||||||
print _('You are not allowed to access this resource.');
|
print _('You are not allowed to access this resource.');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function versionAction()
|
public function versionAction()
|
||||||
|
@ -157,7 +158,7 @@ class ApiController extends Zend_Controller_Action
|
||||||
*/
|
*/
|
||||||
public function liveInfoAction()
|
public function liveInfoAction()
|
||||||
{
|
{
|
||||||
if (Application_Model_Preference::GetAllow3rdPartyApi()) {
|
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||||
// 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);
|
||||||
|
@ -252,7 +253,7 @@ class ApiController extends Zend_Controller_Action
|
||||||
*/
|
*/
|
||||||
public function liveInfoV2Action()
|
public function liveInfoV2Action()
|
||||||
{
|
{
|
||||||
if (Application_Model_Preference::GetAllow3rdPartyApi()) {
|
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||||
// 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);
|
||||||
|
@ -360,7 +361,7 @@ class ApiController extends Zend_Controller_Action
|
||||||
|
|
||||||
public function weekInfoAction()
|
public function weekInfoAction()
|
||||||
{
|
{
|
||||||
if (Application_Model_Preference::GetAllow3rdPartyApi()) {
|
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||||
// 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);
|
||||||
|
@ -479,7 +480,7 @@ class ApiController extends Zend_Controller_Action
|
||||||
*/
|
*/
|
||||||
public function showLogoAction()
|
public function showLogoAction()
|
||||||
{
|
{
|
||||||
if (Application_Model_Preference::GetAllow3rdPartyApi()) {
|
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$showId = $request->getParam('id');
|
$showId = $request->getParam('id');
|
||||||
|
|
||||||
|
@ -510,7 +511,7 @@ class ApiController extends Zend_Controller_Action
|
||||||
*/
|
*/
|
||||||
public function stationMetadataAction()
|
public function stationMetadataAction()
|
||||||
{
|
{
|
||||||
if (Application_Model_Preference::GetAllow3rdPartyApi()) {
|
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||||
// 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);
|
||||||
|
@ -549,7 +550,7 @@ class ApiController extends Zend_Controller_Action
|
||||||
*/
|
*/
|
||||||
public function stationLogoAction()
|
public function stationLogoAction()
|
||||||
{
|
{
|
||||||
if (Application_Model_Preference::GetAllow3rdPartyApi()) {
|
if (Application_Model_Preference::GetAllow3rdPartyApi() || $this->checkAuth()) {
|
||||||
// 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);
|
||||||
|
@ -1515,5 +1516,30 @@ class ApiController extends Zend_Controller_Action
|
||||||
$this->_helper->json($result);
|
$this->_helper->json($result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called from PYPO (pypofetch) every 2 minutes and updates
|
||||||
|
* metadata on TuneIn if we haven't done so in the last 4 minutes. We have
|
||||||
|
* to do this because TuneIn turns off metadata if it has not received a
|
||||||
|
* request within 5 minutes. This is necessary for long tracks > 5 minutes.
|
||||||
|
*/
|
||||||
|
public function updateMetadataOnTuneinAction()
|
||||||
|
{
|
||||||
|
if (!Application_Model_Preference::getTuneinEnabled()) {
|
||||||
|
$this->_helper->json->sendJson(array(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastTuneInMetadataUpdate = Application_Model_Preference::geLastTuneinMetadataUpdate();
|
||||||
|
if (time() - $lastTuneInMetadataUpdate >= 240) {
|
||||||
|
$metadata = $metadata = Application_Model_Schedule::getCurrentPlayingTrack();
|
||||||
|
if (!is_null($metadata)) {
|
||||||
|
Application_Common_TuneIn::sendMetadataToTunein(
|
||||||
|
$metadata["title"],
|
||||||
|
$metadata["artist"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->_helper->json->sendJson(array(1));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ class PreferenceController extends Zend_Controller_Action
|
||||||
Application_Model_Preference::SetSoundCloudLicense($values["SoundCloudLicense"]);*/
|
Application_Model_Preference::SetSoundCloudLicense($values["SoundCloudLicense"]);*/
|
||||||
|
|
||||||
$this->view->statusMsg = "<div class='success'>". _("Preferences updated.")."</div>";
|
$this->view->statusMsg = "<div class='success'>". _("Preferences updated.")."</div>";
|
||||||
|
$form = new Application_Form_Preferences();
|
||||||
$this->view->form = $form;
|
$this->view->form = $form;
|
||||||
//$this->_helper->json->sendJson(array("valid"=>"true", "html"=>$this->view->render('preference/index.phtml')));
|
//$this->_helper->json->sendJson(array("valid"=>"true", "html"=>$this->view->render('preference/index.phtml')));
|
||||||
} else {
|
} else {
|
||||||
|
@ -491,31 +492,42 @@ class PreferenceController extends Zend_Controller_Action
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = Application_Model_User::getCurrentUser();
|
$this->deleteFutureScheduleItems();
|
||||||
$playlists = $blocks = $streams = [];
|
$this->deleteCloudFiles();
|
||||||
|
$this->deleteStoredFiles();
|
||||||
|
|
||||||
$allPlaylists = CcPlaylistQuery::create()->find();
|
$this->getResponse()
|
||||||
foreach ($allPlaylists as $p) {
|
->setHttpResponseCode(200)
|
||||||
$playlists[] = $p->getDbId();
|
->appendBody("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deleteFutureScheduleItems() {
|
||||||
|
$utcTimezone = new DateTimeZone("UTC");
|
||||||
|
$nowDateTime = new DateTime("now", $utcTimezone);
|
||||||
|
$scheduleItems = CcScheduleQuery::create()
|
||||||
|
->filterByDbEnds($nowDateTime->format("Y-m-d H:i:s"), Criteria::GREATER_THAN)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
// Delete all the schedule items
|
||||||
|
foreach ($scheduleItems as $i) {
|
||||||
|
// If this is the currently playing track, cancel the current show
|
||||||
|
if ($i->isCurrentItem()) {
|
||||||
|
$instanceId = $i->getDbInstanceId();
|
||||||
|
$instance = CcShowInstancesQuery::create()->findPk($instanceId);
|
||||||
|
$showId = $instance->getDbShowId();
|
||||||
|
|
||||||
|
// From ScheduleController
|
||||||
|
$scheduler = new Application_Model_Scheduler();
|
||||||
|
$scheduler->cancelShow($showId);
|
||||||
|
Application_Model_StoredFile::updatePastFilesIsScheduled();
|
||||||
|
}
|
||||||
|
|
||||||
|
$i->delete();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$allBlocks = CcBlockQuery::create()->find();
|
private function deleteCloudFiles() {
|
||||||
foreach ($allBlocks as $b) {
|
|
||||||
$blocks[] = $b->getDbId();
|
|
||||||
}
|
|
||||||
|
|
||||||
$allStreams = CcWebstreamQuery::create()->find();
|
|
||||||
foreach ($allStreams as $s) {
|
|
||||||
$streams[] = $s->getDbId();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete all playlists, blocks, and streams
|
|
||||||
Application_Model_Playlist::deletePlaylists($playlists, $user->getId());
|
|
||||||
Application_Model_Block::deleteBlocks($blocks, $user->getId());
|
|
||||||
Application_Model_Webstream::deleteStreams($streams, $user->getId());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Delete all the cloud files
|
|
||||||
$CC_CONFIG = Config::getConfig();
|
$CC_CONFIG = Config::getConfig();
|
||||||
|
|
||||||
foreach ($CC_CONFIG["supportedStorageBackends"] as $storageBackend) {
|
foreach ($CC_CONFIG["supportedStorageBackends"] as $storageBackend) {
|
||||||
|
@ -525,7 +537,9 @@ class PreferenceController extends Zend_Controller_Action
|
||||||
} catch(Exception $e) {
|
} catch(Exception $e) {
|
||||||
Logging::info($e->getMessage());
|
Logging::info($e->getMessage());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deleteStoredFiles() {
|
||||||
// Delete all files from the database
|
// Delete all files from the database
|
||||||
$files = CcFilesQuery::create()->find();
|
$files = CcFilesQuery::create()->find();
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
|
@ -534,10 +548,6 @@ class PreferenceController extends Zend_Controller_Action
|
||||||
// every S3 file we delete.
|
// every S3 file we delete.
|
||||||
$storedFile->delete(true);
|
$storedFile->delete(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->getResponse()
|
|
||||||
->setHttpResponseCode(200)
|
|
||||||
->appendBody("OK");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,13 +315,6 @@ class ScheduleController extends Zend_Controller_Action
|
||||||
{
|
{
|
||||||
$range = Application_Model_Schedule::GetPlayOrderRangeOld();
|
$range = Application_Model_Schedule::GetPlayOrderRangeOld();
|
||||||
|
|
||||||
// If there is no current track playing update TuneIn so it doesn't
|
|
||||||
// display outdated metadata
|
|
||||||
//TODO: find a better solution for this so we don't spam the station on TuneIn
|
|
||||||
/*if (is_null($range["current"]) && Application_Model_Preference::getTuneinEnabled()) {
|
|
||||||
Application_Common_TuneIn::updateOfflineMetadata();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
$show = Application_Model_Show::getCurrentShow();
|
$show = Application_Model_Show::getCurrentShow();
|
||||||
|
|
||||||
/* Convert all UTC times to localtime before sending back to user. */
|
/* Convert all UTC times to localtime before sending back to user. */
|
||||||
|
|
|
@ -239,7 +239,7 @@ class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ($product["status"] === "Active") {
|
if (($product["status"] === "Active") || ($product["status"] === "Suspended")) {
|
||||||
$airtimeProduct = $product;
|
$airtimeProduct = $product;
|
||||||
$subdomain = '';
|
$subdomain = '';
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ class Application_Form_TuneInPreferences extends Zend_Form_SubForm
|
||||||
$enableTunein->addDecorator('Label', array('class' => 'enable-tunein'));
|
$enableTunein->addDecorator('Label', array('class' => 'enable-tunein'));
|
||||||
$enableTunein->setLabel(_("Push metadata to your station on TuneIn?"));
|
$enableTunein->setLabel(_("Push metadata to your station on TuneIn?"));
|
||||||
$enableTunein->setValue(Application_Model_Preference::getTuneinEnabled());
|
$enableTunein->setValue(Application_Model_Preference::getTuneinEnabled());
|
||||||
$enableTunein->setAttrib("class", "block-display");
|
|
||||||
$this->addElement($enableTunein);
|
$this->addElement($enableTunein);
|
||||||
|
|
||||||
$tuneinStationId = new Zend_Form_Element_Text("tunein_station_id");
|
$tuneinStationId = new Zend_Form_Element_Text("tunein_station_id");
|
||||||
|
@ -76,7 +75,6 @@ class Application_Form_TuneInPreferences extends Zend_Form_SubForm
|
||||||
Logging::error("Failed to reach TuneIn: ". curl_errno($ch)." - ". curl_error($ch) . " - " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
Logging::error("Failed to reach TuneIn: ". curl_errno($ch)." - ". curl_error($ch) . " - " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
||||||
if (curl_error($ch) == "The requested URL returned error: 403 Forbidden") {
|
if (curl_error($ch) == "The requested URL returned error: 403 Forbidden") {
|
||||||
$this->getElement("enable_tunein")->setErrors(array(_("Invalid TuneIn Settings. Please ensure your TuneIn settings are correct and try again.")));
|
$this->getElement("enable_tunein")->setErrors(array(_("Invalid TuneIn Settings. Please ensure your TuneIn settings are correct and try again.")));
|
||||||
|
|
||||||
$valid = false;
|
$valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,8 +83,10 @@ class Application_Form_TuneInPreferences extends Zend_Form_SubForm
|
||||||
if ($valid) {
|
if ($valid) {
|
||||||
$xmlObj = new SimpleXMLElement($xmlData);
|
$xmlObj = new SimpleXMLElement($xmlData);
|
||||||
if (!$xmlObj || $xmlObj->head->status != "200") {
|
if (!$xmlObj || $xmlObj->head->status != "200") {
|
||||||
|
$this->getElement("enable_tunein")->setErrors(array(_("Invalid TuneIn Settings. Please ensure your TuneIn settings are correct and try again.")));
|
||||||
$valid = false;
|
$valid = false;
|
||||||
} else if ($xmlObj->head->status == "200") {
|
} else if ($xmlObj->head->status == "200") {
|
||||||
|
Application_Model_Preference::setLastTuneinMetadataUpdate(time());
|
||||||
$valid = true;
|
$valid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1513,4 +1513,14 @@ class Application_Model_Preference
|
||||||
{
|
{
|
||||||
return self::getValue("tunein_station_id");
|
return self::getValue("tunein_station_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function geLastTuneinMetadataUpdate()
|
||||||
|
{
|
||||||
|
return self::getValue("last_tunein_metadata_update");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function setLastTuneinMetadataUpdate($value)
|
||||||
|
{
|
||||||
|
self::setValue("last_tunein_metadata_update", $value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,6 @@ SQL;
|
||||||
$currentMedia["ends"] = $currentMedia["show_ends"];
|
$currentMedia["ends"] = $currentMedia["show_ends"];
|
||||||
}
|
}
|
||||||
|
|
||||||
$currentMediaScheduleId = $currentMedia["id"];
|
|
||||||
$currentMediaFileId = $currentMedia["file_id"];
|
$currentMediaFileId = $currentMedia["file_id"];
|
||||||
$currentMediaStreamId = $currentMedia["stream_id"];
|
$currentMediaStreamId = $currentMedia["stream_id"];
|
||||||
if (isset($currentMediaFileId)) {
|
if (isset($currentMediaFileId)) {
|
||||||
|
@ -234,9 +233,10 @@ SQL;
|
||||||
);
|
);
|
||||||
|
|
||||||
$previousMedia = CcScheduleQuery::create()
|
$previousMedia = CcScheduleQuery::create()
|
||||||
->filterByDbId($currentMediaScheduleId-1)
|
->filterByDbStarts($currentMedia["starts"], Criteria::LESS_THAN)
|
||||||
|
->filterByDbId($currentMedia["id"], Criteria::NOT_EQUAL)
|
||||||
->filterByDbPlayoutStatus(0, Criteria::GREATER_THAN)
|
->filterByDbPlayoutStatus(0, Criteria::GREATER_THAN)
|
||||||
->orderByDbStarts()
|
->orderByDbStarts(Criteria::DESC)
|
||||||
->findOne();
|
->findOne();
|
||||||
if (isset($previousMedia)) {
|
if (isset($previousMedia)) {
|
||||||
$previousMediaFileId = $previousMedia->getDbFileId();
|
$previousMediaFileId = $previousMedia->getDbFileId();
|
||||||
|
@ -253,10 +253,6 @@ SQL;
|
||||||
$previousWebstream = CcWebstreamQuery::create()
|
$previousWebstream = CcWebstreamQuery::create()
|
||||||
->filterByDbId($previousMediaStreamId)
|
->filterByDbId($previousMediaStreamId)
|
||||||
->findOne();
|
->findOne();
|
||||||
/*$previousWebstreamMetadata = CcWebstreamMetadataQuery::create()
|
|
||||||
->filterByDbInstanceId($previousMedia->getDbInstanceId())
|
|
||||||
->orderByDbStartTime(Criteria::DESC)
|
|
||||||
->findOne();*/
|
|
||||||
$previousMediaName = $previousWebstream->getDbName();
|
$previousMediaName = $previousWebstream->getDbName();
|
||||||
} else {
|
} else {
|
||||||
$previousMediaType = null;
|
$previousMediaType = null;
|
||||||
|
@ -270,8 +266,9 @@ SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
$nextMedia = CcScheduleQuery::create()
|
$nextMedia = CcScheduleQuery::create()
|
||||||
->filterByDbId($currentMediaScheduleId+1)
|
->filterByDbStarts($currentMedia["starts"], Criteria::GREATER_THAN)
|
||||||
->orderByDbStarts()
|
->filterByDbId($currentMedia["id"], Criteria::NOT_EQUAL)
|
||||||
|
->orderByDbStarts(Criteria::ASC)
|
||||||
->findOne();
|
->findOne();
|
||||||
if (isset($nextMedia)) {
|
if (isset($nextMedia)) {
|
||||||
$nextMediaFileId = $nextMedia->getDbFileId();
|
$nextMediaFileId = $nextMedia->getDbFileId();
|
||||||
|
@ -287,10 +284,6 @@ SQL;
|
||||||
$nextWebstream = CcWebstreamQuery::create()
|
$nextWebstream = CcWebstreamQuery::create()
|
||||||
->filterByDbId($nextMediaStreamId)
|
->filterByDbId($nextMediaStreamId)
|
||||||
->findOne();
|
->findOne();
|
||||||
/*$nextWebstreamMetadata = CcWebstreamMetadataQuery::create()
|
|
||||||
->filterByDbInstanceId($nextMedia->getDbInstanceId())
|
|
||||||
->orderByDbStartTime(Criteria::DESC)
|
|
||||||
->findOne();*/
|
|
||||||
$nextMediaName = $nextWebstream->getDbName();
|
$nextMediaName = $nextWebstream->getDbName();
|
||||||
} else {
|
} else {
|
||||||
$nextMediaType = null;
|
$nextMediaType = null;
|
||||||
|
|
|
@ -85,6 +85,7 @@ api_config['get_files_without_silan_value'] = 'get-files-without-silan-value/api
|
||||||
api_config['update_cue_values_by_silan'] = 'update-cue-values-by-silan/api_key/%%api_key%%'
|
api_config['update_cue_values_by_silan'] = 'update-cue-values-by-silan/api_key/%%api_key%%'
|
||||||
api_config['api_base'] = 'api'
|
api_config['api_base'] = 'api'
|
||||||
api_config['bin_dir'] = '/usr/lib/airtime/api_clients/'
|
api_config['bin_dir'] = '/usr/lib/airtime/api_clients/'
|
||||||
|
api_config['update_metadata_on_tunein'] = 'update-metadata-on-tunein/api_key/%%api_key%%'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -532,6 +533,9 @@ class AirtimeApiClient(object):
|
||||||
#TODO
|
#TODO
|
||||||
self.logger.error(str(e))
|
self.logger.error(str(e))
|
||||||
|
|
||||||
|
def update_metadata_on_tunein(self):
|
||||||
|
self.services.update_metadata_on_tunein()
|
||||||
|
|
||||||
|
|
||||||
class InvalidContentType(Exception):
|
class InvalidContentType(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -14,7 +14,7 @@ import traceback
|
||||||
import pure
|
import pure
|
||||||
|
|
||||||
from Queue import Empty
|
from Queue import Empty
|
||||||
from threading import Thread
|
from threading import Thread, Timer
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
from api_clients import api_client
|
from api_clients import api_client
|
||||||
|
@ -441,6 +441,12 @@ class PypoFetch(Thread):
|
||||||
|
|
||||||
return success
|
return success
|
||||||
|
|
||||||
|
# This function makes a request to Airtime to see if we need to
|
||||||
|
# push metadata to TuneIn. We have to do this because TuneIn turns
|
||||||
|
# off metadata if it does not receive a request every 5 minutes.
|
||||||
|
def update_metadata_on_tunein(self):
|
||||||
|
self.api_client.update_metadata_on_tunein()
|
||||||
|
Timer(120, self.update_metadata_on_tunein).start()
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
#Make sure all Liquidsoap queues are empty. This is important in the
|
#Make sure all Liquidsoap queues are empty. This is important in the
|
||||||
|
@ -452,8 +458,10 @@ class PypoFetch(Thread):
|
||||||
|
|
||||||
self.set_bootstrap_variables()
|
self.set_bootstrap_variables()
|
||||||
|
|
||||||
|
self.update_metadata_on_tunein()
|
||||||
|
|
||||||
# Bootstrap: since we are just starting up, we need to grab the
|
# Bootstrap: since we are just starting up, we need to grab the
|
||||||
# most recent schedule. After that we fetch the schedule every 30
|
# most recent schedule. After that we fetch the schedule every 8
|
||||||
# minutes or wait for schedule updates to get pushed.
|
# minutes or wait for schedule updates to get pushed.
|
||||||
success = self.persistent_manual_schedule_fetch(max_attempts=5)
|
success = self.persistent_manual_schedule_fetch(max_attempts=5)
|
||||||
|
|
||||||
|
@ -463,6 +471,7 @@ class PypoFetch(Thread):
|
||||||
loops = 1
|
loops = 1
|
||||||
while True:
|
while True:
|
||||||
self.logger.info("Loop #%s", loops)
|
self.logger.info("Loop #%s", loops)
|
||||||
|
manual_fetch_needed = False
|
||||||
try:
|
try:
|
||||||
"""
|
"""
|
||||||
our simple_queue.get() requires a timeout, in which case we
|
our simple_queue.get() requires a timeout, in which case we
|
||||||
|
@ -478,17 +487,26 @@ class PypoFetch(Thread):
|
||||||
Currently we are checking every POLL_INTERVAL seconds
|
Currently we are checking every POLL_INTERVAL seconds
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
message = self.fetch_queue.get(block=True, timeout=self.listener_timeout)
|
message = self.fetch_queue.get(block=True, timeout=self.listener_timeout)
|
||||||
|
manual_fetch_needed = False
|
||||||
self.handle_message(message)
|
self.handle_message(message)
|
||||||
except Empty, e:
|
except Empty as e:
|
||||||
self.logger.info("Queue timeout. Fetching schedule manually")
|
self.logger.info("Queue timeout. Fetching schedule manually")
|
||||||
self.persistent_manual_schedule_fetch(max_attempts=5)
|
manual_fetch_needed = True
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
top = traceback.format_exc()
|
top = traceback.format_exc()
|
||||||
self.logger.error('Exception: %s', e)
|
self.logger.error('Exception: %s', e)
|
||||||
self.logger.error("traceback: %s", top)
|
self.logger.error("traceback: %s", top)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if manual_fetch_needed:
|
||||||
|
self.persistent_manual_schedule_fetch(max_attempts=5)
|
||||||
|
except Exception as e:
|
||||||
|
top = traceback.format_exc()
|
||||||
|
self.logger.error('Failed to manually fetch the schedule.')
|
||||||
|
self.logger.error('Exception: %s', e)
|
||||||
|
self.logger.error("traceback: %s", top)
|
||||||
|
|
||||||
loops += 1
|
loops += 1
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -496,3 +514,4 @@ class PypoFetch(Thread):
|
||||||
Entry point of the thread
|
Entry point of the thread
|
||||||
"""
|
"""
|
||||||
self.main()
|
self.main()
|
||||||
|
self.logger.info('PypoFetch thread exiting')
|
||||||
|
|
|
@ -30,6 +30,7 @@ class PypoFile(Thread):
|
||||||
self.media_queue = schedule_queue
|
self.media_queue = schedule_queue
|
||||||
self.media = None
|
self.media = None
|
||||||
self.cache_dir = os.path.join(config["cache_dir"], "scheduler")
|
self.cache_dir = os.path.join(config["cache_dir"], "scheduler")
|
||||||
|
self._config = self.read_config_file(CONFIG_PATH)
|
||||||
|
|
||||||
def copy_file(self, media_item):
|
def copy_file(self, media_item):
|
||||||
"""
|
"""
|
||||||
|
@ -60,11 +61,9 @@ class PypoFile(Thread):
|
||||||
if do_copy:
|
if do_copy:
|
||||||
self.logger.debug("copying from %s to local cache %s" % (src, dst))
|
self.logger.debug("copying from %s to local cache %s" % (src, dst))
|
||||||
try:
|
try:
|
||||||
config = self.read_config_file(CONFIG_PATH)
|
|
||||||
CONFIG_SECTION = "general"
|
CONFIG_SECTION = "general"
|
||||||
username = config.get(CONFIG_SECTION, 'api_key')
|
username = self._config.get(CONFIG_SECTION, 'api_key')
|
||||||
|
host = self._config.get(CONFIG_SECTION, 'base_url')
|
||||||
host = config.get(CONFIG_SECTION, 'base_url')
|
|
||||||
url = "http://%s/rest/media/%s/download" % (host, media_item["id"])
|
url = "http://%s/rest/media/%s/download" % (host, media_item["id"])
|
||||||
with open(dst, "wb") as handle:
|
with open(dst, "wb") as handle:
|
||||||
response = requests.get(url, auth=requests.auth.HTTPBasicAuth(username, ''), stream=True, verify=False)
|
response = requests.get(url, auth=requests.auth.HTTPBasicAuth(username, ''), stream=True, verify=False)
|
||||||
|
@ -205,3 +204,4 @@ class PypoFile(Thread):
|
||||||
Entry point of the thread
|
Entry point of the thread
|
||||||
"""
|
"""
|
||||||
self.main()
|
self.main()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue