diff --git a/soap/swad_web_service.h b/soap/swad_web_service.h index 1c38919ee..250cc3e10 100644 --- a/soap/swad_web_service.h +++ b/soap/swad_web_service.h @@ -440,8 +440,8 @@ struct swad__sendMessageOutput struct swad__usersArray usersArray; }; -/* getLocations */ -struct swad__getLocationsOutput +/* location */ +struct swad__location { int institutionCode; char *institutionShortName; @@ -458,12 +458,25 @@ struct swad__getLocationsOutput char *roomFullName; }; -/* sendCurrentLocation */ -struct swad__sendCurrentLocationOutput +/* getLocation */ +struct swad__getLocationOutput + { + struct swad__location location; + }; + +/* sendMyLocation */ +struct swad__sendMyLocationOutput { int success; }; +/* getLastLocation */ +struct swad__getLastLocationOutput + { + struct swad__location location; + long checkinTime; + }; + /*****************************************************************************/ /*************************** Web service functions ***************************/ /*****************************************************************************/ @@ -549,8 +562,9 @@ int swad__sendMessage (char *wsKey,int messageCode,char *to,char *subject,char * struct swad__sendMessageOutput *sendMessageOut); /* Wi-Fi-based positioning system */ -int swad__getLocations (char *wsKey,char *MAC, - struct swad__getLocationsOutput *getLocationsOut); -int swad__sendCurrentLocation (char *wsKey,int roomCode, - struct swad__sendCurrentLocationOutput *endCurrentLocationOut); - +int swad__getLocation (char *wsKey,char *MAC, + struct swad__getLocationOutput *getLocationOut); +int swad__sendMyLocation (char *wsKey,int roomCode, + struct swad__sendMyLocationOutput *sendMyLocationOut); +int swad__getLastLocation (char *wsKey,int userCode, + struct swad__getLastLocationOutput *getLastLocationOut); diff --git a/sql/cambios.sql b/sql/cambios.sql index 37d5422fe..a7b4dbbb5 100644 --- a/sql/cambios.sql +++ b/sql/cambios.sql @@ -13383,3 +13383,22 @@ SELECT COUNT(*) FROM exa_log_user_agent WHERE LogCod=(SELECT MAX(LogCod) FROM ex INSERT INTO room_check_in (UsrCod,RooCod,CheckInTime) SELECT 1,RooCod,NOW() FROM rooms WHERE RooCod=1; + + + + + + + + + + + +---------------------------------------- + + +INSERT INTO room_check_in (UsrCod,RooCod,CheckInTime) VALUES (1,1,NOW()); + +SELECT institutions.InsCod,institutions.ShortName,institutions.FullName,centres.CtrCod,centres.ShortName,centres.FullName,buildings.BldCod,buildings.ShortName,buildings.FullName,rooms.Floor,rooms.RooCod,rooms.ShortName,rooms.FullName,UNIX_TIMESTAMP(room_check_in.CheckInTime) FROM room_check_in,rooms,buildings,centres,institutions WHERE room_check_in.UsrCod=1 AND room_check_in.CheckInTime=(SELECT MAX(CheckInTime) FROM room_check_in.UsrCod=1) AND room_check_in.RooCod=rooms.RooCod AND rooms.BldCod=buildings.BldCod AND buildings.CtrCod=centres.CtrCod AND centres.InsCod=institutions.InsCod; + +SELECT COUNT(*) FROM (SELECT DISTINCT degrees.CtrCod FROM crs_usr,courses,degrees WHERE crs_usr.UsrCod=1346 AND crs_usr.CrsCod=courses.CrsCod AND courses.DegCod=degrees.DegCod) AS centres1,(SELECT DISTINCT degrees.CtrCod FROM crs_usr,courses,degrees WHERE crs_usr.UsrCod=1331 AND crs_usr.CrsCod=courses.CrsCod AND courses.DegCod=degrees.DegCod) AS centres2 WHERE centres1.CtrCod=centres2.CtrCod; diff --git a/swad_API.c b/swad_API.c index d16bad2db..6f900d80e 100644 --- a/swad_API.c +++ b/swad_API.c @@ -166,8 +166,9 @@ static const char *API_Functions[1 + API_NUM_FUNCTIONS] = [API_getMatches ] = "getMatches", // 29 [API_getMatchStatus ] = "getMatchStatus", // 30 [API_answerMatchQuestion ] = "answerMatchQuestion", // 31 - [API_getLocations ] = "getLocations", // 32 - [API_sendCurrentLocation ] = "sendCurrentLocation", // 33 + [API_getLocation ] = "getLocation", // 32 + [API_sendMyLocation ] = "sendMyLocation", // 33 + [API_getLastLocation ] = "getLastLocation", // 34 }; /* Web service roles (they do not match internal swad-core roles) */ @@ -272,6 +273,14 @@ static void API_ListDir (unsigned Level,const char *Path,const char *PathInTree) static bool API_WriteRowFileBrowser (unsigned Level,Brw_FileType_t FileType,const char *FileName); static void API_IndentXMLLine (unsigned Level); +static void API_GetDataOfLocation (struct soap *soap, + struct swad__location *location, + time_t *CheckInTime, + MYSQL_RES **mysql_res, + unsigned NumLocs); +static void API_ResetLocation (struct soap *soap, + struct swad__location *location); + /*****************************************************************************/ /******* Function called when a web service if required by a plugin **********/ /*****************************************************************************/ @@ -5894,20 +5903,18 @@ int swad__getMarks (struct soap *soap, /**************** Get locations associated to a MAC address ******************/ /*****************************************************************************/ -int swad__getLocations (struct soap *soap, - char *wsKey,char *MAC, // input - struct swad__getLocationsOutput *getLocationsOut) // output +int swad__getLocation (struct soap *soap, + char *wsKey,char *MAC, // input + struct swad__getLocationOutput *getLocationOut) // output { int ReturnCode; unsigned long MACnum; MYSQL_RES *mysql_res; - MYSQL_ROW row; unsigned NumLocs; - size_t Length; /***** Initializations *****/ API_Set_gSOAP_RuntimeEnv (soap); - Gbl.WebService.Function = API_getLocations; + Gbl.WebService.Function = API_getLocation; /***** Check web service key *****/ if ((ReturnCode = API_CheckWSKey (wsKey)) != SOAP_OK) @@ -5956,113 +5963,10 @@ int swad__getLocations (struct soap *soap, " ORDER BY rooms.Capacity DESC LIMIT 1", // Get the biggest room MACnum); - if (NumLocs) // Rooms found - { - /* Get next location */ - row = mysql_fetch_row (mysql_res); - /* - 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] - */ - - /* Get institution code (row[0]) */ - getLocationsOut->institutionCode = (int) Str_ConvertStrCodToLongCod (row[0]); - - /* Get institution short name (row[1]) */ - Length = strlen (row[1]); - getLocationsOut->institutionShortName = (char *) soap_malloc (soap,Length + 1); - Str_Copy (getLocationsOut->institutionShortName,row[1],Length); - - /* Get institution full name (row[2]) */ - Length = strlen (row[2]); - getLocationsOut->institutionFullName = (char *) soap_malloc (soap,Length + 1); - Str_Copy (getLocationsOut->institutionFullName,row[2],Length); - - /* Get center code (row[3]) */ - getLocationsOut->centerCode = (int) Str_ConvertStrCodToLongCod (row[3]); - - /* Get center short name (row[4]) */ - Length = strlen (row[4]); - getLocationsOut->centerShortName = (char *) soap_malloc (soap,Length + 1); - Str_Copy (getLocationsOut->centerShortName,row[4],Length); - - /* Get center full name (row[5]) */ - Length = strlen (row[5]); - getLocationsOut->centerFullName = (char *) soap_malloc (soap,Length + 1); - Str_Copy (getLocationsOut->centerFullName,row[5],Length); - - /* Get building code (row[6]) */ - getLocationsOut->buildingCode = (int) Str_ConvertStrCodToLongCod (row[6]); - - /* Get building short name (row[7]) */ - Length = strlen (row[7]); - getLocationsOut->buildingShortName = (char *) soap_malloc (soap,Length + 1); - Str_Copy (getLocationsOut->buildingShortName,row[7],Length); - - /* Get building full name (row[8]) */ - Length = strlen (row[8]); - getLocationsOut->buildingFullName = (char *) soap_malloc (soap,Length + 1); - Str_Copy (getLocationsOut->buildingFullName,row[8],Length); - - /* Get floor (row[9]) */ - getLocationsOut->floor = (int) Str_ConvertStrCodToLongCod (row[9]); - - /* Get room code (row[10]) */ - getLocationsOut->roomCode = (int) Str_ConvertStrCodToLongCod (row[10]); - - /* Get room short name (row[11]) */ - Length = strlen (row[11]); - getLocationsOut->roomShortName = (char *) soap_malloc (soap,Length + 1); - Str_Copy (getLocationsOut->roomShortName,row[11],Length); - - /* Get room full name (row[12]) */ - Length = strlen (row[12]); - getLocationsOut->roomFullName = (char *) soap_malloc (soap,Length + 1); - Str_Copy (getLocationsOut->roomFullName,row[12],Length); - } - else - { - /* No room found ==> reset output */ - getLocationsOut->institutionCode = -1; - getLocationsOut->institutionShortName = (char *) soap_malloc (soap,1); - getLocationsOut->institutionShortName[0] = '\0'; - getLocationsOut->institutionFullName = (char *) soap_malloc (soap,1); - getLocationsOut->institutionFullName[0] = '\0'; - - getLocationsOut->centerCode = -1; - getLocationsOut->centerShortName = (char *) soap_malloc (soap,1); - getLocationsOut->centerShortName[0] = '\0'; - getLocationsOut->centerFullName = (char *) soap_malloc (soap,1); - getLocationsOut->centerFullName[0] = '\0'; - - getLocationsOut->buildingCode = -1; - getLocationsOut->buildingShortName = (char *) soap_malloc (soap,1); - getLocationsOut->buildingShortName[0] = '\0'; - getLocationsOut->buildingFullName = (char *) soap_malloc (soap,1); - getLocationsOut->buildingFullName[0] = '\0'; - - getLocationsOut->floor = 0; - - getLocationsOut->roomCode = -1; - getLocationsOut->roomShortName = (char *) soap_malloc (soap,1); - getLocationsOut->roomShortName[0] = '\0'; - getLocationsOut->roomFullName = (char *) soap_malloc (soap,1); - getLocationsOut->roomFullName[0] = '\0'; - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); + API_GetDataOfLocation (soap, + &(getLocationOut->location), + NULL, // Don't get check in time + &mysql_res,NumLocs); return SOAP_OK; } @@ -6071,19 +5975,19 @@ int swad__getLocations (struct soap *soap, /***************** Check in (send user's current location) *******************/ /*****************************************************************************/ -int swad__sendCurrentLocation (struct soap *soap, - char *wsKey,int roomCode, // input - struct swad__sendCurrentLocationOutput *sendCurrentLocationOut) // output +int swad__sendMyLocation (struct soap *soap, + char *wsKey,int roomCode, // input + struct swad__sendMyLocationOutput *sendMyLocationOut) // output { int ReturnCode; long ChkCod; /***** Initializations *****/ API_Set_gSOAP_RuntimeEnv (soap); - Gbl.WebService.Function = API_sendCurrentLocation; + Gbl.WebService.Function = API_sendMyLocation; /***** Default values returned on error *****/ - sendCurrentLocationOut->success = 0; // error + sendMyLocationOut->success = 0; // error /***** Check web service key *****/ if ((ReturnCode = API_CheckWSKey (wsKey)) != SOAP_OK) @@ -6113,7 +6017,242 @@ int swad__sendCurrentLocation (struct soap *soap, Gbl.Usrs.Me.UsrDat.UsrCod,roomCode); /***** Return notification code *****/ - sendCurrentLocationOut->success = (ChkCod > 0) ? 1 : 0; + sendMyLocationOut->success = (ChkCod > 0) ? 1 : 0; return SOAP_OK; } + +/*****************************************************************************/ +/***************** Check in (send user's current location) *******************/ +/*****************************************************************************/ + +int swad__getLastLocation (struct soap *soap, + char *wsKey,int userCode, // input + struct swad__getLastLocationOutput *getLastLocationOut) // output + { + int ReturnCode; + MYSQL_RES *mysql_res; + unsigned NumLocs; + + /***** Initializations *****/ + API_Set_gSOAP_RuntimeEnv (soap); + Gbl.WebService.Function = API_getLastLocation; + + /***** Check web service key *****/ + if ((ReturnCode = API_CheckWSKey (wsKey)) != SOAP_OK) + return ReturnCode; + if (Gbl.Usrs.Me.UsrDat.UsrCod < 0) // Web service key does not exist in database + return soap_receiver_fault (soap, + "Bad web service key", + "Web service key does not exist in database"); + + /***** Check if I can see user's location *****/ + /* + I can only consult the location of another user + if the intersection of the centers of our courses is not empty. + The other user does not have to share any course with me, + but at least some course of each one has to share center. + */ + if (DB_QueryCOUNT ("can not get session data", + "SELECT COUNT(*) FROM " + "(SELECT DISTINCT degrees.CtrCod" + " FROM crs_usr,courses,degrees" + " WHERE crs_usr.UsrCod=%ld" + " AND crs_usr.CrsCod=courses.CrsCod" + " AND courses.DegCod=degrees.DegCod) AS C1," // centres of my courses + "(SELECT DISTINCT degrees.CtrCod" + " FROM crs_usr,courses,degrees" + " WHERE crs_usr.UsrCod=%d" + " AND crs_usr.CrsCod=courses.CrsCod" + " AND courses.DegCod=degrees.DegCod) AS C2" // centres of user's courses + " WHERE C1.CtrCod=C2.CtrCod", + Gbl.Usrs.Me.UsrDat.UsrCod, + userCode)) + { + /***** 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] + "UNIX_TIMESTAMP(room_check_in.CheckInTime)" // row[13] + " FROM room_check_in,rooms,buildings,centres,institutions" + " WHERE room_check_in.UsrCod=%d" + " AND room_check_in.ChkCod=" + "(SELECT ChkCod FROM room_check_in" + " WHERE UsrCod=%d" + " ORDER BY ChkCod DESC LIMIT 1)" // Faster than SELECT MAX + " AND room_check_in.RooCod=rooms.RooCod" + " AND rooms.BldCod=buildings.BldCod" + " AND buildings.CtrCod=centres.CtrCod" + " AND centres.InsCod=institutions.InsCod", + userCode,userCode); + API_GetDataOfLocation (soap, + &(getLastLocationOut->location), + &(getLastLocationOut->checkinTime), // Get check in time + &mysql_res,NumLocs); + } + else + { + /* I can not see user's location ==> reset output */ + API_ResetLocation (soap, &(getLastLocationOut->location)); + getLastLocationOut->checkinTime = 0L; + } + + return SOAP_OK; + } + +/*****************************************************************************/ +/************************* Get assignment data *******************************/ +/*****************************************************************************/ + +static void API_GetDataOfLocation (struct soap *soap, + struct swad__location *location, + time_t *CheckInTime, + MYSQL_RES **mysql_res, + unsigned NumLocs) + { + MYSQL_ROW row; + size_t Length; + + /***** Get data of location from database *****/ + if (NumLocs) // Rooms found + { + /* Get row */ + row = mysql_fetch_row (*mysql_res); + /* + 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] (optional) + */ + + /* Get institution code (row[0]) */ + location->institutionCode = (int) Str_ConvertStrCodToLongCod (row[0]); + + /* Get institution short name (row[1]) */ + Length = strlen (row[1]); + location->institutionShortName = (char *) soap_malloc (soap,Length + 1); + Str_Copy (location->institutionShortName,row[1],Length); + + /* Get institution full name (row[2]) */ + Length = strlen (row[2]); + location->institutionFullName = (char *) soap_malloc (soap,Length + 1); + Str_Copy (location->institutionFullName,row[2],Length); + + /* Get center code (row[3]) */ + location->centerCode = (int) Str_ConvertStrCodToLongCod (row[3]); + + /* Get center short name (row[4]) */ + Length = strlen (row[4]); + location->centerShortName = (char *) soap_malloc (soap,Length + 1); + Str_Copy (location->centerShortName,row[4],Length); + + /* Get center full name (row[5]) */ + Length = strlen (row[5]); + location->centerFullName = (char *) soap_malloc (soap,Length + 1); + Str_Copy (location->centerFullName,row[5],Length); + + /* Get building code (row[6]) */ + location->buildingCode = (int) Str_ConvertStrCodToLongCod (row[6]); + + /* Get building short name (row[7]) */ + Length = strlen (row[7]); + location->buildingShortName = (char *) soap_malloc (soap,Length + 1); + Str_Copy (location->buildingShortName,row[7],Length); + + /* Get building full name (row[8]) */ + Length = strlen (row[8]); + location->buildingFullName = (char *) soap_malloc (soap,Length + 1); + Str_Copy (location->buildingFullName,row[8],Length); + + /* Get floor (row[9]) */ + location->floor = (int) Str_ConvertStrCodToLongCod (row[9]); + + /* Get room code (row[10]) */ + location->roomCode = (int) Str_ConvertStrCodToLongCod (row[10]); + + /* Get room short name (row[11]) */ + Length = strlen (row[11]); + location->roomShortName = (char *) soap_malloc (soap,Length + 1); + Str_Copy (location->roomShortName,row[11],Length); + + /* Get room full name (row[12]) */ + Length = strlen (row[12]); + location->roomFullName = (char *) soap_malloc (soap,Length + 1); + Str_Copy (location->roomFullName,row[12],Length); + + /* Get check in time (row[13]) */ + if (CheckInTime) + { + *CheckInTime = 0L; + if (row[13]) + sscanf (row[13],"%ld",CheckInTime); + } + } + else + { + /* No room found ==> reset output */ + API_ResetLocation (soap,location); + + if (CheckInTime) + *CheckInTime = 0L; + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (mysql_res); + } + +/*****************************************************************************/ +/************************* Get assignment data *******************************/ +/*****************************************************************************/ + +static void API_ResetLocation (struct soap *soap, + struct swad__location *location) + { + location->institutionCode = -1; + location->institutionShortName = (char *) soap_malloc (soap,1); + location->institutionShortName[0] = '\0'; + location->institutionFullName = (char *) soap_malloc (soap,1); + location->institutionFullName[0] = '\0'; + + location->centerCode = -1; + location->centerShortName = (char *) soap_malloc (soap,1); + location->centerShortName[0] = '\0'; + location->centerFullName = (char *) soap_malloc (soap,1); + location->centerFullName[0] = '\0'; + + location->buildingCode = -1; + location->buildingShortName = (char *) soap_malloc (soap,1); + location->buildingShortName[0] = '\0'; + location->buildingFullName = (char *) soap_malloc (soap,1); + location->buildingFullName[0] = '\0'; + + location->floor = 0; + + location->roomCode = -1; + location->roomShortName = (char *) soap_malloc (soap,1); + location->roomShortName[0] = '\0'; + location->roomFullName = (char *) soap_malloc (soap,1); + location->roomFullName[0] = '\0'; + } diff --git a/swad_API.h b/swad_API.h index 1657c1ad1..32d769a57 100644 --- a/swad_API.h +++ b/swad_API.h @@ -31,7 +31,7 @@ /***************************** Public constants ******************************/ /*****************************************************************************/ -#define API_NUM_FUNCTIONS 33 +#define API_NUM_FUNCTIONS 34 /*****************************************************************************/ /******************************* Public types ********************************/ @@ -72,8 +72,9 @@ typedef enum API_getMatches = 29, API_getMatchStatus = 30, API_answerMatchQuestion = 31, - API_getLocations = 32, - API_sendCurrentLocation = 33, + API_getLocation = 32, + API_sendMyLocation = 33, + API_getLastLocation = 34, } API_Function_t; /*****************************************************************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 879156359..338afb916 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -556,12 +556,15 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.247.1 (2020-05-25)" +#define Log_PLATFORM_VERSION "SWAD 19.248 (2020-05-25)" #define CSS_FILE "swad19.238.2.css" #define JS_FILE "swad19.246.1.js" /* + + Version 19.248.1: May 30, 2020 Exam session results can not be marked as visible if end of time is not in the past. (? lines) + Version 19.248: May 30, 2020 New API function getLastLocation. (302787 lines) Version 19.247.1: May 29, 2020 Do not show exam results in hidden exams or hidden exam sessions. (302646 lines) - Version 19.247: May 24, 2020 New API function getCurrentLocation. (302622 lines) + Version 19.247: May 24, 2020 New API function sendMyCurrentLocation. (302622 lines) 1 change necessary in database: CREATE TABLE IF NOT EXISTS room_check_in (ChkCod INT NOT NULL AUTO_INCREMENT,UsrCod INT NOT NULL,RooCod INT NOT NULL,CheckInTime DATETIME NOT NULL,UNIQUE INDEX(ChkCod),INDEX(UsrCod,CheckInTime),INDEX(CheckInTime)); If you want to use MyISAM: diff --git a/swad_search.c b/swad_search.c index 377f258c8..c53c44cb0 100644 --- a/swad_search.c +++ b/swad_search.c @@ -44,7 +44,7 @@ /*****************************************************************************/ #define Sch_MIN_LENGTH_LONGEST_WORD 3 -#define Sch_MIN_LENGTH_TOTAL 3 // "A An" is not valid; "A An Ann" is valid +#define Sch_MIN_LENGTH_TOTAL 6 // "An Ann" is not valid; "A An Ann" is valid /*****************************************************************************/ /****************************** Private types ********************************/