smartfacecloud-emulator-dispatcher
Version:
Handles Emulator Dispatcher Part of SmartfaceCloud
212 lines (190 loc) • 7.06 kB
JavaScript
const path = require('path');
const fs = require('fs');
const URIParser = require('./URIParser');
const FileTransfer = require('./FileTransfer');
const FilePackager = require('./FilePackager');
const ProjectChecker = require('../common/ProjectChecker');
const MessageFactory = require('../common/MessageFactory');
const LogToConsole = require("../common/LogToConsole");
const errorMessages = require("../common/errorMessages");
const sendResetTimeout = require("../common/sendResetTimeout");
const isEmptyObject = require("../common/isEmptyObject");
const CONSTANTS = require("../constants");
const gc = require("js-gc");
function FileService() {
const DEVICE = 'device';
const MESSAGE = 'message';
const DEBUGGER = 'debugger';
const DISPATCHER = 'dispatcher';
const UI = 'UI';
const CONTROL = 'control';
const IDLE = 1;
const SENDING = 2;
var self = this;
var messageFactory = new MessageFactory();
var bypassSecurityCheck;
var logToConsole;
var log;
this.emit = null;
this.callbackList = {};
this.ws = null;
this.connectedDeviceType = "";
this.basePaths = {
iOS: {},
Android: {}
};
this.init = function(emitFunction, opts) {
opts = opts || {};
logToConsole = opts.logToConsole;
bypassSecurityCheck = opts.bypassSecurityCheck;
log = new LogToConsole(logToConsole, '[FILE]').log;
if (!emitFunction) {
throw new Error("Required parameters are missing!");
}
self.emit = emitFunction;
self.ws = opts.data.ws;
self.getProjectPaths();
log("FileService init");
};
this.replaceWebsocket = function(ws) {
self.ws = ws;
};
this.getProjectPaths = function() {
const workspaceDir = CONSTANTS.WORKSPACE_PATH;
const content = fs.readFileSync(path.join(workspaceDir, 'config', 'project.json'), 'utf8');
try {
var project = JSON.parse(content);
self.basePaths.iOS.scripts = path.join(workspaceDir, project.build.input.ios.scripts);
self.basePaths.iOS.images = path.join(workspaceDir, project.build.input.ios.images);
self.basePaths.iOS.assets = path.join(workspaceDir, project.build.input.ios.assets);
self.basePaths.iOS.fonts = path.join(workspaceDir, "config", "Fonts");
self.basePaths.iOS.config = path.join(workspaceDir, "config");
self.basePaths.Android.scripts = path.join(workspaceDir, project.build.input.android.scripts);
self.basePaths.Android.images = path.join(workspaceDir, project.build.input.android.images);
self.basePaths.Android.assets = path.join(workspaceDir, project.build.input.android.assets);
self.basePaths.Android.fonts = path.join(workspaceDir, "config", "Fonts");
self.basePaths.Android.config = path.join(workspaceDir, "config");
log("Received project paths");
}
catch (e) {
log("**ERROR**", e);
process.exit('config/project.json does not exist or is broken');
}
};
this.handleMessage = function(from, message) {
log("Handle message from", from, "message", JSON.stringify(message));
if (self.callbackList[message.id]) {
self.callbackList[message.id](message);
}
switch (true) {
case message.command === "getFiles":
var allUIWebsockets = global.shared.allUIWebsockets;
var allWebsockets = global.shared.allWebsockets;
var connectedObject = allWebsockets[message.__deviceId].connectedObject;
var isBrowserActive = connectedObject && allUIWebsockets[connectedObject.browserGuid];
////////////////////////////////////////
if (!connectedObject) {
log("\n\ndevice is missing, allWebsocket ID's =>");
for (var key in allWebsockets) {
log(key);
}
log("\n__deviceId", message.__deviceId);
log("\nend of device\n\n");
}
if (!isBrowserActive) {
log("\n\nbrowser is missing, allUIWebsocket ID's =>");
for (var key in allUIWebsockets) {
log(key);
}
log("\n__deviceId", message.__deviceId);
log("\nend of browser\n\n");
}
////////////////////////////////////////
//if (!isBrowserActive && !bypassSecurityCheck) {
// self.sendMessage(CONTROL, 'cancelTransfer',
// messageFactory.createMessage('cancelTransfer', {
// errorMessage: errorMessages.IDE_CLOSED
// }));
//}
//else {
new ProjectChecker(logToConsole).check(
CONSTANTS.WORKSPACE_PATH,
function(err, cliErrReport, errors, warnings) {
var shouldShowErrorsOnUI = (err || errors || warnings);
var shouldShowErrorsOnDevice = (err || errors);
var shouldSendFiles = !shouldShowErrorsOnDevice;
!isEmptyObject(err) && log("**ERROR**", JSON.stringify(err));
!isEmptyObject(cliErrReport) && log("**ERROR**", JSON.stringify(cliErrReport));
!isEmptyObject(errors) && log("**ERROR**", JSON.stringify(errors));
!isEmptyObject(warnings) && log("**ERROR**", JSON.stringify(warnings));
if (shouldSendFiles) {
self.getFiles(message);
}
if (shouldShowErrorsOnUI) {
self.sendMessage(UI, 'showErrors',
messageFactory.createMessage('showErrors', cliErrReport));
}
if (shouldShowErrorsOnDevice) {
log('cancelTransfer', cliErrReport);
self.sendMessage(CONTROL, 'cancelTransfer',
messageFactory.createMessage('cancelTransfer', {
errorMessage: errorMessages.CANCEL_TRANSFER
}));
}
});
//}
break;
case message.event === "deviceInfo":
self.connectedDeviceType = message.deviceInfo.os;
log("deviceInfo event, connectedDeviceType:", self.connectedDeviceType);
break;
default:
}
};
this.getFiles = function(message) {
log('getFiles');
var deviceID = message.__deviceId;
sendResetTimeout.set(deviceID, function() {
self.sendMessage(DEVICE, "resetTimeout",
messageFactory.createMessage("resetTimeout"));
});
sendRequestedFiles(message, function(err) {
err && log(err);
!err && log("File sent");
sendResetTimeout.clear(deviceID);
});
};
this.sendMessage = function(to, command, message, callback) {
if (callback) {
self.callbackList[message.id] = callback;
}
self.emit(MESSAGE, to, command, message);
};
function sendRequestedFiles(requestMessage, callback) {
var isIOS = self.connectedDeviceType === "iOS";
var basePaths = self.basePaths[isIOS ? "iOS" : "Android"];
var filePackager = new FilePackager();
const indexData = global.shared.allDeviceInfos[requestMessage.__deviceId].indexData;
requestMessage.data.files.forEach(function(file) {
var filePath = (indexData.files[file] && indexData.files[file].fullPath) || URIParser.findFilePath(basePaths, file);
var info = URIParser.parse(file, isIOS);
filePackager.addFile(filePath, info.fileName, info.fileNameWithSchema);
});
filePackager.finalize(function(err, data) {
if (err) {
return callback("**ERROR** Finalizing package have failed: " + err);
}
else {
FileTransfer.sendFileOverWS(self.ws, data, logToConsole, function(err) {
// Cleanup
filePackager.destroy();
filePackager = null;
data = null;
gc();
return callback(err && "**ERROR** " + err);
});
}
});
}
}
module.exports = FileService;