diff --git a/swad_changelog.h b/swad_changelog.h index a0549fc1..1ac2faa4 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -103,11 +103,12 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 14.85.2 (2015/03/11)" +#define Log_PLATFORM_VERSION "SWAD 14.86 (2015/03/11)" // 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 sql/swad*.sql | tail -1 /* + Version 14.86: Mar 11, 2015 Show user's figures per days. (181525 lines) Version 14.85.2: Mar 11, 2015 Refactoring in user's figures. (181478 lines) Version 14.85.1: Mar 11, 2015 Remove user's figures when removing user's account. (181472 lines) Version 14.85: Mar 11, 2015 Number of messages sent is stored in user's figures. (181457 lines) diff --git a/swad_statistic.c b/swad_statistic.c index b61ded52..5ee63231 100644 --- a/swad_statistic.c +++ b/swad_statistic.c @@ -121,7 +121,6 @@ static void Sta_ShowNumAccessesPerCourse (unsigned long NumRows,MYSQL_RES *mysql static void Sta_WriteDegree (long DegCod); static void Sta_DrawBarNumClicks (char Color,float NumPagesGenerated,float MaxPagesGenerated,float TotalPagesGenerated,unsigned MaxBarWidth); static void Sta_WriteSelectedRangeOfDates (unsigned NumDays); -static void Sta_WriteFloatNum (float Number); static void Sta_GetAndShowDegCrsStats (void); static void Sta_WriteHeadDegsCrssInSWAD (void); @@ -1856,7 +1855,7 @@ static void Sta_ShowNumAccessesPerUsr (unsigned long NumRows,MYSQL_RES *mysql_re UsrDat.RoleInCurrentCrsDB == Rol_ROLE_STUDENT ? 'c' : 'v', BarWidth); - Sta_WriteFloatNum (NumPagesGenerated); + Str_WriteFloatNum (NumPagesGenerated); fprintf (Gbl.F.Out," " ""); } @@ -2339,14 +2338,14 @@ static void Sta_DrawBarColors (Sta_ColorType_t ColorType,float MaxPagesGenerated " text-align:center; vertical-align:bottom;\">", GRAPH_DISTRIBUTION_PER_HOUR_TOTAL_WIDTH/5, GRAPH_DISTRIBUTION_PER_HOUR_TOTAL_WIDTH/5); - Sta_WriteFloatNum ((float) Interval * MaxPagesGenerated / 5.0); + Str_WriteFloatNum ((float) Interval * MaxPagesGenerated / 5.0); fprintf (Gbl.F.Out,""); } fprintf (Gbl.F.Out,"", (GRAPH_DISTRIBUTION_PER_HOUR_TOTAL_WIDTH/5)/2, (GRAPH_DISTRIBUTION_PER_HOUR_TOTAL_WIDTH/5)/2); - Sta_WriteFloatNum (MaxPagesGenerated); + Str_WriteFloatNum (MaxPagesGenerated); fprintf (Gbl.F.Out,"" "" ""); @@ -2381,7 +2380,7 @@ static void Sta_DrawAccessesPerHourForADay (Sta_ColorType_t ColorType,float NumP { Sta_SetColor (ColorType,NumPagesGenerated[Hour],MaxPagesGenerated,&R,&G,&B); fprintf (Gbl.F.Out,"" "", @@ -2767,7 +2766,7 @@ static void Sta_WriteAccessHour (unsigned Hour,float NumPagesGenerated,float Max fprintf (Gbl.F.Out,"%u%%
", (unsigned) (((NumPagesGenerated * 100.0) / TotalPagesGenerated) + 0.5)); - Sta_WriteFloatNum (NumPagesGenerated); + Str_WriteFloatNum (NumPagesGenerated); fprintf (Gbl.F.Out,"
"); AltoBarra = (unsigned) (((NumPagesGenerated * 400.0) / MaxPagesGenerated) + 0.5); if (AltoBarra == 0) @@ -3531,7 +3530,7 @@ static void Sta_DrawBarNumClicks (char Color,float NumPagesGenerated,float MaxPa Gbl.Prefs.IconsURL,Color,BarWidth); /* Write the number of clicks */ - Sta_WriteFloatNum (NumPagesGenerated); + Str_WriteFloatNum (NumPagesGenerated); fprintf (Gbl.F.Out," (%u", (unsigned) (((NumPagesGenerated * 100.0) / TotalPagesGenerated) + 0.5)); @@ -3588,39 +3587,6 @@ static void Sta_WriteSelectedRangeOfDates (unsigned NumDays) fprintf (Gbl.F.Out,"

"); } -/*****************************************************************************/ -/******** Write a number in floating point with the correct accuracy *********/ -/*****************************************************************************/ - -static void Sta_WriteFloatNum (float Number) - { - double IntegerPart,FractionaryPart; - char *Format; - - FractionaryPart = modf ((double) Number,&IntegerPart); - - if (FractionaryPart == 0.0) - fprintf (Gbl.F.Out,"%.0f",IntegerPart); - else - { - if (IntegerPart != 0.0 || FractionaryPart >= 0.1) - Format = "%.2f"; - else if (FractionaryPart >= 0.01) - Format = "%.3f"; - else if (FractionaryPart >= 0.001) - Format = "%.4f"; - else if (FractionaryPart >= 0.0001) - Format = "%.5f"; - else if (FractionaryPart >= 0.00001) - Format = "%.6f"; - else if (FractionaryPart >= 0.000001) - Format = "%.7f"; - else - Format = "%e"; - fprintf (Gbl.F.Out,Format,Number); - } - } - /*****************************************************************************/ /************************** Show use of the platform *************************/ /*****************************************************************************/ diff --git a/swad_string.c b/swad_string.c index db2c5b77..b405897d 100644 --- a/swad_string.c +++ b/swad_string.c @@ -28,6 +28,7 @@ #include // For NULL #include // For isprint, isspace, etc. #include // For setlocale +#include // For log10, floor, ceil, modf, sqrt... #include // For malloc and free #include // For string functions @@ -598,6 +599,40 @@ char Str_ConvertToLowerLetter (char Ch) } } +/*****************************************************************************/ +/******** Write a number in floating point with the correct accuracy *********/ +/*****************************************************************************/ + +void Str_WriteFloatNum (float Number) + { + double IntegerPart; + double FractionaryPart; + char *Format; + + FractionaryPart = modf ((double) Number,&IntegerPart); + + if (FractionaryPart == 0.0) + fprintf (Gbl.F.Out,"%.0f",IntegerPart); + else + { + if (IntegerPart != 0.0 || FractionaryPart >= 0.1) + Format = "%.2f"; + else if (FractionaryPart >= 0.01) + Format = "%.3f"; + else if (FractionaryPart >= 0.001) + Format = "%.4f"; + else if (FractionaryPart >= 0.0001) + Format = "%.5f"; + else if (FractionaryPart >= 0.00001) + Format = "%.6f"; + else if (FractionaryPart >= 0.000001) + Format = "%.7f"; + else + Format = "%e"; + fprintf (Gbl.F.Out,Format,Number); + } + } + /*****************************************************************************/ /********** Convert a string that holds a number in floating comma ***********/ /********** to another in floating point changing commas to points ***********/ diff --git a/swad_string.h b/swad_string.h index 7acfeae6..76a90cf0 100644 --- a/swad_string.h +++ b/swad_string.h @@ -74,8 +74,11 @@ char *Str_ConvertToUpperText (char *Str); char *Str_ConvertToLowerText (char *Str); char Str_ConvertToUpperLetter (char Ch); char Str_ConvertToLowerLetter (char Ch); + +void Str_WriteFloatNum (float Number); void Str_ConvertStrFloatCommaToStrFloatPoint (char *Str); float Str_GetFloatNumFromStr (const char *Str); + void Str_AddStrToQuery (char *Query,const char *Str,size_t SizeOfQuery); void Str_ChangeFormat (Str_ChangeFrom_t ChangeFrom,Str_ChangeTo_t ChangeTo, char *Str,size_t MaxLengthStr,bool RemoveLeadingAndTrailingSpaces); diff --git a/swad_text.c b/swad_text.c index e5c9bd9a..88ed1ac6 100644 --- a/swad_text.c +++ b/swad_text.c @@ -6892,9 +6892,30 @@ const char *Txt_Day = "Dia"; #endif +const char *Txt_day = +#if L==0 + "dia"; +#elif L==1 + "Tag"; +#elif L==2 + "day"; +#elif L==3 + "día"; +#elif L==4 + "jour"; +#elif L==5 + "ára"; +#elif L==6 + "giorno"; +#elif L==7 + "dzień"; +#elif L==8 + "dia"; +#endif + const char *Txt_days = #if L==0 - "días"; // Necessita traduccio + "dies"; #elif L==1 "Tage"; #elif L==2 @@ -6904,11 +6925,11 @@ const char *Txt_days = #elif L==4 "jours"; #elif L==5 - "días"; // Okoteve traducción + "ára"; #elif L==6 "giorni"; #elif L==7 - "dni"; + "dni;"; #elif L==8 "dias"; #endif diff --git a/swad_user.c b/swad_user.c index cfd7f4b8..4308354b 100644 --- a/swad_user.c +++ b/swad_user.c @@ -94,6 +94,7 @@ const char *Usr_UsrDatMainFieldNames[Usr_NUM_MAIN_FIELDS_DATA_USR]; struct UsrFigures { struct DateTime FirstClickTime; // 0 ==> unknown first click time of user never logged + int NumDays; // -1 ==> not applicable long NumClicks; // -1L ==> unknown number of clicks long NumForPst; // -1L ==> unknown number of forum posts long NumMsgSnt; // -1L ==> unknown number of messages sent @@ -7583,9 +7584,9 @@ void Usr_ShowDetailsUserProfile (const struct UsrData *UsrDat) { extern const char *The_ClassFormul[The_NUM_THEMES]; extern const char *Txt_Figures; - // extern const char *Txt_Shortcut; - // extern const char *Txt_STR_LANG_ID[Txt_NUM_LANGUAGES]; extern const char *Txt_First_access; + extern const char *Txt_day; + extern const char *Txt_days; extern const char *Txt_Calculate; extern const char *Txt_Clicks; extern const char *Txt_Courses_as_a_ROLE; @@ -7604,26 +7605,6 @@ void Usr_ShowDetailsUserProfile (const struct UsrData *UsrDat) /***** Start table *****/ Lay_StartRoundFrameTable10 (NULL,2,Txt_Figures); - /***** Shortcut to the user's profile *****/ - /* - fprintf (Gbl.F.Out,"" - "" - "%s:" - "" - "" - "" - "%s/%s?usr=@%s" - "" - "" - "", - The_ClassFormul[Gbl.Prefs.Theme], - Txt_Shortcut, - Cfg_HTTPS_URL_SWAD_CGI,Txt_STR_LANG_ID[Gbl.Prefs.Language],UsrDat->Nickname, - Cfg_HTTPS_URL_SWAD_CGI,Txt_STR_LANG_ID[Gbl.Prefs.Language],UsrDat->Nickname); - */ - /***** First click time and number of clicks *****/ Usr_GetUsrFigures (UsrDat->UsrCod,&UsrFigures); @@ -7640,8 +7621,13 @@ void Usr_ShowDetailsUserProfile (const struct UsrData *UsrDat) if (UsrFigures.FirstClickTime.Date.Year) { Dat_WriteDate (UsrFigures.FirstClickTime.Date.YYYYMMDD); - fprintf (Gbl.F.Out," "); + fprintf (Gbl.F.Out," "); Dat_WriteHourMinute (&(UsrFigures.FirstClickTime.YYYYMMDDHHMMSS[8])); + if (UsrFigures.NumDays >= 0) + fprintf (Gbl.F.Out," (%d %s)", + UsrFigures.NumDays, + (UsrFigures.NumDays == 1) ? Txt_day : + Txt_days); } else // First click time is unknown or user never logged { @@ -7666,7 +7652,16 @@ void Usr_ShowDetailsUserProfile (const struct UsrData *UsrDat) The_ClassFormul[Gbl.Prefs.Theme], Txt_Clicks); if (UsrFigures.NumClicks >= 0) + { fprintf (Gbl.F.Out,"%ld",UsrFigures.NumClicks); + if (UsrFigures.NumDays >= 0) + { + fprintf (Gbl.F.Out," ("); + Str_WriteFloatNum ((float) UsrFigures.NumClicks / + (float) (UsrFigures.NumDays + 1)); + fprintf (Gbl.F.Out,"/%s)",Txt_day); + } + } else // Number of clicks is unknown { /***** Button to fetch and store number of clicks *****/ @@ -7752,7 +7747,16 @@ void Usr_ShowDetailsUserProfile (const struct UsrData *UsrDat) The_ClassFormul[Gbl.Prefs.Theme], Txt_Forum_posts); if (UsrFigures.NumForPst >= 0) + { fprintf (Gbl.F.Out,"%ld",UsrFigures.NumForPst); + if (UsrFigures.NumDays >= 0) + { + fprintf (Gbl.F.Out," ("); + Str_WriteFloatNum ((float) UsrFigures.NumForPst / + (float) (UsrFigures.NumDays + 1)); + fprintf (Gbl.F.Out,"/%s)",Txt_day); + } + } else // Number of forum posts is unknown { /***** Button to fetch and store number of forum posts *****/ @@ -7776,7 +7780,16 @@ void Usr_ShowDetailsUserProfile (const struct UsrData *UsrDat) The_ClassFormul[Gbl.Prefs.Theme], Txt_Messages_sent); if (UsrFigures.NumMsgSnt >= 0) + { fprintf (Gbl.F.Out,"%ld",UsrFigures.NumMsgSnt); + if (UsrFigures.NumDays >= 0) + { + fprintf (Gbl.F.Out," ("); + Str_WriteFloatNum ((float) UsrFigures.NumMsgSnt / + (float) (UsrFigures.NumDays + 1)); + fprintf (Gbl.F.Out,"/%s)",Txt_day); + } + } else // Number of clicks is unknown { /***** Button to fetch and store number of messages sent *****/ @@ -7806,6 +7819,7 @@ static void Usr_GetUsrFigures (long UsrCod,struct UsrFigures *UsrFigures) /***** Get user's code from database *****/ sprintf (Query,"SELECT DATE_FORMAT(FirstClickTime,'%%Y%%m%%d%%H%%i%%S')," + "DATEDIFF(NOW(),FirstClickTime)," "NumClicks,NumForPst,NumMsgSnt" " FROM usr_figures WHERE UsrCod='%ld'", UsrCod); @@ -7818,16 +7832,25 @@ static void Usr_GetUsrFigures (long UsrCod,struct UsrFigures *UsrFigures) if (!(Dat_GetDateTimeFromYYYYMMDDHHMMSS (&(UsrFigures->FirstClickTime),row[0]))) Lay_ShowErrorAndExit ("Error when reading first click time."); - /* Get number of clicks (row[1]) */ - if (sscanf (row[1],"%ld",&UsrFigures->NumClicks) != 1) + /* Get number of days since first click (row[1]) */ + if (UsrFigures->FirstClickTime.Date.Year) + { + if (sscanf (row[1],"%d",&UsrFigures->NumDays) != 1) + UsrFigures->NumDays = -1; + } + else + UsrFigures->NumDays = -1; + + /* Get number of clicks (row[2]) */ + if (sscanf (row[2],"%ld",&UsrFigures->NumClicks) != 1) UsrFigures->NumClicks = -1L; - /* Get number of forum posts (row[2]) */ - if (sscanf (row[2],"%ld",&UsrFigures->NumForPst) != 1) + /* Get number of forum posts (row[3]) */ + if (sscanf (row[3],"%ld",&UsrFigures->NumForPst) != 1) UsrFigures->NumForPst = -1L; - /* Get number of messages sent (row[3]) */ - if (sscanf (row[3],"%ld",&UsrFigures->NumMsgSnt) != 1) + /* Get number of messages sent (row[4]) */ + if (sscanf (row[4],"%ld",&UsrFigures->NumMsgSnt) != 1) UsrFigures->NumMsgSnt = -1L; } else @@ -8046,6 +8069,7 @@ static void Usr_GetNumMsgSntAndStoreAsUsrFigure (long UsrCod) static void Usr_ResetUsrFigures (struct UsrFigures *UsrFigures) { Dat_GetDateTimeFromYYYYMMDDHHMMSS (&(UsrFigures->FirstClickTime),"00000000000000"); // unknown first click time or user never logged + UsrFigures->NumDays = -1; // not applicable UsrFigures->NumClicks = -1L; // unknown number of clicks UsrFigures->NumForPst = -1L; // unknown number of forum posts UsrFigures->NumMsgSnt = -1L; // unknown number of messages sent