Fix bug with import status of podcst episodes

This commit is contained in:
Duncan Sommerville 2015-11-12 11:37:39 -05:00
parent c7dcd4f00a
commit 26c9a19836
5 changed files with 31 additions and 94 deletions

View file

@ -323,6 +323,10 @@ class Application_Service_PodcastEpisodeService extends Application_Service_Thir
$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]) ?
CcFiles::getSanitizedFileById($episodeFiles[$itemId]) : array(); CcFiles::getSanitizedFileById($episodeFiles[$itemId]) : array();
// If the analyzer hasn't finished with the file, leave it as pending
if (!empty($file) && $file["import_status"] == CcFiles::IMPORT_STATUS_PENDING) {
$ingested = -1;
}
array_push($episodesArray, array( array_push($episodesArray, array(
"podcast_id" => $podcast->getDbId(), "podcast_id" => $podcast->getDbId(),

View file

@ -335,6 +335,7 @@ thead th.ui-state-default:focus {
#sb_show_filter { #sb_show_filter {
right: 0; right: 0;
max-width: 125px;
position: absolute; position: absolute;
} }

View file

@ -4011,6 +4011,10 @@ li .ui-state-hover {
top: 74px !important; top: 74px !important;
} }
.angular_wrapper > .btn-toolbar {
padding: 5px 0 0 5px;
}
.podcast-metadata p { .podcast-metadata p {
text-align: center; text-align: center;
padding: 0 10px; padding: 0 10px;

View file

@ -1486,13 +1486,6 @@ var AIRTIME = (function(AIRTIME) {
click: function () { click: function () {
var data = [], episodes = mod.podcastEpisodeTableWidget.getSelectedRows(); var data = [], episodes = mod.podcastEpisodeTableWidget.getSelectedRows();
$.each(episodes, function () { $.each(episodes, function () {
// If the file exists but the ftype is empty, the file hasn't finished being
// analyzed. This forces the deletion, but causes the analyzer to throw an error...
// I'm opting for more consistent behaviour (if it looks like a file is imported,
// the user should be able to delete it, rather than it seeming like the delete
// button did nothing), but maybe the answer is to add an additional state that
// checks if the file is finished being analyzed? -- Duncan FIXME
if (this.file.ftype === "") { this.file.ftype = "audioclip"; }
data.push({id: this.file.id, type: this.file.ftype}); data.push({id: this.file.id, type: this.file.ftype});
}); });
mod.fnDeleteItems(data); mod.fnDeleteItems(data);

View file

@ -33,21 +33,6 @@ var AIRTIME = (function (AIRTIME) {
$scope.csrf = jQuery("#csrf").val(); $scope.csrf = jQuery("#csrf").val();
tab.contents.find("table").attr("id", "podcast_episodes_" + podcast.id); tab.contents.find("table").attr("id", "podcast_episodes_" + podcast.id);
/**
* Override the switchTo function to reload the table when the tab is focused.
* Should help to reduce the number of cases where the frontend doesn't match the state
* of the backend (due to automatic ingestion).
*
* Note that these cases should already be very few and far between.
*
* TODO: make sure this doesn't noticeably slow performance
* XXX: it's entirely possible that this (in the angular app) is not where we want this function...
*/
tab.switchTo = function () {
AIRTIME.tabs.Tab.prototype.switchTo.call(this);
self.reloadEpisodeTable();
};
/** /**
* Save and update the podcast object. * Save and update the podcast object.
*/ */
@ -74,72 +59,6 @@ var AIRTIME = (function (AIRTIME) {
return self; return self;
} }
/**
* Initialize the podcast episode table.
*
* @private
*/
PodcastController.prototype._initTable = function() {
/*
* Remove the episode table for imported podcasts since its functionality is replicated in the left-hand pane
*
var self = this,
$scope = self.$scope;
// We want to fetch the data statically for imported podcasts because we would need to implement sorting
// in a very convoluted way on the backend to accommodate the nonexistent rows for uningested episodes
var params = {
bServerSide : false,
sAjaxSource : null,
// Initialize the table with empty data so we can defer loading
// If we load sequentially there's a delay before the table appears
aaData : {},
aoColumns : [
{ "sTitle" : "" , "mDataProp" : "guid" , "sClass" : "podcast_episodes_guid" , "bVisible" : false },
{ "sTitle" : $.i18n._("Title") , "mDataProp" : "title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" },
{ "sTitle" : $.i18n._("Author") , "mDataProp" : "author" , "sClass" : "podcast_episodes_author" , "sWidth" : "170px" },
{ "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" },
{ "sTitle" : $.i18n._("Link") , "mDataProp" : "link" , "sClass" : "podcast_episodes_link" , "sWidth" : "170px" },
{ "sTitle" : $.i18n._("Publication Date") , "mDataProp" : "pub_date" , "sClass" : "podcast_episodes_pub_date" , "sWidth" : "170px" }
]
},
buttons = {
slideToggle: {},
importBtn: {
title : $.i18n._('Import Selected'),
iconClass : '',
extraBtnClass : 'btn-new',
elementId : '',
eventHandlers : {
click: function () {
mod.importSelectedEpisodes(self.episodeTable.getSelectedRows(), self.episodeTable);
}
},
validateConstraints: function () {
// Only importable rows can be selected
return this.getSelectedRows().length >= 1;
}
}
};
self.episodeTable = AIRTIME.podcast.initPodcastEpisodeDatatable(
$scope.tab.contents.find('.podcast_episodes'),
params,
buttons,
{
hideIngestCheckboxes: true,
podcastId: $scope.podcast.id
}
);
self.reloadEpisodeTable();
*/
};
/**
* Reload the podcast episode table.
*/
PodcastController.prototype.reloadEpisodeTable = function() {
this.episodeTable.reload();
};
/** /**
* Initialize the controller. * Initialize the controller.
* *
@ -150,7 +69,6 @@ var AIRTIME = (function (AIRTIME) {
// TODO: this solves a race condition, but we should look for the root cause // TODO: this solves a race condition, but we should look for the root cause
AIRTIME.tabs.onResize(); AIRTIME.tabs.onResize();
self.$scope.tab.setName(self.$scope.podcast.title); self.$scope.tab.setName(self.$scope.podcast.title);
self._initTable();
// Add an onclose hook to the tab to remove the table object and the // Add an onclose hook to the tab to remove the table object and the
// import listener so we don't cause memory leaks. // import listener so we don't cause memory leaks.
if (self.episodeTable) { if (self.episodeTable) {
@ -182,15 +100,31 @@ var AIRTIME = (function (AIRTIME) {
$stationPodcastTab = tab; $stationPodcastTab = tab;
/** /**
* Override the tab close function to 'unset' the module-scope $stationPodcastTab.
*
* @override * @override
*
* Override the tab close function to 'unset' the module-scope $stationPodcastTab.
*/ */
tab.close = function () { tab.close = function () {
AIRTIME.tabs.Tab.prototype.close.call(this); AIRTIME.tabs.Tab.prototype.close.call(this);
$stationPodcastTab = undefined; $stationPodcastTab = undefined;
}; };
/**
* @override
*
* Override the switchTo function to reload the table when the tab is focused.
* Should help to reduce the number of cases where the frontend doesn't match the state
* of the backend (due to automatic ingestion).
*
* Note that these cases should already be very few and far between.
*
* XXX: it's entirely possible that this (in the angular module) is not where we want this function...
*/
tab.switchTo = function () {
AIRTIME.tabs.Tab.prototype.switchTo.call(this);
self.reloadEpisodeTable();
};
return this; return this;
} }
@ -259,7 +193,7 @@ var AIRTIME = (function (AIRTIME) {
params = { params = {
sAjaxSource : endpoint + $scope.podcast.id + '/episodes', sAjaxSource : endpoint + $scope.podcast.id + '/episodes',
aoColumns: [ aoColumns: [
// TODO: it might be dangerous to use CcFiles here? We should alias this instead // TODO: it might be wrong to use CcFiles here? We should alias this instead
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "CcFiles.track_title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" }, /* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "CcFiles.track_title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" },
/* Description */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "CcFiles.description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" } /* Description */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "CcFiles.description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" }
] ]
@ -283,12 +217,13 @@ var AIRTIME = (function (AIRTIME) {
PodcastController.prototype.initialize.call(this); PodcastController.prototype.initialize.call(this);
// We want to override the default tab name behaviour and use "Station Podcast" for clarity // We want to override the default tab name behaviour and use "Station Podcast" for clarity
this.$scope.tab.setName(jQuery.i18n._("Station Podcast")); this.$scope.tab.setName(jQuery.i18n._("Station Podcast"));
self._initTable();
}; };
/** /**
* Reload the Station podcast episode table.
*
* @override * @override
*
* Reload the Station podcast episode table.
*/ */
StationPodcastController.prototype.reloadEpisodeTable = function() { StationPodcastController.prototype.reloadEpisodeTable = function() {
this.episodeTable.getDatatable().fnDraw(); this.episodeTable.getDatatable().fnDraw();