From 1132e3971dece77a9aa4423bbd30cbfc595fc042 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Fri, 18 Dec 2015 17:26:49 +0100 Subject: [PATCH] initial implementation for GET groups --- common/locales/en/api-v3.json | 3 +- website/src/controllers/api-v3/groups.js | 71 +++++++++++++++++++++++- website/src/models/group.js | 1 + 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/common/locales/en/api-v3.json b/common/locales/en/api-v3.json index d223c66961..206a0bcd35 100644 --- a/common/locales/en/api-v3.json +++ b/common/locales/en/api-v3.json @@ -29,5 +29,6 @@ "directionUpDown": "\"direction\" is required and must be 'up' or 'down'", "alreadyTagged": "The task is already tagged with given tag.", "groupIdRequired": "\"groupId\" must be a valid UUID", - "groupNotFound": "Group not found." + "groupNotFound": "Group not found.", + "groupTypesRequired": "You must supply a valid \"type\" query string." } diff --git a/website/src/controllers/api-v3/groups.js b/website/src/controllers/api-v3/groups.js index 7617f3ea99..7074168198 100644 --- a/website/src/controllers/api-v3/groups.js +++ b/website/src/controllers/api-v3/groups.js @@ -1,12 +1,81 @@ import { authWithHeaders } from '../../middlewares/api-v3/auth'; +import Q from 'q'; +import _ from 'lodash'; import cron from '../../middlewares/api-v3/cron'; import { model as Group } from '../../models/group'; import { NotFound, + BadRequest, } from '../../libs/api-v3/errors'; let api = {}; +/** + * @api {get} /groups Get groups + * @apiVersion 3.0.0 + * @apiName GetGroups + * @apiGroup Group + * + * @apiParam {string} type The type of groups to retrieve. Must be a query string representing a list of values like 'tavern,party'. Possible values are party, privateGuilds, publicGuilds, tavern + * + * @apiSuccess {Array} groups An array of the requested groups + */ +api.getGroups = { + method: 'GET', + url: '/groups', + middlewares: [authWithHeaders(), cron], + handler (req, res, next) { + let user = res.locals.user; + + req.checkQuery('type', res.t('groupTypesRequired')).notEmpty(); // TODO better validation + + let validationErrors = req.validationErrors(); + if (validationErrors) return next(validationErrors); + + // TODO validate types are acceptable? probably not necessary + let types = req.query.type.split(','); + let groupFields = 'name description memberCount balance leader'; + let sort = '-memberCount'; + let queries = []; + + types.forEach(type => { + switch (type) { + case 'party': + queries.push(Group.getGroup(user, 'party', groupFields)); + break; + case 'privateGuilds': + queries.push(Group.find({ + type: 'guild', + privacy: 'private', + _id: {$in: user.guilds}, + }).select(groupFields).sort(sort).exec()); // TODO isMember + break; + case 'publicGuilds': + queries.push(Group.find({ + type: 'guild', + privacy: 'public', + }).select(groupFields).sort(sort).exec()); // TODO use lean? isMember + break; + case 'tavern': + queries.push(Group.getGroup(user, 'habitrpg', groupFields)); + break; + } + }); + + // If no valid value for type was supplied, return an error + if (queries.length === 0) return next(new BadRequest(res.t('groupTypesRequired'))); + + Q.all(queries) // TODO we would like not to return a single big array but Q doesn't support the funtionality https://github.com/kriskowal/q/issues/328 + .then(results => { + res.respond(200, _.reduce(results, (m, v) => { + if (_.isEmpty(v)) return m; + return m.concat(Array.isArray(v) ? v : [v]); + }, [])); + }) + .catch(next); + }, +}; + /** * @api {get} /groups/:groupId Get group * @apiVersion 3.0.0 @@ -29,7 +98,7 @@ api.getGroup = { let validationErrors = req.validationErrors(); if (validationErrors) return next(validationErrors); - Group.getGroup(user, req.params.groupId) + Group.getGroup(user, req.params.groupId, true) .then(group => { if (!group) throw new NotFound(res.t('groupNotFound')); diff --git a/website/src/models/group.js b/website/src/models/group.js index 0fe32464d0..e6d125fd89 100644 --- a/website/src/models/group.js +++ b/website/src/models/group.js @@ -145,6 +145,7 @@ schema.post('remove', function postRemoveGroup (group) { return doc; };*/ +// TODO populate, isMember? schema.statics.getGroup = function getGroup (user, groupId, fields) { let query;