diff --git a/src/server/index.js b/src/server/index.js index 8504eda..b788772 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -21,6 +21,7 @@ api.use(function(req, res, next) { res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); +api.use(require('express-log-url')); // #endregion @@ -161,4 +162,46 @@ api.post("/tournament/create", (req, res) => { .catch(err => res.json({"status": "error", "data": err})) .then(msg => res.json({"status": "OK", "data": msg})); }); + +api.post("/tournament/:tournamentId/edit", (req, res) => { + let tournamentId = req.params.tournamentId; + if (isNaN(tournamentId)) { + res.json({"status": "error", "data": "tournamentId must be a number"}); + return + } + tournamentId = parseInt(tournamentId); + let name = req.body.name; + let description = req.body.description; + let startDate = req.body.startDate; + let endDate = req.body.endDate; + console.log(startDate); + if (name == undefined || name == "" || description == undefined || description == "") { + res.json({"status": "error", "data": "name and description must be provided"}); + return + } + if (startDate == undefined || endDate == undefined) { + res.json({"status": "error", "data": "startDate and endDate must be defined"}); + return + } + try { + startDate = new Date(startDate); + endDate = new Date(endDate); + } catch (err) { + res.json({"status": "error", "data": "startDate and endDate must be valid dates"}); + return + } + // let today = new Date(); + // if (startDate < today) { + // res.json({"status": "error", "data": "startDate cannot be in the past"}); + // return + // } + if (startDate > endDate) { + res.json({"status": "error", "data": "startDate cannot be after endDate"}); + return + } + + tmdb.editTournament(tournamentId, name, description, startDate, endDate) + .catch(err => res.json({"status": "error", "data": err})) + .then(msg => res.json({"status": "OK", "data": msg})); +}); // #endregion \ No newline at end of file diff --git a/src/server/package-lock.json b/src/server/package-lock.json index 30e2427..07ff362 100644 --- a/src/server/package-lock.json +++ b/src/server/package-lock.json @@ -12,6 +12,7 @@ "dotenv": "^16.0.0", "ejs": "^3.1.6", "express": "^4.17.3", + "express-log-url": "^1.5.1", "mysql": "^2.18.1", "sequelize": "^6.17.0" }, @@ -103,7 +104,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -288,7 +288,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -304,7 +303,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -313,7 +311,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -379,7 +376,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -390,8 +386,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/concat-map": { "version": "0.0.1", @@ -652,6 +647,14 @@ "node": ">= 0.10.0" } }, + "node_modules/express-log-url": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/express-log-url/-/express-log-url-1.5.1.tgz", + "integrity": "sha512-72eLutsZY7PgP9/c3L962yLl4tmhmfgupoOFudWa11WzLgvfIHkC9lxYoMAF/PQ6aB/E0phY1+TW9YCnjFEtdQ==", + "dependencies": { + "chalk": "^4.1.0" + } + }, "node_modules/filelist": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", @@ -2233,7 +2236,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -2372,7 +2374,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2381,14 +2382,12 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -2436,7 +2435,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -2444,8 +2442,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "concat-map": { "version": "0.0.1", @@ -2655,6 +2652,14 @@ "vary": "~1.1.2" } }, + "express-log-url": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/express-log-url/-/express-log-url-1.5.1.tgz", + "integrity": "sha512-72eLutsZY7PgP9/c3L962yLl4tmhmfgupoOFudWa11WzLgvfIHkC9lxYoMAF/PQ6aB/E0phY1+TW9YCnjFEtdQ==", + "requires": { + "chalk": "^4.1.0" + } + }, "filelist": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", diff --git a/src/server/package.json b/src/server/package.json index 2888015..4d39607 100644 --- a/src/server/package.json +++ b/src/server/package.json @@ -14,6 +14,7 @@ "dotenv": "^16.0.0", "ejs": "^3.1.6", "express": "^4.17.3", + "express-log-url": "^1.5.1", "mysql": "^2.18.1", "sequelize": "^6.17.0" }, diff --git a/src/server/tmdb.js b/src/server/tmdb.js index 8aed35b..49100ad 100644 --- a/src/server/tmdb.js +++ b/src/server/tmdb.js @@ -8,6 +8,7 @@ module.exports = { getMatch: getMatch, setMatchWinner: setMatchWinner, createTournament: createTournament, + editTournament: editTournament, getTeamsByTournamentId: getTeamsByTournamentId, } @@ -84,8 +85,8 @@ function getMatch(matchId) { } // Removes a given team from a given match. This is done by setting the teamId-property containing the given team to null. -function unsetContestant(matchId, teamId) { - let match = getMatch(matchId); +async function unsetContestant(matchId, teamId) { + let match = await getMatch(matchId); if (match.team1Id == teamId) { connection.query("UPDATE matches SET team1Id = NULL WHERE id = ?", [mysql.escape(matchId)], (err, result) => { if (err) { console.log(err); } @@ -110,8 +111,11 @@ function setMatchWinner(matchId, winnerId) { reject("Winner must be one of the teams in the match"); } - // Final match doesn't have a parent + // Final match doesn't have a parent, skip this step if (match.parentMatchId != null) { + if (match.winnerId != null) { + unsetContestant(match.parentMatchId, match.winnerId); + } // Enter the winner of the match into the parent match getMatch(match.parentMatchId) .catch(err =>reject(err)) @@ -159,12 +163,48 @@ function createTournament(name, description, startDate, endDate, teamLimit) { console.log(err); reject(err); } else { + + // Create the matches for the tournament + let tournamentId = sets.insertId; + let tiers = Math.log2(teamLimit); + for (let tier = 0; tier < tiers; tier++) { + let matchCount = Math.pow(2, tier); + for (let matchId = 0; matchId < matchCount; matchId++) { + let parentMatchId = null; + if (tier > 0) { + parentMatchId = Math.pow(2, tier - 1) + Math.floor((matchId - (matchId % 2)) / 2); + } + connection.query("INSERT INTO matches (tournamentId, parentMatchId, tier) VALUES (?, ?, ?)", + [tournamentId, parentMatchId, tier], (err, sets) => { + if (err) { + console.error("Could not create match:"); + console.log(err); + } + }); + } + } resolve("Tournament created"); } }); }); } +function editTournament(tournamentId, name, description, startDate, endDate) { + startDate = startDate.toISOString().slice(0, 19).replace('T', ' '); + endDate = endDate.toISOString().slice(0, 19).replace('T', ' '); + return new Promise(function(resolve, reject) { + connection.query("UPDATE tournaments SET name = ?, description = ?, startTime = ?, endTime = ? WHERE id = ?", + [mysql.escape(name), mysql.escape(description), startDate, endDate, mysql.escape(tournamentId)], (err, sets) => { + if (err) { + console.log(err); + reject(err); + } else { + resolve("Tournament updated"); + } + }); + }); +} + function getTeamsByTournamentId(tournamentId) { return new Promise(function(resolve, reject) { connection.query("SELECT * FROM teams WHERE tournamentId = ?", [mysql.escape(tournamentId)], (err, teams) => {