diff --git a/js/swad.js b/js/swad.js
index 08eff34b..9f760b99 100644
--- a/js/swad.js
+++ b/js/swad.js
@@ -4,8 +4,7 @@
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
- Copyright (C) 1999-2012 Antonio Cañas-Vargas
- & Daniel J. Calandria-Hernández,
+ Copyright (C) 1999-2015 Antonio Cañas-Vargas
University of Granada (SPAIN) (acanas@ugr.es)
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);
}
}
diff --git a/swad_changelog.h b/swad_changelog.h
index df4ec097..266e2150 100644
--- a/swad_changelog.h
+++ b/swad_changelog.h
@@ -103,11 +103,14 @@
/****************************** 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:
// 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".
Parameter "InsCod" is renamed to "ins".
Parameter "CtrCod" is renamed to "ctr".
diff --git a/swad_config.h b/swad_config.h
index 708bd81e..9356e2c9 100644
--- a/swad_config.h
+++ b/swad_config.h
@@ -458,7 +458,7 @@
#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
#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_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
diff --git a/swad_global.c b/swad_global.c
index b768594f..e0f01abd 100644
--- a/swad_global.c
+++ b/swad_global.c
@@ -404,7 +404,7 @@ void Gbl_InitializeGlobals (void)
Gbl.Stat.Role = Sta_IDENTIFIED_USRS;
Gbl.Stat.NumAction = ActAll;
Gbl.Stat.RowsPerPage = 50;
- Gbl.Stat.UseStatType = Sta_DEGREES_AND_COURSES;
+ Gbl.Stat.UseStatType = Sta_USERS;
Gbl.Scope.Current = Sco_SCOPE_CRS;
diff --git a/swad_main.c b/swad_main.c
index f929cb4b..16e4c979 100644
--- a/swad_main.c
+++ b/swad_main.c
@@ -70,21 +70,28 @@ extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
int main (int argc, char *argv[])
{
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"
+ ""
+ "
%s"
+ "
"
+ "%s está parado por mantenimiento durante pocos minutos
"
+ "Intente acceder más tarde, por favor.
"
+ ""
+ "",
+ 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"
- ""
- "%s"
- "
"
- "%s está parado por mantenimiento durante pocos minutos
"
- "Intente acceder más tarde, por favor.
"
- ""
- "",
- Cfg_PLATFORM_FULL_NAME,
- Cfg_PLATFORM_SHORT_NAME);
- exit (0);
-*/
if (argc > 1)
{
fprintf (stdout,"Call %s without parameters",argv[0]);
diff --git a/swad_parameter.c b/swad_parameter.c
index 102f73a1..92dbcb7b 100644
--- a/swad_parameter.c
+++ b/swad_parameter.c
@@ -171,9 +171,20 @@ void Par_GetMainParameters (void)
Gbl.CurrentAct = ActUnk;
Par_GetParToText ("act",UnsignedStr,10);
if (UnsignedStr[0])
+ {
if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1)
if (UnsignedNum <= Act_MAX_ACTION_COD)
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 *****/
Par_GetParToText ("ses",Gbl.Session.Id,Ses_LENGTH_SESSION_ID);
@@ -191,6 +202,25 @@ void Par_GetMainParameters (void)
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 *****/
switch (Gbl.CurrentAct)
diff --git a/swad_statistic.c b/swad_statistic.c
index 889cc40f..3ae8967a 100644
--- a/swad_statistic.c
+++ b/swad_statistic.c
@@ -159,6 +159,8 @@ static void Sta_WriteForumTitleAndStats (For_ForumType_t ForumType,
static void Sta_WriteForumTotalStats (struct Sta_StatsForum *StatsForum);
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_GetAndShowNumUsrsPerLayout (void);
static void Sta_GetAndShowNumUsrsPerTheme (void);
@@ -3699,14 +3701,14 @@ void Sta_ShowUseOfPlatform (void)
/***** Show the stat of use selected by user *****/
switch (Gbl.Stat.UseStatType)
{
- case Sta_DEGREES_AND_COURSES:
- /***** Number of degrees and courses *****/
- Sta_GetAndShowDegCrsStats ();
- break;
case Sta_USERS:
/***** Number of users *****/
Sta_GetAndShowUsersStats ();
break;
+ case Sta_DEGREES_AND_COURSES:
+ /***** Number of degrees and courses *****/
+ Sta_GetAndShowDegCrsStats ();
+ break;
case Sta_SOCIAL_NETWORKS:
/***** Number of users in social networks *****/
Net_ShowWebAndSocialNetworksStats ();
@@ -3748,6 +3750,10 @@ void Sta_ShowUseOfPlatform (void)
/***** Number of surveys *****/
Sta_GetAndShowSurveysStats ();
break;
+ case Sta_PRIVACY:
+ /***** Number of users who have chosen a privacy *****/
+ Sta_GetAndShowNumUsrsPerPrivacy ();
+ break;
case Sta_LANGUAGES:
/***** Number of users who have chosen a language *****/
Sta_GetAndShowNumUsrsPerLanguage ();
@@ -6327,6 +6333,164 @@ static void Sta_GetAndShowSurveysStats (void)
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,""
+ ""
+ "%s"
+ " | "
+ ""
+ "%s"
+ " | "
+ ""
+ "%s"
+ " | "
+ "
",
+ 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,""
+ ""
+ "%s"
+ " | "
+ ""
+ "%u"
+ " | "
+ ""
+ "%5.2f%%"
+ " | "
+ "
",
+ 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 ***********/
/*****************************************************************************/
diff --git a/swad_statistic.h b/swad_statistic.h
index c2981965..c8590b72 100644
--- a/swad_statistic.h
+++ b/swad_statistic.h
@@ -86,11 +86,11 @@ typedef enum
Sta_ACC_GBL_PER_COURSE = 20,
} Sta_ClicksStatType_t;
-#define Sta_NUM_TYPES_USE_STATS 18
+#define Sta_NUM_TYPES_USE_STATS 19
typedef enum
{
- Sta_DEGREES_AND_COURSES, // Number of degrees and courses
Sta_USERS, // Number of users
+ Sta_DEGREES_AND_COURSES, // Number of degrees and courses
Sta_SOCIAL_NETWORKS, // Number of users in social networks
Sta_FOLDERS_AND_FILES, // Number of folders and files
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_FORUMS, // Number of forums, threads and posts
Sta_SURVEYS, // Number of surveys
+ Sta_PRIVACY, // Number of users per privacity
Sta_LANGUAGES, // Number of users per language
Sta_LAYOUTS, // Number of users per layout
Sta_THEMES, // Number of users per theme
diff --git a/swad_text.c b/swad_text.c
index 85c540a7..337bc03a 100644
--- a/swad_text.c
+++ b/swad_text.c
@@ -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] =
{
-#if L==0
- "Titulaciones y asignaturas" // Necessita traducció
-#elif L==1
- "Studiengänge und Kursen"
-#elif L==2
- "Degrees and courses"
-#elif L==3
- "Titulaciones y asignaturas"
-#elif L==4
- "Études et matiè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çoes e disciplinas"
-#endif
- ,
#if L==0
"Usuaris"
#elif L==1
@@ -35784,6 +35764,26 @@ const char *Txt_STAT_USE_STAT_TYPES[Sta_NUM_TYPES_USE_STATS] =
"Utilizadores"
#endif
,
+#if L==0
+ "Titulaciones y asignaturas" // Necessita traducció
+#elif L==1
+ "Studiengänge und Kursen"
+#elif L==2
+ "Degrees and courses"
+#elif L==3
+ "Titulaciones y asignaturas"
+#elif L==4
+ "Études et matiè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çoes e disciplinas"
+#endif
+ ,
#if L==0
"Webs / xarxes socials"
#elif L==1
@@ -35984,6 +35984,26 @@ const char *Txt_STAT_USE_STAT_TYPES[Sta_NUM_TYPES_USE_STATS] =
"Inquéritos"
#endif
,
+#if L==0
+ "Privacitat"
+#elif L==1
+ "Geheimhaltung"
+#elif L==2
+ "Privacy"
+#elif L==3
+ "Privacidad"
+#elif L==4
+ "Privacité"
+#elif L==5
+ "Privacidad" // Okoteve traducción
+#elif L==6
+ "Privatezza"
+#elif L==7
+ "Prywatność"
+#elif L==8
+ "Privacidade"
+#endif
+ ,
#if L==0
"Idioma"
#elif L==1