Version18.85

This commit is contained in:
Antonio Cañas Vargas 2019-03-21 20:04:01 +01:00
parent 7e598fe52a
commit 252a8178fa
9 changed files with 513 additions and 243 deletions

View File

@ -2774,6 +2774,29 @@ a:hover img.CENTRE_PHOTO_SHOW
height:100%; height:100%;
} }
/* Slideshare:
487 / 599 = 0,813021703
422 / 514 = 0,821011673
357 / 429 = 0,832167832
292 / 344 = 0,848837209 */
.MED_EMBED_CONT /* Adjust container height to get a 16:9 aspect ratio */
{
position:relative;
box-sizing:border-box;
margin:10px 0;
padding-bottom:56.25%; /* percentage relative to width */
}
.MED_EMBED_CONT iframe,
.MED_EMBED_CONT object,
.MED_EMBED_CONT embed
{
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
}
/********** Author of assignments, attendance, messages, surveys... **********/ /********** Author of assignments, attendance, messages, surveys... **********/
.AUTHOR_1_LINE .AUTHOR_1_LINE
{ {
@ -2898,12 +2921,12 @@ a:hover img.CENTRE_PHOTO_SHOW
} }
@media only screen and (min-width: 800px) @media only screen and (min-width: 800px)
{ /* For tablets and desktop */ { /* For tablets and desktop */
.TL_WIDTH {width:536px;} .TL_WIDTH {width:566px;} /* 536 -> 566 */
.TL_RIGHT_WIDTH {width:480px;} .TL_RIGHT_WIDTH {width:510px;} /* 480 -> 510 */
.TL_RIGHT_AUTHOR_WIDTH {width:320px;} .TL_RIGHT_AUTHOR_WIDTH {width:350px;} /* 320 -> 350 */
.TL_POST_MED_WIDTH {width:440px;} .TL_POST_MED_WIDTH {width:470px;} /* 440 -> 470 */
.TL_COMMENT_WIDTH {width:440px;} .TL_COMMENT_WIDTH {width:470px;} /* 440 -> 470 */
.TL_COMMENT_AUTHOR_WIDTH {width:280px;} .TL_COMMENT_AUTHOR_WIDTH {width:310px;} /* 280 -> 310 */
} }
.TL_NEW_PUB .TL_NEW_PUB

View File

@ -772,24 +772,31 @@ function AJAXCreateObject () {
/*****************************************************************************/ /*****************************************************************************/
function mediaClickOnActivateUpload (id) { function mediaClickOnActivateUpload (id) {
var par_upl = document.getElementById (id + '_par_upl'); var par_upl = document.getElementById (id + '_par_upl');
if (par_upl.disabled) { // Click on highlighted icon if (par_upl.disabled) { // Click on highlighted icon
var par_emb = document.getElementById (id + '_par_emb'); // par_upl already got
var par_you = document.getElementById (id + '_par_you');
var par_emb = document.getElementById (id + '_par_emb');
var ico_upl = document.getElementById (id + '_ico_upl'); var ico_upl = document.getElementById (id + '_ico_upl');
var ico_you = document.getElementById (id + '_ico_you');
var ico_emb = document.getElementById (id + '_ico_emb'); var ico_emb = document.getElementById (id + '_ico_emb');
var fil = document.getElementById (id + '_fil'); var fil = document.getElementById (id + '_fil');
var url = document.getElementById (id + '_url'); var url = document.getElementById (id + '_url');
var tit = document.getElementById (id + '_tit'); var tit = document.getElementById (id + '_tit');
// Disable embed and enable upload // Enable embed, disable others
par_emb.disabled = true; // Disable embed
par_upl.disabled = false; // Enable upload par_upl.disabled = false; // Enable upload
par_you.disabled = true; // Disable youtube
par_emb.disabled = true; // Disable embed
ico_upl.className = 'PREF_ON'; // Highlighted upload icon ico_upl.className = 'PREF_ON'; // Highlighted upload icon
ico_you.className = 'PREF_OFF'; // Normal youtube icon
ico_emb.className = 'PREF_OFF'; // Normal embed icon ico_emb.className = 'PREF_OFF'; // Normal embed icon
fil.style.display = ''; // Show file input fil.style.display = ''; // Show file input
fil.disabled = false; // Enable file input fil.disabled = false; // Enable file input
url.style.display = ''; // Show URL input url.style.display = ''; // Show URL input
@ -799,26 +806,33 @@ function mediaClickOnActivateUpload (id) {
tit.disabled = false; // Enable title input tit.disabled = false; // Enable title input
} }
else // Click on shadowed icon else // Click on shadowed icon
mediaDisableUploadAndEmbed (id); mediaDisableAll (id);
} }
function mediaClickOnActivateEmbed (id) { function mediaClickOnActivateYoutube (id) {
var par_emb = document.getElementById (id + '_par_emb'); var par_you = document.getElementById (id + '_par_you');
if (par_emb.disabled) { // Click on highlighted icon if (par_you.disabled) { // Click on highlighted icon
var par_upl = document.getElementById (id + '_par_upl'); var par_upl = document.getElementById (id + '_par_upl');
// par_you already got
var par_emb = document.getElementById (id + '_par_emb');
var ico_upl = document.getElementById (id + '_ico_upl'); var ico_upl = document.getElementById (id + '_ico_upl');
var ico_you = document.getElementById (id + '_ico_you');
var ico_emb = document.getElementById (id + '_ico_emb'); var ico_emb = document.getElementById (id + '_ico_emb');
var fil = document.getElementById (id + '_fil'); var fil = document.getElementById (id + '_fil');
var url = document.getElementById (id + '_url'); var url = document.getElementById (id + '_url');
var tit = document.getElementById (id + '_tit'); var tit = document.getElementById (id + '_tit');
// Disable upload and enable embed // Enable youtube, disable others
par_upl.disabled = true; // Disable upload par_upl.disabled = true; // Disable upload
par_emb.disabled = false; // Enable embed par_you.disabled = false; // Enable youtube
par_emb.disabled = true; // Disable embed
ico_emb.className = 'PREF_ON'; // Highlighted embed icon
ico_upl.className = 'PREF_OFF'; // Normal upload icon ico_upl.className = 'PREF_OFF'; // Normal upload icon
ico_you.className = 'PREF_ON'; // Highlighted youtube icon
ico_emb.className = 'PREF_OFF'; // Normal embed icon
fil.style.display = 'none'; // Hide file input fil.style.display = 'none'; // Hide file input
fil.disabled = true; // Disable file input fil.disabled = true; // Disable file input
@ -830,22 +844,66 @@ function mediaClickOnActivateEmbed (id) {
tit.disabled = true; // Disable title input tit.disabled = true; // Disable title input
} }
else // Click on shadowed icon else // Click on shadowed icon
mediaDisableUploadAndEmbed (id); mediaDisableAll (id);
} }
function mediaDisableUploadAndEmbed (id) { function mediaClickOnActivateEmbed (id) {
var par_upl = document.getElementById (id + '_par_upl');
var par_emb = document.getElementById (id + '_par_emb'); var par_emb = document.getElementById (id + '_par_emb');
if (par_emb.disabled) { // Click on highlighted icon
var par_upl = document.getElementById (id + '_par_upl');
var par_you = document.getElementById (id + '_par_you');
// par_emb already got
var ico_upl = document.getElementById (id + '_ico_upl');
var ico_you = document.getElementById (id + '_ico_you');
var ico_emb = document.getElementById (id + '_ico_emb');
var fil = document.getElementById (id + '_fil');
var url = document.getElementById (id + '_url');
var tit = document.getElementById (id + '_tit');
// Enable embed, disable others
par_upl.disabled = true; // Disable upload
par_you.disabled = true; // Disable youtube
par_emb.disabled = false; // Enable embed
ico_upl.className = 'PREF_OFF'; // Normal upload icon
ico_you.className = 'PREF_OFF'; // Normal youtube icon
ico_emb.className = 'PREF_ON'; // Highlighted embed icon
fil.style.display = 'none'; // Hide file input
fil.disabled = true; // Disable file input
url.style.display = ''; // Show URL input
url.disabled = false; // Enable URL input
tit.style.display = 'none'; // Hide title input
tit.disabled = true; // Disable title input
}
else // Click on shadowed icon
mediaDisableAll (id);
}
function mediaDisableAll (id) {
var par_upl = document.getElementById (id + '_par_upl');
var par_you = document.getElementById (id + '_par_you');
var par_emb = document.getElementById (id + '_par_emb');
var ico_upl = document.getElementById (id + '_ico_upl'); var ico_upl = document.getElementById (id + '_ico_upl');
var ico_you = document.getElementById (id + '_ico_you');
var ico_emb = document.getElementById (id + '_ico_emb'); var ico_emb = document.getElementById (id + '_ico_emb');
var fil = document.getElementById (id + '_fil'); var fil = document.getElementById (id + '_fil');
var url = document.getElementById (id + '_url'); var url = document.getElementById (id + '_url');
var tit = document.getElementById (id + '_tit'); var tit = document.getElementById (id + '_tit');
par_upl.disabled = true; // Disable upload par_upl.disabled = true; // Disable upload
par_you.disabled = true; // Disable youtube
par_emb.disabled = true; // Disable embed par_emb.disabled = true; // Disable embed
ico_upl.className = 'PREF_OFF'; // Normal upload icon ico_upl.className = 'PREF_OFF'; // Normal upload icon
ico_you.className = 'PREF_OFF'; // Normal youtube icon
ico_emb.className = 'PREF_OFF'; // Normal embed icon ico_emb.className = 'PREF_OFF'; // Normal embed icon
fil.style.display = 'none'; // Hide file input fil.style.display = 'none'; // Hide file input

View File

@ -797,7 +797,7 @@ CREATE TABLE IF NOT EXISTS marks_properties (
-- --
CREATE TABLE IF NOT EXISTS media ( CREATE TABLE IF NOT EXISTS media (
MedCod INT NOT NULL AUTO_INCREMENT, MedCod INT NOT NULL AUTO_INCREMENT,
Type ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none', Type ENUM('none','jpg','gif','mp4','webm','ogg','youtube','embed') NOT NULL DEFAULT 'none',
Name VARCHAR(43) NOT NULL DEFAULT '', Name VARCHAR(43) NOT NULL DEFAULT '',
URL VARCHAR(255) NOT NULL DEFAULT '', URL VARCHAR(255) NOT NULL DEFAULT '',
Title VARCHAR(2047) NOT NULL DEFAULT '', Title VARCHAR(2047) NOT NULL DEFAULT '',

View File

@ -459,10 +459,19 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf ps2pdf source.ps destination.pdf
*/ */
#define Log_PLATFORM_VERSION "SWAD 18.84.1 (2019-03-20)" #define Log_PLATFORM_VERSION "SWAD 18.85 (2019-03-21)"
#define CSS_FILE "swad18.83.css" #define CSS_FILE "swad18.85.css"
#define JS_FILE "swad18.80.js" #define JS_FILE "swad18.85.js"
/* /*
Version 18.85: Mar 21, 2019 New media: other embed media.
Width of timeline increased 30 pixels.
Fixed bug in creation of a test question, reported by Javier Fernández Baldomero. (240825 lines)
1 change necessary in database:
ALTER TABLE media CHANGE COLUMN Type Type ENUM('none','jpg','gif','mp4','webm','ogg','youtube','embed') NOT NULL DEFAULT 'none';
Copy the following icon to icon public directory:
sudo cp icon/code.svg /var/www/html/swad/icon/
Version 18.84.1: Mar 20, 2019 Added MIME type application/vnd.wolfram.mathematica.package, reported by José Martínez Aroza. Version 18.84.1: Mar 20, 2019 Added MIME type application/vnd.wolfram.mathematica.package, reported by José Martínez Aroza.
Conversion of BMP images to JPG, reported by José Martínez Aroza. (240587 lines) Conversion of BMP images to JPG, reported by José Martínez Aroza. (240587 lines)
Version 18.84: Mar 20, 2019 Temporary directories for download are created in a two level system to avoid overflow number of directories. (240582 lines) Version 18.84: Mar 20, 2019 Temporary directories for download are created in a two level system to avoid overflow number of directories. (240582 lines)

View File

@ -1712,20 +1712,20 @@ mysql> DESCRIBE marks_properties;
/***** Table media *****/ /***** Table media *****/
/* /*
mysql> DESCRIBE media; mysql> DESCRIBE media;
+--------+-------------------------------------------------------+------+-----+---------+----------------+ +--------+---------------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+--------+-------------------------------------------------------+------+-----+---------+----------------+ +--------+---------------------------------------------------------------+------+-----+---------+----------------+
| MedCod | int(11) | NO | PRI | NULL | auto_increment | | MedCod | int(11) | NO | PRI | NULL | auto_increment |
| Type | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | MUL | none | | | Type | enum('none','jpg','gif','mp4','webm','ogg','youtube','embed') | NO | MUL | none | |
| Name | varchar(43) | NO | | | | | Name | varchar(43) | NO | | | |
| URL | varchar(255) | NO | | | | | URL | varchar(255) | NO | | | |
| Title | varchar(2047) | NO | | | | | Title | varchar(2047) | NO | | | |
+--------+-------------------------------------------------------+------+-----+---------+----------------+ +--------+---------------------------------------------------------------+------+-----+---------+----------------+
5 rows in set (0.01 sec) 5 rows in set (0.01 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS media (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS media ("
"MedCod INT NOT NULL AUTO_INCREMENT," "MedCod INT NOT NULL AUTO_INCREMENT,"
"Type ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none'," "Type ENUM('none','jpg','gif','mp4','webm','ogg','youtube','embed') NOT NULL DEFAULT 'none',"
"Name VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME "Name VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"URL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW "URL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"Title VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE "Title VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE

View File

@ -62,6 +62,7 @@ const char *Med_StringsTypeDB[Med_NUM_TYPES] =
"webm", // Med_WEBM "webm", // Med_WEBM
"ogg", // Med_OGG "ogg", // Med_OGG
"youtube", // Med_YOUTUBE "youtube", // Med_YOUTUBE
"embed", // Med_EMBED
}; };
const char *Med_Extensions[Med_NUM_TYPES] = const char *Med_Extensions[Med_NUM_TYPES] =
@ -73,6 +74,7 @@ const char *Med_Extensions[Med_NUM_TYPES] =
"webm", // Med_WEBM "webm", // Med_WEBM
"ogg", // Med_OGG "ogg", // Med_OGG
"", // Med_YOUTUBE "", // Med_YOUTUBE
"", // Med_EMBED
}; };
#define Med_MAX_SIZE_GIF (5UL * 1024UL * 1024UL) // 5 MiB #define Med_MAX_SIZE_GIF (5UL * 1024UL * 1024UL) // 5 MiB
@ -82,13 +84,14 @@ const char *Med_Extensions[Med_NUM_TYPES] =
/****************************** Internal types *******************************/ /****************************** Internal types *******************************/
/*****************************************************************************/ /*****************************************************************************/
#define Med_NUM_FORM_TYPES 3 #define Med_NUM_FORM_TYPES 4
typedef enum typedef enum
{ {
Med_FORM_UNKNOWN = 0, Med_FORM_NONE = 0,
Med_FORM_FILE = 1, Med_FORM_FILE = 1,
Med_FORM_EMBED = 2, Med_FORM_YOUTUBE = 2,
Med_FORM_EMBED = 3,
} Med_FormType_t; } Med_FormType_t;
/*****************************************************************************/ /*****************************************************************************/
@ -131,6 +134,8 @@ static int Med_ResizeImage (struct Media *Media,
static int Med_GetFirstFrame (const char PathFileOriginal[PATH_MAX + 1], static int Med_GetFirstFrame (const char PathFileOriginal[PATH_MAX + 1],
const char PathFileProcessed[PATH_MAX + 1]); const char PathFileProcessed[PATH_MAX + 1]);
static void Med_GetAndProcessYouTubeFromForm (const char *ParamURL,
struct Media *Media);
static void Med_GetAndProcessEmbedFromForm (const char *ParamURL, static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
struct Media *Media); struct Media *Media);
@ -148,6 +153,7 @@ static void Med_ShowVideo (struct Media *Media,
const char PathMedPriv[PATH_MAX + 1], const char PathMedPriv[PATH_MAX + 1],
const char *ClassMedia); const char *ClassMedia);
static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia); static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia);
static void Med_ShowEmbed (struct Media *Media,const char *ClassMedia);
static Med_Type_t Med_GetTypeFromStrInDB (const char *Str); static Med_Type_t Med_GetTypeFromStrInDB (const char *Str);
static Med_Type_t Med_GetTypeFromExtAndMIME (const char *Extension, static Med_Type_t Med_GetTypeFromExtAndMIME (const char *Extension,
@ -335,11 +341,12 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput)
/***** Action to perform on media *****/ /***** Action to perform on media *****/
Par_PutHiddenParamUnsigned (ParamUploadMedia.Action,(unsigned) Med_ACTION_NEW_MEDIA); Par_PutHiddenParamUnsigned (ParamUploadMedia.Action,(unsigned) Med_ACTION_NEW_MEDIA);
/***** Start icons *****/ /***** Icons *****/
/* Start icons */
fprintf (Gbl.F.Out,"<div class=\"PREF_CONTAINERS\">" // icons containers fprintf (Gbl.F.Out,"<div class=\"PREF_CONTAINERS\">" // icons containers
"<div class=\"PREF_CONTAINER\">"); // icons container "<div class=\"PREF_CONTAINER\">"); // icons container
/***** Upload icon *****/ /* Upload icon */
fprintf (Gbl.F.Out,"<div id=\"%s_ico_upl\"" // <id>_ico_upl fprintf (Gbl.F.Out,"<div id=\"%s_ico_upl\"" // <id>_ico_upl
" class=\"PREF_OFF\">" " class=\"PREF_OFF\">"
"<img src=\"%s/file-image.svg\"" "<img src=\"%s/file-image.svg\""
@ -352,7 +359,38 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput)
Txt_Image_video,Txt_Image_video, Txt_Image_video,Txt_Image_video,
Id); Id);
/***** Form type *****/ /* YouTube icon */
fprintf (Gbl.F.Out,"<div id=\"%s_ico_you\"" // <id>_ico_you
" class=\"PREF_OFF\">"
"<img src=\"%s/youtube-brands.svg\""
" alt=\"%s\" title=\"%s\""
" class=\"ICO_HIGHLIGHT ICOx16\""
" onclick=\"mediaClickOnActivateYouTube('%s');\" />"
"</div>", // <id>_ico_you
Id,
Cfg_URL_ICON_PUBLIC,
"YouTube","YouTube",
Id);
/* Embed icon */
fprintf (Gbl.F.Out,"<div id=\"%s_ico_emb\"" // <id>_ico_emb
" class=\"PREF_OFF\">"
"<img src=\"%s/code.svg\""
" alt=\"%s\" title=\"%s\""
" class=\"ICO_HIGHLIGHT ICOx16\""
" onclick=\"mediaClickOnActivateEmbed('%s');\" />"
"</div>", // <id>_ico_emb
Id,
Cfg_URL_ICON_PUBLIC,
"Embed","Embed",
Id);
/* End icons */
fprintf (Gbl.F.Out,"</div>" // icons container
"</div>"); // icons containers
/***** Hidden field with form type *****/
/* Upload file */
fprintf (Gbl.F.Out,"<input type=\"hidden\"" fprintf (Gbl.F.Out,"<input type=\"hidden\""
" id=\"%s_par_upl\"" // <id>_par_upl " id=\"%s_par_upl\"" // <id>_par_upl
" name=\"%s\" value=\"%u\"" " name=\"%s\" value=\"%u\""
@ -360,28 +398,15 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput)
Id,ParamUploadMedia.FormType, Id,ParamUploadMedia.FormType,
(unsigned) Med_FORM_FILE); (unsigned) Med_FORM_FILE);
/***** Embed icon *****/ /* YouTube embedded video */
fprintf (Gbl.F.Out,"<div id=\"%s_ico_emb\"" // <id>_ico_emb fprintf (Gbl.F.Out,"<input type=\"hidden\""
" class=\"PREF_OFF\">" " id=\"%s_par_you\"" // <id>_par_you
"<img src=\"%s/youtube-brands.svg\"" " name=\"%s\" value=\"%u\""
" alt=\"%s\" title=\"%s\"" " disabled=\"disabled\" />",
" class=\"ICO_HIGHLIGHT ICOx16\"" Id,ParamUploadMedia.FormType,
" onclick=\"mediaClickOnActivateEmbed('%s');\" />" (unsigned) Med_FORM_YOUTUBE);
"</div>", // <id>_ico_emb
Id,
Cfg_URL_ICON_PUBLIC,
"YouTube","YouTube",
Id);
/***** End icons *****/ /* Other embedded media */
fprintf (Gbl.F.Out,"</div>" // icons container
"</div>"); // icons containers
/***** Start input fields *****/
fprintf (Gbl.F.Out,"<div class=\"%s\">", // input fields
ClassInput);
/***** Form type *****/
fprintf (Gbl.F.Out,"<input type=\"hidden\"" fprintf (Gbl.F.Out,"<input type=\"hidden\""
" id=\"%s_par_emb\"" // <id>_par_emb " id=\"%s_par_emb\"" // <id>_par_emb
" name=\"%s\" value=\"%u\"" " name=\"%s\" value=\"%u\""
@ -389,6 +414,10 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput)
Id,ParamUploadMedia.FormType, Id,ParamUploadMedia.FormType,
(unsigned) Med_FORM_EMBED); (unsigned) Med_FORM_EMBED);
/***** Start input fields *****/
fprintf (Gbl.F.Out,"<div class=\"%s\">", // input fields
ClassInput);
/***** Media file *****/ /***** Media file *****/
fprintf (Gbl.F.Out,"<input id=\"%s_fil\" type=\"file\"" // <id>_fil fprintf (Gbl.F.Out,"<input id=\"%s_fil\" type=\"file\"" // <id>_fil
" name=\"%s\" accept=\"image/,video/\"" " name=\"%s\" accept=\"image/,video/\""
@ -471,37 +500,35 @@ void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media,
Usr_GetURLFromForm (ParamUploadMedia.URL,Media); Usr_GetURLFromForm (ParamUploadMedia.URL,Media);
Usr_GetTitleFromForm (ParamUploadMedia.Title,Media); Usr_GetTitleFromForm (ParamUploadMedia.Title,Media);
} }
else break;
{ case Med_FORM_YOUTUBE:
/* Create alert with warning */ Media->Action = Med_ACTION_NEW_MEDIA;
Ale_CreateAlert (Ale_WARNING,SectionForAlerts,
Txt_Error_sending_or_processing_image_video);
/* Reset media (no media will be saved into database) */ /* Get and process embed YouTube video from form */
Med_ResetMedia (Media); Med_GetAndProcessYouTubeFromForm (ParamUploadMedia.URL,Media);
}
break; break;
case Med_FORM_EMBED: case Med_FORM_EMBED:
Media->Action = Med_ACTION_NEW_MEDIA; Media->Action = Med_ACTION_NEW_MEDIA;
/* Get and process embed URL from form */ /* Get and process other embed media from form */
Med_GetAndProcessEmbedFromForm (ParamUploadMedia.URL,Media); Med_GetAndProcessEmbedFromForm (ParamUploadMedia.URL,Media);
/* Check status of media after getting and processing it */
if (Media->Status != Med_PROCESSED)
{
/* Create alert with warning */
Ale_CreateAlert (Ale_WARNING,SectionForAlerts,
Txt_Error_sending_or_processing_image_video);
/* Reset media (no media will be saved into database) */
Med_ResetMedia (Media);
}
break; break;
default: // No media form selected default: // No media form selected
Media->Action = Med_ACTION_NO_MEDIA; Media->Action = Med_ACTION_NO_MEDIA;
break; break;
} }
/***** Check status of media *****/
if (FormType != Med_FORM_NONE && // A media form is selected
Media->Status != Med_PROCESSED) // No media successfully processed
{
/* Create alert with warning */
Ale_CreateAlert (Ale_WARNING,SectionForAlerts,
Txt_Error_sending_or_processing_image_video);
/* Reset media (no media will be saved into database) */
Med_ResetMedia (Media);
}
break; break;
case Med_ACTION_KEEP_MEDIA: // Keep current image/video unchanged case Med_ACTION_KEEP_MEDIA: // Keep current image/video unchanged
Media->Action = Med_ACTION_KEEP_MEDIA; Media->Action = Med_ACTION_KEEP_MEDIA;
@ -580,7 +607,7 @@ static Med_FormType_t Usr_GetFormTypeFromForm (struct ParamUploadMedia *ParamUpl
return (Med_FormType_t) Par_GetParToUnsignedLong (ParamUploadMedia->FormType, return (Med_FormType_t) Par_GetParToUnsignedLong (ParamUploadMedia->FormType,
0, 0,
Med_NUM_FORM_TYPES - 1, Med_NUM_FORM_TYPES - 1,
(unsigned long) Med_FORM_UNKNOWN); (unsigned long) Med_FORM_NONE);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -961,11 +988,11 @@ static int Med_GetFirstFrame (const char PathFileOriginal[PATH_MAX + 1],
} }
/*****************************************************************************/ /*****************************************************************************/
/**************************** Get media from form ****************************/ /************* Get link from form and transform to YouTube code **************/
/*****************************************************************************/ /*****************************************************************************/
static void Med_GetAndProcessEmbedFromForm (const char *ParamURL, static void Med_GetAndProcessYouTubeFromForm (const char *ParamURL,
struct Media *Media) struct Media *Media)
{ {
extern const char Str_BIN_TO_BASE64URL[64 + 1]; extern const char Str_BIN_TO_BASE64URL[64 + 1];
char *PtrHost = NULL; char *PtrHost = NULL;
@ -980,6 +1007,7 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
FULL, // www.youtube.com/watch? FULL, // www.youtube.com/watch?
EMBED, // www.youtube.com/embed/ EMBED, // www.youtube.com/embed/
} YouTube = WRONG; } YouTube = WRONG;
bool CodeFound = false;
/***** Set media status *****/ /***** Set media status *****/
Media->Status = Med_STATUS_NONE; Media->Status = Med_STATUS_NONE;
@ -1101,20 +1129,77 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
CodeLength = strspn (PtrCode,Str_BIN_TO_BASE64URL); CodeLength = strspn (PtrCode,Str_BIN_TO_BASE64URL);
if (CodeLength > 0 && if (CodeLength > 0 &&
CodeLength <= Med_BYTES_NAME) CodeLength <= Med_BYTES_NAME)
{ CodeFound = true; // Success!
/***** Success! *****/
/* Copy code */
strncpy (Media->Name,PtrCode,CodeLength);
Media->Name[CodeLength] = '\0';
Media->Type = Med_YOUTUBE;
Media->Status = Med_PROCESSED;
}
} }
} }
} }
} }
} }
/***** Set or reset media *****/
if (CodeFound)
{
/* Copy code */
strncpy (Media->Name,PtrCode,CodeLength);
Media->Name[CodeLength] = '\0';
/* Set media type and status */
Media->Type = Med_EMBED;
Media->Status = Med_PROCESSED;
}
else
/* Reset media */
Med_ResetMedia (Media);
}
/*****************************************************************************/
/************************ Get embed link from form ***************************/
/*****************************************************************************/
static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
struct Media *Media)
{
extern const char Str_BIN_TO_BASE64URL[64 + 1];
char *PtrHost = NULL;
bool URLFound = false;
/***** Set media status *****/
Media->Status = Med_STATUS_NONE;
/***** Get embed URL from form *****/
Usr_GetURLFromForm (ParamURL,Media);
/***** Process URL trying to convert it to a YouTube embed URL *****/
if (Media->URL)
if (Media->URL[0]) // URL given by user is not empty
{
/* Examples of valid embed URLs:
//www.slideshare.net/slideshow/embed_code/key/yngasD9sIZ7GQV
*/
/***** Step 1: Skip scheme *****/
if (!strncasecmp (Media->URL,"https://",8)) // URL starts by https://
PtrHost = &Media->URL[8];
else if (!strncasecmp (Media->URL,"http://" ,7)) // URL starts by http://
PtrHost = &Media->URL[7];
else if (!strncasecmp (Media->URL,"//" ,2)) // URL starts by //
PtrHost = &Media->URL[2];
/***** Check if a URL is found *****/
if (PtrHost)
if (PtrHost[0])
URLFound = true; // Success!
}
/***** Set or reset media *****/
if (URLFound)
{
/* Set media type and status */
Media->Type = Med_EMBED;
Media->Status = Med_PROCESSED;
}
else
/* Reset media */
Med_ResetMedia (Media);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1172,49 +1257,58 @@ void Med_MoveMediaToDefinitiveDir (struct Media *Media)
/***** Check trivial case *****/ /***** Check trivial case *****/
if (Media->Status == Med_PROCESSED) if (Media->Status == Med_PROCESSED)
{ {
if (Media->Type == Med_YOUTUBE) switch (Media->Type)
// Nothing to do with files ==> Processing successfully finished
Media->Status = Med_MOVED; // Success
else
{ {
/***** Create private subdirectory for media if it does not exist *****/ case Med_JPG:
snprintf (PathMedPriv,sizeof (PathMedPriv), case Med_GIF:
"%s/%c%c", case Med_MP4:
Cfg_PATH_MEDIA_PRIVATE, case Med_WEBM:
Media->Name[0], case Med_OGG:
Media->Name[1]); /***** Create private subdirectory for media if it does not exist *****/
Fil_CreateDirIfNotExists (PathMedPriv); snprintf (PathMedPriv,sizeof (PathMedPriv),
"%s/%c%c",
Cfg_PATH_MEDIA_PRIVATE,
Media->Name[0],
Media->Name[1]);
Fil_CreateDirIfNotExists (PathMedPriv);
/***** Move files *****/ /***** Move files *****/
switch (Media->Type) switch (Media->Type)
{ {
case Med_JPG: case Med_JPG:
/* Move JPG */ /* Move JPG */
if (Med_MoveTmpFileToDefDir (Media,PathMedPriv,
Med_Extensions[Med_JPG]))
Media->Status = Med_MOVED; // Success
break;
case Med_GIF:
/* Move PNG */
if (Med_MoveTmpFileToDefDir (Media,PathMedPriv,
"png"))
/* Move GIF */
if (Med_MoveTmpFileToDefDir (Media,PathMedPriv, if (Med_MoveTmpFileToDefDir (Media,PathMedPriv,
Med_Extensions[Med_GIF])) Med_Extensions[Med_JPG]))
Media->Status = Med_MOVED; // Success Media->Status = Med_MOVED; // Success
break; break;
case Med_MP4: case Med_GIF:
case Med_WEBM: /* Move PNG */
case Med_OGG: if (Med_MoveTmpFileToDefDir (Media,PathMedPriv,
/* Move MP4 or WEBM or OGG */ "png"))
if (Med_MoveTmpFileToDefDir (Media,PathMedPriv, /* Move GIF */
Med_Extensions[Media->Type])) if (Med_MoveTmpFileToDefDir (Media,PathMedPriv,
Media->Status = Med_MOVED; // Success Med_Extensions[Med_GIF]))
break; Media->Status = Med_MOVED; // Success
default: break;
Lay_ShowErrorAndExit ("Wrong media type."); case Med_MP4:
break; // Not reached case Med_WEBM:
} case Med_OGG:
/* Move MP4 or WEBM or OGG */
if (Med_MoveTmpFileToDefDir (Media,PathMedPriv,
Med_Extensions[Media->Type]))
Media->Status = Med_MOVED; // Success
break;
default:
break;
}
break;
case Med_YOUTUBE:
case Med_EMBED:
// Nothing to do with files ==> Processing successfully finished
Media->Status = Med_MOVED; // Success
break;
default:
break;
} }
} }
@ -1276,7 +1370,7 @@ void Med_StoreMediaInDB (struct Media *Media)
" VALUES" " VALUES"
" ('%s','%s','%s','%s')", " ('%s','%s','%s','%s')",
Med_GetStringTypeForDB (Media->Type), Med_GetStringTypeForDB (Media->Type),
Media->Name, Media->Name ? Media->Name : "",
Media->URL ? Media->URL : "", Media->URL ? Media->URL : "",
Media->Title ? Media->Title : ""); Media->Title ? Media->Title : "");
Media->Status = Med_STORED_IN_DB; Media->Status = Med_STORED_IN_DB;
@ -1301,56 +1395,70 @@ void Med_ShowMedia (struct Media *Media,
/***** Start media container *****/ /***** Start media container *****/
fprintf (Gbl.F.Out,"<div class=\"%s\">",ClassContainer); fprintf (Gbl.F.Out,"<div class=\"%s\">",ClassContainer);
if (Media->Type == Med_YOUTUBE) switch (Media->Type)
/***** Show media *****/
Med_ShowYoutube (Media,ClassMedia);
else // Uploaded file
{ {
/***** If no media to show ==> nothing to do *****/ case Med_JPG:
if (!Media->Name) case Med_GIF:
return; case Med_MP4:
if (!Media->Name[0]) case Med_WEBM:
return; case Med_OGG:
/***** Show uploaded file *****/
/* If no media to show ==> nothing to do */
if (!Media->Name)
return;
if (!Media->Name[0])
return;
/***** Start optional link to external URL *****/ /* Start optional link to external URL */
PutLink = false; PutLink = false;
if (Media->URL) if (Media->URL)
if (Media->URL[0]) if (Media->URL[0])
PutLink = true; PutLink = true;
if (PutLink) if (PutLink)
fprintf (Gbl.F.Out,"<a href=\"%s\" target=\"_blank\">",Media->URL); fprintf (Gbl.F.Out,"<a href=\"%s\" target=\"_blank\">",Media->URL);
/***** Create a temporary public directory used to show the media *****/ /* Create a temporary public directory used to show the media */
Brw_CreateDirDownloadTmp (); Brw_CreateDirDownloadTmp ();
/***** Build path to private directory with the media *****/ /* Build path to private directory with the media */
snprintf (PathMedPriv,sizeof (PathMedPriv), snprintf (PathMedPriv,sizeof (PathMedPriv),
"%s/%c%c", "%s/%c%c",
Cfg_PATH_MEDIA_PRIVATE, Cfg_PATH_MEDIA_PRIVATE,
Media->Name[0], Media->Name[0],
Media->Name[1]); Media->Name[1]);
/***** Show media *****/ /* Show media */
switch (Media->Type) switch (Media->Type)
{ {
case Med_JPG: case Med_JPG:
Med_ShowJPG (Media,PathMedPriv,ClassMedia); Med_ShowJPG (Media,PathMedPriv,ClassMedia);
break; break;
case Med_GIF: case Med_GIF:
Med_ShowGIF (Media,PathMedPriv,ClassMedia); Med_ShowGIF (Media,PathMedPriv,ClassMedia);
break; break;
case Med_MP4: case Med_MP4:
case Med_WEBM: case Med_WEBM:
case Med_OGG: case Med_OGG:
Med_ShowVideo (Media,PathMedPriv,ClassMedia); Med_ShowVideo (Media,PathMedPriv,ClassMedia);
break; break;
default: default:
break; break;
} }
/***** End optional link to external URL *****/ /* End optional link to external URL */
if (PutLink) if (PutLink)
fprintf (Gbl.F.Out,"</a>"); fprintf (Gbl.F.Out,"</a>");
break;
case Med_YOUTUBE:
/***** Show embed YouTube video *****/
Med_ShowYoutube (Media,ClassMedia);
break;
case Med_EMBED:
/***** Show other embed media *****/
Med_ShowEmbed (Media,ClassMedia);
break;
default:
break;
} }
/***** End media container *****/ /***** End media container *****/
@ -1548,7 +1656,7 @@ static void Med_ShowVideo (struct Media *Media,
} }
/*****************************************************************************/ /*****************************************************************************/
/*************************** Show an embed media *****************************/ /*********************** Show an embed YouTube video *************************/
/*****************************************************************************/ /*****************************************************************************/
static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia) static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia)
@ -1562,7 +1670,7 @@ static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia)
if (Gbl.Usrs.Me.UsrDat.Prefs.AcceptThirdPartyCookies) if (Gbl.Usrs.Me.UsrDat.Prefs.AcceptThirdPartyCookies)
{ {
/***** Show linked external media *****/ /***** Show linked external media *****/
// Example of code give by YouTube: // Example of code given by YouTube:
// <iframe width="560" height="315" // <iframe width="560" height="315"
// src="https://www.youtube.com/embed/xu9IbeF9CBw" // src="https://www.youtube.com/embed/xu9IbeF9CBw"
// frameborder="0" // frameborder="0"
@ -1602,6 +1710,60 @@ static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia)
} }
} }
/*****************************************************************************/
/*************************** Show an embed media *****************************/
/*****************************************************************************/
static void Med_ShowEmbed (struct Media *Media,const char *ClassMedia)
{
extern const char *Txt_To_watch_YouTube_videos_you_have_to_accept_third_party_cookies_in_your_personal_settings;
extern const char *Txt_Settings;
/***** Check if embed URL exists *****/
if (Media->URL[0]) // Embed URL
{
if (Gbl.Usrs.Me.UsrDat.Prefs.AcceptThirdPartyCookies)
{
/***** Show linked external media *****/
// Example of code given by Slideshare:
// <iframe src="//www.slideshare.net/slideshow/embed_code/key/yngasD9sIZ7GQV"
// width="595" height="485" frameborder="0"
// marginwidth="0" marginheight="0" scrolling="no"
// style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;"
// allowfullscreen>
// </iframe>
fprintf (Gbl.F.Out,"<div class=\"MED_EMBED_CONT\">"
"<iframe src=\"%s\""
" frameborder=\"0\""
" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\""
" allowfullscreen=\"allowfullscreen\""
" class=\"%s\"",
Media->URL,ClassMedia);
if (Media->Title)
if (Media->Title[0])
fprintf (Gbl.F.Out," title=\"%s\"",Media->Title);
fprintf (Gbl.F.Out,">"
"</iframe>"
"</div>");
}
else
{
/***** Alert to inform about third party cookies *****/
/* Start alert */
Ale_ShowAlertAndButton1 (Ale_INFO,Txt_To_watch_YouTube_videos_you_have_to_accept_third_party_cookies_in_your_personal_settings);
/* Put form to change cookies preferences */
if (!Gbl.Form.Inside)
Lay_PutContextualLinkIconText (ActReqEdiPrf,Coo_COOKIES_ID,NULL,
"cog.svg",
Txt_Settings);
/* End alert */
Ale_ShowAlertAndButton2 (ActUnk,NULL,NULL,NULL,Btn_NO_BUTTON,NULL);
}
}
}
/*****************************************************************************/ /*****************************************************************************/
/********** Remove several media files and entries in database ***************/ /********** Remove several media files and entries in database ***************/
/*****************************************************************************/ /*****************************************************************************/
@ -1648,56 +1810,65 @@ void Med_RemoveMedia (long MedCod)
Med_GetMediaDataByCod (&Media); Med_GetMediaDataByCod (&Media);
/***** Step 1. Remove media files from filesystem *****/ /***** Step 1. Remove media files from filesystem *****/
if (Media.Type != Med_TYPE_NONE && switch (Media.Type)
Media.Type != Med_YOUTUBE &&
Media.Name[0])
{ {
/***** Build path to private directory with the media *****/ case Med_JPG:
snprintf (PathMedPriv,sizeof (PathMedPriv), case Med_GIF:
"%s/%c%c", case Med_MP4:
Cfg_PATH_MEDIA_PRIVATE, case Med_WEBM:
Media.Name[0], case Med_OGG:
Media.Name[1]); if (Media.Name[0])
{
/***** Build path to private directory with the media *****/
snprintf (PathMedPriv,sizeof (PathMedPriv),
"%s/%c%c",
Cfg_PATH_MEDIA_PRIVATE,
Media.Name[0],
Media.Name[1]);
/***** Remove files *****/ /***** Remove files *****/
switch (Media.Type) switch (Media.Type)
{ {
case Med_JPG: case Med_JPG:
/***** Remove private JPG file *****/ /***** Remove private JPG file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv), snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.%s", "%s/%s.%s",
PathMedPriv,Media.Name,Med_Extensions[Med_JPG]); PathMedPriv,Media.Name,Med_Extensions[Med_JPG]);
unlink (FullPathMediaPriv); unlink (FullPathMediaPriv);
break; break;
case Med_GIF: case Med_GIF:
/***** Remove private GIF file *****/ /***** Remove private GIF file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv), snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.%s", "%s/%s.%s",
PathMedPriv,Media.Name,Med_Extensions[Med_GIF]); PathMedPriv,Media.Name,Med_Extensions[Med_GIF]);
unlink (FullPathMediaPriv); unlink (FullPathMediaPriv);
/***** Remove private PNG file *****/ /***** Remove private PNG file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv), snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.png", "%s/%s.png",
PathMedPriv,Media.Name); PathMedPriv,Media.Name);
unlink (FullPathMediaPriv); unlink (FullPathMediaPriv);
break; break;
case Med_MP4: case Med_MP4:
case Med_WEBM: case Med_WEBM:
case Med_OGG: case Med_OGG:
/***** Remove private video file *****/ /***** Remove private video file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv), snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.%s", "%s/%s.%s",
PathMedPriv,Media.Name,Med_Extensions[Media.Type]); PathMedPriv,Media.Name,Med_Extensions[Media.Type]);
unlink (FullPathMediaPriv); unlink (FullPathMediaPriv);
break; break;
default: default:
break; break;
} }
// Public links are removed automatically after a period // Public links are removed automatically after a period
}
break;
default:
break;
} }
/***** Step 2. Remove entry for this media from database *****/ /***** Step 2. Remove entry for this media from database *****/

View File

@ -86,7 +86,7 @@ typedef enum
Med_STORED_IN_DB, Med_STORED_IN_DB,
} Med_Status_t; } Med_Status_t;
#define Med_NUM_TYPES 7 #define Med_NUM_TYPES 8
typedef enum typedef enum
{ {
Med_TYPE_NONE, Med_TYPE_NONE,
@ -96,6 +96,7 @@ typedef enum
Med_WEBM, Med_WEBM,
Med_OGG, Med_OGG,
Med_YOUTUBE, Med_YOUTUBE,
Med_EMBED,
} Med_Type_t; } Med_Type_t;
/***** Struct used to get images/videos from forms *****/ /***** Struct used to get images/videos from forms *****/

View File

@ -5643,28 +5643,36 @@ static long Tst_GetMedCodFromDB (int NumOpt)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
long MedCod; unsigned long NumRows;
long MedCod = -1L;
/***** Query depending on NumOpt *****/ /***** Query depending on NumOpt *****/
if (NumOpt < 0) if (NumOpt < 0)
// Get media associated to stem // Get media associated to stem
DB_QuerySELECT (&mysql_res,"can not get media", NumRows = DB_QuerySELECT (&mysql_res,"can not get media",
"SELECT MedCod" // row[0] "SELECT MedCod" // row[0]
" FROM tst_questions" " FROM tst_questions"
" WHERE QstCod=%ld AND CrsCod=%ld", " WHERE QstCod=%ld AND CrsCod=%ld",
Gbl.Test.QstCod,Gbl.CurrentCrs.Crs.CrsCod); Gbl.Test.QstCod,Gbl.CurrentCrs.Crs.CrsCod);
else else
// Get media associated to answer // Get media associated to answer
DB_QuerySELECT (&mysql_res,"can not get media", NumRows = DB_QuerySELECT (&mysql_res,"can not get media",
"SELECT MedCod" // row[0] "SELECT MedCod" // row[0]
" FROM tst_answers" " FROM tst_answers"
" WHERE QstCod=%ld AND AnsInd=%u", " WHERE QstCod=%ld AND AnsInd=%u",
Gbl.Test.QstCod,(unsigned) NumOpt); Gbl.Test.QstCod,(unsigned) NumOpt);
row = mysql_fetch_row (mysql_res); if (NumRows)
{
/***** Get media code (row[0]) *****/ if (NumRows == 1)
MedCod = Str_ConvertStrCodToLongCod (row[0]); {
/***** Get media code (row[0]) *****/
row = mysql_fetch_row (mysql_res);
MedCod = Str_ConvertStrCodToLongCod (row[0]);
}
else // NumRows > 1
Lay_ShowErrorAndExit ("Duplicated media in database.");
}
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res); DB_FreeMySQLResult (&mysql_res);

View File

@ -49330,11 +49330,11 @@ const char *Txt_TIMELINE_Post_removed =
#elif L==3 // en #elif L==3 // en
"Post removed."; "Post removed.";
#elif L==4 // es #elif L==4 // es
"Publicaci&oacute;n eliminada"; "Publicaci&oacute;n eliminada.";
#elif L==5 // fr #elif L==5 // fr
"Publication supprim&eacute;e."; "Publication supprim&eacute;e.";
#elif L==6 // gn #elif L==6 // gn
"Publicaci&oacute;n eliminada"; // Okoteve traducción "Publicaci&oacute;n eliminada."; // Okoteve traducción
#elif L==7 // it #elif L==7 // it
"Pubblicazione rimossa."; "Pubblicazione rimossa.";
#elif L==8 // pl #elif L==8 // pl