From 81f42bda5586360e733f3afc66cf8a82bbeb94e1 Mon Sep 17 00:00:00 2001 From: Jack Allnutt Date: Fri, 22 Aug 2014 10:41:14 +0100 Subject: [PATCH] Simplify the settings generator settingsgenerator.js: * getSettings' callback now passes an error object as its first argument * generateSettings now returns a Promise httphandler.js: * serveSettings will now respond with HTTP 500 (Internal Server Error) if there is an error generating the settings object --- server/httphandler.js | 25 +++--- server/settingsgenerator.js | 147 ++++++++++++++++-------------------- 2 files changed, 79 insertions(+), 93 deletions(-) diff --git a/server/httphandler.js b/server/httphandler.js index c3fc067..1d4e5f7 100644 --- a/server/httphandler.js +++ b/server/httphandler.js @@ -2,8 +2,6 @@ var url = require('url'), fs = require('fs'), node_static = require('node-static'), Negotiator = require('negotiator'), - _ = require('lodash'), - config = require('./configuration.js'), winston = require('winston'), SettingsGenerator = require('./settingsgenerator.js'), Stats = require('./stats.js'); @@ -92,7 +90,7 @@ fs.readdir('client/assets/locales', function (err, files) { * Find the closest translation we have for the language * set in the browser. **/ -var serveMagicLocale = function (request, response) { +function serveMagicLocale(request, response) { var default_locale_id = 'en-gb', found_locale, negotiator; @@ -113,27 +111,32 @@ var serveMagicLocale = function (request, response) { Vary: 'Accept-Language', 'Content-Language': found_locale }, request, response); -}; +} /** * Handle the settings.json request */ -var serveSettings = function(request, response) { +function serveSettings(request, response) { var referrer_url, - debug = false, - settings; + debug = false; // Check the referrer for a debug option - if (request.headers['referer']) { - referrer_url = url.parse(request.headers['referer'], true); + if (request.headers.referer) { + referrer_url = url.parse(request.headers.referer, true); if (referrer_url.query && referrer_url.query.debug) { debug = true; } } - SettingsGenerator.get(debug, function(settings) { + SettingsGenerator.get(debug, function(err, settings) { + if (err) { + winston.error('Error generating settings', err); + response.writeHead(500, 'Internal Server Error'); + return response.end(); + } + if (request.headers['if-none-match'] && request.headers['if-none-match'] === settings.hash) { response.writeHead(304, 'Not Modified'); return response.end(); @@ -145,4 +148,4 @@ var serveSettings = function(request, response) { }); response.end(settings.settings); }); -}; +} diff --git a/server/settingsgenerator.js b/server/settingsgenerator.js index 0eefe79..176e86d 100644 --- a/server/settingsgenerator.js +++ b/server/settingsgenerator.js @@ -1,5 +1,6 @@ var fs = require('fs'), crypto = require('crypto'), + Promise = require('es6-promise').Promise, config = require('./configuration.js'); @@ -31,15 +32,16 @@ config.on('loaded', function () { function getSettings(debug, callback) { var settings = cached_settings[debug ? 'debug' : 'production']; - var returnSettings = function() { - callback(settings); - }; - // Generate the settings if we don't have them cached as yet if (settings.settings === '') { - generateSettings(debug, returnSettings); + generateSettings(debug).then(function (settings) { + cached_settings[debug ? 'debug' : 'production'] = settings; + callback(null, settings); + }, function (err) { + callback(err); + }); } else { - returnSettings(); + callback(null, settings); } } @@ -48,7 +50,7 @@ function getSettings(debug, callback) { * Generate a settings object for the client. * Settings include available translations, default client config, etc */ -function generateSettings(debug, callback) { +function generateSettings(debug) { var vars = { server_settings: {}, client_plugins: [], @@ -92,92 +94,73 @@ function generateSettings(debug, callback) { addScripts(vars, debug); - // Further jobs depend on callbacks, so tally up completed jobs before callback() - var total_jobs = 2, - completed_jobs = 0, - jobComplete = function() { - completed_jobs++; - - if (completed_jobs < total_jobs) - return; - - settings = cached_settings[debug?'debug':'production']; - settings.settings = JSON.stringify(vars); - settings.hash = crypto.createHash('md5').update(settings.settings).digest('hex'); - - callback(); - }; - - addThemes(vars, jobComplete); - addTranslations(vars, jobComplete); - -} - - -function addThemes(vars, callback) { - readThemeInfo(config.get().client_themes || ['relaxed'], function (err, themes) { - if (err) { - return callback(err); - } - + return Promise.all([addThemes().then(function (themes) { vars.themes = themes; - return callback(); + }), addTranslations().then(function (translations) { + vars.translations = translations; + })]).then(function () { + var settings = JSON.stringify(vars); + return ({ + settings: settings, + hash: crypto.createHash('md5').update(settings).digest('hex') + }); }); } -function readThemeInfo(themes, prev, callback) { - "use strict"; - var theme = themes[0]; - - if (typeof prev === 'function') { - callback = prev; - prev = []; - } - - fs.readFile(__dirname + '/../client/assets/themes/' + theme.toLowerCase() + '/theme.json', function (err, theme_json) { - if (err) { - return callback(err); - } - - try { - theme_json = JSON.parse(theme_json); - } catch (e) { - return callback(e); - } - - prev.push(theme_json); - - if (themes.length > 1) { - return readThemeInfo(themes.slice(1), prev, callback); - } - - callback(null, prev); - }); +function addThemes() { + return (config.get().client_themes || ['relaxed']).reduce(function (prom, theme) { + return prom.then(function (themes) { + return new Promise(function readThemeInfo(resolve, reject) { + fs.readFile(__dirname + '/../client/assets/themes/' + theme.toLowerCase() + '/theme.json', function (err, theme_json) { + var theme; + if (err) { + return reject(err); + } + + try { + theme = JSON.parse(theme_json); + } catch (e) { + return reject(e); + } + + themes.push(theme); + resolve(themes); + }); + }); + }); + }, Promise.resolve([])); } - -function addTranslations(vars, callback) { - // Get a list of available translations - fs.readFile(__dirname + '/../client/src/translations/translations.json', function (err, translations) { - if (err) { - return callback(err); - } - - translations = JSON.parse(translations); - fs.readdir(__dirname + '/../client/src/translations/', function (err, pofiles) { +function addTranslations() { + return new Promise(function (resolve, reject) { + fs.readFile(__dirname + '/../client/src/translations/translations.json', function readTranslations(err, translations) { if (err) { - return callback(err); + return reject(err); + } + + try { + translations = JSON.parse(translations); + } catch (e) { + return reject(e); } + + fs.readdir(__dirname + '/../client/src/translations/', function readTranslationFile(err, pofiles) { + var trans = []; - pofiles.forEach(function (file) { - var locale = file.slice(0, -3); - if ((file.slice(-3) === '.po') && (locale !== 'template')) { - vars.translations.push({tag: locale, language: translations[locale]}); + if (err) { + return reject(err); } - }); - return callback(); + pofiles.forEach(function (file) { + var locale = file.slice(0, -3); + if ((file.slice(-3) === '.po') && (locale !== 'template')) { + trans.push({tag: locale, language: translations[locale]}); + } + }); + + resolve(trans); + }); }); }); } @@ -265,4 +248,4 @@ function addScripts(vars, debug) { 'src/applets/startup.js' ] ]); -} \ No newline at end of file +} -- 2.25.1