From 4368244ffa5e79b3a1b63800c68e810883224745 Mon Sep 17 00:00:00 2001 From: acanas Date: Wed, 13 May 2020 02:12:11 +0200 Subject: [PATCH] Version19.227 --- sql/swad.sql | 8 +++++ swad_changelog.h | 10 ++++-- swad_database.c | 18 ++++++++++ swad_file_browser.h | 1 + swad_media.c | 29 ++++++++++------ swad_session.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ swad_session.h | 7 ++++ 7 files changed, 145 insertions(+), 12 deletions(-) diff --git a/sql/swad.sql b/sql/swad.sql index 7c93668ce..2353d11a7 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -678,6 +678,14 @@ CREATE TABLE IF NOT EXISTS file_browser_size ( UNIQUE INDEX(FileBrowser,Cod,ZoneUsrCod), INDEX(ZoneUsrCod)); -- +-- Table file_cache: stores the media private paths linked from public directories in current session +-- +CREATE TABLE IF NOT EXISTS file_cache ( + SessionId CHAR(43) NOT NULL, + PrivPath TEXT COLLATE latin1_bin NOT NULL, + TmpPubDir TEXT COLLATE latin1_bin NOT NULL, + INDEX(SessionId)); +-- -- Table file_view: stores the number of times each user has seen each file -- CREATE TABLE IF NOT EXISTS file_view ( diff --git a/swad_changelog.h b/swad_changelog.h index 064c7099e..020b57205 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -548,11 +548,17 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.226 (2020-05-12)" +#define Log_PLATFORM_VERSION "SWAD 19.227 (2020-05-13)" #define CSS_FILE "swad19.217.css" #define JS_FILE "swad19.223.js" /* -// TODO: Public link to images on exams should be cached during the current session. When session is closed ==> remove public link + Version 19.227: May 13, 2020 Cache of linked images. (303586 lines) + 1 change necessary in database: +CREATE TABLE IF NOT EXISTS file_cache (SessionId CHAR(43) NOT NULL,PrivPath TEXT COLLATE latin1_bin NOT NULL,TmpPubDir TEXT COLLATE latin1_bin NOT NULL,INDEX(SessionId)); + If you want to use MyISAM: +ALTER TABLE exa_set_answers ENGINE=MyISAM; +ALTER TABLE exa_set_questions ENGINE=MyISAM; +ALTER TABLE file_cache ENGINE=MyISAM; Version 19.226: May 12, 2020 Questions and answer are cloned from test bank to exams. (303468 lines) 18 changes necessary in database: diff --git a/swad_database.c b/swad_database.c index 913e939b1..fe69dba02 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1481,6 +1481,24 @@ mysql> DESCRIBE file_browser_size; "UNIQUE INDEX(FileBrowser,Cod,ZoneUsrCod)," "INDEX(ZoneUsrCod))"); + /***** Table file_cache *****/ +/* +mysql> DESCRIBE file_cache; ++-----------+----------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++-----------+----------+------+-----+---------+-------+ +| SessionId | char(43) | NO | MUL | NULL | | +| PrivPath | text | NO | | NULL | | +| TmpPubDir | text | NO | | NULL | | ++-----------+----------+------+-----+---------+-------+ +3 rows in set (0.01 sec) +*/ + DB_CreateTable ("CREATE TABLE IF NOT EXISTS file_cache (" + "SessionId CHAR(43) NOT NULL," // Cns_BYTES_SESSION_ID + "PrivPath TEXT COLLATE latin1_bin NOT NULL," // PATH_MAX + "TmpPubDir TEXT COLLATE latin1_bin NOT NULL," // PATH_MAX + "INDEX(SessionId))"); + /***** Table file_view *****/ /* mysql> DESCRIBE file_view; diff --git a/swad_file_browser.h b/swad_file_browser.h index 950337df1..fc46059f7 100644 --- a/swad_file_browser.h +++ b/swad_file_browser.h @@ -198,6 +198,7 @@ void Brw_RemoveUsrFilesFromDB (long UsrCod); void Brw_PutHiddenParamFullTreeIfSelected (void *FullTree); void Brw_CreateDirDownloadTmp (void); + void Brw_AskEditWorksCrs (void); void Brw_AskRemFileFromTree (void); void Brw_RemFileFromTree (void); diff --git a/swad_media.c b/swad_media.c index a9ea0dbce..c78a1f4b6 100644 --- a/swad_media.c +++ b/swad_media.c @@ -1458,9 +1458,6 @@ void Med_ShowMedia (const struct Media *Media, if (PutLink) HTM_A_Begin ("href=\"%s\" target=\"_blank\"",Media->URL); - /* Create a temporary public directory used to show the media */ - Brw_CreateDirDownloadTmp (); - /* Build path to private directory with the media */ snprintf (PathMedPriv,sizeof (PathMedPriv), "%s/%c%c", @@ -1516,6 +1513,7 @@ static void Med_ShowJPG (const struct Media *Media, { extern const char *Txt_File_not_found; char FileNameMedia[NAME_MAX + 1]; + char TmpPubDir[PATH_MAX + 1]; char *FullPathMediaPriv; char *URL; @@ -1530,15 +1528,23 @@ static void Med_ShowJPG (const struct Media *Media, /***** Check if private media file exists *****/ if (Fil_CheckIfPathExists (FullPathMediaPriv)) { - /***** Create symbolic link from temporary public directory to private file - in order to gain access to it for showing/downloading *****/ - Brw_CreateTmpPublicLinkToPrivateFile (FullPathMediaPriv,FileNameMedia); + /***** Get cached public link to private file *****/ + if (!Ses_GetPublicDirFromCache (FullPathMediaPriv,TmpPubDir)) + { + /***** Create symbolic link from temporary public directory to private file + in order to gain access to it for showing/downloading *****/ + Brw_CreateDirDownloadTmp (); + Brw_CreateTmpPublicLinkToPrivateFile (FullPathMediaPriv,FileNameMedia); + + snprintf (TmpPubDir,sizeof (TmpPubDir), + "%s/%s", + Gbl.FileBrowser.TmpPubDir.L,Gbl.FileBrowser.TmpPubDir.R); + Ses_AddPublicDirToCache (FullPathMediaPriv,TmpPubDir); + } /***** Show media *****/ - if (asprintf (&URL,"%s/%s/%s", - Cfg_URL_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir.L, - Gbl.FileBrowser.TmpPubDir.R) < 0) + if (asprintf (&URL,"%s/%s", + Cfg_URL_FILE_BROWSER_TMP_PUBLIC,TmpPubDir) < 0) Lay_NotEnoughMemoryExit (); HTM_IMG (URL,FileNameMedia,Media->Title, "class=\"%s\" lazyload=\"on\"",ClassMedia); // Lazy load of the media @@ -1579,6 +1585,7 @@ static void Med_ShowGIF (const struct Media *Media, { /***** Create symbolic link from temporary public directory to private file in order to gain access to it for showing/downloading *****/ + Brw_CreateDirDownloadTmp (); Brw_CreateTmpPublicLinkToPrivateFile (FullPathGIFPriv,FileNameMedia); /***** Create URL pointing to symbolic link *****/ @@ -1605,6 +1612,7 @@ static void Med_ShowGIF (const struct Media *Media, { /***** Create symbolic link from temporary public directory to private file in order to gain access to it for showing/downloading *****/ + Brw_CreateDirDownloadTmp (); Brw_CreateTmpPublicLinkToPrivateFile (FullPathPNGPriv,FileNameMedia); /***** Show static PNG and animated GIF *****/ @@ -1667,6 +1675,7 @@ static void Med_ShowVideo (const struct Media *Media, { /***** Create symbolic link from temporary public directory to private file in order to gain access to it for showing/downloading *****/ + Brw_CreateDirDownloadTmp (); Brw_CreateTmpPublicLinkToPrivateFile (FullPathMediaPriv,FileNameMediaPriv); /***** Create URL pointing to symbolic link *****/ diff --git a/swad_session.c b/swad_session.c index 079646d0b..42fa3b74a 100644 --- a/swad_session.c +++ b/swad_session.c @@ -118,6 +118,9 @@ void Ses_CloseSession (void) { if (Gbl.Usrs.Me.Logged) { + /***** Remove links to private files from cache *****/ + Ses_RemovePublicDirsCache (); + /***** Remove session from database *****/ Ses_RemoveSessionFromDB (); Gbl.Session.IsOpen = false; @@ -127,7 +130,9 @@ void Ses_CloseSession (void) /***** If there are no more sessions for current user ==> remove user from connected list *****/ Con_RemoveOldConnected (); + /***** Remove unused data associated to expired sessions *****/ Ses_RemoveHiddenParFromExpiredSessions (); + Ses_RemovePublicDirsFromExpiredSessions (); /***** Now, user is not logged in *****/ Gbl.Usrs.Me.Role.LoggedBeforeCloseSession = Gbl.Usrs.Me.Role.Logged; @@ -450,3 +455,82 @@ void Ses_GetHiddenParFromDB (const char *ParamName,char *ParamValue, Lay_ShowErrorAndExit (ErrorTxt); } } + +/*****************************************************************************/ +/******** Get public directory used to link private path from cache **********/ +/*****************************************************************************/ + +bool Ses_GetPublicDirFromCache (const char *FullPathMediaPriv, + char TmpPubDir[PATH_MAX + 1]) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + bool Cached = false; + + /***** Reset temporary directory *****/ + TmpPubDir[0] = '\0'; + + if (Gbl.Session.IsOpen) + { + /***** Get temporary directory from cache *****/ + if (DB_QuerySELECT (&mysql_res,"can not get check if file is cached", + "SELECT TmpPubDir FROM file_cache" + " WHERE SessionId='%s' AND PrivPath='%s'", + Gbl.Session.Id,FullPathMediaPriv)) + { + /* Get the temporary public directory (row[0]) */ + row = mysql_fetch_row (mysql_res); + Str_Copy (TmpPubDir,row[0],PATH_MAX); + Cached = true; + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + + return Cached; + } + +/*****************************************************************************/ +/********* Add public directory used to link private path to cache ***********/ +/*****************************************************************************/ + +void Ses_AddPublicDirToCache (const char *FullPathMediaPriv, + const char TmpPubDir[PATH_MAX + 1]) + { + /***** Insert into cache *****/ + if (Gbl.Session.IsOpen) + DB_QueryINSERT ("can not cache file", + "INSERT INTO file_cache" + " (SessionId,PrivPath,TmpPubDir)" + " VALUES" + " ('%s','%s','%s')", + Gbl.Session.Id,FullPathMediaPriv,TmpPubDir); + } + +/*****************************************************************************/ +/****** Remove public directories used to link private paths from cache ******/ +/*****************************************************************************/ + +void Ses_RemovePublicDirsCache (void) + { + /***** Insert into cache *****/ + if (Gbl.Session.IsOpen) + DB_QueryDELETE ("can not cache file", + "DELETE FROM file_cache WHERE SessionId='%s'", + Gbl.Session.Id); + } + +/*****************************************************************************/ +/****** Remove public directories used to link private paths from cache ******/ +/****** (from expired sessions) ******/ +/*****************************************************************************/ + +void Ses_RemovePublicDirsFromExpiredSessions (void) + { + /***** Remove public directories in expired sessions *****/ + DB_QueryDELETE ("can not remove public directories in expired sessions", + "DELETE FROM file_cache" + " WHERE SessionId NOT IN" + " (SELECT SessionId FROM sessions)"); + } diff --git a/swad_session.h b/swad_session.h index 63454a016..a7fdfbe18 100644 --- a/swad_session.h +++ b/swad_session.h @@ -53,4 +53,11 @@ void Ses_RemoveHiddenParFromExpiredSessions (void); void Ses_GetHiddenParFromDB (const char *ParamName,char *ParamValue, size_t MaxBytes); +bool Ses_GetPublicDirFromCache (const char *FullPathMediaPriv, + char TmpPubDir[PATH_MAX + 1]); +void Ses_AddPublicDirToCache (const char *FullPathMediaPriv, + const char TmpPubDir[PATH_MAX + 1]); +void Ses_RemovePublicDirsCache (void); +void Ses_RemovePublicDirsFromExpiredSessions (void); + #endif