2014-03-02 14:45:57 -05:00
|
|
|
"use strict";
|
|
|
|
|
|
2013-12-02 16:19:30 -05:00
|
|
|
var fs = require('fs'),
|
2013-07-17 16:17:19 -04:00
|
|
|
path = require('path'),
|
2013-12-02 16:19:30 -05:00
|
|
|
async = require('async'),
|
2013-09-17 15:38:50 -04:00
|
|
|
winston = require('winston'),
|
2013-12-02 16:19:30 -05:00
|
|
|
nconf = require('nconf'),
|
2014-02-28 20:13:28 -05:00
|
|
|
_ = require('underscore'),
|
2014-03-24 14:12:59 -04:00
|
|
|
less = require('less'),
|
2014-04-03 17:27:26 -04:00
|
|
|
fork = require('child_process').fork,
|
2014-04-12 18:33:52 -04:00
|
|
|
rimraf = require('rimraf'),
|
|
|
|
|
mkdirp = require('mkdirp'),
|
2013-12-02 16:19:30 -05:00
|
|
|
|
|
|
|
|
utils = require('./../public/src/utils'),
|
2014-02-21 23:01:15 -05:00
|
|
|
translator = require('./../public/src/translator'),
|
2013-12-02 16:19:30 -05:00
|
|
|
db = require('./database'),
|
2014-01-27 12:19:25 -05:00
|
|
|
plugins = require('./plugins'),
|
|
|
|
|
User = require('./user');
|
2013-12-02 16:19:30 -05:00
|
|
|
|
2013-09-24 12:33:51 -04:00
|
|
|
(function (Meta) {
|
2013-09-30 11:17:12 -04:00
|
|
|
Meta.config = {};
|
2013-08-23 13:14:36 -04:00
|
|
|
Meta.configs = {
|
2013-09-24 12:33:51 -04:00
|
|
|
init: function (callback) {
|
2013-09-30 11:18:02 -04:00
|
|
|
delete Meta.config;
|
|
|
|
|
|
2013-09-24 12:33:51 -04:00
|
|
|
Meta.configs.list(function (err, config) {
|
2013-12-02 16:19:30 -05:00
|
|
|
if(err) {
|
2014-01-31 15:19:45 +02:00
|
|
|
winston.error(err);
|
2013-12-02 16:19:30 -05:00
|
|
|
return callback(err);
|
2013-09-24 12:33:51 -04:00
|
|
|
}
|
2013-12-02 16:19:30 -05:00
|
|
|
|
|
|
|
|
Meta.config = config;
|
|
|
|
|
callback();
|
2013-08-23 13:14:36 -04:00
|
|
|
});
|
|
|
|
|
},
|
2013-09-24 12:33:51 -04:00
|
|
|
list: function (callback) {
|
2013-12-02 16:19:30 -05:00
|
|
|
db.getObject('config', function (err, config) {
|
|
|
|
|
if(err) {
|
2013-12-23 19:17:03 -05:00
|
|
|
return callback(err);
|
2013-08-10 16:15:58 -04:00
|
|
|
}
|
2013-12-02 16:19:30 -05:00
|
|
|
|
|
|
|
|
config = config || {};
|
|
|
|
|
config.status = 'ok';
|
|
|
|
|
callback(err, config);
|
2013-05-25 20:32:22 -04:00
|
|
|
});
|
|
|
|
|
},
|
2013-09-24 12:33:51 -04:00
|
|
|
get: function (field, callback) {
|
2013-12-02 16:19:30 -05:00
|
|
|
db.getObjectField('config', field, callback);
|
2013-09-11 13:49:17 -04:00
|
|
|
},
|
2013-09-24 12:33:51 -04:00
|
|
|
getFields: function (fields, callback) {
|
2013-12-02 16:19:30 -05:00
|
|
|
db.getObjectFields('config', fields, callback);
|
2013-08-13 11:25:10 -04:00
|
|
|
},
|
2013-09-24 12:33:51 -04:00
|
|
|
set: function (field, value, callback) {
|
2014-01-19 18:02:01 -05:00
|
|
|
if(!field) {
|
|
|
|
|
return callback(new Error('invalid config field'));
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-04 17:57:51 -05:00
|
|
|
db.setObjectField('config', field, value, function(err, res) {
|
2013-09-24 12:33:51 -04:00
|
|
|
if (callback) {
|
2014-01-09 14:21:58 -05:00
|
|
|
if(!err && Meta.config) {
|
2013-09-29 14:18:43 -04:00
|
|
|
Meta.config[field] = value;
|
2014-01-09 14:21:58 -05:00
|
|
|
}
|
|
|
|
|
|
2013-08-13 11:25:10 -04:00
|
|
|
callback(err, res);
|
2013-09-24 12:33:51 -04:00
|
|
|
}
|
2013-05-25 20:32:22 -04:00
|
|
|
});
|
2013-06-06 15:34:12 -04:00
|
|
|
},
|
2013-09-24 12:33:51 -04:00
|
|
|
setOnEmpty: function (field, value, callback) {
|
2013-12-04 17:57:51 -05:00
|
|
|
Meta.configs.get(field, function (err, curValue) {
|
2014-01-13 14:28:05 -05:00
|
|
|
if(err) {
|
|
|
|
|
return callback(err);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-24 12:33:51 -04:00
|
|
|
if (!curValue) {
|
|
|
|
|
Meta.configs.set(field, value, callback);
|
|
|
|
|
} else {
|
|
|
|
|
callback();
|
|
|
|
|
}
|
2013-09-11 13:49:17 -04:00
|
|
|
});
|
|
|
|
|
},
|
2013-09-24 12:33:51 -04:00
|
|
|
remove: function (field) {
|
2013-12-02 16:19:30 -05:00
|
|
|
db.deleteObjectField('config', field);
|
2013-05-25 20:32:22 -04:00
|
|
|
}
|
2013-09-24 12:33:51 -04:00
|
|
|
};
|
2013-07-17 16:17:19 -04:00
|
|
|
|
|
|
|
|
Meta.themes = {
|
2013-09-24 12:33:51 -04:00
|
|
|
get: function (callback) {
|
2014-02-14 17:11:25 +00:00
|
|
|
var themePath = nconf.get('themes_path');
|
2014-03-06 14:51:43 -05:00
|
|
|
if (typeof themePath !== 'string') {
|
|
|
|
|
return callback(null, []);
|
|
|
|
|
}
|
2013-09-24 12:33:51 -04:00
|
|
|
fs.readdir(themePath, function (err, files) {
|
|
|
|
|
async.filter(files, function (file, next) {
|
|
|
|
|
fs.stat(path.join(themePath, file), function (err, fileStat) {
|
|
|
|
|
if (err) {
|
2013-12-23 15:23:08 -05:00
|
|
|
return next(false);
|
2013-09-24 12:33:51 -04:00
|
|
|
}
|
2013-07-17 16:17:19 -04:00
|
|
|
|
2013-08-28 16:32:59 -04:00
|
|
|
next((fileStat.isDirectory() && file.slice(0, 13) === 'nodebb-theme-'));
|
|
|
|
|
});
|
2013-09-24 12:33:51 -04:00
|
|
|
}, function (themes) {
|
|
|
|
|
async.map(themes, function (theme, next) {
|
2013-09-17 13:09:37 -04:00
|
|
|
var config = path.join(themePath, theme, 'theme.json');
|
2013-08-28 16:32:59 -04:00
|
|
|
|
|
|
|
|
if (fs.existsSync(config)) {
|
2013-09-24 12:33:51 -04:00
|
|
|
fs.readFile(config, function (err, file) {
|
2014-03-02 14:45:57 -05:00
|
|
|
if (err) {
|
|
|
|
|
return next();
|
|
|
|
|
} else {
|
2013-11-01 11:27:02 -04:00
|
|
|
var configObj = JSON.parse(file.toString());
|
2013-10-29 18:25:33 -04:00
|
|
|
next(err, configObj);
|
2013-09-24 12:33:51 -04:00
|
|
|
}
|
2013-07-17 16:17:19 -04:00
|
|
|
});
|
2013-09-24 12:33:51 -04:00
|
|
|
} else {
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
}, function (err, themes) {
|
|
|
|
|
themes = themes.filter(function (theme) {
|
2013-08-28 16:32:59 -04:00
|
|
|
return (theme !== undefined);
|
|
|
|
|
});
|
|
|
|
|
callback(null, themes);
|
2013-07-17 16:17:19 -04:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
2013-10-21 12:07:37 -04:00
|
|
|
},
|
|
|
|
|
set: function(data, callback) {
|
|
|
|
|
var themeData = {
|
2014-03-09 17:29:05 -04:00
|
|
|
'theme:type': data.type,
|
|
|
|
|
'theme:id': data.id,
|
|
|
|
|
'theme:staticDir': '',
|
|
|
|
|
'theme:templates': '',
|
|
|
|
|
'theme:src': ''
|
|
|
|
|
};
|
2014-01-17 16:27:17 -05:00
|
|
|
|
2013-10-21 12:07:37 -04:00
|
|
|
switch(data.type) {
|
2014-03-24 14:12:59 -04:00
|
|
|
case 'local':
|
|
|
|
|
async.waterfall([
|
|
|
|
|
function(next) {
|
|
|
|
|
fs.readFile(path.join(nconf.get('themes_path'), data.id, 'theme.json'), function(err, config) {
|
|
|
|
|
if (!err) {
|
|
|
|
|
config = JSON.parse(config.toString());
|
|
|
|
|
next(null, config);
|
|
|
|
|
} else {
|
|
|
|
|
next(err);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
function(config, next) {
|
|
|
|
|
themeData['theme:staticDir'] = config.staticDir ? config.staticDir : '';
|
|
|
|
|
themeData['theme:templates'] = config.templates ? config.templates : '';
|
|
|
|
|
themeData['theme:src'] = config.frameworkCSS ? config.frameworkCSS : '';
|
2013-10-21 12:07:37 -04:00
|
|
|
|
2014-03-24 14:12:59 -04:00
|
|
|
db.setObject('config', themeData, next);
|
|
|
|
|
}
|
|
|
|
|
], callback);
|
|
|
|
|
break;
|
2013-10-21 12:07:37 -04:00
|
|
|
|
2014-03-24 14:12:59 -04:00
|
|
|
case 'bootswatch':
|
2014-03-29 14:37:44 -04:00
|
|
|
db.setObjectField('config', 'theme:src', data.src, callback);
|
2014-03-24 14:12:59 -04:00
|
|
|
break;
|
2013-10-21 12:07:37 -04:00
|
|
|
}
|
2013-07-17 16:17:19 -04:00
|
|
|
}
|
2013-09-24 12:33:51 -04:00
|
|
|
};
|
2013-07-24 15:19:26 -04:00
|
|
|
|
2013-08-11 16:12:20 -04:00
|
|
|
Meta.title = {
|
2014-01-27 12:19:25 -05:00
|
|
|
tests: {
|
|
|
|
|
isCategory: /^category\/\d+\/?/,
|
|
|
|
|
isTopic: /^topic\/\d+\/?/,
|
|
|
|
|
isUserPage: /^user\/[^\/]+(\/[\w]+)?/
|
|
|
|
|
},
|
2014-04-14 15:58:13 -04:00
|
|
|
build: function (urlFragment, language, callback) {
|
|
|
|
|
Meta.title.parseFragment(decodeURIComponent(urlFragment), language, function(err, title) {
|
2013-09-24 12:33:51 -04:00
|
|
|
if (err) {
|
2014-01-27 17:15:17 -05:00
|
|
|
title = Meta.config.browserTitle || 'NodeBB';
|
2013-09-24 12:33:51 -04:00
|
|
|
} else {
|
2014-01-27 17:15:17 -05:00
|
|
|
title = (title ? title + ' | ' : '') + (Meta.config.browserTitle || 'NodeBB');
|
2013-09-24 12:33:51 -04:00
|
|
|
}
|
2013-08-11 16:12:20 -04:00
|
|
|
|
2013-12-07 16:57:43 -05:00
|
|
|
callback(null, title);
|
2013-08-11 16:12:20 -04:00
|
|
|
});
|
|
|
|
|
},
|
2014-04-14 15:58:13 -04:00
|
|
|
parseFragment: function (urlFragment, language, callback) {
|
2014-01-27 11:38:34 -05:00
|
|
|
var translated = ['', 'recent', 'unread', 'users', 'notifications'];
|
|
|
|
|
if (translated.indexOf(urlFragment) !== -1) {
|
|
|
|
|
if (!urlFragment.length) {
|
|
|
|
|
urlFragment = 'home';
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-14 15:58:13 -04:00
|
|
|
translator.translate('[[pages:' + urlFragment + ']]', language, function(translated) {
|
2014-01-27 11:38:34 -05:00
|
|
|
callback(null, translated);
|
|
|
|
|
});
|
2014-01-27 12:19:25 -05:00
|
|
|
} else if (this.tests.isCategory.test(urlFragment)) {
|
2013-09-17 13:09:37 -04:00
|
|
|
var cid = urlFragment.match(/category\/(\d+)/)[1];
|
2013-07-24 15:19:26 -04:00
|
|
|
|
2013-09-24 12:33:51 -04:00
|
|
|
require('./categories').getCategoryField(cid, 'name', function (err, name) {
|
2013-08-11 16:12:20 -04:00
|
|
|
callback(null, name);
|
|
|
|
|
});
|
2014-01-27 12:19:25 -05:00
|
|
|
} else if (this.tests.isTopic.test(urlFragment)) {
|
2013-09-17 13:09:37 -04:00
|
|
|
var tid = urlFragment.match(/topic\/(\d+)/)[1];
|
2013-07-24 15:19:26 -04:00
|
|
|
|
2013-09-24 12:33:51 -04:00
|
|
|
require('./topics').getTopicField(tid, 'title', function (err, title) {
|
2013-08-11 16:12:20 -04:00
|
|
|
callback(null, title);
|
|
|
|
|
});
|
2014-01-27 12:19:25 -05:00
|
|
|
} else if (this.tests.isUserPage.test(urlFragment)) {
|
|
|
|
|
var matches = urlFragment.match(/user\/([^\/]+)\/?([\w]+)?/),
|
|
|
|
|
userslug = matches[1],
|
|
|
|
|
subpage = matches[2];
|
|
|
|
|
|
|
|
|
|
User.getUsernameByUserslug(userslug, function(err, username) {
|
|
|
|
|
if (subpage) {
|
2014-04-14 15:58:13 -04:00
|
|
|
translator.translate('[[pages:user.' + subpage + ', ' + username + ']]', language, function(translated) {
|
2014-01-27 12:19:25 -05:00
|
|
|
callback(null, translated);
|
2014-03-02 14:45:57 -05:00
|
|
|
});
|
2014-01-27 12:19:25 -05:00
|
|
|
} else {
|
|
|
|
|
callback(null, username);
|
|
|
|
|
}
|
|
|
|
|
});
|
2013-09-24 12:33:51 -04:00
|
|
|
} else {
|
|
|
|
|
callback(null);
|
|
|
|
|
}
|
2013-08-11 16:12:20 -04:00
|
|
|
}
|
2013-09-24 12:33:51 -04:00
|
|
|
};
|
2013-08-23 13:14:36 -04:00
|
|
|
|
2013-09-24 12:33:51 -04:00
|
|
|
Meta.js = {
|
2014-02-25 16:50:58 -05:00
|
|
|
cache: undefined,
|
2014-03-24 14:12:59 -04:00
|
|
|
prepared: false,
|
2013-09-24 12:33:51 -04:00
|
|
|
scripts: [
|
2013-09-24 13:01:18 -04:00
|
|
|
'vendor/jquery/js/jquery.js',
|
2014-01-19 17:17:40 -05:00
|
|
|
'vendor/jquery/js/jquery-ui-1.10.4.custom.js',
|
2014-03-11 19:31:23 -04:00
|
|
|
'vendor/jquery/timeago/jquery.timeago.min.js',
|
|
|
|
|
'vendor/jquery/js/jquery.form.min.js',
|
2013-09-24 13:01:18 -04:00
|
|
|
'vendor/bootstrap/js/bootstrap.min.js',
|
|
|
|
|
'vendor/requirejs/require.js',
|
|
|
|
|
'vendor/bootbox/bootbox.min.js',
|
2013-12-04 11:40:57 -05:00
|
|
|
'vendor/tinycon/tinycon.js',
|
2013-12-31 10:48:59 -05:00
|
|
|
'vendor/xregexp/xregexp.js',
|
|
|
|
|
'vendor/xregexp/unicode/unicode-base.js',
|
2014-04-08 17:35:03 -04:00
|
|
|
'src/utils.js',
|
2013-12-04 11:40:57 -05:00
|
|
|
'src/app.js',
|
2013-09-24 13:01:18 -04:00
|
|
|
'src/templates.js',
|
|
|
|
|
'src/ajaxify.js',
|
2014-03-28 14:18:42 -04:00
|
|
|
'src/variables.js',
|
|
|
|
|
'src/widgets.js',
|
2013-09-24 15:15:39 -04:00
|
|
|
'src/translator.js',
|
2014-03-28 17:49:58 -04:00
|
|
|
'src/helpers.js',
|
2014-04-08 17:35:03 -04:00
|
|
|
'src/overrides.js'
|
2013-09-24 12:33:51 -04:00
|
|
|
],
|
2014-03-08 16:04:22 -05:00
|
|
|
minFile: 'nodebb.min.js',
|
2014-03-24 14:12:59 -04:00
|
|
|
prepare: function (callback) {
|
2013-11-25 00:53:27 -05:00
|
|
|
plugins.fireHook('filter:scripts.get', this.scripts, function(err, scripts) {
|
2014-02-21 13:27:40 -05:00
|
|
|
var ctime,
|
2013-11-25 00:53:27 -05:00
|
|
|
jsPaths = scripts.map(function (jsPath) {
|
2014-02-11 10:57:51 -05:00
|
|
|
jsPath = path.normalize(jsPath);
|
|
|
|
|
|
2014-03-02 13:28:09 -05:00
|
|
|
// The filter:scripts.get plugin will be deprecated as of v0.5.0, specify scripts in plugin.json instead
|
2013-12-29 19:36:18 -05:00
|
|
|
if (jsPath.substring(0, 7) === 'plugins') {
|
2014-02-28 20:13:28 -05:00
|
|
|
var matches = _.map(plugins.staticDirs, function(realPath, mappedPath) {
|
|
|
|
|
if (jsPath.match(mappedPath)) {
|
|
|
|
|
return mappedPath;
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}).filter(function(a) { return a; });
|
2013-12-29 21:35:03 -05:00
|
|
|
|
2014-02-28 20:13:28 -05:00
|
|
|
if (matches.length) {
|
2014-03-24 14:12:59 -04:00
|
|
|
var relPath = jsPath.slice(('plugins/' + matches[0]).length),
|
2014-03-02 16:33:45 -05:00
|
|
|
pluginId = matches[0].split(path.sep)[0];
|
|
|
|
|
|
|
|
|
|
winston.warn('[meta.scripts.get (' + pluginId + ')] filter:scripts.get is deprecated, consider using "scripts" in plugin.json');
|
2014-02-28 20:13:28 -05:00
|
|
|
return plugins.staticDirs[matches[0]] + relPath;
|
2014-02-06 15:58:27 -05:00
|
|
|
} else {
|
2014-02-28 20:51:12 -05:00
|
|
|
winston.warn('[meta.scripts.get] Could not resolve mapped path: ' + jsPath + '. Are you sure it is defined by a plugin?');
|
2014-02-06 15:58:27 -05:00
|
|
|
return null;
|
|
|
|
|
}
|
2013-12-29 19:36:18 -05:00
|
|
|
} else {
|
2013-12-29 21:35:03 -05:00
|
|
|
return path.join(__dirname, '..', '/public', jsPath);
|
2013-12-29 19:36:18 -05:00
|
|
|
}
|
2013-11-25 00:53:27 -05:00
|
|
|
});
|
2013-09-24 12:33:51 -04:00
|
|
|
|
2014-03-02 13:28:09 -05:00
|
|
|
// Remove scripts that could not be found (remove this line at v0.5.0)
|
2014-03-02 14:45:57 -05:00
|
|
|
Meta.js.scripts = jsPaths.filter(function(path) {
|
|
|
|
|
return path !== null;
|
|
|
|
|
});
|
2013-12-29 19:36:18 -05:00
|
|
|
|
2014-03-02 13:28:09 -05:00
|
|
|
// Add plugin scripts
|
|
|
|
|
Meta.js.scripts = Meta.js.scripts.concat(plugins.clientScripts);
|
|
|
|
|
|
2014-03-24 14:12:59 -04:00
|
|
|
Meta.js.prepared = true;
|
|
|
|
|
callback();
|
2013-11-25 00:53:27 -05:00
|
|
|
});
|
2014-04-03 17:27:26 -04:00
|
|
|
},
|
|
|
|
|
minify: function(minify) {
|
|
|
|
|
// Prepare js for minification/concatenation
|
|
|
|
|
var minifier = fork('minifier.js');
|
|
|
|
|
|
|
|
|
|
minifier.on('message', function(payload) {
|
|
|
|
|
if (payload.action !== 'error') {
|
|
|
|
|
winston.info('[meta/js] Compilation complete');
|
|
|
|
|
Meta.js.cache = payload.data;
|
|
|
|
|
minifier.kill();
|
|
|
|
|
} else {
|
|
|
|
|
winston.error('[meta/js] Could not compile client-side scripts!');
|
|
|
|
|
winston.error('[meta/js] ' + payload.error.message);
|
|
|
|
|
minifier.kill();
|
|
|
|
|
process.exit();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.prepare(function() {
|
|
|
|
|
minifier.send({
|
|
|
|
|
action: minify ? 'js.minify' : 'js.concatenate',
|
|
|
|
|
scripts: Meta.js.scripts
|
|
|
|
|
});
|
|
|
|
|
});
|
2013-09-24 12:33:51 -04:00
|
|
|
}
|
|
|
|
|
};
|
2013-09-24 15:36:17 -04:00
|
|
|
|
2014-03-24 14:12:59 -04:00
|
|
|
/* Themes */
|
|
|
|
|
Meta.css = {};
|
|
|
|
|
Meta.css.cache = undefined;
|
|
|
|
|
Meta.css.minify = function() {
|
|
|
|
|
winston.info('[meta/css] Minifying LESS/CSS');
|
|
|
|
|
db.getObjectFields('config', ['theme:type', 'theme:id'], function(err, themeData) {
|
|
|
|
|
var themeId = (themeData['theme:id'] || 'nodebb-theme-vanilla'),
|
|
|
|
|
baseThemePath = path.join(nconf.get('themes_path'), (themeData['theme:type'] && themeData['theme:type'] === 'local' ? themeId : 'nodebb-theme-vanilla')),
|
|
|
|
|
paths = [
|
|
|
|
|
baseThemePath,
|
2014-03-24 15:35:58 -04:00
|
|
|
path.join(__dirname, '../node_modules'),
|
|
|
|
|
path.join(__dirname, '../public/vendor/fontawesome/less')
|
2014-03-24 14:12:59 -04:00
|
|
|
],
|
|
|
|
|
source = '@import "./theme";\n@import "font-awesome";',
|
|
|
|
|
x, numLESS, numCSS;
|
|
|
|
|
|
|
|
|
|
// Add the imports for each LESS file
|
|
|
|
|
for(x=0,numLESS=plugins.lessFiles.length;x<numLESS;x++) {
|
|
|
|
|
source += '\n@import "./' + plugins.lessFiles[x] + '";';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ... and for each CSS file
|
|
|
|
|
for(x=0,numCSS=plugins.cssFiles.length;x<numCSS;x++) {
|
|
|
|
|
source += '\n@import (inline) "./' + plugins.cssFiles[x] + '";';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parser = new (less.Parser)({
|
|
|
|
|
paths: paths
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
parser.parse(source, function(err, tree) {
|
|
|
|
|
if (err) {
|
|
|
|
|
winston.error('[meta/css] Could not minify LESS/CSS: ' + err.message);
|
|
|
|
|
process.exit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Meta.css.cache = tree.toCSS({
|
|
|
|
|
cleancss: true
|
|
|
|
|
});
|
|
|
|
|
winston.info('[meta/css] Done.');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2014-03-13 17:15:07 -04:00
|
|
|
/* Sounds */
|
|
|
|
|
Meta.sounds = {};
|
2014-04-12 18:33:52 -04:00
|
|
|
Meta.sounds.init = function() {
|
|
|
|
|
var soundsPath = path.join(__dirname, '../public/sounds');
|
|
|
|
|
|
|
|
|
|
plugins.fireHook('filter:sounds.get', [], function(err, filePaths) {
|
|
|
|
|
if (err) {
|
|
|
|
|
winston.error('Could not initialise sound files:' + err.message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clear the sounds directory
|
|
|
|
|
async.series([
|
|
|
|
|
function(next) {
|
|
|
|
|
rimraf(soundsPath, next);
|
|
|
|
|
},
|
|
|
|
|
function(next) {
|
|
|
|
|
mkdirp(soundsPath, next);
|
|
|
|
|
}
|
|
|
|
|
], function(err) {
|
|
|
|
|
if (err) {
|
|
|
|
|
winston.error('Could not initialise sound files:' + err.message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Link paths
|
|
|
|
|
async.each(filePaths, function(filePath, next) {
|
|
|
|
|
fs.symlink(filePath, path.join(soundsPath, path.basename(filePath)), 'file', next);
|
|
|
|
|
}, function(err) {
|
|
|
|
|
if (!err) {
|
|
|
|
|
winston.info('[sounds] Sounds OK');
|
|
|
|
|
} else {
|
|
|
|
|
winston.error('[sounds] Could not initialise sounds: ' + err.message);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Meta.sounds.getFiles = function(callback) {
|
2014-03-24 14:12:59 -04:00
|
|
|
// todo: Possibly move these into a bundled module?
|
2014-03-13 17:15:07 -04:00
|
|
|
fs.readdir(path.join(__dirname, '../public/sounds'), function(err, files) {
|
|
|
|
|
var localList = {};
|
|
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
|
winston.error('Could not get local sound files:' + err.message);
|
|
|
|
|
console.log(err.stack);
|
|
|
|
|
return callback(null, []);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return proper paths
|
|
|
|
|
files.forEach(function(filename) {
|
2014-03-24 20:24:06 -04:00
|
|
|
localList[filename] = nconf.get('relative_path') + '/sounds/' + filename;
|
2014-03-13 17:15:07 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
callback(null, localList);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Meta.sounds.getMapping = function(callback) {
|
2014-03-17 11:36:30 -04:00
|
|
|
db.getObject('settings:sounds', function(err, sounds) {
|
2014-03-13 17:15:07 -04:00
|
|
|
if (err || !sounds) {
|
|
|
|
|
// Send default sounds
|
|
|
|
|
var defaults = {
|
|
|
|
|
notification: 'notification.wav',
|
|
|
|
|
'chat-incoming': 'waterdrop-high.wav',
|
|
|
|
|
'chat-outgoing': 'waterdrop-low.wav'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return callback(null, defaults);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
callback.apply(null, arguments);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2014-03-14 00:34:51 -04:00
|
|
|
/* Settings */
|
|
|
|
|
Meta.settings = {};
|
2014-03-17 10:37:11 -04:00
|
|
|
Meta.settings.get = function(hash, callback) {
|
|
|
|
|
hash = 'settings:' + hash;
|
2014-03-29 17:58:41 -04:00
|
|
|
db.getObject(hash, function(err, settings) {
|
|
|
|
|
if (err) {
|
|
|
|
|
callback(err);
|
|
|
|
|
} else {
|
|
|
|
|
callback(null, settings || {});
|
|
|
|
|
}
|
|
|
|
|
});
|
2014-03-17 10:37:11 -04:00
|
|
|
};
|
|
|
|
|
|
2014-03-18 11:44:22 -04:00
|
|
|
Meta.settings.getOne = function(hash, field, callback) {
|
|
|
|
|
hash = 'settings:' + hash;
|
|
|
|
|
db.getObjectField(hash, field, callback);
|
|
|
|
|
};
|
|
|
|
|
|
2014-03-17 10:37:11 -04:00
|
|
|
Meta.settings.set = function(hash, values, callback) {
|
|
|
|
|
hash = 'settings:' + hash;
|
|
|
|
|
db.setObject(hash, values, callback);
|
|
|
|
|
};
|
2014-03-14 00:34:51 -04:00
|
|
|
|
2014-03-18 11:44:22 -04:00
|
|
|
Meta.settings.setOne = function(hash, field, value, callback) {
|
|
|
|
|
hash = 'settings:' + hash;
|
|
|
|
|
db.setObjectField(hash, field, value, callback);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Meta.settings.setOnEmpty = function (hash, field, value, callback) {
|
|
|
|
|
Meta.settings.getOne(hash, field, function (err, curValue) {
|
|
|
|
|
if (err) {
|
|
|
|
|
return callback(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!curValue) {
|
|
|
|
|
Meta.settings.setOne(hash, field, value, callback);
|
|
|
|
|
} else {
|
|
|
|
|
callback();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2014-03-13 17:15:07 -04:00
|
|
|
/* Assorted */
|
2014-02-22 03:11:13 -05:00
|
|
|
Meta.restart = function() {
|
|
|
|
|
if (process.send) {
|
2014-04-09 13:10:28 -04:00
|
|
|
process.send({
|
|
|
|
|
action: 'restart'
|
|
|
|
|
});
|
2014-02-22 03:11:13 -05:00
|
|
|
} else {
|
|
|
|
|
winston.error('[meta.restart] Could not restart, are you sure NodeBB was started with `./nodebb start`?');
|
|
|
|
|
}
|
|
|
|
|
};
|
2014-01-31 15:19:45 +02:00
|
|
|
}(exports));
|