swad-core/swad_connected.c

762 lines
28 KiB
C
Raw Normal View History

2014-12-01 23:55:08 +01:00
// swad_connected.c: connected users
/*
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-2023 Antonio Ca<EFBFBD>as Vargas
2014-12-01 23:55:08 +01:00
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 *********************************/
/*****************************************************************************/
2019-12-30 22:32:06 +01:00
#define _GNU_SOURCE // For asprintf
2014-12-01 23:55:08 +01:00
#include <limits.h> // For maximum values
#include <linux/limits.h> // For PATH_MAX
2019-12-29 12:39:00 +01:00
#include <stddef.h> // For NULL
2019-12-30 22:32:06 +01:00
#include <stdio.h> // For asprintf
2020-01-03 22:16:51 +01:00
#include <stdlib.h> // For free
2014-12-01 23:55:08 +01:00
#include <string.h> // For string functions
#include "swad_action_list.h"
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
#include "swad_connected.h"
#include "swad_connected_database.h"
2014-12-01 23:55:08 +01:00
#include "swad_database.h"
#include "swad_error.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2014-12-01 23:55:08 +01:00
#include "swad_global.h"
2021-02-11 22:57:09 +01:00
#include "swad_hierarchy_level.h"
2019-10-23 19:05:05 +02:00
#include "swad_HTML.h"
2019-12-14 14:30:34 +01:00
#include "swad_log.h"
2014-12-01 23:55:08 +01:00
#include "swad_parameter.h"
#include "swad_photo.h"
2019-09-28 15:03:22 +02:00
#include "swad_role.h"
2014-12-01 23:55:08 +01:00
#include "swad_string.h"
#include "swad_user.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
2019-11-21 16:47:07 +01:00
/**************************** Private prototypes *****************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2020-04-08 13:40:21 +02:00
static void Con_PutIconToUpdateConnected (__attribute__((unused)) void *Args);
static void Con_PutParScope (__attribute__((unused)) void *Args);
2016-03-24 13:50:57 +01:00
2017-01-30 17:45:16 +01:00
static void Con_ShowGlobalConnectedUsrsRole (Rol_Role_t Role,unsigned UsrsTotal);
2015-12-20 01:41:07 +01:00
static void Con_ComputeConnectedUsrsWithARoleBelongingToCurrentCrs (Rol_Role_t Role);
2016-03-15 19:41:01 +01:00
static void Con_ShowConnectedUsrsBelongingToLocation (void);
2015-12-20 01:41:07 +01:00
2014-12-01 23:55:08 +01:00
static void Con_ShowConnectedUsrsWithARoleBelongingToCurrentLocationOnMainZone (Rol_Role_t Role);
2016-03-15 22:15:25 +01:00
static void Con_ShowConnectedUsrsWithARoleBelongingToCurrentCrsOnRightColumn (Rol_Role_t Role);
2017-01-30 17:45:16 +01:00
static unsigned Con_GetConnectedUsrsTotal (Rol_Role_t Role);
static void Con_GetNumConnectedWithARoleBelongingToCurrentScope (Rol_Role_t Role,
struct Con_ConnectedUsrs *Usrs);
2014-12-01 23:55:08 +01:00
static void Con_ComputeConnectedUsrsWithARoleCurrentCrsOneByOne (Rol_Role_t Role);
static void Con_ShowConnectedUsrsCurrentCrsOneByOneOnRightColumn (Rol_Role_t Role);
static void Con_WriteRowConnectedUsrOnRightColumn (Rol_Role_t Role);
static void Con_ShowConnectedUsrsCurrentLocationOneByOneOnMainZone (Rol_Role_t Role);
/*****************************************************************************/
/************************** Show connected users *****************************/
/*****************************************************************************/
void Con_ShowConnectedUsrs (void)
{
2016-11-21 18:12:23 +01:00
extern const char *Hlp_USERS_Connected;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Connected_users;
extern const char *Txt_Sessions;
extern const char *Txt_Connected_PLURAL;
2019-12-30 22:32:06 +01:00
char *Title;
2014-12-01 23:55:08 +01:00
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
2015-09-22 23:58:18 +02:00
if (Gbl.Usrs.Me.Logged)
{
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuBegin ();
Log_PutLinkToLastClicks (); // Show last clicks in real time
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2015-09-22 23:58:18 +02:00
}
2016-03-15 19:41:01 +01:00
/***** Get scope *****/
Sco_SetScopesForListingStudents ();
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeCon");
2015-03-24 19:41:54 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2015-03-24 19:41:54 +01:00
/* Current time */
2019-12-30 22:32:06 +01:00
if (asprintf (&Title,"%s"
"<div id=\"connected_current_time\">"
"</div>",
2019-12-30 22:32:06 +01:00
Txt_Connected_users) < 0)
Err_NotEnoughMemoryExit ();
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Title,
2020-04-08 13:40:21 +02:00
Con_PutIconToUpdateConnected,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Connected,Box_NOT_CLOSABLE);
2019-12-30 22:32:06 +01:00
free (Title);
2015-12-30 18:52:45 +01:00
/***** Current time *****/
Dat_WriteLocalDateHMSFromUTC ("connected_current_time",Dat_GetStartExecutionTimeUTC (),
Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA,
false,false,true,0x7);
2014-12-01 23:55:08 +01:00
/***** Number of connected users in the whole platform *****/
HTM_FIELDSET_Begin ("class=\"CON CON_%s\"",The_GetSuffix ());
HTM_LEGEND (Txt_Sessions);
Con_ShowGlobalConnectedUsrs ();
HTM_FIELDSET_End ();
/***** Show connected users in the current location *****/
if (Gbl.Scope.Current != HieLvl_UNK)
{
HTM_FIELDSET_Begin ("class=\"CON CON_%s\"",The_GetSuffix ());
HTM_LEGEND (Txt_Connected_PLURAL);
Con_ShowConnectedUsrsBelongingToLocation ();
HTM_FIELDSET_End ();
}
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2014-12-01 23:55:08 +01:00
}
2016-03-24 13:50:57 +01:00
/*****************************************************************************/
/******************** Put icon to update connected users *********************/
/*****************************************************************************/
2020-04-08 13:40:21 +02:00
static void Con_PutIconToUpdateConnected (__attribute__((unused)) void *Args)
2016-03-24 13:50:57 +01:00
{
Ico_PutContextualIconToUpdate (ActLstCon,NULL,
Con_PutParScope,NULL);
}
static void Con_PutParScope (__attribute__((unused)) void *Args)
{
Sco_PutParScope ("ScopeCon",Gbl.Scope.Current);
2016-03-24 13:50:57 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/******************** Show total number of connected users *******************/
/*****************************************************************************/
void Con_ShowGlobalConnectedUsrs (void)
{
extern const char *Txt_Sessions;
2016-03-15 10:21:56 +01:00
extern const char *Txt_Connected_users;
2014-12-01 23:55:08 +01:00
extern const char *Txt_session;
extern const char *Txt_sessions;
extern const char *Txt_user[Usr_NUM_SEXS];
2016-06-27 12:35:15 +02:00
extern const char *Txt_users[Usr_NUM_SEXS];
2017-01-30 19:02:13 +01:00
Rol_Role_t Role;
unsigned NumUsrs[Rol_NUM_ROLES];
unsigned NumUsrsTotal;
/***** Get number of connected users *****/
2017-05-18 19:13:41 +02:00
for (Role = Rol_GST, NumUsrsTotal = 0;
2017-01-30 19:02:13 +01:00
Role <= Rol_SYS_ADM;
Role++)
{
NumUsrs[Role] = Con_GetConnectedUsrsTotal (Role);
NumUsrsTotal += NumUsrs[Role];
}
2014-12-01 23:55:08 +01:00
/***** Number of sessions *****/
/* Link to view more details about connected users */
Frm_BeginForm (ActLstCon);
HTM_BUTTON_Submit_Begin (Txt_Connected_users,"class=\"BT_LINK\"");
2014-12-01 23:55:08 +01:00
/* Write total number of sessions */
HTM_TxtF ("%u&nbsp;%s",Gbl.Session.NumSessions,
Gbl.Session.NumSessions == 1 ? Txt_session :
Txt_sessions);
2016-03-15 19:41:01 +01:00
HTM_BUTTON_End ();
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
if (NumUsrsTotal)
{
HTM_DIV_Begin ("class=\"CON_LIST\"");
/***** Write total number of users *****/
HTM_TxtF ("%u&nbsp;%s:",NumUsrsTotal,
NumUsrsTotal == 1 ? Txt_user[Usr_SEX_UNKNOWN] :
Txt_users[Usr_SEX_UNKNOWN]);
/***** Write total number of users with each role *****/
for (Role = Rol_GST, NumUsrsTotal = 0;
Role <= Rol_SYS_ADM;
Role++)
Con_ShowGlobalConnectedUsrsRole (Role,NumUsrs[Role]);
2016-03-15 10:21:56 +01:00
HTM_DIV_End ();
}
2014-12-01 23:55:08 +01:00
}
2017-01-30 17:45:16 +01:00
static void Con_ShowGlobalConnectedUsrsRole (Rol_Role_t Role,unsigned UsrsTotal)
{
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
extern const char *Txt_ROLES_PLURAL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
if (UsrsTotal)
2019-11-09 21:03:02 +01:00
{
2019-11-09 21:08:20 +01:00
HTM_BR ();
2019-11-11 10:59:24 +01:00
HTM_TxtF ("%u&nbsp;%s",UsrsTotal,
UsrsTotal == 1 ? Txt_ROLES_SINGUL_abc[Role][Usr_SEX_UNKNOWN] :
Txt_ROLES_PLURAL_abc[Role][Usr_SEX_UNKNOWN]);
2019-11-09 21:03:02 +01:00
}
2017-01-30 17:45:16 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/*********** Compute connected users who belong to current course ************/
/*****************************************************************************/
void Con_ComputeConnectedUsrsBelongingToCurrentCrs (void)
{
2015-12-20 01:41:07 +01:00
if ((Gbl.Prefs.SideCols & Lay_SHOW_RIGHT_COLUMN) && // Right column visible
Gbl.Hierarchy.Level == HieLvl_CRS && // Course selected
2015-12-20 01:41:07 +01:00
(Gbl.Usrs.Me.IBelongToCurrentCrs || // I can view users
2017-06-04 18:18:54 +02:00
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM))
2015-12-20 01:41:07 +01:00
{
Gbl.Usrs.Connected.NumUsrs = 0;
Gbl.Usrs.Connected.NumUsrsToList = 0;
Gbl.Scope.Current = HieLvl_CRS;
2015-12-20 01:41:07 +01:00
/***** Number of teachers *****/
2017-05-18 19:13:41 +02:00
Con_ComputeConnectedUsrsWithARoleBelongingToCurrentCrs (Rol_TCH);
2015-12-20 01:41:07 +01:00
2017-05-20 12:04:12 +02:00
/***** Number of non-editing teachers *****/
2017-05-21 21:23:13 +02:00
Con_ComputeConnectedUsrsWithARoleBelongingToCurrentCrs (Rol_NET);
2017-05-20 12:04:12 +02:00
2015-12-20 01:41:07 +01:00
/***** Number of students *****/
2017-05-18 19:13:41 +02:00
Con_ComputeConnectedUsrsWithARoleBelongingToCurrentCrs (Rol_STD);
2015-12-20 01:41:07 +01:00
}
}
/*****************************************************************************/
/** Compute number of connected users of a type who belong to current course */
/*****************************************************************************/
2014-12-01 23:55:08 +01:00
2015-12-20 01:41:07 +01:00
static void Con_ComputeConnectedUsrsWithARoleBelongingToCurrentCrs (Rol_Role_t Role)
{
/***** Get number of connected users who belong to current course *****/
Con_GetNumConnectedWithARoleBelongingToCurrentScope (Role,&Gbl.Usrs.Connected.Usrs[Role]);
2014-12-01 23:55:08 +01:00
2015-12-20 01:41:07 +01:00
/***** Get list connected users belonging to this course *****/
Con_ComputeConnectedUsrsWithARoleCurrentCrsOneByOne (Role);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2015-12-20 01:41:07 +01:00
/****** Show number of connected users who belong to current location ********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-03-15 19:41:01 +01:00
static void Con_ShowConnectedUsrsBelongingToLocation (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_from;
struct Con_ConnectedUsrs Usrs;
2014-12-01 23:55:08 +01:00
/***** Number of connected users who belong to scope *****/
Con_GetNumConnectedWithARoleBelongingToCurrentScope (Rol_UNK,&Usrs);
/* Write number of connected users */
HTM_TxtF ("%u %s ",Usrs.NumUsrs,Txt_from);
2016-03-15 19:41:01 +01:00
/* Put form to change scope */
Frm_BeginForm (ActLstCon);
Sco_PutSelectorScope ("ScopeCon",HTM_SUBMIT_ON_CHANGE);
Frm_EndForm ();
2016-03-15 19:41:01 +01:00
/***** Number of teachers and students *****/
HTM_TABLE_Begin ("CON_LIST");
Con_ShowConnectedUsrsWithARoleBelongingToCurrentLocationOnMainZone (Rol_TCH);
Con_ShowConnectedUsrsWithARoleBelongingToCurrentLocationOnMainZone (Rol_NET);
Con_ShowConnectedUsrsWithARoleBelongingToCurrentLocationOnMainZone (Rol_STD);
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
Con_ShowConnectedUsrsWithARoleBelongingToCurrentLocationOnMainZone (Rol_GST);
HTM_TABLE_End ();
2017-05-29 15:00:23 +02:00
/***** Put link to register students *****/
Enr_CheckStdsAndPutButtonToRegisterStdsInCurrentCrs ();
2016-03-15 19:41:01 +01:00
}
/*****************************************************************************/
/* Show number of connected users who belong to current course on right col. */
/*****************************************************************************/
2016-03-15 22:15:25 +01:00
void Con_ShowConnectedUsrsBelongingToCurrentCrs (void)
2016-03-15 19:41:01 +01:00
{
2016-03-15 22:15:25 +01:00
extern const char *Txt_Connected_users;
2016-03-15 19:41:01 +01:00
extern const char *Txt_from;
2021-02-11 22:57:09 +01:00
char CourseName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1];
struct Con_ConnectedUsrs Usrs;
2016-03-15 19:41:01 +01:00
2019-04-03 20:57:04 +02:00
/***** Trivial check *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Hierarchy.Crs.CrsCod <= 0) // No course selected
2016-03-15 19:41:01 +01:00
return;
/***** Number of connected users who belong to course *****/
/* Link to view more details about connected users */
Frm_BeginForm (ActLstCon);
HTM_BUTTON_Submit_Begin (Txt_Connected_users,"class=\"BT_LINK\"");
Str_Copy (CourseName,Gbl.Hierarchy.Crs.ShrtName,sizeof (CourseName) - 1);
Con_GetNumConnectedWithARoleBelongingToCurrentScope (Rol_UNK,&Usrs);
HTM_TxtF ("%u %s %s",Usrs.NumUsrs,Txt_from,CourseName);
HTM_BUTTON_End ();
Frm_EndForm ();
/***** Number of teachers and students *****/
HTM_TABLE_Begin ("CON_LIST");
Gbl.Usrs.Connected.NumUsr = 0;
Gbl.Usrs.Connected.NumUsrs = 0;
Gbl.Usrs.Connected.NumUsrsToList = 0;
Con_ShowConnectedUsrsWithARoleBelongingToCurrentCrsOnRightColumn (Rol_TCH);
Con_ShowConnectedUsrsWithARoleBelongingToCurrentCrsOnRightColumn (Rol_NET);
Con_ShowConnectedUsrsWithARoleBelongingToCurrentCrsOnRightColumn (Rol_STD);
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/* Show number of connected users with a role who belong to current location */
/*****************************************************************************/
static void Con_ShowConnectedUsrsWithARoleBelongingToCurrentLocationOnMainZone (Rol_Role_t Role)
{
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2014-12-01 23:55:08 +01:00
extern const char *Txt_ROLES_PLURAL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
struct Con_ConnectedUsrs Usrs;
2014-12-01 23:55:08 +01:00
/***** Write number of connected users who belong to current course *****/
Con_GetNumConnectedWithARoleBelongingToCurrentScope (Role,&Usrs);
2016-03-15 19:41:01 +01:00
if (Usrs.NumUsrs)
2014-12-01 23:55:08 +01:00
{
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"3\" class=\"CT\"");
HTM_TxtF ("%u&nbsp;%s",
Usrs.NumUsrs,
Usrs.NumUsrs == 1 ? Txt_ROLES_SINGUL_abc[Role][Usrs.Sex] :
Txt_ROLES_PLURAL_abc[Role][Usrs.Sex]);
HTM_TD_End ();
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2016-03-15 19:41:01 +01:00
/***** I can see connected users *****/
Con_ShowConnectedUsrsCurrentLocationOneByOneOnMainZone (Role);
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
2016-03-15 22:15:25 +01:00
/** Show number of connected users with a role who belong to current course **/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-03-15 22:15:25 +01:00
static void Con_ShowConnectedUsrsWithARoleBelongingToCurrentCrsOnRightColumn (Rol_Role_t Role)
2014-12-01 23:55:08 +01:00
{
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2014-12-01 23:55:08 +01:00
extern const char *Txt_ROLES_PLURAL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
extern const char *Txt_Connected_users;
2015-12-20 01:41:07 +01:00
unsigned NumUsrsThisRole = Gbl.Usrs.Connected.Usrs[Role].NumUsrs;
Usr_Sex_t UsrSex = Gbl.Usrs.Connected.Usrs[Role].Sex;
2014-12-01 23:55:08 +01:00
2016-03-15 19:41:01 +01:00
if (NumUsrsThisRole)
2014-12-01 23:55:08 +01:00
{
2016-03-15 19:41:01 +01:00
/***** Write number of connected users who belong to current course *****/
Gbl.Usrs.Connected.NumUsrs += NumUsrsThisRole;
Gbl.Usrs.Connected.NumUsrsToList += NumUsrsThisRole;
if (Gbl.Usrs.Connected.NumUsrsToList > Cfg_MAX_CONNECTED_SHOWN)
Gbl.Usrs.Connected.NumUsrsToList = Cfg_MAX_CONNECTED_SHOWN;
2014-12-01 23:55:08 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"3\" class=\"CON_USR_NARROW_TIT\"");
HTM_TxtF ("%u&nbsp;%s",NumUsrsThisRole,
NumUsrsThisRole == 1 ? Txt_ROLES_SINGUL_abc[Role][UsrSex] :
Txt_ROLES_PLURAL_abc[Role][UsrSex]);
HTM_TD_End ();
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2016-03-15 19:41:01 +01:00
/***** I can see connected users *****/
Con_ShowConnectedUsrsCurrentCrsOneByOneOnRightColumn (Role);
/***** Write message with number of users not listed *****/
if (Gbl.Usrs.Connected.NumUsrsToList < Gbl.Usrs.Connected.NumUsrs)
{
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"3\" class=\"CM\"");
Frm_BeginForm (ActLstCon);
Sco_PutParScope ("ScopeCon",HieLvl_CRS);
HTM_INPUT_IMAGE (Cfg_URL_ICON_PUBLIC,"ellipsis-h.svg",
Txt_Connected_users,
"class=\"ICO16x16 ICO_HIGHLIGHT ICO_BLACK_%s\"",
The_GetSuffix ());
Frm_EndForm ();
HTM_TD_End ();
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2016-03-15 19:41:01 +01:00
}
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
2017-01-30 17:45:16 +01:00
/********************* Get connected users with a role ***********************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-01-30 17:45:16 +01:00
static unsigned Con_GetConnectedUsrsTotal (Rol_Role_t Role)
2014-12-01 23:55:08 +01:00
{
if (!DB_CheckIfDatabaseIsOpen ())
2014-12-01 23:55:08 +01:00
return 0;
2017-01-30 17:45:16 +01:00
/***** Get number of connected users with a role from database *****/
return Con_DB_GetConnectedUsrsTotal (Role);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************** Get connected users belonging to current scope ***************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
// Return user's sex in UsrSex
static void Con_GetNumConnectedWithARoleBelongingToCurrentScope (Rol_Role_t Role,
struct Con_ConnectedUsrs *Usrs)
2014-12-01 23:55:08 +01:00
{
extern const char *Usr_StringsSexDB[Usr_NUM_SEXS];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumSexs;
Usr_Sex_t Sex;
/***** Default values *****/
Usrs->NumUsrs = 0;
Usrs->Sex = Usr_SEX_UNKNOWN;
2014-12-01 23:55:08 +01:00
/***** Get number of connected users who belong to current course from database *****/
if (Con_DB_GetNumConnectedFromCurrentLocation (&mysql_res,Role))
2014-12-01 23:55:08 +01:00
{
row = mysql_fetch_row (mysql_res);
2014-12-01 23:55:08 +01:00
/***** Get number of users (row[0]) *****/
if (sscanf (row[0],"%u",&(Usrs->NumUsrs)) != 1)
Err_ShowErrorAndExit ("Error when getting number of connected users who belong to this location.");
2014-12-01 23:55:08 +01:00
/***** Get number of distinct sexs (row[1]) *****/
if (sscanf (row[1],"%u",&NumSexs) != 1)
Err_ShowErrorAndExit ("Error when getting number of sexs in connected users who belong to this location.");
2014-12-01 23:55:08 +01:00
/***** Get users' sex (row[2]) *****/
if (NumSexs == 1)
for (Sex = (Usr_Sex_t) 0;
Sex <= (Usr_Sex_t) (Usr_NUM_SEXS - 1);
Sex++)
if (!strcasecmp (row[2],Usr_StringsSexDB[Sex]))
{
Usrs->Sex = Sex;
break;
}
}
2014-12-01 23:55:08 +01:00
/***** Free structure that stores the query result *****/
2020-02-24 12:43:18 +01:00
DB_FreeMySQLResult (&mysql_res);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************* Compute connected users one by one **********************/
/*****************************************************************************/
static void Con_ComputeConnectedUsrsWithARoleCurrentCrsOneByOne (Rol_Role_t Role)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumUsrs;
2018-10-19 13:55:02 +02:00
unsigned NumUsr = Gbl.Usrs.Connected.NumUsrs; // Save current number of users
2014-12-01 23:55:08 +01:00
/***** Get connected users who belong to current course from database *****/
NumUsrs = Con_DB_GetConnectedFromCurrentLocation (&mysql_res,Role);
Gbl.Usrs.Connected.NumUsrs += NumUsrs;
Gbl.Usrs.Connected.NumUsrsToList += NumUsrs;
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Connected.NumUsrsToList > Cfg_MAX_CONNECTED_SHOWN)
Gbl.Usrs.Connected.NumUsrsToList = Cfg_MAX_CONNECTED_SHOWN;
/***** Write list of connected users *****/
for (;
NumUsr < Gbl.Usrs.Connected.NumUsrsToList;
NumUsr++)
{
row = mysql_fetch_row (mysql_res);
/* Get user code (row[0]) */
Gbl.Usrs.Connected.Lst[NumUsr].UsrCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get course code (row[1]) */
2019-04-03 20:57:04 +02:00
Gbl.Usrs.Connected.Lst[NumUsr].ThisCrs = (Str_ConvertStrCodToLongCod (row[1]) ==
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod);
2014-12-01 23:55:08 +01:00
2015-10-26 22:34:29 +01:00
/* Compute elapsed time from last access */
if (sscanf (row[2],"%ld",&Gbl.Usrs.Connected.Lst[NumUsr].TimeDiff) != 1)
Gbl.Usrs.Connected.Lst[NumUsr].TimeDiff = (time_t) 0;
2014-12-01 23:55:08 +01:00
}
/***** Free structure that stores the query result *****/
2020-02-24 12:43:18 +01:00
DB_FreeMySQLResult (&mysql_res);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************* Show connected users one by one *************************/
/*****************************************************************************/
static void Con_ShowConnectedUsrsCurrentCrsOneByOneOnRightColumn (Rol_Role_t Role)
{
/***** Write list of connected users *****/
for (;
Gbl.Usrs.Connected.NumUsr < Gbl.Usrs.Connected.NumUsrsToList;
Gbl.Usrs.Connected.NumUsr++)
/* Write row in screen */
Con_WriteRowConnectedUsrOnRightColumn (Role);
}
/*****************************************************************************/
/********************* Write the name of a connected user ********************/
/*****************************************************************************/
static void Con_WriteRowConnectedUsrOnRightColumn (Rol_Role_t Role)
{
2015-03-30 14:37:44 +02:00
extern const char *Txt_View_record_for_this_course;
static const Act_Action_t NextAction[Rol_NUM_ROLES] =
{
[Rol_STD] = ActSeeRecOneStd,
[Rol_NET] = ActSeeRecOneTch,
[Rol_TCH] = ActSeeRecOneTch,
};
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
};
2019-11-18 20:12:10 +01:00
const char *ClassTxt;
2017-02-17 01:59:58 +01:00
long UsrCod;
Usr_MeOrOther_t MeOrOther;
struct Usr_Data *UsrDat;
struct Usr_Data OtherUsrDat;
2017-02-17 01:59:58 +01:00
/***** Get user's code from list *****/
UsrCod = Gbl.Usrs.Connected.Lst[Gbl.Usrs.Connected.NumUsr].UsrCod;
MeOrOther = Usr_ItsMe (UsrCod);
2017-02-17 01:59:58 +01:00
switch (MeOrOther)
2017-02-17 01:59:58 +01:00
{
case Usr_ME:
UsrDat = &Gbl.Usrs.Me.UsrDat;
break;
case Usr_OTHER:
default:
/***** Initialize structure with user's data *****/
OtherUsrDat.UsrCod = UsrCod;
Usr_UsrDataConstructor (&OtherUsrDat);
/***** Get user's data *****/
Usr_GetAllUsrDataFromUsrCod (&OtherUsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS);
UsrDat = &OtherUsrDat;
break;
2017-02-17 01:59:58 +01:00
}
2014-12-01 23:55:08 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-08 00:26:14 +02:00
/***** Show photo *****/
HTM_TD_Begin ("class=\"CON_PHOTO %s\"",The_GetColorRows ());
Pho_ShowUsrPhotoIfAllowed (UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write full name and link *****/
ClassTxt = (Gbl.Usrs.Connected.Lst[Gbl.Usrs.Connected.NumUsr].ThisCrs) ? "CON_NAME_NARROW CON_CRS" :
"CON_NAME_NARROW CON_NO_CRS";
HTM_TD_Begin ("class=\"%s %s\"",ClassTxt,The_GetColorRows ());
if (!NextAction[Role])
Err_WrongRoleExit ();
Frm_BeginForm (NextAction[Role]);
Usr_PutParUsrCodEncrypted (UsrDat->EnUsrCod);
2019-10-23 21:37:01 +02:00
HTM_DIV_Begin ("class=\"CON_NAME_NARROW\""); // Limited width
HTM_BUTTON_Submit_Begin (Txt_View_record_for_this_course,
"class=\"LT BT_LINK\"");
Usr_WriteFirstNameBRSurnames (UsrDat);
HTM_BUTTON_End ();
HTM_DIV_End ();
2019-10-23 21:37:01 +02:00
Frm_EndForm ();
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write time from last access *****/
ClassTxt = (Gbl.Usrs.Connected.Lst[Gbl.Usrs.Connected.NumUsr].ThisCrs ? "CON_SINCE CON_CRS" :
"CON_SINCE CON_NO_CRS");
HTM_TD_Begin ("class=\"%s %s\"",ClassTxt,The_GetColorRows ());
HTM_DIV_Begin ("id=\"hm%u\"",Gbl.Usrs.Connected.NumUsr); // Used for automatic update, only when displayed on right column
Dat_WriteHoursMinutesSecondsFromSeconds (Gbl.Usrs.Connected.Lst[Gbl.Usrs.Connected.NumUsr].TimeDiff);
HTM_DIV_End (); // Used for automatic update, only when displayed on right column
HTM_TD_End ();
2019-10-08 15:49:01 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
switch (MeOrOther)
{
case Usr_ME:
break;
case Usr_OTHER:
default:
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&OtherUsrDat);
break;
}
2014-12-01 23:55:08 +01:00
The_ChangeRowColor ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************** Show connected users one by one ************************/
/*****************************************************************************/
static void Con_ShowConnectedUsrsCurrentLocationOneByOneOnMainZone (Rol_Role_t Role)
{
static const Act_Action_t NextAction[Rol_NUM_ROLES] =
{
[Rol_STD] = ActSeeRecOneStd,
[Rol_NET] = ActSeeRecOneTch,
[Rol_TCH] = ActSeeRecOneTch,
};
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
};
2014-12-01 23:55:08 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2018-10-30 14:47:31 +01:00
unsigned NumUsrs = 0; // Initialized to avoid warning
2014-12-01 23:55:08 +01:00
unsigned NumUsr;
bool ThisCrs;
time_t TimeDiff;
2019-11-19 00:17:23 +01:00
const char *ClassTxt;
struct Usr_Data UsrDat;
bool PutLinkToRecord = (Gbl.Hierarchy.Level == HieLvl_CRS && // Course selected
Gbl.Scope.Current == HieLvl_CRS && // Scope is current course
(Role == Rol_STD || // Role is student,...
Role == Rol_NET || // ...non-editing teacher...
Role == Rol_TCH)); // ...or teacher
2014-12-01 23:55:08 +01:00
/***** Get connected users who belong to current location from database *****/
if ((NumUsrs = Con_DB_GetConnectedFromCurrentLocation (&mysql_res,Role)))
2014-12-01 23:55:08 +01:00
{
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** Write list of connected users *****/
for (NumUsr = 0;
NumUsr < NumUsrs;
NumUsr++)
{
row = mysql_fetch_row (mysql_res);
/* Get user's data */
UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat, // Existing user
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
2015-03-13 00:16:02 +01:00
{
2015-12-19 18:25:44 +01:00
/* Get course code (row[1]) */
ThisCrs = (Str_ConvertStrCodToLongCod (row[1]) == Gbl.Hierarchy.Crs.CrsCod);
2015-12-19 18:25:44 +01:00
/* Compute time from last access */
if (sscanf (row[2],"%ld",&TimeDiff) != 1)
TimeDiff = (time_t) 0;
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-08 00:26:14 +02:00
/***** Show photo *****/
HTM_TD_Begin ("class=\"CON_PHOTO %s\"",The_GetColorRows ());
Pho_ShowUsrPhotoIfAllowed (&UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
HTM_TD_End ();
2015-12-19 18:25:44 +01:00
/***** Write full name and link *****/
ClassTxt = ThisCrs ? "CON_NAME_WIDE CON_CRS" :
"CON_NAME_WIDE CON_NO_CRS";
HTM_TD_Begin ("class=\"%s %s\"",
ClassTxt,The_GetColorRows ());
if (PutLinkToRecord)
{
if (!NextAction[Role])
Err_WrongRoleExit ();
Frm_BeginForm (NextAction[Role]);
Usr_PutParUsrCodEncrypted (UsrDat.EnUsrCod);
}
if (PutLinkToRecord)
HTM_BUTTON_Submit_Begin (UsrDat.FullName,
"class=\"LT BT_LINK\"");
Usr_WriteFirstNameBRSurnames (&UsrDat);
if (PutLinkToRecord)
HTM_BUTTON_End ();
if (PutLinkToRecord)
Frm_EndForm ();
HTM_TD_End ();
/***** Write time from last access *****/
ClassTxt = ThisCrs ? "CON_SINCE CON_CRS" :
"CON_SINCE CON_NO_CRS";
HTM_TD_Begin ("class=\"%s %s\"",
ClassTxt,The_GetColorRows ());
Dat_WriteHoursMinutesSecondsFromSeconds (TimeDiff);
HTM_TD_End ();
2019-10-08 00:26:14 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2015-12-19 18:25:44 +01:00
The_ChangeRowColor ();
2015-12-19 18:25:44 +01:00
}
2014-12-01 23:55:08 +01:00
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
/***** Free structure that stores the query result *****/
2015-03-16 14:05:16 +01:00
DB_FreeMySQLResult (&mysql_res);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****** Write script to automatically update clocks of connected users *******/
/*****************************************************************************/
void Con_WriteScriptClockConnected (void)
{
unsigned NumUsr;
2019-11-11 00:15:44 +01:00
HTM_TxtF ("\tNumUsrsCon = %u;\n",Gbl.Usrs.Connected.NumUsrsToList);
2014-12-01 23:55:08 +01:00
for (NumUsr = 0;
NumUsr < Gbl.Usrs.Connected.NumUsrsToList;
NumUsr++)
2019-11-11 00:15:44 +01:00
HTM_TxtF ("\tListSeconds[%u] = %ld;\n",
NumUsr,Gbl.Usrs.Connected.Lst[NumUsr].TimeDiff);
HTM_Txt ("\twriteClockConnected();\n");
2014-12-01 23:55:08 +01:00
}