From 62012a1052433068196e793ca615940c2ca2df83 Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Sat, 2 Nov 2013 18:01:29 -0700 Subject: [PATCH] fix adding challenges as subdoc to groups. write migration to restore those that have been created. Also in migration fix missing task.ids (taskSchema issue) --- migrations/20131102_restore_task_ids.js | 25 ++++++++ src/controllers/challenges.js | 78 ++++++++++++++----------- views/options/social/challenge-box.jade | 16 +++++ views/options/social/group.jade | 19 +----- views/options/social/tavern.jade | 2 + 5 files changed, 88 insertions(+), 52 deletions(-) create mode 100644 migrations/20131102_restore_task_ids.js create mode 100644 views/options/social/challenge-box.jade diff --git a/migrations/20131102_restore_task_ids.js b/migrations/20131102_restore_task_ids.js new file mode 100644 index 0000000000..260675fbf5 --- /dev/null +++ b/migrations/20131102_restore_task_ids.js @@ -0,0 +1,25 @@ +// mongo habitrpg ./node_modules/lodash/lodash.js ./migrations/20131028_task_subdocs_tags_invites.js + +db.challenges.find().forEach(function(chal){ + _.each(chal.habits.concat(chal.dailys).concat(chal.todos).concat(chal.rewards), function(task){ + task.id = task.id || task._id; + }) + try { + db.challenges.update({_id:chal._id}, chal); + db.groups.update({_id:chal.group}, {$addToSet:{challenges:chal._id}}) + } catch(e) { + print(e); + } +}); + +db.users.find().forEach(function(user){ + _.each(user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards), function(task){ + task.id = task.id || task._id; + }) + try { + db.users.update({_id:user._id}, user); + } catch(e) { + print(e); + } +}); + diff --git a/src/controllers/challenges.js b/src/controllers/challenges.js index 6983e7cd76..eaf15b0bc9 100644 --- a/src/controllers/challenges.js +++ b/src/controllers/challenges.js @@ -123,54 +123,63 @@ api.getMember = function(req, res) { // CREATE api.create = function(req, res){ var user = res.locals.user; - var waterfall = []; + var group, chal; + + // First, make sure they've selected a legit group, and store it for later + var waterfall = [ + function(cb){ + Group.findById(req.body.group).exec(cb); + }, + function(_group, cb){ + if (!_group) return cb("Group." + req.body.group + " not found"); + group = _group; + cb(null); + } + ]; + + // If they're adding a prize, do some validation if (+req.body.prize < 0) return res.json(401, {err: 'Challenge prize must be >= 0'}); if (req.body.group=='habitrpg' && +req.body.prize < 1) return res.json(401, {err: 'Prize must be at least 1 Gem for public challenges.'}); if (+req.body.prize > 0) { - waterfall = [ - function(cb){ - Group.findById(req.body.group).select('balance leader').exec(cb); - }, - function(group, cb){ - if (!group) return cb("Group." + req.body.group + " not found"); - var groupBalance = ((group.balance && group.leader==user._id) ? group.balance : 0); - if (req.body.prize > (user.balance*4 + groupBalance*4)) - return cb("Challenge.prize > (your gems + group balance). Purchase more gems or lower prize amount.s") + waterfall.push(function(cb){ + var groupBalance = ((group.balance && group.leader==user._id) ? group.balance : 0); + if (req.body.prize > (user.balance*4 + groupBalance*4)) + return cb("Challenge.prize > (your gems + group balance). Purchase more gems or lower prize amount.s") - var net = req.body.prize/4; // I really should have stored user.balance as gems rather than dollars... stupid... + var net = req.body.prize/4; // I really should have stored user.balance as gems rather than dollars... stupid... - // user is group leader, and group has balance. Subtract from that first, then take the rest from user - if (groupBalance > 0) { - group.balance -= net; - if (group.balance < 0) { - net = Math.abs(group.balance); - group.balance = 0; - } + // user is group leader, and group has balance. Subtract from that first, then take the rest from user + if (groupBalance > 0) { + group.balance -= net; + if (group.balance < 0) { + net = Math.abs(group.balance); + group.balance = 0; } - user.balance -= net; - group.save(cb) } - ]; + user.balance -= net; + cb(null) + }); } + waterfall = waterfall.concat([ - function() { // if we're dealing with prize above, arguemnts will be `group, numRows, cb` - else `cb` - var cb = arguments[arguments.length-1]; - var challenge = new Challenge(req.body); // FIXME sanitize - challenge.members.push(user._id); - challenge.save(cb); + function(cb) { // if we're dealing with prize above, arguemnts will be `group, numRows, cb` - else `cb` + var chal = new Challenge(req.body); // FIXME sanitize + chal.members.push(user._id); + chal.save(cb) }, - function(chal, num, cb) { + function(_chal, num, cb){ + chal = _chal; + group.challenges.push(chal._id); + group.save(cb); + }, + function(_group, num, cb) { // Auto-join creator to challenge (see members.push above) syncChalToUser(chal, user); - user.save(function(err){ - if (err) return cb(err); - cb(null, chal); - }); + user.save(cb); } ]); - async.waterfall(waterfall, function(err, chal){ + async.waterfall(waterfall, function(err){ if (err) return res.json(500, {err:err}); - Group.update({_id:chal.group}, {$addToSet:{challenges:chal._id}}) // fixme error-check, and also better to do in middleware? res.json(chal); }); } @@ -255,7 +264,8 @@ function closeChal(cid, broken, cb) { function(users, cb2) { var parallel = []; _.each(users, function(user){ - _.find(user.tags, {id:cid}).challenge = undefined; + var tag = _.find(user.tags, {id:cid}); + if (tag) tag.challenge = undefined; _.each(user.tasks, function(task){ if (task.challenge && task.challenge.id == removed._id) { _.merge(task.challenge, broken); diff --git a/views/options/social/challenge-box.jade b/views/options/social/challenge-box.jade new file mode 100644 index 0000000000..213e61b724 --- /dev/null +++ b/views/options/social/challenge-box.jade @@ -0,0 +1,16 @@ +// ------ Challenges ------- +.modal(style='position: relative;top: auto;left: auto;right: auto;margin: 0 auto 20px;z-index: 1;max-width: 100%;') + .modal-header + h3 + | Challenges + a.pull-right(target='_blank', href='https://trello.com/card/challenges-individual-party-guild-public/50e5d3684fe3a7266b0036d6/58') + i.icon-question-sign + .modal-body + div(ng-if='group.challenges.length > 0') + table.table.table-striped + tr(ng-repeat='challenge in group.challenges') + td + a(ui-sref='options.social.challenges.detail({cid:challenge._id})') {{challenge.name}} + div(ng-if='group.challenges.length == 0') + p. + No challenges yet, visit Challenges to create one. \ No newline at end of file diff --git a/views/options/social/group.jade b/views/options/social/group.jade index 189d39a4fa..28a71938e6 100644 --- a/views/options/social/group.jade +++ b/views/options/social/group.jade @@ -47,24 +47,7 @@ a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank' li(ng-repeat='website in group.websites') a(target='_blank', ng-href='{{website}}') {{website}} - // ------ Challenges ------- - .modal(style='position: relative;top: auto;left: auto;right: auto;margin: 0 auto 20px;z-index: 1;max-width: 100%;') - .modal-header - h3 - | Challenges - a.pull-right(target='_blank', href='https://trello.com/card/challenges-individual-party-guild-public/50e5d3684fe3a7266b0036d6/58') - i.icon-question-sign - .modal-body - div(ng-if='group.challenges.length > 0') - table.table.table-striped - tr(ng-repeat='challenge in group.challenges') - td - a(ui-sref='options.social.challenges.detail({cid:challenge._id})') {{challenge.name}} - p. - Visit the Challenges for more information. - div(ng-if='group.challenges.length == 0') - p. - No challenges yet, visit the Challenges tab to create one. + include ./challenge-box // ------ Members ------- .modal(style='position: relative;top: auto;left: auto;right: auto;margin: 0 auto 20px;z-index: 1;max-width: 100%;') diff --git a/views/options/social/tavern.jade b/views/options/social/tavern.jade index 54e21ce681..f4ba422d0c 100644 --- a/views/options/social/tavern.jade +++ b/views/options/social/tavern.jade @@ -42,6 +42,8 @@ h4 a(target='_blank', href='http://community.habitrpg.com/forum') Community Forum + include ./challenge-box + .span8(ng-controller='ChatCtrl') h3 Tavern Talk .row-fluid