From f483f14a61ff5a8af1330cabb02ce1c6bc39d3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:48:24 +0200 Subject: [PATCH 001/161] New geography question template: Area --- .../geography/AreaQuestionGenerator.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/geography/AreaQuestionGenerator.java diff --git a/src/main/java/com/uniovi/components/generators/geography/AreaQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/AreaQuestionGenerator.java new file mode 100644 index 00000000..d69d2edd --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/geography/AreaQuestionGenerator.java @@ -0,0 +1,52 @@ +package com.uniovi.components.generators.geography; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; + +public class AreaQuestionGenerator extends AbstractGeographyGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "What is the area of "); + put("es", "¿Cuál es el área de "); + put("fr", "Quelle est la superficie de "); + } + }; + + public AreaQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?country ?countryLabel ?area\n" + + "WHERE {" + + " ?country wdt:P31 wd:Q3624078 ." + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + + " ?country wdt:P2046 ?area ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + // Este generador de preguntas no necesita opciones, ya que la respuesta correcta es el área. + return Collections.emptyList(); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("area").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("countryLabel").path("value").asText() + "?"; + } +} From 9f26f042933a1c27faf2d0414f92db987d37247d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:48:55 +0200 Subject: [PATCH 002/161] New geography question template: Currency --- .../geography/CurrencyQuestionGenerator.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/geography/CurrencyQuestionGenerator.java diff --git a/src/main/java/com/uniovi/components/generators/geography/CurrencyQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/CurrencyQuestionGenerator.java new file mode 100644 index 00000000..14bda93f --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/geography/CurrencyQuestionGenerator.java @@ -0,0 +1,76 @@ +package com.uniovi.components.generators.geography; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; + +public class CurrencyQuestionGenerator extends AbstractGeographyGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "What is the currency of "); + put("es", "¿Cuál es la moneda de "); + put("fr", "Quelle est la monnaie de "); + } + }; + + public CurrencyQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?country ?countryLabel ?currency ?currencyLabel\n" + + "WHERE {" + + " ?country wdt:P31 wd:Q3624078 ." + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + + " ?country wdt:P38 ?currency ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllCurrencies(JsonNode resultsNode, String correctCurrency) { + // Obtener todas las monedas del JSON (distintas a la moneda correcta) + List allCurrencies = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String currency = result.path("currencyLabel").path("value").asText(); + if (!currency.equals(correctCurrency)) { + allCurrencies.add(currency); + } + } + return allCurrencies; + } + + private List selectRandomIncorrectCurrencies(List allCurrencies, String correctCurrency, int count) { + List incorrectCurrencies = new ArrayList<>(); + while (incorrectCurrencies.size() < count && allCurrencies.size() > 0) { + int randomIndex = random.nextInt(allCurrencies.size()); + String selectedCurrency = allCurrencies.remove(randomIndex); + if (!selectedCurrency.equals(correctCurrency) && !incorrectCurrencies.contains(selectedCurrency)) { + incorrectCurrencies.add(selectedCurrency); + } + } + return incorrectCurrencies; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String currencyLabel = result.path("currencyLabel").path("value").asText(); + return selectRandomIncorrectCurrencies(getAllCurrencies(results, currencyLabel), currencyLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("currencyLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("countryLabel").path("value").asText() + "?"; + } +} From 6d1b749b0cfd3cc8a325b09be22a8c704f16813f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:51:36 +0200 Subject: [PATCH 003/161] New geography question template: Population --- .../geography/LanguageQuestionGenerator.java | 76 +++++++++++++++++++ .../PopulationQuestionGenerator.java | 52 +++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/geography/LanguageQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/geography/PopulationQuestionGenerator.java diff --git a/src/main/java/com/uniovi/components/generators/geography/LanguageQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/LanguageQuestionGenerator.java new file mode 100644 index 00000000..b1bf363a --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/geography/LanguageQuestionGenerator.java @@ -0,0 +1,76 @@ +package com.uniovi.components.generators.geography; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; + +public class LanguageQuestionGenerator extends AbstractGeographyGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "What is the official language of "); + put("es", "¿Cuál es el idioma oficial de "); + put("fr", "Quelle est la langue officielle de "); + } + }; + + public LanguageQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?country ?countryLabel ?language ?languageLabel\n" + + "WHERE {" + + " ?country wdt:P31 wd:Q3624078 ." + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + + " ?country wdt:P37 ?language ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllLanguages(JsonNode resultsNode, String correctLanguage) { + // Obtener todos los idiomas del JSON (distintos al idioma correcto) + List allLanguages = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String language = result.path("languageLabel").path("value").asText(); + if (!language.equals(correctLanguage)) { + allLanguages.add(language); + } + } + return allLanguages; + } + + private List selectRandomIncorrectLanguages(List allLanguages, String correctLanguage, int count) { + List incorrectLanguages = new ArrayList<>(); + while (incorrectLanguages.size() < count && allLanguages.size() > 0) { + int randomIndex = random.nextInt(allLanguages.size()); + String selectedLanguage = allLanguages.remove(randomIndex); + if (!selectedLanguage.equals(correctLanguage) && !incorrectLanguages.contains(selectedLanguage)) { + incorrectLanguages.add(selectedLanguage); + } + } + return incorrectLanguages; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String languageLabel = result.path("languageLabel").path("value").asText(); + return selectRandomIncorrectLanguages(getAllLanguages(results, languageLabel), languageLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("languageLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("countryLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/geography/PopulationQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/PopulationQuestionGenerator.java new file mode 100644 index 00000000..e0df4901 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/geography/PopulationQuestionGenerator.java @@ -0,0 +1,52 @@ +package com.uniovi.components.generators.geography; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; + +public class PopulationQuestionGenerator extends AbstractGeographyGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "What is the population of "); + put("es", "¿Cuál es la población de "); + put("fr", "Quelle est la population de "); + } + }; + + public PopulationQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?country ?countryLabel ?population\n" + + "WHERE {" + + " ?country wdt:P31 wd:Q3624078 ." + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + + " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + + " ?country wdt:P1082 ?population ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + // Este generador de preguntas no necesita opciones, ya que la respuesta correcta es la población. + return Collections.emptyList(); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("population").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("countryLabel").path("value").asText() + "?"; + } +} From 898364921af083607ab386f8e922a57d8ab3b5a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:53:44 +0200 Subject: [PATCH 004/161] New geography question category: History --- .../java/com/uniovi/services/impl/CategoryServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java index 636bffe5..53bd6936 100644 --- a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java @@ -40,7 +40,8 @@ public Category getCategoryByName(String name) { } private static final Map.Entry[] CATEGORIES = new AbstractMap.SimpleEntry[] { - new AbstractMap.SimpleEntry<>("Geography", "Questions about geography") + new AbstractMap.SimpleEntry<>("Geography", "Questions about geography"), + new AbstractMap.SimpleEntry<>("History", "Questions about history") }; @PostConstruct From 3f412859ac974c5974b88fb9425a6d501d39fa4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:54:21 +0200 Subject: [PATCH 005/161] Revert "New geography question category: History" This reverts commit 898364921af083607ab386f8e922a57d8ab3b5a7. --- .../java/com/uniovi/services/impl/CategoryServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java index 53bd6936..636bffe5 100644 --- a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java @@ -40,8 +40,7 @@ public Category getCategoryByName(String name) { } private static final Map.Entry[] CATEGORIES = new AbstractMap.SimpleEntry[] { - new AbstractMap.SimpleEntry<>("Geography", "Questions about geography"), - new AbstractMap.SimpleEntry<>("History", "Questions about history") + new AbstractMap.SimpleEntry<>("Geography", "Questions about geography") }; @PostConstruct From 2888e2dc95a7cc08775239b48285831b08e1029d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:55:17 +0200 Subject: [PATCH 006/161] New history question template: Artifact --- .../history/AbstractHistoryGenerator.java | 17 +++++ .../HistoricalArtifactQuestionGeneration.java | 75 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/history/AbstractHistoryGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalArtifactQuestionGeneration.java diff --git a/src/main/java/com/uniovi/components/generators/history/AbstractHistoryGenerator.java b/src/main/java/com/uniovi/components/generators/history/AbstractHistoryGenerator.java new file mode 100644 index 00000000..da8d870b --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/history/AbstractHistoryGenerator.java @@ -0,0 +1,17 @@ +package com.uniovi.components.generators.history; + +import com.uniovi.components.generators.AbstractQuestionGenerator; +import com.uniovi.entities.Category; +import com.uniovi.services.CategoryService; + +public abstract class AbstractHistoryGenerator extends AbstractQuestionGenerator { + + protected AbstractHistoryGenerator(CategoryService categoryService) { + super(categoryService); + } + + @Override + public Category getCategory() { + return categoryService.getCategoryByName("History"); + } +} diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalArtifactQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalArtifactQuestionGeneration.java new file mode 100644 index 00000000..0bb30abf --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/history/HistoricalArtifactQuestionGeneration.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.history; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.*; + +public class HistoricalArtifactQuestionGeneration extends AbstractHistoryGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which historical artifact is associated with "); + put("es", "¿Con qué artefacto histórico se asocia "); + put("fr", "Quel artefact historique est associé à "); + } + }; + + public HistoricalArtifactQuestionGeneration(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + private List getAllArtifacts(JsonNode resultsNode, String correctArtifact) { + // Obtaining all historical artifacts from the JSON (different from the correct artifact) + List allArtifacts = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String artifact = result.path("artifactLabel").path("value").asText(); + if (!artifact.equals(correctArtifact)) { + allArtifacts.add(artifact); + } + } + return allArtifacts; + } + + private List selectRandomIncorrectArtifacts(List allArtifacts, String correctArtifact, int count) { + List incorrectArtifacts = new ArrayList<>(); + while (incorrectArtifacts.size() < count && allArtifacts.size() > 0) { + int randomIndex = random.nextInt(allArtifacts.size()); + String selectedArtifact = allArtifacts.remove(randomIndex); + if (!selectedArtifact.equals(correctArtifact) && !incorrectArtifacts.contains(selectedArtifact)) { + incorrectArtifacts.add(selectedArtifact); + } + } + return incorrectArtifacts; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String artifactLabel = result.path("artifactLabel").path("value").asText(); + return selectRandomIncorrectArtifacts(getAllArtifacts(results, artifactLabel), artifactLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("artifactLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?artifact ?artifactLabel ?historicalEvent ?historicalEventLabel\n" + + "WHERE {" + + " ?artifact wdt:P31 wd:Q5314 ." + + " ?historicalEvent wdt:P31 wd:Q198 ." + + " OPTIONAL { ?artifact wdt:P1080 ?historicalEvent } ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}" + + "ORDER BY ?artifactLabel"; + } +} From 6d67b5e19338fd387b603bfd807bdb3c7138cb65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:56:06 +0200 Subject: [PATCH 007/161] New history question template: Battle --- .../HistoricalBattleQuestionGeneration.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalBattleQuestionGeneration.java diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalBattleQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalBattleQuestionGeneration.java new file mode 100644 index 00000000..5c83c79c --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/history/HistoricalBattleQuestionGeneration.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.history; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.*; + +public class HistoricalBattleQuestionGeneration extends AbstractHistoryGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which historical battle is associated with "); + put("es", "¿Con qué batalla histórica se asocia "); + put("fr", "Quelle bataille historique est associée à "); + } + }; + + public HistoricalBattleQuestionGeneration(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + private List getAllBattles(JsonNode resultsNode, String correctBattle) { + // Obtaining all historical battles from the JSON (different from the correct battle) + List allBattles = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String battle = result.path("battleLabel").path("value").asText(); + if (!battle.equals(correctBattle)) { + allBattles.add(battle); + } + } + return allBattles; + } + + private List selectRandomIncorrectBattles(List allBattles, String correctBattle, int count) { + List incorrectBattles = new ArrayList<>(); + while (incorrectBattles.size() < count && allBattles.size() > 0) { + int randomIndex = random.nextInt(allBattles.size()); + String selectedBattle = allBattles.remove(randomIndex); + if (!selectedBattle.equals(correctBattle) && !incorrectBattles.contains(selectedBattle)) { + incorrectBattles.add(selectedBattle); + } + } + return incorrectBattles; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String battleLabel = result.path("battleLabel").path("value").asText(); + return selectRandomIncorrectBattles(getAllBattles(results, battleLabel), battleLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("battleLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?battle ?battleLabel ?historicalEvent ?historicalEventLabel\n" + + "WHERE {" + + " ?battle wdt:P31 wd:Q178561 ." + + " ?historicalEvent wdt:P31 wd:Q198 ." + + " OPTIONAL { ?battle wdt:P361 ?historicalEvent } ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}" + + "ORDER BY ?battleLabel"; + } +} From 760b15a608187a49ef4aa6e57a0d27870b0e0bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:56:32 +0200 Subject: [PATCH 008/161] New history question template: Dynasty --- .../HistoricalDynastyQuestionGeneration.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalDynastyQuestionGeneration.java diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalDynastyQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalDynastyQuestionGeneration.java new file mode 100644 index 00000000..7f65f88e --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/history/HistoricalDynastyQuestionGeneration.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.history; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.*; + +public class HistoricalDynastyQuestionGeneration extends AbstractHistoryGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which historical dynasty is associated with "); + put("es", "¿Con qué dinastía histórica se asocia "); + put("fr", "Quelle dynastie historique est associée à "); + } + }; + + public HistoricalDynastyQuestionGeneration(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + private List getAllDynasties(JsonNode resultsNode, String correctDynasty) { + // Obtaining all historical dynasties from the JSON (different from the correct dynasty) + List allDynasties = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String dynasty = result.path("dynastyLabel").path("value").asText(); + if (!dynasty.equals(correctDynasty)) { + allDynasties.add(dynasty); + } + } + return allDynasties; + } + + private List selectRandomIncorrectDynasties(List allDynasties, String correctDynasty, int count) { + List incorrectDynasties = new ArrayList<>(); + while (incorrectDynasties.size() < count && allDynasties.size() > 0) { + int randomIndex = random.nextInt(allDynasties.size()); + String selectedDynasty = allDynasties.remove(randomIndex); + if (!selectedDynasty.equals(correctDynasty) && !incorrectDynasties.contains(selectedDynasty)) { + incorrectDynasties.add(selectedDynasty); + } + } + return incorrectDynasties; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String dynastyLabel = result.path("dynastyLabel").path("value").asText(); + return selectRandomIncorrectDynasties(getAllDynasties(results, dynastyLabel), dynastyLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("dynastyLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?dynasty ?dynastyLabel ?historicalEvent ?historicalEventLabel\n" + + "WHERE {" + + " ?dynasty wdt:P31 wd:Q11410 ." + + " ?historicalEvent wdt:P31 wd:Q198 ." + + " OPTIONAL { ?dynasty wdt:P108 ?historicalEvent } ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}" + + "ORDER BY ?dynastyLabel"; + } +} From 53c1dff15626483dae977902841279362f3f2a84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:56:55 +0200 Subject: [PATCH 009/161] New history question template: Event --- .../HistoricalEventQuestionGeneration.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalEventQuestionGeneration.java diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalEventQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalEventQuestionGeneration.java new file mode 100644 index 00000000..cede3058 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/history/HistoricalEventQuestionGeneration.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.history; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.*; + +public class HistoricalEventQuestionGeneration extends AbstractHistoryGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "In what historical event did "); + put("es", "¿En qué evento histórico participó "); + put("fr", "Dans quel événement historique a participé "); + } + }; + + public HistoricalEventQuestionGeneration(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + private List getAllEvents(JsonNode resultsNode, String correctEvent) { + // Obtener todos los eventos históricos del JSON (diferentes al evento correcto) + List allEvents = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String event = result.path("eventLabel").path("value").asText(); + if (!event.equals(correctEvent)) { + allEvents.add(event); + } + } + return allEvents; + } + + private List selectRandomIncorrectEvents(List allEvents, String correctEvent, int count) { + List incorrectEvents = new ArrayList<>(); + while (incorrectEvents.size() < count && allEvents.size() > 0) { + int randomIndex = random.nextInt(allEvents.size()); + String selectedEvent = allEvents.remove(randomIndex); + if (!selectedEvent.equals(correctEvent) && !incorrectEvents.contains(selectedEvent)) { + incorrectEvents.add(selectedEvent); + } + } + return incorrectEvents; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String eventLabel = result.path("eventLabel").path("value").asText(); + return selectRandomIncorrectEvents(getAllEvents(results, eventLabel), eventLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("eventLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("personLabel").path("value").asText() + "?"; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?person ?personLabel ?event ?eventLabel\n" + + "WHERE {" + + " ?person wdt:P31 wd:Q5 ." + + " ?event wdt:P31 wd:Q198 ." + + " OPTIONAL { ?person wdt:P106 ?event } ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}" + + "ORDER BY ?personLabel"; + } +} From d559d2a26ceac010bdd38f2cec0554c86d3639d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:57:08 +0200 Subject: [PATCH 010/161] New history question template: Invention --- ...HistoricalInventionQuestionGeneration.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalInventionQuestionGeneration.java diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalInventionQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalInventionQuestionGeneration.java new file mode 100644 index 00000000..01af421d --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/history/HistoricalInventionQuestionGeneration.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.history; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.*; + +public class HistoricalInventionQuestionGeneration extends AbstractHistoryGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which historical invention is associated with "); + put("es", "¿Con qué invención histórica se asocia "); + put("fr", "Quelle invention historique est associée à "); + } + }; + + public HistoricalInventionQuestionGeneration(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + private List getAllInventions(JsonNode resultsNode, String correctInvention) { + // Obtaining all historical inventions from the JSON (different from the correct invention) + List allInventions = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String invention = result.path("inventionLabel").path("value").asText(); + if (!invention.equals(correctInvention)) { + allInventions.add(invention); + } + } + return allInventions; + } + + private List selectRandomIncorrectInventions(List allInventions, String correctInvention, int count) { + List incorrectInventions = new ArrayList<>(); + while (incorrectInventions.size() < count && allInventions.size() > 0) { + int randomIndex = random.nextInt(allInventions.size()); + String selectedInvention = allInventions.remove(randomIndex); + if (!selectedInvention.equals(correctInvention) && !incorrectInventions.contains(selectedInvention)) { + incorrectInventions.add(selectedInvention); + } + } + return incorrectInventions; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String inventionLabel = result.path("inventionLabel").path("value").asText(); + return selectRandomIncorrectInventions(getAllInventions(results, inventionLabel), inventionLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("inventionLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?invention ?inventionLabel ?historicalEvent ?historicalEventLabel\n" + + "WHERE {" + + " ?invention wdt:P31 wd:Q39614 ." + + " ?historicalEvent wdt:P31 wd:Q198 ." + + " OPTIONAL { ?invention wdt:P921 ?historicalEvent } ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}" + + "ORDER BY ?inventionLabel"; + } +} From 277b86216a8746f403c234353c0edfc5cb1fc016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:57:26 +0200 Subject: [PATCH 011/161] New history question template: Leader --- .../HistoricalLeaderQuestionGeneration.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalLeaderQuestionGeneration.java diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalLeaderQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalLeaderQuestionGeneration.java new file mode 100644 index 00000000..17cce194 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/history/HistoricalLeaderQuestionGeneration.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.history; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.*; + +public class HistoricalLeaderQuestionGeneration extends AbstractHistoryGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which historical leader is associated with "); + put("es", "¿Con qué líder histórico se asocia "); + put("fr", "Quel leader historique est associé à "); + } + }; + + public HistoricalLeaderQuestionGeneration(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + private List getAllLeaders(JsonNode resultsNode, String correctLeader) { + // Obtaining all historical leaders from the JSON (different from the correct leader) + List allLeaders = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String leader = result.path("leaderLabel").path("value").asText(); + if (!leader.equals(correctLeader)) { + allLeaders.add(leader); + } + } + return allLeaders; + } + + private List selectRandomIncorrectLeaders(List allLeaders, String correctLeader, int count) { + List incorrectLeaders = new ArrayList<>(); + while (incorrectLeaders.size() < count && allLeaders.size() > 0) { + int randomIndex = random.nextInt(allLeaders.size()); + String selectedLeader = allLeaders.remove(randomIndex); + if (!selectedLeader.equals(correctLeader) && !incorrectLeaders.contains(selectedLeader)) { + incorrectLeaders.add(selectedLeader); + } + } + return incorrectLeaders; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String leaderLabel = result.path("leaderLabel").path("value").asText(); + return selectRandomIncorrectLeaders(getAllLeaders(results, leaderLabel), leaderLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("leaderLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?leader ?leaderLabel ?historicalEvent ?historicalEventLabel\n" + + "WHERE {" + + " ?leader wdt:P31 wd:Q5 ." + + " ?historicalEvent wdt:P31 wd:Q198 ." + + " OPTIONAL { ?leader wdt:P6 ?historicalEvent } ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}" + + "ORDER BY ?leaderLabel"; + } +} From 983432a8fd36da46837abd59c7364cf6e60e74b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:57:45 +0200 Subject: [PATCH 012/161] New history question template: Period --- .../HistoricalPeriodQuestionGeneration.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalPeriodQuestionGeneration.java diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalPeriodQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalPeriodQuestionGeneration.java new file mode 100644 index 00000000..b1a7f81c --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/history/HistoricalPeriodQuestionGeneration.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.history; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.*; + +public class HistoricalPeriodQuestionGeneration extends AbstractHistoryGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which historical period is associated with "); + put("es", "¿Con qué período histórico se asocia "); + put("fr", "Quelle période historique est associée à "); + } + }; + + public HistoricalPeriodQuestionGeneration(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + private List getAllPeriods(JsonNode resultsNode, String correctPeriod) { + // Obtaining all historical periods from the JSON (different from the correct period) + List allPeriods = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String period = result.path("periodLabel").path("value").asText(); + if (!period.equals(correctPeriod)) { + allPeriods.add(period); + } + } + return allPeriods; + } + + private List selectRandomIncorrectPeriods(List allPeriods, String correctPeriod, int count) { + List incorrectPeriods = new ArrayList<>(); + while (incorrectPeriods.size() < count && allPeriods.size() > 0) { + int randomIndex = random.nextInt(allPeriods.size()); + String selectedPeriod = allPeriods.remove(randomIndex); + if (!selectedPeriod.equals(correctPeriod) && !incorrectPeriods.contains(selectedPeriod)) { + incorrectPeriods.add(selectedPeriod); + } + } + return incorrectPeriods; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String periodLabel = result.path("periodLabel").path("value").asText(); + return selectRandomIncorrectPeriods(getAllPeriods(results, periodLabel), periodLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("periodLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?period ?periodLabel ?historicalEvent ?historicalEventLabel\n" + + "WHERE {" + + " ?period wdt:P31 wd:Q186067 ." + + " ?historicalEvent wdt:P31 wd:Q198 ." + + " OPTIONAL { ?period wdt:P155 ?historicalEvent } ." + + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}" + + "ORDER BY ?periodLabel"; + } +} From 4ccf34844a637cca296a0b262dc1d184533ccace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Sat, 6 Apr 2024 22:58:31 +0200 Subject: [PATCH 013/161] InsertSampleDataService updated with new question templates --- .../services/InsertSampleDataService.java | 86 +++++++++++++++---- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/uniovi/services/InsertSampleDataService.java b/src/main/java/com/uniovi/services/InsertSampleDataService.java index cfab4b6d..add55fcf 100644 --- a/src/main/java/com/uniovi/services/InsertSampleDataService.java +++ b/src/main/java/com/uniovi/services/InsertSampleDataService.java @@ -2,9 +2,8 @@ import com.uniovi.components.MultipleQuestionGenerator; import com.uniovi.components.generators.QuestionGenerator; -import com.uniovi.components.generators.geography.BorderQuestionGenerator; -import com.uniovi.components.generators.geography.CapitalQuestionGenerator; -import com.uniovi.components.generators.geography.ContinentQuestionGeneration; +import com.uniovi.components.generators.geography.*; +import com.uniovi.components.generators.history.*; import com.uniovi.dto.PlayerDto; import com.uniovi.entities.Associations; import com.uniovi.entities.GameSession; @@ -14,6 +13,7 @@ import com.uniovi.repositories.QuestionRepository; import jakarta.annotation.PostConstruct; import jakarta.transaction.Transactional; +import org.hibernate.validator.constraints.Currency; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -69,33 +69,87 @@ public void insertSampleQuestions() { @Transactional public void generateSampleData() { - questionRepository.deleteAll(); - MultipleQuestionGenerator allQuestionGenerator = new MultipleQuestionGenerator( + // Generar preguntas de geografía en inglés + MultipleQuestionGenerator geographyQuestionsEn = new MultipleQuestionGenerator( new ContinentQuestionGeneration(categoryService, Question.ENGLISH), new CapitalQuestionGenerator(categoryService, Question.ENGLISH), - new BorderQuestionGenerator(categoryService, Question.ENGLISH) + new BorderQuestionGenerator(categoryService, Question.ENGLISH), + new AreaQuestionGenerator(categoryService, Question.ENGLISH), + new CurrencyQuestionGenerator(categoryService, Question.ENGLISH), + new LanguageQuestionGenerator(categoryService, Question.ENGLISH), + new PopulationQuestionGenerator(categoryService, Question.ENGLISH) ); - List questionsEn = allQuestionGenerator.getQuestions(); - questionsEn.forEach(questionService::addNewQuestion); + List geographyQuestions = geographyQuestionsEn.getQuestions(); + geographyQuestions.forEach(questionService::addNewQuestion); - allQuestionGenerator = new MultipleQuestionGenerator( + // Generar preguntas de geografía en español + MultipleQuestionGenerator geographyQuestionsEs = new MultipleQuestionGenerator( new ContinentQuestionGeneration(categoryService, Question.SPANISH), new CapitalQuestionGenerator(categoryService, Question.SPANISH), - new BorderQuestionGenerator(categoryService, Question.SPANISH) + new BorderQuestionGenerator(categoryService, Question.SPANISH), + new AreaQuestionGenerator(categoryService, Question.SPANISH), + new CurrencyQuestionGenerator(categoryService, Question.SPANISH), + new LanguageQuestionGenerator(categoryService, Question.SPANISH), + new PopulationQuestionGenerator(categoryService, Question.SPANISH) ); - List questionsEs = allQuestionGenerator.getQuestions(); - questionsEs.forEach(questionService::addNewQuestion); + List geographyQuestionsSpanish = geographyQuestionsEs.getQuestions(); + geographyQuestionsSpanish.forEach(questionService::addNewQuestion); - allQuestionGenerator = new MultipleQuestionGenerator( + // Generar preguntas de geografía en francés + MultipleQuestionGenerator geographyQuestionsFr = new MultipleQuestionGenerator( new ContinentQuestionGeneration(categoryService, Question.FRENCH), new CapitalQuestionGenerator(categoryService, Question.FRENCH), - new BorderQuestionGenerator(categoryService, Question.FRENCH) + new BorderQuestionGenerator(categoryService, Question.FRENCH), + new AreaQuestionGenerator(categoryService, Question.FRENCH), + new CurrencyQuestionGenerator(categoryService, Question.FRENCH), + new LanguageQuestionGenerator(categoryService, Question.FRENCH), + new PopulationQuestionGenerator(categoryService, Question.FRENCH) + ); + List geographyQuestionsFrench = geographyQuestionsFr.getQuestions(); + geographyQuestionsFrench.forEach(questionService::addNewQuestion); + + // Generar preguntas de historia en inglés + MultipleQuestionGenerator historyQuestionsEn = new MultipleQuestionGenerator( + new HistoricalArtifactQuestionGeneration(categoryService, Question.ENGLISH), + new HistoricalBattleQuestionGeneration(categoryService, Question.ENGLISH), + new HistoricalDynastyQuestionGeneration(categoryService, Question.ENGLISH), + new HistoricalEventQuestionGeneration(categoryService, Question.ENGLISH), + new HistoricalInventionQuestionGeneration(categoryService, Question.ENGLISH), + new HistoricalPeriodQuestionGeneration(categoryService, Question.ENGLISH), + new HistoricalLeaderQuestionGeneration(categoryService, Question.ENGLISH) + ); + List historyQuestions = historyQuestionsEn.getQuestions(); + historyQuestions.forEach(questionService::addNewQuestion); + + // Generar preguntas de historia en español + MultipleQuestionGenerator historyQuestionsEs = new MultipleQuestionGenerator( + new HistoricalArtifactQuestionGeneration(categoryService, Question.SPANISH), + new HistoricalBattleQuestionGeneration(categoryService, Question.SPANISH), + new HistoricalDynastyQuestionGeneration(categoryService, Question.SPANISH), + new HistoricalEventQuestionGeneration(categoryService, Question.SPANISH), + new HistoricalInventionQuestionGeneration(categoryService, Question.SPANISH), + new HistoricalPeriodQuestionGeneration(categoryService, Question.SPANISH), + new HistoricalLeaderQuestionGeneration(categoryService, Question.SPANISH) + ); + List historyQuestionsSpanish = historyQuestionsEs.getQuestions(); + historyQuestionsSpanish.forEach(questionService::addNewQuestion); + + // Generar preguntas de historia en francés + MultipleQuestionGenerator historyQuestionsFr = new MultipleQuestionGenerator( + new HistoricalArtifactQuestionGeneration(categoryService, Question.FRENCH), + new HistoricalBattleQuestionGeneration(categoryService, Question.FRENCH), + new HistoricalDynastyQuestionGeneration(categoryService, Question.FRENCH), + new HistoricalEventQuestionGeneration(categoryService, Question.FRENCH), + new HistoricalInventionQuestionGeneration(categoryService, Question.FRENCH), + new HistoricalPeriodQuestionGeneration(categoryService, Question.FRENCH), + new HistoricalLeaderQuestionGeneration(categoryService, Question.FRENCH) ); - List questionsFr = allQuestionGenerator.getQuestions(); - questionsFr.forEach(questionService::addNewQuestion); + List historyQuestionsFrench = historyQuestionsFr.getQuestions(); + historyQuestionsFrench.forEach(questionService::addNewQuestion); log.info("Sample questions inserted"); } + } From 5b978a5df1f82a56bc2b5d264f4dea822b7d8833 Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Sat, 6 Apr 2024 23:21:57 +0200 Subject: [PATCH 014/161] Fix - Add new question category: History --- .../java/com/uniovi/services/impl/CategoryServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java index 636bffe5..53bd6936 100644 --- a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java @@ -40,7 +40,8 @@ public Category getCategoryByName(String name) { } private static final Map.Entry[] CATEGORIES = new AbstractMap.SimpleEntry[] { - new AbstractMap.SimpleEntry<>("Geography", "Questions about geography") + new AbstractMap.SimpleEntry<>("Geography", "Questions about geography"), + new AbstractMap.SimpleEntry<>("History", "Questions about history") }; @PostConstruct From 79cbfb5de46deeb2bc136645bc1dbc53c330b6b8 Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Sat, 6 Apr 2024 23:46:19 +0200 Subject: [PATCH 015/161] Add new question category and templates: Science --- .../science/AbstractScienceGenerator.java | 17 +++++ .../MathPhysicsFormulaQuestionGenerator.java | 75 ++++++++++++++++++ ...cientificAchievementQuestionGenerator.java | 76 +++++++++++++++++++ .../ScientificDiscoveryQuestionGenerator.java | 76 +++++++++++++++++++ .../ScientistBirthplaceQuestionGenerator.java | 76 +++++++++++++++++++ .../services/impl/CategoryServiceImpl.java | 3 +- 6 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/uniovi/components/generators/science/AbstractScienceGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java diff --git a/src/main/java/com/uniovi/components/generators/science/AbstractScienceGenerator.java b/src/main/java/com/uniovi/components/generators/science/AbstractScienceGenerator.java new file mode 100644 index 00000000..8978f068 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/science/AbstractScienceGenerator.java @@ -0,0 +1,17 @@ +package com.uniovi.components.generators.science; + +import com.uniovi.components.generators.AbstractQuestionGenerator; +import com.uniovi.entities.Category; +import com.uniovi.services.CategoryService; + +public abstract class AbstractScienceGenerator extends AbstractQuestionGenerator { + + protected AbstractScienceGenerator(CategoryService categoryService) { + super(categoryService); + } + + @Override + public Category getCategory() { + return categoryService.getCategoryByName("Science"); + } +} diff --git a/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java new file mode 100644 index 00000000..666b7052 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.science; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class MathPhysicsFormulaQuestionGenerator extends AbstractScienceGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "What is the formula for "); + put("es", "¿Cuál es la fórmula para "); + put("fr", "Quelle est la formule pour "); + } + }; + + public MathPhysicsFormulaQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?formula ?formulaLabel\n" + + "WHERE {" + + " ?formula wdt:P31 wd:Q5185279 ." + // Instance of Mathematical or physical formula + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllFormulas(JsonNode resultsNode, String correctFormula) { + List allFormulas = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String formula = result.path("formulaLabel").path("value").asText(); + if (!formula.equals(correctFormula)) { + allFormulas.add(formula); + } + } + return allFormulas; + } + + private List selectRandomIncorrectFormulas(List allFormulas, String correctFormula, int count) { + List incorrectFormulas = new ArrayList<>(); + while (incorrectFormulas.size() < count && allFormulas.size() > 0) { + int randomIndex = random.nextInt(allFormulas.size()); + String selectedFormula = allFormulas.remove(randomIndex); + if (!selectedFormula.equals(correctFormula) && !incorrectFormulas.contains(selectedFormula)) { + incorrectFormulas.add(selectedFormula); + } + } + return incorrectFormulas; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String formulaLabel = result.path("formulaLabel").path("value").asText(); + return selectRandomIncorrectFormulas(getAllFormulas(results, formulaLabel), formulaLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("formulaLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("formulaLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java new file mode 100644 index 00000000..a3812b60 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java @@ -0,0 +1,76 @@ +package com.uniovi.components.generators.science; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class ScientificAchievementQuestionGenerator extends AbstractScienceGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "What significant achievement is associated with "); + put("es", "¿Qué logro significativo está asociado con "); + put("fr", "Quelle réalisation significative est associée à "); + } + }; + + public ScientificAchievementQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?scientist ?scientistLabel ?achievement ?achievementLabel\n" + + "WHERE {" + + " ?scientist wdt:P31 wd:Q5 ." + // Instance of Human + " ?scientist wdt:P166 ?achievement ." + // Notable achievement + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllAchievements(JsonNode resultsNode, String correctAchievement) { + List allAchievements = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String achievement = result.path("achievementLabel").path("value").asText(); + if (!achievement.equals(correctAchievement)) { + allAchievements.add(achievement); + } + } + return allAchievements; + } + + private List selectRandomIncorrectAchievements(List allAchievements, String correctAchievement, int count) { + List incorrectAchievements = new ArrayList<>(); + while (incorrectAchievements.size() < count && allAchievements.size() > 0) { + int randomIndex = random.nextInt(allAchievements.size()); + String selectedAchievement = allAchievements.remove(randomIndex); + if (!selectedAchievement.equals(correctAchievement) && !incorrectAchievements.contains(selectedAchievement)) { + incorrectAchievements.add(selectedAchievement); + } + } + return incorrectAchievements; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String achievementLabel = result.path("achievementLabel").path("value").asText(); + return selectRandomIncorrectAchievements(getAllAchievements(results, achievementLabel), achievementLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("achievementLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("scientistLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java new file mode 100644 index 00000000..53fc837b --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java @@ -0,0 +1,76 @@ +package com.uniovi.components.generators.science; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class ScientificDiscoveryQuestionGenerator extends AbstractScienceGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Who discovered "); + put("es", "¿Quién descubrió "); + put("fr", "Qui a découvert "); + } + }; + + public ScientificDiscoveryQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?scientist ?scientistLabel ?discovery ?discoveryLabel\n" + + "WHERE {" + + " ?scientist wdt:P31 wd:Q5 ." + // Instance of Human + " ?scientist wdt:P61 ?discovery ." + // Discovery + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllDiscoveries(JsonNode resultsNode, String correctDiscovery) { + List allDiscoveries = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String discovery = result.path("discoveryLabel").path("value").asText(); + if (!discovery.equals(correctDiscovery)) { + allDiscoveries.add(discovery); + } + } + return allDiscoveries; + } + + private List selectRandomIncorrectDiscoveries(List allDiscoveries, String correctDiscovery, int count) { + List incorrectDiscoveries = new ArrayList<>(); + while (incorrectDiscoveries.size() < count && allDiscoveries.size() > 0) { + int randomIndex = random.nextInt(allDiscoveries.size()); + String selectedDiscovery = allDiscoveries.remove(randomIndex); + if (!selectedDiscovery.equals(correctDiscovery) && !incorrectDiscoveries.contains(selectedDiscovery)) { + incorrectDiscoveries.add(selectedDiscovery); + } + } + return incorrectDiscoveries; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String discoveryLabel = result.path("discoveryLabel").path("value").asText(); + return selectRandomIncorrectDiscoveries(getAllDiscoveries(results, discoveryLabel), discoveryLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("scientistLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("discoveryLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java new file mode 100644 index 00000000..2e1183a6 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java @@ -0,0 +1,76 @@ +package com.uniovi.components.generators.science; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class ScientistBirthplaceQuestionGenerator extends AbstractScienceGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Where was the scientist "); + put("es", "¿Dónde nació el científico "); + put("fr", "Où est né le scientifique "); + } + }; + + public ScientistBirthplaceQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?scientist ?scientistLabel ?birthplace ?birthplaceLabel\n" + + "WHERE {" + + " ?scientist wdt:P31 wd:Q5 ." + // Instance of Human + " ?scientist wdt:P19 ?birthplace ." + // Place of birth + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllBirthplaces(JsonNode resultsNode, String correctBirthplace) { + List allBirthplaces = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String birthplace = result.path("birthplaceLabel").path("value").asText(); + if (!birthplace.equals(correctBirthplace)) { + allBirthplaces.add(birthplace); + } + } + return allBirthplaces; + } + + private List selectRandomIncorrectBirthplaces(List allBirthplaces, String correctBirthplace, int count) { + List incorrectBirthplaces = new ArrayList<>(); + while (incorrectBirthplaces.size() < count && allBirthplaces.size() > 0) { + int randomIndex = random.nextInt(allBirthplaces.size()); + String selectedBirthplace = allBirthplaces.remove(randomIndex); + if (!selectedBirthplace.equals(correctBirthplace) && !incorrectBirthplaces.contains(selectedBirthplace)) { + incorrectBirthplaces.add(selectedBirthplace); + } + } + return incorrectBirthplaces; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String birthplaceLabel = result.path("birthplaceLabel").path("value").asText(); + return selectRandomIncorrectBirthplaces(getAllBirthplaces(results, birthplaceLabel), birthplaceLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("birthplaceLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("scientistLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java index 53bd6936..a973d6cf 100644 --- a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java @@ -41,7 +41,8 @@ public Category getCategoryByName(String name) { private static final Map.Entry[] CATEGORIES = new AbstractMap.SimpleEntry[] { new AbstractMap.SimpleEntry<>("Geography", "Questions about geography"), - new AbstractMap.SimpleEntry<>("History", "Questions about history") + new AbstractMap.SimpleEntry<>("History", "Questions about history"), + new AbstractMap.SimpleEntry<>("Science", "Questions about science"), }; @PostConstruct From 8fe0cac4ac3f996705d4efe93cb81b227b18b462 Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Sat, 6 Apr 2024 23:49:10 +0200 Subject: [PATCH 016/161] Add new question category and templates: Art --- .../generators/art/AbstractArtGenerator.java | 17 ++++ .../art/ArtMovementQuestionGenerator.java | 75 ++++++++++++++++++ .../art/ArtPeriodQuestionGenerator.java | 75 ++++++++++++++++++ .../art/ArtStyleQuestionGenerator.java | 75 ++++++++++++++++++ .../art/ArtWorkQuestionGenerator.java | 77 +++++++++++++++++++ .../services/impl/CategoryServiceImpl.java | 1 + 6 files changed, 320 insertions(+) create mode 100644 src/main/java/com/uniovi/components/generators/art/AbstractArtGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java diff --git a/src/main/java/com/uniovi/components/generators/art/AbstractArtGenerator.java b/src/main/java/com/uniovi/components/generators/art/AbstractArtGenerator.java new file mode 100644 index 00000000..8d0999ef --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/art/AbstractArtGenerator.java @@ -0,0 +1,17 @@ +package com.uniovi.components.generators.art; + +import com.uniovi.components.generators.AbstractQuestionGenerator; +import com.uniovi.entities.Category; +import com.uniovi.services.CategoryService; + +public abstract class AbstractArtGenerator extends AbstractQuestionGenerator { + + protected AbstractArtGenerator(CategoryService categoryService) { + super(categoryService); + } + + @Override + public Category getCategory() { + return categoryService.getCategoryByName("Art"); + } +} diff --git a/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java new file mode 100644 index 00000000..b83b1e25 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.art; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class ArtMovementQuestionGenerator extends AbstractArtGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which art movement is associated with "); + put("es", "¿Con qué movimiento artístico se asocia "); + put("fr", "Quel mouvement artistique est associé à "); + } + }; + + public ArtMovementQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?movement ?movementLabel\n" + + "WHERE {" + + " ?movement wdt:P31 wd:Q968159 ." + // Instance of Art movement + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllMovements(JsonNode resultsNode, String correctMovement) { + List allMovements = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String movement = result.path("movementLabel").path("value").asText(); + if (!movement.equals(correctMovement)) { + allMovements.add(movement); + } + } + return allMovements; + } + + private List selectRandomIncorrectMovements(List allMovements, String correctMovement, int count) { + List incorrectMovements = new ArrayList<>(); + while (incorrectMovements.size() < count && allMovements.size() > 0) { + int randomIndex = random.nextInt(allMovements.size()); + String selectedMovement = allMovements.remove(randomIndex); + if (!selectedMovement.equals(correctMovement) && !incorrectMovements.contains(selectedMovement)) { + incorrectMovements.add(selectedMovement); + } + } + return incorrectMovements; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String movementLabel = result.path("movementLabel").path("value").asText(); + return selectRandomIncorrectMovements(getAllMovements(results, movementLabel), movementLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("movementLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("movementLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java new file mode 100644 index 00000000..312c0086 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.art; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class ArtPeriodQuestionGenerator extends AbstractArtGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which art period is associated with "); + put("es", "¿Con qué período artístico se asocia "); + put("fr", "Quelle période artistique est associée à "); + } + }; + + public ArtPeriodQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?period ?periodLabel\n" + + "WHERE {" + + " ?period wdt:P31 wd:Q187437 ." + // Instance of Art period + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllPeriods(JsonNode resultsNode, String correctPeriod) { + List allPeriods = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String period = result.path("periodLabel").path("value").asText(); + if (!period.equals(correctPeriod)) { + allPeriods.add(period); + } + } + return allPeriods; + } + + private List selectRandomIncorrectPeriods(List allPeriods, String correctPeriod, int count) { + List incorrectPeriods = new ArrayList<>(); + while (incorrectPeriods.size() < count && allPeriods.size() > 0) { + int randomIndex = random.nextInt(allPeriods.size()); + String selectedPeriod = allPeriods.remove(randomIndex); + if (!selectedPeriod.equals(correctPeriod) && !incorrectPeriods.contains(selectedPeriod)) { + incorrectPeriods.add(selectedPeriod); + } + } + return incorrectPeriods; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String periodLabel = result.path("periodLabel").path("value").asText(); + return selectRandomIncorrectPeriods(getAllPeriods(results, periodLabel), periodLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("periodLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("periodLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java new file mode 100644 index 00000000..19cfafeb --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.art; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class ArtStyleQuestionGenerator extends AbstractArtGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which art style is associated with "); + put("es", "¿Con qué estilo artístico se asocia "); + put("fr", "Quel style artistique est associé à "); + } + }; + + public ArtStyleQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?style ?styleLabel\n" + + "WHERE {" + + " ?style wdt:P31 wd:Q179337 ." + // Instance of Art style + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllStyles(JsonNode resultsNode, String correctStyle) { + List allStyles = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String style = result.path("styleLabel").path("value").asText(); + if (!style.equals(correctStyle)) { + allStyles.add(style); + } + } + return allStyles; + } + + private List selectRandomIncorrectStyles(List allStyles, String correctStyle, int count) { + List incorrectStyles = new ArrayList<>(); + while (incorrectStyles.size() < count && allStyles.size() > 0) { + int randomIndex = random.nextInt(allStyles.size()); + String selectedStyle = allStyles.remove(randomIndex); + if (!selectedStyle.equals(correctStyle) && !incorrectStyles.contains(selectedStyle)) { + incorrectStyles.add(selectedStyle); + } + } + return incorrectStyles; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String styleLabel = result.path("styleLabel").path("value").asText(); + return selectRandomIncorrectStyles(getAllStyles(results, styleLabel), styleLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("styleLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("styleLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java new file mode 100644 index 00000000..38e40f6e --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java @@ -0,0 +1,77 @@ +package com.uniovi.components.generators.art; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class ArtWorkQuestionGenerator extends AbstractArtGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Who created the artwork "); + put("es", "¿Quién creó la obra de arte "); + put("fr", "Qui a créé l'œuvre d'art "); + } + }; + + public ArtWorkQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?artist ?artistLabel ?artwork ?artworkLabel\n" + + "WHERE {" + + " ?artist wdt:P31 wd:Q5 ." + // Instance of Human + " ?artwork wdt:P31 wd:Q3305213 ." + // Instance of Artwork + " ?artwork wdt:P170 ?artist ." + // Creator + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllArtworks(JsonNode resultsNode, String correctArtwork) { + List allArtworks = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String artwork = result.path("artworkLabel").path("value").asText(); + if (!artwork.equals(correctArtwork)) { + allArtworks.add(artwork); + } + } + return allArtworks; + } + + private List selectRandomIncorrectArtworks(List allArtworks, String correctArtwork, int count) { + List incorrectArtworks = new ArrayList<>(); + while (incorrectArtworks.size() < count && allArtworks.size() > 0) { + int randomIndex = random.nextInt(allArtworks.size()); + String selectedArtwork = allArtworks.remove(randomIndex); + if (!selectedArtwork.equals(correctArtwork) && !incorrectArtworks.contains(selectedArtwork)) { + incorrectArtworks.add(selectedArtwork); + } + } + return incorrectArtworks; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String artworkLabel = result.path("artworkLabel").path("value").asText(); + return selectRandomIncorrectArtworks(getAllArtworks(results, artworkLabel), artworkLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("artistLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("artworkLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java index a973d6cf..8ddcd60e 100644 --- a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java @@ -43,6 +43,7 @@ public Category getCategoryByName(String name) { new AbstractMap.SimpleEntry<>("Geography", "Questions about geography"), new AbstractMap.SimpleEntry<>("History", "Questions about history"), new AbstractMap.SimpleEntry<>("Science", "Questions about science"), + new AbstractMap.SimpleEntry<>("Science", "Questions about art") }; @PostConstruct From 41b2333d023580a385e1c70b2a8e1e5fadfe2849 Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Sat, 6 Apr 2024 23:50:43 +0200 Subject: [PATCH 017/161] Fix generators --- .../components/generators/art/ArtMovementQuestionGenerator.java | 1 - .../components/generators/art/ArtPeriodQuestionGenerator.java | 1 - .../components/generators/art/ArtStyleQuestionGenerator.java | 1 - .../components/generators/art/ArtWorkQuestionGenerator.java | 1 - .../generators/science/MathPhysicsFormulaQuestionGenerator.java | 1 - .../science/ScientificAchievementQuestionGenerator.java | 1 - .../generators/science/ScientificDiscoveryQuestionGenerator.java | 1 - .../generators/science/ScientistBirthplaceQuestionGenerator.java | 1 - 8 files changed, 8 deletions(-) diff --git a/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java index b83b1e25..81fef3cd 100644 --- a/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; -@Component public class ArtMovementQuestionGenerator extends AbstractArtGenerator { private static final Map STATEMENTS = new HashMap<>() { { diff --git a/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java index 312c0086..e005d262 100644 --- a/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; -@Component public class ArtPeriodQuestionGenerator extends AbstractArtGenerator { private static final Map STATEMENTS = new HashMap<>() { { diff --git a/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java index 19cfafeb..e347e643 100644 --- a/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; -@Component public class ArtStyleQuestionGenerator extends AbstractArtGenerator { private static final Map STATEMENTS = new HashMap<>() { { diff --git a/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java index 38e40f6e..68f95d23 100644 --- a/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; -@Component public class ArtWorkQuestionGenerator extends AbstractArtGenerator { private static final Map STATEMENTS = new HashMap<>() { { diff --git a/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java index 666b7052..4c907fba 100644 --- a/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; -@Component public class MathPhysicsFormulaQuestionGenerator extends AbstractScienceGenerator { private static final Map STATEMENTS = new HashMap<>() { { diff --git a/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java index a3812b60..36304b41 100644 --- a/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; -@Component public class ScientificAchievementQuestionGenerator extends AbstractScienceGenerator { private static final Map STATEMENTS = new HashMap<>() { { diff --git a/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java index 53fc837b..b868667b 100644 --- a/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; -@Component public class ScientificDiscoveryQuestionGenerator extends AbstractScienceGenerator { private static final Map STATEMENTS = new HashMap<>() { { diff --git a/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java index 2e1183a6..55763766 100644 --- a/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; -@Component public class ScientistBirthplaceQuestionGenerator extends AbstractScienceGenerator { private static final Map STATEMENTS = new HashMap<>() { { From 61ec4bf333c49118294d01bb45b27ff704860c7a Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Sat, 6 Apr 2024 23:54:53 +0200 Subject: [PATCH 018/161] Add new question category and templates: Movie --- .../movie/AbstractMovieGenerator.java | 17 +++++ .../movie/MovieDirectorQuestionGenerator.java | 75 +++++++++++++++++++ .../movie/MovieGenreQuestionGenerator.java | 74 ++++++++++++++++++ .../MovieReleaseYearQuestionGenerator.java | 75 +++++++++++++++++++ .../movie/OriginalTitleQuestionGenerator.java | 74 ++++++++++++++++++ .../services/impl/CategoryServiceImpl.java | 3 +- 6 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/uniovi/components/generators/movie/AbstractMovieGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/movie/MovieDirectorQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/movie/MovieGenreQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/movie/MovieReleaseYearQuestionGenerator.java create mode 100644 src/main/java/com/uniovi/components/generators/movie/OriginalTitleQuestionGenerator.java diff --git a/src/main/java/com/uniovi/components/generators/movie/AbstractMovieGenerator.java b/src/main/java/com/uniovi/components/generators/movie/AbstractMovieGenerator.java new file mode 100644 index 00000000..89eb2bef --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/movie/AbstractMovieGenerator.java @@ -0,0 +1,17 @@ +package com.uniovi.components.generators.movie; + +import com.uniovi.components.generators.AbstractQuestionGenerator; +import com.uniovi.entities.Category; +import com.uniovi.services.CategoryService; + +public abstract class AbstractMovieGenerator extends AbstractQuestionGenerator { + + protected AbstractMovieGenerator(CategoryService categoryService) { + super(categoryService); + } + + @Override + public Category getCategory() { + return categoryService.getCategoryByName("Movie"); + } +} diff --git a/src/main/java/com/uniovi/components/generators/movie/MovieDirectorQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/movie/MovieDirectorQuestionGenerator.java new file mode 100644 index 00000000..35cd2ab2 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/movie/MovieDirectorQuestionGenerator.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.movie; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MovieDirectorQuestionGenerator extends AbstractMovieGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Who directed the movie "); + put("es", "¿Quién dirigió la película "); + put("fr", "Qui a dirigé le film "); + } + }; + + public MovieDirectorQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?director ?directorLabel ?movie ?movieLabel\n" + + "WHERE {" + + " ?director wdt:P31 wd:Q5 ." + // Instance of Human + " ?movie wdt:P31 wd:Q11424 ." + // Instance of Film + " ?movie wdt:P57 ?director ." + // Director + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllMovies(JsonNode resultsNode, String correctMovie) { + List allMovies = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String movie = result.path("movieLabel").path("value").asText(); + if (!movie.equals(correctMovie)) { + allMovies.add(movie); + } + } + return allMovies; + } + + private List selectRandomIncorrectMovies(List allMovies, String correctMovie, int count) { + List incorrectMovies = new ArrayList<>(); + while (incorrectMovies.size() < count && allMovies.size() > 0) { + int randomIndex = random.nextInt(allMovies.size()); + String selectedMovie = allMovies.remove(randomIndex); + if (!selectedMovie.equals(correctMovie) && !incorrectMovies.contains(selectedMovie)) { + incorrectMovies.add(selectedMovie); + } + } + return incorrectMovies; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String movieLabel = result.path("movieLabel").path("value").asText(); + return selectRandomIncorrectMovies(getAllMovies(results, movieLabel), movieLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("directorLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("movieLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/movie/MovieGenreQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/movie/MovieGenreQuestionGenerator.java new file mode 100644 index 00000000..8da6a045 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/movie/MovieGenreQuestionGenerator.java @@ -0,0 +1,74 @@ +package com.uniovi.components.generators.movie; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MovieGenreQuestionGenerator extends AbstractMovieGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "Which genre does the movie "); + put("es", "¿A qué género pertenece la película "); + put("fr", "À quel genre appartient le film "); + } + }; + + public MovieGenreQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?movie ?movieLabel ?genre ?genreLabel\n" + + "WHERE {" + + " ?movie wdt:P31 wd:Q11424 ." + // Instance of Film + " ?movie wdt:P136 ?genre ." + // Genre + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllMovies(JsonNode resultsNode, String correctMovie) { + List allMovies = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String movie = result.path("movieLabel").path("value").asText(); + if (!movie.equals(correctMovie)) { + allMovies.add(movie); + } + } + return allMovies; + } + + private List selectRandomIncorrectGenres(List allMovies, String correctMovie, int count) { + List incorrectGenres = new ArrayList<>(); + while (incorrectGenres.size() < count && allMovies.size() > 0) { + int randomIndex = random.nextInt(allMovies.size()); + String selectedMovie = allMovies.remove(randomIndex); + if (!selectedMovie.equals(correctMovie) && !incorrectGenres.contains(selectedMovie)) { + incorrectGenres.add(selectedMovie); + } + } + return incorrectGenres; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String movieLabel = result.path("movieLabel").path("value").asText(); + return selectRandomIncorrectGenres(getAllMovies(results, movieLabel), movieLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("genreLabel").path("value").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("movieLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/movie/MovieReleaseYearQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/movie/MovieReleaseYearQuestionGenerator.java new file mode 100644 index 00000000..88b78d5d --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/movie/MovieReleaseYearQuestionGenerator.java @@ -0,0 +1,75 @@ +package com.uniovi.components.generators.movie; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MovieReleaseYearQuestionGenerator extends AbstractMovieGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "In which year was the movie "); + put("es", "¿En qué año se lanzó la película "); + put("fr", "En quelle année est sorti le film "); + } + }; + + public MovieReleaseYearQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?movie ?movieLabel ?releaseYear\n" + + "WHERE {" + + " ?movie wdt:P31 wd:Q11424 ." + // Instance of Film + " ?movie wdt:P577 ?releaseDate ." + // Release date + " BIND(YEAR(?releaseDate) AS ?releaseYear)" + // Extract year + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllMovies(JsonNode resultsNode, String correctMovie) { + List allMovies = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String movie = result.path("movieLabel").path("value").asText(); + if (!movie.equals(correctMovie)) { + allMovies.add(movie); + } + } + return allMovies; + } + + private List selectRandomIncorrectYears(List allMovies, String correctMovie, int count) { + List incorrectYears = new ArrayList<>(); + while (incorrectYears.size() < count && allMovies.size() > 0) { + int randomIndex = random.nextInt(allMovies.size()); + String selectedMovie = allMovies.remove(randomIndex); + if (!selectedMovie.equals(correctMovie) && !incorrectYears.contains(selectedMovie)) { + incorrectYears.add(selectedMovie); + } + } + return incorrectYears; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String movieLabel = result.path("movieLabel").path("value").asText(); + return selectRandomIncorrectYears(getAllMovies(results, movieLabel), movieLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("releaseYear").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("movieLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/components/generators/movie/OriginalTitleQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/movie/OriginalTitleQuestionGenerator.java new file mode 100644 index 00000000..84f61091 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/movie/OriginalTitleQuestionGenerator.java @@ -0,0 +1,74 @@ +package com.uniovi.components.generators.movie; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.services.CategoryService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OriginalTitleQuestionGenerator extends AbstractMovieGenerator { + private static final Map STATEMENTS = new HashMap<>() { + { + put("en", "What is the original title of the movie "); + put("es", "¿Cuál es el título original de la película "); + put("fr", "Quel est le titre original du film "); + } + }; + + public OriginalTitleQuestionGenerator(CategoryService categoryService, String language) { + super(categoryService); + this.statement = STATEMENTS.get(language); + this.language = language; + } + + @Override + public String getQuery() { + return "SELECT DISTINCT ?movie ?movieLabel ?originalTitle\n" + + "WHERE {" + + " ?movie wdt:P31 wd:Q11424 ." + // Instance of Film + " ?movie wdt:P1476 ?originalTitle ." + // Original title + " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + + "}"; + } + + private List getAllMovies(JsonNode resultsNode, String correctMovie) { + List allMovies = new ArrayList<>(); + for (JsonNode result : resultsNode) { + String movie = result.path("movieLabel").path("value").asText(); + if (!movie.equals(correctMovie)) { + allMovies.add(movie); + } + } + return allMovies; + } + + private List selectRandomIncorrectTitles(List allMovies, String correctMovie, int count) { + List incorrectTitles = new ArrayList<>(); + while (incorrectTitles.size() < count && allMovies.size() > 0) { + int randomIndex = random.nextInt(allMovies.size()); + String selectedMovie = allMovies.remove(randomIndex); + if (!selectedMovie.equals(correctMovie) && !incorrectTitles.contains(selectedMovie)) { + incorrectTitles.add(selectedMovie); + } + } + return incorrectTitles; + } + + @Override + protected List generateOptions(JsonNode results, JsonNode result) { + String movieLabel = result.path("movieLabel").path("value").asText(); + return selectRandomIncorrectTitles(getAllMovies(results, movieLabel), movieLabel, 3); + } + + @Override + protected String generateCorrectAnswer(JsonNode result) { + return result.path("originalTitle").asText(); + } + + @Override + protected String getQuestionSubject(JsonNode result) { + return this.statement + result.path("movieLabel").path("value").asText() + "?"; + } +} diff --git a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java index 8ddcd60e..4ba93d4d 100644 --- a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java @@ -43,7 +43,8 @@ public Category getCategoryByName(String name) { new AbstractMap.SimpleEntry<>("Geography", "Questions about geography"), new AbstractMap.SimpleEntry<>("History", "Questions about history"), new AbstractMap.SimpleEntry<>("Science", "Questions about science"), - new AbstractMap.SimpleEntry<>("Science", "Questions about art") + new AbstractMap.SimpleEntry<>("Art", "Questions about art"), + new AbstractMap.SimpleEntry<>("Movie", "Questions about movies") }; @PostConstruct From f7080ce07ca74673746f41d02bb5b6acfda06605 Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Sun, 7 Apr 2024 00:06:57 +0200 Subject: [PATCH 019/161] Update InsertSampleDataService with the new templates --- .../services/InsertSampleDataService.java | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/src/main/java/com/uniovi/services/InsertSampleDataService.java b/src/main/java/com/uniovi/services/InsertSampleDataService.java index add55fcf..db1e0dff 100644 --- a/src/main/java/com/uniovi/services/InsertSampleDataService.java +++ b/src/main/java/com/uniovi/services/InsertSampleDataService.java @@ -2,8 +2,20 @@ import com.uniovi.components.MultipleQuestionGenerator; import com.uniovi.components.generators.QuestionGenerator; +import com.uniovi.components.generators.art.ArtMovementQuestionGenerator; +import com.uniovi.components.generators.art.ArtPeriodQuestionGenerator; +import com.uniovi.components.generators.art.ArtStyleQuestionGenerator; +import com.uniovi.components.generators.art.ArtWorkQuestionGenerator; import com.uniovi.components.generators.geography.*; import com.uniovi.components.generators.history.*; +import com.uniovi.components.generators.movie.MovieDirectorQuestionGenerator; +import com.uniovi.components.generators.movie.MovieGenreQuestionGenerator; +import com.uniovi.components.generators.movie.MovieReleaseYearQuestionGenerator; +import com.uniovi.components.generators.movie.OriginalTitleQuestionGenerator; +import com.uniovi.components.generators.science.MathPhysicsFormulaQuestionGenerator; +import com.uniovi.components.generators.science.ScientificAchievementQuestionGenerator; +import com.uniovi.components.generators.science.ScientificDiscoveryQuestionGenerator; +import com.uniovi.components.generators.science.ScientistBirthplaceQuestionGenerator; import com.uniovi.dto.PlayerDto; import com.uniovi.entities.Associations; import com.uniovi.entities.GameSession; @@ -110,6 +122,7 @@ public void generateSampleData() { List geographyQuestionsFrench = geographyQuestionsFr.getQuestions(); geographyQuestionsFrench.forEach(questionService::addNewQuestion); + // Generar preguntas de historia en inglés MultipleQuestionGenerator historyQuestionsEn = new MultipleQuestionGenerator( new HistoricalArtifactQuestionGeneration(categoryService, Question.ENGLISH), @@ -149,6 +162,90 @@ public void generateSampleData() { List historyQuestionsFrench = historyQuestionsFr.getQuestions(); historyQuestionsFrench.forEach(questionService::addNewQuestion); + + MultipleQuestionGenerator scienceQuestionsEn = new MultipleQuestionGenerator( + new MathPhysicsFormulaQuestionGenerator(categoryService, Question.ENGLISH), + new ScientificAchievementQuestionGenerator(categoryService, Question.ENGLISH), + new ScientificDiscoveryQuestionGenerator(categoryService, Question.ENGLISH), + new ScientistBirthplaceQuestionGenerator(categoryService, Question.ENGLISH) + ); + List scienceQuestions = scienceQuestionsEn.getQuestions(); + scienceQuestions.forEach(questionService::addNewQuestion); + + MultipleQuestionGenerator scienceQuestionsEs = new MultipleQuestionGenerator( + new MathPhysicsFormulaQuestionGenerator(categoryService, Question.SPANISH), + new ScientificAchievementQuestionGenerator(categoryService, Question.SPANISH), + new ScientificDiscoveryQuestionGenerator(categoryService, Question.SPANISH), + new ScientistBirthplaceQuestionGenerator(categoryService, Question.SPANISH) + ); + List scienceQuestionsSpanish = scienceQuestionsEs.getQuestions(); + scienceQuestionsSpanish.forEach(questionService::addNewQuestion); + + MultipleQuestionGenerator scienceQuestionsFr = new MultipleQuestionGenerator( + new MathPhysicsFormulaQuestionGenerator(categoryService, Question.FRENCH), + new ScientificAchievementQuestionGenerator(categoryService, Question.FRENCH), + new ScientificDiscoveryQuestionGenerator(categoryService, Question.FRENCH), + new ScientistBirthplaceQuestionGenerator(categoryService, Question.FRENCH) + ); + List scienceQuestionsFrench = scienceQuestionsFr.getQuestions(); + scienceQuestionsFrench.forEach(questionService::addNewQuestion); + + + MultipleQuestionGenerator artQuestionsEn = new MultipleQuestionGenerator( + new ArtMovementQuestionGenerator(categoryService, Question.ENGLISH), + new ArtPeriodQuestionGenerator(categoryService, Question.ENGLISH), + new ArtStyleQuestionGenerator(categoryService, Question.ENGLISH), + new ArtWorkQuestionGenerator(categoryService, Question.ENGLISH) + ); + List artQuestions = artQuestionsEn.getQuestions(); + artQuestions.forEach(questionService::addNewQuestion); + + MultipleQuestionGenerator artQuestionsEs = new MultipleQuestionGenerator( + new ArtMovementQuestionGenerator(categoryService, Question.SPANISH), + new ArtPeriodQuestionGenerator(categoryService, Question.SPANISH), + new ArtStyleQuestionGenerator(categoryService, Question.SPANISH), + new ArtWorkQuestionGenerator(categoryService, Question.SPANISH) + ); + List artQuestionsSpanish = artQuestionsEs.getQuestions(); + artQuestionsSpanish.forEach(questionService::addNewQuestion); + + MultipleQuestionGenerator artQuestionsFr = new MultipleQuestionGenerator( + new ArtMovementQuestionGenerator(categoryService, Question.FRENCH), + new ArtPeriodQuestionGenerator(categoryService, Question.FRENCH), + new ArtStyleQuestionGenerator(categoryService, Question.FRENCH), + new ArtWorkQuestionGenerator(categoryService, Question.FRENCH) + ); + List artQuestionsFrench = artQuestionsFr.getQuestions(); + artQuestionsFrench.forEach(questionService::addNewQuestion); + + + MultipleQuestionGenerator movieQuestionsEn = new MultipleQuestionGenerator( + new MovieDirectorQuestionGenerator(categoryService, Question.ENGLISH), + new MovieGenreQuestionGenerator(categoryService, Question.ENGLISH), + new MovieReleaseYearQuestionGenerator(categoryService, Question.ENGLISH), + new OriginalTitleQuestionGenerator(categoryService, Question.ENGLISH) + ); + List movieQuestions = movieQuestionsEn.getQuestions(); + movieQuestions.forEach(questionService::addNewQuestion); + + MultipleQuestionGenerator movieQuestionsEs = new MultipleQuestionGenerator( + new MovieDirectorQuestionGenerator(categoryService, Question.SPANISH), + new MovieGenreQuestionGenerator(categoryService, Question.SPANISH), + new MovieReleaseYearQuestionGenerator(categoryService, Question.SPANISH), + new OriginalTitleQuestionGenerator(categoryService, Question.SPANISH) + ); + List movieQuestionsSpanish = movieQuestionsEs.getQuestions(); + movieQuestionsSpanish.forEach(questionService::addNewQuestion); + + MultipleQuestionGenerator movieQuestionsFr = new MultipleQuestionGenerator( + new MovieDirectorQuestionGenerator(categoryService, Question.FRENCH), + new MovieGenreQuestionGenerator(categoryService, Question.FRENCH), + new MovieReleaseYearQuestionGenerator(categoryService, Question.FRENCH), + new OriginalTitleQuestionGenerator(categoryService, Question.FRENCH) + ); + List movieQuestionsFrench = movieQuestionsFr.getQuestions(); + movieQuestionsFrench.forEach(questionService::addNewQuestion); + log.info("Sample questions inserted"); } From 391f82f94086148c6f84dfe6ce72c9e3f5db3860 Mon Sep 17 00:00:00 2001 From: uo288061 Date: Tue, 9 Apr 2024 19:05:16 +0200 Subject: [PATCH 020/161] frontEnd for multiplayer --- .../uniovi/controllers/GameController.java | 5 ++++ src/main/resources/messages.properties | 6 +++++ src/main/resources/messages_en.properties | 9 +++++++ src/main/resources/messages_es.properties | 7 +++++ src/main/resources/messages_fr.properties | 6 +++++ .../templates/game/multiplayerGame.html | 26 +++++++++++++++++++ src/main/resources/templates/index.html | 6 +++++ 7 files changed, 65 insertions(+) create mode 100644 src/main/resources/templates/game/multiplayerGame.html diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index 59c20083..4d049db2 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -54,6 +54,11 @@ public String getGame(HttpSession session, Model model, Principal principal) { return "game/basicGame"; } + @GetMapping("/multiplayerGame") + public String getMultyplayerGame(HttpSession session, Model model, Principal principal) { + return "game/multiplayerGame"; + } + /** * This method is used to check the answer for a specific question diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 2b91abb1..3281838a 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -37,6 +37,7 @@ error.error=Error: index.heading=WIQ index.subtitle=Responde las preguntas correctamente y GANA!!! index.button=JUGAR +index.multiplayer.button= Juega con amigos # -------------------Statements for the home.html file--------------------- home.heading=Bienvenido @@ -82,6 +83,11 @@ ranking.question.right=Respuestas correctas ranking.question.wrong=Respuestas incorrectas ranking.time=Tiempo +# -------------------Statements for the multiplayerGame.html file--------------------- +multi.text = ¿Aún no tienes un código? Crea uno y compártelo con tus amigos +multi.create = Crear +multi.placeholder= Introduce el código de una partida +multi.label = Únete a una partida # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API api.doc.description=Esta es la documentación de la API de WIQ. Aquí puedes encontrar información sobre los recursos disponibles, los parámetros que aceptan y los ejemplos de uso. diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 97f0f133..434ff4bc 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -37,6 +37,8 @@ error.error=Error: index.heading=WIQ index.subtitle=Answer the questions correctly and WIN!!! index.button=PLAY +index.multiplayer.button= Play with friends + # -------------------Statements for the home.html file--------------------- home.heading=Welcome @@ -83,6 +85,13 @@ ranking.question.right=Right answers ranking.question.wrong=Wrong answers ranking.time=Time +# -------------------Statements for the multiplayerGame.html file--------------------- +multi.text =Don't have a code yet? Create one and share it with your friends +multi.create = Create +multi.placeholder=Enter the game code +multi.label=Join a game + + # -------------------Statements for the apiHome.html file--------------------- api.doc.title=API Documentation api.doc.description=This document describes the REST API endpoints. diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index 174dad48..62f487b6 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -38,6 +38,8 @@ error.error=Error: index.heading=WIQ index.subtitle=Responde las preguntas correctamente y GANA!!! index.button=JUGAR +index.multiplayer.button= Juega con amigos + # -------------------Statements for the home.html file--------------------- home.heading=Bienvenido @@ -84,6 +86,11 @@ ranking.question.right=Respuestas correctas ranking.question.wrong=Respuestas incorrectas ranking.time=Tiempo +# -------------------Statements for the multiplayerGame.html file--------------------- +multi.text = ¿Aún no tienes un código? Crea uno y compártelo con tus amigos +multi.create = Crear +multi.placeholder= Introduce el código de una partida +multi.label = Únete a una partida # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API api.doc.description=Esta es la documentación de la API de WIQ. Aquí puedes encontrar información sobre los recursos disponibles, los parámetros que aceptan y los ejemplos de uso. diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index 1f5d2b22..62aec8e4 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -36,6 +36,7 @@ error.error=Erreur : index.heading=WIQ index.subtitle=Répondez aux questions correctement et GAGNEZ !!! index.button=JOUER +index.multiplayer.button=Jouez avec des amis # -------------------Statements for the home.html file--------------------- home.heading=Bienvenue @@ -78,6 +79,11 @@ ranking.question.right=Réponses correctes ranking.question.wrong=Réponses incorrectes ranking.time=Temps +# -------------------Statements for the multiplayerGame.html file--------------------- +multi.text = Vous n'avez pas encore de code ? Créez-en un et partagez-le avec vos amis. +multi.create = Créer +multi.placeholder=Entrez le code du jeu +multi.label=Rejoignez une partie # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentation de l'API api.doc.description=Ceci est la documentation de l'API de WIQ. Vous pouvez trouver ici des informations sur les ressources disponibles, les paramètres qu'elles acceptent et des exemples d'utilisation. diff --git a/src/main/resources/templates/game/multiplayerGame.html b/src/main/resources/templates/game/multiplayerGame.html new file mode 100644 index 00000000..8176c8e5 --- /dev/null +++ b/src/main/resources/templates/game/multiplayerGame.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+ + +
+ +

+ +

+ + + + +
+ + + diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index d199e522..434df7e5 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -10,6 +10,7 @@

+ @@ -18,6 +19,11 @@

window.location.href = "/game"; }); +
From 152e2164d6ede79030eebbf919a5c0fb46eefea1 Mon Sep 17 00:00:00 2001 From: uo288061 Date: Tue, 9 Apr 2024 20:01:53 +0200 Subject: [PATCH 021/161] init backEnd for multiplayer --- src/main/java/com/uniovi/dto/PlayerDto.java | 3 +++ src/main/java/com/uniovi/entities/Player.java | 5 +++++ .../java/com/uniovi/repositories/PlayerRepository.java | 3 +++ src/main/java/com/uniovi/services/PlayerService.java | 7 +++++++ .../java/com/uniovi/services/impl/PlayerServiceImpl.java | 9 +++++++++ 5 files changed, 27 insertions(+) diff --git a/src/main/java/com/uniovi/dto/PlayerDto.java b/src/main/java/com/uniovi/dto/PlayerDto.java index 027b26fa..b3d1e87d 100644 --- a/src/main/java/com/uniovi/dto/PlayerDto.java +++ b/src/main/java/com/uniovi/dto/PlayerDto.java @@ -22,6 +22,9 @@ public class PlayerDto { @Schema(hidden = true) private String passwordConfirm; + @Schema(description = "code of group of the player", example = "5565") + private Integer multiplayerCode; + @Schema(description = "Roles of the player", example = "[\"ROLE_USER\"]") private String[] roles; } diff --git a/src/main/java/com/uniovi/entities/Player.java b/src/main/java/com/uniovi/entities/Player.java index 491a8bd8..022a385c 100644 --- a/src/main/java/com/uniovi/entities/Player.java +++ b/src/main/java/com/uniovi/entities/Player.java @@ -33,6 +33,9 @@ public class Player implements JsonEntity { @NotEmpty private String password; + @Column + private Integer multiplayerCode; + @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER) private Set roles = new HashSet<>(); @@ -42,6 +45,8 @@ public class Player implements JsonEntity { @OneToOne(cascade = CascadeType.ALL, mappedBy = "player") private ApiKey apiKey; + + // Transient: no se almacena en la base de datos @Transient private String passwordConfirm; diff --git a/src/main/java/com/uniovi/repositories/PlayerRepository.java b/src/main/java/com/uniovi/repositories/PlayerRepository.java index 77c2d9f8..247e8964 100644 --- a/src/main/java/com/uniovi/repositories/PlayerRepository.java +++ b/src/main/java/com/uniovi/repositories/PlayerRepository.java @@ -1,9 +1,12 @@ package com.uniovi.repositories; import com.uniovi.entities.Player; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; public interface PlayerRepository extends CrudRepository { Player findByEmail(String email); Player findByUsername(String nickname); + @Query("SELECT player FROM Player player WHERE player.multiplayerCode=:multiplayerCode") + Iterable findAllByMultiplayerCode(int multiplayerCode); } diff --git a/src/main/java/com/uniovi/services/PlayerService.java b/src/main/java/com/uniovi/services/PlayerService.java index f59669e3..278db10a 100644 --- a/src/main/java/com/uniovi/services/PlayerService.java +++ b/src/main/java/com/uniovi/services/PlayerService.java @@ -26,6 +26,13 @@ public interface PlayerService { */ List getUsers(); + + /** + * Get all the players in the database with same multiplayerCode + * @return A list with the players + */ + List getUsersByMultiplayerCode(int multiplayerCode); + /** * Get a player by its id * @param id The id of the player diff --git a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java index f4fa462d..125af896 100644 --- a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java @@ -71,6 +71,13 @@ public List getUsers() { return l; } + @Override + public List getUsersByMultiplayerCode(int multiplayerCode) { + List l = new ArrayList<>(); + playerRepository.findAllByMultiplayerCode(multiplayerCode).forEach(l::add); + return l; + } + @Override public Optional getUser(Long id) { return playerRepository.findById(id); @@ -116,6 +123,8 @@ public void updatePlayer(Long id, PlayerDto playerDto) { p.setUsername(playerDto.getUsername()); if (playerDto.getPassword() != null) p.setPassword(passwordEncoder.encode(playerDto.getPassword())); + if(playerDto.getMultiplayerCode() != null) + p.setMultiplayerCode(playerDto.getMultiplayerCode()); if (playerDto.getRoles() != null) { p.getRoles().clear(); for (String roleStr : playerDto.getRoles()) { From 3eb53d92a13f22f4e420f9b1fe4acc53b75e0181 Mon Sep 17 00:00:00 2001 From: uo288061 Date: Tue, 9 Apr 2024 21:19:54 +0200 Subject: [PATCH 022/161] more backEnd for multiplayer --- .../java/com/uniovi/controllers/GameController.java | 11 ++++++++++- src/main/resources/messages.properties | 1 + src/main/resources/messages_en.properties | 1 + src/main/resources/messages_es.properties | 2 ++ src/main/resources/messages_fr.properties | 2 ++ .../resources/templates/game/multiplayerGame.html | 8 +++++++- 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index 4d049db2..bead274f 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -1,5 +1,6 @@ package com.uniovi.controllers; +import com.uniovi.dto.PlayerDto; import com.uniovi.entities.GameSession; import com.uniovi.entities.Player; import com.uniovi.entities.Question; @@ -55,10 +56,18 @@ public String getGame(HttpSession session, Model model, Principal principal) { } @GetMapping("/multiplayerGame") - public String getMultyplayerGame(HttpSession session, Model model, Principal principal) { + public String getMultiplayerGame() { return "game/multiplayerGame"; } + @GetMapping("/multiplayerGame/{code}") + public String joinMultiplayerGame(@PathVariable String code, HttpSession session, Principal principal) { + Optional player = playerService.getUserByUsername(principal.getName()); + Player p = player.orElse(null); + //playerService.changeMultiplayerCode(code,new PlayerDto()); + return "game/multiplayerGame"; + } + /** * This method is used to check the answer for a specific question diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 3281838a..883e3c19 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -88,6 +88,7 @@ multi.text = ¿Aún no tienes un código? Crea uno y compártelo con tus amigos multi.create = Crear multi.placeholder= Introduce el código de una partida multi.label = Únete a una partida +multi.join = Unirse # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API api.doc.description=Esta es la documentación de la API de WIQ. Aquí puedes encontrar información sobre los recursos disponibles, los parámetros que aceptan y los ejemplos de uso. diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 434ff4bc..bf3b1b6f 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -90,6 +90,7 @@ multi.text =Don't have a code yet? Create one and share it with your friends multi.create = Create multi.placeholder=Enter the game code multi.label=Join a game +multi.join = Join # -------------------Statements for the apiHome.html file--------------------- diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index 62f487b6..f3df8923 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -91,6 +91,8 @@ multi.text = ¿Aún no tienes un código? Crea uno y compártelo con tus amigos multi.create = Crear multi.placeholder= Introduce el código de una partida multi.label = Únete a una partida +multi.join = Unirse + # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API api.doc.description=Esta es la documentación de la API de WIQ. Aquí puedes encontrar información sobre los recursos disponibles, los parámetros que aceptan y los ejemplos de uso. diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index 62aec8e4..49103510 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -84,6 +84,8 @@ multi.text = Vous n'avez pas encore de code ? Créez-en un et partagez-le avec v multi.create = Créer multi.placeholder=Entrez le code du jeu multi.label=Rejoignez une partie +multi.join =Rejoindre + # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentation de l'API api.doc.description=Ceci est la documentation de l'API de WIQ. Vous pouvez trouver ici des informations sur les ressources disponibles, les paramètres qu'elles acceptent et des exemples d'utilisation. diff --git a/src/main/resources/templates/game/multiplayerGame.html b/src/main/resources/templates/game/multiplayerGame.html index 8176c8e5..f6154237 100644 --- a/src/main/resources/templates/game/multiplayerGame.html +++ b/src/main/resources/templates/game/multiplayerGame.html @@ -12,11 +12,17 @@ th:placeholder="#{multi.placeholder}"/> + + + +

- + + + From 06f209de12b262f58367639f2490efea8ceb553b Mon Sep 17 00:00:00 2001 From: uo288061 Date: Wed, 10 Apr 2024 13:06:13 +0200 Subject: [PATCH 023/161] fixing backEnd for multiplayer (It is not yet implemented) done about 30% --- .../com/uniovi/configuration/SecurityConfig.java | 1 + .../com/uniovi/controllers/GameController.java | 4 ++-- .../java/com/uniovi/services/PlayerService.java | 7 +++++++ .../uniovi/services/impl/PlayerServiceImpl.java | 12 ++++++++++++ .../resources/templates/game/multiplayerGame.html | 15 ++++++++++----- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/uniovi/configuration/SecurityConfig.java b/src/main/java/com/uniovi/configuration/SecurityConfig.java index c0af5d20..9c3d3e45 100644 --- a/src/main/java/com/uniovi/configuration/SecurityConfig.java +++ b/src/main/java/com/uniovi/configuration/SecurityConfig.java @@ -47,6 +47,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/signup/**").permitAll() .requestMatchers("/api/**").permitAll() .requestMatchers("/game/**").authenticated() + .requestMatchers("/multiplayerGame/**").authenticated() .requestMatchers("/ranking/playerRanking").authenticated() .requestMatchers("/**").permitAll() ).formLogin( diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index bead274f..bbdecd71 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -61,10 +61,10 @@ public String getMultiplayerGame() { } @GetMapping("/multiplayerGame/{code}") - public String joinMultiplayerGame(@PathVariable String code, HttpSession session, Principal principal) { + public String joinMultiplayerGame(@PathVariable String code, HttpSession session, Principal principal, Model model) { Optional player = playerService.getUserByUsername(principal.getName()); Player p = player.orElse(null); - //playerService.changeMultiplayerCode(code,new PlayerDto()); + playerService.changeMultiplayerCode(p.getId(),code); return "game/multiplayerGame"; } diff --git a/src/main/java/com/uniovi/services/PlayerService.java b/src/main/java/com/uniovi/services/PlayerService.java index 278db10a..50c31651 100644 --- a/src/main/java/com/uniovi/services/PlayerService.java +++ b/src/main/java/com/uniovi/services/PlayerService.java @@ -74,6 +74,13 @@ public interface PlayerService { */ void updatePlayer(Long id, PlayerDto playerDto); + /** + * Update the multiplayerCode of a player + * @param id The id of the player to update + * @param code The new multiplayerCode of the player + */ + void changeMultiplayerCode(Long id, String code); + /** * Delete a player from the database * @param id The id of the player to delete diff --git a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java index 125af896..17fea133 100644 --- a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java @@ -141,6 +141,18 @@ public void updatePlayer(Long id, PlayerDto playerDto) { playerRepository.save(p); } + @Override + public void changeMultiplayerCode(Long id, String code) { + Optional player = playerRepository.findById(id); + if (player.isEmpty()) + return; + + Player p = player.get(); + p.setMultiplayerCode(Integer.parseInt(code)); + playerRepository.save(p); + + } + @Override public void deletePlayer(Long id) { playerRepository.deleteById(id); diff --git a/src/main/resources/templates/game/multiplayerGame.html b/src/main/resources/templates/game/multiplayerGame.html index f6154237..0b2258b3 100644 --- a/src/main/resources/templates/game/multiplayerGame.html +++ b/src/main/resources/templates/game/multiplayerGame.html @@ -12,15 +12,20 @@ th:placeholder="#{multi.placeholder}"/> - - - - + + + +

- + From 15c35d5a0780a7ae88fd5b930b4876b5a393bbb6 Mon Sep 17 00:00:00 2001 From: uo288061 Date: Wed, 10 Apr 2024 14:57:15 +0200 Subject: [PATCH 024/161] starting multiplayer lobby --- .../uniovi/configuration/SecurityConfig.java | 1 + .../uniovi/controllers/GameController.java | 16 +++++++++++++-- .../com/uniovi/services/PlayerService.java | 2 +- .../services/impl/PlayerServiceImpl.java | 20 ++++++++++++++----- src/main/resources/templates/game/lobby.html | 9 +++++++++ 5 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 src/main/resources/templates/game/lobby.html diff --git a/src/main/java/com/uniovi/configuration/SecurityConfig.java b/src/main/java/com/uniovi/configuration/SecurityConfig.java index 9c3d3e45..0bb5723e 100644 --- a/src/main/java/com/uniovi/configuration/SecurityConfig.java +++ b/src/main/java/com/uniovi/configuration/SecurityConfig.java @@ -48,6 +48,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/api/**").permitAll() .requestMatchers("/game/**").authenticated() .requestMatchers("/multiplayerGame/**").authenticated() + .requestMatchers("/lobby/**").authenticated() .requestMatchers("/ranking/playerRanking").authenticated() .requestMatchers("/**").permitAll() ).formLogin( diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index bbdecd71..c41e8bbe 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -1,6 +1,5 @@ package com.uniovi.controllers; -import com.uniovi.dto.PlayerDto; import com.uniovi.entities.GameSession; import com.uniovi.entities.Player; import com.uniovi.entities.Question; @@ -17,6 +16,7 @@ import java.security.Principal; import java.time.Duration; import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; @Controller @@ -64,10 +64,22 @@ public String getMultiplayerGame() { public String joinMultiplayerGame(@PathVariable String code, HttpSession session, Principal principal, Model model) { Optional player = playerService.getUserByUsername(principal.getName()); Player p = player.orElse(null); - playerService.changeMultiplayerCode(p.getId(),code); + if(playerService.changeMultiplayerCode(p.getId(),code)){ + model.addAttribute("multiplayerGameCode",code); + session.setAttribute("multiplayerCode",code); + return "game/lobby"; + } return "game/multiplayerGame"; } + @GetMapping("/game/lobby") + public String createLobby( HttpSession session, Principal principal, Model model) { + int code = Integer.parseInt((String)session.getAttribute("multiplayerCode")); + List players=playerService.getUsersByMultiplayerCode(code); + model.addAttribute("players",players); + return "/game/lobby"; + } + /** * This method is used to check the answer for a specific question diff --git a/src/main/java/com/uniovi/services/PlayerService.java b/src/main/java/com/uniovi/services/PlayerService.java index 50c31651..fa77b9ca 100644 --- a/src/main/java/com/uniovi/services/PlayerService.java +++ b/src/main/java/com/uniovi/services/PlayerService.java @@ -79,7 +79,7 @@ public interface PlayerService { * @param id The id of the player to update * @param code The new multiplayerCode of the player */ - void changeMultiplayerCode(Long id, String code); + boolean changeMultiplayerCode(Long id, String code); /** * Delete a player from the database diff --git a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java index 17fea133..0071aebb 100644 --- a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java @@ -142,15 +142,25 @@ public void updatePlayer(Long id, PlayerDto playerDto) { } @Override - public void changeMultiplayerCode(Long id, String code) { + public boolean changeMultiplayerCode(Long id, String code) { Optional player = playerRepository.findById(id); if (player.isEmpty()) - return; + return false; Player p = player.get(); - p.setMultiplayerCode(Integer.parseInt(code)); - playerRepository.save(p); - + if(true/*existsMultiplayerCode(code)*/){ + p.setMultiplayerCode(Integer.parseInt(code)); + playerRepository.save(p); + return true; + } + return false; + } + /** + * A multiplayerCodeExists if there are any player + * with same multiplayerCode at the moment of the join + * */ + private boolean existsMultiplayerCode(String code){ + return ! getUsersByMultiplayerCode(Integer.parseInt(code)).isEmpty(); } @Override diff --git a/src/main/resources/templates/game/lobby.html b/src/main/resources/templates/game/lobby.html new file mode 100644 index 00000000..632b47ce --- /dev/null +++ b/src/main/resources/templates/game/lobby.html @@ -0,0 +1,9 @@ + + + + + + + +
+
From 7c197e8899b286b3c3dfac315b6dac0c9e6d3e6f Mon Sep 17 00:00:00 2001 From: uo288061 Date: Wed, 10 Apr 2024 18:42:23 +0200 Subject: [PATCH 025/161] done multiplayer lobby, now the list of players updates automatically --- .../uniovi/controllers/GameController.java | 16 +++++++-- src/main/resources/templates/game/lobby.html | 35 ++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index c41e8bbe..25c73517 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -16,6 +16,7 @@ import java.security.Principal; import java.time.Duration; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -67,16 +68,27 @@ public String joinMultiplayerGame(@PathVariable String code, HttpSession session if(playerService.changeMultiplayerCode(p.getId(),code)){ model.addAttribute("multiplayerGameCode",code); session.setAttribute("multiplayerCode",code); - return "game/lobby"; + return "redirect:/game/lobby"; } return "game/multiplayerGame"; } + @GetMapping("/game/lobby/{code}") + @ResponseBody + public List updatePlayerList(@PathVariable String code) { + List players = playerService.getUsersByMultiplayerCode(Integer.parseInt(code)); + List playerNames = new ArrayList<>(); + for (Player player : players) { + playerNames.add(player.getUsername()); + } + return playerNames; + } @GetMapping("/game/lobby") - public String createLobby( HttpSession session, Principal principal, Model model) { + public String createLobby( HttpSession session, Model model) { int code = Integer.parseInt((String)session.getAttribute("multiplayerCode")); List players=playerService.getUsersByMultiplayerCode(code); model.addAttribute("players",players); + model.addAttribute("code",code); return "/game/lobby"; } diff --git a/src/main/resources/templates/game/lobby.html b/src/main/resources/templates/game/lobby.html index 632b47ce..fa7b8517 100644 --- a/src/main/resources/templates/game/lobby.html +++ b/src/main/resources/templates/game/lobby.html @@ -1,9 +1,42 @@ + -
+
+

Jugadores unidos a la partida:

+

Comparte el código de tu partida con tus amigos

+ +
    +
  • +
+
+ + + + From a1c33f2d8fe01ffbefa880fe045d0986de0ce34f Mon Sep 17 00:00:00 2001 From: UO287568 Date: Wed, 10 Apr 2024 20:24:26 +0200 Subject: [PATCH 026/161] =?UTF-8?q?Correci=C3=B3n=20contador=20de=20pregun?= =?UTF-8?q?tas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/game/basicGame.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/game/basicGame.html b/src/main/resources/templates/game/basicGame.html index 43c37fad..52236c9c 100644 --- a/src/main/resources/templates/game/basicGame.html +++ b/src/main/resources/templates/game/basicGame.html @@ -14,7 +14,7 @@ / - +

From 989fee51ed55f099f050e0ed7e443c95e165a0c5 Mon Sep 17 00:00:00 2001 From: uo288061 Date: Wed, 10 Apr 2024 23:58:26 +0200 Subject: [PATCH 027/161] fix some problems --- .../uniovi/controllers/GameController.java | 2 +- .../services/impl/PlayerServiceImpl.java | 13 ++++++- src/main/resources/messages.properties | 5 +++ src/main/resources/messages_en.properties | 4 +++ src/main/resources/messages_es.properties | 6 ++++ src/main/resources/messages_fr.properties | 5 +++ src/main/resources/templates/game/lobby.html | 7 ++-- .../templates/game/multiplayerGame.html | 34 ++++++++++++++----- 8 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index 25c73517..c266dea4 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -70,7 +70,7 @@ public String joinMultiplayerGame(@PathVariable String code, HttpSession session session.setAttribute("multiplayerCode",code); return "redirect:/game/lobby"; } - return "game/multiplayerGame"; + return "redirect:/multiplayerGame"; } @GetMapping("/game/lobby/{code}") diff --git a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java index 0071aebb..26582630 100644 --- a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java @@ -148,7 +148,7 @@ public boolean changeMultiplayerCode(Long id, String code) { return false; Player p = player.get(); - if(true/*existsMultiplayerCode(code)*/){ + if(existsMultiplayerCode(code)){ p.setMultiplayerCode(Integer.parseInt(code)); playerRepository.save(p); return true; @@ -163,6 +163,17 @@ private boolean existsMultiplayerCode(String code){ return ! getUsersByMultiplayerCode(Integer.parseInt(code)).isEmpty(); } + private void createMultiplayerGame(Long id){ + Optional player = playerRepository.findById(id); + if (player.isEmpty()) + return; + + Player p = player.get(); + int code = (int)Math.floor(Math.random()*10000); + p.setMultiplayerCode(code); + playerRepository.save(p); + } + @Override public void deletePlayer(Long id) { playerRepository.deleteById(id); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 883e3c19..7c52e584 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -89,6 +89,11 @@ multi.create = Crear multi.placeholder= Introduce el código de una partida multi.label = Únete a una partida multi.join = Unirse +multi.onlyNumber = Solo se permiten números + +# -------------------Statements for the lobby.html file--------------------- +lobby.info =Jugadores unidos a la partida: +lobby.friends =Comparte el código de tu partida con tus amigos # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API api.doc.description=Esta es la documentación de la API de WIQ. Aquí puedes encontrar información sobre los recursos disponibles, los parámetros que aceptan y los ejemplos de uso. diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index bf3b1b6f..822b9262 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -91,6 +91,10 @@ multi.create = Create multi.placeholder=Enter the game code multi.label=Join a game multi.join = Join +multi.onlyNumber=Only numbers allowed +# -------------------Statements for the lobby.html file--------------------- +lobby.info =Players joining the game: +lobby.friends =Share your game code with your friends # -------------------Statements for the apiHome.html file--------------------- diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index f3df8923..adc24abf 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -92,6 +92,12 @@ multi.create = Crear multi.placeholder= Introduce el código de una partida multi.label = Únete a una partida multi.join = Unirse +multi.onlyNumber = Solo se permiten números + + +# -------------------Statements for the lobby.html file--------------------- +lobby.info =Jugadores unidos a la partida: +lobby.friends =Comparte el código de tu partida con tus amigos # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index 49103510..5da89f5c 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -85,6 +85,11 @@ multi.create = Créer multi.placeholder=Entrez le code du jeu multi.label=Rejoignez une partie multi.join =Rejoindre +multi.onlyNumber=Seuls les chiffres sont autorisés + +# -------------------Statements for the lobby.html file--------------------- +lobby.info =Joueurs rejoignant le jeu : +lobby.friends =Partagez votre code de jeu avec vos amis # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentation de l'API diff --git a/src/main/resources/templates/game/lobby.html b/src/main/resources/templates/game/lobby.html index fa7b8517..e1835a09 100644 --- a/src/main/resources/templates/game/lobby.html +++ b/src/main/resources/templates/game/lobby.html @@ -7,17 +7,14 @@
-

Jugadores unidos a la partida:

-

Comparte el código de tu partida con tus amigos

+

+

- - -

@@ -35,3 +31,25 @@ + + From c1a4d4ee0f8c0dbde9dcc6ea2016a632e08976fa Mon Sep 17 00:00:00 2001 From: uo288061 Date: Thu, 11 Apr 2024 12:51:24 +0200 Subject: [PATCH 028/161] create and join buttons working correctly --- .../uniovi/controllers/GameController.java | 20 ++++++++++++++++--- .../com/uniovi/services/PlayerService.java | 2 ++ .../services/impl/PlayerServiceImpl.java | 10 ++++------ src/main/resources/templates/game/lobby.html | 6 ++++-- .../templates/game/multiplayerGame.html | 7 +++---- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index c266dea4..4b0b83df 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -58,7 +58,10 @@ public String getGame(HttpSession session, Model model, Principal principal) { @GetMapping("/multiplayerGame") public String getMultiplayerGame() { - return "game/multiplayerGame"; + //EL elminar el multiplaterCode del jugador se puede hacer cuando comienze el proximo + //juego con amigos o cuando acaba la partida, lo suyo seria cuando acabe + //ya mirare como + return "game/multiplayerGame"; } @GetMapping("/multiplayerGame/{code}") @@ -69,8 +72,19 @@ public String joinMultiplayerGame(@PathVariable String code, HttpSession session model.addAttribute("multiplayerGameCode",code); session.setAttribute("multiplayerCode",code); return "redirect:/game/lobby"; + } else { + //Hay q tratarlo como como se hace en sinUp, hacienado validate y tal + return "redirect:/multiplayerGame"; } - return "redirect:/multiplayerGame"; + } + + @GetMapping("/multiplayerGame/createGame") + public String createMultiplayerGame(HttpSession session, Principal principal, Model model) { + Optional player = playerService.getUserByUsername(principal.getName()); + Player p = player.orElse(null); + String code=""+playerService.createMultiplayerGame(p.getId()); + session.setAttribute("multiplayerCode",code); + return "redirect:/game/lobby"; } @GetMapping("/game/lobby/{code}") @@ -88,7 +102,7 @@ public String createLobby( HttpSession session, Model model) { int code = Integer.parseInt((String)session.getAttribute("multiplayerCode")); List players=playerService.getUsersByMultiplayerCode(code); model.addAttribute("players",players); - model.addAttribute("code",code); + model.addAttribute("code",session.getAttribute("multiplayerCode")); return "/game/lobby"; } diff --git a/src/main/java/com/uniovi/services/PlayerService.java b/src/main/java/com/uniovi/services/PlayerService.java index fa77b9ca..e80a82c5 100644 --- a/src/main/java/com/uniovi/services/PlayerService.java +++ b/src/main/java/com/uniovi/services/PlayerService.java @@ -81,6 +81,8 @@ public interface PlayerService { */ boolean changeMultiplayerCode(Long id, String code); + int createMultiplayerGame(Long id); + /** * Delete a player from the database * @param id The id of the player to delete diff --git a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java index 26582630..68b3b619 100644 --- a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java @@ -6,16 +6,13 @@ import com.uniovi.entities.Associations; import com.uniovi.entities.Player; import com.uniovi.repositories.PlayerRepository; -import com.uniovi.repositories.RoleRepository; import com.uniovi.services.PlayerService; import com.uniovi.services.RoleService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import com.uniovi.entities.Role; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -162,16 +159,17 @@ public boolean changeMultiplayerCode(Long id, String code) { private boolean existsMultiplayerCode(String code){ return ! getUsersByMultiplayerCode(Integer.parseInt(code)).isEmpty(); } - - private void createMultiplayerGame(Long id){ + @Override + public int createMultiplayerGame(Long id){ Optional player = playerRepository.findById(id); if (player.isEmpty()) - return; + return -1; Player p = player.get(); int code = (int)Math.floor(Math.random()*10000); p.setMultiplayerCode(code); playerRepository.save(p); + return code; } @Override diff --git a/src/main/resources/templates/game/lobby.html b/src/main/resources/templates/game/lobby.html index e1835a09..8eff1a48 100644 --- a/src/main/resources/templates/game/lobby.html +++ b/src/main/resources/templates/game/lobby.html @@ -7,8 +7,10 @@

-

-

+

+

+ +

  • diff --git a/src/main/resources/templates/game/multiplayerGame.html b/src/main/resources/templates/game/multiplayerGame.html index ee208a03..e9c29ccf 100644 --- a/src/main/resources/templates/game/multiplayerGame.html +++ b/src/main/resources/templates/game/multiplayerGame.html @@ -15,16 +15,15 @@
- - +

- + -
From 5d3c4c4f3e8b596fb122a847bae3ac2fdb15797b Mon Sep 17 00:00:00 2001 From: UO287568 Date: Thu, 11 Apr 2024 20:14:59 +0200 Subject: [PATCH 029/161] =?UTF-8?q?Correci=C3=B3n=20primera=20respuesta=20?= =?UTF-8?q?la=20correcta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/generators/AbstractQuestionGenerator.java | 2 +- src/main/java/com/uniovi/entities/Question.java | 7 ++++++- src/main/resources/templates/game/fragments/gameFrame.html | 4 ++-- src/test/java/com/uniovi/Wiq_UnitTests.java | 4 ++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java index 9754c2c5..fd192279 100644 --- a/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java @@ -44,7 +44,7 @@ public void questionGenerator(String statement, List options, String cor answers.add(correct); Question question = new Question(statement, answers, correct, category, language); - question.scrambleOptions(); + //question.scrambleOptions(); questions.add(question); } diff --git a/src/main/java/com/uniovi/entities/Question.java b/src/main/java/com/uniovi/entities/Question.java index 10ac54f3..aad73c71 100644 --- a/src/main/java/com/uniovi/entities/Question.java +++ b/src/main/java/com/uniovi/entities/Question.java @@ -78,8 +78,13 @@ public boolean isCorrectAnswer(Answer answer){ return answer.isCorrect(); } - public void scrambleOptions(){ + /*public void scrambleOptions(){ + Collections.shuffle(options); USO EN LOS TESTS Y ABSTRACTQUESTIONGENERATOR + }*/ + + public List returnScrambledOptions(){ Collections.shuffle(options); + return options; } @Override diff --git a/src/main/resources/templates/game/fragments/gameFrame.html b/src/main/resources/templates/game/fragments/gameFrame.html index 7dc5fea5..8f81a3ec 100644 --- a/src/main/resources/templates/game/fragments/gameFrame.html +++ b/src/main/resources/templates/game/fragments/gameFrame.html @@ -4,7 +4,7 @@

-
+
@@ -48,7 +48,7 @@

let progressBar = $('#progressBar'); let currentTime = parseFloat(progressBar.attr('aria-valuenow')); let decrement = 100 * updateInterval / timeoutPeriod; - let newTime = Math.max(0, currentTime - decrement);; + let newTime = Math.max(0, currentTime - decrement); // Calculate the color based on the percentage let greenValue = Math.round((newTime * 255) / 100); let redValue = 255 - greenValue; diff --git a/src/test/java/com/uniovi/Wiq_UnitTests.java b/src/test/java/com/uniovi/Wiq_UnitTests.java index c28558c4..52494d87 100644 --- a/src/test/java/com/uniovi/Wiq_UnitTests.java +++ b/src/test/java/com/uniovi/Wiq_UnitTests.java @@ -453,8 +453,8 @@ public void testScrambleOptions() { question.addOption(option2); question.addOption(option3); - question.scrambleOptions(); - List scrambledOptions = question.getOptions(); + // question.scrambleOptions(); + List scrambledOptions = question.returnScrambledOptions(); Assertions.assertTrue(scrambledOptions.contains(option1)); Assertions.assertTrue(scrambledOptions.contains(option2)); From acd0e36bd2b66727fbf95d14cadb8af75ca9b508 Mon Sep 17 00:00:00 2001 From: uo288061 Date: Fri, 12 Apr 2024 00:04:13 +0200 Subject: [PATCH 030/161] players can can play multiplayer games --- .../uniovi/controllers/GameController.java | 14 +++++++++++++ src/main/java/com/uniovi/dto/PlayerDto.java | 4 ++-- .../services/impl/PlayerServiceImpl.java | 4 ++-- src/main/resources/messages.properties | 5 +++++ src/main/resources/messages_en.properties | 3 +++ src/main/resources/messages_es.properties | 4 ++++ src/main/resources/messages_fr.properties | 4 ++++ .../game/fragments/multiFinished.html | 21 +++++++++++++++++++ src/main/resources/templates/game/lobby.html | 3 +++ 9 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/templates/game/fragments/multiFinished.html diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index 4b0b83df..29c87f00 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -106,6 +106,13 @@ public String createLobby( HttpSession session, Model model) { return "/game/lobby"; } + @GetMapping("/game/startMultiplayerGame") + public String startMultiplayerGame( HttpSession session, Model model) { + //La idea seria q dando uno al boton de empezar empezasen todos + return "/game/lobby"; + } + + /** * This method is used to check the answer for a specific question @@ -163,6 +170,13 @@ else if(questionService.checkAnswer(idQuestion, idAnswer)) { public String updateGame(Model model, HttpSession session) { GameSession gameSession = (GameSession) session.getAttribute("gameSession"); Question nextQuestion = gameSession.getCurrentQuestion(); + if(nextQuestion == null && session.getAttribute("multiplayerCode") !=null){ + gameSessionService.endGame(gameSession); + session.removeAttribute("gameSession"); + model.addAttribute("score", gameSession.getScore()); + model.addAttribute("multiplayerCode",session.getAttribute("multiplayerCode")); + return "game/fragments/multiFinished"; + } if (nextQuestion == null) { gameSessionService.endGame(gameSession); session.removeAttribute("gameSession"); diff --git a/src/main/java/com/uniovi/dto/PlayerDto.java b/src/main/java/com/uniovi/dto/PlayerDto.java index b3d1e87d..2e3d6571 100644 --- a/src/main/java/com/uniovi/dto/PlayerDto.java +++ b/src/main/java/com/uniovi/dto/PlayerDto.java @@ -22,8 +22,8 @@ public class PlayerDto { @Schema(hidden = true) private String passwordConfirm; - @Schema(description = "code of group of the player", example = "5565") - private Integer multiplayerCode; + //@Schema(description = "code of group of the player", example = "5565") + //private Integer multiplayerCode; @Schema(description = "Roles of the player", example = "[\"ROLE_USER\"]") private String[] roles; diff --git a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java index 68b3b619..bd96e189 100644 --- a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java @@ -120,8 +120,8 @@ public void updatePlayer(Long id, PlayerDto playerDto) { p.setUsername(playerDto.getUsername()); if (playerDto.getPassword() != null) p.setPassword(passwordEncoder.encode(playerDto.getPassword())); - if(playerDto.getMultiplayerCode() != null) - p.setMultiplayerCode(playerDto.getMultiplayerCode()); + //if(playerDto.getMultiplayerCode() != null) + // p.setMultiplayerCode(playerDto.getMultiplayerCode()); if (playerDto.getRoles() != null) { p.getRoles().clear(); for (String roleStr : playerDto.getRoles()) { diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 7c52e584..bdcbb083 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -94,6 +94,11 @@ multi.onlyNumber = Solo se permiten números # -------------------Statements for the lobby.html file--------------------- lobby.info =Jugadores unidos a la partida: lobby.friends =Comparte el código de tu partida con tus amigos +lobby.start = Empezar + +# -------------------Statements for the lobby.html file--------------------- +multi.code= Código de la partida + # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API api.doc.description=Esta es la documentación de la API de WIQ. Aquí puedes encontrar información sobre los recursos disponibles, los parámetros que aceptan y los ejemplos de uso. diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 822b9262..306cd4bd 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -95,7 +95,10 @@ multi.onlyNumber=Only numbers allowed # -------------------Statements for the lobby.html file--------------------- lobby.info =Players joining the game: lobby.friends =Share your game code with your friends +lobby.start =Start +# -------------------Statements for the lobby.html file--------------------- +multi.code= Game code # -------------------Statements for the apiHome.html file--------------------- api.doc.title=API Documentation diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index adc24abf..cca0ef1a 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -98,6 +98,10 @@ multi.onlyNumber = Solo se permiten números # -------------------Statements for the lobby.html file--------------------- lobby.info =Jugadores unidos a la partida: lobby.friends =Comparte el código de tu partida con tus amigos +lobby.start =Empezar + +# -------------------Statements for the lobby.html file--------------------- +multi.code= Código de la partida # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index 5da89f5c..49502cf8 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -90,6 +90,10 @@ multi.onlyNumber=Seuls les chiffres sont autorisés # -------------------Statements for the lobby.html file--------------------- lobby.info =Joueurs rejoignant le jeu : lobby.friends =Partagez votre code de jeu avec vos amis +lobby.start = Commencer + +# -------------------Statements for the lobby.html file--------------------- +multi.code=Code du jeu # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentation de l'API diff --git a/src/main/resources/templates/game/fragments/multiFinished.html b/src/main/resources/templates/game/fragments/multiFinished.html new file mode 100644 index 00000000..8837fc95 --- /dev/null +++ b/src/main/resources/templates/game/fragments/multiFinished.html @@ -0,0 +1,21 @@ +
+

+

+ + +

+ +

+ + +

+ +
+
+ +
\ No newline at end of file diff --git a/src/main/resources/templates/game/lobby.html b/src/main/resources/templates/game/lobby.html index 8eff1a48..1ee2ebdf 100644 --- a/src/main/resources/templates/game/lobby.html +++ b/src/main/resources/templates/game/lobby.html @@ -16,6 +16,9 @@

  • + + +
    -
    \ No newline at end of file diff --git a/src/main/resources/templates/game/multiFinished.html b/src/main/resources/templates/game/multiFinished.html new file mode 100644 index 00000000..a2493267 --- /dev/null +++ b/src/main/resources/templates/game/multiFinished.html @@ -0,0 +1,44 @@ + + + + + + + +
    +

    +

    + +

    + + + + + +
      +
    • +
    +
    +
    + From 81accd16306b94d6285a597bc9bb31c373f10e9b Mon Sep 17 00:00:00 2001 From: uo288061 Date: Sun, 14 Apr 2024 12:28:01 +0200 Subject: [PATCH 032/161] Players with same multiplayerCode, have same questions --- .../uniovi/controllers/GameController.java | 22 ++++++++++- .../uniovi/services/GameSessionService.java | 3 ++ .../com/uniovi/services/QuestionService.java | 2 + .../uniovi/services/impl/GameSessionImpl.java | 6 ++- .../services/impl/QuestionServiceImpl.java | 38 +++++++++++++++++-- src/main/resources/templates/game/lobby.html | 2 +- 6 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index 5f13e1bc..85cd910a 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -40,13 +40,13 @@ public GameController(QuestionService questionService, GameSessionService gameSe @GetMapping("/game") public String getGame(HttpSession session, Model model, Principal principal) { GameSession gameSession = (GameSession) session.getAttribute("gameSession"); - if (gameSession != null) { if (checkUpdateGameSession(gameSession, session)) { return "game/fragments/gameFinished"; } } else { gameSession = gameSessionService.startNewGame(getLoggedInPlayer(principal)); + playerService.deleteMultiplayerCode(gameSession.getPlayer().getId()); session.setAttribute("gameSession", gameSession); } @@ -64,6 +64,26 @@ public String getMultiplayerGame() { return "game/multiplayerGame"; } + @GetMapping("/startMultiplayerGame") + public String getMultiplayerGame(HttpSession session, Model model, Principal principal) { + GameSession gameSession = (GameSession) session.getAttribute("gameSession"); + + if (gameSession != null) { + if (checkUpdateGameSession(gameSession, session)) { + return "game/fragments/gameFinished"; + } + } else { + gameSession = gameSessionService.startNewMultiplayerGame(getLoggedInPlayer(principal), + playerService.getUserByUsername(principal.getName()).get().getMultiplayerCode()); + session.setAttribute("gameSession", gameSession); + + } + + model.addAttribute("question", gameSession.getCurrentQuestion()); + model.addAttribute("questionDuration", getRemainingTime(gameSession)); + return "game/basicGame"; + } + @GetMapping("/multiplayerGame/{code}") public String joinMultiplayerGame(@PathVariable String code, HttpSession session, Principal principal, Model model) { Optional player = playerService.getUserByUsername(principal.getName()); diff --git a/src/main/java/com/uniovi/services/GameSessionService.java b/src/main/java/com/uniovi/services/GameSessionService.java index e3eb4c55..a70c194c 100644 --- a/src/main/java/com/uniovi/services/GameSessionService.java +++ b/src/main/java/com/uniovi/services/GameSessionService.java @@ -43,5 +43,8 @@ public interface GameSessionService { Page getPlayerRanking(Pageable pageable, Player player); GameSession startNewGame(Player player); + + GameSession startNewMultiplayerGame(Player player, int code); + void endGame(GameSession gameSession); } diff --git a/src/main/java/com/uniovi/services/QuestionService.java b/src/main/java/com/uniovi/services/QuestionService.java index 7eb7d422..30e36c3d 100644 --- a/src/main/java/com/uniovi/services/QuestionService.java +++ b/src/main/java/com/uniovi/services/QuestionService.java @@ -59,6 +59,8 @@ public interface QuestionService { */ List getRandomQuestions(int num); + List getRandomMultiplayerQuestions(int num, int code); + /** * Check if the answer is correct * @param idquestion The id of the question diff --git a/src/main/java/com/uniovi/services/impl/GameSessionImpl.java b/src/main/java/com/uniovi/services/impl/GameSessionImpl.java index d7e2ad3a..aca3509e 100644 --- a/src/main/java/com/uniovi/services/impl/GameSessionImpl.java +++ b/src/main/java/com/uniovi/services/impl/GameSessionImpl.java @@ -7,7 +7,6 @@ import com.uniovi.services.GameSessionService; import com.uniovi.services.QuestionService; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -51,6 +50,11 @@ public GameSession startNewGame(Player player) { return new GameSession(player, questionService.getRandomQuestions(NORMAL_GAME_QUESTION_NUM)); } + @Override + public GameSession startNewMultiplayerGame(Player player, int code) { + return new GameSession(player, questionService.getRandomMultiplayerQuestions(NORMAL_GAME_QUESTION_NUM,code)); + } + @Override public void endGame(GameSession gameSession) { Associations.PlayerGameSession.addGameSession(gameSession.getPlayer(), gameSession); diff --git a/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java index f0ec9f7e..79e4c218 100644 --- a/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java @@ -12,15 +12,13 @@ import com.uniovi.services.QuestionService; import jakarta.persistence.EntityManager; import jakarta.transaction.Transactional; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.querydsl.QPageRequest; import org.springframework.stereotype.Service; import java.security.SecureRandom; -import java.sql.SQLException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -110,6 +108,38 @@ public List getRandomQuestions(int num) { return res; } + @Override + public List getRandomMultiplayerQuestions(int num, int code) { + List allQuestions = questionRepository.findAll().stream() + .filter(question -> question.getLanguage().equals(LocaleContextHolder.getLocale().getLanguage())).toList(); + List res = new ArrayList<>(); + int size= allQuestions.size(); + + int currentIndex = generateIndex(code, size) -4; + + for (int i = 0; i < num; i++) { + + Question question = allQuestions.get(currentIndex); + + while (question.hasEmptyOptions() || res.contains(question)) { + question = allQuestions.get(currentIndex); + } + + res.add(question); + currentIndex++; + } + return res; + } + private int generateIndex(int code, int size) { + int hashCode = combineHash(code, LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + return Math.abs(hashCode) % size; + } + + private int combineHash(int code, String date) { + String combinedString = code + date; + return combinedString.hashCode(); + } + @Override public boolean checkAnswer(Long idquestion, Long idanswer) { Optional q = questionRepository.findById(idquestion); diff --git a/src/main/resources/templates/game/lobby.html b/src/main/resources/templates/game/lobby.html index 1ee2ebdf..16b72e96 100644 --- a/src/main/resources/templates/game/lobby.html +++ b/src/main/resources/templates/game/lobby.html @@ -16,7 +16,7 @@

  • - +
    From 5aaa8dbac24a22a903dd1b969b495f2cab8d25a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20D=C3=ADaz=20N=C3=BA=C3=B1ez?= Date: Mon, 15 Apr 2024 16:48:59 +0200 Subject: [PATCH 033/161] Undo CategoryServiceImpl and InsertSampleDataService changes to only add the new generators classes and don't affect the current code --- .../services/InsertSampleDataService.java | 196 +++--------------- .../services/impl/CategoryServiceImpl.java | 8 +- 2 files changed, 28 insertions(+), 176 deletions(-) diff --git a/src/main/java/com/uniovi/services/InsertSampleDataService.java b/src/main/java/com/uniovi/services/InsertSampleDataService.java index db1e0dff..ff76371a 100644 --- a/src/main/java/com/uniovi/services/InsertSampleDataService.java +++ b/src/main/java/com/uniovi/services/InsertSampleDataService.java @@ -2,20 +2,9 @@ import com.uniovi.components.MultipleQuestionGenerator; import com.uniovi.components.generators.QuestionGenerator; -import com.uniovi.components.generators.art.ArtMovementQuestionGenerator; -import com.uniovi.components.generators.art.ArtPeriodQuestionGenerator; -import com.uniovi.components.generators.art.ArtStyleQuestionGenerator; -import com.uniovi.components.generators.art.ArtWorkQuestionGenerator; -import com.uniovi.components.generators.geography.*; -import com.uniovi.components.generators.history.*; -import com.uniovi.components.generators.movie.MovieDirectorQuestionGenerator; -import com.uniovi.components.generators.movie.MovieGenreQuestionGenerator; -import com.uniovi.components.generators.movie.MovieReleaseYearQuestionGenerator; -import com.uniovi.components.generators.movie.OriginalTitleQuestionGenerator; -import com.uniovi.components.generators.science.MathPhysicsFormulaQuestionGenerator; -import com.uniovi.components.generators.science.ScientificAchievementQuestionGenerator; -import com.uniovi.components.generators.science.ScientificDiscoveryQuestionGenerator; -import com.uniovi.components.generators.science.ScientistBirthplaceQuestionGenerator; +import com.uniovi.components.generators.geography.BorderQuestionGenerator; +import com.uniovi.components.generators.geography.CapitalQuestionGenerator; +import com.uniovi.components.generators.geography.ContinentQuestionGeneration; import com.uniovi.dto.PlayerDto; import com.uniovi.entities.Associations; import com.uniovi.entities.GameSession; @@ -25,7 +14,6 @@ import com.uniovi.repositories.QuestionRepository; import jakarta.annotation.PostConstruct; import jakarta.transaction.Transactional; -import org.hibernate.validator.constraints.Currency; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -34,6 +22,7 @@ import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; +import java.io.IOException; import java.time.LocalDateTime; import java.util.*; @@ -61,7 +50,7 @@ public InsertSampleDataService(PlayerService playerService, QuestionService ques @Transactional @EventListener(ApplicationReadyEvent.class) // Uncomment this line to insert sample data on startup - public void insertSampleQuestions() { + public void insertSampleQuestions() throws InterruptedException, IOException { if (!playerService.getUserByEmail("test@test.com").isPresent()) { PlayerDto player = new PlayerDto(); player.setEmail("test@test.com"); @@ -80,173 +69,40 @@ public void insertSampleQuestions() { } @Transactional - public void generateSampleData() { + public void generateTestQuestions() { + questionRepository.deleteAll(); + questionService.testQuestions(4); + } + + @Transactional + public void generateSampleData() throws InterruptedException, IOException { + questionRepository.deleteAll(); - // Generar preguntas de geografía en inglés - MultipleQuestionGenerator geographyQuestionsEn = new MultipleQuestionGenerator( + MultipleQuestionGenerator allQuestionGenerator = new MultipleQuestionGenerator( new ContinentQuestionGeneration(categoryService, Question.ENGLISH), new CapitalQuestionGenerator(categoryService, Question.ENGLISH), - new BorderQuestionGenerator(categoryService, Question.ENGLISH), - new AreaQuestionGenerator(categoryService, Question.ENGLISH), - new CurrencyQuestionGenerator(categoryService, Question.ENGLISH), - new LanguageQuestionGenerator(categoryService, Question.ENGLISH), - new PopulationQuestionGenerator(categoryService, Question.ENGLISH) + new BorderQuestionGenerator(categoryService, Question.ENGLISH) ); - List geographyQuestions = geographyQuestionsEn.getQuestions(); - geographyQuestions.forEach(questionService::addNewQuestion); + List questionsEn = allQuestionGenerator.getQuestions(); + questionsEn.forEach(questionService::addNewQuestion); - // Generar preguntas de geografía en español - MultipleQuestionGenerator geographyQuestionsEs = new MultipleQuestionGenerator( + allQuestionGenerator = new MultipleQuestionGenerator( new ContinentQuestionGeneration(categoryService, Question.SPANISH), new CapitalQuestionGenerator(categoryService, Question.SPANISH), - new BorderQuestionGenerator(categoryService, Question.SPANISH), - new AreaQuestionGenerator(categoryService, Question.SPANISH), - new CurrencyQuestionGenerator(categoryService, Question.SPANISH), - new LanguageQuestionGenerator(categoryService, Question.SPANISH), - new PopulationQuestionGenerator(categoryService, Question.SPANISH) + new BorderQuestionGenerator(categoryService, Question.SPANISH) ); - List geographyQuestionsSpanish = geographyQuestionsEs.getQuestions(); - geographyQuestionsSpanish.forEach(questionService::addNewQuestion); + List questionsEs = allQuestionGenerator.getQuestions(); + questionsEs.forEach(questionService::addNewQuestion); - // Generar preguntas de geografía en francés - MultipleQuestionGenerator geographyQuestionsFr = new MultipleQuestionGenerator( + allQuestionGenerator = new MultipleQuestionGenerator( new ContinentQuestionGeneration(categoryService, Question.FRENCH), new CapitalQuestionGenerator(categoryService, Question.FRENCH), - new BorderQuestionGenerator(categoryService, Question.FRENCH), - new AreaQuestionGenerator(categoryService, Question.FRENCH), - new CurrencyQuestionGenerator(categoryService, Question.FRENCH), - new LanguageQuestionGenerator(categoryService, Question.FRENCH), - new PopulationQuestionGenerator(categoryService, Question.FRENCH) - ); - List geographyQuestionsFrench = geographyQuestionsFr.getQuestions(); - geographyQuestionsFrench.forEach(questionService::addNewQuestion); - - - // Generar preguntas de historia en inglés - MultipleQuestionGenerator historyQuestionsEn = new MultipleQuestionGenerator( - new HistoricalArtifactQuestionGeneration(categoryService, Question.ENGLISH), - new HistoricalBattleQuestionGeneration(categoryService, Question.ENGLISH), - new HistoricalDynastyQuestionGeneration(categoryService, Question.ENGLISH), - new HistoricalEventQuestionGeneration(categoryService, Question.ENGLISH), - new HistoricalInventionQuestionGeneration(categoryService, Question.ENGLISH), - new HistoricalPeriodQuestionGeneration(categoryService, Question.ENGLISH), - new HistoricalLeaderQuestionGeneration(categoryService, Question.ENGLISH) - ); - List historyQuestions = historyQuestionsEn.getQuestions(); - historyQuestions.forEach(questionService::addNewQuestion); - - // Generar preguntas de historia en español - MultipleQuestionGenerator historyQuestionsEs = new MultipleQuestionGenerator( - new HistoricalArtifactQuestionGeneration(categoryService, Question.SPANISH), - new HistoricalBattleQuestionGeneration(categoryService, Question.SPANISH), - new HistoricalDynastyQuestionGeneration(categoryService, Question.SPANISH), - new HistoricalEventQuestionGeneration(categoryService, Question.SPANISH), - new HistoricalInventionQuestionGeneration(categoryService, Question.SPANISH), - new HistoricalPeriodQuestionGeneration(categoryService, Question.SPANISH), - new HistoricalLeaderQuestionGeneration(categoryService, Question.SPANISH) - ); - List historyQuestionsSpanish = historyQuestionsEs.getQuestions(); - historyQuestionsSpanish.forEach(questionService::addNewQuestion); - - // Generar preguntas de historia en francés - MultipleQuestionGenerator historyQuestionsFr = new MultipleQuestionGenerator( - new HistoricalArtifactQuestionGeneration(categoryService, Question.FRENCH), - new HistoricalBattleQuestionGeneration(categoryService, Question.FRENCH), - new HistoricalDynastyQuestionGeneration(categoryService, Question.FRENCH), - new HistoricalEventQuestionGeneration(categoryService, Question.FRENCH), - new HistoricalInventionQuestionGeneration(categoryService, Question.FRENCH), - new HistoricalPeriodQuestionGeneration(categoryService, Question.FRENCH), - new HistoricalLeaderQuestionGeneration(categoryService, Question.FRENCH) - ); - List historyQuestionsFrench = historyQuestionsFr.getQuestions(); - historyQuestionsFrench.forEach(questionService::addNewQuestion); - - - MultipleQuestionGenerator scienceQuestionsEn = new MultipleQuestionGenerator( - new MathPhysicsFormulaQuestionGenerator(categoryService, Question.ENGLISH), - new ScientificAchievementQuestionGenerator(categoryService, Question.ENGLISH), - new ScientificDiscoveryQuestionGenerator(categoryService, Question.ENGLISH), - new ScientistBirthplaceQuestionGenerator(categoryService, Question.ENGLISH) - ); - List scienceQuestions = scienceQuestionsEn.getQuestions(); - scienceQuestions.forEach(questionService::addNewQuestion); - - MultipleQuestionGenerator scienceQuestionsEs = new MultipleQuestionGenerator( - new MathPhysicsFormulaQuestionGenerator(categoryService, Question.SPANISH), - new ScientificAchievementQuestionGenerator(categoryService, Question.SPANISH), - new ScientificDiscoveryQuestionGenerator(categoryService, Question.SPANISH), - new ScientistBirthplaceQuestionGenerator(categoryService, Question.SPANISH) + new BorderQuestionGenerator(categoryService, Question.FRENCH) ); - List scienceQuestionsSpanish = scienceQuestionsEs.getQuestions(); - scienceQuestionsSpanish.forEach(questionService::addNewQuestion); - - MultipleQuestionGenerator scienceQuestionsFr = new MultipleQuestionGenerator( - new MathPhysicsFormulaQuestionGenerator(categoryService, Question.FRENCH), - new ScientificAchievementQuestionGenerator(categoryService, Question.FRENCH), - new ScientificDiscoveryQuestionGenerator(categoryService, Question.FRENCH), - new ScientistBirthplaceQuestionGenerator(categoryService, Question.FRENCH) - ); - List scienceQuestionsFrench = scienceQuestionsFr.getQuestions(); - scienceQuestionsFrench.forEach(questionService::addNewQuestion); - - - MultipleQuestionGenerator artQuestionsEn = new MultipleQuestionGenerator( - new ArtMovementQuestionGenerator(categoryService, Question.ENGLISH), - new ArtPeriodQuestionGenerator(categoryService, Question.ENGLISH), - new ArtStyleQuestionGenerator(categoryService, Question.ENGLISH), - new ArtWorkQuestionGenerator(categoryService, Question.ENGLISH) - ); - List artQuestions = artQuestionsEn.getQuestions(); - artQuestions.forEach(questionService::addNewQuestion); - - MultipleQuestionGenerator artQuestionsEs = new MultipleQuestionGenerator( - new ArtMovementQuestionGenerator(categoryService, Question.SPANISH), - new ArtPeriodQuestionGenerator(categoryService, Question.SPANISH), - new ArtStyleQuestionGenerator(categoryService, Question.SPANISH), - new ArtWorkQuestionGenerator(categoryService, Question.SPANISH) - ); - List artQuestionsSpanish = artQuestionsEs.getQuestions(); - artQuestionsSpanish.forEach(questionService::addNewQuestion); - - MultipleQuestionGenerator artQuestionsFr = new MultipleQuestionGenerator( - new ArtMovementQuestionGenerator(categoryService, Question.FRENCH), - new ArtPeriodQuestionGenerator(categoryService, Question.FRENCH), - new ArtStyleQuestionGenerator(categoryService, Question.FRENCH), - new ArtWorkQuestionGenerator(categoryService, Question.FRENCH) - ); - List artQuestionsFrench = artQuestionsFr.getQuestions(); - artQuestionsFrench.forEach(questionService::addNewQuestion); - - - MultipleQuestionGenerator movieQuestionsEn = new MultipleQuestionGenerator( - new MovieDirectorQuestionGenerator(categoryService, Question.ENGLISH), - new MovieGenreQuestionGenerator(categoryService, Question.ENGLISH), - new MovieReleaseYearQuestionGenerator(categoryService, Question.ENGLISH), - new OriginalTitleQuestionGenerator(categoryService, Question.ENGLISH) - ); - List movieQuestions = movieQuestionsEn.getQuestions(); - movieQuestions.forEach(questionService::addNewQuestion); - - MultipleQuestionGenerator movieQuestionsEs = new MultipleQuestionGenerator( - new MovieDirectorQuestionGenerator(categoryService, Question.SPANISH), - new MovieGenreQuestionGenerator(categoryService, Question.SPANISH), - new MovieReleaseYearQuestionGenerator(categoryService, Question.SPANISH), - new OriginalTitleQuestionGenerator(categoryService, Question.SPANISH) - ); - List movieQuestionsSpanish = movieQuestionsEs.getQuestions(); - movieQuestionsSpanish.forEach(questionService::addNewQuestion); - - MultipleQuestionGenerator movieQuestionsFr = new MultipleQuestionGenerator( - new MovieDirectorQuestionGenerator(categoryService, Question.FRENCH), - new MovieGenreQuestionGenerator(categoryService, Question.FRENCH), - new MovieReleaseYearQuestionGenerator(categoryService, Question.FRENCH), - new OriginalTitleQuestionGenerator(categoryService, Question.FRENCH) - ); - List movieQuestionsFrench = movieQuestionsFr.getQuestions(); - movieQuestionsFrench.forEach(questionService::addNewQuestion); + List questionsFr = allQuestionGenerator.getQuestions(); + questionsFr.forEach(questionService::addNewQuestion); log.info("Sample questions inserted"); } - -} +} \ No newline at end of file diff --git a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java index 4ba93d4d..cf3c3545 100644 --- a/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/CategoryServiceImpl.java @@ -40,11 +40,7 @@ public Category getCategoryByName(String name) { } private static final Map.Entry[] CATEGORIES = new AbstractMap.SimpleEntry[] { - new AbstractMap.SimpleEntry<>("Geography", "Questions about geography"), - new AbstractMap.SimpleEntry<>("History", "Questions about history"), - new AbstractMap.SimpleEntry<>("Science", "Questions about science"), - new AbstractMap.SimpleEntry<>("Art", "Questions about art"), - new AbstractMap.SimpleEntry<>("Movie", "Questions about movies") + new AbstractMap.SimpleEntry<>("Geography", "Questions about geography") }; @PostConstruct @@ -56,4 +52,4 @@ public void init() { } } } -} +} \ No newline at end of file From 4968265365f587cba0f5b38cded88396cd14f29e Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Mon, 15 Apr 2024 20:33:13 +0200 Subject: [PATCH 034/161] Update multiplayerGame.html style --- src/main/resources/static/css/multiplayer.css | 3 ++ .../templates/game/multiplayerGame.html | 38 ++++++++++--------- src/main/resources/templates/index.html | 1 + 3 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 src/main/resources/static/css/multiplayer.css diff --git a/src/main/resources/static/css/multiplayer.css b/src/main/resources/static/css/multiplayer.css new file mode 100644 index 00000000..f52b5a09 --- /dev/null +++ b/src/main/resources/static/css/multiplayer.css @@ -0,0 +1,3 @@ +.display-5 { + margin-top: 3em; +} \ No newline at end of file diff --git a/src/main/resources/templates/game/multiplayerGame.html b/src/main/resources/templates/game/multiplayerGame.html index e9c29ccf..38bbae5e 100644 --- a/src/main/resources/templates/game/multiplayerGame.html +++ b/src/main/resources/templates/game/multiplayerGame.html @@ -2,28 +2,30 @@ - + - -
    - - - - +
    + +
    + + + + +
    + + + +

    + +

    + + +
    - - - -

    - -

    - - -
    diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 434df7e5..3ab7de4e 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -10,6 +10,7 @@

    +

    From 863dc8f8ade5540583cde7cced87469ab60366ab Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Mon, 15 Apr 2024 20:33:29 +0200 Subject: [PATCH 035/161] Update lobby.html style --- src/main/resources/messages.properties | 3 +- src/main/resources/messages_en.properties | 3 +- src/main/resources/messages_es.properties | 3 +- src/main/resources/messages_fr.properties | 3 +- src/main/resources/static/css/multiplayer.css | 16 +++++++++- src/main/resources/templates/game/lobby.html | 31 ++++++++++++++----- 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 907e3eac..f2c9fd66 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -37,7 +37,7 @@ error.error=Error: index.heading=WIQ index.subtitle=Responde las preguntas correctamente y GANA!!! index.button=JUGAR -index.multiplayer.button= Juega con amigos +index.multiplayer.button=JUGAR CON AMIGOS # -------------------Statements for the home.html file--------------------- home.heading=Bienvenido @@ -90,6 +90,7 @@ multi.placeholder= Introduce el código de una partida multi.label = Únete a una partida multi.join = Unirse multi.onlyNumber = Solo se permiten números +multi.copyCode= Copiar código # -------------------Statements for the lobby.html file--------------------- lobby.info =Jugadores unidos a la partida: diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 07ce0be4..27524e6e 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -37,7 +37,7 @@ error.error=Error: index.heading=WIQ index.subtitle=Answer the questions correctly and WIN!!! index.button=PLAY -index.multiplayer.button= Play with friends +index.multiplayer.button=PLAY WITH FRIENDS # -------------------Statements for the home.html file--------------------- @@ -92,6 +92,7 @@ multi.placeholder=Enter the game code multi.label=Join a game multi.join = Join multi.onlyNumber=Only numbers allowed +multi.copyCode= Copy code # -------------------Statements for the lobby.html file--------------------- lobby.info =Players joining the game: lobby.friends =Share your game code with your friends diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index b8b91a94..fbc770ba 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -38,7 +38,7 @@ error.error=Error: index.heading=WIQ index.subtitle=Responde las preguntas correctamente y GANA!!! index.button=JUGAR -index.multiplayer.button= Juega con amigos +index.multiplayer.button=JUGAR CON AMIGOS # -------------------Statements for the home.html file--------------------- @@ -93,6 +93,7 @@ multi.placeholder= Introduce el código de una partida multi.label = Únete a una partida multi.join = Unirse multi.onlyNumber = Solo se permiten números +multi.copyCode= Copiar código # -------------------Statements for the lobby.html file--------------------- diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index 9281e4cd..d540adf3 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -36,7 +36,7 @@ error.error=Erreur : index.heading=WIQ index.subtitle=Répondez aux questions correctement et GAGNEZ !!! index.button=JOUER -index.multiplayer.button=Jouez avec des amis +index.multiplayer.button=JOUEZ AVEC DES AMIS # -------------------Statements for the home.html file--------------------- home.heading=Bienvenue @@ -86,6 +86,7 @@ multi.placeholder=Entrez le code du jeu multi.label=Rejoignez une partie multi.join =Rejoindre multi.onlyNumber=Seuls les chiffres sont autorisés +multi.copyCode= Copier le code # -------------------Statements for the lobby.html file--------------------- lobby.info =Joueurs rejoignant le jeu : diff --git a/src/main/resources/static/css/multiplayer.css b/src/main/resources/static/css/multiplayer.css index f52b5a09..f48f3fb4 100644 --- a/src/main/resources/static/css/multiplayer.css +++ b/src/main/resources/static/css/multiplayer.css @@ -1,3 +1,17 @@ .display-5 { margin-top: 3em; -} \ No newline at end of file +} + +#lobbyCode, #label-code { + font-size: 3em; +} + +#lobbyInfo { + margin-top: 3em; +} + +#playerList { + list-style-type: none; + text-align: center; + padding: 0; +} diff --git a/src/main/resources/templates/game/lobby.html b/src/main/resources/templates/game/lobby.html index 16b72e96..c3da3314 100644 --- a/src/main/resources/templates/game/lobby.html +++ b/src/main/resources/templates/game/lobby.html @@ -3,23 +3,26 @@ - + -
    -

    -

    -

    +
    +

    + + +

    + + +
    - - - +
    + From db833af981a47ab554d1077e50e14f2c66258a29 Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Mon, 15 Apr 2024 20:45:53 +0200 Subject: [PATCH 036/161] Fix small bug of code validation (only numbers are permited) --- .../resources/templates/game/multiplayerGame.html | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/resources/templates/game/multiplayerGame.html b/src/main/resources/templates/game/multiplayerGame.html index 38bbae5e..1be2cbb6 100644 --- a/src/main/resources/templates/game/multiplayerGame.html +++ b/src/main/resources/templates/game/multiplayerGame.html @@ -42,15 +42,22 @@ function toggleJoinButton() { var codeInput = document.getElementById("code"); var joinBtn = document.getElementById("joinBtn"); + var errorMsg = document.getElementById("error-msg"); + + if (codeInput.value.trim() === "") { + joinBtn.disabled = true; + errorMsg.style.display = "none"; + return; + } var containsOnlyNumbers = /^[0-9]+$/.test(codeInput.value); if (containsOnlyNumbers) { joinBtn.disabled = false; - document.getElementById("error-msg").style.display = "none"; + errorMsg.style.display = "none"; } else { joinBtn.disabled = true; - document.getElementById("error-msg").style.display = "block"; + errorMsg.style.display = "block"; } } From 586805e1ac352871310b3576806c020fce90e2e5 Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Tue, 16 Apr 2024 00:01:41 +0200 Subject: [PATCH 037/161] Change multiFinished.html style --- .../resources/templates/game/multiFinished.html | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/resources/templates/game/multiFinished.html b/src/main/resources/templates/game/multiFinished.html index a2493267..59d75576 100644 --- a/src/main/resources/templates/game/multiFinished.html +++ b/src/main/resources/templates/game/multiFinished.html @@ -3,23 +3,26 @@ - + -
    + + +

    -

    +

    +
      +
    • +
    - -
      -
    • -
    +
    + - - - - -
    -

    + +

    + +

    -

    +

    - - - -
    + - +
    \ No newline at end of file From db70848afa61cb069b1445034ac4a6f0b2ad53ca Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Tue, 16 Apr 2024 20:04:23 +0200 Subject: [PATCH 042/161] multiFinished style update --- src/main/resources/messages.properties | 4 ++++ src/main/resources/messages_en.properties | 4 ++++ src/main/resources/messages_es.properties | 3 +++ src/main/resources/messages_fr.properties | 4 ++++ src/main/resources/static/css/multiplayer.css | 9 +++++++++ 5 files changed, 24 insertions(+) diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index f2c9fd66..d60dc860 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -101,6 +101,10 @@ lobby.start = Empezar multi.code= Código de la partida multi.results =Ver resultados +# -------------------Statements for the multiFinished.html file--------------------- +multi.finished= Partida finalizada +multi.points = Puntuaciones + # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API api.doc.description=Esta es la documentación de la API de WIQ. Aquí puedes encontrar información sobre los recursos disponibles, los parámetros que aceptan y los ejemplos de uso. diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 27524e6e..9decb6b2 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -102,6 +102,10 @@ lobby.start =Start multi.code= Game code multi.results = See results +# -------------------Statements for the multiFinished.html file--------------------- +multi.finished= Finished game +multi.points = Points + # -------------------Statements for the apiHome.html file--------------------- api.doc.title=API Documentation api.doc.description=This document describes the REST API endpoints. diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index fbc770ba..23425529 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -105,6 +105,9 @@ lobby.start =Empezar multi.code= Código de la partida multi.results =Ver resultados +# -------------------Statements for the multiFinished.html file--------------------- +multi.finished= Partida finalizada +multi.points = Puntuaciones # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index d540adf3..cefd1890 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -97,6 +97,10 @@ lobby.start = Commencer multi.code=Code du jeu multi.results=Voir les résultats +# -------------------Statements for the multiFinished.html file--------------------- +multi.finished= Jeu terminé +multi.points = Points + # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentation de l'API diff --git a/src/main/resources/static/css/multiplayer.css b/src/main/resources/static/css/multiplayer.css index f48f3fb4..6715e189 100644 --- a/src/main/resources/static/css/multiplayer.css +++ b/src/main/resources/static/css/multiplayer.css @@ -15,3 +15,12 @@ text-align: center; padding: 0; } + +#finishedGame { + font-size: 5em; + margin-bottom: 0.5em; +} + +#multiPoints { + margin-top: 3em; +} From f8ffba962c744eae71f0574773894419424e0c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pelayo=20Rojas=20=C3=8D=C3=B1igo?= Date: Tue, 16 Apr 2024 20:54:22 +0200 Subject: [PATCH 043/161] Add grafana and prometheus --- .env | 4 ++ Dockerfile | 4 +- docker-compose.yml | 43 ++++++++++++-- pom.xml | 8 +++ prometheus.yml | 14 +++++ .../resources/application-prod.properties | 3 +- src/main/resources/application.properties | 6 +- testCert.crt | 55 ++++++++++++++++++ testCert.p12 | Bin 0 -> 5129 bytes 9 files changed, 127 insertions(+), 10 deletions(-) create mode 100644 .env create mode 100644 prometheus.yml create mode 100644 testCert.crt create mode 100644 testCert.p12 diff --git a/.env b/.env new file mode 100644 index 00000000..a78d130b --- /dev/null +++ b/.env @@ -0,0 +1,4 @@ +MYSQL_HOST=db +KEYSTORE_PATH=./testCert.p12 +KEYSTORE_PASSWORD=123456 +WIQ_IMAGE=pelayori/wiq_es04b \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 752ecea9..0edd0077 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # Build stage with Maven and JDK 17 FROM maven:3.8.4-openjdk-17-slim as build -WORKDIR /app +WORKDIR ./app COPY pom.xml . COPY src src/ # Use Maven directly instead of the Maven Wrapper @@ -8,6 +8,6 @@ RUN mvn clean package -DskipTests # Run stage with JDK 17 FROM openjdk:17-slim -COPY --from=build /app/target/*.jar app.jar +COPY --from=build ./app/target/*.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=prod","-jar","/app.jar"] EXPOSE 443 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index a61915cf..a3593872 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,13 +18,13 @@ services: restart: always wiq_es04b: - image: ghcr.io/arquisoft/wiq_es04b:latest + image: ${WIQ_IMAGE:-"ghcr.io/arquisoft/wiq_es04b:latest"} environment: MYSQL_HOST: ${MYSQL_HOST} - MYSQL_PORT: ${MYSQL_PORT} - MYSQL_DATABASE: ${MYSQL_DATABASE} - MYSQL_USER: ${MYSQL_USER} - MYSQL_PASSWORD: ${MYSQL_PASSWORD} + MYSQL_DATABASE: ${MYSQL_DATABASE:-wiq_es04b} + MYSQL_USER: ${MYSQL_USER:-wiq_es04b} + MYSQL_PASSWORD: ${MYSQL_PASSWORD:-wiq_es04b} + MYSQL_PORT: ${MYSQL_PORT:-3306} KEYSTORE_PATH: ${KEYSTORE_PATH} KEYSTORE_PASSWORD: ${KEYSTORE_PASSWORD} ports: @@ -38,9 +38,40 @@ services: volumes: - ${KEYSTORE_PATH}:/certs/keystore.p12 + prometheus: + image: prom/prometheus:latest + volumes: + - prometheus_data:/prometheus + - ./prometheus.yml:/etc/prometheus/prometheus.yml + ports: + - "9090:9090" + networks: + - mynetwork + depends_on: + - wiq_es04b + restart: always + + grafana: + image: grafana/grafana:latest + volumes: + - grafana_data:/var/lib/grafana + environment: + GF_AUTH_DISABLE_LOGIN_FORM: true + GF_AUTH_ANONYMOUS_ENABLED: true + GF_AUTH_ANONYMOUS_ORG_ROLE: Admin + ports: + - "3000:3000" + networks: + - mynetwork + depends_on: + - prometheus + restart: always + volumes: db_data: + prometheus_data: + grafana_data: networks: mynetwork: - driver: bridge + driver: bridge \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7961a9d5..52e13e70 100644 --- a/pom.xml +++ b/pom.xml @@ -114,6 +114,14 @@ springdoc-openapi-starter-webmvc-ui 2.5.0 + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-registry-prometheus + diff --git a/prometheus.yml b/prometheus.yml new file mode 100644 index 00000000..127bc94a --- /dev/null +++ b/prometheus.yml @@ -0,0 +1,14 @@ +global: + scrape_interval: 2s + scrape_timeout: 1s + +scrape_configs: + - job_name: 'spring-application' + scrape_interval: 2s + scrape_timeout: 1s + metrics_path: '/actuator/prometheus' + scheme: https + tls_config: + insecure_skip_verify: true + static_configs: + - targets: [ 'wiq_es04b:443' ] \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 6e483e24..d7689afa 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -11,4 +11,5 @@ spring.jpa.hibernate.ddl-auto=update server.ssl.key-store=/certs/keystore.p12 server.ssl.key-store-password=${KEYSTORE_PASSWORD} server.ssl.keyStoreType=PKCS12 -server.ssl.keyAlias=keystore \ No newline at end of file +server.ssl.keyAlias=keystore +server.ssl.enabled-protocols=TLSv1.2 \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b2dc761a..660a6bfa 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ # Port 3000 for testing, local deployment -server.port=3000 +server.port=3100 server.address=0.0.0.0 # HSQL db @@ -13,3 +13,7 @@ springdoc.api-docs.path=/api-docs springdoc.swagger-ui.path=/api springdoc.swagger-ui.operationsSorter=method springdoc.packagesToScan=com.uniovi.controllers.api + +management.endpoint.metrics.enabled=true +management.endpoints.web.exposure.include=prometheus +management.endpoints.jmx.exposure.include=* diff --git a/testCert.crt b/testCert.crt new file mode 100644 index 00000000..d366bf5c --- /dev/null +++ b/testCert.crt @@ -0,0 +1,55 @@ +Bag Attributes + friendlyName: youralias + localKeyID: 54 69 6D 65 20 31 37 31 33 32 38 34 33 38 34 39 32 35 +subject=C = d, ST = d, L = d, O = d, OU = d, CN = d + +issuer=C = d, ST = d, L = d, O = d, OU = d, CN = d + +-----BEGIN CERTIFICATE----- +MIIDMzCCAhugAwIBAgIINBF3UUhqeiAwDQYJKoZIhvcNAQELBQAwSDEKMAgGA1UE +BhMBZDEKMAgGA1UECBMBZDEKMAgGA1UEBxMBZDEKMAgGA1UEChMBZDEKMAgGA1UE +CxMBZDEKMAgGA1UEAxMBZDAeFw0yNDA0MTYxNjE5NDRaFw0zNDA0MTQxNjE5NDRa +MEgxCjAIBgNVBAYTAWQxCjAIBgNVBAgTAWQxCjAIBgNVBAcTAWQxCjAIBgNVBAoT +AWQxCjAIBgNVBAsTAWQxCjAIBgNVBAMTAWQwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC5E0IFN+5p/sv0qGs9MnvVVjusbWV+BIW4wWmt8c3Rbd73cuSG +BS6iHErbZh7t8uv7wY0hO06lqsphRRjBzD5ouS4MS4dsLpMkgjMcll8PY17nA/iy +HiIb/Cp18srzqGQIXBow6gXaMcTU8irN+TEtmlT/DvwtVpVqy6eCqmmhPxXsyyw1 +8DxlWRTV2o7pPXg0YC6r6YEHLbprBbwa1YAqiaSciKTWgQuR1w7abkQz8slaM4kH +MLdad1ra0F96YaHDuDQBRD0Pe13xk4yvE4il3JiOoA1EEa7xC5CYdg2lb/kR1RME +3t7L7Aiv+ThxiIeK3Agj11Oj9lOn5NL93CW/AgMBAAGjITAfMB0GA1UdDgQWBBSv ++MwjgZhyyuU+LUZvM14sw4JmCjANBgkqhkiG9w0BAQsFAAOCAQEAp455G+Awasa0 +ZbN2tTyFaT5rhFfyZ5BNTPBnmVVOP6XCa2Ot3tc+wWu4eMp5bmPDziHYfyeApI8r +zPbSiPgt8SKDCBwI4UCysdKgjxPfWSPxlWV/SXAU3wyijlm/hyQpZzcDakW0Wrj6 +ihvC+zoOC0DOkU2AfWTHgz6M/zB+OCY8jPX57niPTTp4LUlA/VNUu2O6QWn/4M2y +mzkKtpmKyfS8niQOq+4K3UlVXHb4pu+hSdeizXYz1a81mB8AbLDwcuEsfMNJ9BeY +iYeTlkeBbY7Zw9yTNnZsrjyCtTedCO8POvEbC6nbZAyLb1MD6DsBrF/8D5Wf37ZK +/bF0j5s1jA== +-----END CERTIFICATE----- +Bag Attributes + friendlyName: keystore + localKeyID: 54 69 6D 65 20 31 37 31 33 32 38 35 39 38 39 39 34 30 +subject=C = Unknown, ST = Unknown, L = Unknown, O = Unknown, OU = Unknown, CN = Unknown + +issuer=C = Unknown, ST = Unknown, L = Unknown, O = Unknown, OU = Unknown, CN = Unknown + +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIIXpBa0S6OUOUwDQYJKoZIhvcNAQELBQAwbDEQMA4GA1UE +BhMHVW5rbm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQ +MA4GA1UEChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5r +bm93bjAeFw0yNDA0MTYxNjQ2MjlaFw0zNDA0MTQxNjQ2MjlaMGwxEDAOBgNVBAYT +B1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24xEDAO +BgNVBAoTB1Vua25vd24xEDAOBgNVBAsTB1Vua25vd24xEDAOBgNVBAMTB1Vua25v +d24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0bVkhX3R258hDQ0ce +iJNDVDdM0tHZaDXi6Z8/0a71C5/fNO/yDBGosL+DquRp0gDKpHQY0dd8+//Mr2mJ +gRqvQ5x6bs1PXkpdoCceHCWhV66nCdzGC6JAwxO4vlDAWA5dBZbyUGdLHnedq3vc +q6OYxg8HfMItU7nOME6cv7nb74FRgxkODWZ5xo96HkgAVmbutwn01+yZjtTPjug0 +NO/nsciaHMpRKpCmopMsJ2fRJwOraT9CfGd3DLxgikHK1foJqtHmorBN5Nog3J2O +UtfhVYjsgU+PQXLP01mTMFFVxRbfWOySYfx3L/KNElbsHXLwVW4GcZwZV47Wmwj1 +CEoNAgMBAAGjITAfMB0GA1UdDgQWBBS9q5bQ4tQ/xdvAHutrqAFLNOiLoDANBgkq +hkiG9w0BAQsFAAOCAQEAHGpap48KVmhZVBRhVtUOJQ7FUT5KoIdJ5SPgji5ofj9o +96NL9o4+/3hH7xSuVH4CDi/GRVt5nv0sXoKpZ1zXG2n/5E/GenHybbjj7J/Rg9rn +0MLWrWaU32C8s9fouqUz9IyaMuUGTB208fOQB4Ymwz83xdoGZtC8P+vP1Q5DZyQn +XI8R7VDhcKRoCMBvqCWm2ynU1viPUEfNV/064S8TFuhYD4wXcqhSzgogsO0iKLIE +nGWRbkEeN+fuaiwUDszemLNXfpp5ojwbWW5+I6i2QUWqVbJbk0fDItgGGX5pzTqj +8cnJoqNaeBTzKTTW9/0mr5kkPqXtQCQum/3vnUo9wQ== +-----END CERTIFICATE----- diff --git a/testCert.p12 b/testCert.p12 new file mode 100644 index 0000000000000000000000000000000000000000..a6f4004585c34e934b82b51fda1269dcd99083fc GIT binary patch literal 5129 zcmbW5WmFV^md9rp7#O;wLy(pj29Sm!MjE691nH0lfgz+EI;5mU8c7-H6eWcLq(cPh zZegTheP{Q)_x8)~p8ay~x&IsA?(f`lp(tuR93TjaqC$fqe37b=XCy#;U_Oc}9~VWH z^HbCK*+W*L>cJ6^b+pp93G}l zZS2YeJBO(TR%^ty$tRt*7vT*jbct1n#do>@ z+9uvPJZXE?Q7E%YUcjd`f}fs-@6$1tmRZI#U@GAxJsOi z3hvAcnSZiU$N^)NMY4Wz?aHDTyJYk{7nKoJqOBqcG4R#E6*IMf<`W zmmXa^8r9a>*}Wu8+U41F%^M1eo!Di}o!}=K ziE>`(Xo%PH`0fej{R5G=L8 z+wR02{clD-6seWIs$_HRBYO=$L_;@yvrVfR14an7aeomLeiX_2t<)zH#QAN2FlnJt zpy~7GOzWNKQ$djKBHm3MwTdzR+)QzvZPGx0$FdFTA)-kW$jgt0_XbvC;9i6nM}+ToC@r z!#+MR=%)<-jXa9>^Dq|~fR*EKA*=NSKA%zETxeS-yA7at>2&brcO~SMfl@wpWG{P| zr)h>d({9gsg0FT7Ollb)T_IqlTe8L7lFBpZg~JWhM|~{*;4MdilwtD?uBnzcrqTF3 z0fkxV;&buESvVxzxwR5%UUzBq)0``Ew)4V&m_6D561Jn z?Ugf-aD=f^y_vzD>d-66mD}&E2ie?$3W7%IX>3bp0&^_ds&5Dh$rU`?P-gSz;vmmE zp$isOx}}fD95uY~msJjd3++Ceq7DPkrY+0OloAE)3y|YK?L(fVcLg?T&lR?95R%XJ zmR=atYmKcpIp?{ZZuk=xEUpge9KX)PgnvtESRhPAAS-q zPX5u8zKQKU>KGhRMru=FTC%>zu7)jW3+KMScw_oZ!Kd?*aG+?9Huy=0;GNCH1Pm-X zt(F0PCBf*s#lHq4jg+-9bn;ci9;?(Ck|C}Us)e)y=fZZAj~0~l#uD$?5HW8k0z=Ep z<6czzNfh^Wl+g^@27UsgQTmO}O=#k-lW-M=pAnrOFu|pBua%w)Or;Ct zp%M_)0xGfvZml25yxEO@S}7sR?E!?GyR9==cu$ zJblqu=hu!-u(d(*`tRrTDKQ>D9q^dD`@qnrwXk-0R zgV|uh7vaZHwtwOhLM=?qLJ9B(xC49uF9B8n7l7km>-Fy?_k^i&DGeN5?d}VU3yZ)c zL`5V-C1GNJIh^tTf^#F{;3?){xkK|C(K%D=H{qB zFZ&0aqp~Rd4vgE|*dpEUID_x!XCxl#zbDt24roMcZ~ur4!YC9HKz-lk$M)dSpn7H! ziwvx_gCV7Kw$t(Th#B4^eyc~ynw4>G_e^+9(%gTJ!w7UB(}pE4A+ zj?{&~spWkZO9w1r`{xJ2RUr!n&#V%7rd#qA?Y799&d#j$;J>Ro%h3bpQrM=2^tw$Q zzX0p)lcHTXBw@BchK1kq(KKf_{q*kxXhC3b@Tfg)zmx{Tz2CsNnUe$k+~KoG(w{fX zf?s51_HHEh2Yucr7)d-6cvl4n6AC@x@vc*mnu0Wsluq4N>Hl^+1-?+d1ogSO>u9r|xe~ zChG_IL$a$4x*P#qrB4(gvJ57uWo zkT`>mTQ_x&lyF-Bic%X|dqb4JmPat?;Y#r4> zg|#W=%4zRW+5E~2V!d@GX?_^I!S`V@g9Qh#Ri*bj5eEMWn%9E(YAa0h{^FpkNIG~6 zrun<4iPQ45(Qz{d0Id*!LRvJnvr^Sjegd&h|9 zR};Am`DBG~Vy4?AE*k;>etf`-)}5;P-wr-sNUKO*HM9C^3_&e(NhM2bF&&znT>D$H zXqS+6v&d9cDakh-(Y&A>dq!Tig#OHf;E%BlsqooCPh6|_`^i0=`U)LkzY6YDT`$kw zSrZmX+@s|KPAp+ss|u=XO$2E)KaP$3BR~2aeHE%!2r^#6Wlrz zI7vY?TWn3 zNtTFQv&nq<0-{kNn%%Vj7gV1(2(CZ8Xy{96QNIf0n~@Ji;eW!>nb&5{oTpzpXys^o zRC=c*-tikZW^?%Tr^S%#&(X)}O9WH<-@2lJ_~?`8A6#3+wiS?InhmlHv~cKWaq!`? znc1|Xz~fNeUwE*aKDB|p+x(5?ys}aSw#eiq=gBzn3P&Yqqy^S%!Kw(f6np_;@_S~& z*BMr-q8WfeaOsRYF&DKQNY0hDajYyu( ztA`7?ewy1OQZsjb#JTdq1x%wgWC^}urAYqlyJNy^6t;&^gpvq&`Bu7Kw%MapWnKgw zSGz83SA9=y`cmy<%+fwFP|IaVmKX3fjqn03mUpgaTt1`O_KQiK9}b18jl2q#mCjyd z4}=GP{z?=<^|j3=c8MT>Rko@A!&H`Tz7Qxy)rspvSbywkvfp-VX~i973dL?L4t|;I z5cl#(BY~GM%Kn=SV)0_-5KLN&&SfU&{U9WzCbkz|acl@5x^9Q0t6@w-K1$eO@ilXh{ ziYIc|Fv{*}Rhj}V&IV;!l*)@g!T1%1f})k|*+j`IQ1I==hGn8syRd2e>t9bFfWv1Q z!P=cui-xrbqB2abV_+`+nM>GG@5taT`ANze4?lSQzC(_`^0u;~{L(d&_v6l^q>Rus zx43IVxA0Vx!564|FdDrME zD_Lgr5q01OKUAdd(TO@#w!p4U+|W%tdtv$|svXs_mMY6AG8#}y@oVLAIoUMMTekSe zZ*E=SZi-^18y|h&yM)Jm!tkprx@x3oa4KC-x}T}^oMomDvVX!ki0jI_ew;O-NC{b( zzi2jAt&iFNQ#RBvQntC#$7tWFsp0>^dyK(@e~t%D?AVK?;2!U{D%9WV3uv2g%xM=P zwsR;+g}%oo^z1*JU`^-lKae4M&Gnkri(AKy68UH(1;x=fXIq zhpQ+VPw@SLS-*+404BON{a~+*L0paB03`k@5-qYSTC8_O5@xT%<4D#hlK~O6+56M$ zyPp^lYCwFyPWN)zxxHryDO_0DbZ_%FPGS^6wwIJ$D)|bM50tzvJ~rW3!ctw2 zLAD@Ps?oT{c1%~Gg$E&GzBj+!^Oyj+M;d12OJC+-&$N*HF#U(oR6^0Nx__etX2X7% zI&Q41xZy(z#56v)ea*u;!HSe;-rhUq;je?6Qh~GIm+}x}Vb;=e*9l^d2(Eya<8a2> zejLNDaxbQC_L)VvjiRELb^f=dK=Zc>6~WzQ`r9!NvWU>eHpQu8u2LRrUPmos??gL) zzkbGwbhjXaT+>Ie8MplShP4$Z;-&E8%(AdUcIeAJX1gA#+t_a4W*gVzuSbo1zsiR{ zEnsM57#}&7LK>_O8>x&0kE3V9d86hJOzQ2I`>tYU^JMOR_R?D|UD~)whW~M2AQ^(h zkdr%=5v#S!Po8`3YuAruj82Ap)=&c)1#Y}n-Vo%ty2m8TH0_wVrf*Isq?wBAZD^G( zIO_?vwOG=L$#QpgysF5#Z~w^y2}m+}*E3-80HLUJBGtH;d*k}&O6+1`BSK)2ObTu| zNn+^#+00A~R-f!Q>OwfhS(&;x5XnzrUFt4%HutPBM)ls0DGHAH*q#~lt5iI0C5Pet zOqmLe$st~P%=8r$UGv!Gx+kKvNn+AdHv)kfZI+g8!}?L zlF}Y|I`@Vz?2ANDshQkL$231P5o3CjuSgr|0N0D@Y7n0Z)0Ydzy{#XHEm`DobpsT$ zY0oaU&g+bmT6+NlA0%wPn9`W*t-KE_aAuZ!?xJA%+#=#wo?X$PeL1jAb<@50Ygx$F z_lGvNoKJGqoV$BUdried@pWn-7n@HOoWQ~XPjkah*7F_@*pdNnOBU=$DCrJ%a!aSP z82CbOyIlHw9`MBDVdu8MkVkTu5aaprQ@U~|ZpbQb)?v$R?+p?n)R17B3B4^>dAm^g zQqkjGmRO{9%^#x3n&rAB*@5RMr&rcck%!Wqc=1ze62ZMS$X|LxeEgc3-MF<|x&h*w zGMT`+YM-sEb6>hNNfnC7HgruzQSG7qpwu0^7e%dr literal 0 HcmV?d00001 From 473e41fa1b9621a37bc10a5574e732a265e37d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pelayo=20Rojas=20=C3=8D=C3=B1igo?= Date: Tue, 16 Apr 2024 20:57:27 +0200 Subject: [PATCH 044/161] Add grafana and prometheus --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index a3593872..f6a7e156 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -56,7 +56,7 @@ services: volumes: - grafana_data:/var/lib/grafana environment: - GF_AUTH_DISABLE_LOGIN_FORM: true + GF_AUTH_DISABLE_LOGIN_FORM: 1 GF_AUTH_ANONYMOUS_ENABLED: true GF_AUTH_ANONYMOUS_ORG_ROLE: Admin ports: From cef4298fcb8b90a14f8cefe5861825b7bb9a2b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pelayo=20Rojas=20=C3=8D=C3=B1igo?= Date: Tue, 16 Apr 2024 20:59:00 +0200 Subject: [PATCH 045/161] Add grafana and prometheus --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index f6a7e156..e88e89ed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,7 +18,7 @@ services: restart: always wiq_es04b: - image: ${WIQ_IMAGE:-"ghcr.io/arquisoft/wiq_es04b:latest"} + image: ${WIQ_IMAGE:-ghcr.io/arquisoft/wiq_es04b:latest} environment: MYSQL_HOST: ${MYSQL_HOST} MYSQL_DATABASE: ${MYSQL_DATABASE:-wiq_es04b} From b4b0d1d3748e34bda10be2d45d7809a3f6337052 Mon Sep 17 00:00:00 2001 From: RicardoDiNu Date: Tue, 16 Apr 2024 21:37:53 +0200 Subject: [PATCH 046/161] Some endMultiGame logic added --- .../com/uniovi/controllers/GameController.java | 15 ++++++++++++++- .../resources/templates/game/multiFinished.html | 4 ++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index eb7945b8..2fe79f4e 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -148,6 +148,15 @@ public Map updateFinishedGame(@PathVariable String code, HttpSess return playerInfo; } +// @GetMapping("/multiplayerGame/endGame/{code}") +// public String endMultiplayerGame(@PathVariable String code) { +// List players = playerService.getUsersByMultiplayerCode(Integer.parseInt(code)); +// for (Player player : players) { +// player.setScoreMultiplayerCode(null); +// } +// return "redirect:/index.html"; +// } + @GetMapping("/game/lobby/{code}") @@ -232,7 +241,7 @@ else if(questionService.checkAnswer(idQuestion, idAnswer)) { } @GetMapping("/game/update") - public String updateGame(Model model, HttpSession session) { + public String updateGame(Model model, HttpSession session, Principal principal) { GameSession gameSession = (GameSession) session.getAttribute("gameSession"); Question nextQuestion = gameSession.getCurrentQuestion(); if(nextQuestion == null && gameSession.getPlayer().getMultiplayerCode()!=null/*session.getAttribute("multiplayerCode") !=null*/){ @@ -244,6 +253,10 @@ public String updateGame(Model model, HttpSession session) { model.addAttribute("code",session.getAttribute("multiplayerCode")); session.removeAttribute("gameSession"); + Optional player = playerService.getUserByUsername(principal.getName()); + Player p = player.orElse(null); + playerService.setScoreMultiplayerCode(p.getId(),""+gameSession.getScore()); + return "game/multiFinished"; } if (nextQuestion == null) { diff --git a/src/main/resources/templates/game/multiFinished.html b/src/main/resources/templates/game/multiFinished.html index 7a09d28b..5e5860c0 100644 --- a/src/main/resources/templates/game/multiFinished.html +++ b/src/main/resources/templates/game/multiFinished.html @@ -11,6 +11,10 @@

  • + + + + \ No newline at end of file diff --git a/src/main/resources/templates/game/fragments/gameFrame.html b/src/main/resources/templates/game/fragments/gameFrame.html index c118cb34..e68ffd2a 100644 --- a/src/main/resources/templates/game/fragments/gameFrame.html +++ b/src/main/resources/templates/game/fragments/gameFrame.html @@ -50,10 +50,8 @@

    } $("#btn" + answer.id).off("click"); }); - $("#continueBtn").click(function () { - $("#gameFrame").load("/game/" + qId + "/" + aId); - }); - $("#continueBtn").show(); + + initiateTimeout(qId, aId); } let timeoutPeriod = [[${questionDuration}]] * 1000; // Timeout period in milliseconds (e.g., 8000ms for 8 seconds) @@ -87,6 +85,48 @@

    clearInterval(interval); } } + + function initiateTimeout(qId, aId) { + let timeoutPeriod = 8000; // Timeout period in milliseconds (e.g., 8000ms for 8 seconds) + let updateInterval = 100; // How often to update the progress bar (in milliseconds) + let progressBar = $('#progressBar'); + + let activeTimeout = setTimeout(function () { + clearInterval(interval); // Ensure the interval is cleared when the timeout completes + $("#gameFrame").load('/game/update'); + updateQuestionCounter(); + }, timeoutPeriod); + + timeoutPeriod = timeoutPeriod - updateInterval * 2; // Adjust the timeout period to account for the update interval + let interval = setInterval(updateProgressBar, updateInterval); + + function updateProgressBar() { + let currentTime = parseFloat(progressBar.attr('aria-valuenow')); + let decrement = 100 * updateInterval / timeoutPeriod; + let newTime = Math.max(0, currentTime - decrement); + + // Calculate the color based on the percentage + let greenValue = Math.round((newTime * 255) / 100); + let redValue = 255 - greenValue; + let color = 'rgb(' + redValue + ',' + greenValue + ',0)'; + + progressBar.css('width', newTime + '%'); + progressBar.css('background-color', color); // Apply the calculated color + progressBar.attr('aria-valuenow', newTime); + + if(newTime <= 0) { + clearInterval(interval); + } + } + $("#continueBtn").show(); + $("#continueBtn").off('click').on('click', function () { + if (activeTimeout) { + clearTimeout(activeTimeout); + clearInterval(interval); + } + $("#gameFrame").load("/game/" + qId + "/" + aId); + }); + } } initiateGameCounters(); From 212f5fe06cc3d790c3857af44d89b07c55b4b3b9 Mon Sep 17 00:00:00 2001 From: UO287568 Date: Wed, 17 Apr 2024 15:21:04 +0200 Subject: [PATCH 049/161] =?UTF-8?q?Correcci=C3=B3n=20contador=20y=20barra?= =?UTF-8?q?=20de=20progreso?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/game/fragments/gameFrame.html | 52 +++++++------------ .../templates/game/fragments/stopwatch.html | 10 +++- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/main/resources/templates/game/fragments/gameFrame.html b/src/main/resources/templates/game/fragments/gameFrame.html index e68ffd2a..7833a350 100644 --- a/src/main/resources/templates/game/fragments/gameFrame.html +++ b/src/main/resources/templates/game/fragments/gameFrame.html @@ -35,15 +35,14 @@

    if (!(corrAnswerId == answer.id)) { $("#btn" + answer.id).css("background-color", "red"); } - prueba(questionId, answer.id); + respuesta(questionId, answer.id); }); }); } setupAnswers(); - function prueba(qId, aId) { - + function respuesta(qId, aId) { answers.forEach(answer => { if (corrAnswerId == answer.id) { $("#btn" + answer.id).css("background-color", "green"); @@ -59,8 +58,7 @@

    timeoutId = setTimeout(() => { //$("#gameFrame").load('/game/[[${question.id}]]/-1'); - prueba(questionId, -1); - clearTimeout(timeoutId); + respuesta(questionId, -1); }, timeoutPeriod); initStopwatch(timeoutPeriod / 1000); @@ -87,41 +85,31 @@

    } function initiateTimeout(qId, aId) { - let timeoutPeriod = 8000; // Timeout period in milliseconds (e.g., 8000ms for 8 seconds) - let updateInterval = 100; // How often to update the progress bar (in milliseconds) + if (timeoutId) { + clearTimeout(timeoutId); + clearInterval(interval); + } + timeoutPeriod = 12000; // Timeout period in milliseconds (e.g., 8000ms for 8 seconds) + updateInterval = 100; // How often to update the progress bar (in milliseconds) let progressBar = $('#progressBar'); + progressBar.attr('aria-valuenow', 100); - let activeTimeout = setTimeout(function () { - clearInterval(interval); // Ensure the interval is cleared when the timeout completes - $("#gameFrame").load('/game/update'); - updateQuestionCounter(); + timeoutId = setTimeout(function () { + if (timeoutId) { + clearTimeout(timeoutId); + clearInterval(interval); + } + $("#gameFrame").load("/game/" + qId + "/" + aId); }, timeoutPeriod); + initStopwatch(timeoutPeriod / 1000); timeoutPeriod = timeoutPeriod - updateInterval * 2; // Adjust the timeout period to account for the update interval - let interval = setInterval(updateProgressBar, updateInterval); + interval = setInterval(updateProgressBar, updateInterval); - function updateProgressBar() { - let currentTime = parseFloat(progressBar.attr('aria-valuenow')); - let decrement = 100 * updateInterval / timeoutPeriod; - let newTime = Math.max(0, currentTime - decrement); - - // Calculate the color based on the percentage - let greenValue = Math.round((newTime * 255) / 100); - let redValue = 255 - greenValue; - let color = 'rgb(' + redValue + ',' + greenValue + ',0)'; - - progressBar.css('width', newTime + '%'); - progressBar.css('background-color', color); // Apply the calculated color - progressBar.attr('aria-valuenow', newTime); - - if(newTime <= 0) { - clearInterval(interval); - } - } $("#continueBtn").show(); $("#continueBtn").off('click').on('click', function () { - if (activeTimeout) { - clearTimeout(activeTimeout); + if (timeoutId) { + clearTimeout(timeoutId); clearInterval(interval); } $("#gameFrame").load("/game/" + qId + "/" + aId); diff --git a/src/main/resources/templates/game/fragments/stopwatch.html b/src/main/resources/templates/game/fragments/stopwatch.html index 1282f055..5d51ef9a 100644 --- a/src/main/resources/templates/game/fragments/stopwatch.html +++ b/src/main/resources/templates/game/fragments/stopwatch.html @@ -7,11 +7,19 @@ diff --git a/src/main/resources/templates/ranking/multiplayerRanking_table.html b/src/main/resources/templates/ranking/multiplayerRanking_table.html deleted file mode 100644 index de5e46b9..00000000 --- a/src/main/resources/templates/ranking/multiplayerRanking_table.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - -
    PosiciónJugadorPuntuación
    \ No newline at end of file From 16887719f4936f6f85dc7e2c3fa2d5b6a9f1d45f Mon Sep 17 00:00:00 2001 From: uo287545 Date: Wed, 24 Apr 2024 20:34:01 +0200 Subject: [PATCH 063/161] First version of the base JSON done --- .../static/JSON/QuestionTemplates.json | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/resources/static/JSON/QuestionTemplates.json diff --git a/src/main/resources/static/JSON/QuestionTemplates.json b/src/main/resources/static/JSON/QuestionTemplates.json new file mode 100644 index 00000000..e7c58eed --- /dev/null +++ b/src/main/resources/static/JSON/QuestionTemplates.json @@ -0,0 +1,22 @@ +{ + "language_placeholder": "[LANGUAGE]", + "categories": [ + { + "name": "Geography", + "questions": [ + { + "type": "capital", + "sparqlQuery": "Consulta SPARQL para obtener preguntas sobre fronteras" + }, + { + "type": "border", + "sparqlQuery": "Consulta SPARQL para obtener preguntas sobre fronteras" + }, + { + "type": "continent", + "sparqlQuery": "Consulta SPARQL para obtener preguntas sobre continentes" + } + ] + } + ] +} From 48fe6057a6c3e7dced82a55c7eac4ff8bf50e41c Mon Sep 17 00:00:00 2001 From: uo287545 Date: Wed, 24 Apr 2024 20:37:53 +0200 Subject: [PATCH 064/161] Added statements for the capital question --- .../resources/static/JSON/QuestionTemplates.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/resources/static/JSON/QuestionTemplates.json b/src/main/resources/static/JSON/QuestionTemplates.json index e7c58eed..0fff93f2 100644 --- a/src/main/resources/static/JSON/QuestionTemplates.json +++ b/src/main/resources/static/JSON/QuestionTemplates.json @@ -6,7 +6,21 @@ "questions": [ { "type": "capital", - "sparqlQuery": "Consulta SPARQL para obtener preguntas sobre fronteras" + "statements": [ + { + "language": "es", + "statement": "¿Cuál es la capital de [COUNTRY]?" + }, + { + "language": "en", + "statement": "What is the capital of [COUNTRY]?" + }, + { + "language": "fr", + "statement": "Quelle est la capitale de [COUNTRY]?" + } + ], + "sparqlQuery": "Consulta SPARQL para obtener preguntas sobre capitales" }, { "type": "border", From 147bb7d4c2fa7bec4f72c43568df03948fb1f8ac Mon Sep 17 00:00:00 2001 From: uo288061 Date: Wed, 24 Apr 2024 23:08:36 +0200 Subject: [PATCH 065/161] small changes --- .../com/uniovi/controllers/GameController.java | 7 ++++--- .../resources/templates/game/multiFinished.html | 15 +++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index e5a905d2..53c36810 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -193,10 +193,11 @@ public Map endMultiplayerGameTable(@PathVariable String code) { @GetMapping("/game/lobby/{code}") @ResponseBody public List updatePlayerList(@PathVariable String code) { - List players = playerService.getUsersByMultiplayerCode(Integer.parseInt(code)); + //List players = playerService.getUsersByMultiplayerCode(Integer.parseInt(code)); + Map players= multiplayerSessionService.getPlayersWithScores(Integer.parseInt(code)); List playerNames = new ArrayList<>(); - for (Player player : players) { - playerNames.add(player.getUsername()); + for (Map.Entry player : players.entrySet()) { + playerNames.add(player.getKey().getUsername()); } return playerNames; } diff --git a/src/main/resources/templates/game/multiFinished.html b/src/main/resources/templates/game/multiFinished.html index c3b2d6ff..54fa4c20 100644 --- a/src/main/resources/templates/game/multiFinished.html +++ b/src/main/resources/templates/game/multiFinished.html @@ -6,27 +6,22 @@

    -

    + - -->
    \ No newline at end of file From 0c7930b671d9f84b8ae52b77ee05d847faaa68a7 Mon Sep 17 00:00:00 2001 From: Pelayori <31128562+Pelayori@users.noreply.github.com> Date: Thu, 25 Apr 2024 01:00:53 +0200 Subject: [PATCH 066/161] Add table and dropdown to user management --- .../uniovi/configuration/SecurityConfig.java | 1 + .../uniovi/controllers/PlayersController.java | 22 ++++++++ src/main/java/com/uniovi/entities/Role.java | 5 ++ .../uniovi/repositories/PlayerRepository.java | 4 ++ .../services/InsertSampleDataService.java | 41 +++++++------- .../com/uniovi/services/PlayerService.java | 9 ++++ .../services/impl/PlayerServiceImpl.java | 7 +++ src/main/resources/messages.properties | 14 ++++- src/main/resources/messages_en.properties | 1 + src/main/resources/messages_es.properties | 1 + src/main/resources/messages_fr.properties | 1 + src/main/resources/static/css/admin.css | 22 ++++++++ src/main/resources/static/css/custom.css | 10 ++++ .../resources/templates/fragments/head.html | 2 +- .../templates/fragments/pagination.html | 4 +- .../fragments/paginationDynamic.html | 36 +++++++++++++ .../templates/player/admin/admin.html | 54 +++++++++++++++++++ .../player/admin/questionManagement.html | 1 + .../player/admin/userManagement.html | 30 +++++++++++ src/main/resources/templates/player/home.html | 13 ++--- 20 files changed, 248 insertions(+), 30 deletions(-) create mode 100644 src/main/resources/static/css/admin.css create mode 100644 src/main/resources/templates/fragments/paginationDynamic.html create mode 100644 src/main/resources/templates/player/admin/admin.html create mode 100644 src/main/resources/templates/player/admin/questionManagement.html create mode 100644 src/main/resources/templates/player/admin/userManagement.html diff --git a/src/main/java/com/uniovi/configuration/SecurityConfig.java b/src/main/java/com/uniovi/configuration/SecurityConfig.java index c0af5d20..674cd83f 100644 --- a/src/main/java/com/uniovi/configuration/SecurityConfig.java +++ b/src/main/java/com/uniovi/configuration/SecurityConfig.java @@ -48,6 +48,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/api/**").permitAll() .requestMatchers("/game/**").authenticated() .requestMatchers("/ranking/playerRanking").authenticated() + .requestMatchers("/admin/**").hasAuthority("ROLE_ADMIN") .requestMatchers("/**").permitAll() ).formLogin( form -> form diff --git a/src/main/java/com/uniovi/controllers/PlayersController.java b/src/main/java/com/uniovi/controllers/PlayersController.java index d291b6c6..afbc33c1 100644 --- a/src/main/java/com/uniovi/controllers/PlayersController.java +++ b/src/main/java/com/uniovi/controllers/PlayersController.java @@ -122,4 +122,26 @@ public String showPlayerRanking(Pageable pageable, Model model, Principal princi return "ranking/playerRanking"; } + + // ----- Admin endpoints ----- + + @GetMapping("/player/admin") + public String showAdminPanel(Model model) { + return "player/admin/admin"; + } + + @GetMapping("/player/admin/userManagement") + public String showUserManagementFragment(Model model, Pageable pageable) { + model.addAttribute("endpoint", "/player/admin/userManagement"); + Page users = playerService.getPlayersPage(pageable); + model.addAttribute("page", users); + model.addAttribute("users", users.getContent()); + + return "player/admin/userManagement"; + } + + @GetMapping("/player/admin/questionManagement") + public String showQuestionManagementFragment() { + return "player/admin/questionManagement"; + } } diff --git a/src/main/java/com/uniovi/entities/Role.java b/src/main/java/com/uniovi/entities/Role.java index c767c425..0d4d45c0 100644 --- a/src/main/java/com/uniovi/entities/Role.java +++ b/src/main/java/com/uniovi/entities/Role.java @@ -22,4 +22,9 @@ public class Role { public Role(String name) { this.name = name; } + + @Override + public String toString() { + return name; + } } diff --git a/src/main/java/com/uniovi/repositories/PlayerRepository.java b/src/main/java/com/uniovi/repositories/PlayerRepository.java index 77c2d9f8..cf4f0a98 100644 --- a/src/main/java/com/uniovi/repositories/PlayerRepository.java +++ b/src/main/java/com/uniovi/repositories/PlayerRepository.java @@ -1,9 +1,13 @@ package com.uniovi.repositories; import com.uniovi.entities.Player; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; public interface PlayerRepository extends CrudRepository { Player findByEmail(String email); Player findByUsername(String nickname); + + Page findAll(Pageable pageable); } diff --git a/src/main/java/com/uniovi/services/InsertSampleDataService.java b/src/main/java/com/uniovi/services/InsertSampleDataService.java index f51a0ed8..d5415fc7 100644 --- a/src/main/java/com/uniovi/services/InsertSampleDataService.java +++ b/src/main/java/com/uniovi/services/InsertSampleDataService.java @@ -32,35 +32,36 @@ public class InsertSampleDataService { private final QuestionService questionService; private final CategoryService categoryService; private final QuestionRepository questionRepository; - private final GameSessionRepository gameSessionRepository; - private Environment environment; + private final Environment environment; - private Logger log = LoggerFactory.getLogger(InsertSampleDataService.class); + private final Logger log = LoggerFactory.getLogger(InsertSampleDataService.class); public InsertSampleDataService(PlayerService playerService, QuestionService questionService, CategoryService categoryService, QuestionRepository questionRepository, - GameSessionRepository gameSessionRepository, Environment environment) { + Environment environment) { this.playerService = playerService; this.questionService = questionService; this.categoryService = categoryService; this.questionRepository = questionRepository; - this.gameSessionRepository = gameSessionRepository; this.environment = environment; } @Transactional @EventListener(ApplicationReadyEvent.class) // Uncomment this line to insert sample data on startup public void insertSampleQuestions() throws InterruptedException, IOException { - if (!playerService.getUserByEmail("test@test.com").isPresent()) { + if (playerService.getUserByEmail("test@test.com").isEmpty()) { PlayerDto player = new PlayerDto(); player.setEmail("test@test.com"); player.setUsername("test"); player.setPassword("test"); - player.setRoles(new String[]{"ROLE_USER"}); + if (isProfileActive("prod")) + player.setRoles(new String[]{"ROLE_USER"}); + else + player.setRoles(new String[]{"ROLE_USER", "ROLE_ADMIN"}); playerService.generateApiKey(playerService.addNewPlayer(player)); } - if (Arrays.stream(environment.getActiveProfiles()).anyMatch(env -> (env.equalsIgnoreCase("test")))) { + if (isProfileActive("test")) { log.info("Test profile active, skipping sample data insertion"); return; } @@ -80,29 +81,33 @@ public void generateSampleData() throws InterruptedException, IOException { questionRepository.deleteAll(); MultipleQuestionGenerator allQuestionGenerator = new MultipleQuestionGenerator( - new ContinentQuestionGeneration(categoryService, Question.ENGLISH), - new CapitalQuestionGenerator(categoryService, Question.ENGLISH), - new BorderQuestionGenerator(categoryService, Question.ENGLISH) + //new ContinentQuestionGeneration(categoryService, Question.ENGLISH), + //new CapitalQuestionGenerator(categoryService, Question.ENGLISH), + //new BorderQuestionGenerator(categoryService, Question.ENGLISH) ); List questionsEn = allQuestionGenerator.getQuestions(); questionsEn.forEach(questionService::addNewQuestion); allQuestionGenerator = new MultipleQuestionGenerator( - new ContinentQuestionGeneration(categoryService, Question.SPANISH), - new CapitalQuestionGenerator(categoryService, Question.SPANISH), + //new ContinentQuestionGeneration(categoryService, Question.SPANISH), + //new CapitalQuestionGenerator(categoryService, Question.SPANISH), new BorderQuestionGenerator(categoryService, Question.SPANISH) ); List questionsEs = allQuestionGenerator.getQuestions(); questionsEs.forEach(questionService::addNewQuestion); - allQuestionGenerator = new MultipleQuestionGenerator( - new ContinentQuestionGeneration(categoryService, Question.FRENCH), - new CapitalQuestionGenerator(categoryService, Question.FRENCH), - new BorderQuestionGenerator(categoryService, Question.FRENCH) - ); + //allQuestionGenerator = new MultipleQuestionGenerator( + // new ContinentQuestionGeneration(categoryService, Question.FRENCH), + // new CapitalQuestionGenerator(categoryService, Question.FRENCH), + // new BorderQuestionGenerator(categoryService, Question.FRENCH) + //); List questionsFr = allQuestionGenerator.getQuestions(); questionsFr.forEach(questionService::addNewQuestion); log.info("Sample questions inserted"); } + + public boolean isProfileActive(String profile) { + return Arrays.stream(environment.getActiveProfiles()).anyMatch(env -> (env.equalsIgnoreCase(profile))); + } } diff --git a/src/main/java/com/uniovi/services/PlayerService.java b/src/main/java/com/uniovi/services/PlayerService.java index f59669e3..0cf320a2 100644 --- a/src/main/java/com/uniovi/services/PlayerService.java +++ b/src/main/java/com/uniovi/services/PlayerService.java @@ -4,6 +4,8 @@ import com.uniovi.entities.Player; import com.uniovi.repositories.PlayerRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; @@ -72,4 +74,11 @@ public interface PlayerService { * @param id The id of the player to delete */ void deletePlayer(Long id); + + /** + * Get a page with all the players in the database + * @param pageable The page information + * @return A page with all the players + */ + Page getPlayersPage(Pageable pageable); } diff --git a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java index f4fa462d..d3b868a4 100644 --- a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java @@ -10,6 +10,8 @@ import com.uniovi.services.PlayerService; import com.uniovi.services.RoleService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import com.uniovi.entities.Role; @@ -136,4 +138,9 @@ public void updatePlayer(Long id, PlayerDto playerDto) { public void deletePlayer(Long id) { playerRepository.deleteById(id); } + + @Override + public Page getPlayersPage(Pageable pageable) { + return playerRepository.findAll(pageable); + } } diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 2b91abb1..7130729c 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -13,6 +13,7 @@ navbar.toEnglish=Inglés navbar.toSpanish=Español navbar.toFrench=Francés navbar.currentLanguage=Español +navbar.section.admin=Panel de administración # Buttons for non-authenticated users navbar.signup=Regístrate @@ -114,4 +115,15 @@ game.continue=Siguiente pregunta answer.correct=La respuesta correcta era: game.points=Puntos: game.currentQuestion=Pregunta: -game.finish=El juego ha terminado. Tu puntuación ha sido: \ No newline at end of file +game.finish=El juego ha terminado. Tu puntuación ha sido: + + +# -------------------Statements for the admin section--------------------- +admin.section.user.management=Administración de usuarios +admin.section.question.management=Administración de preguntas +role.label=Roles +user.details=Acciones + +# -------------------Statements for the page management--------------------- +page.first=Primera +page.last=Última \ No newline at end of file diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 97f0f133..901ef79b 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -13,6 +13,7 @@ navbar.toEnglish=English navbar.toSpanish=Spanish navbar.toFrench=French navbar.currentLanguage=English +navbar.section.admin=Administration Section # Buttons for non-authenticated users navbar.signup=Sign Up diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index 174dad48..61bf6b83 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -13,6 +13,7 @@ navbar.toEnglish=Inglés navbar.toSpanish=Español navbar.toFrench=Francés navbar.currentLanguage=Español +navbar.section.admin=Panel de administración # Buttons for non-authenticated users navbar.signup=Regístrate diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index 1f5d2b22..616c23b8 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -12,6 +12,7 @@ navbar.toEnglish=Anglais navbar.toSpanish=Espagnol navbar.toFrench=Français navbar.currentLanguage=Français +navbar.section.admin=Espace administrateur navbar.signup=S'inscrire navbar.login=Se connecter diff --git a/src/main/resources/static/css/admin.css b/src/main/resources/static/css/admin.css new file mode 100644 index 00000000..a797f39b --- /dev/null +++ b/src/main/resources/static/css/admin.css @@ -0,0 +1,22 @@ +.nav .nav-link { + color: white; + border-color: white; +} + +.nav .nav-item { + margin: 0 5px; + flex: 1; +} + +.nav .nav-link.active { + color: black !important; +} + +.nav-tabs { + border-bottom: 0px; +} + +.separator { + border-bottom: 1px solid white; + margin: 10px 0; +} \ No newline at end of file diff --git a/src/main/resources/static/css/custom.css b/src/main/resources/static/css/custom.css index 1499a864..9d7cb489 100644 --- a/src/main/resources/static/css/custom.css +++ b/src/main/resources/static/css/custom.css @@ -66,4 +66,14 @@ footer { .prueba { font-weight: bold; +} + +.button-container { + display: flex; + justify-content: space-between; +} + +.button-container a { + flex: 1; + margin: 0 5px; } \ No newline at end of file diff --git a/src/main/resources/templates/fragments/head.html b/src/main/resources/templates/fragments/head.html index b75eb3c5..77172126 100644 --- a/src/main/resources/templates/fragments/head.html +++ b/src/main/resources/templates/fragments/head.html @@ -14,7 +14,7 @@ crossorigin="anonymous"> - + diff --git a/src/main/resources/templates/fragments/pagination.html b/src/main/resources/templates/fragments/pagination.html index ff816374..3a7fd539 100644 --- a/src/main/resources/templates/fragments/pagination.html +++ b/src/main/resources/templates/fragments/pagination.html @@ -2,7 +2,7 @@
    • - Primera + Primera
    • @@ -22,7 +22,7 @@
    • Última + th:href="@{'?page='+${page.getTotalPages()-1}}" th:text="#{page.last}"> Última
    \ No newline at end of file diff --git a/src/main/resources/templates/fragments/paginationDynamic.html b/src/main/resources/templates/fragments/paginationDynamic.html new file mode 100644 index 00000000..7fb943c9 --- /dev/null +++ b/src/main/resources/templates/fragments/paginationDynamic.html @@ -0,0 +1,36 @@ +
    + + +
    \ No newline at end of file diff --git a/src/main/resources/templates/player/admin/admin.html b/src/main/resources/templates/player/admin/admin.html new file mode 100644 index 00000000..27b2b915 --- /dev/null +++ b/src/main/resources/templates/player/admin/admin.html @@ -0,0 +1,54 @@ + + + + + + + + + + +
    +

    + +
    +
    +
    +
    +
    + + + + diff --git a/src/main/resources/templates/player/admin/questionManagement.html b/src/main/resources/templates/player/admin/questionManagement.html new file mode 100644 index 00000000..1c9b64fb --- /dev/null +++ b/src/main/resources/templates/player/admin/questionManagement.html @@ -0,0 +1 @@ +

    Preguntas

    \ No newline at end of file diff --git a/src/main/resources/templates/player/admin/userManagement.html b/src/main/resources/templates/player/admin/userManagement.html new file mode 100644 index 00000000..0f723162 --- /dev/null +++ b/src/main/resources/templates/player/admin/userManagement.html @@ -0,0 +1,30 @@ +
    +

    +
    + + + + + + + + + + + + + + + + + +
    UsernameEmailRoleActions
    UsernameEmailRole
    +
    +
    +
    \ No newline at end of file diff --git a/src/main/resources/templates/player/home.html b/src/main/resources/templates/player/home.html index abf528c5..9de4e5cb 100644 --- a/src/main/resources/templates/player/home.html +++ b/src/main/resources/templates/player/home.html @@ -8,18 +8,15 @@

    -

    -
    -
    - -
    -
    - -
    + +
    + + +
    From f8374a8815f515b35badd0bb9b5bd195364621e9 Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 01:24:42 +0200 Subject: [PATCH 067/161] Added currency question --- .../static/JSON/QuestionTemplates.json | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/main/resources/static/JSON/QuestionTemplates.json b/src/main/resources/static/JSON/QuestionTemplates.json index 0fff93f2..cb0a2fc3 100644 --- a/src/main/resources/static/JSON/QuestionTemplates.json +++ b/src/main/resources/static/JSON/QuestionTemplates.json @@ -1,5 +1,6 @@ { "language_placeholder": "[LANGUAGE]", + "question_placeholder": "[QUESTION]", "categories": [ { "name": "Geography", @@ -9,26 +10,36 @@ "statements": [ { "language": "es", - "statement": "¿Cuál es la capital de [COUNTRY]?" + "statement": "¿Cuál es la capital de [QUESTION]?" }, { "language": "en", - "statement": "What is the capital of [COUNTRY]?" + "statement": "What is the capital of [QUESTION]?" }, { "language": "fr", - "statement": "Quelle est la capitale de [COUNTRY]?" + "statement": "Quelle est la capitale de [QUESTION]?" } ], - "sparqlQuery": "Consulta SPARQL para obtener preguntas sobre capitales" + "sparqlQuery": "select distinct ?country ?countryLabel ?capital ?capitalLabel where {\n ?country wdt:P31 wd:Q6256 .\n ?capital wdt:P31 wd:Q5119 .\n ?country wdt:P36 ?capital .\n ?country rdfs:label ?countryLabel .\n ?capital rdfs:label ?capitalLabel .\n FILTER(LANG(?countryLabel)=\"[LANGUAGE]\" && LANG(?capitalLabel)=\"[LANGUAGE]\")\n }" }, { - "type": "border", - "sparqlQuery": "Consulta SPARQL para obtener preguntas sobre fronteras" - }, - { - "type": "continent", - "sparqlQuery": "Consulta SPARQL para obtener preguntas sobre continentes" + "type": "currency", + "statements": [ + { + "language": "es", + "statement": "¿Cuál es la moneda de [QUESTION]?" + }, + { + "language": "en", + "statement": "What is the currency of [QUESTION]?" + }, + { + "language": "fr", + "statement": "Quelle est la monnaie de [QUESTION]?" + } + ], + "sparqlQuery": "select distinct ?country ?countryLabel ?currency ?currencyLabel where {\n ?country wdt:P31 wd:Q6256 .\n ?currency wdt:P31 wd:Q8142 .\n ?country wdt:P38 ?currency .\n ?country rdfs:label ?countryLabel .\n ?currency rdfs:label ?currencyLabel .\n FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240} .\n FILTER(LANG(?countryLabel)=\"[LANGUAGE]\" && LANG(?currencyLabel)=\"[LANGUAGE]\")\n }" } ] } From 11f09d33f0d6666d0f27b12e9eaceba4ef1a8cff Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 02:49:41 +0200 Subject: [PATCH 068/161] Initial implementation of the new question generator --- .../generators/QuestionGenerator.java | 4 -- .../generators/QuestionGeneratorV2.java | 48 +++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java diff --git a/src/main/java/com/uniovi/components/generators/QuestionGenerator.java b/src/main/java/com/uniovi/components/generators/QuestionGenerator.java index ccaa4dab..7b552684 100644 --- a/src/main/java/com/uniovi/components/generators/QuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/QuestionGenerator.java @@ -11,8 +11,4 @@ public interface QuestionGenerator { String getQuery(); List getQuestions(); - - Category getCategory(); - - } diff --git a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java new file mode 100644 index 00000000..00287cf7 --- /dev/null +++ b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java @@ -0,0 +1,48 @@ +package com.uniovi.components.generators; + +import com.fasterxml.jackson.databind.JsonNode; +import com.uniovi.entities.Category; +import com.uniovi.entities.Question; + +import java.util.ArrayList; +import java.util.List; + +public class QuestionGeneratorV2 implements QuestionGenerator{ + + private JsonNode jsonNode; + private String language_placeholder; + private String question_placeholder; + private String language; + + public QuestionGeneratorV2(JsonNode jsonNode, String language) { + this.jsonNode = jsonNode; + this.language_placeholder = jsonNode.get("language_placeholder").textValue(); + this.question_placeholder = jsonNode.get("question_placeholder").textValue(); + this.language = language; + } + + @Override + public String getQuery() { + return null; + } + + @Override + public List getQuestions() { + List questions = new ArrayList<>(); + JsonNode categories = jsonNode.findValue("categories"); + for(JsonNode category : categories){ + String categoryName = category.get("name").textValue(); + Category cat = new Category(categoryName); + JsonNode questionsNode = category.findValue("questions"); + for(JsonNode question : questionsNode){ + questions.addAll(this.generateQuestion(question, cat)); + } + } + return questions; + } + + private List generateQuestion(JsonNode question, Category cat) { + String query = question.get("sparqlQuery").textValue(); + query = query.replace(language_placeholder, language); + } +} From e5a6f37607203ecfad6e7e6cde169670b31c6cee Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 03:00:08 +0200 Subject: [PATCH 069/161] First part of the request system --- .../generators/QuestionGeneratorV2.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java index 00287cf7..1ff9cd60 100644 --- a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java +++ b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java @@ -1,9 +1,16 @@ package com.uniovi.components.generators; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.uniovi.entities.Category; import com.uniovi.entities.Question; +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -44,5 +51,53 @@ public List getQuestions() { private List generateQuestion(JsonNode question, Category cat) { String query = question.get("sparqlQuery").textValue(); query = query.replace(language_placeholder, language); + JsonNode results = getQueryResult(query); + + } + + private JsonNode getQueryResult(String query) { + + HttpClient client = HttpClient.newHttpClient(); + try { + + String endpointUrl = "https://query.wikidata.org/sparql?query=" + + URLEncoder.encode(this.getQuery(), StandardCharsets.UTF_8) + + "&format=json"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(endpointUrl)) + .header("Accept", "application/json") + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Process the JSON response using Jackson ObjectMapper + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonResponse = objectMapper.readTree(response.body()); + + // Access the data from the JSON response + JsonNode resultsNode = jsonResponse.path("results").path("bindings"); + + for (JsonNode result : resultsNode) { + + List options = this.generateOptions(resultsNode, result); + String correctAnswer = this.generateCorrectAnswer(result); + String questionStatement = this.getQuestionSubject(result); + + } + } catch (InterruptedException e) { + throw new QuestionGeneratorException("Generation of questions was interrupted"); + } catch (Exception e) { + throw new QuestionGeneratorException("An error occurred while generating questions"); + } + + return questions; + + } + + private static class QuestionGeneratorException extends RuntimeException { + public QuestionGeneratorException(String message) { + super(message); + } } } From 8a8ef292014d9b94140fe9ab62b1dd753800c779 Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 03:13:01 +0200 Subject: [PATCH 070/161] Added question and answer placeholders to the JSON --- src/main/resources/static/JSON/QuestionTemplates.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/resources/static/JSON/QuestionTemplates.json b/src/main/resources/static/JSON/QuestionTemplates.json index cb0a2fc3..29df09ae 100644 --- a/src/main/resources/static/JSON/QuestionTemplates.json +++ b/src/main/resources/static/JSON/QuestionTemplates.json @@ -1,6 +1,7 @@ { "language_placeholder": "[LANGUAGE]", "question_placeholder": "[QUESTION]", + "answer_placeholder": "[ANSWER]", "categories": [ { "name": "Geography", @@ -21,7 +22,9 @@ "statement": "Quelle est la capitale de [QUESTION]?" } ], - "sparqlQuery": "select distinct ?country ?countryLabel ?capital ?capitalLabel where {\n ?country wdt:P31 wd:Q6256 .\n ?capital wdt:P31 wd:Q5119 .\n ?country wdt:P36 ?capital .\n ?country rdfs:label ?countryLabel .\n ?capital rdfs:label ?capitalLabel .\n FILTER(LANG(?countryLabel)=\"[LANGUAGE]\" && LANG(?capitalLabel)=\"[LANGUAGE]\")\n }" + "question": "countryLabel", + "answer": "capitalLabel", + "sparqlQuery": "select distinct ?country ?[QUESTION] ?capital ?[ANSWER] where {\n ?country wdt:P31 wd:Q6256 .\n ?capital wdt:P31 wd:Q5119 .\n ?country wdt:P36 ?capital .\n ?country rdfs:label ?countryLabel .\n ?capital rdfs:label ?capitalLabel .\n FILTER(LANG(?countryLabel)=\"[LANGUAGE]\" && LANG(?capitalLabel)=\"[LANGUAGE]\")\n }" }, { "type": "currency", @@ -39,7 +42,9 @@ "statement": "Quelle est la monnaie de [QUESTION]?" } ], - "sparqlQuery": "select distinct ?country ?countryLabel ?currency ?currencyLabel where {\n ?country wdt:P31 wd:Q6256 .\n ?currency wdt:P31 wd:Q8142 .\n ?country wdt:P38 ?currency .\n ?country rdfs:label ?countryLabel .\n ?currency rdfs:label ?currencyLabel .\n FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240} .\n FILTER(LANG(?countryLabel)=\"[LANGUAGE]\" && LANG(?currencyLabel)=\"[LANGUAGE]\")\n }" + "question": "countryLabel", + "answer": "currencyLabel", + "sparqlQuery": "select distinct ?country ?[QUESTION] ?currency ?[ANSWER] where {\n ?country wdt:P31 wd:Q6256 .\n ?currency wdt:P31 wd:Q8142 .\n ?country wdt:P38 ?currency .\n ?country rdfs:label ?countryLabel .\n ?currency rdfs:label ?currencyLabel .\n FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240} .\n FILTER(LANG(?countryLabel)=\"[LANGUAGE]\" && LANG(?currencyLabel)=\"[LANGUAGE]\")\n }" } ] } From e3191167f0a8955b0166830c2d9f0a62ead50c1d Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 03:30:13 +0200 Subject: [PATCH 071/161] Added statement generation based on language --- .../generators/QuestionGeneratorV2.java | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java index 1ff9cd60..c03e7386 100644 --- a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java +++ b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java @@ -19,12 +19,14 @@ public class QuestionGeneratorV2 implements QuestionGenerator{ private JsonNode jsonNode; private String language_placeholder; private String question_placeholder; + private String answer_placeholder; private String language; public QuestionGeneratorV2(JsonNode jsonNode, String language) { this.jsonNode = jsonNode; this.language_placeholder = jsonNode.get("language_placeholder").textValue(); this.question_placeholder = jsonNode.get("question_placeholder").textValue(); + this.answer_placeholder = jsonNode.get("answer_placeholder").textValue(); this.language = language; } @@ -49,15 +51,47 @@ public List getQuestions() { } private List generateQuestion(JsonNode question, Category cat) { + // Get the SPARQL query from the JSON String query = question.get("sparqlQuery").textValue(); - query = query.replace(language_placeholder, language); + // Replace the placeholders in the query with the actual values + query = query.replace(language_placeholder, language). + replace(question_placeholder, question.get("question").textValue()). + replace(answer_placeholder, question.get("answer").textValue()); + // Execute the query and get the results JsonNode results = getQueryResult(query); + List questions = new ArrayList<>(); + // Prepare the statement base based on the language + String statement = this.prepareStatement(question); + for(JsonNode result : results){ + String statement = result.get("statement").textValue(); + List options = new ArrayList<>(); + for(JsonNode option : result.get("options")){ + options.add(option.textValue()); + } + String correctAnswer = result.get("correctAnswer").textValue(); + this.questionGenerator(statement, options, correctAnswer, cat, questions); + } + } + /** + * Generates a statement based on the language of the question + * @param question The question node + * @return The statement in the language of the question or null if the language is not found + */ + private String prepareStatement(JsonNode question) { + JsonNode statementNode = question.findValue("statements"); + for (JsonNode statement : statementNode) { + if (statement.get("language").textValue().equals(language)) { + return statement.get("statement").textValue(); + } + } + return null; } private JsonNode getQueryResult(String query) { HttpClient client = HttpClient.newHttpClient(); + JsonNode resultsNode; try { String endpointUrl = "https://query.wikidata.org/sparql?query=" + @@ -76,22 +110,15 @@ private JsonNode getQueryResult(String query) { JsonNode jsonResponse = objectMapper.readTree(response.body()); // Access the data from the JSON response - JsonNode resultsNode = jsonResponse.path("results").path("bindings"); - - for (JsonNode result : resultsNode) { - - List options = this.generateOptions(resultsNode, result); - String correctAnswer = this.generateCorrectAnswer(result); - String questionStatement = this.getQuestionSubject(result); + resultsNode = jsonResponse.path("results").path("bindings"); - } } catch (InterruptedException e) { throw new QuestionGeneratorException("Generation of questions was interrupted"); } catch (Exception e) { throw new QuestionGeneratorException("An error occurred while generating questions"); } - return questions; + return resultsNode; } From 28e106839812dece6d79bf4b65b1866ded3e7bb3 Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 03:49:28 +0200 Subject: [PATCH 072/161] First version of the question generator finished --- .../generators/QuestionGeneratorV2.java | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java index c03e7386..8b7d39c8 100644 --- a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java +++ b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.uniovi.entities.Answer; import com.uniovi.entities.Category; import com.uniovi.entities.Question; @@ -53,24 +54,50 @@ public List getQuestions() { private List generateQuestion(JsonNode question, Category cat) { // Get the SPARQL query from the JSON String query = question.get("sparqlQuery").textValue(); + + // Get the question and answer words from the JSON + String questionLabel = question.get("question").textValue(); + String answerLabel= question.get("answer").textValue(); + // Replace the placeholders in the query with the actual values query = query.replace(language_placeholder, language). - replace(question_placeholder, question.get("question").textValue()). - replace(answer_placeholder, question.get("answer").textValue()); + replace(question_placeholder, questionLabel). + replace(answer_placeholder, answerLabel); + // Execute the query and get the results JsonNode results = getQueryResult(query); List questions = new ArrayList<>(); + // Prepare the statement base based on the language String statement = this.prepareStatement(question); - for(JsonNode result : results){ - String statement = result.get("statement").textValue(); - List options = new ArrayList<>(); - for(JsonNode option : result.get("options")){ - options.add(option.textValue()); + + for (JsonNode result : results) { + // Generate the correct answer + String correctAnswer = result.get(answerLabel).textValue(); + Answer correct = new Answer(correctAnswer, true); + + // Generate the options + List options = this.generateOptions(results, correctAnswer, answerLabel); + + + // Generate the question statement + String questionStatement = statement.replace(question_placeholder, result.get(questionLabel).textValue()); + + // Generate the question + questions.add(new Question(questionStatement, options, correct, cat, language)); + } + return questions; + } + + private List generateOptions(JsonNode results, String correctAnswer, String answerLabel) { + List options = new ArrayList<>(); + for (JsonNode result : results) { + String option = result.get(answerLabel).textValue(); + if (!option.equals(correctAnswer)) { + options.add(new Answer(option, false)); } - String correctAnswer = result.get("correctAnswer").textValue(); - this.questionGenerator(statement, options, correctAnswer, cat, questions); } + return options; } /** From b812a5f8af316cb099c7ee2ecef48cf15029af11 Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 03:56:04 +0200 Subject: [PATCH 073/161] Added name only constructor for category --- src/main/java/com/uniovi/entities/Category.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/uniovi/entities/Category.java b/src/main/java/com/uniovi/entities/Category.java index c368e762..dcfa19fc 100644 --- a/src/main/java/com/uniovi/entities/Category.java +++ b/src/main/java/com/uniovi/entities/Category.java @@ -33,6 +33,10 @@ public Category(String name, String description) { this.description = description; } + public Category(String categoryName) { + this.name = categoryName; + } + @Override public String toString() { return name; From a079a2116ad51d048108a370d276349576a0b676 Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 04:19:00 +0200 Subject: [PATCH 074/161] Removed old templates --- .../generators/AbstractQuestionGenerator.java | 97 ------------------- .../generators/art/AbstractArtGenerator.java | 17 ---- .../art/ArtMovementQuestionGenerator.java | 74 -------------- .../art/ArtPeriodQuestionGenerator.java | 74 -------------- .../art/ArtStyleQuestionGenerator.java | 74 -------------- .../art/ArtWorkQuestionGenerator.java | 76 --------------- .../geography/AbstractGeographyGenerator.java | 17 ---- .../geography/AreaQuestionGenerator.java | 52 ---------- .../geography/BorderQuestionGenerator.java | 76 --------------- .../geography/CapitalQuestionGenerator.java | 77 --------------- .../ContinentQuestionGeneration.java | 76 --------------- .../geography/CurrencyQuestionGenerator.java | 76 --------------- .../geography/LanguageQuestionGenerator.java | 76 --------------- .../PopulationQuestionGenerator.java | 52 ---------- .../history/AbstractHistoryGenerator.java | 17 ---- .../HistoricalArtifactQuestionGeneration.java | 75 -------------- .../HistoricalBattleQuestionGeneration.java | 75 -------------- .../HistoricalDynastyQuestionGeneration.java | 75 -------------- .../HistoricalEventQuestionGeneration.java | 75 -------------- ...HistoricalInventionQuestionGeneration.java | 75 -------------- .../HistoricalLeaderQuestionGeneration.java | 75 -------------- .../HistoricalPeriodQuestionGeneration.java | 75 -------------- .../movie/AbstractMovieGenerator.java | 17 ---- .../movie/MovieDirectorQuestionGenerator.java | 75 -------------- .../movie/MovieGenreQuestionGenerator.java | 74 -------------- .../MovieReleaseYearQuestionGenerator.java | 75 -------------- .../movie/OriginalTitleQuestionGenerator.java | 74 -------------- .../science/AbstractScienceGenerator.java | 17 ---- .../MathPhysicsFormulaQuestionGenerator.java | 74 -------------- ...cientificAchievementQuestionGenerator.java | 75 -------------- .../ScientificDiscoveryQuestionGenerator.java | 75 -------------- .../ScientistBirthplaceQuestionGenerator.java | 75 -------------- 32 files changed, 2087 deletions(-) delete mode 100644 src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/art/AbstractArtGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/geography/AbstractGeographyGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/geography/AreaQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/geography/BorderQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/geography/CapitalQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/geography/ContinentQuestionGeneration.java delete mode 100644 src/main/java/com/uniovi/components/generators/geography/CurrencyQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/geography/LanguageQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/geography/PopulationQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/history/AbstractHistoryGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalArtifactQuestionGeneration.java delete mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalBattleQuestionGeneration.java delete mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalDynastyQuestionGeneration.java delete mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalEventQuestionGeneration.java delete mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalInventionQuestionGeneration.java delete mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalLeaderQuestionGeneration.java delete mode 100644 src/main/java/com/uniovi/components/generators/history/HistoricalPeriodQuestionGeneration.java delete mode 100644 src/main/java/com/uniovi/components/generators/movie/AbstractMovieGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/movie/MovieDirectorQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/movie/MovieGenreQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/movie/MovieReleaseYearQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/movie/OriginalTitleQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/science/AbstractScienceGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java delete mode 100644 src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java diff --git a/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java deleted file mode 100644 index 7c534d91..00000000 --- a/src/main/java/com/uniovi/components/generators/AbstractQuestionGenerator.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.uniovi.components.generators; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.uniovi.entities.Answer; -import com.uniovi.entities.Category; -import com.uniovi.entities.Question; -import com.uniovi.services.CategoryService; -import java.net.URI; -import java.net.URLEncoder; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -public abstract class AbstractQuestionGenerator implements QuestionGenerator{ - private List questions = new ArrayList<>(); - protected final CategoryService categoryService; - - protected Random random = new Random(); - - protected String statement; - protected String language; - - protected AbstractQuestionGenerator(CategoryService categoryService) { - this.categoryService = categoryService; - } - - public void questionGenerator(String statement, List options, String correctAnswer, Category category){ - List answers = new ArrayList<>(); - //Generamos las respuestas y las añadimos a la lista - for(String s: options){ - Answer answer = new Answer(s, false); - answers.add(answer); - } - //Generamos la respuesta correcta y la añadimos a la lista - Answer correct = new Answer(correctAnswer, true); - answers.add(correct); - - Question question = new Question(statement, answers, correct, category, language); - question.scrambleOptions(); - questions.add(question); - } - - public List getQuestions() { - HttpClient client = HttpClient.newHttpClient(); - try { - - String endpointUrl = "https://query.wikidata.org/sparql?query=" + - URLEncoder.encode(this.getQuery(), StandardCharsets.UTF_8) + - "&format=json"; - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(endpointUrl)) - .header("Accept", "application/json") - .build(); - - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - - // Process the JSON response using Jackson ObjectMapper - ObjectMapper objectMapper = new ObjectMapper(); - JsonNode jsonResponse = objectMapper.readTree(response.body()); - - // Access the data from the JSON response - JsonNode resultsNode = jsonResponse.path("results").path("bindings"); - - for (JsonNode result : resultsNode) { - - List options = this.generateOptions(resultsNode, result); - String correctAnswer = this.generateCorrectAnswer(result); - String questionStatement = this.getQuestionSubject(result); - questionGenerator(questionStatement, options, correctAnswer, this.getCategory()); - - } - } catch (InterruptedException e) { - throw new QuestionGeneratorException("Generation of questions was interrupted"); - } catch (Exception e) { - throw new QuestionGeneratorException("An error occurred while generating questions"); - } - - return questions; - } - - protected abstract List generateOptions(JsonNode results, JsonNode result); - protected abstract String generateCorrectAnswer(JsonNode result); - - protected abstract String getQuestionSubject(JsonNode result); - - private static class QuestionGeneratorException extends RuntimeException { - public QuestionGeneratorException(String message) { - super(message); - } - } -} diff --git a/src/main/java/com/uniovi/components/generators/art/AbstractArtGenerator.java b/src/main/java/com/uniovi/components/generators/art/AbstractArtGenerator.java deleted file mode 100644 index 8d0999ef..00000000 --- a/src/main/java/com/uniovi/components/generators/art/AbstractArtGenerator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.uniovi.components.generators.art; - -import com.uniovi.components.generators.AbstractQuestionGenerator; -import com.uniovi.entities.Category; -import com.uniovi.services.CategoryService; - -public abstract class AbstractArtGenerator extends AbstractQuestionGenerator { - - protected AbstractArtGenerator(CategoryService categoryService) { - super(categoryService); - } - - @Override - public Category getCategory() { - return categoryService.getCategoryByName("Art"); - } -} diff --git a/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java deleted file mode 100644 index 81fef3cd..00000000 --- a/src/main/java/com/uniovi/components/generators/art/ArtMovementQuestionGenerator.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.uniovi.components.generators.art; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ArtMovementQuestionGenerator extends AbstractArtGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which art movement is associated with "); - put("es", "¿Con qué movimiento artístico se asocia "); - put("fr", "Quel mouvement artistique est associé à "); - } - }; - - public ArtMovementQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?movement ?movementLabel\n" + - "WHERE {" + - " ?movement wdt:P31 wd:Q968159 ." + // Instance of Art movement - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllMovements(JsonNode resultsNode, String correctMovement) { - List allMovements = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String movement = result.path("movementLabel").path("value").asText(); - if (!movement.equals(correctMovement)) { - allMovements.add(movement); - } - } - return allMovements; - } - - private List selectRandomIncorrectMovements(List allMovements, String correctMovement, int count) { - List incorrectMovements = new ArrayList<>(); - while (incorrectMovements.size() < count && allMovements.size() > 0) { - int randomIndex = random.nextInt(allMovements.size()); - String selectedMovement = allMovements.remove(randomIndex); - if (!selectedMovement.equals(correctMovement) && !incorrectMovements.contains(selectedMovement)) { - incorrectMovements.add(selectedMovement); - } - } - return incorrectMovements; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String movementLabel = result.path("movementLabel").path("value").asText(); - return selectRandomIncorrectMovements(getAllMovements(results, movementLabel), movementLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("movementLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("movementLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java deleted file mode 100644 index e005d262..00000000 --- a/src/main/java/com/uniovi/components/generators/art/ArtPeriodQuestionGenerator.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.uniovi.components.generators.art; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ArtPeriodQuestionGenerator extends AbstractArtGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which art period is associated with "); - put("es", "¿Con qué período artístico se asocia "); - put("fr", "Quelle période artistique est associée à "); - } - }; - - public ArtPeriodQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?period ?periodLabel\n" + - "WHERE {" + - " ?period wdt:P31 wd:Q187437 ." + // Instance of Art period - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllPeriods(JsonNode resultsNode, String correctPeriod) { - List allPeriods = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String period = result.path("periodLabel").path("value").asText(); - if (!period.equals(correctPeriod)) { - allPeriods.add(period); - } - } - return allPeriods; - } - - private List selectRandomIncorrectPeriods(List allPeriods, String correctPeriod, int count) { - List incorrectPeriods = new ArrayList<>(); - while (incorrectPeriods.size() < count && allPeriods.size() > 0) { - int randomIndex = random.nextInt(allPeriods.size()); - String selectedPeriod = allPeriods.remove(randomIndex); - if (!selectedPeriod.equals(correctPeriod) && !incorrectPeriods.contains(selectedPeriod)) { - incorrectPeriods.add(selectedPeriod); - } - } - return incorrectPeriods; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String periodLabel = result.path("periodLabel").path("value").asText(); - return selectRandomIncorrectPeriods(getAllPeriods(results, periodLabel), periodLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("periodLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("periodLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java deleted file mode 100644 index e347e643..00000000 --- a/src/main/java/com/uniovi/components/generators/art/ArtStyleQuestionGenerator.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.uniovi.components.generators.art; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ArtStyleQuestionGenerator extends AbstractArtGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which art style is associated with "); - put("es", "¿Con qué estilo artístico se asocia "); - put("fr", "Quel style artistique est associé à "); - } - }; - - public ArtStyleQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?style ?styleLabel\n" + - "WHERE {" + - " ?style wdt:P31 wd:Q179337 ." + // Instance of Art style - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllStyles(JsonNode resultsNode, String correctStyle) { - List allStyles = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String style = result.path("styleLabel").path("value").asText(); - if (!style.equals(correctStyle)) { - allStyles.add(style); - } - } - return allStyles; - } - - private List selectRandomIncorrectStyles(List allStyles, String correctStyle, int count) { - List incorrectStyles = new ArrayList<>(); - while (incorrectStyles.size() < count && allStyles.size() > 0) { - int randomIndex = random.nextInt(allStyles.size()); - String selectedStyle = allStyles.remove(randomIndex); - if (!selectedStyle.equals(correctStyle) && !incorrectStyles.contains(selectedStyle)) { - incorrectStyles.add(selectedStyle); - } - } - return incorrectStyles; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String styleLabel = result.path("styleLabel").path("value").asText(); - return selectRandomIncorrectStyles(getAllStyles(results, styleLabel), styleLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("styleLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("styleLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java deleted file mode 100644 index 68f95d23..00000000 --- a/src/main/java/com/uniovi/components/generators/art/ArtWorkQuestionGenerator.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.uniovi.components.generators.art; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ArtWorkQuestionGenerator extends AbstractArtGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Who created the artwork "); - put("es", "¿Quién creó la obra de arte "); - put("fr", "Qui a créé l'œuvre d'art "); - } - }; - - public ArtWorkQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?artist ?artistLabel ?artwork ?artworkLabel\n" + - "WHERE {" + - " ?artist wdt:P31 wd:Q5 ." + // Instance of Human - " ?artwork wdt:P31 wd:Q3305213 ." + // Instance of Artwork - " ?artwork wdt:P170 ?artist ." + // Creator - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllArtworks(JsonNode resultsNode, String correctArtwork) { - List allArtworks = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String artwork = result.path("artworkLabel").path("value").asText(); - if (!artwork.equals(correctArtwork)) { - allArtworks.add(artwork); - } - } - return allArtworks; - } - - private List selectRandomIncorrectArtworks(List allArtworks, String correctArtwork, int count) { - List incorrectArtworks = new ArrayList<>(); - while (incorrectArtworks.size() < count && allArtworks.size() > 0) { - int randomIndex = random.nextInt(allArtworks.size()); - String selectedArtwork = allArtworks.remove(randomIndex); - if (!selectedArtwork.equals(correctArtwork) && !incorrectArtworks.contains(selectedArtwork)) { - incorrectArtworks.add(selectedArtwork); - } - } - return incorrectArtworks; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String artworkLabel = result.path("artworkLabel").path("value").asText(); - return selectRandomIncorrectArtworks(getAllArtworks(results, artworkLabel), artworkLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("artistLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("artworkLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/geography/AbstractGeographyGenerator.java b/src/main/java/com/uniovi/components/generators/geography/AbstractGeographyGenerator.java deleted file mode 100644 index d01919e9..00000000 --- a/src/main/java/com/uniovi/components/generators/geography/AbstractGeographyGenerator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.uniovi.components.generators.geography; - -import com.uniovi.components.generators.AbstractQuestionGenerator; -import com.uniovi.entities.Category; -import com.uniovi.services.CategoryService; - -public abstract class AbstractGeographyGenerator extends AbstractQuestionGenerator { - - protected AbstractGeographyGenerator(CategoryService categoryService) { - super(categoryService); - } - - @Override - public Category getCategory() { - return categoryService.getCategoryByName("Geography"); - } -} diff --git a/src/main/java/com/uniovi/components/generators/geography/AreaQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/AreaQuestionGenerator.java deleted file mode 100644 index d69d2edd..00000000 --- a/src/main/java/com/uniovi/components/generators/geography/AreaQuestionGenerator.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.uniovi.components.generators.geography; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.*; - -public class AreaQuestionGenerator extends AbstractGeographyGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "What is the area of "); - put("es", "¿Cuál es el área de "); - put("fr", "Quelle est la superficie de "); - } - }; - - public AreaQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?country ?countryLabel ?area\n" + - "WHERE {" + - " ?country wdt:P31 wd:Q3624078 ." + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + - " ?country wdt:P2046 ?area ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - // Este generador de preguntas no necesita opciones, ya que la respuesta correcta es el área. - return Collections.emptyList(); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("area").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("countryLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/geography/BorderQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/BorderQuestionGenerator.java deleted file mode 100644 index 81d5cdb0..00000000 --- a/src/main/java/com/uniovi/components/generators/geography/BorderQuestionGenerator.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.uniovi.components.generators.geography; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; - -import java.util.*; - -public class BorderQuestionGenerator extends AbstractGeographyGenerator{ - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which countries share a border with "); - put("es", "¿Con qué países comparte frontera "); - put("fr", "Avec quels pays partage-t-il une frontière "); - } - }; - private Set usedCountries = new HashSet<>(); - - public BorderQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - private List getAllBorderingCountries(JsonNode resultsNode, String correctCountry) { - List allBorderingCountries = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String borderingCountry = result.path("borderingCountryLabel").path("value").asText(); - if (!borderingCountry.equals(correctCountry)) { - allBorderingCountries.add(borderingCountry); - } - } - return allBorderingCountries; - } - - private List selectRandomIncorrectBorderingCountries(List allBorderingCountries, String correctCountry, int count) { - List incorrectBorderingCountries = new ArrayList<>(); - while (incorrectBorderingCountries.size() < count && allBorderingCountries.size() > 0) { - int randomIndex = random.nextInt(allBorderingCountries.size()); - String selectedBorderingCountry = allBorderingCountries.remove(randomIndex); - if (!selectedBorderingCountry.equals(correctCountry) && !incorrectBorderingCountries.contains(selectedBorderingCountry)) { - incorrectBorderingCountries.add(selectedBorderingCountry); - } - } - return incorrectBorderingCountries; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String borderingCountryLabel = result.path("borderingCountryLabel").path("value").asText(); - return selectRandomIncorrectBorderingCountries( - getAllBorderingCountries(results, borderingCountryLabel), - borderingCountryLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("borderingCountryLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("countryLabel").path("value").asText() + "?"; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?country ?countryLabel ?borderingCountry ?borderingCountryLabel\n" + - "WHERE {" + - " ?country wdt:P31 wd:Q3624078 ." + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + - " ?country wdt:P47 ?borderingCountry ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/geography/CapitalQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/CapitalQuestionGenerator.java deleted file mode 100644 index 199d4dc5..00000000 --- a/src/main/java/com/uniovi/components/generators/geography/CapitalQuestionGenerator.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.uniovi.components.generators.geography; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.*; - -public class CapitalQuestionGenerator extends AbstractGeographyGenerator{ - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "What is the capital of "); - put("es", "¿Cuál es la capital de "); - put("fr", "Quelle est la capitale de "); - } - }; - - public CapitalQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?country ?countryLabel ?capital ?capitalLabel\n" + - "WHERE {" + - " ?country wdt:P31 wd:Q3624078 ." + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + - " OPTIONAL { ?country wdt:P36 ?capital } ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}" + - "ORDER BY ?countryLabel"; - } - - private List getAllCapitals(JsonNode resultsNode, String correctCapital) { - // Obtener todas las capitales del JSON (distintas a la capital correcta) - List allCapitals = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String capital = result.path("capitalLabel").path("value").asText(); - if (!capital.equals(correctCapital)) { - allCapitals.add(capital); - } - } - return allCapitals; - } - - private List selectRandomIncorrectCapitals(List allCapitals, String correctCapital, int count) { - List incorrectCapitals = new ArrayList<>(); - while (incorrectCapitals.size() < count && allCapitals.size() > 0) { - int randomIndex = random.nextInt(allCapitals.size()); - String selectedCapital = allCapitals.remove(randomIndex); - if (!selectedCapital.equals(correctCapital) && !incorrectCapitals.contains(selectedCapital)) { - incorrectCapitals.add(selectedCapital); - } - } - return incorrectCapitals; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String capitalLabel = result.path("capitalLabel").path("value").asText(); - return selectRandomIncorrectCapitals(getAllCapitals(results, capitalLabel), capitalLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("capitalLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("countryLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/geography/ContinentQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/geography/ContinentQuestionGeneration.java deleted file mode 100644 index dec77dc0..00000000 --- a/src/main/java/com/uniovi/components/generators/geography/ContinentQuestionGeneration.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.uniovi.components.generators.geography; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.scheduling.annotation.Scheduled; - -import java.util.*; - -public class ContinentQuestionGeneration extends AbstractGeographyGenerator{ - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "In which continent is "); - put("es", "¿En qué continente se encuentra "); - put("fr", "Sur quel continent est-il situé "); - } - }; - - public ContinentQuestionGeneration(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - private List getAllContinents(JsonNode resultsNode, String correctContinent) { - // Obtener todas las capitales del JSON (distintas a la capital correcta) - List allContinents = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String continent = result.path("continentLabel").path("value").asText(); - if (!continent.equals(correctContinent)) { - allContinents.add(continent); - } - } - return allContinents; - } - - private List selectRandomIncorrectContinents(List allContinents, String correctContinent, int count) { - List incorrectContinents = new ArrayList<>(); - while (incorrectContinents.size() < count && allContinents.size() > 0) { - int randomIndex = random.nextInt(allContinents.size()); - String selectedCapital = allContinents.remove(randomIndex); - if (!selectedCapital.equals(correctContinent) && !incorrectContinents.contains(selectedCapital)) { - incorrectContinents.add(selectedCapital); - } - } - return incorrectContinents; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String continentLabel = result.path("continentLabel").path("value").asText(); - return selectRandomIncorrectContinents(getAllContinents(results, continentLabel), continentLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("continentLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("countryLabel").path("value").asText() + "?"; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?country ?countryLabel ?continent ?continentLabel\n" + - "WHERE {" + - " ?country wdt:P31 wd:Q3624078 " + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + - " OPTIONAL { ?country wdt:P30 ?continent } ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}" + - "ORDER BY ?countryLabel"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/geography/CurrencyQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/CurrencyQuestionGenerator.java deleted file mode 100644 index 14bda93f..00000000 --- a/src/main/java/com/uniovi/components/generators/geography/CurrencyQuestionGenerator.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.uniovi.components.generators.geography; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.*; - -public class CurrencyQuestionGenerator extends AbstractGeographyGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "What is the currency of "); - put("es", "¿Cuál es la moneda de "); - put("fr", "Quelle est la monnaie de "); - } - }; - - public CurrencyQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?country ?countryLabel ?currency ?currencyLabel\n" + - "WHERE {" + - " ?country wdt:P31 wd:Q3624078 ." + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + - " ?country wdt:P38 ?currency ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllCurrencies(JsonNode resultsNode, String correctCurrency) { - // Obtener todas las monedas del JSON (distintas a la moneda correcta) - List allCurrencies = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String currency = result.path("currencyLabel").path("value").asText(); - if (!currency.equals(correctCurrency)) { - allCurrencies.add(currency); - } - } - return allCurrencies; - } - - private List selectRandomIncorrectCurrencies(List allCurrencies, String correctCurrency, int count) { - List incorrectCurrencies = new ArrayList<>(); - while (incorrectCurrencies.size() < count && allCurrencies.size() > 0) { - int randomIndex = random.nextInt(allCurrencies.size()); - String selectedCurrency = allCurrencies.remove(randomIndex); - if (!selectedCurrency.equals(correctCurrency) && !incorrectCurrencies.contains(selectedCurrency)) { - incorrectCurrencies.add(selectedCurrency); - } - } - return incorrectCurrencies; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String currencyLabel = result.path("currencyLabel").path("value").asText(); - return selectRandomIncorrectCurrencies(getAllCurrencies(results, currencyLabel), currencyLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("currencyLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("countryLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/geography/LanguageQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/LanguageQuestionGenerator.java deleted file mode 100644 index b1bf363a..00000000 --- a/src/main/java/com/uniovi/components/generators/geography/LanguageQuestionGenerator.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.uniovi.components.generators.geography; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.*; - -public class LanguageQuestionGenerator extends AbstractGeographyGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "What is the official language of "); - put("es", "¿Cuál es el idioma oficial de "); - put("fr", "Quelle est la langue officielle de "); - } - }; - - public LanguageQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?country ?countryLabel ?language ?languageLabel\n" + - "WHERE {" + - " ?country wdt:P31 wd:Q3624078 ." + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + - " ?country wdt:P37 ?language ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllLanguages(JsonNode resultsNode, String correctLanguage) { - // Obtener todos los idiomas del JSON (distintos al idioma correcto) - List allLanguages = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String language = result.path("languageLabel").path("value").asText(); - if (!language.equals(correctLanguage)) { - allLanguages.add(language); - } - } - return allLanguages; - } - - private List selectRandomIncorrectLanguages(List allLanguages, String correctLanguage, int count) { - List incorrectLanguages = new ArrayList<>(); - while (incorrectLanguages.size() < count && allLanguages.size() > 0) { - int randomIndex = random.nextInt(allLanguages.size()); - String selectedLanguage = allLanguages.remove(randomIndex); - if (!selectedLanguage.equals(correctLanguage) && !incorrectLanguages.contains(selectedLanguage)) { - incorrectLanguages.add(selectedLanguage); - } - } - return incorrectLanguages; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String languageLabel = result.path("languageLabel").path("value").asText(); - return selectRandomIncorrectLanguages(getAllLanguages(results, languageLabel), languageLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("languageLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("countryLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/geography/PopulationQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/geography/PopulationQuestionGenerator.java deleted file mode 100644 index e0df4901..00000000 --- a/src/main/java/com/uniovi/components/generators/geography/PopulationQuestionGenerator.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.uniovi.components.generators.geography; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.*; - -public class PopulationQuestionGenerator extends AbstractGeographyGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "What is the population of "); - put("es", "¿Cuál es la población de "); - put("fr", "Quelle est la population de "); - } - }; - - public PopulationQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?country ?countryLabel ?population\n" + - "WHERE {" + - " ?country wdt:P31 wd:Q3624078 ." + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240}" + - " FILTER NOT EXISTS {?country wdt:P31 wd:Q28171280}" + - " ?country wdt:P1082 ?population ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - // Este generador de preguntas no necesita opciones, ya que la respuesta correcta es la población. - return Collections.emptyList(); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("population").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("countryLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/history/AbstractHistoryGenerator.java b/src/main/java/com/uniovi/components/generators/history/AbstractHistoryGenerator.java deleted file mode 100644 index da8d870b..00000000 --- a/src/main/java/com/uniovi/components/generators/history/AbstractHistoryGenerator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.uniovi.components.generators.history; - -import com.uniovi.components.generators.AbstractQuestionGenerator; -import com.uniovi.entities.Category; -import com.uniovi.services.CategoryService; - -public abstract class AbstractHistoryGenerator extends AbstractQuestionGenerator { - - protected AbstractHistoryGenerator(CategoryService categoryService) { - super(categoryService); - } - - @Override - public Category getCategory() { - return categoryService.getCategoryByName("History"); - } -} diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalArtifactQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalArtifactQuestionGeneration.java deleted file mode 100644 index 0bb30abf..00000000 --- a/src/main/java/com/uniovi/components/generators/history/HistoricalArtifactQuestionGeneration.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.history; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.scheduling.annotation.Scheduled; - -import java.util.*; - -public class HistoricalArtifactQuestionGeneration extends AbstractHistoryGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which historical artifact is associated with "); - put("es", "¿Con qué artefacto histórico se asocia "); - put("fr", "Quel artefact historique est associé à "); - } - }; - - public HistoricalArtifactQuestionGeneration(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - private List getAllArtifacts(JsonNode resultsNode, String correctArtifact) { - // Obtaining all historical artifacts from the JSON (different from the correct artifact) - List allArtifacts = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String artifact = result.path("artifactLabel").path("value").asText(); - if (!artifact.equals(correctArtifact)) { - allArtifacts.add(artifact); - } - } - return allArtifacts; - } - - private List selectRandomIncorrectArtifacts(List allArtifacts, String correctArtifact, int count) { - List incorrectArtifacts = new ArrayList<>(); - while (incorrectArtifacts.size() < count && allArtifacts.size() > 0) { - int randomIndex = random.nextInt(allArtifacts.size()); - String selectedArtifact = allArtifacts.remove(randomIndex); - if (!selectedArtifact.equals(correctArtifact) && !incorrectArtifacts.contains(selectedArtifact)) { - incorrectArtifacts.add(selectedArtifact); - } - } - return incorrectArtifacts; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String artifactLabel = result.path("artifactLabel").path("value").asText(); - return selectRandomIncorrectArtifacts(getAllArtifacts(results, artifactLabel), artifactLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("artifactLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?artifact ?artifactLabel ?historicalEvent ?historicalEventLabel\n" + - "WHERE {" + - " ?artifact wdt:P31 wd:Q5314 ." + - " ?historicalEvent wdt:P31 wd:Q198 ." + - " OPTIONAL { ?artifact wdt:P1080 ?historicalEvent } ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}" + - "ORDER BY ?artifactLabel"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalBattleQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalBattleQuestionGeneration.java deleted file mode 100644 index 5c83c79c..00000000 --- a/src/main/java/com/uniovi/components/generators/history/HistoricalBattleQuestionGeneration.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.history; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.scheduling.annotation.Scheduled; - -import java.util.*; - -public class HistoricalBattleQuestionGeneration extends AbstractHistoryGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which historical battle is associated with "); - put("es", "¿Con qué batalla histórica se asocia "); - put("fr", "Quelle bataille historique est associée à "); - } - }; - - public HistoricalBattleQuestionGeneration(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - private List getAllBattles(JsonNode resultsNode, String correctBattle) { - // Obtaining all historical battles from the JSON (different from the correct battle) - List allBattles = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String battle = result.path("battleLabel").path("value").asText(); - if (!battle.equals(correctBattle)) { - allBattles.add(battle); - } - } - return allBattles; - } - - private List selectRandomIncorrectBattles(List allBattles, String correctBattle, int count) { - List incorrectBattles = new ArrayList<>(); - while (incorrectBattles.size() < count && allBattles.size() > 0) { - int randomIndex = random.nextInt(allBattles.size()); - String selectedBattle = allBattles.remove(randomIndex); - if (!selectedBattle.equals(correctBattle) && !incorrectBattles.contains(selectedBattle)) { - incorrectBattles.add(selectedBattle); - } - } - return incorrectBattles; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String battleLabel = result.path("battleLabel").path("value").asText(); - return selectRandomIncorrectBattles(getAllBattles(results, battleLabel), battleLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("battleLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?battle ?battleLabel ?historicalEvent ?historicalEventLabel\n" + - "WHERE {" + - " ?battle wdt:P31 wd:Q178561 ." + - " ?historicalEvent wdt:P31 wd:Q198 ." + - " OPTIONAL { ?battle wdt:P361 ?historicalEvent } ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}" + - "ORDER BY ?battleLabel"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalDynastyQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalDynastyQuestionGeneration.java deleted file mode 100644 index 7f65f88e..00000000 --- a/src/main/java/com/uniovi/components/generators/history/HistoricalDynastyQuestionGeneration.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.history; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.scheduling.annotation.Scheduled; - -import java.util.*; - -public class HistoricalDynastyQuestionGeneration extends AbstractHistoryGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which historical dynasty is associated with "); - put("es", "¿Con qué dinastía histórica se asocia "); - put("fr", "Quelle dynastie historique est associée à "); - } - }; - - public HistoricalDynastyQuestionGeneration(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - private List getAllDynasties(JsonNode resultsNode, String correctDynasty) { - // Obtaining all historical dynasties from the JSON (different from the correct dynasty) - List allDynasties = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String dynasty = result.path("dynastyLabel").path("value").asText(); - if (!dynasty.equals(correctDynasty)) { - allDynasties.add(dynasty); - } - } - return allDynasties; - } - - private List selectRandomIncorrectDynasties(List allDynasties, String correctDynasty, int count) { - List incorrectDynasties = new ArrayList<>(); - while (incorrectDynasties.size() < count && allDynasties.size() > 0) { - int randomIndex = random.nextInt(allDynasties.size()); - String selectedDynasty = allDynasties.remove(randomIndex); - if (!selectedDynasty.equals(correctDynasty) && !incorrectDynasties.contains(selectedDynasty)) { - incorrectDynasties.add(selectedDynasty); - } - } - return incorrectDynasties; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String dynastyLabel = result.path("dynastyLabel").path("value").asText(); - return selectRandomIncorrectDynasties(getAllDynasties(results, dynastyLabel), dynastyLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("dynastyLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?dynasty ?dynastyLabel ?historicalEvent ?historicalEventLabel\n" + - "WHERE {" + - " ?dynasty wdt:P31 wd:Q11410 ." + - " ?historicalEvent wdt:P31 wd:Q198 ." + - " OPTIONAL { ?dynasty wdt:P108 ?historicalEvent } ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}" + - "ORDER BY ?dynastyLabel"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalEventQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalEventQuestionGeneration.java deleted file mode 100644 index cede3058..00000000 --- a/src/main/java/com/uniovi/components/generators/history/HistoricalEventQuestionGeneration.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.history; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.scheduling.annotation.Scheduled; - -import java.util.*; - -public class HistoricalEventQuestionGeneration extends AbstractHistoryGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "In what historical event did "); - put("es", "¿En qué evento histórico participó "); - put("fr", "Dans quel événement historique a participé "); - } - }; - - public HistoricalEventQuestionGeneration(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - private List getAllEvents(JsonNode resultsNode, String correctEvent) { - // Obtener todos los eventos históricos del JSON (diferentes al evento correcto) - List allEvents = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String event = result.path("eventLabel").path("value").asText(); - if (!event.equals(correctEvent)) { - allEvents.add(event); - } - } - return allEvents; - } - - private List selectRandomIncorrectEvents(List allEvents, String correctEvent, int count) { - List incorrectEvents = new ArrayList<>(); - while (incorrectEvents.size() < count && allEvents.size() > 0) { - int randomIndex = random.nextInt(allEvents.size()); - String selectedEvent = allEvents.remove(randomIndex); - if (!selectedEvent.equals(correctEvent) && !incorrectEvents.contains(selectedEvent)) { - incorrectEvents.add(selectedEvent); - } - } - return incorrectEvents; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String eventLabel = result.path("eventLabel").path("value").asText(); - return selectRandomIncorrectEvents(getAllEvents(results, eventLabel), eventLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("eventLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("personLabel").path("value").asText() + "?"; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?person ?personLabel ?event ?eventLabel\n" + - "WHERE {" + - " ?person wdt:P31 wd:Q5 ." + - " ?event wdt:P31 wd:Q198 ." + - " OPTIONAL { ?person wdt:P106 ?event } ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}" + - "ORDER BY ?personLabel"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalInventionQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalInventionQuestionGeneration.java deleted file mode 100644 index 01af421d..00000000 --- a/src/main/java/com/uniovi/components/generators/history/HistoricalInventionQuestionGeneration.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.history; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.scheduling.annotation.Scheduled; - -import java.util.*; - -public class HistoricalInventionQuestionGeneration extends AbstractHistoryGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which historical invention is associated with "); - put("es", "¿Con qué invención histórica se asocia "); - put("fr", "Quelle invention historique est associée à "); - } - }; - - public HistoricalInventionQuestionGeneration(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - private List getAllInventions(JsonNode resultsNode, String correctInvention) { - // Obtaining all historical inventions from the JSON (different from the correct invention) - List allInventions = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String invention = result.path("inventionLabel").path("value").asText(); - if (!invention.equals(correctInvention)) { - allInventions.add(invention); - } - } - return allInventions; - } - - private List selectRandomIncorrectInventions(List allInventions, String correctInvention, int count) { - List incorrectInventions = new ArrayList<>(); - while (incorrectInventions.size() < count && allInventions.size() > 0) { - int randomIndex = random.nextInt(allInventions.size()); - String selectedInvention = allInventions.remove(randomIndex); - if (!selectedInvention.equals(correctInvention) && !incorrectInventions.contains(selectedInvention)) { - incorrectInventions.add(selectedInvention); - } - } - return incorrectInventions; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String inventionLabel = result.path("inventionLabel").path("value").asText(); - return selectRandomIncorrectInventions(getAllInventions(results, inventionLabel), inventionLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("inventionLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?invention ?inventionLabel ?historicalEvent ?historicalEventLabel\n" + - "WHERE {" + - " ?invention wdt:P31 wd:Q39614 ." + - " ?historicalEvent wdt:P31 wd:Q198 ." + - " OPTIONAL { ?invention wdt:P921 ?historicalEvent } ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}" + - "ORDER BY ?inventionLabel"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalLeaderQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalLeaderQuestionGeneration.java deleted file mode 100644 index 17cce194..00000000 --- a/src/main/java/com/uniovi/components/generators/history/HistoricalLeaderQuestionGeneration.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.history; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.scheduling.annotation.Scheduled; - -import java.util.*; - -public class HistoricalLeaderQuestionGeneration extends AbstractHistoryGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which historical leader is associated with "); - put("es", "¿Con qué líder histórico se asocia "); - put("fr", "Quel leader historique est associé à "); - } - }; - - public HistoricalLeaderQuestionGeneration(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - private List getAllLeaders(JsonNode resultsNode, String correctLeader) { - // Obtaining all historical leaders from the JSON (different from the correct leader) - List allLeaders = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String leader = result.path("leaderLabel").path("value").asText(); - if (!leader.equals(correctLeader)) { - allLeaders.add(leader); - } - } - return allLeaders; - } - - private List selectRandomIncorrectLeaders(List allLeaders, String correctLeader, int count) { - List incorrectLeaders = new ArrayList<>(); - while (incorrectLeaders.size() < count && allLeaders.size() > 0) { - int randomIndex = random.nextInt(allLeaders.size()); - String selectedLeader = allLeaders.remove(randomIndex); - if (!selectedLeader.equals(correctLeader) && !incorrectLeaders.contains(selectedLeader)) { - incorrectLeaders.add(selectedLeader); - } - } - return incorrectLeaders; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String leaderLabel = result.path("leaderLabel").path("value").asText(); - return selectRandomIncorrectLeaders(getAllLeaders(results, leaderLabel), leaderLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("leaderLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?leader ?leaderLabel ?historicalEvent ?historicalEventLabel\n" + - "WHERE {" + - " ?leader wdt:P31 wd:Q5 ." + - " ?historicalEvent wdt:P31 wd:Q198 ." + - " OPTIONAL { ?leader wdt:P6 ?historicalEvent } ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}" + - "ORDER BY ?leaderLabel"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/history/HistoricalPeriodQuestionGeneration.java b/src/main/java/com/uniovi/components/generators/history/HistoricalPeriodQuestionGeneration.java deleted file mode 100644 index b1a7f81c..00000000 --- a/src/main/java/com/uniovi/components/generators/history/HistoricalPeriodQuestionGeneration.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.history; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.scheduling.annotation.Scheduled; - -import java.util.*; - -public class HistoricalPeriodQuestionGeneration extends AbstractHistoryGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which historical period is associated with "); - put("es", "¿Con qué período histórico se asocia "); - put("fr", "Quelle période historique est associée à "); - } - }; - - public HistoricalPeriodQuestionGeneration(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - private List getAllPeriods(JsonNode resultsNode, String correctPeriod) { - // Obtaining all historical periods from the JSON (different from the correct period) - List allPeriods = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String period = result.path("periodLabel").path("value").asText(); - if (!period.equals(correctPeriod)) { - allPeriods.add(period); - } - } - return allPeriods; - } - - private List selectRandomIncorrectPeriods(List allPeriods, String correctPeriod, int count) { - List incorrectPeriods = new ArrayList<>(); - while (incorrectPeriods.size() < count && allPeriods.size() > 0) { - int randomIndex = random.nextInt(allPeriods.size()); - String selectedPeriod = allPeriods.remove(randomIndex); - if (!selectedPeriod.equals(correctPeriod) && !incorrectPeriods.contains(selectedPeriod)) { - incorrectPeriods.add(selectedPeriod); - } - } - return incorrectPeriods; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String periodLabel = result.path("periodLabel").path("value").asText(); - return selectRandomIncorrectPeriods(getAllPeriods(results, periodLabel), periodLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("periodLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("historicalEventLabel").path("value").asText() + "?"; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?period ?periodLabel ?historicalEvent ?historicalEventLabel\n" + - "WHERE {" + - " ?period wdt:P31 wd:Q186067 ." + - " ?historicalEvent wdt:P31 wd:Q198 ." + - " OPTIONAL { ?period wdt:P155 ?historicalEvent } ." + - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}" + - "ORDER BY ?periodLabel"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/movie/AbstractMovieGenerator.java b/src/main/java/com/uniovi/components/generators/movie/AbstractMovieGenerator.java deleted file mode 100644 index 89eb2bef..00000000 --- a/src/main/java/com/uniovi/components/generators/movie/AbstractMovieGenerator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.uniovi.components.generators.movie; - -import com.uniovi.components.generators.AbstractQuestionGenerator; -import com.uniovi.entities.Category; -import com.uniovi.services.CategoryService; - -public abstract class AbstractMovieGenerator extends AbstractQuestionGenerator { - - protected AbstractMovieGenerator(CategoryService categoryService) { - super(categoryService); - } - - @Override - public Category getCategory() { - return categoryService.getCategoryByName("Movie"); - } -} diff --git a/src/main/java/com/uniovi/components/generators/movie/MovieDirectorQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/movie/MovieDirectorQuestionGenerator.java deleted file mode 100644 index 35cd2ab2..00000000 --- a/src/main/java/com/uniovi/components/generators/movie/MovieDirectorQuestionGenerator.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.movie; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class MovieDirectorQuestionGenerator extends AbstractMovieGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Who directed the movie "); - put("es", "¿Quién dirigió la película "); - put("fr", "Qui a dirigé le film "); - } - }; - - public MovieDirectorQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?director ?directorLabel ?movie ?movieLabel\n" + - "WHERE {" + - " ?director wdt:P31 wd:Q5 ." + // Instance of Human - " ?movie wdt:P31 wd:Q11424 ." + // Instance of Film - " ?movie wdt:P57 ?director ." + // Director - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllMovies(JsonNode resultsNode, String correctMovie) { - List allMovies = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String movie = result.path("movieLabel").path("value").asText(); - if (!movie.equals(correctMovie)) { - allMovies.add(movie); - } - } - return allMovies; - } - - private List selectRandomIncorrectMovies(List allMovies, String correctMovie, int count) { - List incorrectMovies = new ArrayList<>(); - while (incorrectMovies.size() < count && allMovies.size() > 0) { - int randomIndex = random.nextInt(allMovies.size()); - String selectedMovie = allMovies.remove(randomIndex); - if (!selectedMovie.equals(correctMovie) && !incorrectMovies.contains(selectedMovie)) { - incorrectMovies.add(selectedMovie); - } - } - return incorrectMovies; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String movieLabel = result.path("movieLabel").path("value").asText(); - return selectRandomIncorrectMovies(getAllMovies(results, movieLabel), movieLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("directorLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("movieLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/movie/MovieGenreQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/movie/MovieGenreQuestionGenerator.java deleted file mode 100644 index 8da6a045..00000000 --- a/src/main/java/com/uniovi/components/generators/movie/MovieGenreQuestionGenerator.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.uniovi.components.generators.movie; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class MovieGenreQuestionGenerator extends AbstractMovieGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Which genre does the movie "); - put("es", "¿A qué género pertenece la película "); - put("fr", "À quel genre appartient le film "); - } - }; - - public MovieGenreQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?movie ?movieLabel ?genre ?genreLabel\n" + - "WHERE {" + - " ?movie wdt:P31 wd:Q11424 ." + // Instance of Film - " ?movie wdt:P136 ?genre ." + // Genre - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllMovies(JsonNode resultsNode, String correctMovie) { - List allMovies = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String movie = result.path("movieLabel").path("value").asText(); - if (!movie.equals(correctMovie)) { - allMovies.add(movie); - } - } - return allMovies; - } - - private List selectRandomIncorrectGenres(List allMovies, String correctMovie, int count) { - List incorrectGenres = new ArrayList<>(); - while (incorrectGenres.size() < count && allMovies.size() > 0) { - int randomIndex = random.nextInt(allMovies.size()); - String selectedMovie = allMovies.remove(randomIndex); - if (!selectedMovie.equals(correctMovie) && !incorrectGenres.contains(selectedMovie)) { - incorrectGenres.add(selectedMovie); - } - } - return incorrectGenres; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String movieLabel = result.path("movieLabel").path("value").asText(); - return selectRandomIncorrectGenres(getAllMovies(results, movieLabel), movieLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("genreLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("movieLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/movie/MovieReleaseYearQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/movie/MovieReleaseYearQuestionGenerator.java deleted file mode 100644 index 88b78d5d..00000000 --- a/src/main/java/com/uniovi/components/generators/movie/MovieReleaseYearQuestionGenerator.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.movie; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class MovieReleaseYearQuestionGenerator extends AbstractMovieGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "In which year was the movie "); - put("es", "¿En qué año se lanzó la película "); - put("fr", "En quelle année est sorti le film "); - } - }; - - public MovieReleaseYearQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?movie ?movieLabel ?releaseYear\n" + - "WHERE {" + - " ?movie wdt:P31 wd:Q11424 ." + // Instance of Film - " ?movie wdt:P577 ?releaseDate ." + // Release date - " BIND(YEAR(?releaseDate) AS ?releaseYear)" + // Extract year - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllMovies(JsonNode resultsNode, String correctMovie) { - List allMovies = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String movie = result.path("movieLabel").path("value").asText(); - if (!movie.equals(correctMovie)) { - allMovies.add(movie); - } - } - return allMovies; - } - - private List selectRandomIncorrectYears(List allMovies, String correctMovie, int count) { - List incorrectYears = new ArrayList<>(); - while (incorrectYears.size() < count && allMovies.size() > 0) { - int randomIndex = random.nextInt(allMovies.size()); - String selectedMovie = allMovies.remove(randomIndex); - if (!selectedMovie.equals(correctMovie) && !incorrectYears.contains(selectedMovie)) { - incorrectYears.add(selectedMovie); - } - } - return incorrectYears; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String movieLabel = result.path("movieLabel").path("value").asText(); - return selectRandomIncorrectYears(getAllMovies(results, movieLabel), movieLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("releaseYear").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("movieLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/movie/OriginalTitleQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/movie/OriginalTitleQuestionGenerator.java deleted file mode 100644 index 84f61091..00000000 --- a/src/main/java/com/uniovi/components/generators/movie/OriginalTitleQuestionGenerator.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.uniovi.components.generators.movie; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class OriginalTitleQuestionGenerator extends AbstractMovieGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "What is the original title of the movie "); - put("es", "¿Cuál es el título original de la película "); - put("fr", "Quel est le titre original du film "); - } - }; - - public OriginalTitleQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?movie ?movieLabel ?originalTitle\n" + - "WHERE {" + - " ?movie wdt:P31 wd:Q11424 ." + // Instance of Film - " ?movie wdt:P1476 ?originalTitle ." + // Original title - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllMovies(JsonNode resultsNode, String correctMovie) { - List allMovies = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String movie = result.path("movieLabel").path("value").asText(); - if (!movie.equals(correctMovie)) { - allMovies.add(movie); - } - } - return allMovies; - } - - private List selectRandomIncorrectTitles(List allMovies, String correctMovie, int count) { - List incorrectTitles = new ArrayList<>(); - while (incorrectTitles.size() < count && allMovies.size() > 0) { - int randomIndex = random.nextInt(allMovies.size()); - String selectedMovie = allMovies.remove(randomIndex); - if (!selectedMovie.equals(correctMovie) && !incorrectTitles.contains(selectedMovie)) { - incorrectTitles.add(selectedMovie); - } - } - return incorrectTitles; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String movieLabel = result.path("movieLabel").path("value").asText(); - return selectRandomIncorrectTitles(getAllMovies(results, movieLabel), movieLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("originalTitle").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("movieLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/science/AbstractScienceGenerator.java b/src/main/java/com/uniovi/components/generators/science/AbstractScienceGenerator.java deleted file mode 100644 index 8978f068..00000000 --- a/src/main/java/com/uniovi/components/generators/science/AbstractScienceGenerator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.uniovi.components.generators.science; - -import com.uniovi.components.generators.AbstractQuestionGenerator; -import com.uniovi.entities.Category; -import com.uniovi.services.CategoryService; - -public abstract class AbstractScienceGenerator extends AbstractQuestionGenerator { - - protected AbstractScienceGenerator(CategoryService categoryService) { - super(categoryService); - } - - @Override - public Category getCategory() { - return categoryService.getCategoryByName("Science"); - } -} diff --git a/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java deleted file mode 100644 index 4c907fba..00000000 --- a/src/main/java/com/uniovi/components/generators/science/MathPhysicsFormulaQuestionGenerator.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.uniovi.components.generators.science; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class MathPhysicsFormulaQuestionGenerator extends AbstractScienceGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "What is the formula for "); - put("es", "¿Cuál es la fórmula para "); - put("fr", "Quelle est la formule pour "); - } - }; - - public MathPhysicsFormulaQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?formula ?formulaLabel\n" + - "WHERE {" + - " ?formula wdt:P31 wd:Q5185279 ." + // Instance of Mathematical or physical formula - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllFormulas(JsonNode resultsNode, String correctFormula) { - List allFormulas = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String formula = result.path("formulaLabel").path("value").asText(); - if (!formula.equals(correctFormula)) { - allFormulas.add(formula); - } - } - return allFormulas; - } - - private List selectRandomIncorrectFormulas(List allFormulas, String correctFormula, int count) { - List incorrectFormulas = new ArrayList<>(); - while (incorrectFormulas.size() < count && allFormulas.size() > 0) { - int randomIndex = random.nextInt(allFormulas.size()); - String selectedFormula = allFormulas.remove(randomIndex); - if (!selectedFormula.equals(correctFormula) && !incorrectFormulas.contains(selectedFormula)) { - incorrectFormulas.add(selectedFormula); - } - } - return incorrectFormulas; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String formulaLabel = result.path("formulaLabel").path("value").asText(); - return selectRandomIncorrectFormulas(getAllFormulas(results, formulaLabel), formulaLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("formulaLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("formulaLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java deleted file mode 100644 index 36304b41..00000000 --- a/src/main/java/com/uniovi/components/generators/science/ScientificAchievementQuestionGenerator.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.science; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ScientificAchievementQuestionGenerator extends AbstractScienceGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "What significant achievement is associated with "); - put("es", "¿Qué logro significativo está asociado con "); - put("fr", "Quelle réalisation significative est associée à "); - } - }; - - public ScientificAchievementQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?scientist ?scientistLabel ?achievement ?achievementLabel\n" + - "WHERE {" + - " ?scientist wdt:P31 wd:Q5 ." + // Instance of Human - " ?scientist wdt:P166 ?achievement ." + // Notable achievement - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllAchievements(JsonNode resultsNode, String correctAchievement) { - List allAchievements = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String achievement = result.path("achievementLabel").path("value").asText(); - if (!achievement.equals(correctAchievement)) { - allAchievements.add(achievement); - } - } - return allAchievements; - } - - private List selectRandomIncorrectAchievements(List allAchievements, String correctAchievement, int count) { - List incorrectAchievements = new ArrayList<>(); - while (incorrectAchievements.size() < count && allAchievements.size() > 0) { - int randomIndex = random.nextInt(allAchievements.size()); - String selectedAchievement = allAchievements.remove(randomIndex); - if (!selectedAchievement.equals(correctAchievement) && !incorrectAchievements.contains(selectedAchievement)) { - incorrectAchievements.add(selectedAchievement); - } - } - return incorrectAchievements; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String achievementLabel = result.path("achievementLabel").path("value").asText(); - return selectRandomIncorrectAchievements(getAllAchievements(results, achievementLabel), achievementLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("achievementLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("scientistLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java deleted file mode 100644 index b868667b..00000000 --- a/src/main/java/com/uniovi/components/generators/science/ScientificDiscoveryQuestionGenerator.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.science; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ScientificDiscoveryQuestionGenerator extends AbstractScienceGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Who discovered "); - put("es", "¿Quién descubrió "); - put("fr", "Qui a découvert "); - } - }; - - public ScientificDiscoveryQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?scientist ?scientistLabel ?discovery ?discoveryLabel\n" + - "WHERE {" + - " ?scientist wdt:P31 wd:Q5 ." + // Instance of Human - " ?scientist wdt:P61 ?discovery ." + // Discovery - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllDiscoveries(JsonNode resultsNode, String correctDiscovery) { - List allDiscoveries = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String discovery = result.path("discoveryLabel").path("value").asText(); - if (!discovery.equals(correctDiscovery)) { - allDiscoveries.add(discovery); - } - } - return allDiscoveries; - } - - private List selectRandomIncorrectDiscoveries(List allDiscoveries, String correctDiscovery, int count) { - List incorrectDiscoveries = new ArrayList<>(); - while (incorrectDiscoveries.size() < count && allDiscoveries.size() > 0) { - int randomIndex = random.nextInt(allDiscoveries.size()); - String selectedDiscovery = allDiscoveries.remove(randomIndex); - if (!selectedDiscovery.equals(correctDiscovery) && !incorrectDiscoveries.contains(selectedDiscovery)) { - incorrectDiscoveries.add(selectedDiscovery); - } - } - return incorrectDiscoveries; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String discoveryLabel = result.path("discoveryLabel").path("value").asText(); - return selectRandomIncorrectDiscoveries(getAllDiscoveries(results, discoveryLabel), discoveryLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("scientistLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("discoveryLabel").path("value").asText() + "?"; - } -} diff --git a/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java b/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java deleted file mode 100644 index 55763766..00000000 --- a/src/main/java/com/uniovi/components/generators/science/ScientistBirthplaceQuestionGenerator.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.uniovi.components.generators.science; - -import com.fasterxml.jackson.databind.JsonNode; -import com.uniovi.services.CategoryService; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ScientistBirthplaceQuestionGenerator extends AbstractScienceGenerator { - private static final Map STATEMENTS = new HashMap<>() { - { - put("en", "Where was the scientist "); - put("es", "¿Dónde nació el científico "); - put("fr", "Où est né le scientifique "); - } - }; - - public ScientistBirthplaceQuestionGenerator(CategoryService categoryService, String language) { - super(categoryService); - this.statement = STATEMENTS.get(language); - this.language = language; - } - - @Override - public String getQuery() { - return "SELECT DISTINCT ?scientist ?scientistLabel ?birthplace ?birthplaceLabel\n" + - "WHERE {" + - " ?scientist wdt:P31 wd:Q5 ." + // Instance of Human - " ?scientist wdt:P19 ?birthplace ." + // Place of birth - " SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE]," + language + "\" }" + - "}"; - } - - private List getAllBirthplaces(JsonNode resultsNode, String correctBirthplace) { - List allBirthplaces = new ArrayList<>(); - for (JsonNode result : resultsNode) { - String birthplace = result.path("birthplaceLabel").path("value").asText(); - if (!birthplace.equals(correctBirthplace)) { - allBirthplaces.add(birthplace); - } - } - return allBirthplaces; - } - - private List selectRandomIncorrectBirthplaces(List allBirthplaces, String correctBirthplace, int count) { - List incorrectBirthplaces = new ArrayList<>(); - while (incorrectBirthplaces.size() < count && allBirthplaces.size() > 0) { - int randomIndex = random.nextInt(allBirthplaces.size()); - String selectedBirthplace = allBirthplaces.remove(randomIndex); - if (!selectedBirthplace.equals(correctBirthplace) && !incorrectBirthplaces.contains(selectedBirthplace)) { - incorrectBirthplaces.add(selectedBirthplace); - } - } - return incorrectBirthplaces; - } - - @Override - protected List generateOptions(JsonNode results, JsonNode result) { - String birthplaceLabel = result.path("birthplaceLabel").path("value").asText(); - return selectRandomIncorrectBirthplaces(getAllBirthplaces(results, birthplaceLabel), birthplaceLabel, 3); - } - - @Override - protected String generateCorrectAnswer(JsonNode result) { - return result.path("birthplaceLabel").path("value").asText(); - } - - @Override - protected String getQuestionSubject(JsonNode result) { - return this.statement + result.path("scientistLabel").path("value").asText() + "?"; - } -} From 4ac734a9f3aa8680f8ab92bcc0866fa5b1066009 Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 04:35:17 +0200 Subject: [PATCH 075/161] Test controller and temporary comments on some classes that used the old question generation system --- .../components/MultipleQuestionGenerator.java | 3 +- .../generators/QuestionGeneratorV2.java | 21 ++- .../services/InsertSampleDataService.java | 167 +++++++++--------- 3 files changed, 91 insertions(+), 100 deletions(-) diff --git a/src/main/java/com/uniovi/components/MultipleQuestionGenerator.java b/src/main/java/com/uniovi/components/MultipleQuestionGenerator.java index d8409cc5..7a10c2ed 100644 --- a/src/main/java/com/uniovi/components/MultipleQuestionGenerator.java +++ b/src/main/java/com/uniovi/components/MultipleQuestionGenerator.java @@ -4,6 +4,7 @@ import com.uniovi.entities.Category; import com.uniovi.entities.Question; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -14,7 +15,7 @@ public MultipleQuestionGenerator(QuestionGenerator... generators) { this.generators = generators; } - public List getQuestions() { + public List getQuestions() throws IOException { List questions = new ArrayList<>(); for (QuestionGenerator generator : generators) { questions.addAll(generator.getQuestions()); diff --git a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java index 8b7d39c8..1a440e9e 100644 --- a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java +++ b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java @@ -6,6 +6,7 @@ import com.uniovi.entities.Category; import com.uniovi.entities.Question; +import java.io.IOException; import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; @@ -37,7 +38,7 @@ public String getQuery() { } @Override - public List getQuestions() { + public List getQuestions() throws IOException { List questions = new ArrayList<>(); JsonNode categories = jsonNode.findValue("categories"); for(JsonNode category : categories){ @@ -51,7 +52,7 @@ public List getQuestions() { return questions; } - private List generateQuestion(JsonNode question, Category cat) { + private List generateQuestion(JsonNode question, Category cat) throws IOException { // Get the SPARQL query from the JSON String query = question.get("sparqlQuery").textValue(); @@ -73,15 +74,15 @@ private List generateQuestion(JsonNode question, Category cat) { for (JsonNode result : results) { // Generate the correct answer - String correctAnswer = result.get(answerLabel).textValue(); + String correctAnswer = result.path(answerLabel).path("value").asText(); Answer correct = new Answer(correctAnswer, true); // Generate the options List options = this.generateOptions(results, correctAnswer, answerLabel); - + options.add(correct); // Generate the question statement - String questionStatement = statement.replace(question_placeholder, result.get(questionLabel).textValue()); + String questionStatement = statement.replace(question_placeholder, result.path(questionLabel).path("value").asText()); // Generate the question questions.add(new Question(questionStatement, options, correct, cat, language)); @@ -92,7 +93,7 @@ private List generateQuestion(JsonNode question, Category cat) { private List generateOptions(JsonNode results, String correctAnswer, String answerLabel) { List options = new ArrayList<>(); for (JsonNode result : results) { - String option = result.get(answerLabel).textValue(); + String option = result.path(answerLabel).path("value").asText(); if (!option.equals(correctAnswer)) { options.add(new Answer(option, false)); } @@ -115,14 +116,15 @@ private String prepareStatement(JsonNode question) { return null; } - private JsonNode getQueryResult(String query) { + private JsonNode getQueryResult(String query) throws IOException { + System.out.println("Query: " + query); HttpClient client = HttpClient.newHttpClient(); JsonNode resultsNode; try { String endpointUrl = "https://query.wikidata.org/sparql?query=" + - URLEncoder.encode(this.getQuery(), StandardCharsets.UTF_8) + + URLEncoder.encode(query, StandardCharsets.UTF_8) + "&format=json"; HttpRequest request = HttpRequest.newBuilder() @@ -141,10 +143,7 @@ private JsonNode getQueryResult(String query) { } catch (InterruptedException e) { throw new QuestionGeneratorException("Generation of questions was interrupted"); - } catch (Exception e) { - throw new QuestionGeneratorException("An error occurred while generating questions"); } - return resultsNode; } diff --git a/src/main/java/com/uniovi/services/InsertSampleDataService.java b/src/main/java/com/uniovi/services/InsertSampleDataService.java index ff76371a..cc158cd8 100644 --- a/src/main/java/com/uniovi/services/InsertSampleDataService.java +++ b/src/main/java/com/uniovi/services/InsertSampleDataService.java @@ -1,108 +1,99 @@ package com.uniovi.services; import com.uniovi.components.MultipleQuestionGenerator; -import com.uniovi.components.generators.QuestionGenerator; -import com.uniovi.components.generators.geography.BorderQuestionGenerator; -import com.uniovi.components.generators.geography.CapitalQuestionGenerator; -import com.uniovi.components.generators.geography.ContinentQuestionGeneration; import com.uniovi.dto.PlayerDto; -import com.uniovi.entities.Associations; -import com.uniovi.entities.GameSession; -import com.uniovi.entities.Player; import com.uniovi.entities.Question; import com.uniovi.repositories.GameSessionRepository; import com.uniovi.repositories.QuestionRepository; -import jakarta.annotation.PostConstruct; import jakarta.transaction.Transactional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; import java.io.IOException; -import java.time.LocalDateTime; -import java.util.*; +import java.util.Arrays; +import java.util.List; @Service public class InsertSampleDataService { - private final PlayerService playerService; - private final QuestionService questionService; - private final CategoryService categoryService; - private final QuestionRepository questionRepository; - private final GameSessionRepository gameSessionRepository; - private Environment environment; - - private Logger log = LoggerFactory.getLogger(InsertSampleDataService.class); - - public InsertSampleDataService(PlayerService playerService, QuestionService questionService, - CategoryService categoryService, QuestionRepository questionRepository, - GameSessionRepository gameSessionRepository, Environment environment) { - this.playerService = playerService; - this.questionService = questionService; - this.categoryService = categoryService; - this.questionRepository = questionRepository; - this.gameSessionRepository = gameSessionRepository; - this.environment = environment; - } - - @Transactional - @EventListener(ApplicationReadyEvent.class) // Uncomment this line to insert sample data on startup - public void insertSampleQuestions() throws InterruptedException, IOException { - if (!playerService.getUserByEmail("test@test.com").isPresent()) { - PlayerDto player = new PlayerDto(); - player.setEmail("test@test.com"); - player.setUsername("test"); - player.setPassword("test"); - player.setRoles(new String[]{"ROLE_USER"}); - playerService.generateApiKey(playerService.addNewPlayer(player)); - } - - if (Arrays.stream(environment.getActiveProfiles()).anyMatch(env -> (env.equalsIgnoreCase("test")))) { - log.info("Test profile active, skipping sample data insertion"); - return; - } - - generateSampleData(); - } - - @Transactional - public void generateTestQuestions() { - questionRepository.deleteAll(); - questionService.testQuestions(4); - } - - @Transactional - public void generateSampleData() throws InterruptedException, IOException { - - questionRepository.deleteAll(); - - MultipleQuestionGenerator allQuestionGenerator = new MultipleQuestionGenerator( - new ContinentQuestionGeneration(categoryService, Question.ENGLISH), - new CapitalQuestionGenerator(categoryService, Question.ENGLISH), - new BorderQuestionGenerator(categoryService, Question.ENGLISH) - ); - List questionsEn = allQuestionGenerator.getQuestions(); - questionsEn.forEach(questionService::addNewQuestion); - - allQuestionGenerator = new MultipleQuestionGenerator( - new ContinentQuestionGeneration(categoryService, Question.SPANISH), - new CapitalQuestionGenerator(categoryService, Question.SPANISH), - new BorderQuestionGenerator(categoryService, Question.SPANISH) - ); - List questionsEs = allQuestionGenerator.getQuestions(); - questionsEs.forEach(questionService::addNewQuestion); - - allQuestionGenerator = new MultipleQuestionGenerator( - new ContinentQuestionGeneration(categoryService, Question.FRENCH), - new CapitalQuestionGenerator(categoryService, Question.FRENCH), - new BorderQuestionGenerator(categoryService, Question.FRENCH) - ); - List questionsFr = allQuestionGenerator.getQuestions(); - questionsFr.forEach(questionService::addNewQuestion); - - log.info("Sample questions inserted"); - } +// private final PlayerService playerService; +// private final QuestionService questionService; +// private final CategoryService categoryService; +// private final QuestionRepository questionRepository; +// private final GameSessionRepository gameSessionRepository; +// private Environment environment; +// +// private Logger log = LoggerFactory.getLogger(InsertSampleDataService.class); +// +//// public InsertSampleDataService(PlayerService playerService, QuestionService questionService, +//// CategoryService categoryService, QuestionRepository questionRepository, +//// GameSessionRepository gameSessionRepository, Environment environment) { +//// this.playerService = playerService; +//// this.questionService = questionService; +//// this.categoryService = categoryService; +//// this.questionRepository = questionRepository; +//// this.gameSessionRepository = gameSessionRepository; +//// this.environment = environment; +//// } +//// +//// @Transactional +//// @EventListener(ApplicationReadyEvent.class) // Uncomment this line to insert sample data on startup +//// public void insertSampleQuestions() throws InterruptedException, IOException { +//// if (!playerService.getUserByEmail("test@test.com").isPresent()) { +//// PlayerDto player = new PlayerDto(); +//// player.setEmail("test@test.com"); +//// player.setUsername("test"); +//// player.setPassword("test"); +//// player.setRoles(new String[]{"ROLE_USER"}); +//// playerService.generateApiKey(playerService.addNewPlayer(player)); +//// } +//// +//// if (Arrays.stream(environment.getActiveProfiles()).anyMatch(env -> (env.equalsIgnoreCase("test")))) { +//// log.info("Test profile active, skipping sample data insertion"); +//// return; +//// } +//// +//// generateSampleData(); +//// } +//// +//// @Transactional +//// public void generateTestQuestions() { +//// questionRepository.deleteAll(); +//// questionService.testQuestions(4); +//// } +//// +//// @Transactional +//// public void generateSampleData() throws InterruptedException, IOException { +//// +//// questionRepository.deleteAll(); +//// +//// MultipleQuestionGenerator allQuestionGenerator = new MultipleQuestionGenerator( +//// new ContinentQuestionGeneration(categoryService, Question.ENGLISH), +//// new CapitalQuestionGenerator(categoryService, Question.ENGLISH), +//// new BorderQuestionGenerator(categoryService, Question.ENGLISH) +//// ); +//// List questionsEn = allQuestionGenerator.getQuestions(); +//// questionsEn.forEach(questionService::addNewQuestion); +//// +//// allQuestionGenerator = new MultipleQuestionGenerator( +//// new ContinentQuestionGeneration(categoryService, Question.SPANISH), +//// new CapitalQuestionGenerator(categoryService, Question.SPANISH), +//// new BorderQuestionGenerator(categoryService, Question.SPANISH) +//// ); +//// List questionsEs = allQuestionGenerator.getQuestions(); +//// questionsEs.forEach(questionService::addNewQuestion); +//// +//// allQuestionGenerator = new MultipleQuestionGenerator( +//// new ContinentQuestionGeneration(categoryService, Question.FRENCH), +//// new CapitalQuestionGenerator(categoryService, Question.FRENCH), +//// new BorderQuestionGenerator(categoryService, Question.FRENCH) +//// ); +//// List questionsFr = allQuestionGenerator.getQuestions(); +//// questionsFr.forEach(questionService::addNewQuestion); +//// +//// log.info("Sample questions inserted"); +//// } } \ No newline at end of file From bd06490ff643d3dc02eea8843d95fa56c2a7df5e Mon Sep 17 00:00:00 2001 From: uo287545 Date: Thu, 25 Apr 2024 04:53:51 +0200 Subject: [PATCH 076/161] New question generator tested and working --- .../QuestionGeneratorTestController.java | 24 +++++++++++++++---- .../generators/QuestionGenerator.java | 3 ++- .../generators/QuestionGeneratorV2.java | 21 ++++++++++++---- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/uniovi/components/QuestionGeneratorTestController.java b/src/main/java/com/uniovi/components/QuestionGeneratorTestController.java index bb954701..7154ba5f 100644 --- a/src/main/java/com/uniovi/components/QuestionGeneratorTestController.java +++ b/src/main/java/com/uniovi/components/QuestionGeneratorTestController.java @@ -1,21 +1,35 @@ package com.uniovi.components; -import com.uniovi.components.generators.geography.CapitalQuestionGenerator; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.uniovi.components.generators.QuestionGeneratorV2; import com.uniovi.entities.Question; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.io.File; +import java.io.IOException; import java.util.List; @RestController public class QuestionGeneratorTestController { - /*@RequestMapping("/test") - public void test() { + private final String jsonFilePath = "src/main/resources/static/JSON/QuestionTemplates.json"; + + @RequestMapping("/test") + public void test() throws IOException { + // Crear un objeto File con la ruta del archivo JSON + File jsonFile = new File(jsonFilePath); + + // Crear un ObjectMapper de Jackson + ObjectMapper objectMapper = new ObjectMapper(); + + // Leer el archivo JSON y convertirlo en un JsonNode + JsonNode jsonNode = objectMapper.readTree(jsonFile); + QuestionGeneratorV2 qgen = new QuestionGeneratorV2(jsonNode, Question.SPANISH); List q = qgen.getQuestions(); for(Question question : q){ System.out.println(question); } - }*/ + } } diff --git a/src/main/java/com/uniovi/components/generators/QuestionGenerator.java b/src/main/java/com/uniovi/components/generators/QuestionGenerator.java index 7b552684..549cefe8 100644 --- a/src/main/java/com/uniovi/components/generators/QuestionGenerator.java +++ b/src/main/java/com/uniovi/components/generators/QuestionGenerator.java @@ -4,11 +4,12 @@ import com.uniovi.entities.Question; import org.springframework.stereotype.Component; +import java.io.IOException; import java.util.List; @Component public interface QuestionGenerator { String getQuery(); - List getQuestions(); + List getQuestions() throws IOException; } diff --git a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java index 1a440e9e..49268be0 100644 --- a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java +++ b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java @@ -85,18 +85,31 @@ private List generateQuestion(JsonNode question, Category cat) throws String questionStatement = statement.replace(question_placeholder, result.path(questionLabel).path("value").asText()); // Generate the question - questions.add(new Question(questionStatement, options, correct, cat, language)); + Question q = new Question(questionStatement, options, correct, cat, language); + + // Scramble the options + q.scrambleOptions(); + + // Add the question to the list + questions.add(q); } return questions; } private List generateOptions(JsonNode results, String correctAnswer, String answerLabel) { List options = new ArrayList<>(); - for (JsonNode result : results) { - String option = result.path(answerLabel).path("value").asText(); - if (!option.equals(correctAnswer)) { + List usedOptions = new ArrayList<>(); + int size = results.size(); + int tries = 0; + + while (options.size() < 3 && tries < 10){ + int random = (int) (Math.random() * size); + String option = results.get(random).path(answerLabel).path("value").asText(); + if (!option.equals(correctAnswer) && !usedOptions.contains(option) ) { + usedOptions.add(option); options.add(new Answer(option, false)); } + tries++; } return options; } From c85ee32b688f5057582ba42c83c7d7a64ab0f7f8 Mon Sep 17 00:00:00 2001 From: uo288061 Date: Thu, 25 Apr 2024 12:19:39 +0200 Subject: [PATCH 077/161] All multiplayerGame correct --- .../uniovi/controllers/GameController.java | 7 ++-- src/main/resources/messages.properties | 3 +- src/main/resources/messages_en.properties | 4 ++- src/main/resources/messages_es.properties | 4 +-- src/main/resources/messages_fr.properties | 3 +- .../templates/game/multiFinished.html | 35 ++++--------------- .../templates/ranking/multiplayerRanking.html | 7 ++-- 7 files changed, 19 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index 53c36810..25233374 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -70,9 +70,6 @@ public String getGame(HttpSession session, Model model, Principal principal) { @GetMapping("/multiplayerGame") public String getMultiplayerGame() { - //EL elminar el multiplaterCode del jugador se puede hacer cuando comienze el proximo - //juego con amigos o cuando acaba la partida, lo suyo seria cuando acabe - //ya mirare como return "game/multiplayerGame"; } @@ -87,7 +84,6 @@ public String joinMultiplayerGame(@PathVariable String code, HttpSession session session.setAttribute("multiplayerCode",code); return "redirect:/game/lobby"; } else { - //Hay q tratarlo como como se hace en sinUp, hacienado validate y tal return "redirect:/multiplayerGame"; } } @@ -193,12 +189,12 @@ public Map endMultiplayerGameTable(@PathVariable String code) { @GetMapping("/game/lobby/{code}") @ResponseBody public List updatePlayerList(@PathVariable String code) { - //List players = playerService.getUsersByMultiplayerCode(Integer.parseInt(code)); Map players= multiplayerSessionService.getPlayersWithScores(Integer.parseInt(code)); List playerNames = new ArrayList<>(); for (Map.Entry player : players.entrySet()) { playerNames.add(player.getKey().getUsername()); } + Collections.sort(playerNames); return playerNames; } @GetMapping("/game/lobby") @@ -292,6 +288,7 @@ public String updateGame(Model model, HttpSession session, Principal principal) isMultiPlayer=false; //return "game/multiplayerGame/endGame/"+p.getMultiplayerCode(); //return "redirect:multiplayerGame/endGame/"+p.getMultiplayerCode(); + //return "redirect:multiplayerGame/endGame/"+p.getMultiplayerCode(); return "game/multiFinished"; } if (nextQuestion == null) { diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index d60dc860..7a991f88 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -86,11 +86,12 @@ ranking.time=Tiempo # -------------------Statements for the multiplayerGame.html file--------------------- multi.text = ¿Aún no tienes un código? Crea uno y compártelo con tus amigos multi.create = Crear -multi.placeholder= Introduce el código de una partida +multi.placeholder= Introduce el código correcto multi.label = Únete a una partida multi.join = Unirse multi.onlyNumber = Solo se permiten números multi.copyCode= Copiar código +multi.info=Resultados para la partida: # -------------------Statements for the lobby.html file--------------------- lobby.info =Jugadores unidos a la partida: diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 9decb6b2..40a630b2 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -88,11 +88,13 @@ ranking.time=Time # -------------------Statements for the multiplayerGame.html file--------------------- multi.text =Don't have a code yet? Create one and share it with your friends multi.create = Create -multi.placeholder=Enter the game code +multi.placeholder=Enter the correct code multi.label=Join a game multi.join = Join multi.onlyNumber=Only numbers allowed multi.copyCode= Copy code +multi.info=reults for the game: + # -------------------Statements for the lobby.html file--------------------- lobby.info =Players joining the game: lobby.friends =Share your game code with your friends diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index 23425529..bc94b7b2 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -89,12 +89,12 @@ ranking.time=Tiempo # -------------------Statements for the multiplayerGame.html file--------------------- multi.text = ¿Aún no tienes un código? Crea uno y compártelo con tus amigos multi.create = Crear -multi.placeholder= Introduce el código de una partida +multi.placeholder= Introduce el código correcto multi.label = Únete a una partida multi.join = Unirse multi.onlyNumber = Solo se permiten números multi.copyCode= Copiar código - +multi.info=Resultados para la partida: # -------------------Statements for the lobby.html file--------------------- lobby.info =Jugadores unidos a la partida: diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index cefd1890..b9c54eee 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -82,11 +82,12 @@ ranking.time=Temps # -------------------Statements for the multiplayerGame.html file--------------------- multi.text = Vous n'avez pas encore de code ? Créez-en un et partagez-le avec vos amis. multi.create = Créer -multi.placeholder=Entrez le code du jeu +multi.placeholder=Entrez le bon code multi.label=Rejoignez une partie multi.join =Rejoindre multi.onlyNumber=Seuls les chiffres sont autorisés multi.copyCode= Copier le code +multi.info=résultats du jeu: # -------------------Statements for the lobby.html file--------------------- lobby.info =Joueurs rejoignant le jeu : diff --git a/src/main/resources/templates/game/multiFinished.html b/src/main/resources/templates/game/multiFinished.html index 54fa4c20..3aff9e76 100644 --- a/src/main/resources/templates/game/multiFinished.html +++ b/src/main/resources/templates/game/multiFinished.html @@ -6,37 +6,14 @@

    - - - + - - +
    \ No newline at end of file diff --git a/src/main/resources/templates/ranking/multiplayerRanking.html b/src/main/resources/templates/ranking/multiplayerRanking.html index 5c85427a..e47b2963 100644 --- a/src/main/resources/templates/ranking/multiplayerRanking.html +++ b/src/main/resources/templates/ranking/multiplayerRanking.html @@ -8,10 +8,8 @@
    -

    Fin multijugador

    - +

    +

    @@ -25,7 +23,6 @@

    Fin multijugador

    function updatePlayerList() { const code = [[${code}]]; $.ajax({ - //url: '/game/multiFinished/' + code, url: '/endGameList/' + code, type: 'GET', dataType: 'json', From af999eb0c38abf74c0c1b4d32939920846395f06 Mon Sep 17 00:00:00 2001 From: uo288061 Date: Thu, 25 Apr 2024 12:55:25 +0200 Subject: [PATCH 078/161] cleaning code --- .../uniovi/controllers/GameController.java | 59 +------------------ .../uniovi/entities/MultiplayerSession.java | 3 +- .../MultiplayerSessionRepository.java | 5 -- .../services/impl/MultiplayerSessionImpl.java | 9 +-- src/main/resources/messages.properties | 2 +- src/main/resources/messages_en.properties | 2 + src/main/resources/messages_es.properties | 2 + src/main/resources/messages_fr.properties | 1 + .../templates/game/multiplayerGame.html | 3 - .../templates/ranking/multiplayerRanking.html | 6 ++ 10 files changed, 18 insertions(+), 74 deletions(-) diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index 25233374..a28f181d 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -65,9 +65,6 @@ public String getGame(HttpSession session, Model model, Principal principal) { return "game/basicGame"; } - - - @GetMapping("/multiplayerGame") public String getMultiplayerGame() { return "game/multiplayerGame"; @@ -121,50 +118,10 @@ public String startMultiplayerGame(HttpSession session, Model model, Principal p return "game/basicGame"; } -// @GetMapping("/games/multiFinished") -// public String createFinishedLobby( HttpSession session, Model model) { -// int code = Integer.parseInt((String)session.getAttribute("multiplayerCode")); -// List players=playerService.getUsersByMultiplayerCode(code); -// model.addAttribute("players",players); -// model.addAttribute("code",session.getAttribute("multiplayerCode")); -// session.removeAttribute("gameSession"); -// return "/game/multiFinished"; -// } - - -// @GetMapping("/multiplayerGame/finishedGame") -// public String goToFinishedLobby(HttpSession session,Principal principal) { -// Optional player = playerService.getUserByUsername(principal.getName()); -// Player p = player.orElse(null); -// GameSession gameSession = (GameSession) session.getAttribute("gameSession"); -// playerService.setScoreMultiplayerCode(p.getId(),""+gameSession.getScore()); -// return "redirect:/game/multiFinished"; -// } -// - - -// @GetMapping("/game/multiFinished/{code}") -// @ResponseBody -// public Map updateFinishedGame(@PathVariable String code) { -// List players = playerService.getUsersByMultiplayerCode(Integer.parseInt(code)); -// Map playerInfo = new HashMap<>(); -// for (Player player : players) { -// String playerName = player.getUsername(); -// String playerScore = player.getScoreMultiplayerCode(); -// if(playerScore==null){ -// playerScore="N/A"; -// } -// playerInfo.put(playerName, playerScore); -// } -// return playerInfo; -// } - @GetMapping("/multiplayerGame/endGame/{code}") public String endMultiplayerGame(Model model,@PathVariable String code) { -// List playersWithScores =multiplayerSessionService.getPlayersWithScores(Integer.parseInt(code)); -// model.addAttribute("MultiplayerRanking", playersWithScores); - model.addAttribute("code",code); - return "ranking/multiplayerRanking"; + model.addAttribute("code",code); + return "ranking/multiplayerRanking"; } @GetMapping("/endGameList/{code}") @ResponseBody @@ -175,7 +132,7 @@ public Map endMultiplayerGameTable(@PathVariable String code) { String playerName = player.getKey().getUsername(); String playerScoreValue; if(player.getValue()==-1){ - playerScoreValue="N/A"; //estaria bien q pusiese jugagando pero internazionalizadp + playerScoreValue="N/A"; }else{ playerScoreValue=""+player.getValue(); } @@ -184,8 +141,6 @@ public Map endMultiplayerGameTable(@PathVariable String code) { return playersNameWithScore; } - - @GetMapping("/game/lobby/{code}") @ResponseBody public List updatePlayerList(@PathVariable String code) { @@ -208,14 +163,9 @@ public String createLobby( HttpSession session, Model model) { @GetMapping("/game/startMultiplayerGame") public String startMultiplayerGame( HttpSession session, Model model) { - //La idea seria q dando uno al boton de empezar empezasen todos return "/game/lobby"; } - - - - /** * This method is used to check the answer for a specific question * @param idQuestion The id of the question. @@ -286,9 +236,6 @@ public String updateGame(Model model, HttpSession session, Principal principal) playerService.setScoreMultiplayerCode(p.getId(),""+gameSession.getScore()); multiplayerSessionService.changeScore(p.getMultiplayerCode()+"",p.getId(),gameSession.getScore()); isMultiPlayer=false; - //return "game/multiplayerGame/endGame/"+p.getMultiplayerCode(); - //return "redirect:multiplayerGame/endGame/"+p.getMultiplayerCode(); - //return "redirect:multiplayerGame/endGame/"+p.getMultiplayerCode(); return "game/multiFinished"; } if (nextQuestion == null) { diff --git a/src/main/java/com/uniovi/entities/MultiplayerSession.java b/src/main/java/com/uniovi/entities/MultiplayerSession.java index e80d72bf..e9b77a5c 100644 --- a/src/main/java/com/uniovi/entities/MultiplayerSession.java +++ b/src/main/java/com/uniovi/entities/MultiplayerSession.java @@ -19,8 +19,7 @@ public class MultiplayerSession { private Long id; @Column private String multiplayerCode; - //@ManyToMany - //private Set players =new HashSet<>(); + @ElementCollection @Column private Map playerScores = new HashMap<>(); diff --git a/src/main/java/com/uniovi/repositories/MultiplayerSessionRepository.java b/src/main/java/com/uniovi/repositories/MultiplayerSessionRepository.java index 01a5b114..fd9e926e 100644 --- a/src/main/java/com/uniovi/repositories/MultiplayerSessionRepository.java +++ b/src/main/java/com/uniovi/repositories/MultiplayerSessionRepository.java @@ -12,11 +12,6 @@ import java.util.List; public interface MultiplayerSessionRepository extends CrudRepository { - //List findAll(); - -// @Query("SELECT m FROM MultiplayerSession m JOIN FETCH m.playerScores p WHERE m.multiplayerCode = :multiplayerCode ORDER BY p.scoreMultiplayerCode") -// Page findPlayersByMultiplayerCode(Pageable pageable, String multiplayerCode); - MultiplayerSession findByMultiplayerCode(String code); } diff --git a/src/main/java/com/uniovi/services/impl/MultiplayerSessionImpl.java b/src/main/java/com/uniovi/services/impl/MultiplayerSessionImpl.java index bd05d178..05acec97 100644 --- a/src/main/java/com/uniovi/services/impl/MultiplayerSessionImpl.java +++ b/src/main/java/com/uniovi/services/impl/MultiplayerSessionImpl.java @@ -14,8 +14,8 @@ @Service public class MultiplayerSessionImpl implements MultiplayerSessionService { - private PlayerRepository playerRepository; - private MultiplayerSessionRepository multiplayerSessionRepository; + private final PlayerRepository playerRepository; + private final MultiplayerSessionRepository multiplayerSessionRepository; public MultiplayerSessionImpl(PlayerRepository playerRepository, MultiplayerSessionRepository multiplayerSessionRepository) { @@ -23,11 +23,6 @@ public MultiplayerSessionImpl(PlayerRepository playerRepository, MultiplayerSess this.multiplayerSessionRepository = multiplayerSessionRepository; } -// @Override -// public Page getMultiplayerPlayerRanking(Pageable pageable, int multiplayerCode) { -// return multiplayerSessionRepository.findPlayersByMultiplayerCode(pageable, ""+multiplayerCode); -// } - @Override public Map getPlayersWithScores(int multiplayerCode) { MultiplayerSession session = multiplayerSessionRepository.findByMultiplayerCode(String.valueOf(multiplayerCode)); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 7a991f88..2c2e4c47 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -105,7 +105,7 @@ multi.results =Ver resultados # -------------------Statements for the multiFinished.html file--------------------- multi.finished= Partida finalizada multi.points = Puntuaciones - +multi.menu = Ir a la página de inicio # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API api.doc.description=Esta es la documentación de la API de WIQ. Aquí puedes encontrar información sobre los recursos disponibles, los parámetros que aceptan y los ejemplos de uso. diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 40a630b2..5a2d0015 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -107,6 +107,8 @@ multi.results = See results # -------------------Statements for the multiFinished.html file--------------------- multi.finished= Finished game multi.points = Points +multi.menu =Go to home page + # -------------------Statements for the apiHome.html file--------------------- api.doc.title=API Documentation diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index bc94b7b2..bdbaca5c 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -108,6 +108,8 @@ multi.results =Ver resultados # -------------------Statements for the multiFinished.html file--------------------- multi.finished= Partida finalizada multi.points = Puntuaciones +multi.menu = Ir a la página de inicio + # -------------------Statements for the apiHome.html file--------------------- api.doc.title=Documentación de la API diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index b9c54eee..8316898a 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -101,6 +101,7 @@ multi.results=Voir les résultats # -------------------Statements for the multiFinished.html file--------------------- multi.finished= Jeu terminé multi.points = Points +multi.menu =aller à la page d'accueil # -------------------Statements for the apiHome.html file--------------------- diff --git a/src/main/resources/templates/game/multiplayerGame.html b/src/main/resources/templates/game/multiplayerGame.html index 1be2cbb6..81af9294 100644 --- a/src/main/resources/templates/game/multiplayerGame.html +++ b/src/main/resources/templates/game/multiplayerGame.html @@ -11,13 +11,10 @@
    -
    -

    diff --git a/src/main/resources/templates/ranking/multiplayerRanking.html b/src/main/resources/templates/ranking/multiplayerRanking.html index e47b2963..5fc16703 100644 --- a/src/main/resources/templates/ranking/multiplayerRanking.html +++ b/src/main/resources/templates/ranking/multiplayerRanking.html @@ -14,6 +14,12 @@

    + +