From ffd8b13551c0f563a12cb8e79467784993686511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20M=C3=A9ndez=20Murias?= Date: Mon, 18 Mar 2024 10:06:32 +0100 Subject: [PATCH 01/10] Changes on loadData() --- .../geography/cities/citiesQuestions.js | 106 ++++++++++++++---- 1 file changed, 82 insertions(+), 24 deletions(-) diff --git a/question_generator/geography/cities/citiesQuestions.js b/question_generator/geography/cities/citiesQuestions.js index ae3e971d..a2b9cd2d 100644 --- a/question_generator/geography/cities/citiesQuestions.js +++ b/question_generator/geography/cities/citiesQuestions.js @@ -12,7 +12,9 @@ class CitiesQuestions{ } async loadData(){ let newResults={}; - const query=` + const queries=[ + //ciudades del mundo + ` SELECT ?city ?cityLabel ?population ?countryLabel ?elevation_above_sea_level WITH{ SELECT ?city ?cityLabel @@ -36,28 +38,84 @@ class CitiesQuestions{ SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } } ORDER BY DESC(?population) + LIMIT 50 + `, + //ciudades de España + `SELECT ?city ?cityLabel ?population ?countryLabel ?elevation_above_sea_level + WITH{ + SELECT ?city ?cityLabel + WHERE{ + ?city wdt:P31 wd:Q2074737 + } + LIMIT 1000 + } AS %i + WHERE { + INCLUDE %i + OPTIONAL{ + ?city wdt:P1082 ?population. + ?city wdt:P17 ?country. + ?city wdt:P2044 ?elevation_above_sea_level + } + FILTER EXISTS{ + ?city wdt:P1082 ?population. + ?city wdt:P17 ?country. + ?city wdt:P2044 ?elevation_above_sea_level + } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } + } + ORDER BY DESC(?population) + LIMIT 15`, + // Metropolis + ` + SELECT ?city ?cityLabel ?population ?countryLabel ?elevation_above_sea_level + WITH{ + SELECT ?city ?cityLabel + WHERE{ + ?city wdt:P31 wd:Q200250 + } + LIMIT 100 + } AS %i + WHERE { + INCLUDE %i + OPTIONAL{ + ?city wdt:P1082 ?population. + ?city wdt:P17 ?country. + ?city wdt:P2044 ?elevation_above_sea_level + } + FILTER EXISTS{ + ?city wdt:P1082 ?population. + ?city wdt:P17 ?country. + ?city wdt:P2044 ?elevation_above_sea_level + } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } + } + ORDER BY DESC(?population) LIMIT 100 ` - let cities = await queryExecutor.execute(query); - cities.forEach(city => { - const cityId = city.city.value; - const cityName = city.cityLabel.value; - const population = city.population.value; - const country = city.countryLabel.value; - const elevationAboveSeaLevel = city.elevation_above_sea_level.value; + ]; + for(let i = 0; i { + const cityId = city.city.value; + const cityName = city.cityLabel.value; + const population = city.population.value; + const country = city.countryLabel.value; + const elevationAboveSeaLevel = city.elevation_above_sea_level.value; - if (!newResults[cityId]) { - newResults[cityId] = { - cityId: cityId, - cityName: cityName, - population: population, - country: country, - elevation_above_sea_level: [] - }; - } + if (!newResults[cityId]) { + newResults[cityId] = { + cityId: cityId, + name: cityName, + population: population, + country: country, + elevation_above_sea_level: [] + }; + } - newResults[cityId].elevation_above_sea_level.push(parseFloat(elevationAboveSeaLevel)); - }); + newResults[cityId].elevation_above_sea_level.push(parseFloat(elevationAboveSeaLevel)); + }); + } this.cities=newResults; } @@ -74,7 +132,7 @@ class CitiesQuestions{ const results=await this.getRandomCities(numberOfCities); const formattedResults = await results.map(result => { return { - item: result.cityName, + item: result.name, value:parseFloat(result.population), }; }).sort((a, b) => b.value - a.value); @@ -97,13 +155,13 @@ class CitiesQuestions{ let result =(await this.getRandomCities(1))[0]; let country=result.country; - let correct = result.cityName; + let correct = result.name; let incorrects = [] let i=1; while(i Date: Mon, 18 Mar 2024 10:45:27 +0100 Subject: [PATCH 02/10] Question utils --- .../geography/cities/citiesQuestions.js | 25 ++++--------- .../geography/cities/citiesTemplates.js | 4 +-- question_generator/questions-utils.js | 35 +++++++++++++++++++ 3 files changed, 43 insertions(+), 21 deletions(-) create mode 100644 question_generator/questions-utils.js diff --git a/question_generator/geography/cities/citiesQuestions.js b/question_generator/geography/cities/citiesQuestions.js index a2b9cd2d..024460e3 100644 --- a/question_generator/geography/cities/citiesQuestions.js +++ b/question_generator/geography/cities/citiesQuestions.js @@ -1,4 +1,5 @@ -const queryExecutor=require("../../queryExecutor") +const queryExecutor=require("../../queryExecutor"); +const QuestionsUtils = require("../../questions-utils"); class CitiesQuestions{ #citiesQuestions=null; static getInstance(){ @@ -150,26 +151,12 @@ class CitiesQuestions{ } return finalResults } - async getCityForCountry(){ - let numberOfCities=4; - let result =(await this.getRandomCities(1))[0]; - let country=result.country; - let correct = result.name; - let incorrects = [] - let i=1; - while(i { - const results= await citiesQuery.getCityForCountry(); + const results= await citiesQuery.doQuestion('country',4); return{ "question":"Which city is in?", - "question_param":results.country, + "question_param":results.question_param, "correct":results.correct, "incorrects":results.incorrects } diff --git a/question_generator/questions-utils.js b/question_generator/questions-utils.js new file mode 100644 index 00000000..17f5134a --- /dev/null +++ b/question_generator/questions-utils.js @@ -0,0 +1,35 @@ +class QuestionsUtils{ + static getValuesFromDataAndProperty(data, property, nValues){ + const result = { + correct: null, + incorrects: [], + propertyResult:null + }; + const dataArray = Object.values(data); + for (let i=0; i Math.random() - 0.5); + for (let i = 0; i < random.length; i++) { + const value = random[i]; + if(result.correct==null){ + result.propertyResult=value[property]; + result.correct=value.name; + break; + } + else if (!(result.incorrects.includes(value)||result.propertyResult==value[property])) { + result.incorrects.push(value.name); + break; + } + } + } +} + +module.exports=QuestionsUtils; \ No newline at end of file From 874dc754923f2a07c03827c619505a1873c2edc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20M=C3=A9ndez=20Murias?= Date: Sat, 23 Mar 2024 19:39:23 +0100 Subject: [PATCH 03/10] Questions automatizer working --- .../geography/cities/citiesQuestions.js | 161 +++++++++--------- .../geography/cities/citiesTemplates.js | 9 + question_generator/queryExecutor.js | 5 + question_generator/questions-utils.js | 4 +- 4 files changed, 94 insertions(+), 85 deletions(-) diff --git a/question_generator/geography/cities/citiesQuestions.js b/question_generator/geography/cities/citiesQuestions.js index 024460e3..4d0a3e1e 100644 --- a/question_generator/geography/cities/citiesQuestions.js +++ b/question_generator/geography/cities/citiesQuestions.js @@ -11,112 +11,107 @@ class CitiesQuestions{ constructor(){ this.cities={}; } - async loadData(){ - let newResults={}; - const queries=[ - //ciudades del mundo - ` - SELECT ?city ?cityLabel ?population ?countryLabel ?elevation_above_sea_level - WITH{ - SELECT ?city ?cityLabel - WHERE{ - ?city wdt:P31 wd:Q515 - } - LIMIT 1000 - } AS %i - WHERE { - INCLUDE %i - OPTIONAL{ - ?city wdt:P1082 ?population. - ?city wdt:P17 ?country. - ?city wdt:P2044 ?elevation_above_sea_level + async loadCities(){ + let result={}; + const citiesQueries=[ + //Instancia de CITY + `SELECT ?city ?cityLabel ?population ?countryLabel + WITH{ + SELECT ?city ?cityLabel + WHERE{ + ?city wdt:P31 wd:Q515 } - FILTER EXISTS{ + LIMIT 1000 + } AS %i + WHERE { + INCLUDE %i + OPTIONAL{ ?city wdt:P1082 ?population. ?city wdt:P17 ?country. - ?city wdt:P2044 ?elevation_above_sea_level + } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } } - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } - } - ORDER BY DESC(?population) - LIMIT 50 - `, - //ciudades de España - `SELECT ?city ?cityLabel ?population ?countryLabel ?elevation_above_sea_level - WITH{ - SELECT ?city ?cityLabel - WHERE{ - ?city wdt:P31 wd:Q2074737 - } - LIMIT 1000 - } AS %i - WHERE { - INCLUDE %i - OPTIONAL{ - ?city wdt:P1082 ?population. - ?city wdt:P17 ?country. - ?city wdt:P2044 ?elevation_above_sea_level + ORDER BY DESC(?population) + LIMIT 100`, + //Ciudades de España + `SELECT ?city ?cityLabel ?population ?countryLabel + WITH{ + SELECT ?city ?cityLabel + WHERE{ + ?city wdt:P31 wd:Q2074737 } - FILTER EXISTS{ + LIMIT 1000 + } AS %i + WHERE { + INCLUDE %i + OPTIONAL{ ?city wdt:P1082 ?population. ?city wdt:P17 ?country. - ?city wdt:P2044 ?elevation_above_sea_level + } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } } - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } - } - ORDER BY DESC(?population) - LIMIT 15`, - // Metropolis - ` - SELECT ?city ?cityLabel ?population ?countryLabel ?elevation_above_sea_level - WITH{ - SELECT ?city ?cityLabel - WHERE{ - ?city wdt:P31 wd:Q200250 - } - LIMIT 100 - } AS %i - WHERE { - INCLUDE %i - OPTIONAL{ - ?city wdt:P1082 ?population. - ?city wdt:P17 ?country. - ?city wdt:P2044 ?elevation_above_sea_level + ORDER BY DESC(?population) + LIMIT 20`, + //Metropolis + `SELECT ?city ?cityLabel ?population ?countryLabel + WITH{ + SELECT ?city ?cityLabel + WHERE{ + ?city wdt:P31 wd:Q200250 } - FILTER EXISTS{ + LIMIT 1000 + } AS %i + WHERE { + INCLUDE %i + OPTIONAL{ ?city wdt:P1082 ?population. ?city wdt:P17 ?country. - ?city wdt:P2044 ?elevation_above_sea_level + } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } } - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } - } - ORDER BY DESC(?population) - LIMIT 100 - ` + ORDER BY DESC(?population) + LIMIT 5` + ]; - for(let i = 0; i { - const cityId = city.city.value; + cities.forEach(city=>{ + const cityId = city.city.value.match(/Q\d+/)[0]; const cityName = city.cityLabel.value; const population = city.population.value; const country = city.countryLabel.value; - const elevationAboveSeaLevel = city.elevation_above_sea_level.value; - - if (!newResults[cityId]) { - newResults[cityId] = { + if (!result[cityId]) { + result[cityId] = { cityId: cityId, name: cityName, population: population, - country: country, - elevation_above_sea_level: [] - }; + country: country + } } - - newResults[cityId].elevation_above_sea_level.push(parseFloat(elevationAboveSeaLevel)); }); } + return result; + + } + async loadData(){ + let newResults = await this.loadCities(); + const propertiesToLoad=[ + { + name:'elevation_above_sea_level', + id: 'P2044' + } + + ] + for(let i = 0; i 0){ + newResults[cityId][propertiesToLoad[j].name] = r[0][propertiesToLoad[j].name].value; + } + } + } this.cities=newResults; } diff --git a/question_generator/geography/cities/citiesTemplates.js b/question_generator/geography/cities/citiesTemplates.js index 283f5b2e..8ac6a454 100644 --- a/question_generator/geography/cities/citiesTemplates.js +++ b/question_generator/geography/cities/citiesTemplates.js @@ -31,6 +31,15 @@ const templates=[ "correct":results.correct, "incorrects":results.incorrects } + }, + async ()=> + { + const results= await citiesQuery.doQuestion('elevation_above_sea_level',4); + return{ + "question":"Which city is higher above sea level?", + "correct":results.correct, + "incorrects":results.incorrects + } } diff --git a/question_generator/queryExecutor.js b/question_generator/queryExecutor.js index 5af84116..e62ee257 100644 --- a/question_generator/queryExecutor.js +++ b/question_generator/queryExecutor.js @@ -28,5 +28,10 @@ class QueryExecutor{ console.error('Error al realizar la consulta a Wikidata:', error.message); } } + static async executeQueryForEntityAndProperty(entity, property){ + const query= + `SELECT ?${property.name} WHERE{?id ?prop wd:${entity};wdt:${property.id} ?${property.name}.SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }}LIMIT 1` + return await this.execute(query); + } } module.exports=QueryExecutor \ No newline at end of file diff --git a/question_generator/questions-utils.js b/question_generator/questions-utils.js index 17f5134a..48f141d4 100644 --- a/question_generator/questions-utils.js +++ b/question_generator/questions-utils.js @@ -19,12 +19,12 @@ class QuestionsUtils{ const random = dataArray.sort(() => Math.random() - 0.5); for (let i = 0; i < random.length; i++) { const value = random[i]; - if(result.correct==null){ + if(result.correct==null && value[property]!=undefined){ result.propertyResult=value[property]; result.correct=value.name; break; } - else if (!(result.incorrects.includes(value)||result.propertyResult==value[property])) { + else if ((!(result.incorrects.includes(value)||result.propertyResult==value[property]))&& value[property]!=undefined) { result.incorrects.push(value.name); break; } From 7f7eae8196d78e5d0682a8abfa7455ea087fb9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20M=C3=A9ndez=20Murias?= Date: Sat, 23 Mar 2024 20:05:51 +0100 Subject: [PATCH 04/10] Reducing calls to wikidata with the question automator --- question_generator/geography/cities/citiesQuestions.js | 6 +++--- question_generator/queryExecutor.js | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/question_generator/geography/cities/citiesQuestions.js b/question_generator/geography/cities/citiesQuestions.js index 4d0a3e1e..6965fcce 100644 --- a/question_generator/geography/cities/citiesQuestions.js +++ b/question_generator/geography/cities/citiesQuestions.js @@ -105,9 +105,9 @@ class CitiesQuestions{ ] for(let i = 0; i 0){ + let r= await queryExecutor.executeQueryForEntityAndProperty(cityId, propertiesToLoad); + if(r.length>0){ + for(let j=0;j`?${property.name}`).join(' ')} WHERE {?id ?prop wd:${entity};wdt:${properties[0].id} ?${properties[0].name}. OPTIONAL {${properties.map(property=>`?id wdt:${property.id} ?${property.name}.`).join(' ')} SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }}}LIMIT 1` return await this.execute(query); } } From 2edaf27de2ca91dab8fd73d5c8c8703096ae1b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20M=C3=A9ndez=20Murias?= Date: Sat, 23 Mar 2024 21:27:40 +0100 Subject: [PATCH 05/10] Errors solved in question generation and new template added --- .../geography/cities/citiesQuestions.js | 13 +++++++++++-- .../geography/cities/citiesTemplates.js | 16 +++++++--------- question_generator/locales/en.json | 3 ++- question_generator/queryExecutor.js | 13 +++++++++++-- question_generator/questions-utils.js | 2 +- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/question_generator/geography/cities/citiesQuestions.js b/question_generator/geography/cities/citiesQuestions.js index 6965fcce..deaafe54 100644 --- a/question_generator/geography/cities/citiesQuestions.js +++ b/question_generator/geography/cities/citiesQuestions.js @@ -100,15 +100,24 @@ class CitiesQuestions{ { name:'elevation_above_sea_level', id: 'P2044' + }, + { + name:'highest_point', + id: 'P610' + }, + { + name: 'area', + id: 'P2046' } - ] for(let i = 0; i 0){ for(let j=0;j { - const results= await citiesQuery.getHigherCity(); + const results= await citiesQuery.doQuestion('elevation_above_sea_level',4); return{ "question":"Which city is higher above sea level?", "correct":results.correct, "incorrects":results.incorrects } }, - async ()=> - { - const results= await citiesQuery.doQuestion('elevation_above_sea_level',4); - return{ - "question":"Which city is higher above sea level?", - "correct":results.correct, - "incorrects":results.incorrects + async () => { + const results = await citiesQuery.doQuestion('area', 4); + return { + "question": "Which city has a larger area?", + "correct": results.correct, + "incorrects": results.incorrects } } - ] module.exports.getRandomQuestion = () => templates[Math.floor(Math.random()*templates.length)](); module.exports.loadData = () =>loadData(); \ No newline at end of file diff --git a/question_generator/locales/en.json b/question_generator/locales/en.json index 9703c5e2..1887e15b 100644 --- a/question_generator/locales/en.json +++ b/question_generator/locales/en.json @@ -5,5 +5,6 @@ "Which planet is bigger?": "Which planet is bigger?", "Who has more Grand Slams?": "Who has more Grand Slams?", "Who has more followers?": "Who has more followers?", - "Who has more looses?": "Who has more looses?" + "Who has more looses?": "Who has more looses?", + "Which city has a larger area?": "Which city has a larger area?" } \ No newline at end of file diff --git a/question_generator/queryExecutor.js b/question_generator/queryExecutor.js index 1f70e474..2002e705 100644 --- a/question_generator/queryExecutor.js +++ b/question_generator/queryExecutor.js @@ -33,8 +33,17 @@ class QueryExecutor{ return []; } const query= - `SELECT ${properties.map(property=>`?${property.name}`).join(' ')} WHERE {?id ?prop wd:${entity};wdt:${properties[0].id} ?${properties[0].name}. OPTIONAL {${properties.map(property=>`?id wdt:${property.id} ?${property.name}.`).join(' ')} SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }}}LIMIT 1` - return await this.execute(query); + `SELECT ${properties.map(property=>`?${property.name}Label`).join(' ')} WHERE {OPTIONAL {${properties.map(property=>`wd:${entity} wdt:${property.id} ?${property.name}.`).join(' ')}} SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }}LIMIT 1` + let results=await this.execute(query); + const editedResults = results.map(result => { + const editedResult = {}; + for (const key in result) { + const newKey = key.replace(/Label$/, ''); + editedResult[newKey] = result[key]; + } + return editedResult; + }); + return editedResults; } } module.exports=QueryExecutor \ No newline at end of file diff --git a/question_generator/questions-utils.js b/question_generator/questions-utils.js index 48f141d4..bf2d1f32 100644 --- a/question_generator/questions-utils.js +++ b/question_generator/questions-utils.js @@ -24,7 +24,7 @@ class QuestionsUtils{ result.correct=value.name; break; } - else if ((!(result.incorrects.includes(value)||result.propertyResult==value[property]))&& value[property]!=undefined) { + else if ((!(result.incorrects.includes(value.name)||result.propertyResult==value[property]))&& value[property]!=undefined) { result.incorrects.push(value.name); break; } From 1f865fe58033adc3620871641860aa70755cf923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20M=C3=A9ndez=20Murias?= Date: Sat, 23 Mar 2024 22:05:29 +0100 Subject: [PATCH 06/10] Saving of generated questions-v1 --- docker-compose.yml | 2 ++ .../questionGenerationService.js | 18 ++++++++++++++++++ questionservice/question-model.js | 5 +++++ 3 files changed, 25 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 46f9843d..a9c2888b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -48,6 +48,8 @@ services: - "8003:8003" networks: - mynetwork + environment: + QUESTIONS_SERVICE_URL: http://questionservice:8004 questionservice: container_name: questionservice-${teamname:-defaultASW} diff --git a/question_generator/questionGenerationService.js b/question_generator/questionGenerationService.js index 840798ba..87685801 100644 --- a/question_generator/questionGenerationService.js +++ b/question_generator/questionGenerationService.js @@ -6,6 +6,8 @@ const geographyTemplate=require('./geography/geographyTemplate'); const planetTemplate=require('./planets/planetsTemplates'); const sportTemplate=require('./sports/sportTemplate'); const generalTemplate=require('./questionTemplate'); +const axios = require('axios'); +const questionServiceUrl = process.env.QUESTIONS_SERVICE_URL || 'http://localhost:8004'; const app = express(); const port = 8003; @@ -50,6 +52,22 @@ app.get('/api/questions/create', async (req, res) => { randomQuestion = await generalTemplate.getRandomQuestion(); } randomQuestion.question = i18n.__(randomQuestion.question, randomQuestion.question_param); + const saveQuestion = async (question) => { + const url = questionServiceUrl+'/addquestion'; + try { + const response = await axios.post(url, question); + console.log(response.data); + } catch (error) { + console.error(error); + } + }; + //esto creo que puede ser asincrono + await saveQuestion({ + question: randomQuestion.question, + correct: randomQuestion.correct, + incorrects: randomQuestion.incorrects + }); + res.status(200).json( { diff --git a/questionservice/question-model.js b/questionservice/question-model.js index 5e3e72aa..6c2f1cc1 100644 --- a/questionservice/question-model.js +++ b/questionservice/question-model.js @@ -19,6 +19,11 @@ const questionSchema = new mongoose.Schema({ message: 'Options must be between 2 and 4 elements.', }, }, + generationDate: { + type: Date, + default: Date.now, + required: true, + }, }); const Question = mongoose.model('Question', questionSchema); From d1c2d3441ea6fc07d195fc97b477a060e6e112c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20M=C3=A9ndez=20Murias?= Date: Sat, 23 Mar 2024 23:41:40 +0100 Subject: [PATCH 07/10] Improved question saving --- question_generator/locales/en.json | 7 +++++-- question_generator/locales/es.json | 18 ++++++++---------- .../questionGenerationService.js | 16 ++++++++++------ questionservice/question-model.js | 6 ++++++ questionservice/question-service.js | 6 ++++-- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/question_generator/locales/en.json b/question_generator/locales/en.json index 1887e15b..a2b7a02e 100644 --- a/question_generator/locales/en.json +++ b/question_generator/locales/en.json @@ -2,9 +2,12 @@ "Which city is higher above sea level?": "Which city is higher above sea level?", "Which city has more population?": "Which city has more population?", "Which city is in?": "Which city is in %s?", + "Which city has a larger area?": "Which city has a larger area?", + "Which planet is bigger?": "Which planet is bigger?", + "Who has more Grand Slams?": "Who has more Grand Slams?", "Who has more followers?": "Who has more followers?", - "Who has more looses?": "Who has more looses?", - "Which city has a larger area?": "Which city has a larger area?" + "Who has more looses?": "Who has more looses?" + } \ No newline at end of file diff --git a/question_generator/locales/es.json b/question_generator/locales/es.json index 37c8d2da..8d2a7deb 100644 --- a/question_generator/locales/es.json +++ b/question_generator/locales/es.json @@ -1,15 +1,13 @@ { - - "Which city is higher above sea level?": "¿Qué ciudad tiene más altitud sobre el nivel del mar?", + "Which city is higher above sea level?": "¿Qué ciudad está a mayor altitud?", "Which city has more population?": "¿Qué ciudad tiene más población?", - "Which city is in?": "¿Qué ciudad está en %s?", - - - - "Which planet is bigger?": "¿Qué planeta tiene un tamaño mayor?", - - + "Which city is in?": "¿Qué ciudad se encuentra %s?", + "Which city has a larger area?": "¿Qué ciudad tiene un área más grande?", + "Which planet is bigger?": "¿Qué planeta es más grande?", - "Who has more Grand Slams?": "¿Quién tiene más Grand Slams?" + "Who has more Grand Slams?": "¿Quién tiene más Grand Slams?", + "Who has more followers?": "¿Quién tiene más seguidores?", + "Who has more looses?": "¿Quién tiene más derrotas?" + } \ No newline at end of file diff --git a/question_generator/questionGenerationService.js b/question_generator/questionGenerationService.js index 87685801..f46ededd 100644 --- a/question_generator/questionGenerationService.js +++ b/question_generator/questionGenerationService.js @@ -35,7 +35,9 @@ app.use( app.get('/api/questions/create', async (req, res) => { try { - const category = req.query.category; + let category = req.query.category; + //User is null because we are not using authentication yet + let user=null; let randomQuestion; switch (category) { @@ -50,6 +52,7 @@ app.get('/api/questions/create', async (req, res) => { break; default: randomQuestion = await generalTemplate.getRandomQuestion(); + category = 'general'; } randomQuestion.question = i18n.__(randomQuestion.question, randomQuestion.question_param); const saveQuestion = async (question) => { @@ -61,11 +64,12 @@ app.get('/api/questions/create', async (req, res) => { console.error(error); } }; - //esto creo que puede ser asincrono - await saveQuestion({ + saveQuestion({ question: randomQuestion.question, correct: randomQuestion.correct, - incorrects: randomQuestion.incorrects + incorrects: randomQuestion.incorrects, + user: user, + category: category }); @@ -77,7 +81,7 @@ app.get('/api/questions/create', async (req, res) => { } ); } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }); + res.status(500).json({ error: 'Internal Server Error'}); } }); @@ -85,7 +89,7 @@ app.get('/api/questions/create', async (req, res) => { function loadData() { generalTemplate.loadData(); } - +loadData(); // Ejecuta loadData cada hora (60 minutos * 60 segundos * 1000 milisegundos) setInterval(loadData, 60 * 60 * 1000); diff --git a/questionservice/question-model.js b/questionservice/question-model.js index 6c2f1cc1..004d62a5 100644 --- a/questionservice/question-model.js +++ b/questionservice/question-model.js @@ -24,6 +24,12 @@ const questionSchema = new mongoose.Schema({ default: Date.now, required: true, }, + user: { + type: String + }, + category: { + type: String + }, }); const Question = mongoose.model('Question', questionSchema); diff --git a/questionservice/question-service.js b/questionservice/question-service.js index afe67831..48751a90 100644 --- a/questionservice/question-service.js +++ b/questionservice/question-service.js @@ -23,15 +23,17 @@ const validateRequiredFields = (req, fields) => { // Ruta para agregar una nueva pregunta app.post('/addquestion', async (req, res) => { try { - validateRequiredFields(req, ['question', 'correct', 'incorrects']); + validateRequiredFields(req, ['question', 'correct', 'incorrects', 'user', 'category']); - const { question, correct, incorrects } = req.body; + const { question, correct, incorrects, user, category } = req.body; // Crea una nueva instancia del modelo de preguntas const newQuestion = new Question({ question, correct, incorrects, + user, + category }); // Guarda la nueva pregunta en la base de datos From 9adf27c14dbf1fdc9da29740d9996b7954239ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20M=C3=A9ndez=20Murias?= Date: Sun, 24 Mar 2024 00:39:31 +0100 Subject: [PATCH 08/10] Errors solved in question generation tests --- question_generator/locales/en.json | 7 ++++--- question_generator/locales/es.json | 4 +++- question_generator/queryExecutor.js | 4 ++++ question_generator/questionGenerationService.js | 1 - .../questionGenerationService.test.js | 13 ++++++++++++- question_generator/sports/tennis/tennisTemplates.js | 3 ++- questionservice/question-service.js | 9 ++++++--- 7 files changed, 31 insertions(+), 10 deletions(-) diff --git a/question_generator/locales/en.json b/question_generator/locales/en.json index a2b7a02e..705fbbb7 100644 --- a/question_generator/locales/en.json +++ b/question_generator/locales/en.json @@ -3,11 +3,12 @@ "Which city has more population?": "Which city has more population?", "Which city is in?": "Which city is in %s?", "Which city has a larger area?": "Which city has a larger area?", - + "Which planet is bigger?": "Which planet is bigger?", "Who has more Grand Slams?": "Who has more Grand Slams?", "Who has more followers?": "Who has more followers?", - "Who has more looses?": "Who has more looses?" - + "Who has more looses?": "Who has more looses?", + "Who has more wins?": "Who has more wins?", + "Which player is from?" : "Which player is from %s?" } \ No newline at end of file diff --git a/question_generator/locales/es.json b/question_generator/locales/es.json index 8d2a7deb..d743a949 100644 --- a/question_generator/locales/es.json +++ b/question_generator/locales/es.json @@ -8,6 +8,8 @@ "Who has more Grand Slams?": "¿Quién tiene más Grand Slams?", "Who has more followers?": "¿Quién tiene más seguidores?", - "Who has more looses?": "¿Quién tiene más derrotas?" + "Who has more looses?": "¿Quién tiene más derrotas?", + "Who has more wins?": "¿Quién tiene más victorias?", + "Which player is from?" : "¿Qué jugador es de %s?" } \ No newline at end of file diff --git a/question_generator/queryExecutor.js b/question_generator/queryExecutor.js index 2002e705..23cc793b 100644 --- a/question_generator/queryExecutor.js +++ b/question_generator/queryExecutor.js @@ -19,6 +19,10 @@ class QueryExecutor{ }, ...config, }); + if (!response || !response.data) { + console.error('La consulta a Wikidata no devolvió ningún resultado'); + return; + } return response.data.results.bindings; diff --git a/question_generator/questionGenerationService.js b/question_generator/questionGenerationService.js index f46ededd..485120f1 100644 --- a/question_generator/questionGenerationService.js +++ b/question_generator/questionGenerationService.js @@ -59,7 +59,6 @@ app.get('/api/questions/create', async (req, res) => { const url = questionServiceUrl+'/addquestion'; try { const response = await axios.post(url, question); - console.log(response.data); } catch (error) { console.error(error); } diff --git a/question_generator/questionGenerationService.test.js b/question_generator/questionGenerationService.test.js index 17cc1733..a19620f8 100644 --- a/question_generator/questionGenerationService.test.js +++ b/question_generator/questionGenerationService.test.js @@ -1,4 +1,5 @@ const request = require('supertest'); +const axios = require('axios'); let app; beforeAll(async () => { @@ -12,6 +13,16 @@ afterAll(async () => { }); describe('Question generation service', () => { + jest.spyOn(axios, 'post').mockResolvedValue({ + data: { + question: 'Mocked Question', + correct: 'Mocked Correct Answer', + incorrects: ['Mocked Option 1', 'Mocked Option 2'], + user: 'Mocked User', + category: 'Mocked Category' + } + }); + it('should forward create question request to question generation service', async () => { const response = await request(app) .get('/api/questions/create'); @@ -20,7 +31,7 @@ describe('Question generation service', () => { expect(response.body).toHaveProperty('question'); expect(response.body).toHaveProperty('correct'); expect(response.body).toHaveProperty('incorrects'); - },100000); + }, 100000); it('should forward create question request to question generation service', async () => { const response = await request(app) diff --git a/question_generator/sports/tennis/tennisTemplates.js b/question_generator/sports/tennis/tennisTemplates.js index 959afbff..21042644 100644 --- a/question_generator/sports/tennis/tennisTemplates.js +++ b/question_generator/sports/tennis/tennisTemplates.js @@ -17,7 +17,8 @@ const templates=[ { const results = await tennisQuery.getPlayerForCountry(); return{ - "question":"Which player is from " + results.country + "?", + "question":"Which player is from?", + "question_param":results.country, "correct":results.correct, "incorrects":results.incorrects } diff --git a/questionservice/question-service.js b/questionservice/question-service.js index 48751a90..76a526e4 100644 --- a/questionservice/question-service.js +++ b/questionservice/question-service.js @@ -20,8 +20,8 @@ const validateRequiredFields = (req, fields) => { } }; -// Ruta para agregar una nueva pregunta -app.post('/addquestion', async (req, res) => { + +const addQuestion = async (req, res) => { try { validateRequiredFields(req, ['question', 'correct', 'incorrects', 'user', 'category']); @@ -43,7 +43,9 @@ app.post('/addquestion', async (req, res) => { } catch (error) { res.status(500).json({ error: error.message }); } -}); +}; +// Ruta para agregar una nueva pregunta +app.post('/addquestion', addQuestion); // logica para preguntas?? @@ -57,3 +59,4 @@ server.on('close', () => { }); module.exports = server; +module.exports.addQuestion = addQuestion; From 94b4aae063b7b3f616ec2d32ba0616ad14c6c3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20M=C3=A9ndez=20Murias?= Date: Sun, 24 Mar 2024 00:51:11 +0100 Subject: [PATCH 09/10] Error solved in question-service tests --- questionservice/question-service.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/questionservice/question-service.test.js b/questionservice/question-service.test.js index 91d2c29e..183c971e 100644 --- a/questionservice/question-service.test.js +++ b/questionservice/question-service.test.js @@ -21,7 +21,9 @@ describe('Question Service', () => { const newQuestion = { question: 'Mocked Question', correct: 'Mocked Correct Answer', - incorrects: ['Mocked Option 1', 'Mocked Option 2'] + incorrects: ['Mocked Option 1', 'Mocked Option 2'], + user: 'Mocked User', + category: 'Mocked Category' }; const response = await request(app).post('/addquestion').send(newQuestion); From 075a2ab3afe493f262e6140786c1ec7d083f1873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20M=C3=A9ndez=20Murias?= Date: Sun, 24 Mar 2024 03:18:15 +0100 Subject: [PATCH 10/10] New templates added to "geography" category --- .../geography/cities/citiesQuestions.js | 12 ++++++++ .../geography/cities/citiesTemplates.js | 30 ++++++++++++++++++- question_generator/locales/en.json | 4 ++- question_generator/locales/es.json | 4 ++- question_generator/queryExecutor.js | 2 +- 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/question_generator/geography/cities/citiesQuestions.js b/question_generator/geography/cities/citiesQuestions.js index deaafe54..88f124a4 100644 --- a/question_generator/geography/cities/citiesQuestions.js +++ b/question_generator/geography/cities/citiesQuestions.js @@ -108,6 +108,18 @@ class CitiesQuestions{ { name: 'area', id: 'P2046' + }, + { + name: 'continent', + id: 'P30' + }, + { + name: 'head_of_government', + id: 'P6' + }, + { + name: 'located_in_time_zone', + id: 'P421' } ] for(let i = 0; i { const results = await citiesQuery.doQuestion('area', 4); return { - "question": "Which city has a larger area?", + "question": "Which city has an area of?", + "question_param": results.question_param, + "correct": results.correct, + "incorrects": results.incorrects + } + }, + async () => { + const results = await citiesQuery.doQuestion('continent', 4); + return { + "question": "Which city is in?", + "question_param": results.question_param, + "correct": results.correct, + "incorrects": results.incorrects + } + }, + async () => { + const results = await citiesQuery.doQuestion('head_of_government', 4); + return { + "question": "Which city is governed by?", + "question_param": results.question_param, + "correct": results.correct, + "incorrects": results.incorrects + } + }, + async () => { + const results = await citiesQuery.doQuestion('located_in_time_zone', 4); + return { + "question": "Which city is in the time zone?", + "question_param": results.question_param, "correct": results.correct, "incorrects": results.incorrects } diff --git a/question_generator/locales/en.json b/question_generator/locales/en.json index 101c0fa6..c7b75061 100644 --- a/question_generator/locales/en.json +++ b/question_generator/locales/en.json @@ -2,7 +2,9 @@ "Which city is higher above sea level?": "Which city is higher above sea level?", "Which city has more population?": "Which city has more population?", "Which city is in?": "Which city is in %s?", - "Which city has a larger area?": "Which city has a larger area?", + "Which city has an area of?": "Which city has an area od %s km2?", + "Which city is governed by?": "Which city is governed by %s?", + "Which city is in the time zone?": "Which city is in the time zone %s?", "Which planet is bigger?": "Which planet is bigger?", diff --git a/question_generator/locales/es.json b/question_generator/locales/es.json index b904a594..8f2b67f4 100644 --- a/question_generator/locales/es.json +++ b/question_generator/locales/es.json @@ -2,7 +2,9 @@ "Which city is higher above sea level?": "¿Qué ciudad está a mayor altitud?", "Which city has more population?": "¿Qué ciudad tiene más población?", "Which city is in?": "¿Qué ciudad se encuentra %s?", - "Which city has a larger area?": "¿Qué ciudad tiene un área más grande?", + "Which city has an area of?": "¿Qué ciudad tiene un área de %s km2?", + "Which city is governed by?": "¿Qué ciudad es gobernada por %s?", + "Which city is in the time zone?": "¿Qué ciudad está en la zona horaria %s?", "Which planet is bigger?": "¿Qué planeta es más grande?", diff --git a/question_generator/queryExecutor.js b/question_generator/queryExecutor.js index 23cc793b..46fedfd9 100644 --- a/question_generator/queryExecutor.js +++ b/question_generator/queryExecutor.js @@ -37,7 +37,7 @@ class QueryExecutor{ return []; } const query= - `SELECT ${properties.map(property=>`?${property.name}Label`).join(' ')} WHERE {OPTIONAL {${properties.map(property=>`wd:${entity} wdt:${property.id} ?${property.name}.`).join(' ')}} SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }}LIMIT 1` + `SELECT ${properties.map(property=>`?${property.name}Label`).join(' ')} WHERE {${properties.map(property=>`OPTIONAL {wd:${entity} wdt:${property.id} ?${property.name}.}`).join(' ')} SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }}LIMIT 1` let results=await this.execute(query); const editedResults = results.map(result => { const editedResult = {};