Version19.214

This commit is contained in:
acanas 2020-05-06 21:27:06 +02:00
parent 37c672fc89
commit 8a3c93c948
9 changed files with 278 additions and 16 deletions

View File

@ -440,6 +440,36 @@ struct swad__sendMessageOutput
struct swad__usersArray usersArray;
};
/* structs used in getLocations */
struct swad__location
{
int institutionCode;
char *institutionShortName;
char *institutionFullName;
int centerCode;
char *centerShortName;
char *centerFullName;
int buildingCode;
char *buildingShortName;
char *buildingFullName;
int floor;
int roomCode;
char *roomShortName;
char *roomFullName;
};
struct swad__locationsArray
{
struct swad__location *__ptr; // pointer to array
int __size; // number of elements pointed to
};
/* getLocations */
struct swad__getLocationsOutput
{
int numLocations;
struct swad__locationsArray locationsArray;
};
/*****************************************************************************/
/*************************** Web service functions ***************************/
/*****************************************************************************/
@ -523,3 +553,7 @@ int swad__sendNotice (char *wsKey,int courseCode,char *body,
struct swad__sendNoticeOutput *sendNoticeOut);
int swad__sendMessage (char *wsKey,int messageCode,char *to,char *subject,char *body,
struct swad__sendMessageOutput *sendMessageOut);
/* Wi-Fi-based positioning system */
int swad__getLocations (char *wsKey,char *MAC,
struct swad__getLocationsOutput *getLocationsOut);

View File

@ -13339,6 +13339,28 @@ UPDATE usr_data SET InsCod=1130 WHERE InsCod=25037;
ALTER TABLE rooms CHANGE COLUMN BldCod BldCod INT NOT NULL DEFAULT -1;
--------------------
INSERT INTO room_MAC (RooCod,MAC) VALUES (1,0xf07f0667d5ff);
INSERT INTO room_MAC (RooCod,MAC) VALUES (2,0x6886a731695f);
INSERT INTO room_MAC (RooCod,MAC) VALUES (108,0xccd53989961f);
mysql> SELECT RooCod,HEX(MAC) FROM room_MAC;
+--------+--------------+
| RooCod | HEX(MAC) |
+--------+--------------+
| 1 | F07F0667D5FF |
| 2 | 6886A731695F |
| 108 | CCD53989961F |
+--------+--------------+
3 rows in set (0.00 sec)
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 FROM room_MAC,rooms,buildings,centres,institutions WHERE room_MAC.MAC=0xCCD53989961F AND room_MAC.RooCod=rooms.RooCod AND rooms.BldCod=buildings.BldCod AND buildings.CtrCod=centres.CtrCod AND centres.InsCod=institutions.InsCod ORDER BY institutions.FullName,centres.FullName,buildings.FullName,rooms.Floor,rooms.FullName;
-------------------------------

View File

@ -1264,7 +1264,7 @@ CREATE TABLE IF NOT EXISTS projects (
INDEX(CrsCod,ModifTime),
INDEX(CrsCod,DptCod));
--
-- Table rooms: stores the classrooms associated to each centre
-- Table rooms: stores the rooms associated to each centre
--
CREATE TABLE IF NOT EXISTS rooms (
RooCod INT NOT NULL AUTO_INCREMENT,
@ -1278,6 +1278,14 @@ CREATE TABLE IF NOT EXISTS rooms (
UNIQUE INDEX(RooCod),
INDEX(CtrCod,BldCod,Floor));
--
-- Table room_MAC: stores the associations between rooms and MAC addresses
--
CREATE TABLE IF NOT EXISTS room_MAC (
RooCod INT NOT NULL AUTO_INCREMENT,
MAC BIGINT NOT NULL,
UNIQUE INDEX(RooCod,MAC),
UNIQUE INDEX(MAC,RooCod));
--
-- Table sessions: stores the information of open sessions
--
CREATE TABLE IF NOT EXISTS sessions (

View File

@ -166,6 +166,7 @@ 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
};
/* Web service roles (they do not match internal swad-core roles) */
@ -5017,7 +5018,7 @@ int swad__getMatches (struct soap *soap,
" (SELECT mch_groups.MchCod"
" FROM mch_groups,crs_grp_usr"
" WHERE crs_grp_usr.UsrCod=%ld"
" AND mch_groups.GrpCod=crs_grp_usr.GrpCod))",
" AND mch_groups.GrpCod=crs_grp_usr.GrpCod))"
" ORDER BY MchCod",
Game.GamCod,
Gbl.Usrs.Me.UsrDat.UsrCod);
@ -5887,3 +5888,168 @@ int swad__getMarks (struct soap *soap,
return SOAP_OK;
}
/*****************************************************************************/
/**************** Get locations associated to a MAC address ******************/
/*****************************************************************************/
int swad__getLocations (struct soap *soap,
char *wsKey,char *MAC, // input
struct swad__getLocationsOutput *getLocationsOut) // output
{
int ReturnCode;
unsigned long MACnum;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumLocs;
unsigned NumLoc;
size_t Length;
/***** Initializations *****/
API_Set_gSOAP_RuntimeEnv (soap);
Gbl.WebService.Function = API_getLocations;
/***** 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");
/***** Get some of my data *****/
if (!API_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,Gbl.Hierarchy.Crs.CrsCod))
return soap_receiver_fault (soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Convert MAC string to number *****/
if (sscanf (MAC,"%lx",&MACnum) != 1)
return soap_receiver_fault (soap,
"Bad MAC",
"MAC address format should be 12 hexadecimal digits");
/***** 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]
" FROM room_MAC,rooms,buildings,centres,institutions"
" WHERE room_MAC.MAC=%lu"
" AND room_MAC.RooCod=rooms.RooCod"
" AND rooms.BldCod=buildings.BldCod"
" AND buildings.CtrCod=centres.CtrCod"
" AND centres.InsCod=institutions.InsCod"
" ORDER BY institutions.FullName,"
"centres.FullName,"
"buildings.FullName,"
"rooms.Floor,"
"rooms.FullName",
MACnum);
getLocationsOut->locationsArray.__size =
getLocationsOut->numLocations = (int) NumLocs;
if (getLocationsOut->numLocations == 0)
getLocationsOut->locationsArray.__ptr = NULL;
else // Matches found
{
getLocationsOut->locationsArray.__ptr = soap_malloc (soap,
(getLocationsOut->locationsArray.__size) *
sizeof (*(getLocationsOut->locationsArray.__ptr)));
for (NumLoc = 0;
NumLoc < NumLocs;
NumLoc++)
{
/* 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->locationsArray.__ptr[NumLoc].institutionCode = (int) Str_ConvertStrCodToLongCod (row[0]);
/* Get institution short name (row[1]) */
Length = strlen (row[1]);
getLocationsOut->locationsArray.__ptr[NumLoc].institutionShortName = (char *) soap_malloc (soap,Length + 1);
Str_Copy (getLocationsOut->locationsArray.__ptr[NumLoc].institutionShortName,row[1],Length);
/* Get institution full name (row[2]) */
Length = strlen (row[2]);
getLocationsOut->locationsArray.__ptr[NumLoc].institutionFullName = (char *) soap_malloc (soap,Length + 1);
Str_Copy (getLocationsOut->locationsArray.__ptr[NumLoc].institutionFullName,row[2],Length);
/* Get center code (row[3]) */
getLocationsOut->locationsArray.__ptr[NumLoc].centerCode = (int) Str_ConvertStrCodToLongCod (row[3]);
/* Get center short name (row[4]) */
Length = strlen (row[4]);
getLocationsOut->locationsArray.__ptr[NumLoc].centerShortName = (char *) soap_malloc (soap,Length + 1);
Str_Copy (getLocationsOut->locationsArray.__ptr[NumLoc].centerShortName,row[4],Length);
/* Get center full name (row[5]) */
Length = strlen (row[5]);
getLocationsOut->locationsArray.__ptr[NumLoc].centerFullName = (char *) soap_malloc (soap,Length + 1);
Str_Copy (getLocationsOut->locationsArray.__ptr[NumLoc].centerFullName,row[5],Length);
/* Get building code (row[6]) */
getLocationsOut->locationsArray.__ptr[NumLoc].buildingCode = (int) Str_ConvertStrCodToLongCod (row[6]);
/* Get building short name (row[7]) */
Length = strlen (row[7]);
getLocationsOut->locationsArray.__ptr[NumLoc].buildingShortName = (char *) soap_malloc (soap,Length + 1);
Str_Copy (getLocationsOut->locationsArray.__ptr[NumLoc].buildingShortName,row[7],Length);
/* Get building full name (row[8]) */
Length = strlen (row[8]);
getLocationsOut->locationsArray.__ptr[NumLoc].buildingFullName = (char *) soap_malloc (soap,Length + 1);
Str_Copy (getLocationsOut->locationsArray.__ptr[NumLoc].buildingFullName,row[8],Length);
/* Get floor (row[9]) */
getLocationsOut->locationsArray.__ptr[NumLoc].floor = (int) Str_ConvertStrCodToLongCod (row[9]);
/* Get room code (row[10]) */
getLocationsOut->locationsArray.__ptr[NumLoc].roomCode = (int) Str_ConvertStrCodToLongCod (row[10]);
/* Get room short name (row[11]) */
Length = strlen (row[11]);
getLocationsOut->locationsArray.__ptr[NumLoc].roomShortName = (char *) soap_malloc (soap,Length + 1);
Str_Copy (getLocationsOut->locationsArray.__ptr[NumLoc].roomShortName,row[11],Length);
/* Get room full name (row[12]) */
Length = strlen (row[12]);
getLocationsOut->locationsArray.__ptr[NumLoc].roomFullName = (char *) soap_malloc (soap,Length + 1);
Str_Copy (getLocationsOut->locationsArray.__ptr[NumLoc].roomFullName,row[12],Length);
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return SOAP_OK;
}

View File

@ -31,7 +31,7 @@
/***************************** Public constants ******************************/
/*****************************************************************************/
#define API_NUM_FUNCTIONS 31
#define API_NUM_FUNCTIONS 32
/*****************************************************************************/
/******************************* Public types ********************************/
@ -72,6 +72,7 @@ typedef enum
API_getMatches = 29,
API_getMatchStatus = 30,
API_answerMatchQuestion = 31,
API_getLocations = 32,
} API_Function_t;
/*****************************************************************************/

View File

@ -481,6 +481,7 @@ contiene una de las que yo imparto. As
/* TODO: Geolocalización:
Función API sendCurrentLocation...
Parámetros a enviar a la función:
1. Código único de ubicación (número)
@ -502,11 +503,13 @@ Funci
Paramétros: MAC, string con ubicación (ej. "Aula 0.1")
Función API getLocations
1. Añadir tipo de ubicación
2. Añadir lista desplegable de MAC asociadas a una ubicación
3. API: getLocations (como parámetro se pasa la MAC)
- que devolveria las filas de la tabla de ubicaciones asociadas a esa MAC
Función de la API para ver dónde se encuentra un usuario:
getUserLocation
Un usuario sólo podrá consultar la ubicación de otro usuario
si la intersección de los centros de sus asignaturas no es vacía,
es decir, no tienen por qué compartir asignaturas,
pero al menos alguna asignatura de cada uno tiene que compartir el centro
(Por ej. Eva y Antonio comparten ETSIIT, pero no titulación ni asignatura)
*/
// TODO: Sugerencia de Jesús García Miranda. En las preguntas de tipo test de elección única (o un nuevo tipo con un nuevo nombre),
@ -525,6 +528,7 @@ Funci
// TODO: Integrar pull requests con traducciones del alemán del usuario eruedin en GitHub
// TODO: Cambiar icono notificaciones nuevas con "bell-on.svg"
// TODO: Ahmed El Moukhtari Koubaa: Cuando le damos a la opción de mostrar solo los mensajes no leídos, se muestran estos mensajes, pero cuando los intentamos leer, es decir, hacemos clic sobre ellos se recarga toda la página por así decirlo y vuelve a dar una lista con los mensajes, pero descartando aquel que clicamos porque, entiendo yo al menos, que ya lo ha marcado como leído.
// TODO: Cambiar "centre" a "center"
/*****************************************************************************/
/****************************** Public constants *****************************/
@ -544,11 +548,18 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
#define Log_PLATFORM_VERSION "SWAD 19.213.1 (2020-05-06)"
#define Log_PLATFORM_VERSION "SWAD 19.214 (2020-05-06)"
#define CSS_FILE "swad19.193.1.css"
#define JS_FILE "swad19.193.1.js"
/*
Version 19.213.2: May 06, 2020 Change color of dates on current exam event. (? lines)
Version 19.214.1: May 06, 2020 Change color of dates on current exam event. (? lines)
Version 19.214: May 05, 2020 New API function getLocations. (301568 lines)
1 change necessary in database:
CREATE TABLE IF NOT EXISTS room_MAC (RooCod INT NOT NULL AUTO_INCREMENT,MAC BIGINT NOT NULL,UNIQUE INDEX(RooCod,MAC),UNIQUE INDEX(MAC,RooCod));
If you want to use MyISAM:
ALTER TABLE room_MAC ENGINE=MyISAM;
Version 19.213.2: May 06, 2020 Changed settings of firewall. (301361 lines)
Version 19.213.1: May 06, 2020 Fixed bug in edition of set of questions. (301357 lines)
Version 19.213: May 06, 2020 Edition of exam event.
Code refactoring in groups. (301327 lines)

View File

@ -2691,6 +2691,23 @@ mysql> DESCRIBE rooms;
"UNIQUE INDEX(RooCod),"
"INDEX(CtrCod,BldCod,Floor))");
/***** Table room_MAC *****/
/*
mysql> DESCRIBE room_MAC;
+--------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------+------+-----+---------+----------------+
| RooCod | int(11) | NO | PRI | NULL | auto_increment |
| MAC | bigint(20) | NO | PRI | NULL | |
+--------+------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS room_MAC ("
"RooCod INT NOT NULL AUTO_INCREMENT,"
"MAC BIGINT NOT NULL," // 12 digits hexadecimal number
"UNIQUE INDEX(RooCod,MAC),"
"UNIQUE INDEX(MAC,RooCod))");
/***** Table sessions *****/
/*
mysql> DESCRIBE sessions;

View File

@ -1983,14 +1983,16 @@ void Exa_ReceiveFormExam (void)
ItsANewExam = (Exam.ExaCod <= 0);
/***** Get all current exam data from database *****/
// Some data are necessary to show exam and sets of questions again
// Some data, not received from form,
// are necessary to show exam and sets of questions again
if (!ItsANewExam)
{
Exa_GetDataOfExamByCod (&Exam);
Exams.ExaCod = Exam.ExaCod;
}
/***** If I can edit exams ==> receive some data of exam from form *****/
/***** If I can edit exams ==>
overwrite some exam data with the data received from form *****/
Exa_ReceiveExamFieldsFromForm (&Exam,Txt);
if (Exa_CheckExamFieldsReceivedFromForm (&Exam))
{

View File

@ -43,8 +43,9 @@ extern struct Globals Gbl;
/* The maximum number of clicks in the interval
should be large enough to prevent an IP from being banned
due to automatic refresh when the user is viewing the last clicks. */
#define Fw_CHECK_INTERVAL ((time_t)(10UL)) // Check clicks in the last 10 seconds
#define Fw_MAX_CLICKS_IN_INTERVAL 100 // Maximum of 100 clicks allowed in 10 seconds
#define Fw_CHECK_INTERVAL ((time_t)(30UL)) // Check clicks in the last 30 seconds
#define Fw_MAX_CLICKS_IN_INTERVAL 150 // Maximum of 150 clicks allowed in 30 seconds
// (5 clicks/s sustained for 30 s)
#define Fw_TIME_BANNED ((time_t)(60UL*60UL)) // Ban IP for 1 hour