Restructure server code to make embedding easier

This commit is contained in:
Nicholas O'Leary 2013-09-20 17:15:45 +01:00
parent 7348e475eb
commit 0ecbbca7e4
5 changed files with 109 additions and 86 deletions

10
red.js
View File

@ -19,20 +19,18 @@ var util = require("util");
var express = require("express");
var crypto = require("crypto");
var settings = require("./settings");
var RED = require("./red/red.js");
var server;
var app = express();
var redApp = null;
if (settings.https) {
server = https.createServer(settings.https,function(req,res){app(req,res);});
} else {
server = http.createServer(function(req,res){app(req,res);});
}
redApp = require('./red/server.js').init(server,settings);
settings.httpRoot = settings.httpRoot||"/";
if (settings.httpRoot[0] != "/") {
@ -51,9 +49,11 @@ if (settings.httpAuth) {
);
}
app.use(settings.httpRoot,redApp);
RED.init(server,settings);
app.use(settings.httpRoot,RED.app);
server.listen(settings.uiPort);
RED.start();
util.log('[red] Server now running at http'+(settings.https?'s':'')+'://127.0.0.1:'+settings.uiPort+settings.httpRoot);

View File

@ -16,78 +16,80 @@
var fs = require("fs");
var fspath = require("path");
var redUI = require("./server");
var redApp = null;
// -------- Flow Library --------
redUI.app.post(new RegExp("/library/flows\/(.*)"), function(req,res) {
var fullBody = '';
req.on('data', function(chunk) {
fullBody += chunk.toString();
});
req.on('end', function() {
var fn = "lib/flows/"+req.params[0]+".json";
var parts = fn.split("/");
for (var i = 3;i<parts.length;i+=1) {
var dirname = parts.slice(0,i).join("/");
if (!fs.existsSync(dirname)) {
fs.mkdirSync(dirname);
function init() {
redApp = require("./server").app;
// -------- Flow Library --------
redApp.post(new RegExp("/library/flows\/(.*)"), function(req,res) {
var fullBody = '';
req.on('data', function(chunk) {
fullBody += chunk.toString();
});
req.on('end', function() {
var fn = "lib/flows/"+req.params[0]+".json";
var parts = fn.split("/");
for (var i = 3;i<parts.length;i+=1) {
var dirname = parts.slice(0,i).join("/");
if (!fs.existsSync(dirname)) {
fs.mkdirSync(dirname);
}
}
fs.writeFile(fn,fullBody,function(err) {
res.writeHead(204, {'Content-Type': 'text/plain'});
res.end();
});
});
});
function listFiles(dir) {
var dirs = {};
var files = [];
var dirCount = 0;
fs.readdirSync(dir).sort().filter(function(fn) {
var stats = fs.lstatSync(dir+"/"+fn);
if (stats.isDirectory()) {
dirCount += 1;
dirs[fn] = listFiles(dir+"/"+fn);
} else {
files.push(fn.split(".")[0]);
}
fs.writeFile(fn,fullBody,function(err) {
res.writeHead(204, {'Content-Type': 'text/plain'});
});
var result = {};
if (dirCount > 0) { result.d = dirs; }
if (files.length > 0) { result.f = files; }
return result;
}
redApp.get("/library/flows",function(req,res) {
var flows = {};
if (fs.existsSync("lib/flows")) {
flows = listFiles("lib/flows");
} else {
fs.mkdirSync("lib/flows");
}
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(JSON.stringify(flows));
res.end();
});
redApp.get(new RegExp("/library/flows\/(.*)"), function(req,res) {
var fn = "lib/flows/"+req.params[0]+".json";
if (fs.existsSync(fn)) {
fs.readFile(fn,function(err,data) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(data);
res.end();
});
});
});
function listFiles(dir) {
var dirs = {};
var files = [];
var dirCount = 0;
fs.readdirSync(dir).sort().filter(function(fn) {
var stats = fs.lstatSync(dir+"/"+fn);
if (stats.isDirectory()) {
dirCount += 1;
dirs[fn] = listFiles(dir+"/"+fn);
} else {
files.push(fn.split(".")[0]);
res.send(404);
}
});
var result = {};
if (dirCount > 0) { result.d = dirs; }
if (files.length > 0) { result.f = files; }
return result;
}
redUI.app.get("/library/flows",function(req,res) {
var flows = {};
if (fs.existsSync("lib/flows")) {
flows = listFiles("lib/flows");
} else {
fs.mkdirSync("lib/flows");
}
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(JSON.stringify(flows));
res.end();
});
redUI.app.get(new RegExp("/library/flows\/(.*)"), function(req,res) {
var fn = "lib/flows/"+req.params[0]+".json";
if (fs.existsSync(fn)) {
fs.readFile(fn,function(err,data) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(data);
res.end();
});
} else {
res.send(404);
}
});
// ------------------------------
// ------------------------------
}
function createLibrary(type) {
@ -96,11 +98,11 @@ function createLibrary(type) {
var root = fspath.join("lib",type)+"/";
fs.exists(root,function(exists) {
if (!exists) {
fs.mkdir(root);
}
if (!exists) {
fs.mkdir(root);
}
});
redUI.app.get(new RegExp("/library/"+type+"($|\/(.*))"),function(req,res) {
redApp.get(new RegExp("/library/"+type+"($|\/(.*))"),function(req,res) {
var path = req.params[1]||"";
var rootPath = fspath.join(root,path);
@ -141,7 +143,7 @@ function createLibrary(type) {
});
});
redUI.app.post(new RegExp("/library/"+type+"\/(.*)"),function(req,res) {
redApp.post(new RegExp("/library/"+type+"\/(.*)"),function(req,res) {
var path = req.params[0];
var fullBody = '';
req.on('data', function(chunk) {
@ -246,4 +248,5 @@ function getFileBody(root,path,res) {
res.end();
}
module.exports.init = init;
module.exports.register = createLibrary;

View File

@ -66,7 +66,11 @@ var registry = (function() {
events.emit("nodes-stopped");
nodes = {};
},
each: function(cb) {
for (var n in nodes) {
cb(nodes[n]);
}
},
addLogHandler: function(handler) {
logHandlers.push(handler);
}
@ -132,6 +136,7 @@ util.inherits(Node,EventEmitter);
Node.prototype.close = function() {
// called when a node is removed
this.emit("close");
}
@ -325,7 +330,7 @@ var parseConfig = function() {
util.log("[red] unknown type: "+activeConfig[i].type);
}
}
// Clean up any orphaned credentials
var deletedCredentials = false;
for (var c in credentials) {

View File

@ -18,18 +18,28 @@ var events = require("./events");
var server = require("./server");
var nodes = require("./nodes");
var library = require("./library");
var settings = require("../settings");
var settings = null;
var events = require("events");
var RED = {
init: function(httpServer,userSettings) {
settings = userSettings;
server.init(httpServer,settings);
library.init();
},
start: server.start,
nodes: nodes,
app: server.app,
server: server.server,
settings: settings,
library: library,
events: events
};
RED.__defineGetter__("app", function() { return server.app });
RED.__defineGetter__("server", function() { return server.server });
RED.__defineGetter__("settings", function() { return settings });
module.exports = RED;

View File

@ -19,6 +19,8 @@ var util = require('util');
var createUI = require("./ui");
var redNodes = require("./nodes");
var host = require('os').hostname();
//TODO: relocated user dir
var rulesfile = process.argv[2] || 'flows_'+host+'.json';
var app = null;
var server = null;
@ -28,7 +30,6 @@ function createServer(_server,settings) {
app = createUI(settings);
//TODO: relocated user dir
var rulesfile = process.argv[2] || 'flows_'+host+'.json';
fs.exists("lib/",function(exists) {
if (!exists) {
fs.mkdir("lib");
@ -70,7 +71,8 @@ function createServer(_server,settings) {
});
});
});
}
function start() {
console.log("\nWelcome to Node-RED\n===================\n");
util.log("[red] Loading palette nodes");
util.log("------------------------------------------");
@ -83,20 +85,23 @@ function createServer(_server,settings) {
util.log(' npm install {the module name}');
util.log('or any other errors are resolved');
util.log("------------------------------------------");
fs.exists(rulesfile, function (exists) {
if (exists) {
util.log("[red] Loading workspace flow : "+rulesfile);
util.log("[red] Loading flows : "+rulesfile);
fs.readFile(rulesfile,'utf8',function(err,data) {
redNodes.setConfig(JSON.parse(data));
});
} else {
util.log("[red] Flows file not found : "+rulesfile);
}
});
return app;
}
module.exports = {
init: createServer
init: createServer,
start: start
}
module.exports.__defineGetter__("app", function() { return app });