SAAS-1071 - more work on backend podcast implementation
This commit is contained in:
parent
dcb30b3aa7
commit
ca51dcf3ae
|
@ -38,7 +38,6 @@ class Podcast extends BasePodcast
|
||||||
* @throws InvalidPodcastException
|
* @throws InvalidPodcastException
|
||||||
* @throws PodcastLimitReachedException
|
* @throws PodcastLimitReachedException
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static function create($data)
|
public static function create($data)
|
||||||
{
|
{
|
||||||
if (Application_Service_PodcastService::podcastLimitReached()) {
|
if (Application_Service_PodcastService::podcastLimitReached()) {
|
||||||
|
@ -98,24 +97,11 @@ class Podcast extends BasePodcast
|
||||||
$podcast->setDbType(IMPORTED_PODCAST);
|
$podcast->setDbType(IMPORTED_PODCAST);
|
||||||
$podcast->save();
|
$podcast->save();
|
||||||
|
|
||||||
$podcastArray = $podcast->toArray(BasePeer::TYPE_FIELDNAME);
|
return self::_generatePodcastArray($podcast, $rss);
|
||||||
|
|
||||||
$podcastArray["episodes"] = array();
|
|
||||||
foreach ($rss->get_items() as $item) {
|
|
||||||
array_push($podcastArray["episodes"], array(
|
|
||||||
"title" => $item->get_title(),
|
|
||||||
"author" => $item->get_author()->get_name(),
|
|
||||||
"description" => $item->get_description(),
|
|
||||||
"pubDate" => $item->get_date("Y-m-d H:i:s"),
|
|
||||||
"link" => $item->get_enclosure()->get_link()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return $podcastArray;
|
|
||||||
} catch(Exception $e) {
|
} catch(Exception $e) {
|
||||||
$podcast->delete();
|
$podcast->delete();
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,6 +111,7 @@ class Podcast extends BasePodcast
|
||||||
* @param $podcastId
|
* @param $podcastId
|
||||||
*
|
*
|
||||||
* @throws PodcastNotFoundException
|
* @throws PodcastNotFoundException
|
||||||
|
* @throws InvalidPodcastException
|
||||||
* @return array - Podcast Array with a full list of episodes
|
* @return array - Podcast Array with a full list of episodes
|
||||||
*/
|
*/
|
||||||
public static function getPodcastById($podcastId)
|
public static function getPodcastById($podcastId)
|
||||||
|
@ -136,10 +123,22 @@ class Podcast extends BasePodcast
|
||||||
|
|
||||||
$rss = Application_Service_PodcastService::getPodcastFeed($podcast->getDbUrl());
|
$rss = Application_Service_PodcastService::getPodcastFeed($podcast->getDbUrl());
|
||||||
if (!$rss) {
|
if (!$rss) {
|
||||||
throw new PodcastNotFoundException();
|
throw new InvalidPodcastException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Get rid of this duplication and move into a new function (serializer/deserializer)
|
return self::_generatePodcastArray($podcast, $rss);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a podcast object and a SimplePie feed object,
|
||||||
|
* generate a data array to pass back to the front-end
|
||||||
|
*
|
||||||
|
* @param Podcast $podcast Podcast model object
|
||||||
|
* @param SimplePie $rss SimplePie feed object
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private static function _generatePodcastArray($podcast, $rss) {
|
||||||
$podcastArray = $podcast->toArray(BasePeer::TYPE_FIELDNAME);
|
$podcastArray = $podcast->toArray(BasePeer::TYPE_FIELDNAME);
|
||||||
|
|
||||||
$podcastArray["episodes"] = array();
|
$podcastArray["episodes"] = array();
|
||||||
|
@ -148,8 +147,9 @@ class Podcast extends BasePodcast
|
||||||
"title" => $item->get_title(),
|
"title" => $item->get_title(),
|
||||||
"author" => $item->get_author()->get_name(),
|
"author" => $item->get_author()->get_name(),
|
||||||
"description" => $item->get_description(),
|
"description" => $item->get_description(),
|
||||||
"pubDate" => $item->get_date("Y-m-d H:i:s"),
|
"pub_date" => $item->get_date("Y-m-d H:i:s"),
|
||||||
"link" => $item->get_enclosure()->get_link()
|
"link" => $item->get_link(),
|
||||||
|
"enclosure" => $item->get_enclosure()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
class Rest_PodcastController extends Zend_Rest_Controller
|
class Rest_PodcastController extends Zend_Rest_Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Application_Service_PodcastService
|
||||||
|
*/
|
||||||
|
protected $_service;
|
||||||
|
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
$this->view->layout()->disableLayout();
|
$this->view->layout()->disableLayout();
|
||||||
|
@ -9,6 +15,7 @@ class Rest_PodcastController extends Zend_Rest_Controller
|
||||||
// Remove reliance on .phtml files to render requests
|
// Remove reliance on .phtml files to render requests
|
||||||
$this->_helper->viewRenderer->setNoRender(true);
|
$this->_helper->viewRenderer->setNoRender(true);
|
||||||
$this->view->setScriptPath(APPLICATION_PATH . 'views/scripts/');
|
$this->view->setScriptPath(APPLICATION_PATH . 'views/scripts/');
|
||||||
|
$this->_service = new Application_Service_PodcastService();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function indexAction()
|
public function indexAction()
|
||||||
|
@ -119,6 +126,7 @@ class Rest_PodcastController extends Zend_Rest_Controller
|
||||||
try {
|
try {
|
||||||
$requestData = json_decode($this->getRequest()->getRawBody(), true);
|
$requestData = json_decode($this->getRequest()->getRawBody(), true);
|
||||||
|
|
||||||
|
$this->_service->downloadEpisodes($requestData["podcast"]["episodes"]);
|
||||||
$podcast = Podcast::updateFromArray($id, $requestData);
|
$podcast = Podcast::updateFromArray($id, $requestData);
|
||||||
|
|
||||||
$this->getResponse()
|
$this->getResponse()
|
||||||
|
|
|
@ -56,7 +56,7 @@ class Application_Service_PodcastService extends Application_Service_ThirdPartyC
|
||||||
$feed->enable_cache(false);
|
$feed->enable_cache(false);
|
||||||
$feed->init();
|
$feed->init();
|
||||||
return $feed;
|
return $feed;
|
||||||
} catch (FeedException $e) {
|
} catch (Exception $e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,15 +66,28 @@ class Application_Service_PodcastService extends Application_Service_ThirdPartyC
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Given an array of track identifiers, download RSS feed tracks
|
* Given an array of episodes, extract the download URLs and send them to Celery
|
||||||
*
|
*
|
||||||
* @param array $trackIds array of track identifiers to download
|
* @param array $episodes array of podcast episodes
|
||||||
|
*/
|
||||||
|
public function downloadEpisodes($episodes) {
|
||||||
|
$episodeUrls = array();
|
||||||
|
foreach($episodes as $episode) {
|
||||||
|
array_push($episodeUrls, $episode["enclosure"]["link"]);
|
||||||
|
}
|
||||||
|
$this->_download($episodeUrls);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an array of download URLs, download RSS feed tracks
|
||||||
|
*
|
||||||
|
* @param array $downloadUrls array of download URLs to send to Celery
|
||||||
* TODO: do we need other parameters here...?
|
* TODO: do we need other parameters here...?
|
||||||
*/
|
*/
|
||||||
public function download($trackIds) {
|
private function _download($downloadUrls) {
|
||||||
$CC_CONFIG = Config::getConfig();
|
$CC_CONFIG = Config::getConfig();
|
||||||
$data = array(
|
$data = array(
|
||||||
// 'download_urls' => , TODO: get download urls to send to Celery
|
'download_urls' => $downloadUrls,
|
||||||
'callback_url' => Application_Common_HTTPHelper::getStationUrl() . '/rest/media',
|
'callback_url' => Application_Common_HTTPHelper::getStationUrl() . '/rest/media',
|
||||||
'api_key' => $apiKey = $CC_CONFIG["apiKey"][0],
|
'api_key' => $apiKey = $CC_CONFIG["apiKey"][0],
|
||||||
);
|
);
|
||||||
|
@ -87,8 +100,8 @@ class Application_Service_PodcastService extends Application_Service_ThirdPartyC
|
||||||
* Update a ThirdPartyTrackReferences object for a completed upload
|
* Update a ThirdPartyTrackReferences object for a completed upload
|
||||||
*
|
*
|
||||||
* @param $task CeleryTasks the completed CeleryTasks object
|
* @param $task CeleryTasks the completed CeleryTasks object
|
||||||
* @param $trackId int ThirdPartyTrackReferences identifier
|
* @param $episodeId int PodcastEpisodes identifier
|
||||||
* @param $track object third-party service track object
|
* @param $episode object object containing Podcast episode information
|
||||||
* @param $status string Celery task status
|
* @param $status string Celery task status
|
||||||
*
|
*
|
||||||
* @return ThirdPartyTrackReferences the updated ThirdPartyTrackReferences object
|
* @return ThirdPartyTrackReferences the updated ThirdPartyTrackReferences object
|
||||||
|
@ -96,14 +109,14 @@ class Application_Service_PodcastService extends Application_Service_ThirdPartyC
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @throws PropelException
|
* @throws PropelException
|
||||||
*/
|
*/
|
||||||
function updateTrackReference($task, $trackId, $track, $status) {
|
public function updateTrackReference($task, $episodeId, $episode, $status) {
|
||||||
$ref = parent::updateTrackReference($task, $trackId, $track, $status);
|
$ref = parent::updateTrackReference($task, $episodeId, $episode, $status);
|
||||||
|
|
||||||
if ($status == CELERY_SUCCESS_STATUS) {
|
if ($status == CELERY_SUCCESS_STATUS) {
|
||||||
// TODO: handle successful download
|
// TODO: handle successful download
|
||||||
// $ref->setDbForeignId();
|
// $ref->setDbForeignId();
|
||||||
// FIXME: we need the file ID here, but 'track' is too arbitrary...
|
// FIXME: we need the file ID here, but 'track' is too arbitrary...
|
||||||
$ref->setDbFileId($track->fileId);
|
$ref->setDbFileId($episode->fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
$ref->save();
|
$ref->save();
|
||||||
|
|
|
@ -6,14 +6,24 @@
|
||||||
<div class="inner_editor_wrapper">
|
<div class="inner_editor_wrapper">
|
||||||
<form class="podcast-metadata">
|
<form class="podcast-metadata">
|
||||||
<input ng-value="podcast.id" class="obj_id" type="hidden"/>
|
<input ng-value="podcast.id" class="obj_id" type="hidden"/>
|
||||||
<label>
|
<p>
|
||||||
<?php echo _("Podcast Name") ?>
|
<label for="podcast_name">
|
||||||
<input disabled ng-model="podcast.title" type="text"/>
|
<?php echo _("Podcast Name") ?>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<input disabled name="podcast_name" ng-model="podcast.title" type="text"/>
|
||||||
<?php echo _("Podcast URL") ?>
|
</p>
|
||||||
<input disabled ng-model="podcast.url" type="text"/>
|
<p>
|
||||||
</label>
|
<label for="podcast_url">
|
||||||
|
<?php echo _("Podcast URL") ?>
|
||||||
|
</label>
|
||||||
|
<input disabled name="podcast_url" ng-model="podcast.url" type="text"/>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="podcast_auto_ingest">
|
||||||
|
<?php echo _("Automatically download latest episodes?") ?>
|
||||||
|
</label>
|
||||||
|
<input name="podcast_auto_ingest" ng-model="podcast.auto_ingest" type="checkbox"/>
|
||||||
|
</p>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
|
|
||||||
//AngularJS app
|
//AngularJS app
|
||||||
var podcastApp = angular.module('podcast', [])
|
var podcastApp = angular.module('podcast', [])
|
||||||
.controller('RestController', function($scope, $http, podcast, tab) {
|
.controller('RestController', function($scope, $http, podcast, tab, episodeTable) {
|
||||||
|
// We need to pass in the tab object and the episodes table object so we can reference them
|
||||||
|
|
||||||
//We take a podcast object in as a parameter rather fetching the podcast by ID here because
|
//We take a podcast object in as a parameter rather fetching the podcast by ID here because
|
||||||
//when you're creating a new podcast, we already have the object from the result of the POST. We're saving
|
//when you're creating a new podcast, we already have the object from the result of the POST. We're saving
|
||||||
|
@ -20,7 +21,9 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
tab.setName($scope.podcast.title);
|
tab.setName($scope.podcast.title);
|
||||||
|
|
||||||
$scope.savePodcast = function() {
|
$scope.savePodcast = function() {
|
||||||
$http.put(endpoint + $scope.podcast.id, { csrf_token: jQuery("#csrf").val(), podcast: $scope.podcast })
|
var podcastData = $scope.podcast; // Copy the podcast in scope so we can modify it
|
||||||
|
podcastData.episodes = episodeTable.getSelectedRows();
|
||||||
|
$http.put(endpoint + $scope.podcast.id, { csrf_token: jQuery("#csrf").val(), podcast: podcastData })
|
||||||
.success(function() {
|
.success(function() {
|
||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
@ -44,9 +47,10 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
$.post(endpoint + "bulk", { csrf_token: $("#csrf").val(), method: method, ids: ids }, callback);
|
$.post(endpoint + "bulk", { csrf_token: $("#csrf").val(), method: method, ids: ids }, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _bootstrapAngularApp(podcast, tab) {
|
function _bootstrapAngularApp(podcast, tab, table) {
|
||||||
podcastApp.value('podcast', podcast);
|
podcastApp.value('podcast', podcast);
|
||||||
podcastApp.value('tab', tab);
|
podcastApp.value('tab', tab);
|
||||||
|
podcastApp.value('episodeTable', table);
|
||||||
var wrapper = tab.contents.find(".editor_pane_wrapper");
|
var wrapper = tab.contents.find(".editor_pane_wrapper");
|
||||||
wrapper.attr("ng-controller", "RestController");
|
wrapper.attr("ng-controller", "RestController");
|
||||||
angular.bootstrap(wrapper.get(0), ["podcast"]);
|
angular.bootstrap(wrapper.get(0), ["podcast"]);
|
||||||
|
@ -70,9 +74,9 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
var podcast = JSON.parse(json.podcast);
|
var podcast = JSON.parse(json.podcast);
|
||||||
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+podcast.id,
|
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+podcast.id,
|
||||||
tab = AIRTIME.tabs.openTab(json, uid, null);
|
tab = AIRTIME.tabs.openTab(json, uid, null);
|
||||||
_bootstrapAngularApp(podcast, tab);
|
var table = mod.initPodcastEpisodeDatatable(podcast.episodes);
|
||||||
|
_bootstrapAngularApp(podcast, tab, table);
|
||||||
$("#podcast_url_dialog").dialog("close");
|
$("#podcast_url_dialog").dialog("close");
|
||||||
mod.initPodcastEpisodeDatatable(podcast.episodes);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,8 +86,8 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
var podcast = JSON.parse(el.podcast);
|
var podcast = JSON.parse(el.podcast);
|
||||||
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+podcast.id,
|
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+podcast.id,
|
||||||
tab = AIRTIME.tabs.openTab(el, uid, null);
|
tab = AIRTIME.tabs.openTab(el, uid, null);
|
||||||
_bootstrapAngularApp(podcast, tab);
|
var table = mod.initPodcastEpisodeDatatable(podcast.episodes);
|
||||||
mod.initPodcastEpisodeDatatable(podcast.episodes);
|
_bootstrapAngularApp(podcast, tab, table);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -102,13 +106,13 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
/* Author */ { "sTitle" : $.i18n._("Author") , "mDataProp" : "author" , "sClass" : "podcast_episodes_author" , "sWidth" : "170px" },
|
/* Author */ { "sTitle" : $.i18n._("Author") , "mDataProp" : "author" , "sClass" : "podcast_episodes_author" , "sWidth" : "170px" },
|
||||||
/* Description */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" },
|
/* Description */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" },
|
||||||
/* Link */ { "sTitle" : $.i18n._("Link") , "mDataProp" : "link" , "sClass" : "podcast_episodes_link" , "sWidth" : "170px" },
|
/* Link */ { "sTitle" : $.i18n._("Link") , "mDataProp" : "link" , "sClass" : "podcast_episodes_link" , "sWidth" : "170px" },
|
||||||
/* Publication Date */ { "sTitle" : $.i18n._("Publication Date") , "mDataProp" : "pubDate" , "sClass" : "podcast_episodes_pub_date" , "sWidth" : "170px" }
|
/* Publication Date */ { "sTitle" : $.i18n._("Publication Date") , "mDataProp" : "pub_date" , "sClass" : "podcast_episodes_pub_date" , "sWidth" : "170px" }
|
||||||
];
|
];
|
||||||
|
|
||||||
var podcastToolbarButtons = AIRTIME.widgets.Table.getStandardToolbarButtons();
|
var podcastToolbarButtons = AIRTIME.widgets.Table.getStandardToolbarButtons();
|
||||||
|
|
||||||
// Set up the div with id "podcast_table" as a datatable.
|
// Set up the div with id "podcast_table" as a datatable.
|
||||||
mod.podcastEpisodesTableWidget = new AIRTIME.widgets.Table(
|
var podcastEpisodesTableWidget = new AIRTIME.widgets.Table(
|
||||||
AIRTIME.tabs.getActiveTab().contents.find('#podcast_episodes'), // DOM node to create the table inside.
|
AIRTIME.tabs.getActiveTab().contents.find('#podcast_episodes'), // DOM node to create the table inside.
|
||||||
true, // Enable item selection
|
true, // Enable item selection
|
||||||
podcastToolbarButtons, // Toolbar buttons
|
podcastToolbarButtons, // Toolbar buttons
|
||||||
|
@ -116,11 +120,17 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
'aoColumns' : aoColumns,
|
'aoColumns' : aoColumns,
|
||||||
'bServerSide': false,
|
'bServerSide': false,
|
||||||
'sAjaxSource' : null,
|
'sAjaxSource' : null,
|
||||||
'aaData' : episodes
|
'aaData' : episodes,
|
||||||
|
"oColVis": {
|
||||||
|
"sAlign": "right",
|
||||||
|
"aiExclude": [0, 1],
|
||||||
|
"buttonText": $.i18n._("Columns"),
|
||||||
|
"iOverlayFade": 0
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mod.podcastEpisodesDatatable = mod.podcastEpisodesTableWidget.getDatatable();
|
podcastEpisodesTableWidget.getDatatable().textScroll("td");
|
||||||
mod.podcastEpisodesDatatable.textScroll("td");
|
return podcastEpisodesTableWidget;
|
||||||
};
|
};
|
||||||
|
|
||||||
return AIRTIME;
|
return AIRTIME;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"_readme": [
|
"_readme": [
|
||||||
"This file locks the dependencies of your project to a known state",
|
"This file locks the dependencies of your project to a known state",
|
||||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "8d8a51740ad37127ff6618f80861ccfc",
|
"hash": "8d8a51740ad37127ff6618f80861ccfc",
|
||||||
|
@ -231,7 +231,7 @@
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"predis/predis": "0.8.5",
|
"predis/predis": ">=0.8.5",
|
||||||
"videlalvaro/php-amqplib": ">=2.4.0"
|
"videlalvaro/php-amqplib": ">=2.4.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
|
@ -363,29 +363,32 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "predis/predis",
|
"name": "predis/predis",
|
||||||
"version": "v0.8.5",
|
"version": "v1.0.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/nrk/predis.git",
|
"url": "https://github.com/nrk/predis.git",
|
||||||
"reference": "5f2eea628eb465d866ad2771927d83769c8f956c"
|
"reference": "84060b9034d756b4d79641667d7f9efe1aeb8e04"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/nrk/predis/zipball/5f2eea628eb465d866ad2771927d83769c8f956c",
|
"url": "https://api.github.com/repos/nrk/predis/zipball/84060b9034d756b4d79641667d7f9efe1aeb8e04",
|
||||||
"reference": "5f2eea628eb465d866ad2771927d83769c8f956c",
|
"reference": "84060b9034d756b4d79641667d7f9efe1aeb8e04",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.2"
|
"php": ">=5.3.2"
|
||||||
},
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.0"
|
||||||
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-curl": "Allows access to Webdis when paired with phpiredis",
|
"ext-curl": "Allows access to Webdis when paired with phpiredis",
|
||||||
"ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
|
"ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {
|
"psr-4": {
|
||||||
"Predis": "lib/"
|
"Predis\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
@ -406,7 +409,7 @@
|
||||||
"predis",
|
"predis",
|
||||||
"redis"
|
"redis"
|
||||||
],
|
],
|
||||||
"time": "2014-01-16 14:10:29"
|
"time": "2015-07-30 18:34:15"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "propel/propel1",
|
"name": "propel/propel1",
|
||||||
|
@ -700,6 +703,7 @@
|
||||||
"simplepie/simplepie": 20
|
"simplepie/simplepie": 20
|
||||||
},
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
"platform": [],
|
"platform": [],
|
||||||
"platform-dev": []
|
"platform-dev": []
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,12 @@ import json
|
||||||
import urllib2
|
import urllib2
|
||||||
import requests
|
import requests
|
||||||
import soundcloud
|
import soundcloud
|
||||||
|
import cgi
|
||||||
|
import urlparse
|
||||||
|
import posixpath
|
||||||
from celery import Celery
|
from celery import Celery
|
||||||
from celery.utils.log import get_task_logger
|
from celery.utils.log import get_task_logger
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
celery = Celery()
|
celery = Celery()
|
||||||
logger = get_task_logger(__name__)
|
logger = get_task_logger(__name__)
|
||||||
|
@ -93,10 +97,18 @@ def podcast_download(download_urls, callback_url, api_key):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
for url in download_urls:
|
for url in download_urls:
|
||||||
r = requests.get(url, stream=True)
|
with closing(requests.get(url, stream=True)) as r:
|
||||||
r.raise_for_status()
|
# Try to get the filename from the content disposition
|
||||||
with r as f:
|
d = r.headers.get('Content-Disposition')
|
||||||
requests.post(callback_url, data=f, auth=requests.auth.HTTPBasicAuth(api_key, ''))
|
if d:
|
||||||
|
_, params = cgi.parse_header(d)
|
||||||
|
filename = params['filename']
|
||||||
|
else:
|
||||||
|
# Since we don't necessarily get the filename back in the response headers,
|
||||||
|
# parse the URL and get the filename and extension
|
||||||
|
path = urlparse.urlsplit(r.url).path
|
||||||
|
filename = posixpath.basename(path)
|
||||||
|
requests.post(callback_url, files={'file': (filename, r.content)}, auth=requests.auth.HTTPBasicAuth(api_key, ''))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info('Error during file download: {0}'.format(e.message))
|
logger.info('Error during file download: {0}'.format(e.message))
|
||||||
logger.info(str(e))
|
logger.info(str(e))
|
||||||
|
|
Loading…
Reference in New Issue