// swad_report.c: report on my use of the platform
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2016 Antonio Caņas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General 3 License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
/*****************************************************************************/
/*********************************** Headers *********************************/
/*****************************************************************************/
#include // For unlink
#include "swad_database.h"
#include "swad_global.h"
#include "swad_ID.h"
#include "swad_profile.h"
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
#define Rep_MIN_CLICKS_CRS 100 // Minimum number of clicks to show a course in historic log
#define Rep_MAX_BAR_WIDTH 50 // Maximum width of graphic bar
// #define Rep_BLOCK "═" // HTML code for a block in graphic bar
// #define Rep_BLOCK "▒" // HTML code for a block in graphic bar
// #define Rep_BLOCK "█" // HTML code for a block in graphic bar
// #define Rep_BLOCK "≡" // HTML code for a block in graphic bar
// #define Rep_BLOCK "•" // HTML code for a block in graphic bar
// #define Rep_BLOCK "▪" // HTML code for a block in graphic bar
#define Rep_BLOCK "-"
/*****************************************************************************/
/****************************** Internal types *******************************/
/*****************************************************************************/
struct CurrentTimeUTC
{
char StrDate[10+1]; // Example: 2016-10-02
// 1234567890
char StrTime[8+1]; // Example: 19:03:49
// 12345678
};
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/************************* Internal global variables *************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void Rep_CreateMyUsageReport (struct CurrentTimeUTC *CurrentTimeUTC,
char *Permalink);
static void Rep_PutLinkToMyUsageReport (struct CurrentTimeUTC *CurrentTimeUTC,
const char *Permalink);
static void Req_TitleReport (struct CurrentTimeUTC *CurrentTimeUTC);
static void Rep_WriteHeader (struct CurrentTimeUTC *CurrentTimeUTC,
const char *Permalink);
static void Rep_WriteSectionPlatform (void);
static void Rep_WriteSectionUsrInfo (void);
static void Rep_WriteSectionUsrFigures (struct UsrFigures *UsrFigures,
struct tm *tm_FirstClickTime,
struct CurrentTimeUTC *CurrentTimeUTC);
static void Rep_WriteSectionGlobalHits (struct UsrFigures *UsrFigures,
struct tm *tm_FirstClickTime);
static void Rep_WriteSectionCurrentCourses (struct UsrFigures *UsrFigures,
struct tm *tm_FirstClickTime,
struct CurrentTimeUTC *CurrentTimeUTC,
unsigned long MaxHitsPerYear);
static void Rep_WriteSectionHistoricCourses (struct UsrFigures *UsrFigures,
struct tm *tm_FirstClickTime,
unsigned long MaxHitsPerYear);
static unsigned long Rep_GetMaxHitsPerYear (time_t FirstClickTimeUTC);
static void Rep_GetAndWriteCurrentCrssOfAUsr (const struct UsrData *UsrDat,Rol_Role_t Role,
time_t FirstClickTimeUTC,
struct tm *tm_FirstClickTime,
unsigned long MaxHitsPerYear);
static void Rep_GetAndWriteHistoricCrssOfAUsr (const struct UsrData *UsrDat,Rol_Role_t Role,
time_t FirstClickTimeUTC,
struct tm *tm_FirstClickTime,
unsigned long MaxHitsPerYear);
static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
time_t FirstClickTimeUTC,
struct tm *tm_FirstClickTime,
unsigned long MaxHitsPerYear);
static void Rep_ShowMyHitsPerYear (bool AnyCourse,long CrsCod,Rol_Role_t Role,
time_t FirstClickTimeUTC,
struct tm *tm_FirstClickTime,
unsigned long MaxHitsPerYear);
static void Rep_DrawBarNumHits (float HitsNum,float HitsMax,
unsigned MaxBarWidth);
/*****************************************************************************/
/******* Request my usage report (report on my use of the platform) **********/
/*****************************************************************************/
void Rep_ReqMyUsageReport (void)
{
extern const char *Txt_Report_of_use_of_PLATFORM;
extern const char *Txt_Generate_report;
struct CurrentTimeUTC CurrentTimeUTC;
/***** Get current date-time *****/
Dat_GetCurrentDateTimeUTC (CurrentTimeUTC.StrDate,
CurrentTimeUTC.StrTime);
/***** Form to show my usage report *****/
Act_FormStart (ActSeeMyUsgRep);
/***** Start frame *****/
sprintf (Gbl.Title,Txt_Report_of_use_of_PLATFORM,Cfg_PLATFORM_SHORT_NAME);
Lay_StartRoundFrame (NULL,Gbl.Title,NULL);
/***** Header *****/
Req_TitleReport (&CurrentTimeUTC);
/***** Send button and end frame *****/
Lay_EndRoundFrameWithButton (Lay_CONFIRM_BUTTON,Txt_Generate_report);
/***** End of form *****/
Act_FormEnd ();
}
/*****************************************************************************/
/********* Show my usage report (report on my use of the platform) ***********/
/*****************************************************************************/
void Rep_ShowMyUsageReport (void)
{
struct CurrentTimeUTC CurrentTimeUTC;
char Permalink[PATH_MAX+1];
/***** Create my usage report *****/
Rep_CreateMyUsageReport (&CurrentTimeUTC,Permalink);
/***** Put link to my usage report *****/
Rep_PutLinkToMyUsageReport (&CurrentTimeUTC,Permalink);
}
/*****************************************************************************/
/******** Create my usage report (report on my use of the platform) **********/
/*****************************************************************************/
static void Rep_CreateMyUsageReport (struct CurrentTimeUTC *CurrentTimeUTC,
char *Permalink)
{
extern const char *Txt_Report_of_use_of_PLATFORM;
extern const char *Txt_Report;
struct UsrFigures UsrFigures;
char PathReports[PATH_MAX+1];
char PathFileReport[PATH_MAX+1];
struct tm tm_FirstClickTime;
bool GetUsrFiguresAgain;
unsigned long MaxHitsPerYear;
/***** Get current date-time *****/
Dat_GetCurrentDateTimeUTC (CurrentTimeUTC->StrDate,
CurrentTimeUTC->StrTime);
/***** Path for reports *****/
sprintf (PathReports,"%s/%s",Cfg_PATH_SWAD_PUBLIC,Cfg_FOLDER_REP);
Fil_CreateDirIfNotExists (PathReports);
/***** Create a new empty syllabus *****/
/* Path of the private directory for the file with the report */
sprintf (PathFileReport,"%s/%s.html",
PathReports,Gbl.UniqueNameEncrypted);
sprintf (Permalink,"%s/%s/%s.html",
Cfg_URL_SWAD_PUBLIC,
Cfg_FOLDER_REP,
Gbl.UniqueNameEncrypted);
if ((Gbl.F.Rep = fopen (PathFileReport,"wb")) == NULL)
Lay_ShowErrorAndExit ("Can not create report file.");
/***** Start file *****/
Lay_StartHTMLFile (Gbl.F.Rep,Txt_Report);
fprintf (Gbl.F.Rep,"\n");
/***** Header *****/
Rep_WriteHeader (CurrentTimeUTC,Permalink);
/***** Platform *****/
Rep_WriteSectionPlatform ();
/***** Personal information *****/
Rep_WriteSectionUsrInfo ();
/***** Figures *****/
Prf_GetUsrFigures (Gbl.Usrs.Me.UsrDat.UsrCod,&UsrFigures);
GetUsrFiguresAgain = Prf_GetAndStoreAllUsrFigures (Gbl.Usrs.Me.UsrDat.UsrCod,&UsrFigures);
if (GetUsrFiguresAgain)
Prf_GetUsrFigures (Gbl.Usrs.Me.UsrDat.UsrCod,&UsrFigures);
if (UsrFigures.FirstClickTimeUTC)
gmtime_r (&UsrFigures.FirstClickTimeUTC,&tm_FirstClickTime);
Rep_WriteSectionUsrFigures (&UsrFigures,&tm_FirstClickTime,CurrentTimeUTC);
/***** Global hits *****/
Rep_WriteSectionGlobalHits (&UsrFigures,&tm_FirstClickTime);
/***** Current courses *****/
MaxHitsPerYear = Rep_GetMaxHitsPerYear (UsrFigures.FirstClickTimeUTC);
Rep_WriteSectionCurrentCourses (&UsrFigures,&tm_FirstClickTime,
CurrentTimeUTC,MaxHitsPerYear);
/***** Historic courses *****/
Rep_WriteSectionHistoricCourses (&UsrFigures,&tm_FirstClickTime,
MaxHitsPerYear);
/***** End file *****/
fprintf (Gbl.F.Rep,"\n"
"