diff --git a/routes/parameters.js b/routes/parameters.js index 4098664d..15b15824 100644 --- a/routes/parameters.js +++ b/routes/parameters.js @@ -17,6 +17,15 @@ module.exports = { type: 'string', }, }, + guildIDParam: { + name: 'guildID', + in: 'path', + description: 'ID of guild.', + required: true, + schema: { + type: 'string', + }, + }, gameNameParam: { name: 'game', in: 'path', diff --git a/routes/spec.graphql b/routes/spec.graphql index 78190063..17ad1ce7 100644 --- a/routes/spec.graphql +++ b/routes/spec.graphql @@ -50,6 +50,18 @@ type Query { populate_players: String ): Guild + guild_by_id( + """ + ID of guild. + """ + guild_id: String! + + """ + Replace uuid fields with player profiles + """ + populate_players: String + ): Guild + """ Returns player or guild leaderboards diff --git a/routes/spec.js b/routes/spec.js index 72acfee6..a371c016 100644 --- a/routes/spec.js +++ b/routes/spec.js @@ -9,7 +9,7 @@ const getUUID = require('../store/getUUID'); const buildBans = require('../store/buildBans'); const buildBoosters = require('../store/buildBoosters'); const { queryAuctionId } = require('../store/queryAuctions'); -const { getGuildFromPlayer, getGuildFromName } = require('../store/buildGuild'); +const { getGuildFromPlayer, getGuildFromName, getGuildFromID } = require('../store/buildGuild'); const { buildProfileList, buildProfile } = require('../store/buildSkyBlockProfiles'); const { playerObject } = require('./objects'); const { populatePlayers, getPlayer, PlayerError } = require('../store/buildPlayer'); @@ -21,7 +21,7 @@ const { playerNameParam, gameNameParam, typeParam, columnParam, filterParam, sortByParam, limitParam, significantParam, populatePlayersParam, templateParam, itemIdParam, bazaarItemIdParam, fromParam, toParam, auctionUUIDParam, itemUUIDParam, activeParam, pageParam, sortOrderParam, - profileIdParam, guildNameParam, + profileIdParam, guildNameParam, guildIDParam, } = require('./parameters'); const packageJson = require('../package.json'); @@ -856,7 +856,7 @@ Consider supporting The Slothpixel Project on Patreon to help cover the hosting 'guild', ], parameters: [ - guildNameParam, + guildNameParam, populatePlayersParam, ], responses: { 200: { @@ -992,7 +992,163 @@ Consider supporting The Slothpixel Project on Patreon to help cover the hosting route: () => '/guilds/name/:name', func: async (request, response, callback) => { try { - const guild = await getGuildFromName(request.params.name); + const guild = await getGuildFromName(request.params.name, { shouldPopulatePlayers: request.query.populatePlayers }); + if (guild.guild === null) { + return response.status(404).json(guild); + } + return response.json(guild); + } catch (error) { + callback(error); + } + }, + }, + }, + '/guilds/id/{guildID}': { + get: { + summary: 'Get guild stats by the name of the guild', + description: 'Look up a guild from the its name', + operationId: 'guild', + tags: [ + 'guild', + ], + parameters: [ + guildIDParam, populatePlayersParam, + ], + responses: { + 200: { + description: 'successful operation', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + name: { + description: 'Guild\'s name', + type: 'string', + }, + id: { + description: 'Guild id used in hypixel backend', + type: 'string', + }, + created: { + description: 'Guild creation date', + type: 'string', + }, + tag: { + description: 'Guild tag', + type: 'string', + }, + tag_color: { + description: 'Formatting code for the guild tag', + type: 'string', + }, + tag_formatted: { + description: 'Formatted tag string e.g. \'&b[TAG]\'', + type: 'string', + }, + legacy_ranking: { + description: 'Ranking in the number of guild coins owned in the legacy guild system', + type: 'integer', + }, + exp: { + description: 'Total guild xp', + type: 'integer', + }, + level: { + description: 'Guild level', + type: 'number', + }, + exp_by_game: { + description: 'Guild EXP earned in each minigame', + type: 'integer', + }, + exp_history: { + description: 'Contains raw guild xp earned in the past week. Uses format YYYY-MM-DD.', + type: 'object', + }, + description: { + description: 'Guild description', + type: 'string', + }, + preferred_games: { + description: 'Array containing the guild\'s preferred games', + type: 'array', + items: { + type: 'string', + }, + }, + ranks: { + type: 'array', + items: { + type: 'object', + properties: { + name: { + type: 'string', + }, + permissions: { + type: 'array', + items: { + type: 'number', + }, + }, + default: { + type: 'boolean', + }, + tag: { + type: 'string', + }, + created: { + type: 'integer', + }, + priority: { + type: 'integer', + }, + }, + }, + }, + members: { + description: 'Array playerof players on the guild', + type: 'array', + items: { + type: 'object', + properties: { + uuid: { + description: 'Player UUID', + type: 'string', + }, + rank: { + description: 'Player rank in the guild', + type: 'string', + }, + joined: { + description: 'Member join date', + type: 'integer', + }, + quest_participation: { + description: 'How many much the member has contributed to guild quests', + type: 'integer', + }, + exp_history: { + description: 'Contains raw guild xp earned in the past week. Uses format YYYY-MM-DD.', + type: 'object', + }, + muted_till: { + description: 'Date the member is muted until', + type: 'integer', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + route: () => '/guilds/id/:id', + func: async (request, response, callback) => { + try { + const guild = await getGuildFromID(request.params.id, { shouldPopulatePlayers: request.query.populatePlayers }); if (guild.guild === null) { return response.status(404).json(guild); } diff --git a/store/buildGuild.js b/store/buildGuild.js index 8bd94d58..81c0df84 100644 --- a/store/buildGuild.js +++ b/store/buildGuild.js @@ -119,4 +119,15 @@ async function getGuildFromName(guildName, { shouldPopulatePlayers = false } = { return guild; } -module.exports = { getGuildFromPlayer, getGuildFromName, getGuildData }; +async function getGuildFromID(guildID, { shouldPopulatePlayers = false } = {}) { + const guild = await getGuildData(guildID); + if (shouldPopulatePlayers) { + const players = await populatePlayers(guild.members); + guild.members = players; + } + return guild; +} + +module.exports = { + getGuildFromPlayer, getGuildFromName, getGuildData, getGuildFromID, +}; diff --git a/test/test.js b/test/test.js index 4027367b..c6003a29 100644 --- a/test/test.js +++ b/test/test.js @@ -116,7 +116,8 @@ describe('api', () => { || path.endsWith('/status') || path.endsWith('/friends') || path.includes('/bazaar') - || path.includes('/guilds/name')) { + || path.includes('/guilds/name') + || path.includes('guilds/id')) { return callback__(error); } return supertest(app)[verb](`/api${replacedPath}?q=testsearch`).end((error, response) => {