/* jslint node: true */ 'use strict'; // ENiGMA½ const { MenuModule, MenuFlags } = require('./menu_module.js'); const DownloadQueue = require('./download_queue.js'); const ansi = require('./ansi_term.js'); const Errors = require('./enig_error.js').Errors; const FileAreaWeb = require('./file_area_web.js'); const ErrNotEnabled = require('./enig_error.js').ErrorReasons.NotEnabled; const Config = require('./config.js').get; // deps const async = require('async'); const _ = require('lodash'); const moment = require('moment'); exports.moduleInfo = { name: 'File Base Download Web Queue Manager', desc: 'Module for interacting with web backed download queue/batch', author: 'NuSkooler', }; const FormIds = { queueManager: 0, }; const MciViewIds = { queueManager: { queue: 1, navMenu: 2, customRangeStart: 10, }, }; exports.getModule = class FileBaseWebDownloadQueueManager extends MenuModule { constructor(options) { super(options); this.setMergedFlag(MenuFlags.NoHistory); this.dlQueue = new DownloadQueue(this.client); this.menuMethods = { removeItem: (formData, extraArgs, cb) => { const selectedItem = this.dlQueue.items[formData.value.queueItem]; if (!selectedItem) { return cb(null); } this.dlQueue.removeItems(selectedItem.fileId); // :TODO: broken: does not redraw menu properly - needs fixed! return this.removeItemsFromDownloadQueueView( formData.value.queueItem, cb ); }, clearQueue: (formData, extraArgs, cb) => { this.dlQueue.clear(); // :TODO: broken: does not redraw menu properly - needs fixed! return this.removeItemsFromDownloadQueueView('all', cb); }, getBatchLink: (formData, extraArgs, cb) => { return this.generateAndDisplayBatchLink(cb); }, }; } initSequence() { if (0 === this.dlQueue.items.length) { return this.gotoMenu( this.menuConfig.config.emptyQueueMenu || 'fileBaseDownloadManagerEmptyQueue' ); } const self = this; async.series( [ function beforeArt(callback) { return self.beforeArt(callback); }, function display(callback) { return self.displayQueueManagerPage(false, callback); }, ], () => { return self.finishedLoading(); } ); } removeItemsFromDownloadQueueView(itemIndex, cb) { const queueView = this.viewControllers.queueManager.getView( MciViewIds.queueManager.queue ); if (!queueView) { return cb(Errors.DoesNotExist('Queue view does not exist')); } if ('all' === itemIndex) { queueView.setItems([]); queueView.setFocusItems([]); } else { queueView.removeItem(itemIndex); } queueView.redraw(); return cb(null); } displayFileInfoForFileEntry(fileEntry) { this.updateCustomViewTextsWithFilter( 'queueManager', MciViewIds.queueManager.customRangeStart, fileEntry, { filter: ['{webDlLink}', '{webDlExpire}', '{fileName}'] } // :TODO: Others.... ); } updateDownloadQueueView(cb) { const queueView = this.viewControllers.queueManager.getView( MciViewIds.queueManager.queue ); if (!queueView) { return cb(Errors.DoesNotExist('Queue view does not exist')); } queueView.setItems(this.dlQueue.items); queueView.on('index update', idx => { const fileEntry = this.dlQueue.items[idx]; this.displayFileInfoForFileEntry(fileEntry); }); queueView.redraw(); this.displayFileInfoForFileEntry(this.dlQueue.items[0]); return cb(null); } generateAndDisplayBatchLink(cb) { const expireTime = moment().add(Config().fileBase.web.expireMinutes, 'minutes'); FileAreaWeb.createAndServeTempBatchDownload( this.client, this.dlQueue.items, { expireTime: expireTime, }, (err, webBatchDlLink) => { // :TODO: handle not enabled -> display such if (err) { return cb(err); } const webDlExpireTimeFormat = this.menuConfig.config.webDlExpireTimeFormat || 'YYYY-MMM-DD @ h:mm'; const formatObj = { webBatchDlLink: ansi.vtxHyperlink(this.client, webBatchDlLink) + webBatchDlLink, webBatchDlExpire: expireTime.format(webDlExpireTimeFormat), }; this.updateCustomViewTextsWithFilter( 'queueManager', MciViewIds.queueManager.customRangeStart, formatObj, { filter: Object.keys(formatObj).map(k => '{' + k + '}') } ); return cb(null); } ); } displayQueueManagerPage(clearScreen, cb) { const self = this; async.series( [ function prepArtAndViewController(callback) { return self.displayArtAndPrepViewController( 'queueManager', FormIds.queueManager, { clearScreen: clearScreen }, callback ); }, function prepareQueueDownloadLinks(callback) { const webDlExpireTimeFormat = self.menuConfig.config.webDlExpireTimeFormat || 'YYYY-MMM-DD @ h:mm'; const config = Config(); async.each( self.dlQueue.items, (fileEntry, nextFileEntry) => { FileAreaWeb.getExistingTempDownloadServeItem( self.client, fileEntry, (err, serveItem) => { if (err) { if (ErrNotEnabled === err.reasonCode) { return nextFileEntry(err); // we should have caught this prior } const expireTime = moment().add( config.fileBase.web.expireMinutes, 'minutes' ); FileAreaWeb.createAndServeTempDownload( self.client, fileEntry, { expireTime: expireTime }, (err, url) => { if (err) { return nextFileEntry(err); } fileEntry.webDlLinkRaw = url; fileEntry.webDlLink = ansi.vtxHyperlink(self.client, url) + url; fileEntry.webDlExpire = expireTime.format( webDlExpireTimeFormat ); return nextFileEntry(null); } ); } else { fileEntry.webDlLinkRaw = serveItem.url; fileEntry.webDlLink = ansi.vtxHyperlink( self.client, serveItem.url ) + serveItem.url; fileEntry.webDlExpire = moment( serveItem.expireTimestamp ).format(webDlExpireTimeFormat); return nextFileEntry(null); } } ); }, err => { return callback(err); } ); }, function populateViews(callback) { return self.updateDownloadQueueView(callback); }, ], err => { if (cb) { return cb(err); } } ); } };