Issues (208)

server/config.js (1 issue)

1
var fs      = require('fs');
2
var extend  = require('extend');
3
var express = require('express');
4
var request = require('request');
5
6
// ------------------------------------------
7
//  CONSTRUCTOR
8
// ------------------------------------------
9
10
var init = function(){
11
  info('Starting ConfigManager ...');
12
  
13
  // Load properties
14
  load();
15
  
16
  // Configure proxy
17
  if (Config.http.proxy){
18
    request.defaults({'proxy': Config.http.proxy})
19
  }
20
  
21
  // Expose properties to global
22
  global.Config = Config;
23
  
24
  return ConfigManager;
25
}
26
27
// ------------------------------------------
28
//  CONFIG
29
// ------------------------------------------
30
var path   = require('path');
31
var ROOT   = path.normalize(__dirname+'/..');
32
33
var SERVER = path.normalize(ROOT+'/server/server.prop');
34
var PLUGIN = process.env.PLUGINS_PATH || path.normalize(ROOT+'/../../plugins');
35
var VIEW   = path.normalize(ROOT+'/webapp/views');
36
var CUSTOM = path.normalize(ROOT+'/data/custom.prop');
37
38
info('ROOT', ROOT, '\nSERVER', SERVER, '\nPLUGIN', PLUGIN);
39
40
info('NODE_PATH', module.paths);
41
42
var Config = { 'debug' : false };
43
var load = function(){
44
  try { 
45
    extend(true, Config, loadProperties());
46
    extend(true, Config, loadPlugins());
47
    extend(true, Config, loadCustoms());
48
    Config.bot.version = "4.0";
49
  } 
50
  catch(ex) { error('Error while loading properties: %s', ex.message);  }
51
  return ConfigManager;
52
}
53
54
/**
55
 * Load default properties
56
 */
57
var loadProperties = function(){
58
  if (!fs.existsSync(SERVER)) { return {}; }
59
  info('Loading server properties...', SERVER);
60
  var json = fs.readFileSync(SERVER, 'utf8');
61
  return JSON.parse(json);
62
}
63
64
/**
65
 * Load plugin properties recursively
66
 */
67
var loadPlugins = function(folder, json){ 
68
  var json   = json   || {};
69
  var folder = folder || PLUGIN;
70
71
  if (!fs.existsSync(folder)) { return json; }  
72
  fs.readdirSync(folder).forEach(function(file){
73
    var path = folder+'/'+file;
74
    
75
    // Directory
76
    if (fs.statSync(path).isDirectory()){
77
      loadPlugins(path, json);
78
      return json;
79
    }
80
    
81
    // Ends with .prop
82
    if (file.endsWith('.prop')){
83
      info('Loading plugin properties... %s', path);
84
      try {
85
        var load   =  fs.readFileSync(path,'utf8');
86
        var plugin = JSON.parse(load);
87
        extend(true, json, plugin);
88
      } catch(ex){ error('Error in %s: %s', file, ex.message); }
89
    }
90
  });
91
  return json;
92
}
93
94
/**
95
 * Load custom properties
96
 */
97
var loadCustoms = function(){
98
  if (!fs.existsSync(CUSTOM)) { warn("Can't load custom properties !", CUSTOM); return {}; }
99
  info('Loading custom properties...', CUSTOM);
100
  
101
  var load = fs.readFileSync(CUSTOM,'utf8');
102
  var json = {}; 
103
  try { json = JSON.parse(load); } catch (ex){ error('Error in custom.prop: %s', ex.message); }
104
  
105
  json['modules']  = retains(json['modules'],  Config['modules']);
106
  json['phantoms'] = retains(json['phantoms'], Config['phantoms']);
107
  json['cron']     = retains(json['cron'],     Config['cron']);
108
109
  return json;
110
}
111
112
var retains = function(source, target){
113
  if (typeof source != 'object') return source;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
114
  
115
  var clean  = {};
116
  Object.keys(source).forEach(function(attr){
117
    if (attr == 'description' || attr == 'version'){ return false; }
118
    if (target[attr] === undefined
119
        && attr != 'x' && attr != 'y' 
120
        && attr != 'w' && attr != 'h'
121
        && attr != 'c' && attr != 'disabled'){ return warn('Skip config: %s', attr); }
122
    clean[attr] = retains(source[attr], target[attr]);
123
  });
124
  
125
  return clean;
126
}
127
128
/**
129
 * Load plugin properties file
130
 */
131
var loadJSON = function(name){
132
  var path = PLUGIN+'/'+name+'/'+name+'.prop';
133
  if (!fs.existsSync(path)){ return {}; }
134
  info('Loading plugin properties... %s', path);
135
  try {
136
    var json = fs.readFileSync(path,'utf8');
137
    return JSON.parse(json);
138
  } catch(ex){ error('Error in %s: %s', name+'.prop', ex.message); }
139
}
140
141
// ------------------------------------------
142
//  SAVE
143
// ------------------------------------------
144
145
var setProperty = function(keys, value, json){
146
  var config = json || Config;
147
  var keys = keys.split('.');
148
  for (var k in keys){
149
    var key = keys[k];
150
    if (typeof config[key] === 'object' ){
151
      config = config[key];
152
    } else {
153
      config[key] = value;
154
    }
155
  }
156
}
157
158
var save = function(cfg) {
159
  try {
160
    Config = cfg || Config;
161
    var json = JSON.stringify(Config, undefined, 2);
162
163
    //json = json.replace(/\{/g,"{\n  ").replace(/\}/g,"\n  }").replace(/,/g,",\n  ");
164
    fs.writeFileSync(CUSTOM, json, 'utf8');
165
    info('Properties saved successfully');
166
  } catch(ex) {
167
    error('Error while saving properties: %s', ex.message);
168
  }
169
}
170
171
// ------------------------------------------
172
//  ROUTER
173
// ------------------------------------------
174
175
176
var Router = express.Router();
177
178
Router.get('/portal/config', function(req, res, next) {
179
  res.render('portal/config.ejs');
180
});
181
182
Router.post('/portal/config', function(req, res, next) {
183
  var keys    = Object.keys(req.body);
184
  for(var i   = 0 ; i < keys.length ; i++){
185
    var key   = keys[i];
186
    var value = Helper.parse(req.body[key]);
187
    setProperty(key, value);
188
  }
189
  SARAH.ConfigManager.save();
190
  res.redirect('/portal/config');
191
});
192
193
// ------------------------------------------
194
//  PUBLIC
195
// ------------------------------------------
196
197
var ConfigManager = {
198
  'init'   : init,
199
  'load'   : load,
200
  'save'   : save,
201
  
202
  'loadJSON' : loadJSON,
203
  'getConfig': function(){ warn('getConfig is deprecated for SARAH 4.x, use global Config'); return Config; },
204
  'Router' : Router,
205
  'Config' : Config,
206
  'PLUGIN' : PLUGIN,
207
  'ROOT'   : ROOT,
208
  'VIEW'   : VIEW
209
}
210
211
// Exports Manager
212
exports.init = ConfigManager.init;