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+'/..'); |
||
0 ignored issues
–
show
Compatibility
introduced
by
![]() |
|||
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; |
||
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; |