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%;
}
/* 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_1_LINE
{
@ -2898,12 +2921,12 @@ a:hover img.CENTRE_PHOTO_SHOW
}
@media only screen and (min-width: 800px)
{ /* For tablets and desktop */
.TL_WIDTH {width:536px;}
.TL_RIGHT_WIDTH {width:480px;}
.TL_RIGHT_AUTHOR_WIDTH {width:320px;}
.TL_POST_MED_WIDTH {width:440px;}
.TL_COMMENT_WIDTH {width:440px;}
.TL_COMMENT_AUTHOR_WIDTH {width:280px;}
.TL_WIDTH {width:566px;} /* 536 -> 566 */
.TL_RIGHT_WIDTH {width:510px;} /* 480 -> 510 */
.TL_RIGHT_AUTHOR_WIDTH {width:350px;} /* 320 -> 350 */
.TL_POST_MED_WIDTH {width:470px;} /* 440 -> 470 */
.TL_COMMENT_WIDTH {width:470px;} /* 440 -> 470 */
.TL_COMMENT_AUTHOR_WIDTH {width:310px;} /* 280 -> 310 */
}
.TL_NEW_PUB

View File

@ -772,24 +772,31 @@ function AJAXCreateObject () {
/*****************************************************************************/
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
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_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');
// Disable embed and enable upload
par_emb.disabled = true; // Disable embed
// Enable embed, disable others
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_you.className = 'PREF_OFF'; // Normal youtube 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
url.style.display = ''; // Show URL input
@ -799,26 +806,33 @@ function mediaClickOnActivateUpload (id) {
tit.disabled = false; // Enable title input
}
else // Click on shadowed icon
mediaDisableUploadAndEmbed (id);
mediaDisableAll (id);
}
function mediaClickOnActivateEmbed (id) {
var par_emb = document.getElementById (id + '_par_emb');
function mediaClickOnActivateYoutube (id) {
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');
// par_you already got
var par_emb = document.getElementById (id + '_par_emb');
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');
// Disable upload and enable embed
// Enable youtube, disable others
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_you.className = 'PREF_ON'; // Highlighted youtube icon
ico_emb.className = 'PREF_OFF'; // Normal embed icon
fil.style.display = 'none'; // Hide file input
fil.disabled = true; // Disable file input
@ -830,22 +844,66 @@ function mediaClickOnActivateEmbed (id) {
tit.disabled = true; // Disable title input
}
else // Click on shadowed icon
mediaDisableUploadAndEmbed (id);
mediaDisableAll (id);
}
function mediaDisableUploadAndEmbed (id) {
var par_upl = document.getElementById (id + '_par_upl');
function mediaClickOnActivateEmbed (id) {
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_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');
par_upl.disabled = true; // Disable upload
par_you.disabled = true; // Disable youtube
par_emb.disabled = true; // Disable embed
ico_upl.className = 'PREF_OFF'; // Normal upload icon
ico_you.className = 'PREF_OFF'; // Normal youtube icon
ico_emb.className = 'PREF_OFF'; // Normal embed icon
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 (
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 '',
URL VARCHAR(255) NOT NULL DEFAULT '',
Title VARCHAR(2047) NOT NULL DEFAULT '',

View File

@ -459,10 +459,19 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
#define Log_PLATFORM_VERSION "SWAD 18.84.1 (2019-03-20)"
#define CSS_FILE "swad18.83.css"
#define JS_FILE "swad18.80.js"
#define Log_PLATFORM_VERSION "SWAD 18.85 (2019-03-21)"
#define CSS_FILE "swad18.85.css"
#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.
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)

View File

@ -1712,20 +1712,20 @@ mysql> DESCRIBE marks_properties;
/***** Table media *****/
/*
mysql> DESCRIBE media;
+--------+-------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------------------------------------------------+------+-----+---------+----------------+
| MedCod | int(11) | NO | PRI | NULL | auto_increment |
| Type | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | MUL | none | |
| Name | varchar(43) | NO | | | |
| URL | varchar(255) | NO | | | |
| Title | varchar(2047) | NO | | | |
+--------+-------------------------------------------------------+------+-----+---------+----------------+
+--------+---------------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------------------------------------------------------+------+-----+---------+----------------+
| MedCod | int(11) | NO | PRI | NULL | auto_increment |
| Type | enum('none','jpg','gif','mp4','webm','ogg','youtube','embed') | NO | MUL | none | |
| Name | varchar(43) | NO | | | |
| URL | varchar(255) | NO | | | |
| Title | varchar(2047) | NO | | | |
+--------+---------------------------------------------------------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS media ("
"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
"URL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"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
"ogg", // Med_OGG
"youtube", // Med_YOUTUBE
"embed", // Med_EMBED
};
const char *Med_Extensions[Med_NUM_TYPES] =
@ -73,6 +74,7 @@ const char *Med_Extensions[Med_NUM_TYPES] =
"webm", // Med_WEBM
"ogg", // Med_OGG
"", // Med_YOUTUBE
"", // Med_EMBED
};
#define Med_MAX_SIZE_GIF (5UL * 1024UL * 1024UL) // 5 MiB
@ -82,13 +84,14 @@ const char *Med_Extensions[Med_NUM_TYPES] =
/****************************** Internal types *******************************/
/*****************************************************************************/
#define Med_NUM_FORM_TYPES 3
#define Med_NUM_FORM_TYPES 4
typedef enum
{
Med_FORM_UNKNOWN = 0,
Med_FORM_NONE = 0,
Med_FORM_FILE = 1,
Med_FORM_EMBED = 2,
Med_FORM_YOUTUBE = 2,
Med_FORM_EMBED = 3,
} Med_FormType_t;
/*****************************************************************************/
@ -131,6 +134,8 @@ static int Med_ResizeImage (struct Media *Media,
static int Med_GetFirstFrame (const char PathFileOriginal[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,
struct Media *Media);
@ -148,6 +153,7 @@ static void Med_ShowVideo (struct Media *Media,
const char PathMedPriv[PATH_MAX + 1],
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_GetTypeFromExtAndMIME (const char *Extension,
@ -335,11 +341,12 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput)
/***** Action to perform on 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
"<div class=\"PREF_CONTAINER\">"); // icons container
/***** Upload icon *****/
/* Upload icon */
fprintf (Gbl.F.Out,"<div id=\"%s_ico_upl\"" // <id>_ico_upl
" class=\"PREF_OFF\">"
"<img src=\"%s/file-image.svg\""
@ -352,7 +359,38 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput)
Txt_Image_video,Txt_Image_video,
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\""
" id=\"%s_par_upl\"" // <id>_par_upl
" name=\"%s\" value=\"%u\""
@ -360,28 +398,15 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput)
Id,ParamUploadMedia.FormType,
(unsigned) Med_FORM_FILE);
/***** Embed icon *****/
fprintf (Gbl.F.Out,"<div id=\"%s_ico_emb\"" // <id>_ico_emb
" class=\"PREF_OFF\">"
"<img src=\"%s/youtube-brands.svg\""
" alt=\"%s\" title=\"%s\""
" class=\"ICO_HIGHLIGHT ICOx16\""
" onclick=\"mediaClickOnActivateEmbed('%s');\" />"
"</div>", // <id>_ico_emb
Id,
Cfg_URL_ICON_PUBLIC,
"YouTube","YouTube",
Id);
/* YouTube embedded video */
fprintf (Gbl.F.Out,"<input type=\"hidden\""
" id=\"%s_par_you\"" // <id>_par_you
" name=\"%s\" value=\"%u\""
" disabled=\"disabled\" />",
Id,ParamUploadMedia.FormType,
(unsigned) Med_FORM_YOUTUBE);
/***** End icons *****/
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 *****/
/* Other embedded media */
fprintf (Gbl.F.Out,"<input type=\"hidden\""
" id=\"%s_par_emb\"" // <id>_par_emb
" name=\"%s\" value=\"%u\""
@ -389,6 +414,10 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput)
Id,ParamUploadMedia.FormType,
(unsigned) Med_FORM_EMBED);
/***** Start input fields *****/
fprintf (Gbl.F.Out,"<div class=\"%s\">", // input fields
ClassInput);
/***** Media file *****/
fprintf (Gbl.F.Out,"<input id=\"%s_fil\" type=\"file\"" // <id>_fil
" name=\"%s\" accept=\"image/,video/\""
@ -471,37 +500,35 @@ void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media,
Usr_GetURLFromForm (ParamUploadMedia.URL,Media);
Usr_GetTitleFromForm (ParamUploadMedia.Title,Media);
}
else
{
/* Create alert with warning */
Ale_CreateAlert (Ale_WARNING,SectionForAlerts,
Txt_Error_sending_or_processing_image_video);
break;
case Med_FORM_YOUTUBE:
Media->Action = Med_ACTION_NEW_MEDIA;
/* Reset media (no media will be saved into database) */
Med_ResetMedia (Media);
}
/* Get and process embed YouTube video from form */
Med_GetAndProcessYouTubeFromForm (ParamUploadMedia.URL,Media);
break;
case Med_FORM_EMBED:
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);
/* 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;
default: // No media form selected
Media->Action = Med_ACTION_NO_MEDIA;
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;
case Med_ACTION_KEEP_MEDIA: // Keep current image/video unchanged
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,
0,
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,
struct Media *Media)
static void Med_GetAndProcessYouTubeFromForm (const char *ParamURL,
struct Media *Media)
{
extern const char Str_BIN_TO_BASE64URL[64 + 1];
char *PtrHost = NULL;
@ -980,6 +1007,7 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
FULL, // www.youtube.com/watch?
EMBED, // www.youtube.com/embed/
} YouTube = WRONG;
bool CodeFound = false;
/***** Set media status *****/
Media->Status = Med_STATUS_NONE;
@ -1101,20 +1129,77 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
CodeLength = strspn (PtrCode,Str_BIN_TO_BASE64URL);
if (CodeLength > 0 &&
CodeLength <= Med_BYTES_NAME)
{
/***** Success! *****/
/* Copy code */
strncpy (Media->Name,PtrCode,CodeLength);
Media->Name[CodeLength] = '\0';
Media->Type = Med_YOUTUBE;
Media->Status = Med_PROCESSED;
}
CodeFound = true; // Success!
}
}
}
}
}
/***** 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 *****/
if (Media->Status == Med_PROCESSED)
{
if (Media->Type == Med_YOUTUBE)
// Nothing to do with files ==> Processing successfully finished
Media->Status = Med_MOVED; // Success
else
switch (Media->Type)
{
/***** Create private subdirectory for media if it does not exist *****/
snprintf (PathMedPriv,sizeof (PathMedPriv),
"%s/%c%c",
Cfg_PATH_MEDIA_PRIVATE,
Media->Name[0],
Media->Name[1]);
Fil_CreateDirIfNotExists (PathMedPriv);
case Med_JPG:
case Med_GIF:
case Med_MP4:
case Med_WEBM:
case Med_OGG:
/***** Create private subdirectory for media if it does not exist *****/
snprintf (PathMedPriv,sizeof (PathMedPriv),
"%s/%c%c",
Cfg_PATH_MEDIA_PRIVATE,
Media->Name[0],
Media->Name[1]);
Fil_CreateDirIfNotExists (PathMedPriv);
/***** Move files *****/
switch (Media->Type)
{
case Med_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 */
/***** Move files *****/
switch (Media->Type)
{
case Med_JPG:
/* Move JPG */
if (Med_MoveTmpFileToDefDir (Media,PathMedPriv,
Med_Extensions[Med_GIF]))
Med_Extensions[Med_JPG]))
Media->Status = Med_MOVED; // Success
break;
case Med_MP4:
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:
Lay_ShowErrorAndExit ("Wrong media type.");
break; // Not reached
}
break;
case Med_GIF:
/* Move PNG */
if (Med_MoveTmpFileToDefDir (Media,PathMedPriv,
"png"))
/* Move GIF */
if (Med_MoveTmpFileToDefDir (Media,PathMedPriv,
Med_Extensions[Med_GIF]))
Media->Status = Med_MOVED; // Success
break;
case Med_MP4:
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"
" ('%s','%s','%s','%s')",
Med_GetStringTypeForDB (Media->Type),
Media->Name,
Media->Name ? Media->Name : "",
Media->URL ? Media->URL : "",
Media->Title ? Media->Title : "");
Media->Status = Med_STORED_IN_DB;
@ -1301,56 +1395,70 @@ void Med_ShowMedia (struct Media *Media,
/***** Start media container *****/
fprintf (Gbl.F.Out,"<div class=\"%s\">",ClassContainer);
if (Media->Type == Med_YOUTUBE)
/***** Show media *****/
Med_ShowYoutube (Media,ClassMedia);
else // Uploaded file
switch (Media->Type)
{
/***** If no media to show ==> nothing to do *****/
if (!Media->Name)
return;
if (!Media->Name[0])
return;
case Med_JPG:
case Med_GIF:
case Med_MP4:
case Med_WEBM:
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 *****/
PutLink = false;
if (Media->URL)
if (Media->URL[0])
PutLink = true;
if (PutLink)
fprintf (Gbl.F.Out,"<a href=\"%s\" target=\"_blank\">",Media->URL);
/* Start optional link to external URL */
PutLink = false;
if (Media->URL)
if (Media->URL[0])
PutLink = true;
if (PutLink)
fprintf (Gbl.F.Out,"<a href=\"%s\" target=\"_blank\">",Media->URL);
/***** Create a temporary public directory used to show the media *****/
Brw_CreateDirDownloadTmp ();
/* 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",
Cfg_PATH_MEDIA_PRIVATE,
Media->Name[0],
Media->Name[1]);
/* 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]);
/***** Show media *****/
switch (Media->Type)
{
case Med_JPG:
Med_ShowJPG (Media,PathMedPriv,ClassMedia);
break;
case Med_GIF:
Med_ShowGIF (Media,PathMedPriv,ClassMedia);
break;
case Med_MP4:
case Med_WEBM:
case Med_OGG:
Med_ShowVideo (Media,PathMedPriv,ClassMedia);
break;
default:
break;
}
/* Show media */
switch (Media->Type)
{
case Med_JPG:
Med_ShowJPG (Media,PathMedPriv,ClassMedia);
break;
case Med_GIF:
Med_ShowGIF (Media,PathMedPriv,ClassMedia);
break;
case Med_MP4:
case Med_WEBM:
case Med_OGG:
Med_ShowVideo (Media,PathMedPriv,ClassMedia);
break;
default:
break;
}
/***** End optional link to external URL *****/
if (PutLink)
fprintf (Gbl.F.Out,"</a>");
/* End optional link to external URL */
if (PutLink)
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 *****/
@ -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)
@ -1562,7 +1670,7 @@ static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia)
if (Gbl.Usrs.Me.UsrDat.Prefs.AcceptThirdPartyCookies)
{
/***** Show linked external media *****/
// Example of code give by YouTube:
// Example of code given by YouTube:
// <iframe width="560" height="315"
// src="https://www.youtube.com/embed/xu9IbeF9CBw"
// 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 ***************/
/*****************************************************************************/
@ -1648,56 +1810,65 @@ void Med_RemoveMedia (long MedCod)
Med_GetMediaDataByCod (&Media);
/***** Step 1. Remove media files from filesystem *****/
if (Media.Type != Med_TYPE_NONE &&
Media.Type != Med_YOUTUBE &&
Media.Name[0])
switch (Media.Type)
{
/***** 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]);
case Med_JPG:
case Med_GIF:
case Med_MP4:
case Med_WEBM:
case Med_OGG:
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 *****/
switch (Media.Type)
{
case Med_JPG:
/***** Remove private JPG file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.%s",
PathMedPriv,Media.Name,Med_Extensions[Med_JPG]);
unlink (FullPathMediaPriv);
/***** Remove files *****/
switch (Media.Type)
{
case Med_JPG:
/***** Remove private JPG file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.%s",
PathMedPriv,Media.Name,Med_Extensions[Med_JPG]);
unlink (FullPathMediaPriv);
break;
case Med_GIF:
/***** Remove private GIF file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.%s",
PathMedPriv,Media.Name,Med_Extensions[Med_GIF]);
unlink (FullPathMediaPriv);
break;
case Med_GIF:
/***** Remove private GIF file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.%s",
PathMedPriv,Media.Name,Med_Extensions[Med_GIF]);
unlink (FullPathMediaPriv);
/***** Remove private PNG file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.png",
PathMedPriv,Media.Name);
unlink (FullPathMediaPriv);
/***** Remove private PNG file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.png",
PathMedPriv,Media.Name);
unlink (FullPathMediaPriv);
break;
case Med_MP4:
case Med_WEBM:
case Med_OGG:
/***** Remove private video file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.%s",
PathMedPriv,Media.Name,Med_Extensions[Media.Type]);
unlink (FullPathMediaPriv);
break;
case Med_MP4:
case Med_WEBM:
case Med_OGG:
/***** Remove private video file *****/
snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
"%s/%s.%s",
PathMedPriv,Media.Name,Med_Extensions[Media.Type]);
unlink (FullPathMediaPriv);
break;
default:
break;
}
// Public links are removed automatically after a period
break;
default:
break;
}
// Public links are removed automatically after a period
}
break;
default:
break;
}
/***** Step 2. Remove entry for this media from database *****/

View File

@ -86,7 +86,7 @@ typedef enum
Med_STORED_IN_DB,
} Med_Status_t;
#define Med_NUM_TYPES 7
#define Med_NUM_TYPES 8
typedef enum
{
Med_TYPE_NONE,
@ -96,6 +96,7 @@ typedef enum
Med_WEBM,
Med_OGG,
Med_YOUTUBE,
Med_EMBED,
} Med_Type_t;
/***** 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_ROW row;
long MedCod;
unsigned long NumRows;
long MedCod = -1L;
/***** Query depending on NumOpt *****/
if (NumOpt < 0)
// Get media associated to stem
DB_QuerySELECT (&mysql_res,"can not get media",
"SELECT MedCod" // row[0]
" FROM tst_questions"
" WHERE QstCod=%ld AND CrsCod=%ld",
Gbl.Test.QstCod,Gbl.CurrentCrs.Crs.CrsCod);
NumRows = DB_QuerySELECT (&mysql_res,"can not get media",
"SELECT MedCod" // row[0]
" FROM tst_questions"
" WHERE QstCod=%ld AND CrsCod=%ld",
Gbl.Test.QstCod,Gbl.CurrentCrs.Crs.CrsCod);
else
// Get media associated to answer
DB_QuerySELECT (&mysql_res,"can not get media",
"SELECT MedCod" // row[0]
" FROM tst_answers"
" WHERE QstCod=%ld AND AnsInd=%u",
Gbl.Test.QstCod,(unsigned) NumOpt);
NumRows = DB_QuerySELECT (&mysql_res,"can not get media",
"SELECT MedCod" // row[0]
" FROM tst_answers"
" WHERE QstCod=%ld AND AnsInd=%u",
Gbl.Test.QstCod,(unsigned) NumOpt);
row = mysql_fetch_row (mysql_res);
/***** Get media code (row[0]) *****/
MedCod = Str_ConvertStrCodToLongCod (row[0]);
if (NumRows)
{
if (NumRows == 1)
{
/***** 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 *****/
DB_FreeMySQLResult (&mysql_res);

View File

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