mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-03 20:45:58 +01:00
Merge remote-tracking branch 'origin/master' into webserver.js-refactor
This commit is contained in:
2
nodebb
2
nodebb
@@ -56,7 +56,7 @@ case "$1" in
|
||||
echo "Launching NodeBB in \"development\" mode."
|
||||
echo "To run the production build of NodeBB, please use \"forever\"."
|
||||
echo "More Information: https://github.com/designcreateplay/NodeBB/wiki/How-to-run-NodeBB"
|
||||
NODE_ENV=development supervisor -q --extensions 'node|js|tpl' -- loader "$@"
|
||||
NODE_ENV=development supervisor -q --extensions 'node|js|tpl' -- app "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
|
||||
@@ -35,6 +35,17 @@ define(function() {
|
||||
$('.restart').on('click', function() {
|
||||
socket.emit('admin.restart');
|
||||
});
|
||||
|
||||
socket.emit('admin.getVisitorCount', function(err, data) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
var uniqueVisitors = $('#unique-visitors');
|
||||
for(var key in data) {
|
||||
uniqueVisitors.find('#' + key).text(data[key]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Admin.updateRoomUsage = function(err, data) {
|
||||
|
||||
@@ -141,16 +141,16 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
}
|
||||
loadingEl.remove();
|
||||
|
||||
categoriesEl.on('click', function(e) {
|
||||
var el = $(e.target);
|
||||
categoriesEl.on('click', 'li[data-cid]', function(e) {
|
||||
var el = $(this);
|
||||
if (el.is('li')) {
|
||||
confirmCat.html(e.target.innerHTML);
|
||||
confirmCat.html(el.html());
|
||||
confirmDiv.css({display: 'block'});
|
||||
targetCid = el.attr('data-cid');
|
||||
targetCatLabel = e.html();
|
||||
targetCatLabel = el.html();
|
||||
commitEl.prop('disabled', false);
|
||||
}
|
||||
}, false);
|
||||
});
|
||||
|
||||
commitEl.on('click', function() {
|
||||
if (!commitEl.prop('disabled') && targetCid) {
|
||||
@@ -322,11 +322,10 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
|
||||
localStorage.removeItem('topic:' + tid + ':bookmark');
|
||||
}
|
||||
});
|
||||
updateHeader();
|
||||
} else {
|
||||
updateHeader();
|
||||
}
|
||||
|
||||
updateHeader();
|
||||
|
||||
$('#post-container').on('mouseenter', '.favourite-tooltip', function(e) {
|
||||
if (!$(this).data('users-loaded')) {
|
||||
$(this).data('users-loaded', "true");
|
||||
|
||||
@@ -36,4 +36,29 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Unique Visitors</div>
|
||||
<div class="panel-body">
|
||||
<div id="unique-visitors">
|
||||
<div class="text-center pull-left">
|
||||
<div id="day"></div>
|
||||
<div>Day</div>
|
||||
</div>
|
||||
<div class="text-center pull-left">
|
||||
<div id="week"></div>
|
||||
<div>Week</div>
|
||||
</div>
|
||||
<div class="text-center pull-left">
|
||||
<div id="month"></div>
|
||||
<div>Month</div>
|
||||
</div>
|
||||
<div class="text-center pull-left">
|
||||
<div id="alltime"></div>
|
||||
<div>All Time</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
20
src/meta.js
20
src/meta.js
@@ -3,6 +3,7 @@ var fs = require('fs'),
|
||||
async = require('async'),
|
||||
winston = require('winston'),
|
||||
nconf = require('nconf'),
|
||||
_ = require('underscore'),
|
||||
|
||||
utils = require('./../public/src/utils'),
|
||||
translator = require('./../public/src/translator'),
|
||||
@@ -250,14 +251,19 @@ var fs = require('fs'),
|
||||
jsPath = path.normalize(jsPath);
|
||||
|
||||
if (jsPath.substring(0, 7) === 'plugins') {
|
||||
var paths = jsPath.split(path.sep),
|
||||
mappedPath = paths[1];
|
||||
|
||||
if (plugins.staticDirs[mappedPath]) {
|
||||
jsPath = jsPath.replace(path.join('plugins', mappedPath), '');
|
||||
return path.join(plugins.staticDirs[mappedPath], jsPath);
|
||||
var matches = _.map(plugins.staticDirs, function(realPath, mappedPath) {
|
||||
if (jsPath.match(mappedPath)) {
|
||||
return mappedPath;
|
||||
} else {
|
||||
winston.warn('[meta.scripts.get] Could not resolve mapped path: ' + mappedPath + '. Are you sure it is defined by a plugin?');
|
||||
return null;
|
||||
}
|
||||
}).filter(function(a) { return a; });
|
||||
|
||||
if (matches.length) {
|
||||
var relPath = jsPath.slice(new String('plugins/' + matches[0]).length);
|
||||
return plugins.staticDirs[matches[0]] + relPath;
|
||||
} else {
|
||||
winston.warn('[meta.scripts.get] Could not resolve mapped path: ' + jsPath + '. Are you sure it is defined by a plugin?');
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -246,24 +246,31 @@ var fs = require('fs'),
|
||||
`data.priority`, the relative priority of the method when it is eventually called (default: 10)
|
||||
*/
|
||||
|
||||
if (data.hook && data.method) {
|
||||
var method;
|
||||
|
||||
if (data.hook && data.method && typeof data.method === 'string' && data.method.length > 0) {
|
||||
data.id = id;
|
||||
if (!data.priority) data.priority = 10;
|
||||
data.method = data.method.split('.').reduce(function(memo, prop) {
|
||||
if (memo[prop]) {
|
||||
method = data.method.split('.').reduce(function(memo, prop) {
|
||||
if (memo !== null && memo[prop]) {
|
||||
return memo[prop];
|
||||
} else {
|
||||
// Couldn't find method by path, assuming property with periods in it (evil!)
|
||||
Plugins.libraries[data.id][data.method];
|
||||
// Couldn't find method by path, aborting
|
||||
return null;
|
||||
}
|
||||
}, Plugins.libraries[data.id]);
|
||||
|
||||
if (method === null) {
|
||||
winston.warn('[plugins/' + id + '] Hook method mismatch: ' + data.hook + ' => ' + data.method);
|
||||
return callback();
|
||||
}
|
||||
|
||||
// Write the actual method reference to the hookObj
|
||||
data.method = method;
|
||||
|
||||
Plugins.loadedHooks[data.hook] = Plugins.loadedHooks[data.hook] || [];
|
||||
Plugins.loadedHooks[data.hook].push(data);
|
||||
|
||||
if (global.env === 'development') {
|
||||
winston.info('[plugins] Hook registered: ' + data.hook + ' will call ' + id);
|
||||
}
|
||||
callback();
|
||||
} else return;
|
||||
};
|
||||
|
||||
@@ -90,9 +90,7 @@ var winston = require('winston'),
|
||||
|
||||
topics.setTopicField(tid, 'thumb', options.topic_thumb);
|
||||
|
||||
db.searchRemove('topic', tid, function() {
|
||||
db.searchIndex('topic', title, tid);
|
||||
});
|
||||
plugins.fireHook('action:topic.edit', tid);
|
||||
}
|
||||
|
||||
posts.getPostData(pid, function(err, postData) {
|
||||
|
||||
@@ -92,10 +92,10 @@ var db = require('./database'),
|
||||
return next(err);
|
||||
}
|
||||
|
||||
postData.content = content;
|
||||
|
||||
plugins.fireHook('action:post.save', postData);
|
||||
|
||||
postData.content = content;
|
||||
|
||||
next(null, postData);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ var path = require('path'),
|
||||
user.updateLastOnlineTime(req.user.uid);
|
||||
}
|
||||
|
||||
db.sortedSetAdd('ip:recent', Date.now(), req.ip || 'Unknown');
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
@@ -222,15 +224,13 @@ var path = require('path'),
|
||||
return res.redirect('/404');
|
||||
}
|
||||
|
||||
var limit = 50;
|
||||
|
||||
function searchPosts(callback) {
|
||||
Plugins.fireHook('filter:search.query', {
|
||||
index: 'post',
|
||||
query: req.params.terms
|
||||
query: req.params.term
|
||||
}, function(err, pids) {
|
||||
if (err) {
|
||||
return callback(err, null);
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
posts.getPostSummaryByPids(pids, false, callback);
|
||||
@@ -240,10 +240,10 @@ var path = require('path'),
|
||||
function searchTopics(callback) {
|
||||
Plugins.fireHook('filter:search.query', {
|
||||
index: 'topic',
|
||||
query: req.params.terms
|
||||
query: req.params.term
|
||||
}, function(err, tids) {
|
||||
if (err) {
|
||||
return callback(err, null);
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
topics.getTopicsByTids(tids, 0, callback);
|
||||
|
||||
@@ -44,7 +44,7 @@ var nconf = require('nconf'),
|
||||
|
||||
if (matches) {
|
||||
async.map(matches, function(mappedPath, next) {
|
||||
var filePath = path.join(plugins.staticDirs[mappedPath], relPath.slice(mappedPath.length));
|
||||
var filePath = path.join(plugins.staticDirs[mappedPath], decodeURIComponent(relPath.slice(mappedPath.length)));
|
||||
|
||||
fs.exists(filePath, function(exists) {
|
||||
if (exists) {
|
||||
|
||||
@@ -9,6 +9,7 @@ var groups = require('../groups'),
|
||||
categories = require('../categories'),
|
||||
CategoryTools = require('../categoryTools'),
|
||||
logger = require('../logger'),
|
||||
db = require('../database'),
|
||||
admin = {
|
||||
user: require('../admin/user'),
|
||||
categories: require('../admin/categories')
|
||||
@@ -35,6 +36,30 @@ SocketAdmin.restart = function(socket, data, callback) {
|
||||
meta.restart();
|
||||
};
|
||||
|
||||
|
||||
SocketAdmin.getVisitorCount = function(socket, data, callback) {
|
||||
var terms = {
|
||||
day: 86400000,
|
||||
week: 604800000,
|
||||
month: 2592000000
|
||||
};
|
||||
var now = Date.now();
|
||||
async.parallel({
|
||||
day: function(next) {
|
||||
db.sortedSetCount('ip:recent', now - terms.day, now, next);
|
||||
},
|
||||
week: function(next) {
|
||||
db.sortedSetCount('ip:recent', now - terms.week, now, next);
|
||||
},
|
||||
month: function(next) {
|
||||
db.sortedSetCount('ip:recent', now - terms.month, now, next);
|
||||
},
|
||||
alltime: function(next) {
|
||||
db.sortedSetCount('ip:recent', 0, now, next);
|
||||
}
|
||||
}, callback);
|
||||
}
|
||||
|
||||
/* Topics */
|
||||
|
||||
SocketAdmin.topics = {};
|
||||
|
||||
@@ -392,9 +392,6 @@ process.on('uncaughtException', function(err) {
|
||||
// Disable framing
|
||||
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
|
||||
|
||||
// Log IP address
|
||||
db.sortedSetAdd('ip:recent', +new Date(), req.ip || 'Unknown');
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user