From 43ede6ada4279c9ba6c8bafeeec9353189d98377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Mon, 9 Mar 2015 00:16:18 +0100 Subject: [PATCH] Version 14.80 --- js/swad.js | 5 +- swad_changelog.h | 5 +- swad_config.h | 2 +- swad_global.c | 2 +- swad_main.c | 35 ++++++---- swad_parameter.c | 30 +++++++++ swad_statistic.c | 172 +++++++++++++++++++++++++++++++++++++++++++++-- swad_statistic.h | 5 +- swad_text.c | 60 +++++++++++------ 9 files changed, 270 insertions(+), 46 deletions(-) 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