define('application/managers/recording', [
'rofl/class',
'rofl/lib/promise',
'rofl/lib/utils',
'application/managers/api',
'antie/runtimecontext',
'application/events/recordevent'
], function (
Class,
Promise,
Utils,
ApiManager,
RuntimeContext,
RecordEvent
) {
'use strict';
var application,
api,
instance,
RecordingManager;
RecordingManager = Class.extend({
/**
* Initialises the recording manager.
*/
init: function () {
api = ApiManager.getKPNAPI();
application = RuntimeContext.getCurrentApplication();
this._slots = {};
},
/**
* Returns the recordings.
*
* @param {Object} options - The options.
* @returns {Promise} - Promise resolving with the recordings.
*/
getRecordings: function (options) {
var promises = [];
promises.push(this._getEpisodes(options));
promises.push(this._getSeries(options));
return Promise.all(promises);
},
/**
* Returns the future recordings.
*
* @param {Object} [opts] - The retrieval options.
* @returns {Promise} - Promise resolving with the future recordings.
*/
getFutureRecordings: function (opts) {
var now = application.getDate();
return this._getEpisodes(opts)
.then(function (result) {
return Utils.filter(result, function (a) {
return a.getStartTime() * 1000 > now.getTime();
});
});
},
/**
* Returns the current recordings.
*
* @param {Object} [opts] - The retrieval options.
* @returns {Promise} - Promise resolving with the current recordings.
*/
getCurrentRecordings: function (opts) {
var now = application.getDate();
return this._getEpisodes(opts)
.then(function (result) {
return Utils.filter(result, function (a) {
return a.getStartTime() * 1000 < now.getTime();
});
});
},
/**
* Returns the current recordings formatted by series.
*
* @param {Object} [opts] - The retrieval options.
* @returns {Promise} - Promise resolving with the current recordings.
*/
getCurrentSeriesRecordings: function (opts) {
var self = this,
now = application.getDate();
return this._getEpisodes(opts)
.then(function () {
var result = self._slots['episodes'].series,
formatted = [];
Utils.each(result, function (item) {
if (item.getAllItems().length) {
if (item.getAllItems()[0].getSeriesId()) {
formatted.push(item);
} else {
formatted = formatted.concat(item.getAllItems());
}
}
});
formatted = Utils.filter(formatted, function (a) {
if (Utils.isFunction(a.getAllItems)) {
a.setFormattedItems(Utils.filter(a.getAllItems(), function (b) {
return b.getStartTime() * 1000 < now.getTime();
}));
return a.getItemCount() > 0;
}
return a.getStartTime() * 1000 < now.getTime();
});
formatted.sort(function (a, b) {
var itemA,
itemB;
if (Utils.isFunction(a.getItems)) {
itemA = a.getItems()[0];
} else {
itemA = a;
}
if (Utils.isFunction(b.getItems)) {
itemB = b.getItems()[0];
} else {
itemB = b;
}
return itemA.getStartTime() > itemB.getStartTime() ? -1 : 1;
});
return formatted;
});
},
/**
* Returns the future recordings formatted by series.
*
* @param {Object} [opts] - The retrieval options.
* @returns {Promise} - Promise resolving with the future recordings.
*/
getPlannedSeriesRecordings: function (opts) {
var self = this,
now = application.getDate();
return this._getEpisodes(opts)
.then(function () {
var result = self._slots['episodes'].series,
formatted = [];
Utils.each(result, function (item) {
if (item.getAllItems().length) {
if (item.getAllItems()[0].getSeriesId()) {
formatted.push(item);
} else {
formatted = formatted.concat(item.getAllItems());
}
}
});
formatted = Utils.filter(formatted, function (a) {
if (Utils.isFunction(a.getAllItems)) {
a.setFormattedItems(Utils.filter(a.getAllItems(), function (b) {
return b.getStartTime() * 1000 > now.getTime();
}));
return a.getItemCount() > 0;
}
return a.getStartTime() * 1000 > now.getTime();
});
formatted.sort(function (a, b) {
var itemA,
itemB;
if (Utils.isFunction(a.getItems)) {
itemA = a.getItems()[a.getItems().length - 1];
} else {
itemA = a;
}
if (Utils.isFunction(b.getItems)) {
itemB = b.getItems()[b.getItems().length - 1];
} else {
itemB = b;
}
return itemA.getStartTime() > itemB.getStartTime() ? 1 : -1;
});
return formatted;
});
},
/**
* Adds a recording.
*
* @param {number} id - The episode id.
* @returns {Promise} - Promise resolving with an added recording.
*/
addEpisodeRecording: function (id) {
var self = this,
item,
slot;
return api.create('recordings/recording', {
params: {
type: 'episode'
},
data: {
externalContentId: id,
isAutoDeletionEnabled: true
},
withCredentials: true
})
.then(function (result) {
slot = self._slots['episodes'];
slot.ids = slot.ids.concat(result.ids);
item = result.items[result.ids[0]];
slot.items[result.ids[0]] = item;
if (isNaN(item.getSeriesId())) {
slot.series['NaN']._items.push(item);
} else if (!slot.series[item.getSeriesId()]) {
slot.series[item.getSeriesId()] = result.series[item.getSeriesId()];
} else {
slot.series[item.getSeriesId()]._items.push(item);
}
application.broadcastEvent(new RecordEvent('episode', id));
});
},
/**
* Adds a recording.
*
* @param {number|string} id - The series id.
* @param {number|string} channelId - The channel id.
* @returns {Promise} - Promise resolving with an added recording.
*/
addSeriesRecording: function (id, channelId) {
var self = this,
seriesItems;
return api.create('recordings/recording', {
params: {
type: 'series'
},
data: {
channelId: channelId,
seriesId: parseInt(id),
isAutoDeletionEnabled: true,
episodeScope: 'ALL',
isChannelBoundEnabled: true
},
withCredentials: true
})
.then(function (result) {
seriesItems = self._slots['series'].items;
self._slots['series'] = Utils.extend(self._slots['series'], result, true);
debugger;
// Add the result items.
if (seriesItems) {
Utils.each(result.items, function (item) {
seriesItems.push(item);
});
}
application.broadcastEvent(new RecordEvent('series', id));
});
},
/**
* Deletes an item recording.
*
* @param {Object} item - The item to remove from recordings.
* @returns {Promise} - Promise resolving after deletion.
*/
deleteEpisodeRecording: function (item) {
var self = this,
recordingItem,
id;
if (item.getRecordingId && item.getRecordingId()) {
id = item.getRecordingId();
recordingItem = item;
} else {
recordingItem = this._slots['episodes'].items[parseInt(item.getId())];
id = recordingItem.getRecordingId();
}
return api.destroy('recordings/recording', {
params: {
type: 'episode'
},
data: [{
recordId: parseInt(id),
startDeltaTime: recordingItem.getStartDeltaTime() || 0
}],
withCredentials: true
})
.then(function () {
self._removeEpisodeFromStorage(item);
application.broadcastEvent(new RecordEvent('episode', item.getId(), true));
});
},
/**
* Deletes a series recording.
*
* @param {string} id - The series id.
* @returns {Promise} - Promise resolving with the series id.
*/
deleteSeriesRecording: function (id) {
var self = this,
series = this._slots['series'].items,
seriesItem,
i,
j;
for (i = 0, j = series.length; i < j; i++) {
if (series[i].metadata.seriesId === id || series[i].metadata.liveSeriesId === id) {
seriesItem = series[i];
}
}
debugger;
return api.destroy('recordings/recording', {
params: {
type: 'series'
},
data: {
seriesIds: [parseInt(seriesItem.metadata.seriesId)],
isKeepRecordingsEnabled: true
},
withCredentials: true
})
.then(function (response) {
var deleteRecord = response.resultObj.deletedSeriesRecordings[0];
self._slots['series'].items.splice(series.indexOf(seriesItem), 1);
self._removeItemsFromSeriesRecording(
deleteRecord.recordIds,
deleteRecord.seriesId
);
application.broadcastEvent(new RecordEvent('series', id, true));
});
},
/**
* Retrieves the episodes.
*
* @param {Object} [options] - The retrieval options.
* @returns {Promise} - Promise resolving with the recorded episodes.
* @private
*/
_getEpisodes: function (options) {
options = options || {};
if (!this._slots['episodes'] || options.forceReload) {
return api.read('recordings/episodes', {
withCredentials: true
})
.then(Utils.bind(function (result) {
this._slots['episodes'] = result;
return result.items;
}, this))
['catch'](Utils.bind(function () {
this._slots['episodes'] = {
items: []
};
return [];
}, this));
}
return Promise.resolve(this._slots['episodes'].items);
},
/**
* Returns the recorded series.
*
* @param {Object} [options] - The retrieval options.
* @returns {Promise} - Promise resolving with the recorded series.
* @private
*/
_getSeries: function (options) {
options = options || {};
if (!this._slots['series'] || options.forceReload) {
return api.read('recordings/series', {
withCredentials: true
})
.then(Utils.bind(function (result) {
this._slots['series'] = result;
debugger;
return result.items;
}, this))
['catch'](Utils.bind(function () {
this._slots['series'] = {
items: []
};
return [];
}, this));
}
return Promise.resolve(this._slots['series'].items);
},
/**
* Returns true if there is a recording for the given item.
*
* @param {number|string} id - The episodes id.
* @returns {boolean} - True if the episode is being recorded.
*/
hasEpisodeRecording: function (id) {
var episodes = Utils.getNested(this._slots, 'episodes', 'ids');
if (!episodes) {
return false;
}
return episodes.indexOf(parseInt(id)) >= 0;
},
/**
* Returns true if there is a recording for the given item.
*
* @param {number|string} id - The series id.
* @returns {boolean} - True if the series has a recording.
*/
hasSeriesRecording: function (id) {
var series,
i,
j;
if (!id) {
return false;
}
series = Utils.getNested(this._slots, 'series', 'items');
id = parseInt(id);
if (!series || !series.length) {
return false;
}
for (i = 0, j = series.length; i < j; i++) {
if (series[i].metadata.seriesId === id || series[i].metadata.liveSeriesId === id) {
return true;
}
}
return false;
},
/**
* Returns true if there is a recording for the given item.
*
* @param {number|string} id - The episodes id.
* @param {number|String} seriesId - The series id.
* @returns {Promise} - Promise resolving with recording status.
*/
hasRecording: function (id, seriesId) {
var hasEpisode = this.hasEpisodeRecording(id),
hasSeries = this.hasSeriesRecording(seriesId);
return {
episode: hasEpisode,
series: hasSeries
};
},
/**
* Removes the item from episode storage.
*
* @param {Object} item - The item.
* @private
*/
_removeEpisodeFromStorage: function (item) {
var index = this._slots['episodes'].ids.indexOf(parseInt(item.getId()));
if (index >= 0) {
this._slots['episodes'].ids.splice(index, 1);
}
this._removeItemFromSeries(item);
delete this._slots['episodes'].items[item.getId()];
},
/**
* Removes the item from the series storage.
*
* @param {Object} item - The item to be removed.
* @private
*/
_removeItemFromSeries: function (item) {
var series = this._slots['episodes'].series,
seriesItem = series[item.getSeriesId()];
if (!seriesItem) {
seriesItem = series.NaN; // Yuck.
}
item = this._slots['episodes'].items[parseInt(item.getId())];
if (seriesItem && seriesItem.getItems) {
seriesItem._items.splice(seriesItem._items.indexOf(item), 1);
} else {
seriesItem.splice(seriesItem.indexOf(item), 1);
}
},
/**
* Removes the items from series recordings.
*
* @param {Array} ids - The item recordings to remove.
* @param {number} seriesId - The series id the recordings belong to.
* @private
*/
_removeItemsFromSeriesRecording: function (ids, seriesId) {
var seriesItem = this._slots['episodes'].series[seriesId],
self = this;
if (!seriesItem) {
return;
}
// Collect all the indexes of the items to be removed.
Utils.each(seriesItem.getItems(), function (item) {
if (ids.indexOf(item.getRecordingId()) >= 0) {
self._removeEpisodeFromStorage(item);
application.broadcastEvent(new RecordEvent('episode', item.getId(), true));
}
});
},
/**
* Resets the recording manager.
*/
reset: function () {
this._slots = {};
}
});
return {
/**
* Returns the instance.
*
* @returns {RecordingManager} - The recording manager.
*/
getInstance: function () {
if (!instance) {
instance = new RecordingManager();
}
return instance;
}
};
});