Version19.258

This commit is contained in:
acanas 2020-08-18 11:37:02 +02:00
parent 258dcbc975
commit 0b26fdd87f
4 changed files with 136 additions and 59 deletions

View File

@ -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 */

View File

@ -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"

View File

@ -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)

View File

@ -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 */