From 6bb3a12310b09fc867f464dd1e9f65f9eac82225 Mon Sep 17 00:00:00 2001 From: uo287841 Date: Tue, 2 Apr 2024 20:53:45 +0200 Subject: [PATCH 1/6] Questions has an score, when the game starts it is set to 0 and for every question the user has right it increase its value in 1. --- webapp/src/components/Question.jsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/webapp/src/components/Question.jsx b/webapp/src/components/Question.jsx index 930be01..a95a021 100644 --- a/webapp/src/components/Question.jsx +++ b/webapp/src/components/Question.jsx @@ -6,6 +6,7 @@ const Question = (props) => { const [question, setQuestion] = useState([]); const [loading, setLoading] = useState(true); const [counter, setCounter] = useState(0); + const [score, setScore] = useState(0) useEffect(() => { const interval = setInterval(() => { @@ -42,10 +43,14 @@ const Question = (props) => { setLoading(true); const result = await axios.post(`${apiEndpoint}/${props.type}/answer`, { answer }); const res = await axios.get(`${apiEndpoint}/${props.type}/${props.category}/question`); + if ( result.data.correct === "true" ) { + setScore(score +1); + } setQuestion(res.data); setLoading(false); setCounter(0); + } catch (error) { console.log(error); } @@ -58,6 +63,9 @@ const Question = (props) => { return (
+
+ Score: {score} +
{loading ? (

From c6725bec4258d66e8aef9ddcdb0223ff7e5c0611 Mon Sep 17 00:00:00 2001 From: uo287841 Date: Thu, 4 Apr 2024 15:12:15 +0200 Subject: [PATCH 2/6] add Points to the game and to the ranking --- .vscode/launch.json | 15 +++++++++++ questionservice/question-service.js | 42 +++++++++++++++++++++++++++-- webapp/src/components/Question.jsx | 6 +++-- 3 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f6b35a0 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/questionservice/question-service.js b/questionservice/question-service.js index 56e1cfe..7cc764f 100644 --- a/questionservice/question-service.js +++ b/questionservice/question-service.js @@ -204,12 +204,49 @@ app.get('/imgs/foods/question', async (req, res) => { * or not "false". In case it was incorrect, the chosen * associate will be returned as well */ +app.post('/imgs/answer', async (req, res) => { + const { answer, username } = req.body; + + try { + // Check if the answer is correct + if (correctImg === answer) { + // Check if the username exists + const user = await User.findOne({ username }); + if (!user) { + throw new Error('User not found'); + } + + // Add points to the user + user.points += 1; + await user.save(); + + // Send response indicating correct answer and updated user + res.status(200).json({ + correct: true + }); + } else { + // Send response indicating incorrect answer + res.status(200).json({ + correct: false, + country: `${imgToAssociatedMap.get(answer)}` + }); + } + } catch (error) { + // Send error response if any exception occurs + res.status(400).json({ error: error.message }); + } +}); + + +/* app.post('/imgs/answer', (req, res) => { - const answer = req.body; + const { answer, username } = req.body; + if(correctImg==answer){ res.status(200).json({ - correct: "true" + correct: "true", + user: username }) } else { res.status(200).json({ @@ -222,3 +259,4 @@ app.post('/imgs/answer', (req, res) => { app.listen(port, () => { console.log(`Questions service listening on http://localhost:${port}`); }); +*/ diff --git a/webapp/src/components/Question.jsx b/webapp/src/components/Question.jsx index a95a021..fa3b617 100644 --- a/webapp/src/components/Question.jsx +++ b/webapp/src/components/Question.jsx @@ -1,12 +1,14 @@ import React, { useState, useEffect } from "react"; import axios from "axios"; +import useAuthUser from "react-auth-kit/hooks/useAuthUser"; const Question = (props) => { const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; const [question, setQuestion] = useState([]); const [loading, setLoading] = useState(true); const [counter, setCounter] = useState(0); - const [score, setScore] = useState(0) + const [score, setScore] = useState(0); + const auth = useAuthUser(); useEffect(() => { const interval = setInterval(() => { @@ -41,7 +43,7 @@ const Question = (props) => { const answerQuestion = async (answer) => { try { setLoading(true); - const result = await axios.post(`${apiEndpoint}/${props.type}/answer`, { answer }); + const result = await axios.post(`${apiEndpoint}/${props.type}/answer`, { answer: answer, username: auth.username }); const res = await axios.get(`${apiEndpoint}/${props.type}/${props.category}/question`); if ( result.data.correct === "true" ) { setScore(score +1); From 619633460a98016df74ce3c2eeafef3164921e2d Mon Sep 17 00:00:00 2001 From: uo287841 Date: Thu, 4 Apr 2024 21:19:28 +0200 Subject: [PATCH 3/6] Fix issue in question service that didnt read body values correctly --- gatewayservice/gateway-service.js | 4 +++- questionservice/question-service.js | 9 ++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 41540bf..effb539 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -101,8 +101,10 @@ app.get('/imgs/foods/question', async (req, res) => { app.post('/imgs/answer', async (req, res) => { try { const answer = req.body.answer; + const username = req.body.username; + // Forward the request to the question service - const questionResponse = await axios.post(questionServiceUrl+'/imgs/answer', answer, { headers: {'Content-Type': 'text/plain'} }); + const questionResponse = await axios.post(questionServiceUrl+'/imgs/answer', {answer, username }, { headers: {'Content-Type': 'text/plain'} }); res.json(questionResponse.data); } catch (error) { res.status(error.response.status).json({ error: error.response.data.error }); diff --git a/questionservice/question-service.js b/questionservice/question-service.js index 7cc764f..c0cbb6a 100644 --- a/questionservice/question-service.js +++ b/questionservice/question-service.js @@ -204,6 +204,7 @@ app.get('/imgs/foods/question', async (req, res) => { * or not "false". In case it was incorrect, the chosen * associate will be returned as well */ +/* app.post('/imgs/answer', async (req, res) => { const { answer, username } = req.body; @@ -236,12 +237,11 @@ app.post('/imgs/answer', async (req, res) => { res.status(400).json({ error: error.message }); } }); +*/ -/* app.post('/imgs/answer', (req, res) => { - const { answer, username } = req.body; - + const { answer, username } =JSON.parse(req.body); if(correctImg==answer){ res.status(200).json({ @@ -255,8 +255,7 @@ app.post('/imgs/answer', (req, res) => { }) } }); - app.listen(port, () => { console.log(`Questions service listening on http://localhost:${port}`); }); -*/ + From 9e5c4d12f3acac5b798b0af9cbd99d8edede07a2 Mon Sep 17 00:00:00 2001 From: uo287841 Date: Thu, 4 Apr 2024 21:29:20 +0200 Subject: [PATCH 4/6] Update ranking points --- gatewayservice/gateway-service.js | 6 ++++++ users/userservice/user-service.js | 32 +++++++++++++++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index effb539..7f9b4c0 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -105,6 +105,12 @@ app.post('/imgs/answer', async (req, res) => { // Forward the request to the question service const questionResponse = await axios.post(questionServiceUrl+'/imgs/answer', {answer, username }, { headers: {'Content-Type': 'text/plain'} }); + + if (questionResponse.data.correct === "true"){ + await axios.post(userServiceUrl+'/addpoints', {username: username } ); + console.log("done"); + } + res.json(questionResponse.data); } catch (error) { res.status(error.response.status).json({ error: error.response.data.error }); diff --git a/users/userservice/user-service.js b/users/userservice/user-service.js index c85da76..0a63f67 100644 --- a/users/userservice/user-service.js +++ b/users/userservice/user-service.js @@ -57,22 +57,22 @@ app.get('/rankings', async (req, res) => { }) -// app.post("/addpoints", async (req, res) => { -// try { -// validateRequiredFields(req, ['username']); -// const user = await User.findOne({ -// username: req.body.username -// }); -// if (!user) { -// throw new Error('User not found'); -// } -// user.points += 1; -// await user.save(); -// res.status(200).json(user); -// } catch (error) { -// res.status(400).json({ error: error.message }); -// } -// }); + app.post("/addpoints", async (req, res) => { + try { + validateRequiredFields(req, ['username']); + const user = await User.findOne({ + username: req.body.username + }); + if (!user) { + throw new Error('User not found'); + } + user.points += 1; + await user.save(); + res.status(200).json(user); + } catch (error) { + res.status(400).json({ error: error.message }); + } + }); app.post('/adduser', async (req, res) => { try { From a4b967f5cff13d424a6a9f1201276cd05258438c Mon Sep 17 00:00:00 2001 From: uo287841 Date: Thu, 4 Apr 2024 22:18:32 +0200 Subject: [PATCH 5/6] Move addUserPoints to question-service --- gatewayservice/gateway-service.js | 5 - questionservice/package-lock.json | 287 ++++++++++++++++++++++++++++ questionservice/package.json | 2 + questionservice/question-service.js | 78 ++++++-- 4 files changed, 348 insertions(+), 24 deletions(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 7f9b4c0..b41844a 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -105,11 +105,6 @@ app.post('/imgs/answer', async (req, res) => { // Forward the request to the question service const questionResponse = await axios.post(questionServiceUrl+'/imgs/answer', {answer, username }, { headers: {'Content-Type': 'text/plain'} }); - - if (questionResponse.data.correct === "true"){ - await axios.post(userServiceUrl+'/addpoints', {username: username } ); - console.log("done"); - } res.json(questionResponse.data); } catch (error) { diff --git a/questionservice/package-lock.json b/questionservice/package-lock.json index 6ea2cf7..1e38e86 100644 --- a/questionservice/package-lock.json +++ b/questionservice/package-lock.json @@ -5,10 +5,33 @@ "packages": { "": { "dependencies": { + "axios": "^1.6.8", "express": "^4.18.3", + "mongoose": "^8.3.0", "wikibase-sdk": "^8.1.1" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz", + "integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", + "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -26,6 +49,21 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -49,6 +87,14 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/bson": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.6.0.tgz", + "integrity": "sha512-BVINv2SgcMjL4oYbBuCQTpE3/VKOSxrOA8Cj/wQP7izSzlBGVomdm+TcUd0Pzy0ytLSSDweCKQ6X3f5veM5LQA==", + "engines": { + "node": ">=16.20.1" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -75,6 +121,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -131,6 +188,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -251,6 +316,38 @@ "node": ">= 0.8" } }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -387,6 +484,14 @@ "node": ">= 0.10" } }, + "node_modules/kareem": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.0.tgz", + "integrity": "sha512-B9wwgyKKKZkxYZXQzefvb/Ykh9eHixxR+ttTP2c/Pq8NvHi1iYIAImf3nj/DXkPcnenjGEffhPWXnCFRIbNAhw==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -395,6 +500,11 @@ "node": ">= 0.6" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -438,6 +548,126 @@ "node": ">= 0.6" } }, + "node_modules/mongodb": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", + "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.4.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", + "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongoose": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.3.0.tgz", + "integrity": "sha512-Y5QNnuA38CEin8hnA+q//nUVztIi4Xklu9xlmbkd1KdWHnIlemSwf5IL/evcI+e2zplL4g5Y6PMkO+nPSAnIdA==", + "dependencies": { + "bson": "^6.5.0", + "kareem": "2.6.0", + "mongodb": "6.5.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -495,6 +725,19 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -635,6 +878,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -651,6 +907,17 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -687,6 +954,26 @@ "node": ">= 0.8" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/wikibase-sdk": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/wikibase-sdk/-/wikibase-sdk-8.1.1.tgz", diff --git a/questionservice/package.json b/questionservice/package.json index b6071ef..4bb70ba 100644 --- a/questionservice/package.json +++ b/questionservice/package.json @@ -4,7 +4,9 @@ "test": "jest" }, "dependencies": { + "axios": "^1.6.8", "express": "^4.18.3", + "mongoose": "^8.3.0", "wikibase-sdk": "^8.1.1" } } diff --git a/questionservice/question-service.js b/questionservice/question-service.js index c0cbb6a..454e58d 100644 --- a/questionservice/question-service.js +++ b/questionservice/question-service.js @@ -7,6 +7,25 @@ const express = require('express'); const app = express(); const port = 8010; +const axios = require('axios'); +const userServiceUrl = process.env.USER_SERVICE_URL || 'http://localhost:8001'; + +/* +const User = require('../users/userservice/user-model'); +const mongoose = require('mongoose'); +const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/wiq-en1a-users'; +mongoose.connect(mongoUri); + +const mongo = mongoose.connection; + +// Check connection done correctly +mongo.on('error', console.error.bind(console, 'MongoDB connection error:')); +mongo.once('open', function () { + console.log('Connected to MongoDB successfully'); +}); +*/ + + app.use(express.static('public')); app.use(express.text()); @@ -197,6 +216,15 @@ app.get('/imgs/foods/question', async (req, res) => { res.json(question); }); + +function validateRequiredFields(req, requiredFields) { + for (const field of requiredFields) { + if (!(field in req.body)) { + throw new Error(`Missing required field: ${field}`); + } + } +} + /** * Gets a response indicating if the chosen img was correct or not * @param {string} req - img url selected by the player @@ -204,15 +232,35 @@ app.get('/imgs/foods/question', async (req, res) => { * or not "false". In case it was incorrect, the chosen * associate will be returned as well */ + +app.post('/imgs/answer', async (req, res) => { + const { answer, username } =JSON.parse(req.body); + + if(correctImg==answer){ + await axios.post(userServiceUrl+'/addpoints', {username: username } ); + res.status(200).json({ + correct: "true", + }) + } else { + res.status(200).json({ + correct: "false", + country: `${imgToAssociatedMap.get(answer)}` + }) + } +}); + /* app.post('/imgs/answer', async (req, res) => { - const { answer, username } = req.body; + const { answer, username } =JSON.parse(req.body); try { + // Check if the answer is correct if (correctImg === answer) { // Check if the username exists - const user = await User.findOne({ username }); + const user = await User.findOne({ + username: username + }); if (!user) { throw new Error('User not found'); } @@ -234,28 +282,20 @@ app.post('/imgs/answer', async (req, res) => { } } catch (error) { // Send error response if any exception occurs + console.log(error); res.status(400).json({ error: error.message }); } }); */ - -app.post('/imgs/answer', (req, res) => { - const { answer, username } =JSON.parse(req.body); - - if(correctImg==answer){ - res.status(200).json({ - correct: "true", - user: username - }) - } else { - res.status(200).json({ - correct: "false", - country: `${imgToAssociatedMap.get(answer)}` - }) - } -}); -app.listen(port, () => { +const server = app.listen(port, () => { console.log(`Questions service listening on http://localhost:${port}`); }); +/* +// Listen for the 'close' event on the Express.js server +server.on('close', () => { + // Close the Mongoose connection + mongoose.connection.close(); +});*/ + From 2eace1df3af70fe5ee4abbf99f25bdb743135448 Mon Sep 17 00:00:00 2001 From: uo287841 Date: Sat, 6 Apr 2024 12:59:48 +0200 Subject: [PATCH 6/6] Add points updated to the new user-moce, updates the global ranking and the particular category values depending if the answer is correct or not --- gatewayservice/gateway-service.js | 3 ++- questionservice/question-service.js | 7 +++++-- users/userservice/user-service.js | 28 +++++++++++++++++++++++++--- webapp/src/components/Question.jsx | 2 +- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 8587970..343fb31 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -102,9 +102,10 @@ app.post('/imgs/answer', async (req, res) => { try { const answer = req.body.answer; const username = req.body.username; + const category = req.body.category; // Forward the request to the question service - const questionResponse = await axios.post(questionServiceUrl+'/imgs/answer', {answer, username }, { headers: {'Content-Type': 'text/plain'} }); + const questionResponse = await axios.post(questionServiceUrl+'/imgs/answer', {answer, username, category }, { headers: {'Content-Type': 'text/plain'} }); res.json(questionResponse.data); } catch (error) { diff --git a/questionservice/question-service.js b/questionservice/question-service.js index 454e58d..594ac54 100644 --- a/questionservice/question-service.js +++ b/questionservice/question-service.js @@ -234,14 +234,17 @@ function validateRequiredFields(req, requiredFields) { */ app.post('/imgs/answer', async (req, res) => { - const { answer, username } =JSON.parse(req.body); + const { answer, username, category } =JSON.parse(req.body); if(correctImg==answer){ - await axios.post(userServiceUrl+'/addpoints', {username: username } ); + await axios.post(userServiceUrl+'/addpoints', + {username: username, category: category, correct: "true" } ); res.status(200).json({ correct: "true", }) } else { + await axios.post(userServiceUrl+'/addpoints', + {username: username, category: category, correct: "false" } ); res.status(200).json({ correct: "false", country: `${imgToAssociatedMap.get(answer)}` diff --git a/users/userservice/user-service.js b/users/userservice/user-service.js index 7166cc7..7cdf1c3 100644 --- a/users/userservice/user-service.js +++ b/users/userservice/user-service.js @@ -69,15 +69,37 @@ app.get('/rankings/:filter', async (req, res) => { app.post("/addpoints", async (req, res) => { - try { - validateRequiredFields(req, ['username']); + const username = req.body.username; + const category = req.body.category; + const correct = req.body.correct; + + + try { + validateRequiredFields(req, ['username','category','correct']); const user = await User.findOne({ username: req.body.username }); if (!user) { throw new Error('User not found'); } - user.points += 1; + + // updates global and category questions + user.ranking.global.questions += 1; + user.ranking[category].questions += 1; + + + // Answer is correct + if ( correct === "true"){ + user.ranking[category].points += 1; + user.ranking[category].correct += 1; + user.ranking.global.points += 1; + user.ranking.global.correct += 1; + } + else{ // Answer is wrong + user.ranking[category].wrong += 1; + user.ranking.global.wrong += 1; + } + await user.save(); res.status(200).json(user); } catch (error) { diff --git a/webapp/src/components/Question.jsx b/webapp/src/components/Question.jsx index fa3b617..1c02425 100644 --- a/webapp/src/components/Question.jsx +++ b/webapp/src/components/Question.jsx @@ -43,7 +43,7 @@ const Question = (props) => { const answerQuestion = async (answer) => { try { setLoading(true); - const result = await axios.post(`${apiEndpoint}/${props.type}/answer`, { answer: answer, username: auth.username }); + const result = await axios.post(`${apiEndpoint}/${props.type}/answer`, { answer: answer, username: auth.username, category: props.category }); const res = await axios.get(`${apiEndpoint}/${props.type}/${props.category}/question`); if ( result.data.correct === "true" ) { setScore(score +1);