mirror of https://github.com/acanas/swad-core.git
Version19.257
This commit is contained in:
parent
96390926bd
commit
258dcbc975
4
Makefile
4
Makefile
|
@ -48,8 +48,8 @@ OBJS = swad_account.o swad_action.o swad_agenda.o swad_alert.o \
|
|||
swad_institution_config.o \
|
||||
swad_language.o swad_layout.o swad_link.o swad_log.o swad_logo.o \
|
||||
swad_mail.o swad_main.o swad_maintenance.o swad_map.o swad_mark.o \
|
||||
swad_match.o swad_match_result.o swad_media.o swad_menu.o \
|
||||
swad_message.o swad_MFU.o \
|
||||
swad_match.o swad_match_print.o swad_match_result.o swad_media.o \
|
||||
swad_menu.o swad_message.o swad_MFU.o \
|
||||
swad_network.o swad_nickname.o swad_notice.o swad_notification.o \
|
||||
swad_pagination.o swad_parameter.o swad_password.o swad_photo.o \
|
||||
swad_place.o swad_plugin.o swad_privacy.o swad_profile.o \
|
||||
|
|
|
@ -556,7 +556,7 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
|
|||
En OpenSWAD:
|
||||
ps2pdf source.ps destination.pdf
|
||||
*/
|
||||
#define Log_PLATFORM_VERSION "SWAD 19.256 (2020-06-24)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 19.257 (2020-06-24)"
|
||||
#define CSS_FILE "swad19.253.css"
|
||||
#define JS_FILE "swad19.254.js"
|
||||
/*
|
||||
|
@ -567,6 +567,7 @@ TODO: Fix bug: Cuando se pulsa en ver fichas, y luego en una ficha en "Ver traba
|
|||
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.
|
||||
|
||||
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)
|
||||
Version 19.255.1: Jun 23, 2020 Changes in listing of tests results. (303655 lines)
|
||||
|
|
|
@ -3758,7 +3758,7 @@ void Mch_RemoveMyQuestionAnswer (void)
|
|||
Mch_RemoveMyAnswerToMatchQuestion (&Match);
|
||||
|
||||
/***** Compute score and update my match result *****/
|
||||
MchRes_ComputeScoreAndUpdateMyMatchResult (Match.MchCod);
|
||||
MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (Match.MchCod);
|
||||
}
|
||||
|
||||
/***** Show current match status *****/
|
||||
|
@ -3989,7 +3989,7 @@ void Mch_ReceiveQuestionAnswer (void)
|
|||
Mch_UpdateMyAnswerToMatchQuestion (&Match,&UsrAnswer);
|
||||
|
||||
/***** Compute score and update my match result *****/
|
||||
MchRes_ComputeScoreAndUpdateMyMatchResult (Match.MchCod);
|
||||
MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (Match.MchCod);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
// swad_match_print.c: matches prints in games using remote control
|
||||
|
||||
/*
|
||||
SWAD (Shared Workspace At a Distance),
|
||||
is a web platform developed at the University of Granada (Spain),
|
||||
and used to support university teaching.
|
||||
|
||||
This file is part of SWAD core.
|
||||
Copyright (C) 1999-2020 Antonio Cañas Vargas
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/********************************* Headers ***********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "swad_database.h"
|
||||
#include "swad_date.h"
|
||||
#include "swad_global.h"
|
||||
#include "swad_match.h"
|
||||
#include "swad_match_print.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** External global variables from others modules ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
extern struct Globals Gbl;
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************* Private types *******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private variables *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private prototypes ****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void MchPrn_UpdateMyMatchPrintInDB (struct MchPrn_Print *Print);
|
||||
|
||||
/*****************************************************************************/
|
||||
/**************************** Reset match print ******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void MchPrn_ResetPrint (struct MchPrn_Print *Print)
|
||||
{
|
||||
Print->MchCod = -1L;
|
||||
Print->UsrCod = -1L;
|
||||
Print->TimeUTC[Dat_START_TIME] =
|
||||
Print->TimeUTC[Dat_END_TIME ] = (time_t) 0;
|
||||
Print->NumQsts.All =
|
||||
Print->NumQsts.NotBlank = 0;
|
||||
Print->Score = 0.0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********** Compute score and create/update my result in a match ************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (long MchCod)
|
||||
{
|
||||
struct MchPrn_Print Print;
|
||||
|
||||
/***** Compute my match result *****/
|
||||
MchPrn_ResetPrint (&Print);
|
||||
Print.MchCod = MchCod;
|
||||
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
|
||||
Mch_GetMatchQuestionsFromDB (&Print);
|
||||
Mch_ComputeScore (&Print);
|
||||
|
||||
/***** Update my match result in database *****/
|
||||
MchPrn_UpdateMyMatchPrintInDB (&Print);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Create/update my result in a match *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void MchPrn_UpdateMyMatchPrintInDB (struct MchPrn_Print *Print)
|
||||
{
|
||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||
if (DB_QueryCOUNT ("can not get if match result exists",
|
||||
"SELECT COUNT(*) FROM mch_results"
|
||||
" WHERE MchCod=%ld AND UsrCod=%ld",
|
||||
Print->MchCod,Print->UsrCod)) // Match print exists
|
||||
/* Update result */
|
||||
DB_QueryUPDATE ("can not update match result",
|
||||
"UPDATE mch_results"
|
||||
" SET EndTime=NOW(),"
|
||||
"NumQsts=%u,"
|
||||
"NumQstsNotBlank=%u,"
|
||||
"Score='%.15lg'"
|
||||
" WHERE MchCod=%ld AND UsrCod=%ld",
|
||||
Print->NumQsts.All,
|
||||
Print->NumQsts.NotBlank,
|
||||
Print->Score,
|
||||
Print->MchCod,Print->UsrCod);
|
||||
else // Match print doesn't exist
|
||||
/* Create result */
|
||||
DB_QueryINSERT ("can not create match result",
|
||||
"INSERT mch_results "
|
||||
"(MchCod,UsrCod,StartTime,EndTime,NumQsts,NumQstsNotBlank,Score)"
|
||||
" VALUES "
|
||||
"(%ld," // MchCod
|
||||
"%ld," // UsrCod
|
||||
"NOW()," // StartTime
|
||||
"NOW()," // EndTime
|
||||
"%u," // NumQsts
|
||||
"%u," // NumQstsNotBlank
|
||||
"'%.15lg')", // Score
|
||||
Print->MchCod,Print->UsrCod,
|
||||
Print->NumQsts.All,
|
||||
Print->NumQsts.NotBlank,
|
||||
Print->Score);
|
||||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********* Get data of a match print using match code and user code **********/
|
||||
/*****************************************************************************/
|
||||
|
||||
void MchPrn_GetMatchPrintDataByMchCodAndUsrCod (struct MchPrn_Print *Print)
|
||||
{
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
Dat_StartEndTime_t StartEndTime;
|
||||
|
||||
/***** Make database query *****/
|
||||
if (DB_QuerySELECT (&mysql_res,"can not get data of a match print",
|
||||
"SELECT UNIX_TIMESTAMP(mch_results.StartTime)," // row[1]
|
||||
"UNIX_TIMESTAMP(mch_results.EndTime)," // row[2]
|
||||
"mch_results.NumQsts," // row[3]
|
||||
"mch_results.NumQstsNotBlank," // row[4]
|
||||
"mch_results.Score" // row[5]
|
||||
" FROM mch_results,mch_matches,gam_games"
|
||||
" WHERE mch_results.MchCod=%ld"
|
||||
" AND mch_results.UsrCod=%ld"
|
||||
" AND mch_results.MchCod=mch_matches.MchCod"
|
||||
" AND mch_matches.GamCod=gam_games.GamCod"
|
||||
" AND gam_games.CrsCod=%ld", // Extra check
|
||||
Print->MchCod,Print->UsrCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod) == 1)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get start time (row[0] and row[1] hold UTC date-times) */
|
||||
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
||||
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
||||
StartEndTime++)
|
||||
Print->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]);
|
||||
|
||||
/* Get number of questions (row[2]) */
|
||||
if (sscanf (row[2],"%u",&Print->NumQsts.All) != 1)
|
||||
Print->NumQsts.All = 0;
|
||||
|
||||
/* Get number of questions not blank (row[3]) */
|
||||
if (sscanf (row[3],"%u",&Print->NumQsts.NotBlank) != 1)
|
||||
Print->NumQsts.NotBlank = 0;
|
||||
|
||||
/* Get score (row[4]) */
|
||||
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
|
||||
if (sscanf (row[4],"%lf",&Print->Score) != 1)
|
||||
Print->Score = 0.0;
|
||||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
}
|
||||
else
|
||||
MchPrn_ResetPrint (Print);
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
}
|
|
@ -53,4 +53,10 @@ struct MchPrn_Print
|
|||
/***************************** Public prototypes *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void MchPrn_ResetPrint (struct MchPrn_Print *Print);
|
||||
|
||||
void MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (long MchCod);
|
||||
|
||||
void MchPrn_GetMatchPrintDataByMchCodAndUsrCod (struct MchPrn_Print *Print);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -77,10 +77,6 @@ struct MchRes_ICanView
|
|||
/***************************** Private prototypes ****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void MchPrn_ResetPrint (struct MchPrn_Print *Print);
|
||||
|
||||
static void MchRes_UpdateMyMatchResult (struct MchPrn_Print *Print);
|
||||
|
||||
static void MchRes_PutFormToSelUsrsToViewMchResults (void *Games);
|
||||
|
||||
static void MchRes_ListMyMchResultsInCrs (struct Gam_Games *Games);
|
||||
|
@ -110,91 +106,11 @@ static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults,
|
|||
double TotalScore,
|
||||
double TotalGrade);
|
||||
|
||||
static void MchRes_GetMatchResultDataByMchCodAndUsrCod (struct MchPrn_Print *Print);
|
||||
|
||||
static void MchRes_CheckIfICanSeeMatchResult (const struct Gam_Game *Game,
|
||||
const struct Mch_Match *Match,
|
||||
long UsrCod,
|
||||
struct MchRes_ICanView *ICanView);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**************************** Reset match print ******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void MchPrn_ResetPrint (struct MchPrn_Print *Print)
|
||||
{
|
||||
Print->MchCod = -1L;
|
||||
Print->UsrCod = -1L;
|
||||
Print->TimeUTC[Dat_START_TIME] =
|
||||
Print->TimeUTC[Dat_END_TIME ] = (time_t) 0;
|
||||
Print->NumQsts.All =
|
||||
Print->NumQsts.NotBlank = 0;
|
||||
Print->Score = 0.0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********** Compute score and create/update my result in a match ************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void MchRes_ComputeScoreAndUpdateMyMatchResult (long MchCod)
|
||||
{
|
||||
struct MchPrn_Print Print;
|
||||
|
||||
/***** Compute my match result *****/
|
||||
MchPrn_ResetPrint (&Print);
|
||||
Print.MchCod = MchCod;
|
||||
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
|
||||
Mch_GetMatchQuestionsFromDB (&Print);
|
||||
Mch_ComputeScore (&Print);
|
||||
|
||||
/***** Update my match result in database *****/
|
||||
MchRes_UpdateMyMatchResult (&Print);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Create/update my result in a match *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void MchRes_UpdateMyMatchResult (struct MchPrn_Print *Print)
|
||||
{
|
||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||
if (DB_QueryCOUNT ("can not get if match result exists",
|
||||
"SELECT COUNT(*) FROM mch_results"
|
||||
" WHERE MchCod=%ld AND UsrCod=%ld",
|
||||
Print->MchCod,Print->UsrCod)) // Match print exists
|
||||
/* Update result */
|
||||
DB_QueryUPDATE ("can not update match result",
|
||||
"UPDATE mch_results"
|
||||
" SET EndTime=NOW(),"
|
||||
"NumQsts=%u,"
|
||||
"NumQstsNotBlank=%u,"
|
||||
"Score='%.15lg'"
|
||||
" WHERE MchCod=%ld AND UsrCod=%ld",
|
||||
Print->NumQsts.All,
|
||||
Print->NumQsts.NotBlank,
|
||||
Print->Score,
|
||||
Print->MchCod,Print->UsrCod);
|
||||
else // Match print doesn't exist
|
||||
/* Create result */
|
||||
DB_QueryINSERT ("can not create match result",
|
||||
"INSERT mch_results "
|
||||
"(MchCod,UsrCod,StartTime,EndTime,NumQsts,NumQstsNotBlank,Score)"
|
||||
" VALUES "
|
||||
"(%ld," // MchCod
|
||||
"%ld," // UsrCod
|
||||
"NOW()," // StartTime
|
||||
"NOW()," // EndTime
|
||||
"%u," // NumQsts
|
||||
"%u," // NumQstsNotBlank
|
||||
"'%.15lg')", // Score
|
||||
Print->MchCod,Print->UsrCod,
|
||||
Print->NumQsts.All,
|
||||
Print->NumQsts.NotBlank,
|
||||
Print->Score);
|
||||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************************** Show my matches results *************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -974,7 +890,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
|
|||
|
||||
/* Get match result data */
|
||||
Print.UsrCod = UsrDat->UsrCod;
|
||||
MchRes_GetMatchResultDataByMchCodAndUsrCod (&Print);
|
||||
MchPrn_GetMatchPrintDataByMchCodAndUsrCod (&Print);
|
||||
|
||||
/* Get data of match and game */
|
||||
Match.MchCod = Print.MchCod;
|
||||
|
@ -1276,7 +1192,7 @@ void MchRes_ShowOneMchResult (void)
|
|||
/***** Get match result data *****/
|
||||
Print.MchCod = Match.MchCod;
|
||||
Print.UsrCod = UsrDat->UsrCod;
|
||||
MchRes_GetMatchResultDataByMchCodAndUsrCod (&Print);
|
||||
MchPrn_GetMatchPrintDataByMchCodAndUsrCod (&Print);
|
||||
|
||||
/***** Check if I can view this match result and score *****/
|
||||
MchRes_CheckIfICanSeeMatchResult (&Game,&Match,UsrDat->UsrCod,&ICanView);
|
||||
|
@ -1449,62 +1365,6 @@ void MchRes_ShowOneMchResult (void)
|
|||
Lay_NoPermissionExit ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************* Get data of a match result using its match code ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void MchRes_GetMatchResultDataByMchCodAndUsrCod (struct MchPrn_Print *Print)
|
||||
{
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
Dat_StartEndTime_t StartEndTime;
|
||||
|
||||
/***** Make database query *****/
|
||||
if (DB_QuerySELECT (&mysql_res,"can not get data"
|
||||
" of a match result of a user",
|
||||
"SELECT UNIX_TIMESTAMP(mch_results.StartTime)," // row[1]
|
||||
"UNIX_TIMESTAMP(mch_results.EndTime)," // row[2]
|
||||
"mch_results.NumQsts," // row[3]
|
||||
"mch_results.NumQstsNotBlank," // row[4]
|
||||
"mch_results.Score" // row[5]
|
||||
" FROM mch_results,mch_matches,gam_games"
|
||||
" WHERE mch_results.MchCod=%ld"
|
||||
" AND mch_results.UsrCod=%ld"
|
||||
" AND mch_results.MchCod=mch_matches.MchCod"
|
||||
" AND mch_matches.GamCod=gam_games.GamCod"
|
||||
" AND gam_games.CrsCod=%ld", // Extra check
|
||||
Print->MchCod,Print->UsrCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod) == 1)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get start time (row[0] and row[1] hold UTC date-times) */
|
||||
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
||||
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
||||
StartEndTime++)
|
||||
Print->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]);
|
||||
|
||||
/* Get number of questions (row[2]) */
|
||||
if (sscanf (row[2],"%u",&Print->NumQsts.All) != 1)
|
||||
Print->NumQsts.All = 0;
|
||||
|
||||
/* Get number of questions not blank (row[3]) */
|
||||
if (sscanf (row[3],"%u",&Print->NumQsts.NotBlank) != 1)
|
||||
Print->NumQsts.NotBlank = 0;
|
||||
|
||||
/* Get score (row[4]) */
|
||||
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
|
||||
if (sscanf (row[4],"%lf",&Print->Score) != 1)
|
||||
Print->Score = 0.0;
|
||||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
}
|
||||
else
|
||||
MchPrn_ResetPrint (Print);
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Get if I can see match result ************************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
/***************************** Public prototypes *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void MchRes_ComputeScoreAndUpdateMyMatchResult (long MchCod);
|
||||
|
||||
void MchRes_ShowMyMchResultsInCrs (void);
|
||||
void MchRes_ShowMyMchResultsInGam (void);
|
||||
void MchRes_ShowMyMchResultsInMch (void);
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include <mysql/mysql.h> // To access MySQL databases
|
||||
|
||||
#include "swad_cryptography.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Public constants ******************************/
|
||||
/*****************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue