From ff12db979f29bc53c59e06ba753c706178f3b48a Mon Sep 17 00:00:00 2001 From: Zohaib Akhtar Kausar Date: Mon, 26 Feb 2024 21:08:38 +0100 Subject: [PATCH] =?UTF-8?q?Refactorizaci=C3=B3n=20de=20question-service.js?= =?UTF-8?q?=20y=20Modularizaci=C3=B3n=20del=20C=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gatewayservice/gateway-service.js | 15 +++++++ questionservice/question-service.js | 29 ++++++++++++++ questionservice/questionTemplates.js | 33 ++++++++++++++++ questionservice/wikiUtils/wikiCall.js | 22 +++++++++++ questionservice/wikiUtils/wikiQuery.js | 55 ++++++++++++++++++++++++++ 5 files changed, 154 insertions(+) create mode 100644 questionservice/question-service.js create mode 100644 questionservice/questionTemplates.js create mode 100644 questionservice/wikiUtils/wikiCall.js create mode 100644 questionservice/wikiUtils/wikiQuery.js diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 88b84c8..5df3271 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -8,6 +8,7 @@ const port = 8000; const authServiceUrl = process.env.AUTH_SERVICE_URL || 'http://localhost:8002'; const userServiceUrl = process.env.USER_SERVICE_URL || 'http://localhost:8001'; +const generateServiceURL = process.env.GENERATE_SERVICE_URL || 'http://localhost:8003'; app.use(cors()); app.use(express.json()); @@ -41,6 +42,20 @@ app.post('/adduser', async (req, res) => { } }); +app.post('/getquestion', async(req,res)=> { + try{ + // Redirige la solicitud al servicio de generación de preguntas sin enviar un cuerpo de solicitud. + const response = await axios.post(`${generateServiceURL}/getquestion`); + + // Devuelve la respuesta del servicio de generación de preguntas al cliente original. + res.json(response.data); + + } catch(error) { + res.status(error.response.status).json({ error: error.response.data.error }); + } +}); + + // Start the gateway service const server = app.listen(port, () => { console.log(`Gateway Service listening at http://localhost:${port}`); diff --git a/questionservice/question-service.js b/questionservice/question-service.js new file mode 100644 index 0000000..fd98a73 --- /dev/null +++ b/questionservice/question-service.js @@ -0,0 +1,29 @@ +const express = require('express'); +const app = express(); +const port = 8003; + +// Importamos la función desde questionTemplates.js +const getQuestionTemplate = require('./questionTemplates'); + +app.use(express.json()); + +app.post('/getquestion', async (req, res) => { + try { + const questionAndAnswer = await getQuestionTemplate(); // Obtenemos el json de pregunta y sus respuestas + + if (questionAndAnswer) { + res.json(questionAndAnswer); //Devolvemos a la gateway el json + } else { + // Si no se obtuvo una pregunta por alguna razón, enviamos un error genérico + res.status(500).json({ error: "Could not get a question and answers" }); + } + } catch (error) { + // En caso de cualquier error en el proceso, lo capturamos y enviamos un mensaje de error + console.error("Error generating question:", error); + res.status(500).json({ error: "Internal server error when generating the question" }); + } +}); + +app.listen(port, () => { + console.log(`Server listening on http://localhost:${port}`); +}); diff --git a/questionservice/questionTemplates.js b/questionservice/questionTemplates.js new file mode 100644 index 0000000..27e1e17 --- /dev/null +++ b/questionservice/questionTemplates.js @@ -0,0 +1,33 @@ +const wikiQuery = require("./wikiUtils/wikiQuery") + +const templates = [ + async () => { + const country = await wikiQuery.getRandomCountryAndCity(); + //Obtenemos los fakeCities + const fakeCities = await wikiQuery.getFakeCity(country.capital); + const correctAnswer = { answer: country.capital, correct: true }; + const fakeAnswers = fakeCities.map(city => ({ answer: city, correct: false })); + const answers = [correctAnswer, ...fakeAnswers]; + + // Mezclamos las respuestas para que la posición de la correcta sea aleatoria + const shuffledAnswers = shuffleArray(answers); + + return { + question: `¿Cuál es la capital de ${country.name}?`, + answers: shuffledAnswers + }; + }, + // Aquí podemos añadir más templates +]; + +// Función para mezclar las respuestas +function shuffleArray(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; +} + +// Seleccionamos aleatoriamente un template y lo ejecutamos +module.exports = () => templates[Math.floor(Math.random()*templates.length)](); diff --git a/questionservice/wikiUtils/wikiCall.js b/questionservice/wikiUtils/wikiCall.js new file mode 100644 index 0000000..15c5d45 --- /dev/null +++ b/questionservice/wikiUtils/wikiCall.js @@ -0,0 +1,22 @@ +const fetch = require('node-fetch'); + +const ENDPOINT_URL = 'https://query.wikidata.org/sparql'; + +async function wikiCall(sparqlQuery) { + const url = ENDPOINT_URL + '?query=' + encodeURIComponent(sparqlQuery); + const headers = { 'Accept': 'application/sparql-results+json' }; + + try { + const response = await fetch(url, { headers }); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + return data.results.bindings; + } catch (error) { + console.error(`Could not fetch data from Wikidata: ${error}`); + return []; + } +} + +module.exports = wikiCall; diff --git a/questionservice/wikiUtils/wikiQuery.js b/questionservice/wikiUtils/wikiQuery.js new file mode 100644 index 0000000..99ff162 --- /dev/null +++ b/questionservice/wikiUtils/wikiQuery.js @@ -0,0 +1,55 @@ +const wikiCall = require("./wikiCall"); + +//Selecionar un resultado de las consultas aleatorio +const randomElement = (items) => items[Math.floor(Math.random() * items.length)]; + +class wikiQuery { + + static async getRandomCountryAndCity() { + const query = ` + SELECT ?country ?countryLabel ?capitalLabel WHERE { + ?country wdt:P31 wd:Q6256; # Tipo de entidad: País + wdt:P36 ?capital. # Propiedad: Tiene por capital + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],es". } + } + LIMIT 50`; + + const results = randomElement(await wikiCall(query)); + + return { + name: results['countryLabel'].value, + capital: results['capitalLabel'].value + }; + } + + static async getRandomCity() { + const query = ` + SELECT ?city ?cityLabel WHERE { + ?city wdt:P31 wd:Q515; # Tipo de entidad: Ciudad + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],es". } + } + LIMIT 50`; + + + const results = randomElement(await wikiCall(query)); + + return results['cityLabel'].value; + + } + static async getFakeCity(capital) { + let Fakecitys = []; + + while(Fakecitys.length < 3) { + let randomCity = await this.getRandomCity(); + if(randomCity !== capital && !Fakecitys.includes(randomCity)) { + Fakecitys.push(randomCity); + } + } + + return Fakecitys; + } + + +} + +module.exports = wikiQuery \ No newline at end of file