From 32b191fa62e60830700dcd738ecff57a892ca792 Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Tue, 26 Nov 2013 19:09:32 -0500 Subject: [PATCH] removed global.io --- public/src/forum/account.js | 1 + public/src/forum/footer.js | 2 +- src/categories.js | 8 +- src/favourites.js | 13 +- src/notifications.js | 433 ++++++++++++++++++------------------ src/postTools.js | 13 +- src/posts.js | 24 +- src/threadTools.js | 17 +- src/topics.js | 8 +- src/websockets.js | 50 +++-- 10 files changed, 289 insertions(+), 280 deletions(-) diff --git a/public/src/forum/account.js b/public/src/forum/account.js index 8ecafda399..5056c2a26e 100644 --- a/public/src/forum/account.js +++ b/public/src/forum/account.js @@ -72,6 +72,7 @@ define(['forum/accountheader'], function(header) { socket.on('event:new_post', function(data) { var html = templates.prepare(templates['account'].blocks['posts']).parse(data); $('.user-recent-posts').prepend(html); + $('.user-recent-posts span.timeago').timeago(); }); }); diff --git a/public/src/forum/footer.js b/public/src/forum/footer.js index 337013a4bb..22aaf69768 100644 --- a/public/src/forum/footer.js +++ b/public/src/forum/footer.js @@ -139,7 +139,7 @@ }); socket.on('event:new_notification', function() { - document.querySelector('.notifications a i').className = 'fa-circle active'; + document.querySelector('.notifications a i').className = 'fa fa-circle active'; app.alert({ alert_id: 'new_notif', title: 'New notification', diff --git a/src/categories.js b/src/categories.js index cc72bdc7b1..1a5eac3022 100644 --- a/src/categories.js +++ b/src/categories.js @@ -143,7 +143,13 @@ var RDB = require('./redis.js'), Categories.getAllCategories = function(current_user, callback) { RDB.lrange('categories:cid', 0, -1, function(err, cids) { - RDB.handle(err); + if(err) { + return callback(err); + } + if(cids && cids.length === 0) { + return callback(null, {categories : []}); + } + Categories.getCategories(cids, current_user, callback); }); }; diff --git a/src/favourites.js b/src/favourites.js index 5845646064..baaaa33122 100644 --- a/src/favourites.js +++ b/src/favourites.js @@ -1,7 +1,8 @@ -var RDB = require('./redis.js'), - posts = require('./posts.js'), - user = require('./user.js'), - translator = require('./../public/src/translator.js'); +var RDB = require('./redis'), + posts = require('./posts'), + user = require('./user'), + websockets = require('./websockets') + translator = require('./../public/src/translator'); (function (Favourites) { "use strict"; @@ -37,7 +38,7 @@ var RDB = require('./redis.js'), } if (room_id) { - io.sockets. in (room_id).emit('event:rep_up', { + websockets.in(room_id).emit('event:rep_up', { uid: uid !== postData.uid ? postData.uid : 0, pid: pid }); @@ -72,7 +73,7 @@ var RDB = require('./redis.js'), } if (room_id) { - io.sockets. in (room_id).emit('event:rep_down', { + websockets.in(room_id).emit('event:rep_down', { uid: uid !== uid_of_poster ? uid_of_poster : 0, pid: pid }); diff --git a/src/notifications.js b/src/notifications.js index cd6e3edd28..801995c4d6 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -4,148 +4,155 @@ var RDB = require('./redis'), winston = require('winston'), cron = require('cron').CronJob, - notifications = { - init: function() { - if (process.env.NODE_ENV === 'development') { - winston.info('[notifications.init] Registering jobs.'); - } + websockets = require('./websockets'); - new cron('0 0 * * *', notifications.prune, null, true); - }, - get: function(nid, uid, callback) { - RDB.multi() - .hmget('notifications:' + nid, 'text', 'score', 'path', 'datetime', 'uniqueId') - .zrank('uid:' + uid + ':notifications:read', nid) - .exists('notifications:' + nid) - .exec(function(err, results) { - var notification = results[0], - readIdx = results[1]; - if (!results[2]) { - return callback(null); - } - callback({ - nid: nid, - text: notification[0], - score: notification[1], - path: notification[2], - datetime: notification[3], - uniqueId: notification[4], - read: readIdx !== null ? true : false - }); - }); - }, - create: function(text, path, uniqueId, callback) { - /** - * uniqueId is used solely to override stale nids. - * If a new nid is pushed to a user and an existing nid in the user's - * (un)read list contains the same uniqueId, it will be removed, and - * the new one put in its place. - */ - RDB.incr('notifications:next_nid', function(err, nid) { - RDB.sadd('notifications', nid); - RDB.hmset('notifications:' + nid, { - text: text || '', - path: path || null, - datetime: Date.now(), - uniqueId: uniqueId || utils.generateUUID() - }, function(err, status) { - if (!err) { - callback(nid); - } - }); - }); - }, - destroy: function(nid) { - var multi = RDB.multi(); +(function(Notifications) { - multi.del('notifications:' + nid); - multi.srem('notifications', nid); + Notifications.init = function() { + if (process.env.NODE_ENV === 'development') { + winston.info('[notifications.init] Registering jobs.'); + } + new cron('0 0 * * *', Notifications.prune, null, true); + }; + + Notifications.get = function(nid, uid, callback) { + RDB.multi() + .hmget('notifications:' + nid, 'text', 'score', 'path', 'datetime', 'uniqueId') + .zrank('uid:' + uid + ':notifications:read', nid) + .exists('notifications:' + nid) + .exec(function(err, results) { + var notification = results[0], + readIdx = results[1]; - multi.exec(function(err) { - if (err) { - winston.error('Problem deleting expired notifications. Stack follows.'); - winston.error(err.stack); + if (!results[2]) { + return callback(null); + } + + callback({ + nid: nid, + text: notification[0], + score: notification[1], + path: notification[2], + datetime: notification[3], + uniqueId: notification[4], + read: readIdx !== null ? true : false + }); + }); + }; + + Notifications.create = function(text, path, uniqueId, callback) { + /** + * uniqueId is used solely to override stale nids. + * If a new nid is pushed to a user and an existing nid in the user's + * (un)read list contains the same uniqueId, it will be removed, and + * the new one put in its place. + */ + RDB.incr('notifications:next_nid', function(err, nid) { + RDB.sadd('notifications', nid); + RDB.hmset('notifications:' + nid, { + text: text || '', + path: path || null, + datetime: Date.now(), + uniqueId: uniqueId || utils.generateUUID() + }, function(err, status) { + if (!err) { + callback(nid); } }); - }, - push: function(nid, uids, callback) { - if (!Array.isArray(uids)) uids = [uids]; + }); + }; + + function destroy(nid) { + var multi = RDB.multi(); - var numUids = uids.length, - x; + multi.del('notifications:' + nid); + multi.srem('notifications', nid); - notifications.get(nid, null, function(notif_data) { - for (x = 0; x < numUids; x++) { - if (parseInt(uids[x], 10) > 0) { - (function(uid) { - notifications.remove_by_uniqueId(notif_data.uniqueId, uid, function() { - RDB.zadd('uid:' + uid + ':notifications:unread', notif_data.datetime, nid); + multi.exec(function(err) { + if (err) { + winston.error('Problem deleting expired notifications. Stack follows.'); + winston.error(err.stack); + } + }); + } + + Notifications.push = function(nid, uids, callback) { + if (!Array.isArray(uids)) uids = [uids]; - global.io.sockets.in('uid_' + uid).emit('event:new_notification'); + var numUids = uids.length, + x; - // TODO: moving this require to the top of the file overwrites 'notifications' figure out why -baris - //require('./websockets').in('uid_' + uid).emit('event:new_notification'); + Notifications.get(nid, null, function(notif_data) { + for (x = 0; x < numUids; x++) { + if (parseInt(uids[x], 10) > 0) { + (function(uid) { + remove_by_uniqueId(notif_data.uniqueId, uid, function() { + RDB.zadd('uid:' + uid + ':notifications:unread', notif_data.datetime, nid); - if (callback) { - callback(true); - } - }); - })(uids[x]); - } + websockets.in('uid_' + uid).emit('event:new_notification'); + + if (callback) { + callback(true); + } + }); + })(uids[x]); } - }); - }, - remove_by_uniqueId: function(uniqueId, uid, callback) { - async.parallel([ - function(next) { - RDB.zrange('uid:' + uid + ':notifications:unread', 0, -1, function(err, nids) { - if (nids && nids.length > 0) { - async.each(nids, function(nid, next) { - notifications.get(nid, uid, function(nid_info) { - if (nid_info.uniqueId === uniqueId) { - RDB.zrem('uid:' + uid + ':notifications:unread', nid); - } + } + }); + }; + + function remove_by_uniqueId(uniqueId, uid, callback) { + async.parallel([ + function(next) { + RDB.zrange('uid:' + uid + ':notifications:unread', 0, -1, function(err, nids) { + if (nids && nids.length > 0) { + async.each(nids, function(nid, next) { + Notifications.get(nid, uid, function(nid_info) { + if (nid_info.uniqueId === uniqueId) { + RDB.zrem('uid:' + uid + ':notifications:unread', nid); + } - next(); - }); - }, function(err) { next(); }); - } else { + }, function(err) { next(); - } - }); - }, - function(next) { - RDB.zrange('uid:' + uid + ':notifications:read', 0, -1, function(err, nids) { - if (nids && nids.length > 0) { - async.each(nids, function(nid, next) { - notifications.get(nid, uid, function(nid_info) { - if (nid_info && nid_info.uniqueId === uniqueId) { - RDB.zrem('uid:' + uid + ':notifications:read', nid); - } + }); + } else { + next(); + } + }); + }, + function(next) { + RDB.zrange('uid:' + uid + ':notifications:read', 0, -1, function(err, nids) { + if (nids && nids.length > 0) { + async.each(nids, function(nid, next) { + Notifications.get(nid, uid, function(nid_info) { + if (nid_info && nid_info.uniqueId === uniqueId) { + RDB.zrem('uid:' + uid + ':notifications:read', nid); + } - next(); - }); - }, function(err) { next(); }); - } else { + }, function(err) { next(); - } - }); - } - ], function(err) { - if (!err) { - callback(true); - } - }); - }, - mark_read: function(nid, uid, callback) { + }); + } else { + next(); + } + }); + } + ], function(err) { + if (!err) { + callback(true); + } + }); + } + + Notifications.mark_read = function(nid, uid, callback) { if (parseInt(uid) > 0) { - notifications.get(nid, uid, function(notif_data) { + Notifications.get(nid, uid, function(notif_data) { RDB.zrem('uid:' + uid + ':notifications:unread', nid); RDB.zadd('uid:' + uid + ':notifications:read', notif_data.datetime, nid); if (callback) { @@ -153,121 +160,115 @@ var RDB = require('./redis'), } }); } - }, - mark_read_multiple: function(nids, uid, callback) { - if (!Array.isArray(nids) && parseInt(nids, 10) > 0) { - nids = [nids]; - } + } + + Notifications.mark_read_multiple = function(nids, uid, callback) { + if (!Array.isArray(nids) && parseInt(nids, 10) > 0) { + nids = [nids]; + } - async.each(nids, function(nid, next) { - notifications.mark_read(nid, uid, function(err) { - if (!err) { - next(null); - } - }); - }, function(err) { - if (callback) { - callback(err); + async.each(nids, function(nid, next) { + Notifications.mark_read(nid, uid, function(err) { + if (!err) { + next(null); } }); - }, - mark_all_read: function(uid, callback) { - RDB.zrange('uid:' + uid + ':notifications:unread', 0, 10, function(err, nids) { - if (err) { - return callback(err); - } + }, function(err) { + if (callback) { + callback(err); + } + }); + }; + + Notifications.mark_all_read = function(uid, callback) { + RDB.zrange('uid:' + uid + ':notifications:unread', 0, 10, function(err, nids) { + if (err) { + return callback(err); + } - if (nids.length > 0) { - notifications.mark_read_multiple(nids, uid, function(err) { - callback(err); - }); - } else { - callback(); - } - }); - }, - prune: function(cutoff) { - if (process.env.NODE_ENV === 'development') { - winston.info('[notifications.prune] Removing expired notifications from the database.'); + if (nids.length > 0) { + Notifications.mark_read_multiple(nids, uid, function(err) { + callback(err); + }); + } else { + callback(); } + }); + }; + + Notifications.prune = function(cutoff) { + if (process.env.NODE_ENV === 'development') { + winston.info('[notifications.prune] Removing expired notifications from the database.'); + } - var today = new Date(), - numPruned = 0; + var today = new Date(), + numPruned = 0; - if (!cutoff) { - cutoff = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7); - } + if (!cutoff) { + cutoff = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7); + } - var cutoffTime = cutoff.getTime(); + var cutoffTime = cutoff.getTime(); - async.parallel({ - "inboxes": function(next) { - RDB.keys('uid:*:notifications:unread', next); - }, - "nids": function(next) { - RDB.smembers('notifications', function(err, nids) { - async.filter(nids, function(nid, next) { - RDB.hget('notifications:' + nid, 'datetime', function(err, datetime) { - if (parseInt(datetime, 10) < cutoffTime) { - next(true); - } else { - next(false); - } - }); - }, function(expiredNids) { - next(null, expiredNids); + async.parallel({ + "inboxes": function(next) { + RDB.keys('uid:*:notifications:unread', next); + }, + "nids": function(next) { + RDB.smembers('notifications', function(err, nids) { + async.filter(nids, function(nid, next) { + RDB.hget('notifications:' + nid, 'datetime', function(err, datetime) { + if (parseInt(datetime, 10) < cutoffTime) { + next(true); + } else { + next(false); + } }); + }, function(expiredNids) { + next(null, expiredNids); }); - } - }, function(err, results) { - if (!err) { - var numInboxes = results.inboxes.length, - x; - - async.eachSeries(results.nids, function(nid, next) { - var multi = RDB.multi(); + }); + } + }, function(err, results) { + if (!err) { + var numInboxes = results.inboxes.length, + x; - for(x=0;x 0) { - async.each(nids, function(nid, next) { - notifications.mark_read(nid, uid, next); - }); - } + notifications.mark_read_multiple(nids, uid, function() { + + }); }); } diff --git a/src/websockets.js b/src/websockets.js index cff42809c8..3ec3c4a03c 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -58,8 +58,6 @@ module.exports.isUserOnline = isUserOnline; module.exports.init = function(io) { - global.io = io; - io.sockets.on('connection', function(socket) { var hs = socket.handshake, sessionID, uid, lastPostTime = 0; @@ -246,7 +244,7 @@ module.exports.init = function(io) { }); socket.on('post.stats', function(data) { - posts.getTopicPostStats(); + emitTopicPostStats(); }); socket.on('user.email.exists', function(data) { @@ -384,7 +382,7 @@ module.exports.init = function(io) { posts: result.postData }); - posts.getTopicPostStats(); + emitTopicPostStats(); socket.emit('event:alert', { title: 'Thank you for posting', @@ -423,7 +421,7 @@ module.exports.init = function(io) { return; } - posts.reply(data.topic_id, uid, data.content, function(err, result) { + posts.reply(data.topic_id, uid, data.content, function(err, postData) { if(err) { if(err.message === 'content-too-short') { @@ -441,9 +439,9 @@ module.exports.init = function(io) { return; } - if (result) { + if (postData) { lastPostTime = Date.now(); - posts.getTopicPostStats(); + emitTopicPostStats(); socket.emit('event:alert', { title: 'Reply Successful', @@ -451,6 +449,12 @@ module.exports.init = function(io) { type: 'success', timeout: 2000 }); + var socketData = { + posts: [postData] + }; + io.sockets.in('topic_' + postData.tid).emit('event:new_post', socketData); + io.sockets.in('recent_posts').emit('event:new_post', socketData); + io.sockets.in('user/' + postData.uid).emit('event:new_post', socketData); } @@ -495,7 +499,7 @@ module.exports.init = function(io) { if (privileges.editable) { threadTools.delete(data.tid, function(err) { if (!err) { - posts.getTopicPostStats(); + emitTopicPostStats(); socket.emit('api:topic.delete', { status: 'ok', tid: data.tid @@ -510,7 +514,7 @@ module.exports.init = function(io) { threadTools.privileges(data.tid, uid, function(privileges) { if (privileges.editable) { threadTools.restore(data.tid, socket, function(err) { - posts.getTopicPostStats(); + emitTopicPostStats(); socket.emit('api:topic.restore', { status: 'ok', @@ -597,11 +601,12 @@ module.exports.init = function(io) { socket.on('api:posts.delete', function(data, callback) { postTools.delete(uid, data.pid, function(err) { + if(err) { return callback(err); } - posts.getTopicPostStats(); + emitTopicPostStats(); io.sockets.in('topic_' + data.tid).emit('event:post_deleted', { pid: data.pid @@ -616,7 +621,7 @@ module.exports.init = function(io) { return callback(err); } - posts.getTopicPostStats(); + emitTopicPostStats(); io.sockets.in('topic_' + data.tid).emit('event:post_restored', { pid: data.pid @@ -636,9 +641,10 @@ module.exports.init = function(io) { }); socket.on('api:notifications.mark_all_read', function(data, callback) { - console.log(notifications); - require('./notifications').mark_all_read(uid, function(err) { - if (!err) callback(); + notifications.mark_all_read(uid, function(err) { + if (!err) { + callback(); + } }); }); @@ -1011,6 +1017,22 @@ module.exports.init = function(io) { socket.on('api:admin.theme.set', meta.themes.set); }); + + function emitTopicPostStats() { + RDB.mget(['totaltopiccount', 'totalpostcount'], function(err, data) { + if (err) { + return winston.err(err); + } + + var stats = { + topics: data[0] ? data[0] : 0, + posts: data[1] ? data[1] : 0 + }; + + io.sockets.emit('post.stats', stats); + }); + } + module.exports.emitUserCount = function() { RDB.get('usercount', function(err, count) { io.sockets.emit('user.count', {