From ca294fc6ecc5db424b892870c0a7fc619c40e98e Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 29 Sep 2015 18:22:41 -0400 Subject: [PATCH] closes #3663 --- app.js | 6 ++--- loader.js | 4 +-- minifier.js | 17 ++++++------ public/src/modules/translator.js | 3 ++- src/controllers/admin/themes.js | 22 ++++++++-------- src/file.js | 19 +++++++++++++- src/logger.js | 3 ++- src/meta/css.js | 40 ++++++++++++++-------------- src/meta/js.js | 45 ++++++++++++++++---------------- src/meta/themes.js | 43 +++++++++++++++--------------- src/middleware/index.js | 3 ++- src/plugins.js | 3 ++- src/plugins/load.js | 3 ++- src/routes/plugins.js | 31 +++++++--------------- src/webserver.js | 3 ++- 15 files changed, 129 insertions(+), 116 deletions(-) diff --git a/app.js b/app.js index c6714a6425..4aa9371e18 100644 --- a/app.js +++ b/app.js @@ -23,14 +23,14 @@ var nconf = require('nconf'); nconf.argv().env('__'); -var fs = require('fs'), - url = require('url'), +var url = require('url'), async = require('async'), semver = require('semver'), winston = require('winston'), colors = require('colors'), path = require('path'), pkg = require('./package.json'), + file = require('./src/file'), utils = require('./public/src/utils.js'); global.env = process.env.NODE_ENV || 'production'; @@ -53,7 +53,7 @@ if (nconf.get('config')) { configFile = path.resolve(__dirname, nconf.get('config')); } -var configExists = fs.existsSync(configFile); +var configExists = file.existsSync(configFile); loadConfig(); diff --git a/loader.js b/loader.js index 96c78da4ee..20e8335a9a 100644 --- a/loader.js +++ b/loader.js @@ -8,7 +8,7 @@ var nconf = require('nconf'), async = require('async'), logrotate = require('logrotate-stream'), - + file = require('./src/file'), pkg = require('./package.json'); nconf.argv().env().file({ @@ -243,7 +243,7 @@ Loader.notifyWorkers = function(msg, worker_pid) { fs.open(path.join(__dirname, 'config.json'), 'r', function(err) { if (!err) { if (nconf.get('daemon') !== 'false' && nconf.get('daemon') !== false) { - if (fs.existsSync(pidFilePath)) { + if (file.existsSync(pidFilePath)) { try { var pid = fs.readFileSync(pidFilePath, { encoding: 'utf-8' }); process.kill(pid, 0); diff --git a/minifier.js b/minifier.js index 621d61fa08..c1df3930c1 100644 --- a/minifier.js +++ b/minifier.js @@ -4,6 +4,7 @@ var uglifyjs = require('uglify-js'), less = require('less'), async = require('async'), fs = require('fs'), + file = require('./src/file'), crypto = require('crypto'), utils = require('./public/src/utils'), @@ -14,16 +15,16 @@ var uglifyjs = require('uglify-js'), /* Javascript */ Minifier.js.minify = function (scripts, minify, callback) { scripts = scripts.filter(function(file) { - return fs.existsSync(file) && file.endsWith('.js'); + return file && file.endsWith('.js'); }); - if (minify) { - minifyScripts(scripts, function() { - callback.apply(this, arguments); - }); - } else { - concatenateScripts(scripts, callback); - } + async.filter(scripts, file.exists, function(scripts) { + if (minify) { + minifyScripts(scripts, callback); + } else { + concatenateScripts(scripts, callback); + } + }); }; process.on('message', function(payload) { diff --git a/public/src/modules/translator.js b/public/src/modules/translator.js index e2b70220f3..35429af587 100644 --- a/public/src/modules/translator.js +++ b/public/src/modules/translator.js @@ -264,11 +264,12 @@ var fs = require('fs'), path = require('path'), winston = require('winston'), + file = require('../../../src/file'), meta = require('../../../src/meta'); language = language || meta.config.defaultLang || 'en_GB'; - if (!fs.existsSync(path.join(__dirname, '../../language', language))) { + if (!file.existsSync(path.join(__dirname, '../../language', language))) { winston.warn('[translator] Language \'' + meta.config.defaultLang + '\' not found. Defaulting to \'en_GB\''); language = 'en_GB'; } diff --git a/src/controllers/admin/themes.js b/src/controllers/admin/themes.js index 0f87ecc83c..e5ef8a9343 100644 --- a/src/controllers/admin/themes.js +++ b/src/controllers/admin/themes.js @@ -1,24 +1,24 @@ 'use strict'; var path = require('path'); -var fs = require('fs'); +var file = require('../../file'); var themesController = {}; themesController.get = function(req, res, next) { var themeDir = path.join(__dirname, '../../../node_modules/' + req.params.theme); - fs.exists(themeDir, function(exists) { - if (exists) { - var themeConfig = require(path.join(themeDir, 'theme.json')), - screenshotPath = path.join(themeDir, themeConfig.screenshot); - if (themeConfig.screenshot && fs.existsSync(screenshotPath)) { - res.sendFile(screenshotPath); - } else { - res.sendFile(path.join(__dirname, '../../../public/images/themes/default.png')); - } - } else { + file.exists(themeDir, function(exists) { + if (!exists) { return next(); } + + var themeConfig = require(path.join(themeDir, 'theme.json')), + screenshotPath = path.join(themeDir, themeConfig.screenshot); + if (themeConfig.screenshot && file.existsSync(screenshotPath)) { + res.sendFile(screenshotPath); + } else { + res.sendFile(path.join(__dirname, '../../../public/images/themes/default.png')); + } }); }; diff --git a/src/file.js b/src/file.js index 94465b4ad7..2f503f0309 100644 --- a/src/file.js +++ b/src/file.js @@ -8,7 +8,6 @@ var fs = require('fs'), Magic = mmmagic.Magic, mime = require('mime'), - meta = require('./meta'), utils = require('../public/src/utils'); var file = {}; @@ -63,6 +62,7 @@ file.isFileTypeAllowed = function(path, allowedExtensions, callback) { }; file.allowedExtensions = function() { + var meta = require('./meta'); var allowedExtensions = (meta.config.allowedFileExtensions || '').trim(); if (!allowedExtensions) { return []; @@ -80,4 +80,21 @@ file.allowedExtensions = function() { return allowedExtensions; }; +file.exists = function(path, callback) { + fs.stat(path, function(err, stat) { + callback(!err && stat); + }); +}; + +file.existsSync = function(path) { + var exists = false; + try { + exists = fs.statSync(path); + } catch(err) { + exists = false; + } + + return !!exists; +}; + module.exports = file; \ No newline at end of file diff --git a/src/logger.js b/src/logger.js index cd437924be..5b15e90ad6 100644 --- a/src/logger.js +++ b/src/logger.js @@ -10,6 +10,7 @@ var fs = require('fs'), winston = require('winston'), util = require('util'), socketio = require('socket.io'), + file = require('./file'), meta = require('./meta'), morgan = require('morgan'); @@ -76,7 +77,7 @@ var opts = { /* Open the streams to log to: either a path or stdout */ var stream; if(value) { - if(fs.existsSync(value)) { + if(file.existsSync(value)) { var stats = fs.statSync(value); if(stats) { if(stats.isDirectory()) { diff --git a/src/meta/css.js b/src/meta/css.js index f3257e624f..46b54ccb18 100644 --- a/src/meta/css.js +++ b/src/meta/css.js @@ -11,6 +11,7 @@ var winston = require('winston'), plugins = require('../plugins'), emitter = require('../emitter'), db = require('../database'), + file = require('../file'), utils = require('../../public/src/utils'); module.exports = function(Meta) { @@ -149,24 +150,25 @@ module.exports = function(Meta) { Meta.css.getFromFile = function(callback) { var cachePath = path.join(__dirname, '../../public/stylesheet.css'), acpCachePath = path.join(__dirname, '../../public/admin.css'); - fs.exists(cachePath, function(exists) { - if (exists) { - if (nconf.get('isPrimary') === 'true') { - winston.verbose('[meta/css] Reading stylesheets from file'); - async.map([cachePath, acpCachePath], fs.readFile, function(err, files) { - Meta.css.cache = files[0]; - Meta.css.acpCache = files[1]; - - emitter.emit('meta:css.compiled'); - callback(); - }); - } else { - callback(); - } - } else { + file.exists(cachePath, function(exists) { + if (!exists) { winston.warn('[meta/css] No stylesheets found on disk, re-minifying'); - Meta.css.minify.apply(Meta.css, arguments); + Meta.css.minify(callback); + return; } + + if (nconf.get('isPrimary') !== 'true') { + return callback(); + } + + winston.verbose('[meta/css] Reading stylesheets from file'); + async.map([cachePath, acpCachePath], fs.readFile, function(err, files) { + Meta.css.cache = files[0]; + Meta.css.acpCache = files[1]; + + emitter.emit('meta:css.compiled'); + callback(); + }); }); }; @@ -197,10 +199,10 @@ module.exports = function(Meta) { } function filterMissingFiles(files) { - return files.filter(function(file) { - var exists = fs.existsSync(path.join(__dirname, '../../node_modules', file)); + return files.filter(function(filePath) { + var exists = file.existsSync(path.join(__dirname, '../../node_modules', filePath)); if (!exists) { - winston.warn('[meta/css] File not found! ' + file); + winston.warn('[meta/css] File not found! ' + filePath); } return exists; }); diff --git a/src/meta/js.js b/src/meta/js.js index 9bddbd58e9..dd8c364924 100644 --- a/src/meta/js.js +++ b/src/meta/js.js @@ -8,7 +8,7 @@ var winston = require('winston'), os = require('os'), nconf = require('nconf'), fs = require('fs'), - + file = require('../file'), plugins = require('../plugins'), emitter = require('../emitter'), utils = require('../../public/src/utils'); @@ -208,30 +208,31 @@ module.exports = function(Meta) { var scriptPath = path.join(__dirname, '../../public/nodebb.min.js'), mapPath = path.join(__dirname, '../../public/nodebb.min.js.map'), paths = [scriptPath]; - fs.exists(scriptPath, function(exists) { - if (exists) { - if (nconf.get('isPrimary') === 'true') { - fs.exists(mapPath, function(exists) { - if (exists) { - paths.push(mapPath); - } + file.exists(scriptPath, function(exists) { + if (!exists) { + winston.warn('[meta/js] No script file found on disk, re-minifying'); + Meta.js.minify(minify, callback); + return; + } - winston.verbose('[meta/js] Reading client-side scripts from file'); - async.map(paths, fs.readFile, function(err, files) { - Meta.js.cache = files[0]; - Meta.js.map = files[1] || ''; + if (nconf.get('isPrimary') !== 'true') { + return callback(); + } - emitter.emit('meta:js.compiled'); - callback(); - }); - }); - } else { - callback(); + file.exists(mapPath, function(exists) { + if (exists) { + paths.push(mapPath); } - } else { - winston.warn('[meta/js] No script file found on disk, re-minifying'); - Meta.js.minify.apply(Meta.js, arguments); - } + + winston.verbose('[meta/js] Reading client-side scripts from file'); + async.map(paths, fs.readFile, function(err, files) { + Meta.js.cache = files[0]; + Meta.js.map = files[1] || ''; + + emitter.emit('meta:js.compiled'); + callback(); + }); + }); }); }; diff --git a/src/meta/themes.js b/src/meta/themes.js index e10194c9af..fedb1ff0d9 100644 --- a/src/meta/themes.js +++ b/src/meta/themes.js @@ -6,6 +6,8 @@ var nconf = require('nconf'), fs = require('fs'), path = require('path'), async = require('async'), + + file = require('../file'), db = require('../database'); module.exports = function(Meta) { @@ -34,27 +36,24 @@ module.exports = function(Meta) { async.map(themes, function (theme, next) { var config = path.join(themePath, theme, 'theme.json'); - if (fs.existsSync(config)) { - fs.readFile(config, function (err, file) { - if (err) { - return next(); - } else { - var configObj = JSON.parse(file.toString()); - - // Minor adjustments for API output - configObj.type = 'local'; - if (configObj.screenshot) { - configObj.screenshot_url = nconf.get('relative_path') + '/css/previews/' + configObj.id; - } else { - configObj.screenshot_url = nconf.get('relative_path') + '/images/themes/default.png'; - } - - next(err, configObj); - } - }); - } else { - next(); - } + fs.readFile(config, function (err, file) { + if (err) { + return next(); + } + + var configObj = JSON.parse(file.toString()); + + // Minor adjustments for API output + configObj.type = 'local'; + if (configObj.screenshot) { + configObj.screenshot_url = nconf.get('relative_path') + '/css/previews/' + configObj.id; + } else { + configObj.screenshot_url = nconf.get('relative_path') + '/images/themes/default.png'; + } + + next(null, configObj); + }); + }, function (err, themes) { themes = themes.filter(function (theme) { return (theme !== undefined); @@ -145,7 +144,7 @@ module.exports = function(Meta) { if (themeObj.templates) { themePath = path.join(nconf.get('themes_path'), themeObj.id, themeObj.templates); - } else if (fs.existsSync(fallback)) { + } else if (file.existsSync(fallback)) { themePath = fallback; } diff --git a/src/middleware/index.js b/src/middleware/index.js index fedb8b55cb..80b6677970 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -2,6 +2,7 @@ var meta = require('../meta'), db = require('../database'), + file = require('../file'), auth = require('../routes/authentication'), path = require('path'), @@ -21,7 +22,7 @@ var middleware = {}; function setupFavicon(app) { var faviconPath = path.join(__dirname, '../../', 'public', meta.config['brand:favicon'] ? meta.config['brand:favicon'] : 'favicon.ico'); - if (fs.existsSync(faviconPath)) { + if (file.existsSync(faviconPath)) { app.use(nconf.get('relative_path'), favicon(faviconPath)); } } diff --git a/src/plugins.js b/src/plugins.js index 7abf65dafa..f86251293a 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -14,6 +14,7 @@ var fs = require('fs'), translator = require('../public/src/modules/translator'), utils = require('../public/src/utils'), hotswap = require('./hotswap'), + file = require('./file'), controllers = require('./controllers'), app, middleware; @@ -103,7 +104,7 @@ var fs = require('fs'), return path.join(__dirname, '../node_modules/', plugin); }); - async.filter(plugins, fs.exists, function(plugins){ + async.filter(plugins, file.exists, function(plugins) { async.eachSeries(plugins, Plugins.loadPlugin, next); }); }, diff --git a/src/plugins/load.js b/src/plugins/load.js index ad441a2b97..f7d54cc6a8 100644 --- a/src/plugins/load.js +++ b/src/plugins/load.js @@ -6,6 +6,7 @@ var fs = require('fs'), async = require('async'), winston = require('winston'), nconf = require('nconf'), + file = require('../file'), utils = require('../../public/src/utils'); @@ -107,7 +108,7 @@ module.exports = function(Plugins) { var realPath = pluginData.staticDirs[mappedPath]; var staticDir = path.join(pluginPath, realPath); - fs.exists(staticDir, function(exists) { + file.exists(staticDir, function(exists) { if (exists) { Plugins.staticDirs[pluginData.id + '/' + mappedPath] = staticDir; } else { diff --git a/src/routes/plugins.js b/src/routes/plugins.js index ad1c0e84fa..72af49fbed 100644 --- a/src/routes/plugins.js +++ b/src/routes/plugins.js @@ -22,31 +22,18 @@ module.exports = function(app, middleware, controllers) { } else { return null; } - }).filter(function(a) { return a; }); + }).filter(Boolean); - if (matches) { - async.map(matches, function(mappedPath, next) { - var filePath = path.join(plugins.staticDirs[mappedPath], decodeURIComponent(relPath.slice(mappedPath.length))); + if (!matches) { + return next(); + } - fs.exists(filePath, function(exists) { - if (exists) { - next(null, filePath); - } else { - next(); - } - }); - }, function(err, matches) { - if (err) { - return next(err); - } - matches = matches.filter(Boolean); + matches = matches.map(function(mappedPath) { + return path.join(plugins.staticDirs[mappedPath], decodeURIComponent(relPath.slice(mappedPath.length))); + }); - if (matches.length) { - res.sendFile(matches[0]); - } else { - next(); - } - }); + if (matches.length) { + res.sendFile(matches[0]); } else { next(); } diff --git a/src/webserver.js b/src/webserver.js index 9b6fb24e8c..87b9f1a8cc 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -186,9 +186,10 @@ module.exports.testSocket = function(socketPath, callback) { return callback(new Error('invalid socket path : ' + socketPath)); } var net = require('net'); + var file = require('./file'); async.series([ function(next) { - fs.exists(socketPath, function(exists) { + file.exists(socketPath, function(exists) { if (exists) { next(); } else {