From bc25f1babb8ea107909e369ba2038bf2a81dd5f7 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 26 Mar 2018 21:01:23 +0300 Subject: [PATCH] feature(cloudcmd) spero, ishtar, salam, remedy, omnes -> fileop --- client/modules/operation/index.js | 268 ++++++---------------- client/modules/operation/set-listeners.js | 65 ++++++ package.json | 6 +- server/cloudcmd.js | 73 ++---- test/server/cloudcmd.js | 58 ++++- 5 files changed, 213 insertions(+), 257 deletions(-) create mode 100644 client/modules/operation/set-listeners.js diff --git a/client/modules/operation/index.js b/client/modules/operation/index.js index 0c14606d..371882fd 100644 --- a/client/modules/operation/index.js +++ b/client/modules/operation/index.js @@ -1,11 +1,7 @@ /* global CloudCmd */ /* global Util */ /* global DOM */ -/* global spero */ -/* global remedy */ -/* global ishtar */ -/* global salam */ -/* global omnes */ +/* global fileop */ 'use strict'; @@ -14,17 +10,22 @@ CloudCmd.Operation = OperationProto; const currify = require('currify/legacy'); const wraptile = require('wraptile/legacy'); const exec = require('execon'); -const forEachKey = require('../../../common/for-each-key'); const RESTful = require('../../dom/rest'); const removeExtension = require('./remove-extension'); +const setListeners = require('./set-listeners'); + +const removeQuery = (a) => a.replace(/\?.*/, ''); function OperationProto(operation, data) { const Name = 'Operation'; - const TITLE = CloudCmd.TITLE; - const {config} = CloudCmd; + const { + TITLE, + config, + } = CloudCmd; const {Dialog, Images} = DOM; - const create = wraptile(_create); + const initOperations = wraptile(_initOperations); + const authCheck = wraptile(_authCheck); let Loaded; @@ -62,7 +63,7 @@ function OperationProto(operation, data) { if (!config('progress')) return callback(); - load(create(CloudCmd.PREFIX, callback)); + load(initOperations(CloudCmd.PREFIX, callback)); }, () => { Loaded = true; @@ -72,95 +73,62 @@ function OperationProto(operation, data) { ]); } - function authCheck(spawn, ok) { + function _authCheck(spawn, ok) { + const accept = wraptile(ok); + const alertDialog = wraptile(Dialog.alert); + if (!config('auth')) - return ok(); - - spawn.on('accept', ok); - spawn.on('reject', () => { - Dialog.alert(TITLE, 'Wrong credentials!'); - }); + return ok(spawn); + spawn.on('accept', accept(spawn)); + spawn.on('reject', alertDialog (TITLE, 'Wrong credentials!')); spawn.emit('auth', config('username'), config('password')); } - function _initSpero(prefix, fn) { - spero(prefix + '/spero', prefix, (copier) => { + function _initOperations(socketPrefix, fn) { + const prefix = `${socketPrefix}/fileop`; + fileop({prefix, socketPrefix}, (e, operator) => { fn(); - copier.on('connect', () => { - authCheck(copier, () => { - copyFn = (data, callback) => { - setListeners(copier, callback); - copier.copy(data.from, data.to, data.names); - }; - }); - }); - - copier.on('disconnect', () => { - copyFn = RESTful.cp; - }); + operator.on('connect', authCheck(operator, onConnect)); + operator.on('disconnect', onDisconnect); }); } - function _initRemedy(prefix, fn) { - remedy(prefix + '/remedy', prefix, (remover) => { - fn(); - remover.on('connect', () => { - authCheck(remover, () => { - deleteFn = (from, files, callback) => { - setListeners(remover, callback); - from = from.replace(/\?.*/, ''); - remover.remove(from, files); - }; - }); - }); - - remover.on('disconnect', () => { - deleteFn = RESTful.delete; - }); - }); + function onConnect(operator) { + packTarFn = (data, callback) => { + operator.tar(data.from, data.to, data.names) + .then(setListeners({noContinue: true}, callback)); + }; + + packZipFn = (data, callback) => { + operator.zip(data.from, data.to, data.names) + .then(setListeners({noContinue: true}, callback)); + }; + + deleteFn = (from, files, callback) => { + from = removeQuery(from); + operator.remove(from, files) + .then(setListeners(callback)); + }; + + copyFn = (data, callback) => { + operator.copy(data.from, data.to, data.names) + .then(setListeners(callback)); + }; + + extractFn = (data, callback) => { + operator.extract(data.from, data.to) + .then(setListeners({noContinue: true}, callback)); + }; } - function _setTarPacker(prefix, name, pack, fn) { - pack(prefix + '/' + name, prefix, (packer) => { - fn(); - packer.on('connect', () => { - authCheck(packer, () => { - packTarFn = (data, callback) => { - setListeners(packer, {noContinue: true}, callback); - packer.pack(data.from, data.to, data.names); - }; - }); - }); - - packer.on('disconnect', () => { - packTarFn = RESTful.pack; - }); - }); - } - - function _setZipPacker(prefix, name, pack, fn) { - pack(prefix + '/' + name, prefix, (packer) => { - fn(); - packer.on('connect', () => { - authCheck(packer, () => { - packZipFn = (data, callback) => { - setListeners(packer, {noContinue: true}, callback); - packer.pack(data.from, data.to, data.names); - }; - }); - }); - - packer.on('disconnect', () => { - packZipFn = RESTful.pack; - }); - }); - } - - function _initPacker(prefix, fn) { - _setZipPacker(prefix, 'salam', salam, fn); - _setTarPacker(prefix, 'ishtar', ishtar, fn); + function onDisconnect() { + packZipFn = RESTful.pack; + packTarFn = RESTful.pack; + deleteFn = RESTful.delete; + copyFn = RESTful.cp; + extractFn = RESTful.extract; } function getPacker(type) { @@ -170,88 +138,6 @@ function OperationProto(operation, data) { return packTarFn; } - function _initExtractor(prefix, fn) { - omnes(prefix + '/omnes', prefix, (packer) => { - fn(); - packer.on('connect', () => { - authCheck(packer, () => { - extractFn = (data, callback) => { - setListeners(packer, {noContinue: true}, callback); - packer.extract(data.from, data.to); - }; - }); - }); - - packer.on('disconnect', () => { - extractFn = RESTful.extract; - }); - }); - } - - function _create(prefix, callback) { - const initSpero = currify(_initSpero); - const initRemedy = currify(_initRemedy); - const initPacker = currify(_initPacker); - const initExtractor = currify(_initExtractor); - - exec.parallel([ - initSpero(prefix), - initRemedy(prefix), - initPacker(prefix), - initExtractor(prefix) - ], callback); - } - - function setListeners(emitter, options, callback) { - if (!callback) { - callback = options; - options = {}; - } - - let done; - let lastError; - - const removeListener = emitter.removeListener.bind(emitter); - const on = emitter.on.bind(emitter); - - const listeners = { - progress: (value) => { - done = value === 100; - Images.setProgress(value); - }, - - end: () => { - Images - .hide() - .clearProgress(); - - forEachKey(removeListener, listeners); - - if (lastError || done) - callback(lastError); - }, - - error: (error) => { - lastError = error; - - if (options.noContinue) { - listeners.end(error); - Dialog.alert(TITLE, error); - return; - } - - Dialog.confirm(TITLE, error + '\n Continue?') - .then(() => { - emitter.continue(); - }, () => { - emitter.abort(); - }); - } - }; - - forEachKey(on, listeners); - } - this.hide = () => { CloudCmd.View.hide(); }; @@ -260,31 +146,23 @@ function OperationProto(operation, data) { if (!Loaded) return; - switch(operation) { - case 'copy': - Operation.copy(data); - break; + if (operation === 'copy') + return Operation.copy(data); - case 'move': - Operation.move(data); - break; + if (operation === 'move') + return Operation.move(data); - case 'delete': - Operation.delete(); - break; + if (operation === 'delete') + return Operation.delete(); - case 'delete:silent': - Operation.deleteSilent(); - break; + if (operation === 'delete:silent') + return Operation.deleteSilent(); - case 'pack': - Operation.pack(); - break; + if (operation === 'pack') + return Operation.pack(); - case 'extract': - Operation.extract(); - break; - } + if (operation === 'extract') + return Operation.extract(); }; this.copy = processFiles({ @@ -566,17 +444,9 @@ function OperationProto(operation, data) { function load(callback) { const prefix = CloudCmd.PREFIX; - const files = [ - '/spero/spero.js', - '/remedy/remedy.js', - '/ishtar/ishtar.js', - '/salam/salam.js', - '/omnes/omnes.js' - ].map((name) => { - return prefix + name; - }); + const file = `${prefix}/fileop/fileop.js`; - DOM.load.parallel(files, (error) => { + DOM.load.js(file, (error) => { if (error) { Dialog.alert(TITLE, error.message); return exec(callback); diff --git a/client/modules/operation/set-listeners.js b/client/modules/operation/set-listeners.js new file mode 100644 index 00000000..f05da81a --- /dev/null +++ b/client/modules/operation/set-listeners.js @@ -0,0 +1,65 @@ +'use strict'; + +/* global DOM */ +/* global CloudCmd */ + +const { + Images, + Dialog, +} = DOM; + +const forEachKey = require('../../../common/for-each-key'); +const { + TITLE, +} = CloudCmd; + +module.exports = (options, callback) => (emitter) => { + if (!callback) { + callback = options; + options = {}; + } + + let done; + let lastError; + + const removeListener = emitter.removeListener.bind(emitter); + const on = emitter.on.bind(emitter); + + const listeners = { + progress: (value) => { + done = value === 100; + Images.setProgress(value); + }, + + end: () => { + Images + .hide() + .clearProgress(); + + forEachKey(removeListener, listeners); + + if (lastError || done) + callback(lastError); + }, + + error: (error) => { + lastError = error; + + if (options.noContinue) { + listeners.end(error); + Dialog.alert(TITLE, error); + return; + } + + Dialog.confirm(TITLE, error + '\n Continue?') + .then(() => { + emitter.continue(); + }, () => { + emitter.abort(); + }); + } + }; + + forEachKey(on, listeners); +}; + diff --git a/package.json b/package.json index fdba4ebf..2ea0056c 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ }, "subdomain": "cloudcmd", "dependencies": { + "@cloudcmd/fileop": "^1.0.1", "@cloudcmd/read-files-sync": "^1.0.0", "apart": "^1.0.1", "chalk": "^2.0.1", @@ -130,7 +131,6 @@ "fullstore": "^1.0.0", "http-auth": "^3.2.3", "inly": "^1.0.2", - "ishtar": "^2.0.0", "jaguar": "^3.0.0", "jju": "^1.3.0", "join-io": "^2.0.0", @@ -139,18 +139,14 @@ "mellow": "^2.0.0", "minimist": "^1.2.0", "nomine": "^1.0.1", - "omnes": "^1.0.3", "onezip": "^1.0.5", "opn": "^5.1.0", "package-json": "^4.0.1", "ponse": "^1.4.0", "pullout": "^1.0.1", - "remedy": "^3.0.0", "rendy": "^1.1.0", "restafary": "^3.0.0", - "salam": "^1.0.0", "socket.io": "^2.0.3", - "spero": "^2.0.0", "squad": "^2.0.0", "table": "^4.0.1", "try-catch": "^2.0.0", diff --git a/server/cloudcmd.js b/server/cloudcmd.js index c9cb2602..df335a77 100644 --- a/server/cloudcmd.js +++ b/server/cloudcmd.js @@ -25,12 +25,9 @@ const edward = require('edward'); const dword = require('dword'); const deepword = require('deepword'); const nomine = require('nomine'); -const spero = require('spero'); -const remedy = require('remedy'); -const ishtar = require('ishtar'); -const salam = require('salam'); -const omnes = require('omnes'); +const fileop = require('@cloudcmd/fileop'); +const authCheckNew = currify(_authCheckNew); const authenticate = currify(_authenticate); const setUrl = currify(_setUrl); @@ -97,6 +94,20 @@ function authCheck(socket, success) { socket.on('auth', authenticate(socket, success)); } +module.exports._authCheckNew = _authCheckNew; +function _authCheckNew(accept, reject, username, password) { + if (!config('auth')) + return accept(); + + const isName = username === config('username'); + const isPass = password === config('password'); + + if (isName && isPass) + return accept(); + + reject(); +} + module.exports._authenticate = _authenticate; function _authenticate(socket, success, name, pass) { const isName = name === config('username'); @@ -132,34 +143,10 @@ function listen(prefix, socket) { prefix: prefix + '/deepword', }); - spero.listen(socket, { + fileop.listen(socket, { root, - authCheck, - prefix: prefix + '/spero', - }); - - remedy.listen(socket, { - root, - authCheck, - prefix: prefix + '/remedy', - }); - - ishtar.listen(socket, { - root, - authCheck, - prefix: prefix + '/ishtar', - }); - - salam.listen(socket, { - root, - authCheck, - prefix: prefix + '/salam', - }); - - omnes.listen(socket, { - root, - authCheck, - prefix: prefix + '/omnes', + authCheck: authCheckNew, + prefix: prefix + '/fileop', }); config('console') && konsole.listen(socket, { @@ -213,26 +200,8 @@ function cloudcmd(prefix, plugins, modules) { zip, }), - spero({ - prefix : prefix + '/spero', - online, - }), - - remedy({ - prefix : prefix + '/remedy', - }), - - ishtar({ - prefix : prefix + '/ishtar', - online, - }), - - salam({ - prefix: prefix + '/salam', - }), - - omnes({ - prefix: prefix + '/omnes', + fileop({ + prefix : prefix + '/fileop', }), nomine({ diff --git a/test/server/cloudcmd.js b/test/server/cloudcmd.js index dfc12c6a..ee27f6eb 100644 --- a/test/server/cloudcmd.js +++ b/test/server/cloudcmd.js @@ -13,6 +13,7 @@ const { _authenticate, _getPrefix, _authCheck, + _authCheckNew, _replacePrefix, _replaceDist, } = cloudcmd; @@ -118,7 +119,62 @@ test('cloudcmd: replaceDist: !isDev', (t) => { t.end(); }); -test('cloudcmd: authCheck: success', (t) => { +test('cloudcmd: authCheckNew: reject', (t) => { + const auth = config('auth'); + const accept = sinon.stub(); + const reject = sinon.stub(); + const username = 'root'; + const password = 'toor'; + + const set = credentials(); + const reset = set('hello', 'world'); + config('auth', true); + + _authCheckNew(accept, reject, username, password); + + config('auth', auth); + reset(); + + t.ok(reject.called, 'should accept'); + t.end(); +}); + +test('cloudcmd: authCheckNew: accept', (t) => { + const auth = config('auth'); + const accept = sinon.stub(); + const reject = sinon.stub(); + const username = 'root'; + const password = 'toor'; + + const set = credentials(); + const reset = set(username, password); + config('auth', true); + + _authCheckNew(accept, reject, username, password); + + config('auth', auth); + reset(); + + t.ok(accept.called, 'should accept'); + t.end(); +}); + +test('cloudcmd: authCheckNew: accept: no auth', (t) => { + const auth = config('auth'); + const accept = sinon.stub(); + const reject = sinon.stub(); + const username = 'root'; + const password = 'toor'; + + config('auth', false); + _authCheckNew(accept, reject, username, password); + config('auth', auth); + + t.ok(accept.called, 'should accept'); + t.end(); +}); + +test('cloudcmd: authCheckNew: reject', (t) => { const auth = config('auth'); const success = sinon.stub(); const on = sinon.stub;