Skip to content

Commit

Permalink
Masters init (#185)
Browse files Browse the repository at this point in the history
* added teams, seasons, signup pages

* does this fix lintin..

* review fixes, uncomment out steam rank stuff
  • Loading branch information
tristan-gill committed Feb 21, 2021
1 parent eef783b commit 980272c
Show file tree
Hide file tree
Showing 25 changed files with 2,281 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/migrations/037.sql
@@ -0,0 +1,52 @@
CREATE TABLE masters_season (
id varchar(50) PRIMARY KEY NOT NULL,
number integer NOT NULL,
active boolean NOT NULL DEFAULT false,
registration_open boolean NOT NULL DEFAULT false,
UNIQUE(number),
CHECK(number > 0)
);

CREATE TABLE masters_division (
id varchar(50) PRIMARY KEY NOT NULL,
name varchar(100) NOT NULL,
UNIQUE(name)
);

CREATE TABLE masters_team (
id varchar(50) PRIMARY KEY NOT NULL,
season_id varchar(50) NOT NULL REFERENCES masters_season (id),
division_id varchar(50) NOT NULL REFERENCES masters_division (id),
name varchar(100) NOT NULL,
logo varchar(300),
scheduler_discord_id varchar(50),
approved boolean NOT NULL DEFAULT false,
UNIQUE(season_id, name)
);

CREATE TABLE masters_player (
id varchar(50) PRIMARY KEY NOT NULL,
steam_id varchar(50) NOT NULL REFERENCES steam_user (steam_id),
discord_id varchar(50) NOT NULL,
mmr_screenshot varchar(300) NOT NULL DEFAULT '',
UNIQUE(steam_id)
);

CREATE TABLE masters_team_player (
team_id varchar(50) NOT NULL REFERENCES masters_team (id),
player_id varchar(50) NOT NULL REFERENCES masters_player (id),
position int NOT NULL,
UNIQUE(team_id, player_id)
);

CREATE TABLE masters_series (
id varchar(50) PRIMARY KEY NOT NULL,
season_id varchar(50) NOT NULL REFERENCES masters_season (id),
home_team_id varchar(50) NOT NULL REFERENCES masters_team (id),
away_team_id varchar(50) REFERENCES masters_team (id),
home_points integer NOT NULL,
away_points integer NOT NULL,
series_url varchar(100),
round integer NOT NULL,
CHECK(home_team_id != away_team_id)
);
112 changes: 112 additions & 0 deletions src/pages/masters/divisions.js
@@ -0,0 +1,112 @@
const shortid = require('shortid')

async function list(templates, masters, req, res) {
const divisions = await masters.getDivisions()

const html = templates.masters.divisions.list({
user: req.user,
divisions: divisions
})

res.send(html)
}

async function view(templates, masters, req, res) {
const division_id = req.params.division_id
const division = await masters.getDivision(division_id)
const seasons = await masters.getSeasons('DESC')

const html = templates.masters.divisions.view({
user: req.user,
division: division,
seasons: seasons
})

res.send(html)
}

function create(templates, req, res) {
if (!req.user || !req.user.isAdmin) {
res.SendStatus(403)
return
}

const html = templates.masters.divisions.edit({
user: req.user,
verb: 'Create',
csrfToken: req.csrfToken()
})

res.send(html)
}

async function edit(templates, masters, req, res) {
if (!req.user || !req.user.isAdmin) {
res.sendStatus(403)
return
}

const id = req.params.id

const division = await masters.getDivision(id)
const html = templates.masters.divisions.edit({
user: req.user,
verb: 'Edit',
division: division,
csrfToken: req.csrfToken()
})

res.send(html)
}

async function post(masters, req, res) {
if (!req.user || !req.user.isAdmin) {
res.sendStatus(403)
return
}

const division = req.body
division.id = division.id ? division.id : shortid.generate()

await masters.saveDivision(division)
res.redirect('/masters/divisions')
}

async function remove(masters, req, res) {
if (!req.user || !req.user.isAdmin) {
res.sendStatus(403)
return
}

await masters.deleteDivision(req.body.id)
res.redirect('/masters/divisions')
}

module.exports = (templates, masters) => {
return {
list: {
route: '/masters/divisions',
handler: list.bind(null, templates, masters)
},
view: {
route: '/masters/divisions/:division_id',
handler: view.bind(null, templates, masters)
},
create: {
route: '/masters/divisions/create',
handler: create.bind(null, templates)
},
edit: {
route: '/masters/divisions/:id/edit',
handler: edit.bind(null, templates, masters)
},
post: {
route: '/masters/divisions/edit',
handler: post.bind(null, masters)
},
remove: {
route: '/masters/divisions/delete',
handler: remove.bind(null, masters)
}
}
}
16 changes: 16 additions & 0 deletions src/pages/masters/home.js
@@ -0,0 +1,16 @@
const home = (templates, masters, req, res) => {
const html = templates.masters.home({
user: req.user
})

return res.send(html)
}

module.exports = (templates, masters) => {
return {
home: {
route: '/masters',
handler: home.bind(null, templates, masters)
}
}
}
198 changes: 198 additions & 0 deletions src/pages/masters/registration.js
@@ -0,0 +1,198 @@
const shortid = require('shortid')
const request = require('request')
const steamId = require('../../lib/steamId')

async function view(templates, masters, req, res) {
const season_id = req.params.season_id
const division_id = req.params.division_id

const season = await masters.getSeason(season_id)

if (!req.user) {
const html = templates.error.unauthenticated({
user: req.user,
error: `Please log in to be able to register for Season ${season.number}`
})
return res.send(html)
}

const division = await masters.getDivision(division_id)
const player = await masters.getPlayer(req.user.steamId)

const html = templates.masters.registration.edit({
user: req.user,
season,
division,
player,
csrfToken: req.csrfToken()
})
res.send(html)
}

async function shortcut(templates, masters, req, res) {
const season = await masters.getActiveSeason()
req.params.season_id = season.id
return view(templates, masters, req, res)
}

async function directory(templates, masters, req, res) {
const season_id = req.params.season_id
const season = await masters.getSeason(season_id)

if (!req.user) {
const html = templates.error.unauthenticated({
user: req.user,
error: `Please log in to be able to register for Season ${season.number}`
})
return res.send(html)
}

const divisions = await masters.getDivisions()

if (divisions.length === 0) {
const html = templates.error.no_divisions({
user: req.user,
error: 'There don\'t appear to be any active divisions. Ping an admin.'
})
res.send(html)
}

const currentSeasonPlayerTeams = await masters.getPlayerTeams(req.user.steamId, season.id)

const divisionsWithRegistration = divisions.map((d) => {
d.registered = currentSeasonPlayerTeams.some((cspt) => cspt.division_id === d.id)
return d
})

const html = templates.masters.registration.directory({
user: req.user,
season: season,
divisions: divisionsWithRegistration
})
res.send(html)
}

async function directoryShortcut(templates, masters, req, res) {
const season = await masters.getActiveSeason()

if (season) {
req.params.season_id = season.id
return directory(templates, masters, req, res)
} else {
const html = templates.error.no_seasons({
user: req.user
})
res.send(html)
}
}

async function post(templates, masters, steam_user, config, req, res) {
if (!req.user) {
res.sendStatus(403)
return
}

const season = await masters.getSeason(req.body.season_id)
const division = await masters.getDivision(req.body.division_id)

const players = [
{ position: 1 },
{ position: 2 },
{ position: 3 },
{ position: 4 },
{ position: 5 }
]

for (const player of players) {
const steam_id = req.body[`steam_id_${player.position}`]
const mmr_screenshot = req.body[`mmr_screenshot_${player.position}`]
const discord_id = req.body[`discord_name_${player.position}`]

if (!steam_id || !mmr_screenshot || !discord_id) {
return res.sendStatus(400)
}

player.id = shortid.generate()
player.steam_id = steam_id
player.steam_id_64 = steamId.from32to64(steam_id).toString()
player.mmr_screenshot = mmr_screenshot
player.discord_id = discord_id

player.solo_mmr = 0
player.party_mmr = 0
player.rank = 0
player.previous_rank = null
}

const options = {
url: `http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${config.server.steam_api_key}&steamids=${players.map((p) => p.steam_id_64).join(',')}`,
json: true
}
const asyncRequest = () => new Promise((resolve, reject) => request(options, function (error, response, body) {
if( error ){
reject(error)
}
resolve(body)
}))

const playersRequest = await asyncRequest()
const steamPlayers = playersRequest.response.players
for (const steamPlayer of steamPlayers) {
const player = players.find((p) => p.steam_id_64 === steamPlayer.steamid)
player.name = steamPlayer.personaname
player.avatar = (steamPlayer.avatar || '/assets/seal-icon.png').replace('.jpg', '_full.jpg')
}

for (const player of players) {
await steam_user.saveSteamUser(player)
const newPlayer = await masters.savePlayer(player)
player.id = newPlayer.id
}

const team = await masters.saveTeam({
id: shortid.generate(),
season_id: req.body.season_id,
division_id: req.body.division_id,
name: req.body.name,
logo: req.body.logo,
scheduler_discord_id: req.body.scheduler_discord_id,
approved: false
})

for (const player of players) {
await masters.addPlayerToTeam(team.id, player.id, player.position)
}

const html = templates.masters.registration.discord({
user: req.user,
season: season,
division: division
})

res.send(html)
}

module.exports = (templates, masters, steam_user, config) => {
return {
view: {
route: '/masters/seasons/:season_id/divisions/:division_id/register',
handler: view.bind(null, templates, masters)
},
shortcut: {
route: '/masters/divisions/:division_id/register',
handler: shortcut.bind(null, templates, masters)
},
directory: {
route: '/masters/seasons/:season_id/register',
handler: directory.bind(null, templates, masters)
},
directoryShortcut: {
route: '/masters/register',
handler: directoryShortcut.bind(null, templates, masters)
},
post: {
route: '/masters/register',
handler: post.bind(null, templates, masters, steam_user, config)
}
}
}

0 comments on commit 980272c

Please sign in to comment.