From 0b26fdd87f0cbf77d777d4d8b4d1ecd82346f548 Mon Sep 17 00:00:00 2001 From: acanas Date: Tue, 18 Aug 2020 11:37:02 +0200 Subject: [PATCH] Version19.258 --- soap/swad_web_service.h | 9 ++- swad_API.c | 158 +++++++++++++++++++++++++++------------- swad_changelog.h | 22 +++++- swad_game.c | 6 +- 4 files changed, 136 insertions(+), 59 deletions(-) diff --git a/soap/swad_web_service.h b/soap/swad_web_service.h index 250cc3e10..27355e8cd 100644 --- a/soap/swad_web_service.h +++ b/soap/swad_web_service.h @@ -301,13 +301,14 @@ struct swad__getMatchStatusOutput int matchCode; int questionIndex; int numAnswers; - int selected; + int answerIndex; }; /* answerMatchQuestion */ struct swad__answerMatchQuestionOutput { int matchCode; + int answerIndex; }; /* structs used in getUsers and sendMessage */ @@ -524,11 +525,11 @@ int swad__getTrivialQuestion (char *wsKey,char *degrees,float lowerScore,float u /* Games */ int swad__getGames (char *wsKey,int courseCode, struct swad__getGamesOutput *getGamesOut); -int swad__getMatches (char *wsKey,int gameCode, +int swad__getMatches (char *wsKey,int courseCode,int gameCode, struct swad__getMatchesOutput *getMatchesOut); -int swad__getMatchStatus (char *wsKey,int matchCode, +int swad__getMatchStatus (char *wsKey,int courseCode,int gameCode,int matchCode, struct swad__getMatchStatusOutput *getMatchStatusOut); -int swad__answerMatchQuestion (char *wsKey,int matchCode,int questionIndex,int answerIndex, +int swad__answerMatchQuestion (char *wsKey,int courseCode,int gameCode,int matchCode,int questionIndex,int answerIndex, struct swad__answerMatchQuestionOutput *answerMatchQuestionOut); /* List of users */ diff --git a/swad_API.c b/swad_API.c index 6f900d80e..9920953f8 100644 --- a/swad_API.c +++ b/swad_API.c @@ -4823,14 +4823,14 @@ int swad__getGames (struct soap *soap, /***** Query list of games *****/ NumRows = DB_QuerySELECT (&mysql_res,"can not get games", - "SELECT gam_games.GamCod," // row[0] - "gam_games.UsrCod," // row[1] - "MIN(mch_matches.StartTime) AS StartTime," // row[2] - "MAX(mch_matches.EndTime) AS EndTime," // row[3] - "gam_games.MaxGrade," // row[4] - "gam_games.Visibility," // row[5] - "gam_games.Title," // row[6] - "gam_games.Txt" // row[7] + "SELECT gam_games.GamCod," // row[0] + "gam_games.UsrCod," // row[1] + "UNIX_TIMESTAMP(MIN(mch_matches.StartTime)) AS StartTime," // row[2] + "UNIX_TIMESTAMP(MAX(mch_matches.EndTime)) AS EndTime," // row[3] + "gam_games.MaxGrade," // row[4] + "gam_games.Visibility," // row[5] + "gam_games.Title," // row[6] + "gam_games.Txt" // row[7] " FROM gam_games" " LEFT JOIN mch_matches" " ON gam_games.GamCod=mch_matches.GamCod" @@ -4951,7 +4951,7 @@ int swad__getGames (struct soap *soap, /*****************************************************************************/ int swad__getMatches (struct soap *soap, - char *wsKey,int gameCode, // input + char *wsKey,int courseCode,int gameCode, // input struct swad__getMatchesOutput *getMatchesOut) // output { int ReturnCode; @@ -4969,6 +4969,7 @@ int swad__getMatches (struct soap *soap, /***** Initializations *****/ API_Set_gSOAP_RuntimeEnv (soap); Gbl.WebService.Function = API_getMatches; + Gbl.Hierarchy.Crs.CrsCod = (long) courseCode; /***** Check web service key *****/ if ((ReturnCode = API_CheckWSKey (wsKey)) != SOAP_OK) @@ -4978,6 +4979,12 @@ int swad__getMatches (struct soap *soap, "Bad web service key", "Web service key does not exist in database"); + /***** Check if course code is correct *****/ + if (Gbl.Hierarchy.Crs.CrsCod <= 0) + return soap_sender_fault (soap, + "Bad course code", + "Course code must be a integer greater than 0"); + /***** Reset game *****/ Gam_ResetGame (&Game); @@ -4989,13 +4996,6 @@ int swad__getMatches (struct soap *soap, "Game code must be a integer greater than 0"); Gam_GetDataOfGameByCod (&Game); - /***** Check if course code is correct *****/ - Gbl.Hierarchy.Crs.CrsCod = (long) Game.CrsCod; - if (Gbl.Hierarchy.Crs.CrsCod <= 0) - return soap_sender_fault (soap, - "Bad course code", - "Course code must be a integer greater than 0"); - /***** Get some of my data *****/ if (!API_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,Gbl.Hierarchy.Crs.CrsCod)) return soap_receiver_fault (soap, @@ -5134,8 +5134,8 @@ int swad__getMatches (struct soap *soap, /*****************************************************************************/ int swad__getMatchStatus (struct soap *soap, - char *wsKey,int matchCode, // input - struct swad__getMatchStatusOutput *getMatchStatusOut) // output + char *wsKey,int courseCode,int gameCode,int matchCode, // input + struct swad__getMatchStatusOutput *getMatchStatusOut) // output { int ReturnCode; struct Gam_Game Game; @@ -5144,9 +5144,16 @@ int swad__getMatchStatus (struct soap *soap, unsigned NumOptions; struct Mch_UsrAnswer UsrAnswer; + /***** Reset game and match *****/ + Gam_ResetGame (&Game); + Mch_ResetMatch (&Match); + /***** Initializations *****/ API_Set_gSOAP_RuntimeEnv (soap); Gbl.WebService.Function = API_getMatchStatus; + Gbl.Hierarchy.Crs.CrsCod = (long) courseCode; + Game.GamCod = (long) gameCode; + Match.MchCod = (long) matchCode; /***** Check web service key *****/ if ((ReturnCode = API_CheckWSKey (wsKey)) != SOAP_OK) @@ -5156,32 +5163,31 @@ int swad__getMatchStatus (struct soap *soap, "Bad web service key", "Web service key does not exist in database"); - /***** Reset game and match *****/ - Gam_ResetGame (&Game); - Mch_ResetMatch (&Match); - - /***** Get match data from database *****/ - Match.MchCod = (long) matchCode; - if (Match.MchCod <= 0) + /***** Check if course code is correct *****/ + if (Gbl.Hierarchy.Crs.CrsCod <= 0) return soap_sender_fault (soap, - "Bad match code", - "Match code must be a integer greater than 0"); - Mch_GetDataOfMatchByCod (&Match); + "Bad course code", + "Course code must be a integer greater than 0"); /***** Get game data from database *****/ - Game.GamCod = Match.GamCod; if (Game.GamCod <= 0) return soap_sender_fault (soap, "Bad game code", "Game code must be a integer greater than 0"); Gam_GetDataOfGameByCod (&Game); - /***** Check if course code is correct *****/ - Gbl.Hierarchy.Crs.CrsCod = (long) Game.CrsCod; - if (Gbl.Hierarchy.Crs.CrsCod <= 0) + /***** Get match data from database *****/ + if (Match.MchCod <= 0) return soap_sender_fault (soap, - "Bad course code", - "Course code must be a integer greater than 0"); + "Bad match code", + "Match code must be a integer greater than 0"); + Mch_GetDataOfMatchByCod (&Match); + + /* Check that match belongs to game */ + if (Match.GamCod != Game.GamCod) + return soap_sender_fault (soap, + "Bad game code", + "Match code does not belong to game code"); /***** Get some of my data *****/ if (!API_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,Gbl.Hierarchy.Crs.CrsCod)) @@ -5227,7 +5233,7 @@ int swad__getMatchStatus (struct soap *soap, /***** Set number of selected answer *****/ if (NumOptions == 0) - getMatchStatusOut->selected = -1; + getMatchStatusOut->answerIndex = -1; else // Answers found { /***** Get student's answer to this question @@ -5236,9 +5242,22 @@ int swad__getMatchStatus (struct soap *soap, Gbl.Usrs.Me.UsrDat.UsrCod, Match.Status.QstInd, &UsrAnswer); - getMatchStatusOut->selected = UsrAnswer.NumOpt; + getMatchStatusOut->answerIndex = UsrAnswer.NumOpt; } + DB_QueryINSERT ("can not debug", + "INSERT INTO debug" + " (DebugTime,Txt)" + " VALUES" + " (NOW(),'getMatchStatusOut->matchCode: %d;" + " getMatchStatusOut->questionIndex: %d;" + " getMatchStatusOut->numAnswers: %d;" + " getMatchStatusOut->answerIndex: %d')", + getMatchStatusOut->matchCode, + getMatchStatusOut->questionIndex, + getMatchStatusOut->numAnswers, + getMatchStatusOut->answerIndex); + return SOAP_OK; } @@ -5247,16 +5266,25 @@ int swad__getMatchStatus (struct soap *soap, /*****************************************************************************/ int swad__answerMatchQuestion (struct soap *soap, - char *wsKey,int matchCode,int questionIndex,int numOption, // input - struct swad__answerMatchQuestionOutput *answerMatchQuestionOut) // output + char *wsKey,int courseCode,int gameCode,int matchCode,int questionIndex,int numOption, // input + struct swad__answerMatchQuestionOutput *answerMatchQuestionOut) // output { int ReturnCode; // unsigned QstInd; // 0 means that the game has not started. First question has index 1. // unsigned NumOpt; + struct Gam_Game Game; + struct Mch_Match Match; + + /***** Reset game and match *****/ + Gam_ResetGame (&Game); + Mch_ResetMatch (&Match); /***** Initializations *****/ API_Set_gSOAP_RuntimeEnv (soap); Gbl.WebService.Function = API_answerMatchQuestion; + Gbl.Hierarchy.Crs.CrsCod = (long) courseCode; + Game.GamCod = (long) gameCode; + Match.MchCod = (long) matchCode; /***** Check web service key *****/ if ((ReturnCode = API_CheckWSKey (wsKey)) != SOAP_OK) @@ -5266,18 +5294,46 @@ int swad__answerMatchQuestion (struct soap *soap, "Bad web service key", "Web service key does not exist in database"); + /***** Check if course code is correct *****/ + if (Gbl.Hierarchy.Crs.CrsCod <= 0) + return soap_sender_fault (soap, + "Bad course code", + "Course code must be a integer greater than 0"); + + /***** Get game data from database *****/ + if (Game.GamCod <= 0) + return soap_sender_fault (soap, + "Bad game code", + "Game code must be a integer greater than 0"); + Gam_GetDataOfGameByCod (&Game); + + /***** Get match data from database *****/ + if (Match.MchCod <= 0) + return soap_sender_fault (soap, + "Bad match code", + "Match code must be a integer greater than 0"); + Mch_GetDataOfMatchByCod (&Match); + + /* Check that match belongs to game */ + if (Match.GamCod != Game.GamCod) + return soap_sender_fault (soap, + "Bad game code", + "Match code does not belong to game code"); + // TODO: Write the code if (questionIndex > 0 && numOption > 0) { // QstInd = (unsigned) questionIndex; // NumOpt = (unsigned) numOption; answerMatchQuestionOut->matchCode = matchCode; + answerMatchQuestionOut->answerIndex = 1; // TODO: Return the current answer index } else { // QstInd = 0; // NumOpt = 0; answerMatchQuestionOut->matchCode = -1; + answerMatchQuestionOut->answerIndex = -1; } return SOAP_OK; @@ -6072,19 +6128,19 @@ int swad__getLastLocation (struct soap *soap, /***** Get list of locations *****/ NumLocs = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches", - "SELECT institutions.InsCod," // row[ 0] - "institutions.ShortName," // row[ 1] - "institutions.FullName," // row[ 2] - "centres.CtrCod," // row[ 3] - "centres.ShortName," // row[ 4] - "centres.FullName," // row[ 5] - "buildings.BldCod," // row[ 6] - "buildings.ShortName," // row[ 7] - "buildings.FullName," // row[ 8] - "rooms.Floor," // row[ 9] - "rooms.RooCod," // row[10] - "rooms.ShortName," // row[11] - "rooms.FullName," // row[12] + "SELECT institutions.InsCod," // row[ 0] + "institutions.ShortName," // row[ 1] + "institutions.FullName," // row[ 2] + "centres.CtrCod," // row[ 3] + "centres.ShortName," // row[ 4] + "centres.FullName," // row[ 5] + "buildings.BldCod," // row[ 6] + "buildings.ShortName," // row[ 7] + "buildings.FullName," // row[ 8] + "rooms.Floor," // row[ 9] + "rooms.RooCod," // row[10] + "rooms.ShortName," // row[11] + "rooms.FullName," // row[12] "UNIX_TIMESTAMP(room_check_in.CheckInTime)" // row[13] " FROM room_check_in,rooms,buildings,centres,institutions" " WHERE room_check_in.UsrCod=%d" diff --git a/swad_changelog.h b/swad_changelog.h index d43567c3b..a21c7d058 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -499,7 +499,7 @@ Poblar base de datos: En Usuarios > Ubicación aparecería un botón pequeño de "Añadir ubicación". Se preguntaría a SWAD a través de una función de la API si el usuario tiene permiso para añadir ubicaciones. -Función API checkPermission... +Función API checkPermissionToAdminCenter Si es así, se llamaría a la función: Función API newLocation... @@ -517,6 +517,15 @@ pero s Se puede mostrar las últimas dos o tres ubicaciones (y dentro de ellas sólo el último instante de cada ubicación) dentro siempre de lo que haya guardado en la tabla de ubicaciones limitada a 12/24 h. +------------------------------------------------------------------------------- + +Función API +getAvailableRoles + +Devuelve el campo Gbl.Usr.Role.Available. +Con esta función SWADroid sabe si al usuario se le puede mostrar un botón para ver la MAC más cercana + + */ @@ -556,17 +565,26 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.257 (2020-06-24)" +#define Log_PLATFORM_VERSION "SWAD 19.258 (2020-08-11)" #define CSS_FILE "swad19.253.css" #define JS_FILE "swad19.254.js" /* +TODO: José Martínez Aroza: Si estoy viendo la lista de trabajos de un grupo de estudiantes y pulso F5 (reenviando datos) entonces sale el listado duplicado, y la siguiente vez triplicado, etc. + +TODO: Raymon Moreno Colina: ¿sera posible colocarle a las preguntas distinta ponderación (puntuación)?; porque como docente a veces uno formula en un examen cuestiones que tienen mayor profundidad que otras y considero que no debería ser la misma puntuación para toda las preguntas. TODO: Encarnación Hidalgo Tenorio: Antonio, ¿podría @swad_ugr mandar una notificación cuando el alumnado ha mandado su tarea? Se trataría de añadir un par de líneas "Nuevos archivos en actividades", "Nuevos archivos en otros trabajos". TODO: Fix bug: Un estudiante recibe una notificación de un archivo de calificaciones. Luego el archivo es ocultado por el profesor. Pero desde la notificación sigue estando accesible, cuando no debería ser así. Reported by Adrián José Martínez Navarro. TODO: Fix bug: Cuando se pulsa en ver fichas, y luego en una ficha en "Ver trabajos" o "Ver exámenes", o lo que sea, sale dos veces ese estudiante. TODO: No limitar el número de preguntas en un examen a ExaPrn_MAX_QUESTIONS_PER_EXAM_PRINT, sino asignar PrintedQuestions dinámicamente con malloc TODO: Que al generar un examen sólo se cojan preguntas válidas. Y si ya está generado, al entrar de nuevo, que se vean en rojo. +TODO: Create module swad_test_result +"sudo apt install webp" en Ubuntu, y "yum install libwebp libwebp-tools" en CentOS, para decodificar imágenes Web/ug reportado por Javier Fernández Baldomero. +TODO: Escribir la función getAvailableRoles +TODO: Escribir correctamente la función swad__answerMatchQuestion + + Version 19.258: Aug 11, 2020 Changes in API functions related to games and matches. (303951 lines) Version 19.257: Jun 24, 2020 New module swad_match_print. (303887 lines) Version 19.256: Jun 24, 2020 Code refactoring in tests, exams and matches results. (303841 lines) Version 19.255.2: Jun 24, 2020 Changes in listing of tests and exams results. (303701 lines) diff --git a/swad_game.c b/swad_game.c index 78ba33bb3..a8883f224 100644 --- a/swad_game.c +++ b/swad_game.c @@ -1003,8 +1003,10 @@ void Gam_GetDataOfGameByCod (struct Gam_Game *Game) " FROM gam_games" " LEFT JOIN mch_matches" " ON gam_games.GamCod=mch_matches.GamCod" - " WHERE gam_games.GamCod=%ld", - Game->GamCod); + " WHERE gam_games.GamCod=%ld" + " AND gam_games.CrsCod='%ld'", // Extra check + Game->GamCod, + Gbl.Hierarchy.Crs.CrsCod); if (NumRows) // Game found... { /* Get row */