From e8c581129fb61ac01816672aae2dba4f13f1830f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Fri, 8 Apr 2016 16:37:59 +0200 Subject: [PATCH] Version 15.189 --- css/swad15.188.css | 6 ++++ js/swad15.186.js | 4 +-- sql/swad.sql | 6 ++-- swad_action.c | 4 +-- swad_changelog.h | 8 ++++- swad_database.c | 18 ++++++---- swad_file.c | 12 +++++++ swad_image.c | 25 +++++++------ swad_image.h | 3 +- swad_social.c | 87 +++++++++++++++++++++++++++++++++++++++++----- swad_test.c | 43 ++++++++++++----------- 11 files changed, 161 insertions(+), 55 deletions(-) diff --git a/css/swad15.188.css b/css/swad15.188.css index f095b2298..37550e86c 100644 --- a/css/swad15.188.css +++ b/css/swad15.188.css @@ -1953,6 +1953,12 @@ a:hover img.CENTRE_PHOTO_SHOW color:#404040; font-size:13pt; } +.SOCIAL_IMG + { + width:480px; + border-radius:4px; + margin:10px 0; + } .SOCIAL_ICON_COMMENT { display:inline-block; diff --git a/js/swad15.186.js b/js/swad15.186.js index 9ad7adce8..31dbc92bc 100644 --- a/js/swad15.186.js +++ b/js/swad15.186.js @@ -877,8 +877,8 @@ function enableDisableImgAns (elem, isDisabled) { for (var i = 0; i < Tst_MAX_OPTIONS_PER_QUESTION; i++) if (elem.name == ('ImgAct' + i) || - elem.name == ('FilImg' + i) || - elem.name == ('TitImg' + i)) + elem.name == ('ImgFil' + i) || + elem.name == ('ImgTit' + i)) elem.disabled = isDisabled; } diff --git a/sql/swad.sql b/sql/swad.sql index f5eed37fc..4139647c1 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -961,6 +961,8 @@ CREATE TABLE IF NOT EXISTS social_notes_fav ( CREATE TABLE IF NOT EXISTS social_posts ( PstCod INT NOT NULL AUTO_INCREMENT, Content LONGTEXT NOT NULL, + ImageName VARCHAR(43) NOT NULL, + ImageTitle VARCHAR(255) NOT NULL, UNIQUE INDEX(PstCod), FULLTEXT(Content)) ENGINE = MYISAM; -- @@ -1088,7 +1090,7 @@ CREATE TABLE IF NOT EXISTS tst_answers ( Answer TEXT NOT NULL, Feedback TEXT NOT NULL, ImageName VARCHAR(43) NOT NULL, - ImageTitle TEXT NOT NULL, + ImageTitle VARCHAR(255) NOT NULL, Correct ENUM('N','Y') NOT NULL, INDEX(QstCod)); -- @@ -1147,7 +1149,7 @@ CREATE TABLE IF NOT EXISTS tst_questions ( Stem TEXT NOT NULL, Feedback TEXT NOT NULL, ImageName VARCHAR(43) NOT NULL, - ImageTitle TEXT NOT NULL, + ImageTitle VARCHAR(255) NOT NULL, NumHits INT NOT NULL DEFAULT 0, NumHitsNotBlank INT NOT NULL DEFAULT 0, Score DOUBLE PRECISION NOT NULL DEFAULT 0, diff --git a/swad_action.c b/swad_action.c index 0b3445d4a..9ff94f097 100644 --- a/swad_action.c +++ b/swad_action.c @@ -2343,7 +2343,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActSeeFor */{ 95, 2,TabSoc,ActSeeFor ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,For_ShowForumList ,"forum64x64.gif" }, /* ActSeeChtRms */{ 51, 3,TabSoc,ActSeeChtRms ,0x1FC,0x1FC,0x1FC,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Cht_ShowChatRooms ,"chat64x64.gif" }, - /* ActRcvSocPstGbl */{1492,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_ReceiveSocialPostGbl ,NULL}, + /* ActRcvSocPstGbl */{1492,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_DATA,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_ReceiveSocialPostGbl ,NULL}, /* ActRcvSocComGbl */{1503,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_ReceiveCommentGbl ,NULL}, /* ActShaSocNotGbl */{1495,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_ShareSocialNoteGbl ,NULL}, /* ActUnsSocNotGbl */{1496,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_UnshareSocialNoteGbl ,NULL}, @@ -2358,7 +2358,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActReqPubPrf */{1401,-1,TabSoc,ActSeeSocPrf ,0x1FF,0x1FF,0x1FF,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Prf_RequestUserProfile ,NULL}, - /* ActRcvSocPstUsr */{1498,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ReceiveSocialPostUsr ,NULL}, + /* ActRcvSocPstUsr */{1498,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_DATA,Act_MAIN_WINDOW,NULL ,Soc_ReceiveSocialPostUsr ,NULL}, /* ActRcvSocComUsr */{1504,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ReceiveCommentUsr ,NULL}, /* ActShaSocNotUsr */{1499,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ShareSocialNoteUsr ,NULL}, /* ActUnsSocNotUsr */{1500,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_UnshareSocialNoteUsr ,NULL}, diff --git a/swad_changelog.h b/swad_changelog.h index 3f60bafe1..5d470b7d2 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -127,18 +127,24 @@ // TODO: Fix bug in marks reported by Francisco Ocaņa // TODO: In Statistics > Degrees, show only degrees with students // TODO: Change PhotoAttribution in table centres from TEXT to VARCHAR(255) (check maximum length first) +// TODO: In social refreshing via AJAX, an error occurs when session expirates /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 15.188 (2016-04-08)" +#define Log_PLATFORM_VERSION "SWAD 15.189 (2016-04-08)" #define CSS_FILE "swad15.188.css" #define JS_FILE "swad15.186.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 15.189: Apr 08, 2016 Get image atttached to a social post or comment. (198991 lines) + 2 changes necessary in database: +ALTER TABLE social_posts ADD COLUMN ImageName VARCHAR(43) NOT NULL AFTER Content; +ALTER TABLE social_posts ADD COLUMN ImageTitle VARCHAR(255) NOT NULL AFTER ImageName; + Version 15.188: Apr 08, 2016 Form to attach an image to a social post or comment. Not finished. (198904 lines) Version 15.187.2: Apr 08, 2016 Changed CSS of alerts. (198873 lines) Version 15.187.1: Apr 08, 2016 Code optimization in function to change format of string. (198872 lines) diff --git a/swad_database.c b/swad_database.c index 6a9568afb..1f507c8f2 100644 --- a/swad_database.c +++ b/swad_database.c @@ -2025,17 +2025,21 @@ mysql> DESCRIBE social_notes_fav; /***** Table social_posts *****/ /* mysql> DESCRIBE social_posts; -+---------+----------+------+-----+---------+----------------+ -| Field | Type | Null | Key | Default | Extra | -+---------+----------+------+-----+---------+----------------+ -| PubCod | int(11) | NO | PRI | NULL | auto_increment | -| Content | longtext | NO | MUL | NULL | | -+---------+----------+------+-----+---------+----------------+ -2 rows in set (0.00 sec) ++------------+--------------+------+-----+---------+----------------+ +| Field | Type | Null | Key | Default | Extra | ++------------+--------------+------+-----+---------+----------------+ +| PstCod | int(11) | NO | PRI | NULL | auto_increment | +| Content | longtext | NO | MUL | NULL | | +| ImageName | varchar(43) | NO | | NULL | | +| ImageTitle | varchar(255) | NO | | NULL | | ++------------+--------------+------+-----+---------+----------------+ +4 rows in set (0.00 sec) */ DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_posts (" "PubCod INT NOT NULL AUTO_INCREMENT," "Content LONGTEXT NOT NULL," + "ImageName VARCHAR(43) NOT NULL," + "ImageTitle VARCHAR(255) NOT NULL," "UNIQUE INDEX(PubCod)," "FULLTEXT(Content)) ENGINE = MYISAM;"); diff --git a/swad_file.c b/swad_file.c index 16d268e87..4e38ecb49 100644 --- a/swad_file.c +++ b/swad_file.c @@ -231,6 +231,14 @@ struct Param *Fil_StartReceptionOfFile (const char *ParamFile, /***** Get parameter *****/ Par_GetParameter (Par_PARAM_SINGLE,ParamFile,NULL,Fil_MAX_FILE_SIZE,&Param); + Lay_ShowAlert (Lay_ERROR,ParamFile); // !!!!!!!!!!!!!! + + Lay_ShowAlert (Lay_ERROR,"Fil_StartReceptionOfFile () - 0"); // !!!!!!!!!!!!!! + + sprintf (Gbl.Message,"Param->FileName.Start = %lu Param->FileName.Length = %lu", + Param->FileName.Start,Param->FileName.Length); + Lay_ShowAlert (Lay_ERROR,Gbl.Message); // !!!!!!!!!!!!!! + /***** Get filename *****/ /* Check if filename exists */ if (Param->FileName.Start == 0 || @@ -241,12 +249,14 @@ struct Param *Fil_StartReceptionOfFile (const char *ParamFile, } if (Param->FileName.Length > PATH_MAX) Lay_ShowErrorAndExit ("Error while getting filename."); + Lay_ShowAlert (Lay_ERROR,"Fil_StartReceptionOfFile () - 1"); // !!!!!!!!!!!!!! /* Copy filename */ fseek (Gbl.F.Tmp,Param->FileName.Start,SEEK_SET); if (fread (FileName,sizeof (char),Param->FileName.Length,Gbl.F.Tmp) != Param->FileName.Length) Lay_ShowErrorAndExit ("Error while getting filename."); + Lay_ShowAlert (Lay_ERROR,"Fil_StartReceptionOfFile () - 2"); // !!!!!!!!!!!!!! /***** Get MIME type *****/ /* Check if MIME type exists */ @@ -254,6 +264,7 @@ struct Param *Fil_StartReceptionOfFile (const char *ParamFile, Param->ContentType.Length == 0 || Param->ContentType.Length > Brw_MAX_BYTES_MIME_TYPE) Lay_ShowErrorAndExit ("Error while getting content type."); + Lay_ShowAlert (Lay_ERROR,"Fil_StartReceptionOfFile () - 3"); // !!!!!!!!!!!!!! /* Copy MIME type */ fseek (Gbl.F.Tmp,Param->ContentType.Start,SEEK_SET); @@ -261,6 +272,7 @@ struct Param *Fil_StartReceptionOfFile (const char *ParamFile, Param->ContentType.Length) Lay_ShowErrorAndExit ("Error while getting content type."); MIMEType[Param->ContentType.Length] = '\0'; + Lay_ShowAlert (Lay_ERROR,"Fil_StartReceptionOfFile () - 4"); // !!!!!!!!!!!!!! return Param; } diff --git a/swad_image.c b/swad_image.c index 2b5370a40..7ba3bf99b 100644 --- a/swad_image.c +++ b/swad_image.c @@ -126,19 +126,20 @@ void Img_GetImageFromForm (unsigned NumOpt,struct Image *Image, char Title[Img_MAX_BYTES_TITLE+1]; size_t Length; + /***** Reset image *****/ Image->Action = Img_GetImageActionFromForm (ParamAction); Image->Status = Img_FILE_NONE; + Image->Name[0] = '\0'; Img_FreeImageTitle (Image); // Reset to NULL switch (Image->Action) { - case Img_ACTION_NO_IMAGE: // Do not use image (remove current image if exists) - /***** Reset image name *****/ - Image->Name[0] = '\0'; + case Img_ACTION_NO_IMAGE: // Do not use image (remove current image if exists) break; case Img_ACTION_KEEP_IMAGE: // Keep current image unchanged /***** Get image name *****/ - GetImageFromDB (NumOpt,Image); + if (GetImageFromDB) + GetImageFromDB (NumOpt,Image); break; case Img_ACTION_NEW_IMAGE: // Upload new image /***** Get new image (if present ==> process and create temporary file) *****/ @@ -155,7 +156,8 @@ void Img_GetImageFromForm (unsigned NumOpt,struct Image *Image, /***** Get new image (if present ==> process and create temporary file) *****/ Img_GetAndProcessImageFileFromForm (Image,ParamFile, Width,Height,Quality); - if (Image->Status != Img_FILE_PROCESSED) // No new image received-processed successfully + if (Image->Status != Img_FILE_PROCESSED && // No new image received-processed successfully + GetImageFromDB) /* Get image name */ GetImageFromDB (NumOpt,Image); break; @@ -184,12 +186,15 @@ Img_Action_t Img_GetImageActionFromForm (const char *ParamAction) char UnsignedStr[10+1]; unsigned UnsignedNum; + /***** Get parameter with the action to perform on image *****/ Par_GetParToText (ParamAction,UnsignedStr,10); - if (sscanf (UnsignedStr,"%u",&UnsignedNum) != 1) - Lay_ShowErrorAndExit ("Wrong action to perform on image."); - if (UnsignedNum >= Img_NUM_ACTIONS) - Lay_ShowErrorAndExit ("Wrong action to perform on image."); - return (Img_Action_t) UnsignedNum; + if (UnsignedStr[0]) + if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1) + if (UnsignedNum < Img_NUM_ACTIONS) + return (Img_Action_t) UnsignedNum; + + /***** Default action if none supplied *****/ + return Img_ACTION_NO_IMAGE; } /*****************************************************************************/ diff --git a/swad_image.h b/swad_image.h index 987948425..befa138e2 100644 --- a/swad_image.h +++ b/swad_image.h @@ -87,7 +87,8 @@ struct Image Img_Action_t Action; Img_FileStatus_t Status; char Name[Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64+1]; - char *Title; // Title/attribution + char *Title; // Title/attribution (it must be initialized to NULL + // in order to not trying to free it when no memory allocated) }; /*****************************************************************************/ diff --git a/swad_social.c b/swad_social.c index 02845932a..d6413295c 100644 --- a/swad_social.c +++ b/swad_social.c @@ -35,6 +35,7 @@ #include "swad_exam.h" #include "swad_follow.h" #include "swad_global.h" +#include "swad_image.h" #include "swad_layout.h" #include "swad_notice.h" #include "swad_notification.h" @@ -81,6 +82,14 @@ typedef enum // when user clicks on link at bottom of timeline } Soc_WhatToGetFromTimeline_t; +// Social images will be saved with: +// - maximum width of Soc_IMAGE_SAVED_MAX_HEIGHT +// - maximum height of Soc_IMAGE_SAVED_MAX_HEIGHT +// - maintaining the original aspect ratio (aspect ratio recommended: 3:2) +#define Soc_IMAGE_SAVED_MAX_WIDTH 768 +#define Soc_IMAGE_SAVED_MAX_HEIGHT 512 +#define Soc_IMAGE_SAVED_QUALITY 75 // 1 to 100 + /*****************************************************************************/ /****************************** Internal types *******************************/ /*****************************************************************************/ @@ -1442,24 +1451,36 @@ static void Soc_WriteDateTime (time_t TimeUTC) static void Soc_GetAndWriteSocialPost (long PstCod) { - char Query[128]; + char Query[256]; MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned long NumRows; char Content[Cns_MAX_BYTES_LONG_TEXT+1]; + struct Image Image; + + /***** Initialize image *****/ + Image.Action = Img_ACTION_NO_IMAGE; + Image.Status = Img_FILE_NONE; + Image.Name[0] = '\0'; + Image.Title = NULL; /***** Get social post from database *****/ - sprintf (Query,"SELECT Content FROM social_posts WHERE PstCod='%ld'", + sprintf (Query,"SELECT Content,ImageName,ImageTitle" + " FROM social_posts WHERE PstCod='%ld'", PstCod); NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get the content of a social post"); /***** Result should have a unique row *****/ if (NumRows == 1) { - /****** Get content (row[0]) *****/ row = mysql_fetch_row (mysql_res); + + /****** Get content (row[0]) *****/ strncpy (Content,row[0],Cns_MAX_BYTES_LONG_TEXT); Content[Cns_MAX_BYTES_LONG_TEXT] = '\0'; + + /****** Get image name (row[1]) and title (row[2]) *****/ + Img_GetImageNameAndTitleFromRow (row[1],row[2],&Image); } else Content[0] = '\0'; @@ -1469,6 +1490,12 @@ static void Soc_GetAndWriteSocialPost (long PstCod) /***** Write content *****/ Msg_WriteMsgContent (Content,Cns_MAX_BYTES_LONG_TEXT,true,false); + + /***** Show image *****/ + Img_ShowImage (&Image,"SOCIAL_IMG"); + + /***** Free allocated memory for the title/attribution of the image *****/ + Img_FreeImageTitle (&Image); } /*****************************************************************************/ @@ -1992,7 +2019,11 @@ static void Soc_PutTextarea (const char *Placeholder, Placeholder,ClassTextArea, IdButton,IdButton); - /***** Image file *****/ + /***** Attached image (optional) *****/ + /* Action to perform on image */ + Par_PutHiddenParamUnsigned ("ImgAct",(unsigned) Img_ACTION_NEW_IMAGE); + + /* Image file */ fprintf (Gbl.F.Out,"