mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-05-10 21:00:37 -05:00
198 lines
5.2 KiB
JavaScript
198 lines
5.2 KiB
JavaScript
const { UserInputError, gql } = require("apollo-server-express")
|
|
const Placement = require("../mongoose-models/placement")
|
|
const Player = require("../mongoose-models/player")
|
|
|
|
const typeDef = gql`
|
|
extend type Query {
|
|
topPlayers(weapon: String!): topPlayer!
|
|
playerInfo(uid: String, twitter: String): PlayerWithPlacements
|
|
searchForPlayers(name: String!, exact: Boolean): [Placement]!
|
|
searchForPlacements(
|
|
name: String
|
|
weapon: String
|
|
mode: Int
|
|
unique_id: String
|
|
month: Int
|
|
year: Int
|
|
page: Int
|
|
): PlacementCollection!
|
|
}
|
|
type Placement {
|
|
id: ID!
|
|
name: String!
|
|
weapon: String!
|
|
rank: Int!
|
|
mode: Int!
|
|
x_power: Float!
|
|
unique_id: String!
|
|
month: Int!
|
|
year: Int!
|
|
player: Player!
|
|
}
|
|
type topPlayer {
|
|
placements: [Placement!]!
|
|
modeCount: [Int!]!
|
|
}
|
|
type PlayerWithPlacements {
|
|
player: Player!
|
|
placements: [Placement!]!
|
|
}
|
|
type PlacementCollection {
|
|
placements: [Placement]!
|
|
pageCount: Int!
|
|
}
|
|
`
|
|
const resolvers = {
|
|
Query: {
|
|
topPlayers: async (root, args) => {
|
|
const placements = await Placement.find({ weapon: args.weapon })
|
|
.sort({ x_power: "desc" })
|
|
.select({ weapon: 0 })
|
|
.catch(e => {
|
|
throw new UserInputError(e.message, {
|
|
invalidArgs: args,
|
|
})
|
|
})
|
|
|
|
const m = placements.reduce(
|
|
(acc, cur) => {
|
|
if (cur.mode === 1) {
|
|
acc.sz++
|
|
} else if (cur.mode === 2) {
|
|
acc.tc++
|
|
} else if (cur.mode === 3) {
|
|
acc.rm++
|
|
} else {
|
|
acc.cb++
|
|
}
|
|
|
|
return acc
|
|
},
|
|
{ sz: 0, tc: 0, rm: 0, cb: 0 }
|
|
)
|
|
|
|
return {
|
|
placements: placements.slice(0, 101),
|
|
modeCount: [m.sz + m.tc + m.rm + m.cb, m.sz, m.tc, m.rm, m.cb],
|
|
}
|
|
},
|
|
playerInfo: async (root, args) => {
|
|
let searchCriteria = {}
|
|
if (args.uid) searchCriteria = { unique_id: args.uid }
|
|
else if (args.twitter)
|
|
searchCriteria = { twitter: args.twitter.toLowerCase() }
|
|
else
|
|
throw new UserInputError("no id or twitter provided", {
|
|
invalidArgs: args,
|
|
})
|
|
const player = await Player.findOne(searchCriteria).catch(e => {
|
|
throw new UserInputError(e.message, {
|
|
invalidArgs: args,
|
|
})
|
|
})
|
|
|
|
if (!player) {
|
|
return null
|
|
}
|
|
|
|
const placements = await Placement.find({ unique_id: player.unique_id })
|
|
.sort({ year: "desc", month: "desc" })
|
|
.catch(e => {
|
|
throw new UserInputError(e.message, {
|
|
invalidArgs: args,
|
|
})
|
|
})
|
|
|
|
return { player, placements }
|
|
},
|
|
searchForPlayers: async (root, args) => {
|
|
let placements = []
|
|
if (args.exact) {
|
|
placements = await Placement.find({ name: args.name })
|
|
.sort({ x_power: "desc" })
|
|
.limit(100)
|
|
.select({ name: 1, weapon: 1, x_power: 1, unique_id: 1 })
|
|
.catch(e => {
|
|
throw new UserInputError(e.message, {
|
|
invalidArgs: args,
|
|
})
|
|
})
|
|
} else {
|
|
placements = await Placement.find({
|
|
name: { $regex: args.name, $options: "i" },
|
|
})
|
|
.sort({ x_power: "desc" })
|
|
.limit(100)
|
|
.select({ name: 1, weapon: 1, x_power: 1, unique_id: 1 })
|
|
.catch(e => {
|
|
throw new UserInputError(e.message, {
|
|
invalidArgs: args,
|
|
})
|
|
})
|
|
}
|
|
|
|
let uids = []
|
|
|
|
return placements.filter(p => {
|
|
if (uids.length === 21) {
|
|
return false
|
|
}
|
|
const bool = uids.includes(p.unique_id)
|
|
if (bool) {
|
|
return false
|
|
}
|
|
uids.push(p.unique_id)
|
|
return true
|
|
})
|
|
},
|
|
searchForPlacements: async (root, args) => {
|
|
const perPage = 25
|
|
const currentPage = args.page ? args.page - 1 : 0
|
|
const searchCriteria = {}
|
|
|
|
if (args.name)
|
|
searchCriteria.name = { $regex: new RegExp(args.name, "i") }
|
|
if (args.weapon) searchCriteria.weapon = args.weapon
|
|
if (args.mode) searchCriteria.mode = args.mode
|
|
if (args.unique_id) searchCriteria.unique_id = args.unique_id
|
|
if (args.month) searchCriteria.month = args.month
|
|
if (args.year) searchCriteria.year = args.year
|
|
|
|
const placementCount = await Placement.countDocuments(
|
|
searchCriteria
|
|
).catch(e => {
|
|
throw new UserInputError(e.message, {
|
|
invalidArgs: args,
|
|
})
|
|
})
|
|
|
|
const pageCount = Math.ceil(placementCount / perPage)
|
|
// if 0 documents we don't care if the page is wrong
|
|
if (placementCount !== 0) {
|
|
if (args.page > pageCount)
|
|
throw new UserInputError("too big page number given", {
|
|
invalidArgs: args,
|
|
})
|
|
}
|
|
|
|
const placements = await Placement.find(searchCriteria)
|
|
.skip(perPage * currentPage)
|
|
.limit(perPage)
|
|
.sort({ x_power: "desc" })
|
|
.populate("player")
|
|
.catch(e => {
|
|
throw new UserInputError(e.message, {
|
|
invalidArgs: args,
|
|
})
|
|
})
|
|
|
|
return { pageCount, placements }
|
|
},
|
|
},
|
|
}
|
|
|
|
module.exports = {
|
|
Placement: typeDef,
|
|
placementResolvers: resolvers,
|
|
}
|