Version 14.80

This commit is contained in:
Antonio Cañas Vargas 2015-03-09 00:16:18 +01:00
parent e9ccb15657
commit 43ede6ada4
9 changed files with 270 additions and 46 deletions

View File

@ -4,8 +4,7 @@
SWAD (Shared Workspace At a Distance), SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain), is a web platform developed at the University of Granada (Spain),
and used to support university teaching. and used to support university teaching.
Copyright (C) 1999-2012 Antonio Cañas-Vargas Copyright (C) 1999-2015 Antonio Cañas-Vargas
& Daniel J. Calandria-Hernández,
University of Granada (SPAIN) (acanas@ugr.es) University of Granada (SPAIN) (acanas@ugr.es)
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@ -185,7 +184,7 @@ function readConnUsrsData() {
} }
} }
if (delay >= 10000) // If refresh slower than 1 time each 10 seconds, do refresh; else abort if (delay >= 60000) // If refresh slower than 1 time each 60 seconds, do refresh; else abort
setTimeout("refreshConnected()",delay); setTimeout("refreshConnected()",delay);
} }
} }

View File

@ -103,11 +103,14 @@
/****************************** Public constants *****************************/ /****************************** Public constants *****************************/
/*****************************************************************************/ /*****************************************************************************/
#define Log_PLATFORM_VERSION "SWAD 14.79.4 (2015/03/07)" #define Log_PLATFORM_VERSION "SWAD 14.80 (2015/03/09)"
// Number of lines (includes comments but not blank lines) has been got with the following command: // Number of lines (includes comments but not blank lines) has been got with the following command:
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h | tail -1 // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h | tail -1
/* /*
Version 14.80: Mar 09, 2015 New statistic for privacy. (178909 lines)
Version 14.79.6: Mar 08, 2015 Check if file "swad.lock" exists to disable SWAD. (178736 lines)
Version 14.79.5: Mar 08, 2015 Fixed bug when refreshing connected users. (178730 lines)
Version 14.79.4: Mar 07, 2015 Parameter "CtyCod" is renamed to "cty". Version 14.79.4: Mar 07, 2015 Parameter "CtyCod" is renamed to "cty".
Parameter "InsCod" is renamed to "ins". Parameter "InsCod" is renamed to "ins".
Parameter "CtrCod" is renamed to "ctr". Parameter "CtrCod" is renamed to "ctr".

View File

@ -458,7 +458,7 @@
#define Cfg_DAYS_IN_RECENT_LOG 8 // Only accesses in these last days + 1 are stored in recent log. #define Cfg_DAYS_IN_RECENT_LOG 8 // Only accesses in these last days + 1 are stored in recent log.
// Important!!! Must be 1 <= Cfg_DAYS_IN_RECENT_LOG <= 29 // Important!!! Must be 1 <= Cfg_DAYS_IN_RECENT_LOG <= 29
#define Cfg_TIMES_PER_SECOND_REFRESH_CONNECTED 3 // Execute this CGI to refresh connected users about these times per second #define Cfg_TIMES_PER_SECOND_REFRESH_CONNECTED 3 // Execute this CGI to refresh connected users about these times per second
#define Cfg_MIN_TIME_TO_REFRESH_CONNECTED ((time_t)( 30UL)) // Refresh period of connected users in seconds #define Cfg_MIN_TIME_TO_REFRESH_CONNECTED ((time_t)( 60UL)) // Refresh period of connected users in seconds
#define Cfg_MAX_TIME_TO_REFRESH_CONNECTED ((time_t)( 15UL*60UL)) // Refresh period of connected users in seconds #define Cfg_MAX_TIME_TO_REFRESH_CONNECTED ((time_t)( 15UL*60UL)) // Refresh period of connected users in seconds
#define Cfg_TIME_TO_CLOSE_SESSION_FROM_LAST_REFRESH ((time_t)(Cfg_MAX_TIME_TO_REFRESH_CONNECTED * 2)) // After these seconds without refresh of connected users, session is closed #define Cfg_TIME_TO_CLOSE_SESSION_FROM_LAST_REFRESH ((time_t)(Cfg_MAX_TIME_TO_REFRESH_CONNECTED * 2)) // After these seconds without refresh of connected users, session is closed
#define Cfg_TIME_TO_CLOSE_SESSION_FROM_LAST_CLICK ((time_t)( 2*60UL*60UL)) // After these seconds without user's clicks, session is closed #define Cfg_TIME_TO_CLOSE_SESSION_FROM_LAST_CLICK ((time_t)( 2*60UL*60UL)) // After these seconds without user's clicks, session is closed

View File

@ -404,7 +404,7 @@ void Gbl_InitializeGlobals (void)
Gbl.Stat.Role = Sta_IDENTIFIED_USRS; Gbl.Stat.Role = Sta_IDENTIFIED_USRS;
Gbl.Stat.NumAction = ActAll; Gbl.Stat.NumAction = ActAll;
Gbl.Stat.RowsPerPage = 50; Gbl.Stat.RowsPerPage = 50;
Gbl.Stat.UseStatType = Sta_DEGREES_AND_COURSES; Gbl.Stat.UseStatType = Sta_USERS;
Gbl.Scope.Current = Sco_SCOPE_CRS; Gbl.Scope.Current = Sco_SCOPE_CRS;

View File

@ -70,21 +70,28 @@ extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
extern const char *Txt_You_dont_have_permission_to_perform_this_action; extern const char *Txt_You_dont_have_permission_to_perform_this_action;
FILE *FileLock;
/*
"touch swad.lock" in CGI directory if you want to disable SWAD
"rm swad.lock" in CGI directory if you want to enable SWAD
*/
if (Fil_CheckIfPathExists ("./swad.lock"))
{
fprintf (stdout,"Content-type: text/html; charset=windows-1252\r\n"
"Status: 503 Service Temporarily Unavailable\r\n\r\n"
"<html lang=\"es\">"
"<head><title>%s</title></head>"
"<body><br /><br /><br /><br />"
"<h1 style=\"text-align:center;\">%s est&aacute; parado por mantenimiento durante pocos minutos</h1>"
"<h2 style=\"text-align:center;\">Intente acceder m&aacute;s tarde, por favor.</h2>"
"</body>"
"</html>",
Cfg_PLATFORM_FULL_NAME,
Cfg_PLATFORM_SHORT_NAME);
exit (0);
}
/*
fprintf (stdout,"Content-type: text/html; charset=windows-1252\r\n"
"Status: 503 Service Temporarily Unavailable\r\n\r\n"
"<html lang=\"es\">"
"<head><title>%s</title></head>"
"<body><br /><br /><br /><br />"
"<h1 style=\"text-align:center;\">%s est&aacute; parado por mantenimiento durante pocos minutos</h1>"
"<h2 style=\"text-align:center;\">Intente acceder m&aacute;s tarde, por favor.</h2>"
"</body>"
"</html>",
Cfg_PLATFORM_FULL_NAME,
Cfg_PLATFORM_SHORT_NAME);
exit (0);
*/
if (argc > 1) if (argc > 1)
{ {
fprintf (stdout,"Call %s without parameters",argv[0]); fprintf (stdout,"Call %s without parameters",argv[0]);

View File

@ -171,9 +171,20 @@ void Par_GetMainParameters (void)
Gbl.CurrentAct = ActUnk; Gbl.CurrentAct = ActUnk;
Par_GetParToText ("act",UnsignedStr,10); Par_GetParToText ("act",UnsignedStr,10);
if (UnsignedStr[0]) if (UnsignedStr[0])
{
if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1) if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1)
if (UnsignedNum <= Act_MAX_ACTION_COD) if (UnsignedNum <= Act_MAX_ACTION_COD)
Gbl.CurrentAct = Act_FromActCodToAction[UnsignedNum]; Gbl.CurrentAct = Act_FromActCodToAction[UnsignedNum];
}
else
{
// Try old parameter "ActCod" (allowed for compatibility, to be removed soon)
Par_GetParToText ("ActCod",UnsignedStr,10);
if (UnsignedStr[0])
if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1)
if (UnsignedNum <= Act_MAX_ACTION_COD)
Gbl.CurrentAct = Act_FromActCodToAction[UnsignedNum];
}
/***** Get session identifier, if exists *****/ /***** Get session identifier, if exists *****/
Par_GetParToText ("ses",Gbl.Session.Id,Ses_LENGTH_SESSION_ID); Par_GetParToText ("ses",Gbl.Session.Id,Ses_LENGTH_SESSION_ID);
@ -191,6 +202,25 @@ void Par_GetMainParameters (void)
Gbl.Session.Id[0] = '\0'; Gbl.Session.Id[0] = '\0';
} }
} }
else
{
// Try old parameter "IdSes" (allowed for compatibility, to be removed soon)
Par_GetParToText ("IdSes",Gbl.Session.Id,Ses_LENGTH_SESSION_ID);
if (Gbl.Session.Id[0])
{
/***** Get user's code, password, current degree and current course from stored session *****/
if (Ses_GetSessionData ())
{
Gbl.Session.IsOpen = true;
Imp_GetImpSessionData ();
}
else
{
Gbl.Session.HasBeenDisconnected = true;
Gbl.Session.Id[0] = '\0';
}
}
}
/***** Get user password and login *****/ /***** Get user password and login *****/
switch (Gbl.CurrentAct) switch (Gbl.CurrentAct)

View File

@ -159,6 +159,8 @@ static void Sta_WriteForumTitleAndStats (For_ForumType_t ForumType,
static void Sta_WriteForumTotalStats (struct Sta_StatsForum *StatsForum); static void Sta_WriteForumTotalStats (struct Sta_StatsForum *StatsForum);
static void Sta_GetAndShowSurveysStats (void); static void Sta_GetAndShowSurveysStats (void);
static void Sta_GetAndShowNumUsrsPerPrivacy (void);
static void Sta_GetAndShowNumUsrsPerPrivacyForAnObject (const char *TxtObject,const char *FieldName);
static void Sta_GetAndShowNumUsrsPerLanguage (void); static void Sta_GetAndShowNumUsrsPerLanguage (void);
static void Sta_GetAndShowNumUsrsPerLayout (void); static void Sta_GetAndShowNumUsrsPerLayout (void);
static void Sta_GetAndShowNumUsrsPerTheme (void); static void Sta_GetAndShowNumUsrsPerTheme (void);
@ -3699,14 +3701,14 @@ void Sta_ShowUseOfPlatform (void)
/***** Show the stat of use selected by user *****/ /***** Show the stat of use selected by user *****/
switch (Gbl.Stat.UseStatType) switch (Gbl.Stat.UseStatType)
{ {
case Sta_DEGREES_AND_COURSES:
/***** Number of degrees and courses *****/
Sta_GetAndShowDegCrsStats ();
break;
case Sta_USERS: case Sta_USERS:
/***** Number of users *****/ /***** Number of users *****/
Sta_GetAndShowUsersStats (); Sta_GetAndShowUsersStats ();
break; break;
case Sta_DEGREES_AND_COURSES:
/***** Number of degrees and courses *****/
Sta_GetAndShowDegCrsStats ();
break;
case Sta_SOCIAL_NETWORKS: case Sta_SOCIAL_NETWORKS:
/***** Number of users in social networks *****/ /***** Number of users in social networks *****/
Net_ShowWebAndSocialNetworksStats (); Net_ShowWebAndSocialNetworksStats ();
@ -3748,6 +3750,10 @@ void Sta_ShowUseOfPlatform (void)
/***** Number of surveys *****/ /***** Number of surveys *****/
Sta_GetAndShowSurveysStats (); Sta_GetAndShowSurveysStats ();
break; break;
case Sta_PRIVACY:
/***** Number of users who have chosen a privacy *****/
Sta_GetAndShowNumUsrsPerPrivacy ();
break;
case Sta_LANGUAGES: case Sta_LANGUAGES:
/***** Number of users who have chosen a language *****/ /***** Number of users who have chosen a language *****/
Sta_GetAndShowNumUsrsPerLanguage (); Sta_GetAndShowNumUsrsPerLanguage ();
@ -6327,6 +6333,164 @@ static void Sta_GetAndShowSurveysStats (void)
Lay_EndRoundFrameTable10 (); Lay_EndRoundFrameTable10 ();
} }
/*****************************************************************************/
/********** Get and show number of users who have chosen a privacy ***********/
/*****************************************************************************/
static void Sta_GetAndShowNumUsrsPerPrivacy (void)
{
extern const char *Txt_Photo;
extern const char *Txt_Public_profile;
extern const char *Txt_STAT_USE_STAT_TYPES[Sta_NUM_TYPES_USE_STATS];
Lay_StartRoundFrameTable10 (NULL,2,Txt_STAT_USE_STAT_TYPES[Sta_PRIVACY]);
/***** Privacy for photo *****/
Sta_GetAndShowNumUsrsPerPrivacyForAnObject (Txt_Photo,"PhotoVisibility");
/***** Privacy for public profile *****/
Sta_GetAndShowNumUsrsPerPrivacyForAnObject (Txt_Public_profile,"ProfileVisibility");
Lay_EndRoundFrameTable10 ();
}
/*****************************************************************************/
/********** Get and show number of users who have chosen a privacy ***********/
/*****************************************************************************/
static void Sta_GetAndShowNumUsrsPerPrivacyForAnObject (const char *TxtObject,const char *FieldName)
{
extern const char *Txt_No_of_users;
extern const char *Txt_PERCENT_of_users;
extern const char *Pri_VisibilityDB[Pri_NUM_OPTIONS_PRIVACY];
extern const char *Txt_PRIVACY_OPTIONS[Pri_NUM_OPTIONS_PRIVACY];
Pri_Visibility_t Visibility;
char Query[1024];
unsigned NumUsrs[Pri_NUM_OPTIONS_PRIVACY];
unsigned NumUsrsTotal = 0;
/***** Heading row *****/
fprintf (Gbl.F.Out,"<tr>"
"<th class=\"TIT_TBL\" style=\"text-align:left;\">"
"%s"
"</th>"
"<th class=\"TIT_TBL\" style=\"text-align:right;\">"
"%s"
"</th>"
"<th class=\"TIT_TBL\" style=\"text-align:right;\">"
"%s"
"</th>"
"</tr>",
TxtObject,
Txt_No_of_users,
Txt_PERCENT_of_users);
/***** For each privacy option... *****/
for (Visibility = (Pri_Visibility_t) 0;
Visibility < Pri_NUM_OPTIONS_PRIVACY;
Visibility++)
{
/***** Get the number of users who have chosen this privacy option from database *****/
switch (Gbl.Scope.Current)
{
case Sco_SCOPE_SYS:
sprintf (Query,"SELECT COUNT(*)"
" FROM usr_data WHERE %s='%s'",
FieldName,
Pri_VisibilityDB[Visibility]);
break;
case Sco_SCOPE_CTY:
sprintf (Query,"SELECT COUNT(DISTINCT usr_data.UsrCod)"
" FROM institutions,centres,degrees,courses,crs_usr,usr_data"
" WHERE institutions.CtyCod='%ld'"
" AND institutions.InsCod=centres.InsCod"
" AND centres.CtrCod=degrees.CtrCod"
" AND degrees.DegCod=courses.DegCod"
" AND courses.CrsCod=crs_usr.CrsCod"
" AND crs_usr.UsrCod=usr_data.UsrCod"
" AND usr_data.%s='%s'",
Gbl.CurrentCty.Cty.CtyCod,
FieldName,
Pri_VisibilityDB[Visibility]);
break;
case Sco_SCOPE_INS:
sprintf (Query,"SELECT COUNT(DISTINCT usr_data.UsrCod)"
" FROM centres,degrees,courses,crs_usr,usr_data"
" WHERE centres.InsCod='%ld'"
" AND centres.CtrCod=degrees.CtrCod"
" AND degrees.DegCod=courses.DegCod"
" AND courses.CrsCod=crs_usr.CrsCod"
" AND crs_usr.UsrCod=usr_data.UsrCod"
" AND usr_data.%s='%s'",
Gbl.CurrentIns.Ins.InsCod,
FieldName,
Pri_VisibilityDB[Visibility]);
break;
case Sco_SCOPE_CTR:
sprintf (Query,"SELECT COUNT(DISTINCT usr_data.UsrCod)"
" FROM degrees,courses,crs_usr,usr_data"
" WHERE degrees.CtrCod='%ld'"
" AND degrees.DegCod=courses.DegCod"
" AND courses.CrsCod=crs_usr.CrsCod"
" AND crs_usr.UsrCod=usr_data.UsrCod"
" AND usr_data.%s='%s'",
Gbl.CurrentCtr.Ctr.CtrCod,
FieldName,
Pri_VisibilityDB[Visibility]);
break;
case Sco_SCOPE_DEG:
sprintf (Query,"SELECT COUNT(DISTINCT usr_data.UsrCod)"
" FROM courses,crs_usr,usr_data"
" WHERE courses.DegCod='%ld'"
" AND courses.CrsCod=crs_usr.CrsCod"
" AND crs_usr.UsrCod=usr_data.UsrCod"
" AND usr_data.%s='%s'",
Gbl.CurrentDeg.Deg.DegCod,
FieldName,
Pri_VisibilityDB[Visibility]);
break;
case Sco_SCOPE_CRS:
sprintf (Query,"SELECT COUNT(DISTINCT usr_data.UsrCod)"
" FROM crs_usr,usr_data"
" WHERE crs_usr.CrsCod='%ld'"
" AND crs_usr.UsrCod=usr_data.UsrCod"
" AND usr_data.%s='%s'",
Gbl.CurrentCrs.Crs.CrsCod,
FieldName,
Pri_VisibilityDB[Visibility]);
break;
default:
Lay_ShowErrorAndExit ("Wrong scope.");
break;
}
NumUsrs[Visibility] = (unsigned) DB_QueryCOUNT (Query,"can not get the number of users who have chosen a privacy");
/* Update total number of users */
NumUsrsTotal += NumUsrs[Visibility];
}
/***** Write number of users who have chosen each privacy option *****/
for (Visibility = (Pri_Visibility_t) 0;
Visibility < Pri_NUM_OPTIONS_PRIVACY;
Visibility++)
fprintf (Gbl.F.Out,"<tr>"
"<td class=\"DAT\" style=\"text-align:left;\">"
"%s"
"</td>"
"<td class=\"DAT\" style=\"text-align:right;\">"
"%u"
"</td>"
"<td class=\"DAT\" style=\"text-align:right;\">"
"%5.2f%%"
"</td>"
"</tr>",
Txt_PRIVACY_OPTIONS[Visibility],NumUsrs[Visibility],
NumUsrsTotal ? (float) NumUsrs[Visibility] * 100.0 /
(float) NumUsrsTotal :
0);
}
/*****************************************************************************/ /*****************************************************************************/
/********* Get and show number of users who have chosen a language ***********/ /********* Get and show number of users who have chosen a language ***********/
/*****************************************************************************/ /*****************************************************************************/

View File

@ -86,11 +86,11 @@ typedef enum
Sta_ACC_GBL_PER_COURSE = 20, Sta_ACC_GBL_PER_COURSE = 20,
} Sta_ClicksStatType_t; } Sta_ClicksStatType_t;
#define Sta_NUM_TYPES_USE_STATS 18 #define Sta_NUM_TYPES_USE_STATS 19
typedef enum typedef enum
{ {
Sta_DEGREES_AND_COURSES, // Number of degrees and courses
Sta_USERS, // Number of users Sta_USERS, // Number of users
Sta_DEGREES_AND_COURSES, // Number of degrees and courses
Sta_SOCIAL_NETWORKS, // Number of users in social networks Sta_SOCIAL_NETWORKS, // Number of users in social networks
Sta_FOLDERS_AND_FILES, // Number of folders and files Sta_FOLDERS_AND_FILES, // Number of folders and files
Sta_OER, // Number of OERs (Open Educational Resources) Sta_OER, // Number of OERs (Open Educational Resources)
@ -101,6 +101,7 @@ typedef enum
Sta_MSGS_BETWEEN_USERS, // Number of users' (sent and received) messages Sta_MSGS_BETWEEN_USERS, // Number of users' (sent and received) messages
Sta_FORUMS, // Number of forums, threads and posts Sta_FORUMS, // Number of forums, threads and posts
Sta_SURVEYS, // Number of surveys Sta_SURVEYS, // Number of surveys
Sta_PRIVACY, // Number of users per privacity
Sta_LANGUAGES, // Number of users per language Sta_LANGUAGES, // Number of users per language
Sta_LAYOUTS, // Number of users per layout Sta_LAYOUTS, // Number of users per layout
Sta_THEMES, // Number of users per theme Sta_THEMES, // Number of users per theme

View File

@ -35744,26 +35744,6 @@ const char *Txt_STAT_TYPE_COUNT_SMALL[Sta_NUM_STAT_COUNT_TYPES] =
const char *Txt_STAT_USE_STAT_TYPES[Sta_NUM_TYPES_USE_STATS] = const char *Txt_STAT_USE_STAT_TYPES[Sta_NUM_TYPES_USE_STATS] =
{ {
#if L==0
"Titulaciones y asignaturas" // Necessita traducció
#elif L==1
"Studieng&auml;nge und Kursen"
#elif L==2
"Degrees and courses"
#elif L==3
"Titulaciones y asignaturas"
#elif L==4
"&Eacute;tudes et mati&egrave;res"
#elif L==5
"Titulaciones y asignaturas" // Okoteve traducción
#elif L==6
"Lauree e corsi"
#elif L==7
"Degrees and courses" // Potrzebujesz tlumaczenie
#elif L==8
"Titula&ccedil;oes e disciplinas"
#endif
,
#if L==0 #if L==0
"Usuaris" "Usuaris"
#elif L==1 #elif L==1
@ -35784,6 +35764,26 @@ const char *Txt_STAT_USE_STAT_TYPES[Sta_NUM_TYPES_USE_STATS] =
"Utilizadores" "Utilizadores"
#endif #endif
, ,
#if L==0
"Titulaciones y asignaturas" // Necessita traducció
#elif L==1
"Studieng&auml;nge und Kursen"
#elif L==2
"Degrees and courses"
#elif L==3
"Titulaciones y asignaturas"
#elif L==4
"&Eacute;tudes et mati&egrave;res"
#elif L==5
"Titulaciones y asignaturas" // Okoteve traducción
#elif L==6
"Lauree e corsi"
#elif L==7
"Degrees and courses" // Potrzebujesz tlumaczenie
#elif L==8
"Titula&ccedil;oes e disciplinas"
#endif
,
#if L==0 #if L==0
"Webs / xarxes socials" "Webs / xarxes socials"
#elif L==1 #elif L==1
@ -35984,6 +35984,26 @@ const char *Txt_STAT_USE_STAT_TYPES[Sta_NUM_TYPES_USE_STATS] =
"Inqu&eacute;ritos" "Inqu&eacute;ritos"
#endif #endif
, ,
#if L==0
"Privacitat"
#elif L==1
"Geheimhaltung"
#elif L==2
"Privacy"
#elif L==3
"Privacidad"
#elif L==4
"Privacit&eacute;"
#elif L==5
"Privacidad" // Okoteve traducción
#elif L==6
"Privatezza"
#elif L==7
"Prywatno&sacute;&cacute;"
#elif L==8
"Privacidade"
#endif
,
#if L==0 #if L==0
"Idioma" "Idioma"
#elif L==1 #elif L==1