From eb6d5e94b179b55adfb85d14665731a106b9e38e Mon Sep 17 00:00:00 2001 From: uo287545 Date: Mon, 6 May 2024 19:23:20 +0200 Subject: [PATCH] Some fixes --- docs/src/10_quality_requirements.adoc | 7 --- .../generators/QuestionGeneratorV2.java | 1 - .../uniovi/configuration/SecurityConfig.java | 2 +- .../uniovi/controllers/GameController.java | 2 +- .../uniovi/controllers/PlayersController.java | 33 +++++++----- .../services/QuestionGeneratorService.java | 20 +++++-- .../com/uniovi/services/QuestionService.java | 13 +++++ .../services/impl/QuestionServiceImpl.java | 13 ++++- 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/style.css | 19 +++++++ .../resources/static/script/background.js | 24 ++++++++- .../static/script/questionManagement.js | 12 ++--- .../resources/templates/fragments/footer.html | 54 ++++++++++++++++++- .../resources/templates/fragments/head.html | 4 +- .../templates/player/admin/admin.html | 7 +-- .../templates/player/admin/monitoring.html | 2 +- 19 files changed, 182 insertions(+), 43 deletions(-) diff --git a/docs/src/10_quality_requirements.adoc b/docs/src/10_quality_requirements.adoc index f9547253..d53f9778 100644 --- a/docs/src/10_quality_requirements.adoc +++ b/docs/src/10_quality_requirements.adoc @@ -36,10 +36,6 @@ ifndef::imagesdir[:imagesdir: ../images] |The ability of a system to handle increasing workload or growing demands by adapting or expanding its capacity without compromising performance. |SC7 -|Interoperability -|The system must have the ability of seamlessly communicate, exchange data, and work together effectively with different systems, applications, or components, even if they use different technologies. -|SC8 - |=== @@ -69,7 +65,4 @@ ifndef::imagesdir[:imagesdir: ../images] | SC7 | As user demand grows, the deployment does not grow dynamically. However a system can be put in place to deploy more instances of the application to handle the increased workload, trough a load balancer, for example. -| SC8 -| The application seamlessly integrates with other systems, allowing for the exchange of data and functionality without compatibility issues, enhancing its overall interoperability. - |=== \ No newline at end of file diff --git a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java index db4afcb4..92272ec3 100644 --- a/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java +++ b/src/main/java/com/uniovi/components/generators/QuestionGeneratorV2.java @@ -136,7 +136,6 @@ private String prepareStatement(JsonNode question) { } private JsonNode getQueryResult(String query) throws IOException, InterruptedException { - logger.info("Query: {}", query); HttpClient client = HttpClient.newHttpClient(); JsonNode resultsNode; diff --git a/src/main/java/com/uniovi/configuration/SecurityConfig.java b/src/main/java/com/uniovi/configuration/SecurityConfig.java index 8cfbc8f3..e54d636c 100644 --- a/src/main/java/com/uniovi/configuration/SecurityConfig.java +++ b/src/main/java/com/uniovi/configuration/SecurityConfig.java @@ -38,7 +38,7 @@ public static PasswordEncoder passwordEncoder(){ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf - .ignoringRequestMatchers("/api/**") + .ignoringRequestMatchers("/api/**", "/player/admin/**") ) .authorizeHttpRequests(authorize -> authorize diff --git a/src/main/java/com/uniovi/controllers/GameController.java b/src/main/java/com/uniovi/controllers/GameController.java index c4f46423..6c9074c5 100644 --- a/src/main/java/com/uniovi/controllers/GameController.java +++ b/src/main/java/com/uniovi/controllers/GameController.java @@ -173,7 +173,7 @@ public String createLobby( HttpSession session, Model model) { List players = playerService.getUsersByMultiplayerCode(code); model.addAttribute("players",players); model.addAttribute("code",session.getAttribute("multiplayerCode")); - return "/game/lobby"; + return "game/lobby"; } /** diff --git a/src/main/java/com/uniovi/controllers/PlayersController.java b/src/main/java/com/uniovi/controllers/PlayersController.java index 20cae551..dad9e674 100644 --- a/src/main/java/com/uniovi/controllers/PlayersController.java +++ b/src/main/java/com/uniovi/controllers/PlayersController.java @@ -18,6 +18,8 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Controller; @@ -30,6 +32,8 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.security.Principal; import java.util.Optional; import java.util.List; @@ -50,6 +54,7 @@ public PlayersController(PlayerService playerService, SignUpValidator signUpVali this.signUpValidator = signUpValidator; this.gameSessionService = gameSessionService; this.roleService = roleService; + this.questionService = questionService; } @GetMapping("/signup") @@ -245,9 +250,9 @@ public String changeRoles(HttpServletResponse response, @RequestParam String use @GetMapping("/player/admin/questionManagement") public String showQuestionManagementFragment(Model model) throws IOException { - File jsonFile = new File(QuestionGeneratorService.JSON_FILE_PATH); + Resource jsonFile = new ClassPathResource(QuestionGeneratorService.JSON_FILE_PATH); ObjectMapper objectMapper = new ObjectMapper(); - JsonNode json = objectMapper.readTree(jsonFile); + JsonNode json = objectMapper.readTree(jsonFile.getInputStream()); model.addAttribute("jsonContent", json.toString()); return "player/admin/questionManagement"; @@ -260,28 +265,30 @@ public String deleteAllQuestions() throws IOException { return "Questions deleted"; } - @GetMapping("/player/admin/saveQuestions") + @PutMapping("/player/admin/saveQuestions") @ResponseBody - public String saveQuestions(HttpServletResponse response, @RequestParam String json) throws IOException { + public String saveQuestions(HttpServletResponse response, @RequestBody String json) throws IOException { try { JsonNode node = new ObjectMapper().readTree(json); - DefaultPrettyPrinter printer = new DefaultPrettyPrinter(); - DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(); - printer.indentObjectsWith(indenter); // Indent JSON objects - printer.indentArraysWith(indenter); // Indent JSON arrays - - ObjectMapper mapper = new ObjectMapper(); - mapper.writer(printer).writeValue(new FileOutputStream(QuestionGeneratorService.JSON_FILE_PATH), node); + questionService.setJsonGenerator(node); return "Questions saved"; } catch (Exception e) { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return "Invalid JSON"; + return e.getMessage(); } } + @GetMapping("/questions/getJson") + @ResponseBody + public String getJson() { + return questionService.getJsonGenerator().toString(); + } + @GetMapping("/player/admin/monitoring") - public String showMonitoring(Model model) { + public String showMonitoring(HttpServletResponse response) { + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("application/json"); return "player/admin/monitoring"; } } diff --git a/src/main/java/com/uniovi/services/QuestionGeneratorService.java b/src/main/java/com/uniovi/services/QuestionGeneratorService.java index d4e35327..92b5292e 100644 --- a/src/main/java/com/uniovi/services/QuestionGeneratorService.java +++ b/src/main/java/com/uniovi/services/QuestionGeneratorService.java @@ -16,6 +16,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -31,7 +33,7 @@ public class QuestionGeneratorService { private final QuestionService questionService; - public static final String JSON_FILE_PATH = "src/main/resources/static/JSON/QuestionTemplates.json"; + public static final String JSON_FILE_PATH = "static/JSON/QuestionTemplates.json"; private Deque types = new ArrayDeque<>(); @@ -52,9 +54,11 @@ public QuestionGeneratorService(QuestionService questionService, Environment env } private void parseQuestionTypes() throws IOException { - File jsonFile = new File(JSON_FILE_PATH); - ObjectMapper objectMapper = new ObjectMapper(); - json = objectMapper.readTree(jsonFile); + if (json == null) { + Resource resource = new ClassPathResource(JSON_FILE_PATH); + ObjectMapper objectMapper = new ObjectMapper(); + json = objectMapper.readTree(resource.getInputStream()); + } JsonNode categories = json.findValue("categories"); for (JsonNode category : categories) { String categoryName = category.get("name").textValue(); @@ -125,11 +129,19 @@ public void generateTestQuestions(String cat) { questionService.addNewQuestion(new QuestionDto(q)); } + public void setJsonGeneration(JsonNode json) { + this.json = json; + } + public void resetGeneration() throws IOException { types.clear(); parseQuestionTypes(); } + public JsonNode getJsonGeneration() { + return json; + } + @Getter @AllArgsConstructor private static class QuestionType { diff --git a/src/main/java/com/uniovi/services/QuestionService.java b/src/main/java/com/uniovi/services/QuestionService.java index 1cea8683..8332ee56 100644 --- a/src/main/java/com/uniovi/services/QuestionService.java +++ b/src/main/java/com/uniovi/services/QuestionService.java @@ -1,5 +1,6 @@ package com.uniovi.services; +import com.fasterxml.jackson.databind.JsonNode; import com.uniovi.dto.QuestionDto; import com.uniovi.entities.Category; import com.uniovi.entities.Question; @@ -102,4 +103,16 @@ public interface QuestionService { * Delete all the questions */ void deleteAllQuestions() throws IOException; + + /** + * Set the json generator + * @param json The json generator + */ + void setJsonGenerator(JsonNode json); + + /** + * Get the json generator + * @return The json generator + */ + JsonNode getJsonGenerator(); } diff --git a/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java index aed0ceb0..d1e4a202 100644 --- a/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java @@ -1,5 +1,6 @@ package com.uniovi.services.impl; +import com.fasterxml.jackson.databind.JsonNode; import com.uniovi.dto.QuestionDto; import com.uniovi.entities.Answer; import com.uniovi.entities.Associations; @@ -21,8 +22,6 @@ import java.io.IOException; import java.security.SecureRandom; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -179,4 +178,14 @@ public void deleteAllQuestions() throws IOException { questionRepository.deleteAll(); } + @Override + public void setJsonGenerator(JsonNode json) { + questionGeneratorService.setJsonGeneration(json); + } + + @Override + public JsonNode getJsonGenerator() { + return questionGeneratorService.getJsonGeneration(); + } + } diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index d4b67675..508d2069 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -28,6 +28,9 @@ navbar.admin.zone=Zona de administración # -------------------Statements for the footer.html file--------------------- footer.copyright=© ASW - Grupo 04 B footer.nav=Menú de navegación +footer.toggle.on=Sí +footer.toggle.off=No +footer.animation=Animación de fondo # -------------------Statements for the error.html file--------------------- error.page.title=Error! diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index ca5f791c..3c2c7119 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -28,6 +28,9 @@ navbar.admin.zone=Admin Zone # -------------------Statements for the footer.html file--------------------- footer.copyright=© ASW - Group 04 B footer.nav=Navigation +footer.toggle.on=On +footer.toggle.off=Off +footer.animation=Background animation # -------------------Statements for the error.html file--------------------- error.page.title=Error! diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index 75dfbcac..2c3ac354 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -28,6 +28,9 @@ navbar.admin.zone=Zona de administración # -------------------Statements for the footer.html file--------------------- footer.copyright=© ASW - Grupo 04 B footer.nav=Menú de navegación +footer.toggle.on=Sí +footer.toggle.off=No +footer.animation=Animación de fondo # -------------------Statements for the error.html file--------------------- error.page.title=Error! diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index 40ce5dc2..2f7c0e7c 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -26,6 +26,9 @@ navbar.admin.zone=Espace administrateur # -------------------Statements for the footer.html file--------------------- footer.copyright=© ASW - Groupe 04 B footer.nav=Menu de navigation +footer.toggle.on=Oui +footer.toggle.off=Non +footer.animation=Animation de la page # -------------------Statements for the error.html file--------------------- error.page.title=Erreur ! diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index a28db0d5..d6e0c012 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -14,4 +14,23 @@ html { } body { margin-bottom: 60px; /* Margin bottom by footer height */ +} + +div div .btn-danger { + color: #fff; + background-color: #dc3545 !important; + border-color: #dc3545 !important; +} + +div div .btn-success { + color: #fff; + background-color: #218838 !important; + border-color: #1e7e34 !important; +} + +div div .toggle-handle { + border-width: 0 1px; + background-color: #fff !important; + color: #212529; + border-color: #f8f9fa; } \ No newline at end of file diff --git a/src/main/resources/static/script/background.js b/src/main/resources/static/script/background.js index 4be291bf..2f8b5c53 100644 --- a/src/main/resources/static/script/background.js +++ b/src/main/resources/static/script/background.js @@ -1,4 +1,20 @@ // modified version of random-normal +function getCookie(cname) { + let name = cname + "="; + let decodedCookie = decodeURIComponent(document.cookie); + let ca = decodedCookie.split(';'); + for(let i = 0; i =0)return o.pool[a];r++}while(r<100)}function randomNormal(o){if(o=Object.assign({mean:0,dev:1,pool:[]},o),Array.isArray(o.pool)&&o.pool.length>0)return normalPool(o);var r,a,n,e,l=o.mean,t=o.dev;do{r=(a=2*Math.random()-1)*a+(n=2*Math.random()-1)*n}while(r>=1);return e=a*Math.sqrt(-2*Math.log(r)/r),t*e+l} const NUM_PARTICLES = 350; @@ -51,8 +67,13 @@ function drawParticle(particle, canvas, ctx) { ctx.fillText("?", particle.x * canvas.width, particle.y * vh + (canvas.height / 2)); } - +let init = false; function draw(time, canvas, ctx) { + if (init && getCookie("backgroundAnimation") === "false") { + requestAnimationFrame((time) => draw(time, canvas, ctx)); + return; + } + // Move particles particles.forEach((particle, index) => { particles[index] = moveParticle(particle, canvas, time); @@ -66,6 +87,7 @@ function draw(time, canvas, ctx) { drawParticle(particle, canvas, ctx); }) + init = true; // Schedule next frame requestAnimationFrame((time) => draw(time, canvas, ctx)); } diff --git a/src/main/resources/static/script/questionManagement.js b/src/main/resources/static/script/questionManagement.js index 1d3280dd..fa3a92e6 100644 --- a/src/main/resources/static/script/questionManagement.js +++ b/src/main/resources/static/script/questionManagement.js @@ -13,19 +13,19 @@ function setupQuestionManagement() { $("#saveButton").on("click", function () { $.ajax({ url: "/player/admin/saveQuestions", - type: "GET", - data: { - json: JSON.stringify(editor.get()) - }, + type: "PUT", + data: JSON.stringify( + editor.get() + ), contentType: "application/json" }); }); $.ajax({ - url: '/JSON/QuestionTemplates.json', + url: '/questions/getJson', type: 'GET', success: function (data) { - let json = data; + let json = JSON.parse(data); const element = document.getElementById('jsonEditorElement'); const options = {} editor = new JSONEditor(element, options) diff --git a/src/main/resources/templates/fragments/footer.html b/src/main/resources/templates/fragments/footer.html index bebd50d9..ceb443e2 100644 --- a/src/main/resources/templates/fragments/footer.html +++ b/src/main/resources/templates/fragments/footer.html @@ -1,4 +1,3 @@ -
@@ -13,9 +12,60 @@
-
+ +
+
+ +
+
+
diff --git a/src/main/resources/templates/fragments/head.html b/src/main/resources/templates/fragments/head.html index 77172126..8193bf0b 100644 --- a/src/main/resources/templates/fragments/head.html +++ b/src/main/resources/templates/fragments/head.html @@ -21,5 +21,7 @@ - + + + diff --git a/src/main/resources/templates/player/admin/admin.html b/src/main/resources/templates/player/admin/admin.html index c87ee05e..f3e4ee22 100644 --- a/src/main/resources/templates/player/admin/admin.html +++ b/src/main/resources/templates/player/admin/admin.html @@ -42,15 +42,16 @@

let tabContent = $('#tab-content'); activeTab = tabNum; + console.log(window.location.origin); switch (tabNum) { case 'tab1': - tabContent.load('/player/admin/userManagement'); + tabContent.load(window.location.origin + '/player/admin/userManagement'); break; case 'tab2': - tabContent.load('/player/admin/questionManagement'); + tabContent.load(window.location.origin + '/player/admin/questionManagement'); break; case 'tab3': - tabContent.load('/player/admin/monitoring'); + tabContent.load(window.location.origin + '/player/admin/monitoring'); break; } }); diff --git a/src/main/resources/templates/player/admin/monitoring.html b/src/main/resources/templates/player/admin/monitoring.html index bfaed2b7..b832fd43 100644 --- a/src/main/resources/templates/player/admin/monitoring.html +++ b/src/main/resources/templates/player/admin/monitoring.html @@ -1,4 +1,4 @@ \ No newline at end of file +" src="https://monitor.pelayori.com:2053"> \ No newline at end of file