|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var async = require('async'),
|
|
|
|
|
|
|
|
db = require('./database'),
|
|
|
|
batch = require('./batch'),
|
|
|
|
user = require('./user'),
|
|
|
|
utils = require('../public/src/utils');
|
|
|
|
|
|
|
|
|
|
|
|
(function(events) {
|
|
|
|
events.log = function(data, callback) {
|
|
|
|
callback = callback || function() {};
|
|
|
|
|
|
|
|
async.waterfall([
|
|
|
|
function(next) {
|
|
|
|
db.incrObjectField('global', 'nextEid', next);
|
|
|
|
},
|
|
|
|
function(eid, next) {
|
|
|
|
data.timestamp = Date.now();
|
|
|
|
data.eid = eid;
|
|
|
|
|
|
|
|
async.parallel([
|
|
|
|
function(next) {
|
|
|
|
db.sortedSetAdd('events:time', data.timestamp, eid, next);
|
|
|
|
},
|
|
|
|
function(next) {
|
|
|
|
db.setObject('event:' + eid, data, next);
|
|
|
|
}
|
|
|
|
], next);
|
|
|
|
}
|
|
|
|
], function(err, result) {
|
|
|
|
callback(err);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
events.getEvents = function(start, stop, callback) {
|
|
|
|
async.waterfall([
|
|
|
|
function(next) {
|
|
|
|
db.getSortedSetRevRange('events:time', start, stop, next);
|
|
|
|
},
|
|
|
|
function(eids, next) {
|
|
|
|
var keys = eids.map(function(eid) {
|
|
|
|
return 'event:' + eid;
|
|
|
|
});
|
|
|
|
db.getObjects(keys, next);
|
|
|
|
},
|
|
|
|
function(eventsData, next) {
|
|
|
|
eventsData.forEach(function(event) {
|
|
|
|
var e = utils.merge(event);
|
|
|
|
e.eid = e.uid = e.type = e.ip = undefined;
|
|
|
|
event.jsonString = JSON.stringify(e, null, 4);
|
|
|
|
event.timestampISO = new Date(parseInt(event.timestamp, 10)).toUTCString();
|
|
|
|
});
|
|
|
|
addUserData(eventsData, 'uid', 'user', next);
|
|
|
|
},
|
|
|
|
function(eventsData, next) {
|
|
|
|
addUserData(eventsData, 'targetUid', 'targetUser', next);
|
|
|
|
}
|
|
|
|
], callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
function addUserData(eventsData, field, objectName, callback) {
|
|
|
|
var uids = eventsData.map(function(event) {
|
|
|
|
return event && event[field];
|
|
|
|
}).filter(function(uid, index, array) {
|
|
|
|
return uid && array.indexOf(uid) === index;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!uids.length) {
|
|
|
|
return callback(null, eventsData);
|
|
|
|
}
|
|
|
|
|
|
|
|
async.parallel({
|
|
|
|
isAdmin: function(next) {
|
|
|
|
user.isAdministrator(uids, next);
|
|
|
|
},
|
|
|
|
userData: function(next) {
|
|
|
|
user.getMultipleUserFields(uids, ['username', 'userslug', 'picture'], next);
|
|
|
|
}
|
|
|
|
}, function(err, results) {
|
|
|
|
if (err) {
|
|
|
|
return callback(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
var userData = results.userData;
|
|
|
|
|
|
|
|
var map = {};
|
|
|
|
userData.forEach(function(user, index) {
|
|
|
|
user.isAdmin = results.isAdmin[index];
|
|
|
|
map[user.uid] = user;
|
|
|
|
});
|
|
|
|
|
|
|
|
eventsData.forEach(function(event) {
|
|
|
|
if (map[event[field]]) {
|
|
|
|
event[objectName] = map[event[field]];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
callback(null, eventsData);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
events.deleteEvents = function(eids, callback) {
|
|
|
|
callback = callback || function() {};
|
|
|
|
async.parallel([
|
|
|
|
function(next) {
|
|
|
|
var keys = eids.map(function(eid) {
|
|
|
|
return 'event:' + eid;
|
|
|
|
});
|
|
|
|
db.deleteAll(keys, next);
|
|
|
|
},
|
|
|
|
function(next) {
|
|
|
|
db.sortedSetRemove('events:time', eids, next);
|
|
|
|
}
|
|
|
|
], callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
events.deleteAll = function(callback) {
|
|
|
|
callback = callback || function() {};
|
|
|
|
|
|
|
|
batch.processSortedSet('events:time', function(eids, next) {
|
|
|
|
events.deleteEvents(eids, callback);
|
|
|
|
}, {alwaysStartAt: 0}, callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}(module.exports));
|