Channel tools box; memberlist/right bar structure refactor
[KiwiIRC.git] / server / settingsgenerator.js
1 var fs = require('fs'),
2 crypto = require('crypto'),
3 config = require('./configuration.js');
4
5
6 module.exports.generate = generateSettings;
7 module.exports.get = getSettings;
8
9
10 // Cache for settings.json
11 var cached_settings = {
12 debug: {
13 hash: '',
14 settings: ''
15 },
16 production: {
17 hash: '',
18 settings: ''
19 }
20 };
21
22 // Clear the settings cache when the settings change
23 config.on('loaded', function () {
24 cached_settings.debug.settings = cached_settings.production.settings = '';
25 cached_settings.debug.hash = cached_settings.production.hash = '';
26 });
27
28
29
30
31 function getSettings(debug, callback) {
32 var settings = cached_settings[debug ? 'debug' : 'production'];
33
34 var returnSettings = function() {
35 callback(settings);
36 };
37
38 // Generate the settings if we don't have them cached as yet
39 if (settings.settings === '') {
40 generateSettings(debug, returnSettings);
41 } else {
42 returnSettings();
43 }
44 }
45
46
47 /**
48 * Generate a settings object for the client.
49 * Settings include available translations, default client config, etc
50 */
51 function generateSettings(debug, callback) {
52 var vars = {
53 server_settings: {},
54 client_plugins: [],
55 translations: [],
56 scripts: [
57 [
58 'assets/libs/lodash.min.js'
59 ],
60 ['assets/libs/backbone.min.js', 'assets/libs/jed.js']
61 ]
62 };
63
64 // Any restricted server mode set?
65 if (config.get().restrict_server) {
66 vars.server_settings = {
67 connection: {
68 server: config.get().restrict_server,
69 port: config.get().restrict_server_port || 6667,
70 ssl: config.get().restrict_server_ssl,
71 channel: config.get().restrict_server_channel,
72 nick: config.get().restrict_server_nick,
73 allow_change: false
74 }
75 };
76 }
77
78 // Any client default settings?
79 if (config.get().client) {
80 vars.server_settings.client = config.get().client;
81 }
82
83 // Any client plugins?
84 if (config.get().client_plugins && config.get().client_plugins.length > 0) {
85 vars.client_plugins = config.get().client_plugins;
86 }
87
88 addScripts(vars, debug);
89
90 // Further jobs depend on callbacks, so tally up completed jobs before callback()
91 var total_jobs = 2,
92 completed_jobs = 0,
93 jobComplete = function() {
94 completed_jobs++;
95
96 if (completed_jobs < total_jobs)
97 return;
98
99 settings = cached_settings[debug?'debug':'production'];
100 settings.settings = JSON.stringify(vars);
101 settings.hash = crypto.createHash('md5').update(settings.settings).digest('hex');
102
103 callback();
104 };
105
106 addThemes(vars, jobComplete);
107 addTranslations(vars, jobComplete);
108
109 }
110
111
112 function addThemes(vars, callback) {
113 readThemeInfo(config.get().client_themes || ['relaxed'], function (err, themes) {
114 if (err) {
115 return callback(err);
116 }
117
118 vars.themes = themes;
119 return callback();
120 });
121 }
122
123
124 function readThemeInfo(themes, prev, callback) {
125 "use strict";
126 var theme = themes[0];
127
128 if (typeof prev === 'function') {
129 callback = prev;
130 prev = [];
131 }
132
133 fs.readFile(__dirname + '/../client/assets/themes/' + theme.toLowerCase() + '/theme.json', function (err, theme_json) {
134 if (err) {
135 return callback(err);
136 }
137
138 try {
139 theme_json = JSON.parse(theme_json);
140 } catch (e) {
141 return callback(e);
142 }
143
144 prev.push(theme_json);
145
146 if (themes.length > 1) {
147 return readThemeInfo(themes.slice(1), prev, callback);
148 }
149
150 callback(null, prev);
151 });
152 }
153
154
155 function addTranslations(vars, callback) {
156 // Get a list of available translations
157 fs.readFile(__dirname + '/../client/src/translations/translations.json', function (err, translations) {
158 if (err) {
159 return callback(err);
160 }
161
162 translations = JSON.parse(translations);
163 fs.readdir(__dirname + '/../client/src/translations/', function (err, pofiles) {
164 if (err) {
165 return callback(err);
166 }
167
168 pofiles.forEach(function (file) {
169 var locale = file.slice(0, -3);
170 if ((file.slice(-3) === '.po') && (locale !== 'template')) {
171 vars.translations.push({tag: locale, language: translations[locale]});
172 }
173 });
174
175 return callback();
176 });
177 });
178 }
179
180
181 function addScripts(vars, debug) {
182 if (!debug) {
183 vars.scripts.push(['assets/kiwi.min.js', 'assets/libs/engine.io.bundle.min.js']);
184 return;
185 }
186
187 vars.scripts = vars.scripts.concat([
188 [
189 'src/app.js',
190 'assets/libs/engine.io.js',
191 'assets/libs/engine.io.tools.js'
192 ],
193 [
194 'src/models/application.js',
195 'src/models/gateway.js'
196 ],
197 [
198 'src/models/newconnection.js',
199 'src/models/panellist.js',
200 'src/models/networkpanellist.js',
201 'src/models/panel.js',
202 'src/models/member.js',
203 'src/models/memberlist.js',
204 'src/models/network.js',
205 'src/models/channelinfo.js'
206 ],
207
208 [
209 'src/models/channel.js',
210 'src/models/applet.js'
211 ],
212
213 [
214 'src/models/query.js',
215 'src/models/server.js', // Depends on models/channel.js
216 'src/applets/settings.js',
217 'src/applets/chanlist.js',
218 'src/applets/scripteditor.js'
219 ],
220
221 [
222 'src/models/pluginmanager.js',
223 'src/models/datastore.js',
224 'src/helpers/utils.js'
225 ],
226
227 // Some views extend these, so make sure they're loaded beforehand
228 [
229 'src/views/panel.js'
230 ],
231
232 [
233 'src/views/channel.js',
234 'src/views/applet.js',
235 'src/views/application.js',
236 'src/views/apptoolbar.js',
237 'src/views/controlbox.js',
238 'src/views/favicon.js',
239 'src/views/mediamessage.js',
240 'src/views/member.js',
241 'src/views/memberlist.js',
242 'src/views/menubox.js',
243 'src/views/networktabs.js',
244 'src/views/nickchangebox.js',
245 'src/views/resizehandler.js',
246 'src/views/serverselect.js',
247 'src/views/statusmessage.js',
248 'src/views/tabs.js',
249 'src/views/topicbar.js',
250 'src/views/userbox.js',
251 'src/views/channeltools.js',
252 'src/views/channelinfo.js'
253 ]
254 ]);
255 }