diff --git a/core/file_base_filter.js b/core/file_base_filter.js index cd724c52..787a40ba 100644 --- a/core/file_base_filter.js +++ b/core/file_base_filter.js @@ -1,8 +1,9 @@ /* jslint node: true */ 'use strict'; -const _ = require('lodash'); -const uuidV4 = require('uuid/v4'); +// deps +const _ = require('lodash'); +const uuidV4 = require('uuid/v4'); module.exports = class FileBaseFilters { constructor(client) { @@ -122,22 +123,27 @@ module.exports = class FileBaseFilters { system : true, } }; - /* - filters[U_LATEST] = { - name : 'Latest Additions', - areaTag : '', // all - terms : '', // * - tags : '', // * - order : 'descending', - sort : 'upload_timestamp', - uuid : U_LATEST, - system : true, - }; -*/ + return filters; } static getActiveFilter(client) { return new FileBaseFilters(client).get(client.user.properties.file_base_filter_active_uuid); } + + static getFileBaseLastViewedFileIdByUser(user) { + return user.properties.user_file_base_last_viewed || 0; + } + + static setFileBaseLastViewedFileIdForUser(user, fileId, cb) { + const current = FileBaseFilters.getFileBaseLastViewedFileIdByUser(user); + if(fileId < current) { + if(cb) { + cb(null); + } + return; + } + + return user.persistProperty('user_file_base_last_viewed', fileId, cb); + } }; diff --git a/core/file_entry.js b/core/file_entry.js index 06fb6fe1..8cf917c9 100644 --- a/core/file_entry.js +++ b/core/file_entry.js @@ -510,6 +510,14 @@ module.exports = class FileEntry { ); } + if(_.isString(filter.newerThanTimestamp) && filter.newerThanTimestamp.length > 0) { + appendWhereClause(`DATETIME(f.upload_timestamp) > DATETIME("${filter.newerThanTimestamp}", "+1 seconds")`); + } + + if(_.isNumber(filter.newerThanFileId)) { + appendWhereClause(`file_id > ${filter.newerThanFileId}`); + } + sql += `${sqlWhere} ${sqlOrderBy};`; const matchingFileIds = []; diff --git a/core/new_scan.js b/core/new_scan.js index 0483e8d1..3c3f1371 100644 --- a/core/new_scan.js +++ b/core/new_scan.js @@ -6,6 +6,9 @@ const msgArea = require('./message_area.js'); const MenuModule = require('./menu_module.js').MenuModule; const ViewController = require('./view_controller.js').ViewController; const stringFormat = require('./string_format.js'); +const FileEntry = require('./file_entry.js'); +const FileBaseFilters = require('./file_base_filter.js'); +const Errors = require('./enig_error.js').Errors; // deps const _ = require('lodash'); @@ -30,13 +33,21 @@ const MciCodeIds = { ScanStatusList : 2, // VM2 (appends) }; +const Steps = { + MessageConfs : 'messageConferences', + FileBase : 'fileBase', + + Finished : 'finished', +}; + exports.getModule = class NewScanModule extends MenuModule { constructor(options) { super(options); - this.newScanFullExit = _.has(options, 'lastMenuResult.fullExit') ? options.lastMenuResult.fullExit : false; - this.currentStep = 'messageConferences'; + this.newScanFullExit = _.get(options, 'lastMenuResult.fullExit', false); + + this.currentStep = Steps.MessageConfs; this.currentScanAux = {}; // :TODO: Make this conf/area specific: @@ -49,13 +60,6 @@ exports.getModule = class NewScanModule extends MenuModule { updateScanStatus(statusText) { this.setViewText('allViews', MciCodeIds.ScanStatusLabel, statusText); - - /* - view = vc.getView(MciCodeIds.ScanStatusList); - // :TODO: MenuView needs appendItem() - if(view) { - } - */ } newScanMessageConference(cb) { @@ -87,32 +91,19 @@ exports.getModule = class NewScanModule extends MenuModule { this.currentScanAux.area = this.currentScanAux.area || 0; } - const currentConf = this.sortedMessageConfs[this.currentScanAux.conf]; - const self = this; - - async.series( - [ - function scanArea(callback) { - //self.currentScanAux.area = self.currentScanAux.area || 0; - - self.newScanMessageArea(currentConf, () => { - if(self.sortedMessageConfs.length > self.currentScanAux.conf + 1) { - self.currentScanAux.conf += 1; - self.currentScanAux.area = 0; - - self.newScanMessageConference(cb); // recursive to next conf - //callback(null); - } else { - self.updateScanStatus(self.scanCompleteMsg); - callback(new Error('No more conferences')); - } - }); - } - ], - err => { - return cb(err); + const currentConf = this.sortedMessageConfs[this.currentScanAux.conf]; + + this.newScanMessageArea(currentConf, () => { + if(this.sortedMessageConfs.length > this.currentScanAux.conf + 1) { + this.currentScanAux.conf += 1; + this.currentScanAux.area = 0; + + return this.newScanMessageConference(cb); // recursive to next conf } - ); + + this.updateScanStatus(this.scanCompleteMsg); + return cb(Errors.DoesNotExist('No more conferences')); + }); } newScanMessageArea(conf, cb) { @@ -134,7 +125,7 @@ exports.getModule = class NewScanModule extends MenuModule { return callback(null); } else { self.updateScanStatus(self.scanCompleteMsg); - return callback(new Error('No more areas')); // this will stop our scan + return callback(Errors.DoesNotExist('No more areas')); // this will stop our scan } }, function updateStatusScanStarted(callback) { @@ -173,6 +164,28 @@ exports.getModule = class NewScanModule extends MenuModule { ); } + newScanFileBase(cb) { + // :TODO: add in steps + FileEntry.findFiles( + { newerThanFileId : FileBaseFilters.getFileBaseLastViewedFileIdByUser(this.client.user) }, + (err, fileIds) => { + if(err || 0 === fileIds.length) { + return cb(err ? err : Errors.DoesNotExist('No more new files')); + } + + FileBaseFilters.setFileBaseLastViewedFileIdForUser( this.client.user, fileIds[0] ); + + const menuOpts = { + extraArgs : { + fileList : fileIds, + }, + }; + + return this.gotoMenu(this.menuConfig.config.newScanFileBaseList || 'newScanFileBaseList', menuOpts); + } + ); + } + getSaveState() { return { currentStep : this.currentStep, @@ -185,6 +198,26 @@ exports.getModule = class NewScanModule extends MenuModule { this.currentScanAux = savedState.currentScanAux; } + performScanCurrentStep(cb) { + switch(this.currentStep) { + case Steps.MessageConfs : + this.newScanMessageConference( () => { + this.currentStep = Steps.FileBase; + return this.performScanCurrentStep(cb); + }); + break; + + case Steps.FileBase : + this.newScanFileBase( () => { + this.currentStep = Steps.Finished; + return this.performScanCurrentStep(cb); + }); + break; + + default : return cb(null); + } + } + mciReady(mciData, cb) { if(this.newScanFullExit) { // user has canceled the entire scan @ message list view @@ -213,15 +246,7 @@ exports.getModule = class NewScanModule extends MenuModule { vc.loadFromMenuConfig(loadOpts, callback); }, function performCurrentStepScan(callback) { - switch(self.currentStep) { - case 'messageConferences' : - self.newScanMessageConference( () => { - callback(null); // finished - }); - break; - - default : return callback(null); - } + return self.performScanCurrentStep(callback); } ], err => { diff --git a/core/servers/login/telnet.js b/core/servers/login/telnet.js index 5c471473..39fa474d 100644 --- a/core/servers/login/telnet.js +++ b/core/servers/login/telnet.js @@ -184,6 +184,10 @@ const OPTION_NAMES = Object.keys(OPTIONS).reduce(function(names, name) { return names; }, {}); +function unknownOption(bufs, i, event) { + Log.warn( { bufs : bufs, i : i, event : event }, 'Unknown Telnet option'); +} + const OPTION_IMPLS = {}; // :TODO: fill in the rest... OPTION_IMPLS.NO_ARGS = @@ -421,7 +425,9 @@ function parseOption(bufs, i, event) { const option = bufs.get(i); // :TODO: fix deprecation... [i] is not the same event.optionCode = option; event.option = OPTION_NAMES[option]; - return OPTION_IMPLS[option](bufs, i + 1, event); + + const handler = OPTION_IMPLS[option]; + return handler ? handler(bufs, i + 1, event) : unknownOption(bufs, i + 1, event); } diff --git a/core/string_util.js b/core/string_util.js index 250f6502..f7224a66 100644 --- a/core/string_util.js +++ b/core/string_util.js @@ -507,6 +507,8 @@ function createCleanAnsi(input, options, cb) { parser.parse(input); } + +// create2dArray = (rows, columns) => [...Array(rows).keys()].map(i => Array(columns).fill({})) /* const fs = require('graceful-fs'); diff --git a/mods/file_area_list.js b/mods/file_area_list.js index 81c041bf..fbe11d52 100644 --- a/mods/file_area_list.js +++ b/mods/file_area_list.js @@ -76,6 +76,7 @@ exports.getModule = class FileAreaList extends MenuModule { if(options.extraArgs) { this.filterCriteria = options.extraArgs.filterCriteria; + this.fileList = options.fileList; } this.dlQueue = new DownloadQueue(this.client); diff --git a/package.json b/package.json index 252b6763..ec508841 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "ptyw.js": "NuSkooler/ptyw.js", "sanitize-filename": "^1.6.1", "sqlite3": "^3.1.1", - "ssh2": "^0.5.1", + "ssh2": "^0.5.5", "temptmp": "^1.0.0", "uuid": "^3.0.1", "uuid-parse": "^1.0.0",