Source: managers/epg.js

  1. define('application/managers/epg', [
  2. 'product-layer/epg/manager',
  3. 'application/managers/api',
  4. 'rofl/lib/utils',
  5. 'rofl/lib/promise',
  6. 'antie/runtimecontext'
  7. ], function (
  8. AbstractEpgManager,
  9. ApiManager,
  10. Utils,
  11. Promise,
  12. RuntimeContext
  13. ) {
  14. 'use strict';
  15. var api,
  16. DATA_CHUNK_TIME_SPAN = 24 * 60 * 60,
  17. instance,
  18. app,
  19. EpgManager;
  20. EpgManager = AbstractEpgManager.extend({
  21. /**
  22. * Initialises the EPG manager.
  23. */
  24. init: function init () {
  25. init.base.call(this);
  26. api = ApiManager.getKPNAPI();
  27. app = RuntimeContext.getCurrentApplication();
  28. this.setDataChunkTimeSpan(24 * 60 * 60);
  29. },
  30. /**
  31. * Loads the data for the given channel ids and time.
  32. *
  33. * @param {Array} channelIds - The channel ids.
  34. * @param {number} time - The time in seconds.
  35. * @returns {Promise} - Promise resolving with epg data.
  36. */
  37. load: function (channelIds, time) {
  38. return api.read('epg', {
  39. params: {
  40. channels: channelIds,
  41. startTime: time * 1000,
  42. endTime: (time + this.getDataChunkTimeSpan()) * 1000
  43. }
  44. });
  45. },
  46. /**
  47. * Initiator of the EPG data loading.
  48. *
  49. * @param {Array} channelIds - Channel ID's to fetch.
  50. * @param {number} time - Regulated time for fetching the correct time slot.
  51. * @returns {Promise} The load promise.
  52. */
  53. loadData: function (channelIds, time) {
  54. var timeSlot = this._regulateTimeSlot(time),
  55. self = this,
  56. slot = {};
  57. return this.load(channelIds, timeSlot).then(function (epgData) {
  58. if (epgData) {
  59. slot.timeSlot = timeSlot;
  60. slot.previousSlot = timeSlot - DATA_CHUNK_TIME_SPAN;
  61. slot.nextSlot = timeSlot + DATA_CHUNK_TIME_SPAN;
  62. slot.compared = false;
  63. // Make sure the time slot exists
  64. if (!self._slots[timeSlot]) {
  65. self._slots[timeSlot] = {};
  66. }
  67. if (Utils.keys(epgData).length) {
  68. Utils.extend(self._slots[timeSlot], epgData);
  69. }
  70. return Promise.resolve(epgData);
  71. }
  72. return Promise.resolve();
  73. });
  74. },
  75. /**
  76. * Get the current and prev EPG item for a channel ID.
  77. *
  78. * @param {String|Number|Array} channelIds - Channel ID's to load the data for.
  79. * @returns {Promise} EPG data promise.
  80. */
  81. getNowPrev: function (channelIds) {
  82. var self = this,
  83. currentTime = Math.round((app.getDate()).getTime() / 1000),
  84. channels;
  85. if (Utils.isArray(channelIds)) {
  86. channels = channelIds;
  87. } else if (Utils.isString(channelIds) || Utils.isNumber(channelIds)) {
  88. channels = [channelIds];
  89. }
  90. return this.getItem(channels, currentTime).then(function (items) {
  91. var fillMissingPrevs = Utils.bind(self._fillMissingPrevs, self),
  92. fillMissingPrevsInCurrentTime = Utils.bind(self._fillMissingPrevsInCurrentTime, self),
  93. prevTime = currentTime - DATA_CHUNK_TIME_SPAN,
  94. prevTimeSlot = prevTime - (prevTime % DATA_CHUNK_TIME_SPAN),
  95. currentTimeSlot = currentTime - (currentTime % DATA_CHUNK_TIME_SPAN);
  96. if (currentTime > currentTimeSlot) {
  97. return fillMissingPrevsInCurrentTime(currentTimeSlot, items).then(function (filledItems) {
  98. var epgItems = {};
  99. Utils.each(filledItems, function (value, key) {
  100. epgItems[key] = {
  101. now: value.item,
  102. prev: value.prev
  103. };
  104. });
  105. return fillMissingPrevs(prevTimeSlot, items)
  106. .then(function (prevItems) {
  107. Utils.each(prevItems, function (value, key) {
  108. epgItems[key] = {
  109. now: value.item,
  110. prev: value.prev
  111. };
  112. });
  113. return Promise.resolve(epgItems);
  114. });
  115. });
  116. }
  117. return fillMissingPrevs(prevTimeSlot, items).then(function (filledItems) {
  118. var epgItems = {};
  119. Utils.each(filledItems, function (value, key) {
  120. epgItems[key] = {
  121. now: value.item,
  122. prev: value.prev
  123. };
  124. });
  125. return Promise.resolve(epgItems);
  126. });
  127. });
  128. },
  129. /**
  130. * Tries to fill in the blanks, retrieved from the prev time span.
  131. *
  132. * @param {number} time - The time to check for.
  133. * @param {Object} items - The original item to check against.
  134. * @returns {Promise} Load promise.
  135. */
  136. _fillMissingPrevs: function (time, items) {
  137. var missingPrevs = [],
  138. self = this;
  139. Utils.each(items, function (value, key) {
  140. if (!value.prev) {
  141. missingPrevs.push(key);
  142. }
  143. });
  144. return this._loadMissingData(missingPrevs, time).then(function () {
  145. var i = 0,
  146. max = missingPrevs.length,
  147. channelId,
  148. channelSlot,
  149. item,
  150. j,
  151. itemAmount;
  152. for (; i < max; i++) {
  153. channelId = missingPrevs[i];
  154. channelSlot = self._getChannelSlot(channelId, time);
  155. for (j = 0, itemAmount = channelSlot.length; j < itemAmount; j++) {
  156. item = channelSlot[itemAmount - 1];
  157. items[channelId].prev = item || null;
  158. }
  159. }
  160. return Promise.resolve(items);
  161. });
  162. },
  163. /**
  164. * Tries to fill in the blanks, retrieved from the prev time span.
  165. *
  166. * @param {number} time - The time to check for.
  167. * @param {Object} items - The original item to check against.
  168. * @returns {Promise} Load promise.
  169. */
  170. _fillMissingPrevsInCurrentTime: function (time, items) {
  171. var missingPrevs = [],
  172. self = this;
  173. Utils.each(items, function (value, key) {
  174. if (!value.prev) {
  175. missingPrevs.push(key);
  176. }
  177. });
  178. return this._loadMissingData(missingPrevs, time).then(function () {
  179. var i = 0,
  180. max = missingPrevs.length,
  181. channelId,
  182. channelSlot,
  183. currentItem,
  184. item,
  185. j,
  186. itemAmount;
  187. for (; i < max; i++) {
  188. channelId = missingPrevs[i];
  189. channelSlot = self._getChannelSlot(channelId, time);
  190. currentItem = items[channelId].item;
  191. for (j = 0, itemAmount = channelSlot.length; j < itemAmount; j++) {
  192. if (channelSlot[j] === currentItem) {
  193. item = channelSlot[j - 1];
  194. items[channelId].prev = item || null;
  195. }
  196. }
  197. }
  198. return Promise.resolve(items);
  199. });
  200. }
  201. });
  202. return {
  203. /**
  204. * Returns an instance of the epg manager.
  205. *
  206. * @returns {Object} - The epg manager instance.
  207. */
  208. getInstance: function () {
  209. if (!instance) {
  210. instance = new EpgManager();
  211. }
  212. return instance;
  213. }
  214. };
  215. });