Skip to content

Commit

Permalink
Merge pull request #77 from Arquisoft/Ruben
Browse files Browse the repository at this point in the history
Arreglados errores y Test Game
  • Loading branch information
UO289337 authored Mar 27, 2024
2 parents 73dc301 + dc3a85c commit 3c0136a
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 61 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
14 changes: 13 additions & 1 deletion gatewayservice/gateway-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
3 changes: 3 additions & 0 deletions questiongenerator/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
28 changes: 28 additions & 0 deletions questiongenerator/image_questions.js
Original file line number Diff line number Diff line change
@@ -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 };
91 changes: 44 additions & 47 deletions questiongenerator/question.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);

Expand All @@ -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
};

Expand All @@ -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);
Expand Down Expand Up @@ -131,30 +115,44 @@ 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);
}
}

// 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) {
Expand Down Expand Up @@ -201,7 +199,6 @@ async function saveGame(username,id) {


async function saveData(){

try {

var false_options = options.filter(o => o != correctOption);
Expand Down Expand Up @@ -239,4 +236,4 @@ app.get('/updateQuestion', async (req, res) => {
});


module.exports = server
module.exports = server
50 changes: 50 additions & 0 deletions questiongenerator/text_questions.js
Original file line number Diff line number Diff line change
@@ -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 };
2 changes: 1 addition & 1 deletion webapp/.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
REACT_APP_API_ENDPOINT=http://localhost:8000
REACT_APP_API_GENERATOR_ENDPOINT=http://localhost:8003
REACT_GENERATOR_APP_API_ENDPOINT=http://localhost:8003
2 changes: 0 additions & 2 deletions webapp/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 11 additions & 6 deletions webapp/src/components/Game.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
}, [])
Expand Down Expand Up @@ -125,6 +127,9 @@ const Game = () => {
<Typography component="h1" variant="h5" sx={{ textAlign: 'center' }}>
{question}
</Typography>
<div>
{image != null && image != "" && <img src={image} alt="Imagen de la pregunta" width="40%" height="auto"/>}
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '10px', alignItems: 'center', marginTop: '20px' }}>
{options.map((option, index) => (
<Button key={index} sx={{backgroundColor: '#FCF5B8', color: '#413C3C', fontWeight: 'bold' }} variant="contained" color={selectedOption === option ? (answerCorrect ? 'success' : 'error') : 'primary'} onClick={() => handleOptionClick(option)} style={{ width: '100%', height: '100%' }}>
Expand Down
Loading

0 comments on commit 3c0136a

Please sign in to comment.