From c8f87e5d363678477fa5ef33b28544dccc59adf8 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 30 Jan 2015 16:16:49 -0500 Subject: [PATCH 1/5] removed console.log --- public/src/client/account/watched.js | 1 - 1 file changed, 1 deletion(-) diff --git a/public/src/client/account/watched.js b/public/src/client/account/watched.js index bd0e8282dd..9a502b1ee8 100644 --- a/public/src/client/account/watched.js +++ b/public/src/client/account/watched.js @@ -11,7 +11,6 @@ define('forum/account/watched', ['forum/account/header', 'forum/infinitescroll'] }; function loadMore(direction) { - console.log(direction); if (direction < 0) { return; } From e4e9020e1f4f058f16f68de0c0de813ce406c184 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 30 Jan 2015 15:48:17 -0500 Subject: [PATCH 2/5] added groups page to user profile --- public/src/client/groups/list.js | 4 ++-- src/controllers/accounts.js | 23 +++++++++++++++++++++++ src/routes/index.js | 1 + src/views/config.json | 1 + 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/public/src/client/groups/list.js b/public/src/client/groups/list.js index 0410a9fa17..d0b4c69b50 100644 --- a/public/src/client/groups/list.js +++ b/public/src/client/groups/list.js @@ -8,9 +8,9 @@ define('forum/groups/list', function() { var groupsEl = $('#groups-list'); groupsEl.on('click', '.list-cover', function() { - var groupName = $(this).parents('[data-group]').attr('data-group'); + var groupSlug = $(this).parents('[data-slug]').attr('data-slug'); - ajaxify.go('groups/' + utils.slugify(groupName)); + ajaxify.go('groups/' + groupSlug); }); // Group creation diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js index 741de9a626..c55977a351 100644 --- a/src/controllers/accounts.js +++ b/src/controllers/accounts.js @@ -233,6 +233,29 @@ accountsController.getTopics = function(req, res, next) { getFromUserSet('account/topics', 'topics', topics.getTopicsFromSet, 'topics', req, res, next); }; +accountsController.getGroups = function(req, res, next) { + var callerUID = req.user ? parseInt(req.user.uid, 10) : 0; + + getBaseUser(req.params.userslug, callerUID, function(err, userData) { + if (err) { + return next(err); + } + + if (!userData) { + return helpers.notFound(req, res); + } + + groups.getUserGroups([userData.uid], function(err, groups) { + if (err) { + return next(err); + } + + userData.groups = groups[0]; + + res.render('account/groups', userData); + }); + }); +}; function getFromUserSet(tpl, set, method, type, req, res, next) { var callerUID = req.user ? parseInt(req.user.uid, 10) : 0; diff --git a/src/routes/index.js b/src/routes/index.js index 1af03e0930..f8012c9456 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -68,6 +68,7 @@ function accountRoutes(app, middleware, controllers) { setupPageRoute(app, '/user/:userslug/followers', middleware, middlewares, controllers.accounts.getFollowers); setupPageRoute(app, '/user/:userslug/posts', middleware, middlewares, controllers.accounts.getPosts); setupPageRoute(app, '/user/:userslug/topics', middleware, middlewares, controllers.accounts.getTopics); + setupPageRoute(app, '/user/:userslug/groups', middleware, middlewares, controllers.accounts.getGroups); setupPageRoute(app, '/user/:userslug/favourites', middleware, accountMiddlewares, controllers.accounts.getFavourites); setupPageRoute(app, '/user/:userslug/watched', middleware, accountMiddlewares, controllers.accounts.getWatchedTopics); diff --git a/src/views/config.json b/src/views/config.json index 70997cf4a8..26ae7b692c 100644 --- a/src/views/config.json +++ b/src/views/config.json @@ -14,6 +14,7 @@ "^user/.*/watched": "account/watched", "^user/.*/posts": "account/posts", "^user/.*/topics": "account/topics", + "^user/.*/groups": "account/groups", "^user/[^\/]+": "account/profile", "^reset/.*": "reset_code", "^tags/.*": "tag", From ecfa8f7a7df276085c0b8a6d100c46f99bc202ef Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 30 Jan 2015 16:24:57 -0500 Subject: [PATCH 3/5] passing memberCount and createTime into getUserGroups --- src/groups.js | 54 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/groups.js b/src/groups.js index 4a7611c531..4eca55c05d 100644 --- a/src/groups.js +++ b/src/groups.js @@ -781,35 +781,51 @@ var async = require('async'), groupData = groupData.filter(function(group) { return parseInt(group.hidden, 10) !== 1 && !!group.userTitle; + }).map(function(group) { + group.createtimeISO = utils.toISOString(group.createtime); + return group; }); - var groupSets = groupData.map(function(group) { - group.labelColor = group.labelColor || '#000000'; + async.map(groupData, function(groupObj, next) { + Groups.getMemberCount(groupObj.name, function(err, memberCount) { + if (err) { return next(err); } - if (!group['cover:url']) { - group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; - group['cover:position'] = '50% 50%'; + groupObj.memberCount = memberCount; + next(err, groupObj); + }); + }, function(err, groupData) { + if (err) { + return callback(err); } - return 'group:' + group.name + ':members'; - }); + var groupSets = groupData.map(function(group) { + group.labelColor = group.labelColor || '#000000'; - async.map(uids, function(uid, next) { - db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { - if (err) { - return next(err); + if (!group['cover:url']) { + group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; + group['cover:position'] = '50% 50%'; } - var memberOf = []; - isMembers.forEach(function(isMember, index) { - if (isMember) { - memberOf.push(groupData[index]); + return 'group:' + group.name + ':members'; + }); + + async.map(uids, function(uid, next) { + db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { + if (err) { + return next(err); } - }); - next(null, memberOf); - }); - }, callback); + var memberOf = []; + isMembers.forEach(function(isMember, index) { + if (isMember) { + memberOf.push(groupData[index]); + } + }); + + next(null, memberOf); + }); + }, callback); + }); }); }); }; From 607e88b3c3ad28740c49b53105e39c82934db7ff Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 30 Jan 2015 16:27:29 -0500 Subject: [PATCH 4/5] fixed browser title in user groups page --- public/language/en_GB/pages.json | 1 + 1 file changed, 1 insertion(+) diff --git a/public/language/en_GB/pages.json b/public/language/en_GB/pages.json index 8b231f8a94..4095ae38a3 100644 --- a/public/language/en_GB/pages.json +++ b/public/language/en_GB/pages.json @@ -11,6 +11,7 @@ "user.followers": "People who Follow %1", "user.posts": "Posts made by %1", "user.topics": "Topics created by %1", + "user.groups": "%1's Groups", "user.favourites": "%1's Favourite Posts", "user.settings": "User Settings", From dc2a2aa98ec372c7c114dedf2904411e3c40efec Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 30 Jan 2015 22:38:42 -0500 Subject: [PATCH 5/5] store group member count in group hash yet another upgrade script --- src/groups.js | 140 ++++++++++++++++++++++++------------------------- src/upgrade.js | 37 ++++++++++++- 2 files changed, 104 insertions(+), 73 deletions(-) diff --git a/src/groups.js b/src/groups.js index 4eca55c05d..7e41b94b02 100644 --- a/src/groups.js +++ b/src/groups.js @@ -299,7 +299,7 @@ var async = require('async'), }; Groups.getMemberCount = function(groupName, callback) { - db.sortedSetCard('group:' + groupName + ':members', callback); + db.getObjectField('group:' + groupName, 'memberCount', callback); }; Groups.isMemberOfGroupList = function(uid, groupListKey, callback) { @@ -611,46 +611,56 @@ var async = require('async'), }; Groups.join = function(groupName, uid, callback) { - callback = callback || function() {}; - - Groups.exists(groupName, function(err, exists) { - if (exists) { - var tasks = [ - async.apply(db.sortedSetAdd, 'group:' + groupName + ':members', Date.now(), uid) - ]; + function join() { + var tasks = [ + async.apply(db.sortedSetAdd, 'group:' + groupName + ':members', Date.now(), uid), + async.apply(db.incrObjectField, 'group:' + groupName, 'memberCount') + ]; - user.isAdministrator(uid, function(err, isAdmin) { + async.waterfall([ + function(next) { + user.isAdministrator(uid, next); + }, + function(isAdmin, next) { if (isAdmin) { tasks.push(async.apply(db.setAdd, 'group:' + groupName + ':owners', uid)); } + async.parallel(tasks, next); + } + ], function(err, results) { + if (err) { + return callback(err); + } + plugins.fireHook('action:group.join', { + groupName: groupName, + uid: uid + }); + callback(); + }); + } - async.parallel(tasks, function(err) { - plugins.fireHook('action:group.join', { - groupName: groupName, - uid: uid - }); + callback = callback || function() {}; - callback(); - }); - }); - } else { - Groups.create({ - name: groupName, - description: '', - hidden: 1 - }, function(err) { - if (err && err.message !== '[[error:group-already-exists]]') { - winston.error('[groups.join] Could not create new hidden group: ' + err.message); - return callback(err); - } + Groups.exists(groupName, function(err, exists) { + if (err) { + return callback(err); + } - db.sortedSetAdd('group:' + groupName + ':members', Date.now(), uid, callback); - plugins.fireHook('action:group.join', { - groupName: groupName, - uid: uid - }); - }); + if (exists) { + return join(); } + + Groups.create({ + name: groupName, + description: '', + hidden: 1 + }, function(err) { + if (err && err.message !== '[[error:group-already-exists]]') { + winston.error('[groups.join] Could not create new hidden group: ' + err.message); + return callback(err); + } + join(); + }); }); }; @@ -692,9 +702,10 @@ var async = require('async'), callback = callback || function() {}; var tasks = [ - async.apply(db.sortedSetRemove, 'group:' + groupName + ':members', uid), - async.apply(db.setRemove, 'group:' + groupName + ':owners', uid) - ]; + async.apply(db.sortedSetRemove, 'group:' + groupName + ':members', uid), + async.apply(db.setRemove, 'group:' + groupName + ':owners', uid), + async.apply(db.decrObjectField, 'group:' + groupName, 'memberCount') + ]; async.parallel(tasks, function(err) { if (err) { @@ -715,7 +726,7 @@ var async = require('async'), if (group.hidden && group.memberCount === 0) { Groups.destroy(groupName, callback); } else { - return callback(); + callback(); } }); }); @@ -781,51 +792,36 @@ var async = require('async'), groupData = groupData.filter(function(group) { return parseInt(group.hidden, 10) !== 1 && !!group.userTitle; - }).map(function(group) { - group.createtimeISO = utils.toISOString(group.createtime); - return group; }); - async.map(groupData, function(groupObj, next) { - Groups.getMemberCount(groupObj.name, function(err, memberCount) { - if (err) { return next(err); } + var groupSets = groupData.map(function(group) { + group.labelColor = group.labelColor || '#000000'; + group.createtimeISO = utils.toISOString(group.createtime); - groupObj.memberCount = memberCount; - next(err, groupObj); - }); - }, function(err, groupData) { - if (err) { - return callback(err); + if (!group['cover:url']) { + group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; + group['cover:position'] = '50% 50%'; } - var groupSets = groupData.map(function(group) { - group.labelColor = group.labelColor || '#000000'; + return 'group:' + group.name + ':members'; + }); - if (!group['cover:url']) { - group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; - group['cover:position'] = '50% 50%'; + async.map(uids, function(uid, next) { + db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { + if (err) { + return next(err); } - return 'group:' + group.name + ':members'; - }); - - async.map(uids, function(uid, next) { - db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { - if (err) { - return next(err); + var memberOf = []; + isMembers.forEach(function(isMember, index) { + if (isMember) { + memberOf.push(groupData[index]); } - - var memberOf = []; - isMembers.forEach(function(isMember, index) { - if (isMember) { - memberOf.push(groupData[index]); - } - }); - - next(null, memberOf); }); - }, callback); - }); + + next(null, memberOf); + }); + }, callback); }); }); }; diff --git a/src/upgrade.js b/src/upgrade.js index d433c9c06f..05a186ea69 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -21,7 +21,7 @@ var db = require('./database'), schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema - latestSchema = Date.UTC(2015, 0, 21); + latestSchema = Date.UTC(2015, 0, 30); Upgrade.check = function(callback) { db.get('schemaDate', function(err, value) { @@ -773,6 +773,41 @@ Upgrade.upgrade = function(callback) { winston.info('[2015/01/21] Upgrading groups to sorted set skipped'); next(); } + }, + function(next) { + thisSchemaDate = Date.UTC(2015, 0, 30); + if (schemaDate < thisSchemaDate) { + updatesMade = true; + winston.info('[2015/01/30] Adding group member counts'); + + db.getSortedSetRange('groups:createtime', 0, -1, function(err, groupNames) { + if (err) { + return next(err); + } + + var now = Date.now(); + async.each(groupNames, function(groupName, next) { + db.sortedSetCard('group:' + groupName + ':members', function(err, memberCount) { + console.log(groupName, memberCount); + if (err) { + return next(err); + } + + if (parseInt(memberCount, 10)) { + db.setObjectField('group:' + groupName, 'memberCount', memberCount, next); + } else { + next(); + } + }); + }, function(err) { + winston.info('[2015/01/30] Adding group member counts done'); + Upgrade.update(thisSchemaDate, next); + }); + }); + } else { + winston.info('[2015/01/30] Adding group member counts skipped'); + next(); + } } // Add new schema updates here