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/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js
index 9a0e4601..7f4ddc63 100644
--- a/gatewayservice/gateway-service.js
+++ b/gatewayservice/gateway-service.js
@@ -46,7 +46,19 @@ app.post('/adduser', async (req, res) => {
app.get(`/generateQuestion`, async (req, res) => {
try {
// Forward the add user request to the user service
- const response = await axios.get(generatorUrl+'/generateQuestion', req.body);
+ const URL = generatorUrl + '/generateQuestion?user=' + req.query.user + '&newGame=' + req.query.newGame
+ + '&numberOfQuestions=' + req.query.numberOfQuestions;
+ const response = await axios.get(URL);
+ res.json(response.data);
+ } catch (error) {
+ res.status(error.response.status).json({ error: error.response.data.error });
+ }
+});
+
+app.get(`/updateQuestion`, async (req, res) => {
+ try {
+ // Forward the add user request to the user service
+ const response = await axios.get(generatorUrl+'/updateQuestion', req.body);
res.json(response.data);
} catch (error) {
res.status(error.response.status).json({ error: error.response.data.error });
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..0e2b558c
--- /dev/null
+++ b/questiongenerator/image_questions.js
@@ -0,0 +1,28 @@
+// Todas las consultas
+var queries =
+ // pregunta = Imagen de un presidente de EE.UU., opcion = Nombres de presidentes de EE.UU.
+ [`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". }
+ }
+ `,
+ // pregunta = Imagen de un país, opcion = Pais
+ `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 00b9b1b1..48ad3889 100644
--- a/questiongenerator/question.js
+++ b/questiongenerator/question.js
@@ -4,6 +4,9 @@ const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const Question = require('./question-model');
const Game = require('./game-model');
+const { queries:textQueries, questions:textQuestions } = require('./text_questions');
+const { queries:imagesQueries, questions:imagesQuestions } = require('./image_questions');
+
const app = express();
const port = 8003;
@@ -13,53 +16,34 @@ 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;
var gameId = null;
var numberOfQuestions = 0;
-// 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);
@@ -69,22 +53,21 @@ app.get('/generateQuestion', async (req, res) => {
gameId = null;
}
const user = req.query.user;
+ console.log(user);
await generarPregunta();
-
numberOfQuestions++;
if(numberOfQuestions>=5){
numberOfQuestions = 0;
}
-
var id = await saveData();
-
await saveGame(user, id);
-
-
+
+ // Construcción de la respuesta
var response = {
responseQuestion: question,
responseOptions: options,
responseCorrectOption: correctOption,
+ responseImage: image,
question_Id: id
};
@@ -99,6 +82,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);
@@ -131,12 +115,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 = "";
+
+ // 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
- if (!randomIndexes.includes(randomIndex)
- && !(option.startsWith("Q") || option.startsWith("http"))
- && !(quest.startsWith("Q") || quest.startsWith("http"))) {
+ // 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);
}
}
@@ -144,17 +137,22 @@ 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 saveGame(username,id) {
@@ -201,7 +199,6 @@ async function saveGame(username,id) {
async function saveData(){
-
try {
var false_options = options.filter(o => o != correctOption);
@@ -239,4 +236,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..3e353113
--- /dev/null
+++ b/questiongenerator/text_questions.js
@@ -0,0 +1,50 @@
+// Todas las consultas
+var queries =
+ // pregunta = Pais, opcion = capitales
+ [`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
+ `,
+ // pregunta = Club de futbol, opcion = estadio
+ `
+ 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
+ `,
+ // Pregunta = Numero en la tabla periodica, opcion = Elemento
+ `
+ 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
+ `,
+ // Pregunta = Batalla historica, opcion = año
+ `SELECT ?question ?questionLabel ?optionLabel
+ WHERE {
+ ?question wdt:P31 wd:Q178561.
+ ?question wdt:P580 ?date.
+ FILTER (YEAR(?date) >= 1500 && YEAR(?date) <= 2000)
+ 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/.env b/webapp/.env
index edddf932..c421c87a 100644
--- a/webapp/.env
+++ b/webapp/.env
@@ -1,2 +1,2 @@
REACT_APP_API_ENDPOINT=http://localhost:8000
-REACT_APP_API_GENERATOR_ENDPOINT=http://localhost:8003
\ No newline at end of file
+REACT_GENERATOR_APP_API_ENDPOINT=http://localhost:8003
\ 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 6b405cf2..bd2b0884 100644
--- a/webapp/src/components/Game.js
+++ b/webapp/src/components/Game.js
@@ -5,12 +5,12 @@ import { Container, Typography, Button, Snackbar } from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { useUser } from './UserContext';
-// Cambio de prueba
-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 { usernameGlobal } = useUser();
const [question, setQuestion] = useState('');
+ const [image, setImage] = useState('');
const [options, setOptions] = useState([]);
const [correctOption, setCorrectOption] = useState("");
const [questionId,setQuestionId] = useState(null);
@@ -28,26 +28,28 @@ const Game = () => {
const getQuestion = useCallback(async (answeredQuestionsValue) => {
try {
- console.log(" NUMERO DE PREGUNTA " + answeredQuestionsValue);
+ //console.log(" NUMERO DE PREGUNTA " + answeredQuestionsValue);
const createNewGame = answeredQuestionsValue > 0 ? false : true;
- console.log(" HAY QUE CREAR UN NUEVO JUEGO? " + createNewGame);
-
+ //console.log(" HAY QUE CREAR UN NUEVO JUEGO? " + createNewGame);
+
const response = await axios.get(`${apiEndpoint}/generateQuestion`, {
params: {
user: usernameGlobal,
newGame: createNewGame,
- numberOfQuestiona: answeredQuestionsValue
+ numberOfQuestions: answeredQuestionsValue
}
});
setQuestionId(response.data.question_Id);
setQuestion(response.data.responseQuestion);
setOptions(response.data.responseOptions);
setCorrectOption(response.data.responseCorrectOption);
+ setImage(response.data.responseImage);
setOpenSnackbar(true);
setElapsedTime(MAX_TIME);
} catch (error) {
+ console.log(error.message);
setError(error.response.data.error);
}
}, [])
@@ -125,6 +127,9 @@ const Game = () => {