From 6fcb38c75b7cefb1943aaf7bdcad045471ead9b5 Mon Sep 17 00:00:00 2001 From: ruben Date: Sun, 10 Mar 2024 01:33:06 +0100 Subject: [PATCH 1/5] Cambios Endpoint --- webapp/.env | 3 ++- webapp/src/components/Game.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/webapp/.env b/webapp/.env index c810bde7..c421c87a 100644 --- a/webapp/.env +++ b/webapp/.env @@ -1 +1,2 @@ -REACT_APP_API_ENDPOINT=http://localhost:8000 \ No newline at end of file +REACT_APP_API_ENDPOINT=http://localhost:8000 +REACT_GENERATOR_APP_API_ENDPOINT=http://localhost:8003 \ No newline at end of file diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index dc4a1ed9..b3a9bb74 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -3,7 +3,7 @@ import axios from 'axios'; import LinearProgress from '@mui/material/LinearProgress'; import { Container, Typography, Button, Snackbar } from '@mui/material'; -const apiEndpoint = 'http://localhost:8003'; +const apiEndpoint = process.env.REACT_GENERATOR_APP_API_ENDPOINT || 'http://localhost:8003'; const Game = () => { const [question, setQuestion] = useState(''); From af1537421c0bcd98e30fe7909de12f77d68a56c2 Mon Sep 17 00:00:00 2001 From: ruben Date: Mon, 25 Mar 2024 18:34:29 +0100 Subject: [PATCH 2/5] =?UTF-8?q?A=C3=B1adidas=20las=20preguntas=20con=20ima?= =?UTF-8?q?genes=20al=20generador=20de=20preguntas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 2 +- questiongenerator/Dockerfile | 3 + questiongenerator/image_questions.js | 24 ++++++++ questiongenerator/question.js | 86 ++++++++++++++-------------- questiongenerator/text_questions.js | 42 ++++++++++++++ webapp/Dockerfile | 2 - webapp/src/components/Game.js | 7 ++- 7 files changed, 118 insertions(+), 48 deletions(-) create mode 100644 questiongenerator/image_questions.js create mode 100644 questiongenerator/text_questions.js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a147ac10..cd15e8ba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -54,7 +54,7 @@ jobs: uses: elgohr/Publish-Docker-Github-Action@v5 env: API_URI: http://${{ secrets.DEPLOY_HOST }}:8000 - API_GENERATOR_URI: http://${{ secrets.DEPLOY_HOST }}:8003 + API_GENERATOR_URI: http://${{ secrets.DEPLOY_HOST }}:3000 with: name: arquisoft/wiq_es2c/webapp username: ${{ github.actor }} diff --git a/questiongenerator/Dockerfile b/questiongenerator/Dockerfile index dea484cb..067e5357 100644 --- a/questiongenerator/Dockerfile +++ b/questiongenerator/Dockerfile @@ -16,5 +16,8 @@ COPY . . # Expose the port the app runs on EXPOSE 8003 +ARG API_GENERATOR_URI="http://localhost:3000" +ENV REACT_APP_API_GENERATOR_ENDPOINT=$API_GENERATOR_URI + # Define the command to run your app CMD ["node", "question.js"] diff --git a/questiongenerator/image_questions.js b/questiongenerator/image_questions.js new file mode 100644 index 00000000..7bda8f2f --- /dev/null +++ b/questiongenerator/image_questions.js @@ -0,0 +1,24 @@ +// Todas las consultas +var queries = [`SELECT ?option ?optionLabel ?imageLabel + WHERE { + ?option wdt:P31 wd:Q5; + wdt:P39 wd:Q11696; + wdt:P18 ?imageLabel. + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],es". } + } + `,`SELECT DISTINCT ?option ?optionLabel ?imageLabel + WHERE { + ?option wdt:P31 wd:Q6256; + rdfs:label ?optionLabel; + + OPTIONAL { ?option wdt:P18 ?imageLabel. } + FILTER(lang(?optionLabel) = "es") + FILTER EXISTS { ?option wdt:P18 ?imageLabel } + } + `]; + +// Todas las preguntas, en el mismo orden que las consultas +var questions = ["¿Que presidente de EE.UU es el que se muestra en la imagen?", + "¿Que país es el que aparece en la siguiente imagen?"]; + +module.exports = { queries, questions }; \ No newline at end of file diff --git a/questiongenerator/question.js b/questiongenerator/question.js index 673b1dca..2c1da4ef 100644 --- a/questiongenerator/question.js +++ b/questiongenerator/question.js @@ -3,6 +3,9 @@ const express = require('express'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); const Question = require('./question-model'); +const { queries:textQueries, questions:textQuestions } = require('./text_questions'); +const { queries:imagesQueries, questions:imagesQuestions } = require('./image_questions'); + const app = express(); const port = 8003; @@ -11,51 +14,32 @@ const port = 8003; app.use(bodyParser.json()); // Necesario para poder hacer las peticiones desde Game -// http://localhost:3000 -// app.use((req, res, next) => { - res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); + res.setHeader('Access-Control-Allow-Origin', process.env.REACT_APP_API_GENERATOR_ENDPOINT); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.setHeader('Access-Control-Allow-Credentials', true); next(); }); +var queries = []; +queries = queries.concat(textQueries); +queries = queries.concat(imagesQueries); +console.log(queries.length); +var questions = []; +questions = questions.concat(textQuestions); +questions = questions.concat(imagesQuestions); + var correctOption = ""; var options = []; var question = ""; +var image = ""; var url = 'https://query.wikidata.org/sparql'; var questionToSave = null; -// Todas las consultas -var queries = [`SELECT ?question ?questionLabel ?option ?optionLabel - WHERE { - ?question wdt:P31 wd:Q6256; wdt:P36 ?option. - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],es". } - } - `,` - SELECT ?question ?questionLabel ?option ?optionLabel - WHERE { - ?question wdt:P31 wd:Q476028. - ?question wdt:P115 ?option. - ?question wdt:P17 wd:Q29. - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],es". } - } - `,` - SELECT ?option ?optionLabel ?questionLabel (SUBSTR(?símbolo, 1, 1) AS ?sym) - WHERE { - ?option wdt:P31 wd:Q11344; - wdt:P1086 ?questionLabel. - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE], es". } - } - `]; -// Todas las preguntas, en el mismo orden que las consultas -var questions = ["¿Cuál es la capital de ", - "¿En que campo juega el ", - "¿Cual es el elemento de la tabla periódica número "]; + // Número aleatorio que decide la consulta y la pregunta que se mostrarán var randomNumber; - const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/questiondb'; mongoose.connect(mongoUri); @@ -63,16 +47,16 @@ app.get('/generateQuestion', async (req, res) => { try { await generarPregunta(); var id = saveData(); + // Construcción de la respuesta var response = { responseQuestion: question, responseOptions: options, responseCorrectOption: correctOption, + responseImage: image, question_Id: id }; - - res.status(200).json(response); } catch (error) { res.status(400).json({ error: error.message }); @@ -83,6 +67,7 @@ var server = app.listen(port, () => { }); async function generarPregunta() { + randomNumber = Math.floor(Math.random() * 2); try { // Petición a la API de WikiData randomNumber = Math.floor(Math.random() * queries.length); @@ -115,12 +100,21 @@ function procesarDatos(data) { while (randomIndexes.length < 4) { var randomIndex = Math.floor(Math.random() * data.length); var option = data[randomIndex].optionLabel.value; - var quest = data[randomIndex].questionLabel.value; + var quest = ""; - // Comprobamos que tanto la opción como la pregunta no sean entidades de WikiData ni enlaces - if (!randomIndexes.includes(randomIndex) - && !(option.startsWith("Q") || option.startsWith("http")) - && !(quest.startsWith("Q") || quest.startsWith("http"))) { + // Si es una pregunta de texto hay que coger la parte de la pregunta que falta; si es una pregunta de imagen + // la pregunta ya viene en el array + if('questionLabel' in data[randomIndex]) { + quest = data[randomIndex].questionLabel.value; + } + + // Comprobamos que tanto la opción como la pregunta no sean entidades de WikiData ni enlaces o que la pregunta ya + // venga en el array (estara vacia) + if (!randomIndexes.includes(randomIndex) && (quest == "" + || (!(option.startsWith("Q") || option.startsWith("http")) + && !(quest.startsWith("Q") || quest.startsWith("http")) + ) + )) { randomIndexes.push(randomIndex); } } @@ -128,21 +122,25 @@ function procesarDatos(data) { // Escogemos un índice aleatorio como la opción correcta var correctIndex = Math.floor(Math.random() * 4); correctOption = data[randomIndexes[correctIndex]].optionLabel.value; - questionValue = data[randomIndexes[correctIndex]].questionLabel.value; - question = questions[randomNumber] + questionValue + "?"; + + if(quest == "") { + question = questions[randomNumber]; + image = data[randomIndexes[correctIndex]].imageLabel.value; + } else { + image = ""; + questionValue = data[randomIndexes[correctIndex]].questionLabel.value; + question = questions[randomNumber] + questionValue + "?"; + } + // Varriamos las opciones, incluyendo la correcta for (let i = 0; i < 4; i++) { var optionIndex = randomIndexes[i]; options.push(data[optionIndex].optionLabel.value); } - - - } async function saveData(){ - try { var false_options = options.filter(o => o != correctOption); @@ -180,4 +178,4 @@ app.get('/updateQuestion', async (req, res) => { }); -module.exports = server +module.exports = server \ No newline at end of file diff --git a/questiongenerator/text_questions.js b/questiongenerator/text_questions.js new file mode 100644 index 00000000..d7783221 --- /dev/null +++ b/questiongenerator/text_questions.js @@ -0,0 +1,42 @@ +// Todas las consultas +var queries = [`SELECT ?question ?questionLabel ?option ?optionLabel + WHERE { + ?question wdt:P31 wd:Q6256; wdt:P36 ?option. + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],es". } + } + LIMIT 200 + `,` + SELECT ?question ?questionLabel ?option ?optionLabel + WHERE { + ?question wdt:P31 wd:Q476028. + ?question wdt:P115 ?option. + ?question wdt:P17 wd:Q29. + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],es". } + } + LIMIT 100 + `,` + SELECT ?option ?optionLabel ?questionLabel (SUBSTR(?símbolo, 1, 1) AS ?sym) + WHERE { + ?option wdt:P31 wd:Q11344; + wdt:P1086 ?questionLabel. + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE], es". } + } + LIMIT 100 + `,`SELECT ?question ?questionLabel ?optionLabel + WHERE { + ?question wdt:P31 wd:Q178561. + ?question wdt:P580 ?date. + FILTER (YEAR(?date) >= 1500 && YEAR(?date) <= 1945) + BIND(YEAR(?date) as ?optionLabel) + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],es". } + } + LIMIT 100 + `]; + +// Todas las preguntas, en el mismo orden que las consultas +var questions = ["¿Cuál es la capital de ", + "¿En que campo juega el ", + "¿Cuál es el elemento de la tabla periódica número ", + "¿En que año ocurrio la "]; + +module.exports = { queries, questions }; \ No newline at end of file diff --git a/webapp/Dockerfile b/webapp/Dockerfile index d3cdd542..3cbad8b7 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -8,8 +8,6 @@ RUN npm install ARG API_URI="http://localhost:8000" ENV REACT_APP_API_ENDPOINT=$API_URI -ARG API_GENERATOR_URI="http://localhost:8003" -ENV REACT_APP_API_GENERATOR_ENDPOINT=$API_GENERATOR_URI #Create an optimized version of the webapp RUN npm run build diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index 38444418..40163643 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -4,10 +4,11 @@ import LinearProgress from '@mui/material/LinearProgress'; import { Container, Typography, Button, Snackbar } from '@mui/material'; import { useNavigate } from 'react-router-dom'; -const apiEndpoint = process.env.REACT_APP_API_GENERATOR_ENDPOINT || 'http://localhost:8003'; +const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; const Game = () => { const [question, setQuestion] = useState(''); + const [image, setImage] = useState(''); const [options, setOptions] = useState([]); const [correctOption, setCorrectOption] = useState(""); const [questionId,setQuestionId] = useState(null); @@ -30,6 +31,7 @@ const Game = () => { setQuestion(response.data.responseQuestion); setOptions(response.data.responseOptions); setCorrectOption(response.data.responseCorrectOption); + setImage(response.data.responseImage); setOpenSnackbar(true); setElapsedTime(MAX_TIME); } catch (error) { @@ -102,6 +104,9 @@ const Game = () => { {question} +
+ {image != null && image != "" && Imagen de la pregunta} +
{options.map((option, index) => (