* SAAS-1182 - added sanity checks and additional logic to rss import and episode generation
* SAAS-1184 - started work on podcast UI polishing * Fixed pull request issues
This commit is contained in:
parent
1bc0f9e54b
commit
0360b5e460
8 changed files with 59 additions and 32 deletions
|
@ -310,7 +310,7 @@ class StationPodcastTask implements AirtimeTask {
|
||||||
class TaskFactory {
|
class TaskFactory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PHP doesn't have ENUMs so declare them as interface constants
|
* PHP doesn't have ENUMs so declare them as constants
|
||||||
* Task types - values don't really matter as long as they're unique
|
* Task types - values don't really matter as long as they're unique
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,6 @@ class LibraryController extends Zend_Controller_Action
|
||||||
$message = null;
|
$message = null;
|
||||||
$noPermissionMsg = _("You don't have permission to delete selected items.");
|
$noPermissionMsg = _("You don't have permission to delete selected items.");
|
||||||
|
|
||||||
Logging::info($mediaItems);
|
|
||||||
foreach ($mediaItems as $media) {
|
foreach ($mediaItems as $media) {
|
||||||
|
|
||||||
if ($media["type"] === "audioclip") {
|
if ($media["type"] === "audioclip") {
|
||||||
|
|
|
@ -288,6 +288,12 @@ class Application_Service_PodcastEpisodeService extends Application_Service_Thir
|
||||||
|
|
||||||
$episodesArray = array();
|
$episodesArray = array();
|
||||||
foreach ($rss->get_items() as $item) {
|
foreach ($rss->get_items() as $item) {
|
||||||
|
// If the enclosure is empty, this isn't a podcast episode
|
||||||
|
$enclosure = $item->get_enclosure();
|
||||||
|
$url = $enclosure instanceof SimplePie_Enclosure ? $enclosure->get_link() : $enclosure["link"];
|
||||||
|
if (empty($url)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$itemId = $item->get_id();
|
$itemId = $item->get_id();
|
||||||
$ingested = in_array($itemId, $episodeIds) ? (empty($episodeFiles[$itemId]) ? -1 : 1) : 0;
|
$ingested = in_array($itemId, $episodeIds) ? (empty($episodeFiles[$itemId]) ? -1 : 1) : 0;
|
||||||
$file = $ingested > 0 && !empty($episodeFiles[$itemId]) ?
|
$file = $ingested > 0 && !empty($episodeFiles[$itemId]) ?
|
||||||
|
|
|
@ -86,8 +86,17 @@ class Application_Service_PodcastService
|
||||||
$podcastArray["link"] = htmlspecialchars($rss->get_link());
|
$podcastArray["link"] = htmlspecialchars($rss->get_link());
|
||||||
$podcastArray["language"] = htmlspecialchars($rss->get_language());
|
$podcastArray["language"] = htmlspecialchars($rss->get_language());
|
||||||
$podcastArray["copyright"] = htmlspecialchars($rss->get_copyright());
|
$podcastArray["copyright"] = htmlspecialchars($rss->get_copyright());
|
||||||
$podcastArray["creator"] = htmlspecialchars($rss->get_author()->get_name());
|
|
||||||
$podcastArray["category"] = htmlspecialchars($rss->get_categories());
|
$name = empty($rss->get_author()) ? "" : $rss->get_author()->get_name();
|
||||||
|
$podcastArray["creator"] = htmlspecialchars($name);
|
||||||
|
|
||||||
|
$categories = array();
|
||||||
|
if (is_array($rss->get_categories())) {
|
||||||
|
foreach ($rss->get_categories() as $category) {
|
||||||
|
array_push($categories, $category->get_scheme() . ":" . $category->get_term());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$podcastArray["category"] = htmlspecialchars(implode($categories));
|
||||||
|
|
||||||
//TODO: put in constants
|
//TODO: put in constants
|
||||||
$itunesChannel = "http://www.itunes.com/dtds/podcast-1.0.dtd";
|
$itunesChannel = "http://www.itunes.com/dtds/podcast-1.0.dtd";
|
||||||
|
@ -97,11 +106,13 @@ class Application_Service_PodcastService
|
||||||
|
|
||||||
$itunesCategory = $rss->get_channel_tags($itunesChannel, 'category');
|
$itunesCategory = $rss->get_channel_tags($itunesChannel, 'category');
|
||||||
$categoryArray = array();
|
$categoryArray = array();
|
||||||
|
if (is_array($itunesCategory)) {
|
||||||
foreach ($itunesCategory as $c => $data) {
|
foreach ($itunesCategory as $c => $data) {
|
||||||
foreach ($data["attribs"] as $attrib) {
|
foreach ($data["attribs"] as $attrib) {
|
||||||
array_push($categoryArray, $attrib["text"]);
|
array_push($categoryArray, $attrib["text"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$podcastArray["itunes_category"] = implode(",", $categoryArray);
|
$podcastArray["itunes_category"] = implode(",", $categoryArray);
|
||||||
|
|
||||||
$itunesAuthor = $rss->get_channel_tags($itunesChannel, 'author');
|
$itunesAuthor = $rss->get_channel_tags($itunesChannel, 'author');
|
||||||
|
@ -128,6 +139,7 @@ class Application_Service_PodcastService
|
||||||
$importedPodcast = new ImportedPodcast();
|
$importedPodcast = new ImportedPodcast();
|
||||||
$importedPodcast->fromArray($podcastArray, BasePeer::TYPE_FIELDNAME);
|
$importedPodcast->fromArray($podcastArray, BasePeer::TYPE_FIELDNAME);
|
||||||
$importedPodcast->setPodcast($podcast);
|
$importedPodcast->setPodcast($podcast);
|
||||||
|
$importedPodcast->setDbAutoIngest(true);
|
||||||
$importedPodcast->save();
|
$importedPodcast->save();
|
||||||
|
|
||||||
return $podcast->toArray(BasePeer::TYPE_FIELDNAME);
|
return $podcast->toArray(BasePeer::TYPE_FIELDNAME);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="datatable podcast_episodes" cellpadding="0" cellspacing="0"></table>
|
<!-- <table class="datatable podcast_episodes" cellpadding="0" cellspacing="0"></table>-->
|
||||||
|
|
||||||
<div class="btn-toolbar clearfix">
|
<div class="btn-toolbar clearfix">
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
|
|
|
@ -54,22 +54,22 @@
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend><?php echo _("iTunes Fields") ?></legend>
|
<legend><?php echo _("iTunes Fields") ?></legend>
|
||||||
<label><?php echo _("iTunes Author") ?></label>
|
<label><?php echo _("Author") ?></label>
|
||||||
<input name="podcast_itunes_author" ng-model="podcast.itunes_author" type="text"/>
|
<input name="podcast_itunes_author" ng-model="podcast.itunes_author" type="text"/>
|
||||||
|
|
||||||
<label><?php echo _("iTunes Keywords") ?></label>
|
<label><?php echo _("Keywords") ?></label>
|
||||||
<input name="podcast_itunes_keywords" ng-model="podcast.itunes_keywords" type="text"/>
|
<input name="podcast_itunes_keywords" ng-model="podcast.itunes_keywords" type="text"/>
|
||||||
|
|
||||||
<label><?php echo _("iTunes Summary") ?></label>
|
<label><?php echo _("Summary") ?></label>
|
||||||
<textarea name="podcast_itunes_summary" ng-model="podcast.itunes_summary"></textarea>
|
<textarea name="podcast_itunes_summary" ng-model="podcast.itunes_summary"></textarea>
|
||||||
|
|
||||||
<label><?php echo _("iTunes Subtitle") ?></label>
|
<label><?php echo _("Subtitle") ?></label>
|
||||||
<textarea name="podcast_itunes_subtitle" ng-model="podcast.itunes_subtitle"></textarea>
|
<textarea name="podcast_itunes_subtitle" ng-model="podcast.itunes_subtitle"></textarea>
|
||||||
|
|
||||||
<label><?php echo _("iTunes Category") ?></label>
|
<label><?php echo _("Category") ?></label>
|
||||||
<input name="podcast_itunes_category" ng-model="podcast.itunes_category" type="text"/>
|
<input name="podcast_itunes_category" ng-model="podcast.itunes_category" type="text"/>
|
||||||
|
|
||||||
<label><?php echo _("iTunes Explicit") ?></label>
|
<label><?php echo _("Explicit") ?></label>
|
||||||
<input name="podcast_itunes_explicit" ng-model="podcast.itunes_explicit" type="checkbox"/>
|
<input name="podcast_itunes_explicit" ng-model="podcast.itunes_explicit" type="checkbox"/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1274,7 +1274,7 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
var dialog = $("#podcast_episode_dialog").html(episode.description);
|
var dialog = $("#podcast_episode_dialog").html(episode.description);
|
||||||
dialog.html(dialog.text());
|
dialog.html(dialog.text());
|
||||||
dialog.dialog({
|
dialog.dialog({
|
||||||
title: $.i18n._(episode.title),
|
title: episode.title,
|
||||||
width: "auto",
|
width: "auto",
|
||||||
height: "auto",
|
height: "auto",
|
||||||
modal: true,
|
modal: true,
|
||||||
|
|
|
@ -12,8 +12,8 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
/**
|
/**
|
||||||
* PodcastController constructor.
|
* PodcastController constructor.
|
||||||
*
|
*
|
||||||
* @param {Object} $scope angular scope service object
|
* @param {angular.scope} $scope angular scope service object
|
||||||
* @param {Object} $http angular http service object
|
* @param {angular.http} $http angular http service object
|
||||||
* @param {Object} podcast podcast metadata object
|
* @param {Object} podcast podcast metadata object
|
||||||
* @param {int} podcast.id podcast unique identifier
|
* @param {int} podcast.id podcast unique identifier
|
||||||
* @param {string} podcast.title podcast metadata title
|
* @param {string} podcast.title podcast metadata title
|
||||||
|
@ -80,6 +80,9 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
PodcastController.prototype._initTable = function() {
|
PodcastController.prototype._initTable = function() {
|
||||||
|
/*
|
||||||
|
* Remove the episode table for imported podcasts since its functionality is replicated in the left-hand pane
|
||||||
|
*
|
||||||
var self = this,
|
var self = this,
|
||||||
$scope = self.$scope;
|
$scope = self.$scope;
|
||||||
// We want to fetch the data statically for imported podcasts because we would need to implement sorting
|
// We want to fetch the data statically for imported podcasts because we would need to implement sorting
|
||||||
|
@ -91,12 +94,12 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
// If we load sequentially there's a delay before the table appears
|
// If we load sequentially there's a delay before the table appears
|
||||||
aaData : {},
|
aaData : {},
|
||||||
aoColumns : [
|
aoColumns : [
|
||||||
/* GUID */ { "sTitle" : "" , "mDataProp" : "guid" , "sClass" : "podcast_episodes_guid" , "bVisible" : false },
|
{ "sTitle" : "" , "mDataProp" : "guid" , "sClass" : "podcast_episodes_guid" , "bVisible" : false },
|
||||||
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" },
|
{ "sTitle" : $.i18n._("Title") , "mDataProp" : "title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" },
|
||||||
/* Author */ { "sTitle" : $.i18n._("Author") , "mDataProp" : "author" , "sClass" : "podcast_episodes_author" , "sWidth" : "170px" },
|
{ "sTitle" : $.i18n._("Author") , "mDataProp" : "author" , "sClass" : "podcast_episodes_author" , "sWidth" : "170px" },
|
||||||
/* Description */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" },
|
{ "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" },
|
||||||
/* Link */ { "sTitle" : $.i18n._("Link") , "mDataProp" : "link" , "sClass" : "podcast_episodes_link" , "sWidth" : "170px" },
|
{ "sTitle" : $.i18n._("Link") , "mDataProp" : "link" , "sClass" : "podcast_episodes_link" , "sWidth" : "170px" },
|
||||||
/* Publication Date */ { "sTitle" : $.i18n._("Publication Date") , "mDataProp" : "pub_date" , "sClass" : "podcast_episodes_pub_date" , "sWidth" : "170px" }
|
{ "sTitle" : $.i18n._("Publication Date") , "mDataProp" : "pub_date" , "sClass" : "podcast_episodes_pub_date" , "sWidth" : "170px" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
buttons = {
|
buttons = {
|
||||||
|
@ -127,6 +130,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
self.reloadEpisodeTable();
|
self.reloadEpisodeTable();
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,9 +155,11 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
/**
|
/**
|
||||||
* StationPodcastController constructor.
|
* StationPodcastController constructor.
|
||||||
*
|
*
|
||||||
* @param {{}} $scope angular scope service object
|
* @param {angular.scope} $scope angular scope service object
|
||||||
* @param {{}} $http angular http service object
|
* @param {angular.http} $http angular http service object
|
||||||
* @param {{}} podcast podcast metadata object
|
* @param {Object} podcast podcast metadata object
|
||||||
|
* @param {int} podcast.id podcast unique identifier
|
||||||
|
* @param {string} podcast.title podcast metadata title
|
||||||
* @param {Tab} tab Tab object the controller is being bootstrapped in
|
* @param {Tab} tab Tab object the controller is being bootstrapped in
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
|
@ -496,6 +502,10 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
mod.addPodcast = function () {
|
mod.addPodcast = function () {
|
||||||
$.post(endpoint, $("#podcast_url_dialog").find("form").serialize(), function(json) {
|
$.post(endpoint, $("#podcast_url_dialog").find("form").serialize(), function(json) {
|
||||||
_initAppFromResponse(json);
|
_initAppFromResponse(json);
|
||||||
|
// Open the episode view for the newly created podcast in the left-hand pane
|
||||||
|
AIRTIME.library.podcastEpisodeTableWidget.reload(JSON.parse(json.podcast).id);
|
||||||
|
AIRTIME.library.podcastTableWidget.clearSelection();
|
||||||
|
AIRTIME.library.setCurrentTable(AIRTIME.library.DataTableTypeEnum.PODCAST_EPISODES);
|
||||||
$("#podcast_url_dialog").dialog("close");
|
$("#podcast_url_dialog").dialog("close");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -613,7 +623,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
var selected = self.getSelectedRows().length, container,
|
var selected = self.getSelectedRows().length, container,
|
||||||
width = self._$wrapperDOMNode.closest(".dataTables_wrapper").outerWidth(), message;
|
width = self._$wrapperDOMNode.closest(".dataTables_wrapper").outerWidth(), message;
|
||||||
|
|
||||||
message = sprintf($.i18n._("Adding %s Item%s"), selected, selected > 1 ? "s" : "");
|
message = sprintf($.i18n._(selected > 1 ? "Adding %s Items" : "Adding %s Item"), selected);
|
||||||
container = $('<div/>').attr('id', 'draggingContainer').append('<tr/>')
|
container = $('<div/>').attr('id', 'draggingContainer').append('<tr/>')
|
||||||
.find("tr").append('<td/>').find("td")
|
.find("tr").append('<td/>').find("td")
|
||||||
.attr("colspan", 100).width(width).css("max-width", "none")
|
.attr("colspan", 100).width(width).css("max-width", "none")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue