mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-01-29 10:49:51 +01:00
Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
@@ -28,18 +28,27 @@ module.exports = function (Meta) {
|
||||
}, {
|
||||
property: 'og:site_name',
|
||||
content: Meta.config.title || 'NodeBB'
|
||||
}, {
|
||||
name: 'keywords',
|
||||
content: Meta.config.keywords || ''
|
||||
}, {
|
||||
name: 'msapplication-badge',
|
||||
content: 'frequency=30; polling-uri=' + nconf.get('url') + '/sitemap.xml',
|
||||
noEscape: true
|
||||
}, {
|
||||
name: 'msapplication-square150x150logo',
|
||||
content: Meta.config['brand:logo'] || '',
|
||||
noEscape: true
|
||||
}];
|
||||
|
||||
if (Meta.config.keywords) {
|
||||
defaultTags.push({
|
||||
name: 'keywords',
|
||||
content: Meta.config.keywords
|
||||
});
|
||||
}
|
||||
|
||||
if (Meta.config['brand:logo']) {
|
||||
defaultTags.push({
|
||||
name: 'msapplication-square150x150logo',
|
||||
content: Meta.config['brand:logo'],
|
||||
noEscape: true
|
||||
});
|
||||
}
|
||||
|
||||
plugins.fireHook('filter:meta.getMetaTags', defaultTags, next);
|
||||
},
|
||||
links: function (next) {
|
||||
|
||||
@@ -78,14 +78,17 @@ module.exports = function (middleware) {
|
||||
function (results, next) {
|
||||
var str = results.header +
|
||||
(res.locals.postHeader || '') +
|
||||
results.content +
|
||||
results.content + '<script id="ajaxify-data"></script>' +
|
||||
(res.locals.preFooter || '') +
|
||||
results.footer;
|
||||
|
||||
translate(str, req, res, next);
|
||||
},
|
||||
function (translated, next) {
|
||||
next(null, translated + '<script id="ajaxify-data" type="application/json">' + ajaxifyData + '</script>');
|
||||
translated = translated.replace('<script id="ajaxify-data"></script>', function () {
|
||||
return '<script id="ajaxify-data" type="application/json">' + ajaxifyData + '</script>';
|
||||
});
|
||||
next(null, translated);
|
||||
}
|
||||
], fn);
|
||||
};
|
||||
|
||||
69
src/reset.js
69
src/reset.js
@@ -12,20 +12,32 @@ Reset.reset = function (callback) {
|
||||
db.init(function (err) {
|
||||
if (err) {
|
||||
winston.error(err.message);
|
||||
process.exit();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (nconf.get('t')) {
|
||||
if(nconf.get('t') === true) {
|
||||
var themeId = nconf.get('t');
|
||||
if (themeId === true) {
|
||||
resetThemes(callback);
|
||||
} else {
|
||||
resetTheme(nconf.get('t'), callback);
|
||||
if (themeId.indexOf('nodebb-') !== 0) {
|
||||
// Allow omission of `nodebb-theme-`
|
||||
themeId = 'nodebb-theme-' + themeId;
|
||||
}
|
||||
|
||||
resetTheme(themeId, callback);
|
||||
}
|
||||
} else if (nconf.get('p')) {
|
||||
if (nconf.get('p') === true) {
|
||||
var pluginId = nconf.get('p');
|
||||
if (pluginId === true) {
|
||||
resetPlugins(callback);
|
||||
} else {
|
||||
resetPlugin(nconf.get('p'), callback);
|
||||
if (pluginId.indexOf('nodebb-') !== 0) {
|
||||
// Allow omission of `nodebb-plugin-`
|
||||
pluginId = 'nodebb-plugin-' + pluginId;
|
||||
}
|
||||
|
||||
resetPlugin(pluginId, callback);
|
||||
}
|
||||
} else if (nconf.get('w')) {
|
||||
resetWidgets(callback);
|
||||
@@ -39,11 +51,7 @@ Reset.reset = function (callback) {
|
||||
winston.error('[reset] Errors were encountered while resetting your forum settings: %s', err.message);
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
} else {
|
||||
process.stdout.write('\nNodeBB Reset\n'.bold);
|
||||
@@ -58,7 +66,7 @@ Reset.reset = function (callback) {
|
||||
process.stdout.write('\nPlugin and theme reset flags (-p & -t) can take a single argument\n');
|
||||
process.stdout.write(' e.g. ./nodebb reset -p nodebb-plugin-mentions, ./nodebb reset -t nodebb-theme-persona\n');
|
||||
|
||||
process.exit();
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -67,11 +75,7 @@ function resetSettings(callback) {
|
||||
var meta = require('./meta');
|
||||
meta.configs.set('allowLocalLogin', 1, function (err) {
|
||||
winston.info('[reset] Settings reset to default');
|
||||
if (typeof callback === 'function') {
|
||||
callback(err);
|
||||
} else {
|
||||
process.exit();
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -82,7 +86,7 @@ function resetTheme(themeId, callback) {
|
||||
fs.access('node_modules/' + themeId + '/package.json', function (err, fd) {
|
||||
if (err) {
|
||||
winston.warn('[reset] Theme `%s` is not installed on this forum', themeId);
|
||||
process.exit();
|
||||
callback(new Error('theme-not-found'));
|
||||
} else {
|
||||
meta.themes.set({
|
||||
type: 'local',
|
||||
@@ -94,11 +98,7 @@ function resetTheme(themeId, callback) {
|
||||
winston.info('[reset] Theme reset to ' + themeId);
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -112,11 +112,7 @@ function resetThemes(callback) {
|
||||
id: 'nodebb-theme-persona'
|
||||
}, function (err) {
|
||||
winston.info('[reset] Theme reset to Persona');
|
||||
if (typeof callback === 'function') {
|
||||
callback(err);
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,36 +139,25 @@ function resetPlugin(pluginId, callback) {
|
||||
} else {
|
||||
winston.warn('[reset] Plugin `%s` was not active on this forum', pluginId);
|
||||
winston.info('[reset] No action taken.');
|
||||
err = new Error('plugin-not-active');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
function resetPlugins(callback) {
|
||||
db.delete('plugins:active', function (err) {
|
||||
winston.info('[reset] All Plugins De-activated');
|
||||
if (typeof callback === 'function') {
|
||||
callback(err);
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
function resetWidgets(callback) {
|
||||
require('./widgets').reset(function (err) {
|
||||
winston.info('[reset] All Widgets moved to Draft Zone');
|
||||
if (typeof callback === 'function') {
|
||||
callback(err);
|
||||
} else {
|
||||
process.exit();
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
var rewards = {},
|
||||
async = require('async'),
|
||||
plugins = require('../plugins'),
|
||||
db = require('../database');
|
||||
var async = require('async');
|
||||
var plugins = require('../plugins');
|
||||
var db = require('../database');
|
||||
|
||||
var rewards = module.exports;
|
||||
|
||||
rewards.save = function (data, callback) {
|
||||
function save(data, next) {
|
||||
function commit(err, id) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
data.id = id;
|
||||
|
||||
async.series([
|
||||
function (next) {
|
||||
rewards.delete(data, next);
|
||||
},
|
||||
function (next) {
|
||||
db.setAdd('rewards:list', data.id, next);
|
||||
},
|
||||
function (next) {
|
||||
db.setObject('rewards:id:' + data.id, data, next);
|
||||
},
|
||||
function (next) {
|
||||
db.setObject('rewards:id:' + data.id + ':rewards', rewardsData, next);
|
||||
}
|
||||
], next);
|
||||
}
|
||||
async.each(data, function save(data, next) {
|
||||
|
||||
if (!Object.keys(data.rewards).length) {
|
||||
return next();
|
||||
@@ -38,14 +17,36 @@ rewards.save = function (data, callback) {
|
||||
var rewardsData = data.rewards;
|
||||
delete data.rewards;
|
||||
|
||||
if (!parseInt(data.id, 10)) {
|
||||
db.incrObjectField('global', 'rewards:id', commit);
|
||||
} else {
|
||||
commit(false, data.id);
|
||||
}
|
||||
}
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
if (!parseInt(data.id, 10)) {
|
||||
db.incrObjectField('global', 'rewards:id', next);
|
||||
} else {
|
||||
next(null, data.id);
|
||||
}
|
||||
},
|
||||
function (rid, next) {
|
||||
|
||||
async.each(data, save, function (err) {
|
||||
data.id = rid;
|
||||
|
||||
async.series([
|
||||
function (next) {
|
||||
rewards.delete(data, next);
|
||||
},
|
||||
function (next) {
|
||||
db.setAdd('rewards:list', data.id, next);
|
||||
},
|
||||
function (next) {
|
||||
db.setObject('rewards:id:' + data.id, data, next);
|
||||
},
|
||||
function (next) {
|
||||
db.setObject('rewards:id:' + data.id + ':rewards', rewardsData, next);
|
||||
}
|
||||
], next);
|
||||
}
|
||||
], next);
|
||||
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
@@ -84,25 +85,29 @@ rewards.get = function (callback) {
|
||||
};
|
||||
|
||||
function saveConditions(data, callback) {
|
||||
db.delete('conditions:active', function (err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
var rewardsPerCondition = {};
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.delete('conditions:active', next);
|
||||
},
|
||||
function (next) {
|
||||
var conditions = [];
|
||||
|
||||
data.forEach(function (reward) {
|
||||
conditions.push(reward.condition);
|
||||
rewardsPerCondition[reward.condition] = rewardsPerCondition[reward.condition] || [];
|
||||
rewardsPerCondition[reward.condition].push(reward.id);
|
||||
});
|
||||
|
||||
db.setAdd('conditions:active', conditions, next);
|
||||
},
|
||||
function (next) {
|
||||
async.each(Object.keys(rewardsPerCondition), function (condition, next) {
|
||||
db.setAdd('condition:' + condition + ':rewards', rewardsPerCondition[condition], next);
|
||||
}, next);
|
||||
}
|
||||
|
||||
var conditions = [],
|
||||
rewardsPerCondition = {};
|
||||
|
||||
data.forEach(function (reward) {
|
||||
conditions.push(reward.condition);
|
||||
rewardsPerCondition[reward.condition] = rewardsPerCondition[reward.condition] || [];
|
||||
rewardsPerCondition[reward.condition].push(reward.id);
|
||||
});
|
||||
|
||||
db.setAdd('conditions:active', conditions, callback);
|
||||
|
||||
async.each(Object.keys(rewardsPerCondition), function (condition, next) {
|
||||
db.setAdd('condition:' + condition + ':rewards', rewardsPerCondition[condition], next);
|
||||
}, callback);
|
||||
], function (err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -138,5 +143,3 @@ function getActiveRewards(callback) {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = rewards;
|
||||
|
||||
@@ -1,40 +1,36 @@
|
||||
"use strict";
|
||||
|
||||
var rewards = {},
|
||||
db = require('../database'),
|
||||
plugins = require('../plugins'),
|
||||
async = require('async');
|
||||
|
||||
var db = require('../database');
|
||||
var plugins = require('../plugins');
|
||||
var async = require('async');
|
||||
|
||||
var rewards = module.exports;
|
||||
|
||||
rewards.checkConditionAndRewardUser = function (uid, condition, method, callback) {
|
||||
callback = callback || function () {};
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
isConditionActive(condition, function (err, isActive) {
|
||||
if (!isActive) {
|
||||
return back(err);
|
||||
}
|
||||
|
||||
next(err);
|
||||
});
|
||||
isConditionActive(condition, next);
|
||||
},
|
||||
function (next) {
|
||||
getIDsByCondition(condition, function (err, ids) {
|
||||
next(err, ids);
|
||||
});
|
||||
function (isActive, next) {
|
||||
if (!isActive) {
|
||||
return callback();
|
||||
}
|
||||
getIDsByCondition(condition, next);
|
||||
},
|
||||
function (ids, next) {
|
||||
getRewardDataByIDs(ids, next);
|
||||
},
|
||||
function (rewards, next) {
|
||||
filterCompletedRewards(uid, rewards, function (err, filtered) {
|
||||
if (!filtered || !filtered.length) {
|
||||
return back(err);
|
||||
}
|
||||
|
||||
next(err, filtered);
|
||||
});
|
||||
filterCompletedRewards(uid, rewards, next);
|
||||
},
|
||||
function (rewards, next) {
|
||||
if (!rewards || !rewards.length) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
async.filter(rewards, function (reward, next) {
|
||||
if (!reward) {
|
||||
return next(null, false);
|
||||
@@ -51,14 +47,7 @@ rewards.checkConditionAndRewardUser = function (uid, condition, method, callback
|
||||
giveRewards(uid, eligible, next);
|
||||
});
|
||||
}
|
||||
], back);
|
||||
|
||||
|
||||
function back(err) {
|
||||
if (typeof callback === 'function') {
|
||||
callback(err);
|
||||
}
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
function isConditionActive(condition, callback) {
|
||||
@@ -88,14 +77,10 @@ function filterCompletedRewards(uid, rewards, callback) {
|
||||
|
||||
var claimable = parseInt(reward.claimable, 10);
|
||||
|
||||
if (claimable === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (userRewards[reward.id] >= reward.claimable) ? false : true;
|
||||
return claimable === 0 || (userRewards[reward.id] < reward.claimable);
|
||||
});
|
||||
|
||||
callback(false, rewards);
|
||||
callback(null, rewards);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -135,6 +120,3 @@ function giveRewards(uid, rewards, callback) {
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = rewards;
|
||||
@@ -3,6 +3,7 @@
|
||||
var async = require('async');
|
||||
var rss = require('rss');
|
||||
var nconf = require('nconf');
|
||||
var validator = require('validator');
|
||||
|
||||
var posts = require('../posts');
|
||||
var topics = require('../topics');
|
||||
@@ -12,6 +13,18 @@ var meta = require('../meta');
|
||||
var helpers = require('../controllers/helpers');
|
||||
var privileges = require('../privileges');
|
||||
|
||||
module.exports = function (app, middleware, controllers) {
|
||||
app.get('/topic/:topic_id.rss', middleware.maintenanceMode, generateForTopic);
|
||||
app.get('/category/:category_id.rss', middleware.maintenanceMode, generateForCategory);
|
||||
app.get('/recent.rss', middleware.maintenanceMode, generateForRecent);
|
||||
app.get('/popular.rss', middleware.maintenanceMode, generateForPopular);
|
||||
app.get('/popular/:term.rss', middleware.maintenanceMode, generateForPopular);
|
||||
app.get('/recentposts.rss', middleware.maintenanceMode, generateForRecentPosts);
|
||||
app.get('/category/:category_id/recentposts.rss', middleware.maintenanceMode, generateForCategoryRecentPosts);
|
||||
app.get('/user/:userslug/topics.rss', middleware.maintenanceMode, generateForUserTopics);
|
||||
app.get('/tags/:tag.rss', middleware.maintenanceMode, generateForTag);
|
||||
};
|
||||
|
||||
|
||||
function generateForTopic(req, res, callback) {
|
||||
if (parseInt(meta.config['feeds:disableRSS'], 10) === 1) {
|
||||
@@ -56,15 +69,15 @@ function generateForTopic(req, res, callback) {
|
||||
var author = topicData.posts.length ? topicData.posts[0].username : '';
|
||||
|
||||
var feed = new rss({
|
||||
title: topicData.title,
|
||||
description: description,
|
||||
feed_url: nconf.get('url') + '/topic/' + tid + '.rss',
|
||||
site_url: nconf.get('url') + '/topic/' + topicData.slug,
|
||||
image_url: image_url,
|
||||
author: author,
|
||||
ttl: 60
|
||||
}),
|
||||
dateStamp;
|
||||
title: topicData.title,
|
||||
description: description,
|
||||
feed_url: nconf.get('url') + '/topic/' + tid + '.rss',
|
||||
site_url: nconf.get('url') + '/topic/' + topicData.slug,
|
||||
image_url: image_url,
|
||||
author: author,
|
||||
ttl: 60
|
||||
});
|
||||
var dateStamp;
|
||||
|
||||
if (topicData.posts.length > 0) {
|
||||
feed.pubDate = new Date(parseInt(topicData.posts[0].timestamp, 10)).toUTCString();
|
||||
@@ -189,38 +202,42 @@ function generateForPopular(req, res, next) {
|
||||
};
|
||||
var term = terms[req.params.term] || 'day';
|
||||
|
||||
topics.getPopular(term, req.uid, 19, function (err, topics) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
topics.getPopular(term, req.uid, 19, next);
|
||||
},
|
||||
function (topics, next) {
|
||||
generateTopicsFeed({
|
||||
uid: req.uid,
|
||||
title: 'Popular Topics',
|
||||
description: 'A list of topics that are sorted by post count',
|
||||
feed_url: '/popular/' + (req.params.term || 'daily') + '.rss',
|
||||
site_url: '/popular/' + (req.params.term || 'daily')
|
||||
}, topics, next);
|
||||
}
|
||||
], function (err, feed) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
generateTopicsFeed({
|
||||
uid: req.uid,
|
||||
title: 'Popular Topics',
|
||||
description: 'A list of topics that are sorted by post count',
|
||||
feed_url: '/popular/' + (req.params.term || 'daily') + '.rss',
|
||||
site_url: '/popular/' + (req.params.term || 'daily')
|
||||
}, topics, function (err, feed) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
sendFeed(feed, res);
|
||||
});
|
||||
sendFeed(feed, res);
|
||||
});
|
||||
}
|
||||
|
||||
function generateForTopics(options, set, req, res, next) {
|
||||
topics.getTopicsFromSet(set, req.uid, 0, 19, function (err, data) {
|
||||
var start = options.hasOwnProperty('start') ? options.start : 0;
|
||||
var stop = options.hasOwnProperty('stop') ? options.stop : 19;
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
topics.getTopicsFromSet(set, req.uid, start, stop, next);
|
||||
},
|
||||
function (data, next) {
|
||||
generateTopicsFeed(options, data.topics, next);
|
||||
}
|
||||
], function (err, feed) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
generateTopicsFeed(options, data.topics, function (err, feed) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
sendFeed(feed, res);
|
||||
});
|
||||
sendFeed(feed, res);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -359,18 +376,29 @@ function generateForPostsFeed(feedOptions, posts) {
|
||||
return feed;
|
||||
}
|
||||
|
||||
function generateForTag(req, res, next) {
|
||||
if (parseInt(meta.config['feeds:disableRSS'], 10) === 1) {
|
||||
return next();
|
||||
}
|
||||
var tag = validator.escape(String(req.params.tag));
|
||||
var page = parseInt(req.query.page, 10) || 1;
|
||||
var topicsPerPage = meta.config.topicsPerPage || 20;
|
||||
var start = Math.max(0, (page - 1) * topicsPerPage);
|
||||
var stop = start + topicsPerPage - 1;
|
||||
generateForTopics({
|
||||
uid: req.uid,
|
||||
title: 'Topics tagged with ' + tag,
|
||||
description: 'A list of topics that have been tagged with ' + tag,
|
||||
feed_url: '/tags/' + tag + '.rss',
|
||||
site_url: '/tags/' + tag,
|
||||
start: start,
|
||||
stop: stop
|
||||
}, 'tag:' + tag + ':topics', req, res, next);
|
||||
}
|
||||
|
||||
function sendFeed(feed, res) {
|
||||
var xml = feed.xml();
|
||||
res.type('xml').set('Content-Length', Buffer.byteLength(xml)).send(xml);
|
||||
}
|
||||
|
||||
module.exports = function (app, middleware, controllers) {
|
||||
app.get('/topic/:topic_id.rss', middleware.maintenanceMode, generateForTopic);
|
||||
app.get('/category/:category_id.rss', middleware.maintenanceMode, generateForCategory);
|
||||
app.get('/recent.rss', middleware.maintenanceMode, generateForRecent);
|
||||
app.get('/popular.rss', middleware.maintenanceMode, generateForPopular);
|
||||
app.get('/popular/:term.rss', middleware.maintenanceMode, generateForPopular);
|
||||
app.get('/recentposts.rss', middleware.maintenanceMode, generateForRecentPosts);
|
||||
app.get('/category/:category_id/recentposts.rss', middleware.maintenanceMode, generateForCategoryRecentPosts);
|
||||
app.get('/user/:userslug/topics.rss', middleware.maintenanceMode, generateForUserTopics);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var rewardsAdmin = require('../../rewards/admin'),
|
||||
SocketRewards = {};
|
||||
var rewardsAdmin = require('../../rewards/admin');
|
||||
var SocketRewards = module.exports;
|
||||
|
||||
SocketRewards.save = function (socket, data, callback) {
|
||||
rewardsAdmin.save(data, callback);
|
||||
@@ -11,5 +11,3 @@ SocketRewards.delete = function (socket, data, callback) {
|
||||
rewardsAdmin.delete(data, callback);
|
||||
};
|
||||
|
||||
|
||||
module.exports = SocketRewards;
|
||||
@@ -32,6 +32,7 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
<button class="btn btn-primary upload-btn">[[user:upload_picture]]</button>
|
||||
<button class="btn btn-primary crop-btn">[[user:upload_cropped_picture]]</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user