mirror of https://github.com/acanas/swad-core.git
Version 16.17
This commit is contained in:
parent
0b253eb929
commit
79e8583003
|
@ -11644,7 +11644,8 @@ CREATE TABLE IF NOT EXISTS usr_report (RepCod INT NOT NULL AUTO_INCREMENT,UsrCod
|
|||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------
|
||||
--------------------------------------------------
|
||||
|
||||
|
||||
SELECT CrsCod,COUNT(*) AS N FROM crs_usr LEFT JOIN log_full ON (crs_usr.CrsCod=log_full.CrsCod AND crs_usr.UsrCod=log_full.UsrCod AND crs_usr.Role=log_full.Role) WHERE UsrCod='7' AND Role='3' GROUP BY CrsCod ORDER BY N DESC;
|
||||
|
|
|
@ -142,17 +142,20 @@
|
|||
|
||||
// TODO: FIX BUG: Centre and degree admins should see buttons to admin users even a course is not selected
|
||||
|
||||
// TODO: Generar informe -> ¿Realmente desea generar un informe... (puede tardar varios segundos...)? -> Generar informe.
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define Log_PLATFORM_VERSION "SWAD 16.16.1 (2016-10-07)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 16.17 (2016-10-08)"
|
||||
#define CSS_FILE "swad15.229.css"
|
||||
#define JS_FILE "swad15.238.1.js"
|
||||
|
||||
// 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 16.17: Oct 08, 2016 List of most frequent actions in user's usage report. (206189 lines)
|
||||
Version 16.16.1: Oct 07, 2016 Fixed bug in user's usage report. (206108 lines)
|
||||
Version 16.16: Oct 07, 2016 Order current courses in user's usage report by number of clicks.
|
||||
Do not write number of users in historic courses.
|
||||
|
@ -207,7 +210,7 @@ INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1586','es','N','Soli
|
|||
Version 16.4.1: Sep 29, 2016 Changes in hits in current courses in user's usage report. (205316 lines)
|
||||
Version 16.4: Sep 29, 2016 Hits in current courses in user's usage report. (205299 lines)
|
||||
Version 16.3.2: Sep 28, 2016 Changes in behaviour of button to follow user. (205277 lines)
|
||||
Version 16.3.1: Sep 28, 2016 Two different messagesrelated to new account merged into one.
|
||||
Version 16.3.1: Sep 28, 2016 Two different messages related to new account merged into one.
|
||||
Changes in form to create new account. (205271 lines)
|
||||
Version 16.3: Sep 26, 2016 Message translated.
|
||||
Code refactoring of list with empty accounts for an ID. (205287 lines)
|
||||
|
|
107
swad_report.c
107
swad_report.c
|
@ -32,6 +32,7 @@
|
|||
#include "swad_global.h"
|
||||
#include "swad_ID.h"
|
||||
#include "swad_profile.h"
|
||||
#include "swad_tab.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
|
@ -44,6 +45,7 @@
|
|||
#define Rep_FILENAME_ROOT "report"
|
||||
|
||||
#define Rep_MIN_CLICKS_CRS 100 // Minimum number of clicks to show a course in historic log
|
||||
#define Rep_MAX_ACTIONS 50 // Maximum number of actions in list of frequent actions
|
||||
#define Rep_MAX_BAR_WIDTH 50 // Maximum width of graphic bar
|
||||
|
||||
// #define Rep_BLOCK "═" // HTML code for a block in graphic bar
|
||||
|
@ -105,6 +107,7 @@ static void Rep_WriteSectionUsrInfo (void);
|
|||
static void Rep_WriteSectionUsrFigures (const struct UsrFigures *UsrFigures,
|
||||
const struct tm *tm_FirstClickTime,
|
||||
const struct CurrentTimeUTC *CurrentTimeUTC);
|
||||
static void Rep_WriteSectionHitsPerAction (const struct UsrFigures *UsrFigures);
|
||||
static void Rep_WriteSectionGlobalHits (const struct UsrFigures *UsrFigures,
|
||||
const struct tm *tm_FirstClickTime);
|
||||
static void Rep_WriteSectionCurrentCourses (const struct UsrFigures *UsrFigures,
|
||||
|
@ -234,9 +237,12 @@ static void Rep_CreateMyUsageReport (struct CurrentTimeUTC *CurrentTimeUTC,
|
|||
gmtime_r (&UsrFigures.FirstClickTimeUTC,&tm_FirstClickTime);
|
||||
Rep_WriteSectionUsrFigures (&UsrFigures,&tm_FirstClickTime,CurrentTimeUTC);
|
||||
|
||||
/***** Global hits *****/
|
||||
/***** Global count of hits *****/
|
||||
Rep_WriteSectionGlobalHits (&UsrFigures,&tm_FirstClickTime);
|
||||
|
||||
/***** Global hits distributed by action *****/
|
||||
Rep_WriteSectionHitsPerAction (&UsrFigures);
|
||||
|
||||
/***** Current courses *****/
|
||||
MaxHitsPerYear = Rep_GetMaxHitsPerYear (UsrFigures.FirstClickTimeUTC);
|
||||
Rep_WriteSectionCurrentCourses (&UsrFigures,&tm_FirstClickTime,
|
||||
|
@ -749,12 +755,10 @@ static void Rep_WriteSectionUsrFigures (const struct UsrFigures *UsrFigures,
|
|||
static void Rep_WriteSectionGlobalHits (const struct UsrFigures *UsrFigures,
|
||||
const struct tm *tm_FirstClickTime)
|
||||
{
|
||||
extern const char *Txt_Hits;
|
||||
|
||||
/***** Start of section *****/
|
||||
fprintf (Gbl.F.Rep,"<section>"
|
||||
"<h3>%s</h3>",
|
||||
Txt_Hits);
|
||||
"Accesos (clics) por año"); // TODO: Need translation!!!!
|
||||
|
||||
/***** Global (in any course) hits per year *****/
|
||||
Rep_ShowMyHitsPerYear (true,-1L, // Any course
|
||||
|
@ -767,6 +771,86 @@ static void Rep_WriteSectionGlobalHits (const struct UsrFigures *UsrFigures,
|
|||
fprintf (Gbl.F.Rep,"</section>\n");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******** Write section for user's global hits in user's usage report ********/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Rep_WriteSectionHitsPerAction (const struct UsrFigures *UsrFigures)
|
||||
{
|
||||
extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
|
||||
extern Act_Action_t Act_FromActCodToAction[1+Act_MAX_ACTION_COD];
|
||||
extern const char *Txt_TABS_FULL_TXT[Tab_NUM_TABS];
|
||||
char Query[512];
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
unsigned long NumRows;
|
||||
unsigned long NumRow;
|
||||
struct Sta_Hits Hits;
|
||||
long ActCod;
|
||||
char ActTxt[Act_MAX_LENGTH_ACTION_TXT+1];
|
||||
long NumClicks;
|
||||
|
||||
/***** Start of section *****/
|
||||
fprintf (Gbl.F.Rep,"<section>"
|
||||
"<h3>%s</h3>",
|
||||
"Accesos (clics) por acción"); // TODO: Need translation!!!!
|
||||
|
||||
/***** Make the query *****/
|
||||
sprintf (Query,"SELECT SQL_NO_CACHE ActCod,COUNT(*) AS N FROM log_full"
|
||||
" WHERE ClickTime>=FROM_UNIXTIME('%ld') AND UsrCod='%ld'"
|
||||
" GROUP BY ActCod ORDER BY N DESC LIMIT %u",
|
||||
(long) UsrFigures->FirstClickTimeUTC,Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Rep_MAX_ACTIONS);
|
||||
NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get clicks");
|
||||
|
||||
/***** Compute maximum number of hits per action *****/
|
||||
Sta_ComputeMaxAndTotalHits (&Hits,NumRows,mysql_res,1,1);
|
||||
mysql_data_seek (mysql_res,0);
|
||||
|
||||
/***** Write rows *****/
|
||||
for (NumRow = 1, NumClicks = 0;
|
||||
NumRow <= NumRows;
|
||||
NumRow++)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get the action (row[0]) */
|
||||
ActCod = Str_ConvertStrCodToLongCod (row[0]);
|
||||
|
||||
/* Get number hits (in row[1]) */
|
||||
Hits.Num = Str_GetFloatNumFromStr (row[1]);
|
||||
NumClicks += (long) Hits.Num;
|
||||
|
||||
/* Draw bar proportional to number of hits */
|
||||
Rep_DrawBarNumHits (Hits.Num,Hits.Max,Rep_MAX_BAR_WIDTH);
|
||||
|
||||
/* Write action text */
|
||||
fprintf (Gbl.F.Rep," ");
|
||||
if (ActCod >= 0)
|
||||
{
|
||||
if (Txt_TABS_FULL_TXT[Act_Actions[Act_FromActCodToAction[ActCod]].Tab])
|
||||
fprintf (Gbl.F.Rep,"%s > ",
|
||||
Txt_TABS_FULL_TXT[Act_Actions[Act_FromActCodToAction[ActCod]].Tab]);
|
||||
fprintf (Gbl.F.Rep,"%s",Act_GetActionTextFromDB (ActCod,ActTxt));
|
||||
}
|
||||
else
|
||||
fprintf (Gbl.F.Rep,"?");
|
||||
fprintf (Gbl.F.Rep,"<br />");
|
||||
}
|
||||
|
||||
/***** Draw bar for the rest of the clicks *****/
|
||||
if (UsrFigures->NumClicks > NumClicks)
|
||||
fprintf (Gbl.F.Rep,"%ld (%s)<br />",
|
||||
UsrFigures->NumClicks - NumClicks,
|
||||
"otras acciones"); // TODO: Need translation!!!!
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
/***** End of section *****/
|
||||
fprintf (Gbl.F.Rep,"</section>\n");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****** Write section for user's current courses in user's usage report ******/
|
||||
/*****************************************************************************/
|
||||
|
@ -825,7 +909,7 @@ static void Rep_WriteSectionHistoricCourses (const struct UsrFigures *UsrFigures
|
|||
|
||||
/********* Historic clicks of a user without course selected ***********/
|
||||
Rep_GetAndWriteMyHistoricClicsWithoutCrs (UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
|
||||
MaxHitsPerYear);
|
||||
MaxHitsPerYear);
|
||||
|
||||
/***** Historic courses in which the user clicked as student/teacher *****/
|
||||
for (Role = Rol_STUDENT;
|
||||
|
@ -833,8 +917,8 @@ static void Rep_WriteSectionHistoricCourses (const struct UsrFigures *UsrFigures
|
|||
Role++)
|
||||
/* List my courses with this role */
|
||||
Rep_GetAndWriteMyHistoricCrss (Role,
|
||||
UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
|
||||
MaxHitsPerYear);
|
||||
UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
|
||||
MaxHitsPerYear);
|
||||
|
||||
/***** End of section *****/
|
||||
fprintf (Gbl.F.Rep,"</ul>"
|
||||
|
@ -897,6 +981,9 @@ static unsigned long Rep_GetMaxHitsPerYear (time_t FirstClickTimeUTC)
|
|||
if (sscanf (row[0],"%lu",&MaxHitsPerYear) != 1)
|
||||
Lay_ShowErrorAndExit ("Error when getting maximum hits.");
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
return MaxHitsPerYear;
|
||||
}
|
||||
|
||||
|
@ -1226,10 +1313,14 @@ static void Rep_ShowMyHitsPerYear (bool AnyCourse,long CrsCod,Rol_Role_t Role,
|
|||
Rep_DrawBarNumHits (Year == LastYear ? Hits.Num :
|
||||
0.0,
|
||||
Hits.Max,Rep_MAX_BAR_WIDTH);
|
||||
fprintf (Gbl.F.Rep,"<br />");
|
||||
}
|
||||
LastYear = Year;
|
||||
}
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
/***** Finally, show the oldest years without clicks *****/
|
||||
for (Year = LastYear;
|
||||
Year >= Gbl.DateRange.DateIni.Date.Year;
|
||||
|
@ -1240,6 +1331,7 @@ static void Rep_ShowMyHitsPerYear (bool AnyCourse,long CrsCod,Rol_Role_t Role,
|
|||
|
||||
/* Draw bar proportional to number of hits */
|
||||
Rep_DrawBarNumHits (0.0,Hits.Max,Rep_MAX_BAR_WIDTH);
|
||||
fprintf (Gbl.F.Rep,"<br />");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1271,7 +1363,6 @@ static void Rep_DrawBarNumHits (float HitsNum,float HitsMax,
|
|||
fprintf (Gbl.F.Rep," ");
|
||||
Str_WriteFloatNum (Gbl.F.Rep,HitsNum);
|
||||
}
|
||||
fprintf (Gbl.F.Rep,"<br />");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -273,9 +273,11 @@ void Sta_LogAccess (const char *Comments)
|
|||
|
||||
/***** Insert access into database *****/
|
||||
/* Log access in historical log (log_full) */
|
||||
sprintf (Query,"INSERT INTO log_full (ActCod,CtyCod,InsCod,CtrCod,DegCod,CrsCod,UsrCod,"
|
||||
sprintf (Query,"INSERT INTO log_full "
|
||||
"(ActCod,CtyCod,InsCod,CtrCod,DegCod,CrsCod,UsrCod,"
|
||||
"Role,ClickTime,TimeToGenerate,TimeToSend,IP)"
|
||||
" VALUES ('%ld','%ld','%ld','%ld','%ld','%ld','%ld',"
|
||||
" VALUES "
|
||||
"('%ld','%ld','%ld','%ld','%ld','%ld','%ld',"
|
||||
"'%u',NOW(),'%ld','%ld','%s')",
|
||||
Act_Actions[Gbl.Action.Act].ActCod,
|
||||
Gbl.CurrentCty.Cty.CtyCod,
|
||||
|
@ -298,9 +300,11 @@ void Sta_LogAccess (const char *Comments)
|
|||
LogCod = DB_QueryINSERTandReturnCode (Query,"can not log access (full)");
|
||||
|
||||
/* Log access in recent log (log_recent) */
|
||||
sprintf (Query,"INSERT INTO log_recent (LogCod,ActCod,CtyCod,InsCod,CtrCod,DegCod,CrsCod,UsrCod,"
|
||||
sprintf (Query,"INSERT INTO log_recent "
|
||||
"(LogCod,ActCod,CtyCod,InsCod,CtrCod,DegCod,CrsCod,UsrCod,"
|
||||
"Role,ClickTime,TimeToGenerate,TimeToSend,IP)"
|
||||
" VALUES ('%ld','%ld','%ld','%ld','%ld','%ld','%ld','%ld',"
|
||||
" VALUES "
|
||||
"('%ld','%ld','%ld','%ld','%ld','%ld','%ld','%ld',"
|
||||
"'%u',NOW(),'%ld','%ld','%s')",
|
||||
LogCod,Act_Actions[Gbl.Action.Act].ActCod,
|
||||
Gbl.CurrentCty.Cty.CtyCod,
|
||||
|
@ -3002,8 +3006,8 @@ static void Sta_ShowNumHitsPerAction (unsigned long NumRows,
|
|||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Write the action */
|
||||
if (sscanf (row[0],"%ld",&ActCod) != 1)
|
||||
Lay_ShowErrorAndExit ("Wrong action code.");
|
||||
ActCod = Str_ConvertStrCodToLongCod (row[0]);
|
||||
|
||||
if (ActCod >= 0)
|
||||
fprintf (Gbl.F.Out,"<tr>"
|
||||
"<td class=\"LOG RIGHT_TOP\">"
|
||||
|
|
Loading…
Reference in New Issue