Version18.77

This commit is contained in:
Antonio Cañas Vargas 2019-03-15 15:25:31 +01:00
parent 0e5364d642
commit 33b7542f38
17 changed files with 771 additions and 362 deletions

View File

@ -2719,32 +2719,22 @@ a:hover img.CENTRE_PHOTO_SHOW
vertical-align:top; vertical-align:top;
margin-bottom:10px; margin-bottom:10px;
} }
.MED_UPL_BUT /* Upload button _*/ .MED_UPL_ICO_CON /* Upload icon container */
{ {
cursor:pointer; display:inline-block;
} }
.MED_UPL_ICO /* Upload icon */ .MED_UPL_ICO /* Upload icon */
{ {
width:16px; width:16px;
height:16px; height:16px;
margin:0 5px; margin:5px 20px;
vertical-align:middle; vertical-align:middle;
} }
.MED_UPL_FIL /* Upload file */
{
display:none;
}
.MED_UPL_NAM /* Upload filename */
{
color:#808080;
font-size:12pt;
}
.MED_PLAY .MED_PLAY
{ {
position:relative; position:relative;
} }
/* The icon inside the overlay is positioned in the middle vertically and horizontally */ /* The icon inside the overlay is positioned in the middle vertically and horizontally */
.MED_PLAY_ICO .MED_PLAY_ICO
{ {
@ -2757,6 +2747,25 @@ a:hover img.CENTRE_PHOTO_SHOW
color:white; color:white;
text-shadow: 0 0 8px black; text-shadow: 0 0 8px black;
} }
/* For YouTube embedded videos. See https://avexdesigns.com/responsive-youtube-embed/ */
.MED_VIDEO_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_VIDEO_CONT iframe,
.MED_VIDEO_CONT object,
.MED_VIDEO_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

1
icon/file-upload.svg Normal file
View File

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="file-upload" class="svg-inline--fa fa-file-upload fa-w-12" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="#404040" d="M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm65.18 216.01H224v80c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16v-80H94.82c-14.28 0-21.41-17.29-11.27-27.36l96.42-95.7c6.65-6.61 17.39-6.61 24.04 0l96.42 95.7c10.15 10.07 3.03 27.36-11.25 27.36zM377 105L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9z"></path></svg>

After

Width:  |  Height:  |  Size: 625 B

1
icon/paperclip.svg Normal file
View File

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="paperclip" class="svg-inline--fa fa-paperclip fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#404040" d="M43.246 466.142c-58.43-60.289-57.341-157.511 1.386-217.581L254.392 34c44.316-45.332 116.351-45.336 160.671 0 43.89 44.894 43.943 117.329 0 162.276L232.214 383.128c-29.855 30.537-78.633 30.111-107.982-.998-28.275-29.97-27.368-77.473 1.452-106.953l143.743-146.835c6.182-6.314 16.312-6.422 22.626-.241l22.861 22.379c6.315 6.182 6.422 16.312.241 22.626L171.427 319.927c-4.932 5.045-5.236 13.428-.648 18.292 4.372 4.634 11.245 4.711 15.688.165l182.849-186.851c19.613-20.062 19.613-52.725-.011-72.798-19.189-19.627-49.957-19.637-69.154 0L90.39 293.295c-34.763 35.56-35.299 93.12-1.191 128.313 34.01 35.093 88.985 35.137 123.058.286l172.06-175.999c6.177-6.319 16.307-6.433 22.626-.256l22.877 22.364c6.319 6.177 6.434 16.307.256 22.626l-172.06 175.998c-59.576 60.938-155.943 60.216-214.77-.485z"></path></svg>

After

Width:  |  Height:  |  Size: 1020 B

View File

@ -767,6 +767,40 @@ function AJAXCreateObject () {
return obj; return obj;
} }
/*****************************************************************************/
/****************************** Media uploader *******************************/
/*****************************************************************************/
function mediaActivateUpload (id) {
if (document.getElementById (id + '_par_upl').disabled) { // Upload disabled
document.getElementById (id + '_par_emb').disabled = true; // Disable embed
document.getElementById (id + '_par_upl').disabled = false; // Enable upload
document.getElementById (id + '_ico_upl').style.opacity = '1'; // Highlight upload icon
document.getElementById (id + '_ico_emb').style.opacity = '0.2'; // Shadow embed icon
document.getElementById (id + '_fil').style.display = ''; // Show input
document.getElementById (id + '_url').style.display = ''; // Show input
document.getElementById (id + '_tit').style.display = ''; // Show input
}
}
function mediaActivateEmbed (id) {
if (document.getElementById (id + '_par_emb').disabled) { // Embed disabled
document.getElementById (id + '_par_upl').disabled = true; // Disable upload
document.getElementById (id + '_par_emb').disabled = false; // Enable embed
document.getElementById (id + '_ico_emb').style.opacity = '1'; // Highlight embed icon
document.getElementById (id + '_ico_upl').style.opacity = '0.2'; // Shadow upload icon
document.getElementById (id + '_fil').style.display = 'none'; // Hide input
document.getElementById (id + '_url').style.display = ''; // Show input
document.getElementById (id + '_tit').style.display = 'none'; // Hide input
}
}
/*****************************************************************************/ /*****************************************************************************/
/********************** Change display of animated GIF ***********************/ /********************** Change display of animated GIF ***********************/
/*****************************************************************************/ /*****************************************************************************/
@ -1102,15 +1136,6 @@ function disableDetailedClicks () {
document.getElementById('RowsPage').disabled = true; document.getElementById('RowsPage').disabled = true;
} }
/*****************************************************************************/
/************************** Upload images in a form **************************/
/*****************************************************************************/
function mediaUploadOnSelectFile (inputFile,id) {
document.getElementById(id + '_fil').innerHTML = inputFile.value; // Display image filename
document.getElementById(id + '_tit_url').style.display = ''; // Show hidden fields
}
/*****************************************************************************/ /*****************************************************************************/
/************************* Draw an academic calendar *************************/ /************************* Draw an academic calendar *************************/
/*****************************************************************************/ /*****************************************************************************/

View File

@ -560,7 +560,7 @@ CREATE TABLE IF NOT EXISTS forum_post (
Subject TEXT NOT NULL, Subject TEXT NOT NULL,
Content LONGTEXT NOT NULL, Content LONGTEXT NOT NULL,
MediaName VARCHAR(43) NOT NULL DEFAULT '', MediaName VARCHAR(43) NOT NULL DEFAULT '',
MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none', MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',
MediaTitle VARCHAR(2047) NOT NULL DEFAULT '', MediaTitle VARCHAR(2047) NOT NULL DEFAULT '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '', MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(PstCod), UNIQUE INDEX(PstCod),
@ -809,7 +809,7 @@ CREATE TABLE IF NOT EXISTS msg_content (
Subject TEXT NOT NULL, Subject TEXT NOT NULL,
Content LONGTEXT NOT NULL, Content LONGTEXT NOT NULL,
MediaName VARCHAR(43) NOT NULL DEFAULT '', MediaName VARCHAR(43) NOT NULL DEFAULT '',
MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none', MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',
MediaTitle VARCHAR(2047) NOT NULL DEFAULT '', MediaTitle VARCHAR(2047) NOT NULL DEFAULT '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '', MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(MsgCod), UNIQUE INDEX(MsgCod),
@ -822,7 +822,7 @@ CREATE TABLE IF NOT EXISTS msg_content_deleted (
Subject TEXT NOT NULL, Subject TEXT NOT NULL,
Content LONGTEXT NOT NULL, Content LONGTEXT NOT NULL,
MediaName VARCHAR(43) NOT NULL DEFAULT '', MediaName VARCHAR(43) NOT NULL DEFAULT '',
MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none', MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',
MediaTitle VARCHAR(2047) NOT NULL DEFAULT '', MediaTitle VARCHAR(2047) NOT NULL DEFAULT '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '', MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(MsgCod), UNIQUE INDEX(MsgCod),
@ -1026,7 +1026,7 @@ CREATE TABLE IF NOT EXISTS social_comments (
PubCod BIGINT NOT NULL, PubCod BIGINT NOT NULL,
Content LONGTEXT NOT NULL, Content LONGTEXT NOT NULL,
MediaName VARCHAR(43) NOT NULL DEFAULT '', MediaName VARCHAR(43) NOT NULL DEFAULT '',
MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none', MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',
MediaTitle VARCHAR(2047) NOT NULL DEFAULT '', MediaTitle VARCHAR(2047) NOT NULL DEFAULT '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '', MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(PubCod), UNIQUE INDEX(PubCod),
@ -1075,7 +1075,7 @@ CREATE TABLE IF NOT EXISTS social_posts (
PstCod INT NOT NULL AUTO_INCREMENT, PstCod INT NOT NULL AUTO_INCREMENT,
Content LONGTEXT NOT NULL, Content LONGTEXT NOT NULL,
MediaName VARCHAR(43) NOT NULL DEFAULT '', MediaName VARCHAR(43) NOT NULL DEFAULT '',
MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none', MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',
MediaTitle VARCHAR(2047) NOT NULL DEFAULT '', MediaTitle VARCHAR(2047) NOT NULL DEFAULT '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '', MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(PstCod), UNIQUE INDEX(PstCod),
@ -1204,7 +1204,7 @@ CREATE TABLE IF NOT EXISTS tst_answers (
Answer TEXT NOT NULL, Answer TEXT NOT NULL,
Feedback TEXT NOT NULL, Feedback TEXT NOT NULL,
MediaName VARCHAR(43) NOT NULL DEFAULT '', MediaName VARCHAR(43) NOT NULL DEFAULT '',
MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none', MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',
MediaTitle VARCHAR(2047) NOT NULL DEFAULT '', MediaTitle VARCHAR(2047) NOT NULL DEFAULT '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '', MediaURL VARCHAR(255) NOT NULL DEFAULT '',
Correct ENUM('N','Y') NOT NULL, Correct ENUM('N','Y') NOT NULL,
@ -1265,7 +1265,7 @@ CREATE TABLE IF NOT EXISTS tst_questions (
Stem TEXT NOT NULL, Stem TEXT NOT NULL,
Feedback TEXT NOT NULL, Feedback TEXT NOT NULL,
MediaName VARCHAR(43) NOT NULL DEFAULT '', MediaName VARCHAR(43) NOT NULL DEFAULT '',
MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none', MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',
MediaTitle VARCHAR(2047) NOT NULL DEFAULT '', MediaTitle VARCHAR(2047) NOT NULL DEFAULT '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '', MediaURL VARCHAR(255) NOT NULL DEFAULT '',
NumHits INT NOT NULL DEFAULT 0, NumHits INT NOT NULL DEFAULT 0,

View File

@ -450,10 +450,23 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf ps2pdf source.ps destination.pdf
*/ */
#define Log_PLATFORM_VERSION "SWAD 18.76.2 (2019-03-14)" #define Log_PLATFORM_VERSION "SWAD 18.77 (2019-03-15)"
#define CSS_FILE "swad18.68.3.css" #define CSS_FILE "swad18.77.css"
#define JS_FILE "swad18.75.js" #define JS_FILE "swad18.77.js"
/* /*
TODO: Fix edition of media in test edition
Version 18.77: Mar 14, 2019 Embedded YouTube videos. Not finished. (240214 lines)
7 changes necessary in database:
ALTER TABLE forum_post CHANGE COLUMN MediaType MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none';
ALTER TABLE msg_content CHANGE COLUMN MediaType MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none';
ALTER TABLE msg_content_deleted CHANGE COLUMN MediaType MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none';
ALTER TABLE social_comments CHANGE COLUMN MediaType MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none';
ALTER TABLE social_posts CHANGE COLUMN MediaType MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none';
ALTER TABLE tst_answers CHANGE COLUMN MediaType MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none';
ALTER TABLE tst_questions CHANGE COLUMN MediaType MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none';
Copy the following icon to icon public directory:
sudo cp icon/file-image.svg /var/www/html/swad/icon/
Version 18.76.2: Mar 14, 2019 Changes in translation of several messages related to media. (239849 lines) Version 18.76.2: Mar 14, 2019 Changes in translation of several messages related to media. (239849 lines)
Version 18.76.1: Mar 13, 2019 Changes in video tag. (239810 lines) Version 18.76.1: Mar 13, 2019 Changes in video tag. (239810 lines)
Version 18.76: Mar 13, 2019 Video allowed as multimedia. (239814 lines) Version 18.76: Mar 13, 2019 Video allowed as multimedia. (239814 lines)

View File

@ -51,7 +51,7 @@
/*****************************************************************************/ /*****************************************************************************/
extern struct Globals Gbl; extern struct Globals Gbl;
extern const char Str_BIN_TO_BASE64URL[64]; extern const char Str_BIN_TO_BASE64URL[64 + 1];
/*****************************************************************************/ /*****************************************************************************/
/************************ Internal global variables **************************/ /************************ Internal global variables **************************/

View File

@ -1207,22 +1207,22 @@ mysql> DESCRIBE forum_disabled_post;
/***** Table forum_post *****/ /***** Table forum_post *****/
/* /*
mysql> DESCRIBE forum_post; mysql> DESCRIBE forum_post;
+------------+---------------------------------------------+------+-----+---------+----------------+ +------------+-------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------------------+------+-----+---------+----------------+ +------------+-------------------------------------------------------+------+-----+---------+----------------+
| PstCod | int(11) | NO | PRI | NULL | auto_increment | | PstCod | int(11) | NO | PRI | NULL | auto_increment |
| ThrCod | int(11) | NO | MUL | NULL | | | ThrCod | int(11) | NO | MUL | NULL | |
| UsrCod | int(11) | NO | MUL | NULL | | | UsrCod | int(11) | NO | MUL | NULL | |
| CreatTime | datetime | NO | MUL | NULL | | | CreatTime | datetime | NO | MUL | NULL | |
| ModifTime | datetime | NO | MUL | NULL | | | ModifTime | datetime | NO | MUL | NULL | |
| NumNotif | int(11) | NO | | 0 | | | NumNotif | int(11) | NO | | 0 | |
| Subject | text | NO | | NULL | | | Subject | text | NO | | NULL | |
| Content | longtext | NO | | NULL | | | Content | longtext | NO | | NULL | |
| MediaName | varchar(43) | NO | | | | | MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg') | NO | | none | | | MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | | | MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | | | MediaURL | varchar(255) | NO | | | |
+------------+---------------------------------------------+------+-----+---------+----------------+ +------------+-------------------------------------------------------+------+-----+---------+----------------+
12 rows in set (0.00 sec) 12 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS forum_post (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS forum_post ("
@ -1235,7 +1235,7 @@ mysql> DESCRIBE forum_post;
"Subject TEXT NOT NULL," // Cns_MAX_BYTES_SUBJECT "Subject TEXT NOT NULL," // Cns_MAX_BYTES_SUBJECT
"Content LONGTEXT NOT NULL," // Cns_MAX_BYTES_LONG_TEXT "Content LONGTEXT NOT NULL," // Cns_MAX_BYTES_LONG_TEXT
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME "MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none'," "MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE "MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW "MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(PstCod)," "UNIQUE INDEX(PstCod),"
@ -1733,17 +1733,17 @@ mysql> DESCRIBE msg_banned;
/***** Table msg_content *****/ /***** Table msg_content *****/
/* /*
mysql> DESCRIBE msg_content; mysql> DESCRIBE msg_content;
+------------+---------------------------------------------+------+-----+---------+----------------+ +------------+-------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------------------+------+-----+---------+----------------+ +------------+-------------------------------------------------------+------+-----+---------+----------------+
| MsgCod | int(11) | NO | PRI | NULL | auto_increment | | MsgCod | int(11) | NO | PRI | NULL | auto_increment |
| Subject | text | NO | MUL | NULL | | | Subject | text | NO | MUL | NULL | |
| Content | longtext | NO | | NULL | | | Content | longtext | NO | | NULL | |
| MediaName | varchar(43) | NO | | | | | MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg') | NO | | none | | | MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | | | MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | | | MediaURL | varchar(255) | NO | | | |
+------------+---------------------------------------------+------+-----+---------+----------------+ +------------+-------------------------------------------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec) 7 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS msg_content (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS msg_content ("
@ -1751,7 +1751,7 @@ mysql> DESCRIBE msg_content;
"Subject TEXT NOT NULL," "Subject TEXT NOT NULL,"
"Content LONGTEXT NOT NULL," "Content LONGTEXT NOT NULL,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME "MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none'," "MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE "MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW "MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(MsgCod)," "UNIQUE INDEX(MsgCod),"
@ -1760,17 +1760,17 @@ mysql> DESCRIBE msg_content;
/***** Table msg_content_deleted *****/ /***** Table msg_content_deleted *****/
/* /*
mysql> DESCRIBE msg_content_deleted; mysql> DESCRIBE msg_content_deleted;
+------------+---------------------------------------------+------+-----+---------+-------+ +------------+-------------------------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------------------+------+-----+---------+-------+ +------------+-------------------------------------------------------+------+-----+---------+-------+
| MsgCod | int(11) | NO | PRI | NULL | | | MsgCod | int(11) | NO | PRI | NULL | |
| Subject | text | NO | MUL | NULL | | | Subject | text | NO | MUL | NULL | |
| Content | longtext | NO | | NULL | | | Content | longtext | NO | | NULL | |
| MediaName | varchar(43) | NO | | | | | MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg') | NO | | none | | | MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | | | MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | | | MediaURL | varchar(255) | NO | | | |
+------------+---------------------------------------------+------+-----+---------+-------+ +------------+-------------------------------------------------------+------+-----+---------+-------+
7 rows in set (0.00 sec) 7 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS msg_content_deleted (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS msg_content_deleted ("
@ -1778,7 +1778,7 @@ mysql> DESCRIBE msg_content_deleted;
"Subject TEXT NOT NULL," "Subject TEXT NOT NULL,"
"Content LONGTEXT NOT NULL," "Content LONGTEXT NOT NULL,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME "MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none'," "MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE "MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW "MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(MsgCod)," "UNIQUE INDEX(MsgCod),"
@ -2176,23 +2176,23 @@ mysql> DESCRIBE sessions;
/***** Table social_comments *****/ /***** Table social_comments *****/
/* /*
mysql> DESCRIBE social_comments; mysql> DESCRIBE social_comments;
+------------+---------------------------------------------+------+-----+---------+-------+ +------------+-------------------------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------------------+------+-----+---------+-------+ +------------+-------------------------------------------------------+------+-----+---------+-------+
| PubCod | bigint(20) | NO | PRI | NULL | | | PubCod | bigint(20) | NO | PRI | NULL | |
| Content | longtext | NO | MUL | NULL | | | Content | longtext | NO | MUL | NULL | |
| MediaName | varchar(43) | NO | | | | | MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg') | NO | | none | | | MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | | | MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | | | MediaURL | varchar(255) | NO | | | |
+------------+---------------------------------------------+------+-----+---------+-------+ +------------+-------------------------------------------------------+------+-----+---------+-------+
6 rows in set (0.00 sec) 6 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_comments (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_comments ("
"PubCod BIGINT NOT NULL," "PubCod BIGINT NOT NULL,"
"Content LONGTEXT NOT NULL," "Content LONGTEXT NOT NULL,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME "MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none'," "MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE "MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW "MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(PubCod)," "UNIQUE INDEX(PubCod),"
@ -2274,23 +2274,23 @@ mysql> DESCRIBE social_notes_fav;
/***** Table social_posts *****/ /***** Table social_posts *****/
/* /*
mysql> DESCRIBE social_posts; mysql> DESCRIBE social_posts;
+------------+---------------------------------------------+------+-----+---------+----------------+ +------------+-------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------------------+------+-----+---------+----------------+ +------------+-------------------------------------------------------+------+-----+---------+----------------+
| PstCod | int(11) | NO | PRI | NULL | auto_increment | | PstCod | int(11) | NO | PRI | NULL | auto_increment |
| Content | longtext | NO | MUL | NULL | | | Content | longtext | NO | MUL | NULL | |
| MediaName | varchar(43) | NO | | | | | MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg') | NO | | none | | | MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | | | MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | | | MediaURL | varchar(255) | NO | | | |
+------------+---------------------------------------------+------+-----+---------+----------------+ +------------+-------------------------------------------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec) 6 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_posts (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_posts ("
"PubCod INT NOT NULL AUTO_INCREMENT," "PubCod INT NOT NULL AUTO_INCREMENT,"
"Content LONGTEXT NOT NULL," "Content LONGTEXT NOT NULL,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME "MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none'," "MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE "MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW "MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(PubCod)," "UNIQUE INDEX(PubCod),"
@ -2547,19 +2547,19 @@ mysql> DESCRIBE timetable_tut;
/***** Table tst_answers *****/ /***** Table tst_answers *****/
/* /*
mysql> DESCRIBE tst_answers; mysql> DESCRIBE tst_answers;
+------------+---------------------------------------------+------+-----+---------+-------+ +------------+-------------------------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------------------+------+-----+---------+-------+ +------------+-------------------------------------------------------+------+-----+---------+-------+
| QstCod | int(11) | NO | MUL | NULL | | | QstCod | int(11) | NO | MUL | NULL | |
| AnsInd | tinyint(4) | NO | | NULL | | | AnsInd | tinyint(4) | NO | | NULL | |
| Answer | text | NO | | NULL | | | Answer | text | NO | | NULL | |
| Feedback | text | NO | | NULL | | | Feedback | text | NO | | NULL | |
| MediaName | varchar(43) | NO | | | | | MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg') | NO | | none | | | MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | | | MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | | | MediaURL | varchar(255) | NO | | | |
| Correct | enum('N','Y') | NO | | NULL | | | Correct | enum('N','Y') | NO | | NULL | |
+------------+---------------------------------------------+------+-----+---------+-------+ +------------+-------------------------------------------------------+------+-----+---------+-------+
9 rows in set (0.00 sec) 9 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS tst_answers (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS tst_answers ("
@ -2568,7 +2568,7 @@ mysql> DESCRIBE tst_answers;
"Answer TEXT NOT NULL," // Tst_MAX_BYTES_ANSWER_OR_FEEDBACK "Answer TEXT NOT NULL," // Tst_MAX_BYTES_ANSWER_OR_FEEDBACK
"Feedback TEXT NOT NULL," // Tst_MAX_BYTES_ANSWER_OR_FEEDBACK "Feedback TEXT NOT NULL," // Tst_MAX_BYTES_ANSWER_OR_FEEDBACK
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME "MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none'," "MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE "MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW "MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"Correct ENUM('N','Y') NOT NULL," "Correct ENUM('N','Y') NOT NULL,"
@ -2685,7 +2685,7 @@ mysql> DESCRIBE tst_questions;
| Stem | text | NO | | NULL | | | Stem | text | NO | | NULL | |
| Feedback | text | NO | | NULL | | | Feedback | text | NO | | NULL | |
| MediaName | varchar(43) | NO | | | | | MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg') | NO | | none | | | MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | | | MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | | | MediaURL | varchar(255) | NO | | | |
| NumHits | int(11) | NO | | 0 | | | NumHits | int(11) | NO | | 0 | |
@ -2703,7 +2703,7 @@ mysql> DESCRIBE tst_questions;
"Stem TEXT NOT NULL," // Cns_MAX_BYTES_TEXT "Stem TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
"Feedback TEXT NOT NULL," // Cns_MAX_BYTES_TEXT "Feedback TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME "MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg') NOT NULL DEFAULT 'none'," "MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE "MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW "MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"NumHits INT NOT NULL DEFAULT 0," "NumHits INT NOT NULL DEFAULT 0,"

View File

@ -502,7 +502,7 @@ static long For_InsertForumPst (long ThrCod,long UsrCod,
/***** Check if image is received and processed *****/ /***** Check if image is received and processed *****/
if (Media->Action == Med_ACTION_NEW_MEDIA && // Upload new image if (Media->Action == Med_ACTION_NEW_MEDIA && // Upload new image
Media->Status == Med_FILE_PROCESSED) // The new image received has been processed Media->Status == Med_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */ /* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (Media); Med_MoveMediaToDefinitiveDir (Media);

View File

@ -25,8 +25,10 @@
/*********************************** Headers *********************************/ /*********************************** Headers *********************************/
/*****************************************************************************/ /*****************************************************************************/
#define _GNU_SOURCE // For strcasestr, asprintf
#include <linux/limits.h> // For PATH_MAX #include <linux/limits.h> // For PATH_MAX
#include <stdbool.h> // For boolean type #include <stdbool.h> // For boolean type
#include <stdio.h> // For asprintf
#include <stdlib.h> // For exit, system, malloc, free, etc #include <stdlib.h> // For exit, system, malloc, free, etc
#include <string.h> // For string functions #include <string.h> // For string functions
#include <sys/stat.h> // For lstat #include <sys/stat.h> // For lstat
@ -57,6 +59,7 @@ const char *Med_StringsTypeDB[Med_NUM_TYPES] =
"mp4", // Med_MP4 "mp4", // Med_MP4
"webm", // Med_WEBM "webm", // Med_WEBM
"ogg", // Med_OGG "ogg", // Med_OGG
"youtube", // Med_YOUTUBE
}; };
const char *Med_Extensions[Med_NUM_TYPES] = const char *Med_Extensions[Med_NUM_TYPES] =
@ -67,6 +70,7 @@ const char *Med_Extensions[Med_NUM_TYPES] =
"mp4", // Med_MP4 "mp4", // Med_MP4
"webm", // Med_WEBM "webm", // Med_WEBM
"ogg", // Med_OGG "ogg", // Med_OGG
"", // Med_YOUTUBE
}; };
#define Med_MAX_SIZE_GIF (5UL * 1024UL * 1024UL) // 5 MiB #define Med_MAX_SIZE_GIF (5UL * 1024UL * 1024UL) // 5 MiB
@ -76,6 +80,15 @@ const char *Med_Extensions[Med_NUM_TYPES] =
/****************************** Internal types *******************************/ /****************************** Internal types *******************************/
/*****************************************************************************/ /*****************************************************************************/
#define Med_NUM_FORM_TYPES 3
typedef enum
{
Med_FORM_UNKNOWN = 0,
Med_FORM_FILE = 1,
Med_FORM_EMBED = 2,
} Med_FormType_t;
/*****************************************************************************/ /*****************************************************************************/
/************** External global variables from others modules ****************/ /************** External global variables from others modules ****************/
/*****************************************************************************/ /*****************************************************************************/
@ -91,8 +104,11 @@ extern struct Globals Gbl;
/*****************************************************************************/ /*****************************************************************************/
static Med_Action_t Med_GetMediaActionFromForm (const char *ParamAction); static Med_Action_t Med_GetMediaActionFromForm (const char *ParamAction);
static void Med_GetAndProcessFileFromForm (struct Media *Media, static Med_FormType_t Usr_GetFormTypeFromForm (void);
const char *ParamFile); static void Usr_GetURLFromForm (const char *ParamName,struct Media *Media);
static void Usr_GetTitleFromForm (const char *ParamName,struct Media *Media);
static void Med_GetAndProcessFileFromForm (const char *ParamFile,
struct Media *Media);
static bool Med_DetectIfAnimated (struct Media *Media, static bool Med_DetectIfAnimated (struct Media *Media,
const char PathMedPrivTmp[PATH_MAX + 1], const char PathMedPrivTmp[PATH_MAX + 1],
const char PathFileOrg[PATH_MAX + 1]); const char PathFileOrg[PATH_MAX + 1]);
@ -113,6 +129,9 @@ 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_GetAndProcessEmbedFromForm (const char *ParamURL,
struct Media *Media);
static bool Med_MoveTmpFileToDefDir (struct Media *Media, static bool Med_MoveTmpFileToDefDir (struct Media *Media,
const char PathMedPrivTmp[PATH_MAX + 1], const char PathMedPrivTmp[PATH_MAX + 1],
const char PathMedPriv[PATH_MAX + 1], const char PathMedPriv[PATH_MAX + 1],
@ -127,6 +146,8 @@ static void Med_ShowGIF (struct Media *Media,
static void Med_ShowVideo (struct Media *Media, 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 Med_Type_t Med_GetTypeFromExtAndMIME (const char *Extension, static Med_Type_t Med_GetTypeFromExtAndMIME (const char *Extension,
const char *MIMEType); const char *MIMEType);
@ -151,9 +172,9 @@ void Med_MediaConstructor (struct Media *Media)
void Med_ResetMediaExceptTitleAndURL (struct Media *Media) void Med_ResetMediaExceptTitleAndURL (struct Media *Media)
{ {
Media->Action = Med_ACTION_NO_MEDIA; Media->Action = Med_ACTION_NO_MEDIA;
Media->Status = Med_FILE_NONE; Media->Status = Med_STATUS_NONE;
Media->Name[0] = '\0'; Media->Name[0] = '\0';
Media->Type = Med_NONE; Media->Type = Med_TYPE_NONE;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -215,9 +236,25 @@ void Med_GetMediaDataFromRow (const char *Name,
Media->Type = Med_GetTypeFromStrInDB (TypeStr); Media->Type = Med_GetTypeFromStrInDB (TypeStr);
/***** Set status of media file *****/ /***** Set status of media file *****/
Media->Status = (Media->Name[0] && Media->Status = (Media->Type != Med_TYPE_NONE) ? Med_STORED_IN_DB :
Media->Type != Med_NONE) ? Med_NAME_STORED_IN_DB : Med_STATUS_NONE;
Med_FILE_NONE;
/***** Copy image URL to struct *****/
// Media->URL can be empty or filled with previous value
// If filled ==> free it
Med_FreeMediaURL (Media);
if (URL[0])
{
/* Get and limit length of the URL */
Length = strlen (URL);
if (Length > Cns_MAX_BYTES_WWW)
Length = Cns_MAX_BYTES_WWW;
if ((Media->URL = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for image URL.");
Str_Copy (Media->URL,URL,
Length);
}
/***** Copy image title to struct *****/ /***** Copy image title to struct *****/
// Media->Title can be empty or filled with previous value // Media->Title can be empty or filled with previous value
@ -235,23 +272,6 @@ void Med_GetMediaDataFromRow (const char *Name,
Str_Copy (Media->Title,Title, Str_Copy (Media->Title,Title,
Length); Length);
} }
/***** Copy image URL to struct *****/
// Media->URL can be empty or filled with previous value
// If filled ==> free it
Med_FreeMediaURL (Media);
if (URL[0])
{
/* Get and limit length of the URL */
Length = strlen (URL);
if (Length > Med_MAX_BYTES_TITLE)
Length = Med_MAX_BYTES_TITLE;
if ((Media->URL = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for image URL.");
Str_Copy (Media->URL,URL,
Length);
}
} }
/*****************************************************************************/ /*****************************************************************************/
@ -261,7 +281,6 @@ void Med_GetMediaDataFromRow (const char *Name,
void Med_PutMediaUploader (int NumMediaInForm,const char *ClassMediaTitURL) void Med_PutMediaUploader (int NumMediaInForm,const char *ClassMediaTitURL)
{ {
extern const char *Txt_Image_video; extern const char *Txt_Image_video;
extern const char *Txt_optional;
extern const char *Txt_Title_attribution; extern const char *Txt_Title_attribution;
extern const char *Txt_Link; extern const char *Txt_Link;
struct ParamUploadMedia ParamUploadMedia; struct ParamUploadMedia ParamUploadMedia;
@ -274,48 +293,88 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassMediaTitURL)
Frm_SetUniqueId (Id); Frm_SetUniqueId (Id);
/***** Start container *****/ /***** Start container *****/
fprintf (Gbl.F.Out,"<div class=\"MED_UPL_CON\">"); fprintf (Gbl.F.Out,"<div class=\"MED_UPL_CON\">"); // container
/***** 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);
/***** Media file *****/ /***** Upload icon *****/
fprintf (Gbl.F.Out,"<label class=\"MED_UPL_BUT\">" fprintf (Gbl.F.Out,"<div id=\"%s_ico_upl\"" // <id>_ico_upl
"<img src=\"%s/camera.svg\"" " class=\"MED_UPL_ICO_CON\">"
" alt=\"%s\" title=\"%s (%s)\"" "<img src=\"%s/file-image.svg\""
" class=\"MED_UPL_ICO\" />" " alt=\"%s\" title=\"%s\""
"<input type=\"file\" name=\"%s\"" " class=\"MED_UPL_ICO ICO_HIGHLIGHT\""
" accept=\"image/,video/\"" " onclick=\"mediaActivateUpload('%s');\" />"
" class=\"MED_UPL_FIL\"" "</div>", // <id>_ico_upl
" onchange=\"mediaUploadOnSelectFile (this,'%s');\" />" Id,
"<span id=\"%s_fil\" class=\"MED_UPL_NAM\" />" Gbl.Prefs.URLIcons,
"</span>" Txt_Image_video,Txt_Image_video,
"</label>",
Gbl.Prefs.URLIcons,
Txt_Image_video,Txt_Image_video,Txt_optional,
ParamUploadMedia.File,
Id,Id);
/***** Media title/attribution and URL *****/
fprintf (Gbl.F.Out,"<div id=\"%s_tit_url\" style=\"display:none;\">",
Id); Id);
fprintf (Gbl.F.Out,"<input type=\"text\" name=\"%s\""
" placeholder=\"%s (%s)\"" /***** Form type *****/
" class=\"%s\" maxlength=\"%u\" value=\"\" />", fprintf (Gbl.F.Out,"<input type=\"hidden\""
ParamUploadMedia.Title, " id=\"%s_par_upl\"" // <id>_par_upl
Txt_Title_attribution,Txt_optional, " name=\"FormType\" value=\"%u\""
ClassMediaTitURL,Med_MAX_CHARS_TITLE); " disabled=\"disabled\" />",
fprintf (Gbl.F.Out,"<br />" Id,
"<input type=\"url\" name=\"%s\"" (unsigned) Med_FORM_FILE);
" placeholder=\"%s (%s)\""
" class=\"%s\" maxlength=\"%u\" value=\"\" />", /***** Embed icon *****/
fprintf (Gbl.F.Out,"<div id=\"%s_ico_emb\"" // <id>_ico_emb
" class=\"MED_UPL_ICO_CON\">"
"<img src=\"%s/youtube-brands.svg\""
" alt=\"%s\" title=\"%s\""
" class=\"MED_UPL_ICO ICO_HIGHLIGHT\""
" onclick=\"mediaActivateEmbed('%s');\" />"
"</div>", // <id>_ico_emb
Id,
Gbl.Prefs.URLIcons,
"Embed URL","Embed URL",
Id);
/***** Form type *****/
fprintf (Gbl.F.Out,"<input type=\"hidden\""
" id=\"%s_par_emb\"" // <id>_par_emb
" name=\"FormType\" value=\"%u\""
" disabled=\"disabled\" />",
Id,
(unsigned) Med_FORM_EMBED);
/***** Media file *****/
fprintf (Gbl.F.Out,"<div id=\"%s_fil\"" // <id>_fil
" style=\"display:none;\">"
"<input type=\"file\" name=\"%s\""
" accept=\"image/,video/\" />"
"</div>", // <id>_fil
Id,
ParamUploadMedia.File);
/***** Media URL *****/
fprintf (Gbl.F.Out,"<div id=\"%s_url\"" // <id>_url
" style=\"display:none;\">"
"<input type=\"url\" name=\"%s\""
" placeholder=\"%s\""
" class=\"%s\" maxlength=\"%u\" value=\"\" />"
"</div>", // <id>_url
Id,
ParamUploadMedia.URL, ParamUploadMedia.URL,
Txt_Link,Txt_optional, Txt_Link,
ClassMediaTitURL,Cns_MAX_CHARS_WWW); ClassMediaTitURL,Cns_MAX_CHARS_WWW);
fprintf (Gbl.F.Out,"</div>");
/***** Media title *****/
fprintf (Gbl.F.Out,"<div id=\"%s_tit\"" // <id>_tit
" style=\"display:none;\">"
"<input type=\"text\" name=\"%s\""
" placeholder=\"%s\""
" class=\"%s\" maxlength=\"%u\" value=\"\" />",
Id,
ParamUploadMedia.Title,
Txt_Title_attribution,
ClassMediaTitURL,Med_MAX_CHARS_TITLE);
fprintf (Gbl.F.Out,"</div>"); // <id>_tit
/***** End container *****/ /***** End container *****/
fprintf (Gbl.F.Out,"</div>"); fprintf (Gbl.F.Out,"</div>"); // container
} }
/*****************************************************************************/ /*****************************************************************************/
@ -328,37 +387,54 @@ void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media,
void (*GetMediaFromDB) (int NumMediaInForm,struct Media *Media)) void (*GetMediaFromDB) (int NumMediaInForm,struct Media *Media))
{ {
struct ParamUploadMedia ParamUploadMedia; struct ParamUploadMedia ParamUploadMedia;
char Title[Med_MAX_BYTES_TITLE + 1]; Med_FormType_t FormType;
char URL[Cns_MAX_BYTES_WWW + 1];
size_t Length;
/***** Set names of parameters depending on number of media in form *****/ /***** Set names of parameters depending on number of media in form *****/
Med_SetParamNames (&ParamUploadMedia,NumMediaInForm); Med_SetParamNames (&ParamUploadMedia,NumMediaInForm);
/***** First, get action and initialize media (image/video) /***** Get action and initialize media (image/video)
(except title, that will be get after the media file) *****/ (except title, that will be get after the media file) *****/
Media->Action = Med_GetMediaActionFromForm (ParamUploadMedia.Action); Media->Action = Med_GetMediaActionFromForm (ParamUploadMedia.Action);
Media->Status = Med_FILE_NONE; Media->Status = Med_STATUS_NONE;
Media->Name[0] = '\0'; Media->Name[0] = '\0';
Media->Type = Med_NONE; Media->Type = Med_TYPE_NONE;
/***** Secondly, get the media (image/video) name and the file *****/ /***** Get form type *****/
FormType = Usr_GetFormTypeFromForm ();
/***** Get the media (image/video) name and the file *****/
switch (Media->Action) switch (Media->Action)
{ {
case Med_ACTION_NEW_MEDIA: // Upload new image/video case Med_ACTION_NEW_MEDIA: // Upload new image/video
/***** Get new media (if present ==> process and create temporary file) *****/ /***** Get new media *****/
Med_GetAndProcessFileFromForm (Media,ParamUploadMedia.File); switch (FormType)
switch (Media->Status)
{ {
case Med_FILE_NONE: // No new image/video received case Med_FORM_FILE:
Media->Action = Med_ACTION_NO_MEDIA; /***** Get image/video (if present ==> process and create temporary file) *****/
Media->Name[0] = '\0'; Med_GetAndProcessFileFromForm (ParamUploadMedia.File,Media);
Media->Type = Med_NONE; switch (Media->Status)
{
case Med_STATUS_NONE: // No new image/video received
Media->Action = Med_ACTION_NO_MEDIA;
Media->Name[0] = '\0';
Media->Type = Med_TYPE_NONE;
break;
case Med_RECEIVED: // New image/video received, but not processed
Media->Status = Med_STATUS_NONE;
Media->Name[0] = '\0';
Media->Type = Med_TYPE_NONE;
break;
case Med_PROCESSED:
Usr_GetURLFromForm (ParamUploadMedia.URL,Media);
Usr_GetTitleFromForm (ParamUploadMedia.Title,Media);
break;
default:
break;
}
break; break;
case Med_FILE_RECEIVED: // New image/video received, but not processed case Med_FORM_EMBED:
Media->Status = Med_FILE_NONE; /***** Get and process embed URL from form *****/
Media->Name[0] = '\0'; Med_GetAndProcessEmbedFromForm (ParamUploadMedia.URL,Media);
Media->Type = Med_NONE;
break; break;
default: default:
break; break;
@ -370,9 +446,29 @@ void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media,
GetMediaFromDB (NumMediaInForm,Media); GetMediaFromDB (NumMediaInForm,Media);
break; break;
case Med_ACTION_CHANGE_MEDIA: // Replace old image/video by new one case Med_ACTION_CHANGE_MEDIA: // Replace old image/video by new one
/***** Get new image/video (if present ==> process and create temporary file) *****/ switch (FormType)
Med_GetAndProcessFileFromForm (Media,ParamUploadMedia.File); {
if (Media->Status != Med_FILE_PROCESSED && // No new media received-processed successfully case Med_FORM_FILE:
/***** Get image/video (if present ==> process and create temporary file) *****/
Med_GetAndProcessFileFromForm (ParamUploadMedia.File,Media);
switch (Media->Status)
{
case Med_PROCESSED:
Usr_GetURLFromForm (ParamUploadMedia.URL,Media);
Usr_GetTitleFromForm (ParamUploadMedia.Title,Media);
break;
default:
break;
}
break;
case Med_FORM_EMBED:
/***** Get and process embed URL from form *****/
Med_GetAndProcessEmbedFromForm (ParamUploadMedia.URL,Media);
break;
default:
break;
}
if (Media->Status != Med_PROCESSED && // No new media received-processed successfully
GetMediaFromDB != NULL) GetMediaFromDB != NULL)
/* Get media (image/video) name */ /* Get media (image/video) name */
GetMediaFromDB (NumMediaInForm,Media); GetMediaFromDB (NumMediaInForm,Media);
@ -380,36 +476,6 @@ void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media,
case Med_ACTION_NO_MEDIA: // Do not use image/video (remove current image/video if exists) case Med_ACTION_NO_MEDIA: // Do not use image/video (remove current image/video if exists)
break; break;
} }
/***** Third, get image/video title from form *****/
Par_GetParToText (ParamUploadMedia.Title,Title,Med_MAX_BYTES_TITLE);
/* If the title coming from the form is empty, keep current media title unchanged
If not empty, copy it to current media title */
if ((Length = strlen (Title)) > 0)
{
/* Overwrite current title (empty or coming from database)
with the title coming from the form */
Med_FreeMediaTitle (Media);
if ((Media->Title = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for media title.");
Str_Copy (Media->Title,Title,
Length);
}
/***** By last, get media URL from form *****/
Par_GetParToText (ParamUploadMedia.URL,URL,Cns_MAX_BYTES_WWW);
/* If the URL coming from the form is empty, keep current media URL unchanged
If not empty, copy it to current media URL */
if ((Length = strlen (URL)) > 0)
{
/* Overwrite current URL (empty or coming from database)
with the URL coming from the form */
Med_FreeMediaURL (Media);
if ((Media->URL = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for media URL.");
Str_Copy (Media->URL,URL,
Length);
}
} }
/*****************************************************************************/ /*****************************************************************************/
@ -462,12 +528,74 @@ static Med_Action_t Med_GetMediaActionFromForm (const char *ParamAction)
(unsigned long) Med_ACTION_DEFAULT); (unsigned long) Med_ACTION_DEFAULT);
} }
/*****************************************************************************/
/********************* Get from form the type of form ************************/
/*****************************************************************************/
static Med_FormType_t Usr_GetFormTypeFromForm (void)
{
return (Med_FormType_t) Par_GetParToUnsignedLong ("FormType",
0,
Med_NUM_FORM_TYPES - 1,
(unsigned long) Med_FORM_UNKNOWN);
}
/*****************************************************************************/
/********************* Get from form the type of form ************************/
/*****************************************************************************/
static void Usr_GetURLFromForm (const char *ParamName,struct Media *Media)
{
char URL[Cns_MAX_BYTES_WWW + 1];
size_t Length;
/***** Get media URL from form *****/
Par_GetParToText (ParamName,URL,Cns_MAX_BYTES_WWW);
/* If the URL coming from the form is empty, keep current media URL unchanged
If not empty, copy it to current media URL */
if ((Length = strlen (URL)) > 0)
{
/* Overwrite current URL (empty or coming from database)
with the URL coming from the form */
Med_FreeMediaURL (Media);
if ((Media->URL = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for media URL.");
Str_Copy (Media->URL,URL,
Length);
}
}
/*****************************************************************************/
/********************* Get from form the type of form ************************/
/*****************************************************************************/
static void Usr_GetTitleFromForm (const char *ParamName,struct Media *Media)
{
char Title[Med_MAX_BYTES_TITLE + 1];
size_t Length;
/***** Get image/video title from form *****/
Par_GetParToText (ParamName,Title,Med_MAX_BYTES_TITLE);
/* If the title coming from the form is empty, keep current media title unchanged
If not empty, copy it to current media title */
if ((Length = strlen (Title)) > 0)
{
/* Overwrite current title (empty or coming from database)
with the title coming from the form */
Med_FreeMediaTitle (Media);
if ((Media->Title = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for media title.");
Str_Copy (Media->Title,Title,
Length);
}
}
/*****************************************************************************/ /*****************************************************************************/
/**************************** Get media from form ****************************/ /**************************** Get media from form ****************************/
/*****************************************************************************/ /*****************************************************************************/
static void Med_GetAndProcessFileFromForm (struct Media *Media, static void Med_GetAndProcessFileFromForm (const char *ParamFile,
const char *ParamFile) struct Media *Media)
{ {
struct Param *Param; struct Param *Param;
char FileNameImgSrc[PATH_MAX + 1]; char FileNameImgSrc[PATH_MAX + 1];
@ -478,8 +606,8 @@ static void Med_GetAndProcessFileFromForm (struct Media *Media,
char PathMedPrivTmp[PATH_MAX + 1]; char PathMedPrivTmp[PATH_MAX + 1];
char PathFileOrg[PATH_MAX + 1]; // Full name of original uploaded file char PathFileOrg[PATH_MAX + 1]; // Full name of original uploaded file
/***** Set media file status *****/ /***** Set media status *****/
Media->Status = Med_FILE_NONE; Media->Status = Med_STATUS_NONE;
/***** Get filename and MIME type *****/ /***** Get filename and MIME type *****/
Param = Fil_StartReceptionOfFile (ParamFile,FileNameImgSrc,MIMEType); Param = Fil_StartReceptionOfFile (ParamFile,FileNameImgSrc,MIMEType);
@ -501,7 +629,7 @@ static void Med_GetAndProcessFileFromForm (struct Media *Media,
/* Check extension */ /* Check extension */
Media->Type = Med_GetTypeFromExtAndMIME (PtrExtension,MIMEType); Media->Type = Med_GetTypeFromExtAndMIME (PtrExtension,MIMEType);
if (Media->Type == Med_NONE) if (Media->Type == Med_TYPE_NONE)
return; return;
/***** Assign a unique name for the media *****/ /***** Assign a unique name for the media *****/
@ -525,14 +653,14 @@ static void Med_GetAndProcessFileFromForm (struct Media *Media,
/***** End the reception of original not processed media /***** End the reception of original not processed media
(it may be very big) into a temporary file *****/ (it may be very big) into a temporary file *****/
Media->Status = Med_FILE_NONE; Media->Status = Med_STATUS_NONE;
snprintf (PathFileOrg,sizeof (PathFileOrg), snprintf (PathFileOrg,sizeof (PathFileOrg),
"%s/%s_original.%s", "%s/%s_original.%s",
PathMedPrivTmp,Media->Name,PtrExtension); PathMedPrivTmp,Media->Name,PtrExtension);
if (Fil_EndReceptionOfFile (PathFileOrg,Param)) // Success if (Fil_EndReceptionOfFile (PathFileOrg,Param)) // Success
{ {
Media->Status = Med_FILE_RECEIVED; Media->Status = Med_RECEIVED;
/***** Detect if animated GIF *****/ /***** Detect if animated GIF *****/
if (Media->Type == Med_GIF) if (Media->Type == Med_GIF)
@ -626,7 +754,7 @@ static void Med_ProcessJPG (struct Media *Media,
PathMedPrivTmp,Media->Name,Med_Extensions[Med_JPG]); PathMedPrivTmp,Media->Name,Med_Extensions[Med_JPG]);
if (Med_ResizeImage (Media,PathFileOrg,PathFileJPGTmp) == 0) // On success ==> 0 is returned if (Med_ResizeImage (Media,PathFileOrg,PathFileJPGTmp) == 0) // On success ==> 0 is returned
/* Success */ /* Success */
Media->Status = Med_FILE_PROCESSED; Media->Status = Med_PROCESSED;
else // Error processing media else // Error processing media
{ {
/* Remove temporary destination media file */ /* Remove temporary destination media file */
@ -682,7 +810,7 @@ static void Med_ProcessGIF (struct Media *Media,
Ale_ShowAlert (Ale_ERROR,Txt_The_file_could_not_be_processed_successfully); Ale_ShowAlert (Ale_ERROR,Txt_The_file_could_not_be_processed_successfully);
} }
else // Success else // Success
Media->Status = Med_FILE_PROCESSED; Media->Status = Med_PROCESSED;
} }
else // Error getting first frame else // Error getting first frame
{ {
@ -736,7 +864,7 @@ static void Med_ProcessVideo (struct Media *Media,
/* Show error alert */ /* Show error alert */
Ale_ShowAlert (Ale_ERROR,Txt_The_file_could_not_be_processed_successfully); Ale_ShowAlert (Ale_ERROR,Txt_The_file_could_not_be_processed_successfully);
else // Success else // Success
Media->Status = Med_FILE_PROCESSED; Media->Status = Med_PROCESSED;
} }
else // Size exceeded else // Size exceeded
{ {
@ -805,6 +933,187 @@ static int Med_GetFirstFrame (const char PathFileOriginal[PATH_MAX + 1],
return ReturnCode; return ReturnCode;
} }
/*****************************************************************************/
/**************************** Get media from form ****************************/
/*****************************************************************************/
static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
struct Media *Media)
{
extern const char Str_BIN_TO_BASE64URL[64 + 1];
char *PtrHost = NULL;
char *PtrPath = NULL;
char *PtrParams = NULL;
char *PtrCode = NULL;
size_t CodeLength;
char *Code;
enum
{
WRONG, // Bad formed YouTube URL
SHORT, // youtu.be
FULL, // www.youtube.com/watch?
EMBED, // www.youtube.com/embed/
} YouTube = WRONG;
/***** Set media status *****/
Media->Status = Med_STATUS_NONE;
/***** Get embed URL from form *****/
Usr_GetURLFromForm (ParamURL,Media);
// Ale_ShowAlert (Ale_INFO,"DEBUG: Media->URL = '%s'",Media->URL);
/***** 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 YouTube URLs:
https://www.youtube.com/watch?v=xu9IbeF9CBw
https://www.youtube.com/watch?v=xu9IbeF9CBw&t=10
https://youtu.be/xu9IbeF9CBw
https://youtu.be/xu9IbeF9CBw?t=10
https://www.youtube.com/embed/xu9IbeF9CBw
https://www.youtube.com/embed/xu9IbeF9CBw?start=10
*/
/***** 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];
else
PtrHost = &Media->URL[0];
if (PtrHost[0])
{
/***** Step 2: Skip host *****/
// Ale_ShowAlert (Ale_INFO,"DEBUG: PtrHost = '%s'",PtrHost);
if (!strncasecmp (PtrHost,"youtu.be/" , 9)) // Host starts by youtu.be/
{
YouTube = SHORT;
PtrPath = &PtrHost[9];
}
else if (!strncasecmp (PtrHost,"www.youtube.com/",16)) // Host starts by www.youtube.com/
{
YouTube = FULL;
PtrPath = &PtrHost[16];
}
else if (!strncasecmp (PtrHost,"youtube.com/" ,12)) // Host starts by youtube.com/
{
YouTube = FULL;
PtrPath = &PtrHost[12];
}
/* Check pointer to path */
if (PtrPath)
{
if (!PtrPath[0])
YouTube = WRONG;
}
else
YouTube = WRONG;
if (YouTube != WRONG)
{
// Ale_ShowAlert (Ale_INFO,"DEBUG: PtrPath = '%s'",PtrPath);
/***** Step 3: Skip path *****/
if (YouTube == FULL)
{
if (!strncasecmp (PtrPath,"watch?",6)) // Path starts by watch?
PtrParams = &PtrPath[6];
else if (!strncasecmp (PtrPath,"embed/",6)) // Path starts by embed/
{
YouTube = EMBED;
PtrParams = &PtrPath[6];
}
else
YouTube = WRONG;
}
else
PtrParams = &PtrPath[0];
/* Check pointer to params */
if (PtrParams)
{
if (!PtrParams[0])
YouTube = WRONG;
}
else
YouTube = WRONG;
if (YouTube != WRONG)
{
// Ale_ShowAlert (Ale_INFO,"DEBUG: PtrParams = '%s'",PtrParams);
/***** Step 4: Search for video code *****/
switch (YouTube)
{
case SHORT:
PtrCode = PtrParams;
break;
case FULL:
/* Search for v= */
PtrCode = strcasestr (PtrPath,"v=");
if (PtrCode)
PtrCode += 2;
break;
case EMBED:
PtrCode = PtrParams;
break;
default:
PtrCode = NULL;
break;
}
/* Check pointer to code */
if (PtrCode)
{
if (!PtrCode[0])
YouTube = WRONG;
}
else
YouTube = WRONG;
if (YouTube != WRONG)
{
// Ale_ShowAlert (Ale_INFO,"DEBUG: PtrCode = '%s'",PtrCode);
/***** Step 5: Get video code *****/
CodeLength = strspn (PtrCode,Str_BIN_TO_BASE64URL);
if (CodeLength > 0)
{
/* Allocate space for YouTube code */
if ((Code = (char *) malloc (CodeLength + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for YouTube code.");
/* Copy code */
strncpy (Code,PtrCode,CodeLength);
Code[CodeLength] = '\0';
// Ale_ShowAlert (Ale_INFO,"DEBUG: Code = '%s'",Code);
/* Overwrite current URL with the embed URL */
Med_FreeMediaURL (Media);
if (asprintf (&Media->URL,"https://www.youtube.com/embed/%s",
Code) < 0)
Lay_NotEnoughMemoryExit ();
if (strlen (Media->URL) <= Cns_MAX_BYTES_WWW)
{
/***** Success! *****/
// Ale_ShowAlert (Ale_INFO,"DEBUG: Media->URL = '%s'",Media->URL);
Media->Type = Med_YOUTUBE;
Media->Status = Med_PROCESSED;
}
else
Med_FreeMediaURL (Media);
/* Free YouTube code */
free ((void *) Code);
}
}
}
}
}
}
}
/*****************************************************************************/ /*****************************************************************************/
/**** Move temporary processed media file to definitive private directory ****/ /**** Move temporary processed media file to definitive private directory ****/
/*****************************************************************************/ /*****************************************************************************/
@ -814,6 +1123,12 @@ void Med_MoveMediaToDefinitiveDir (struct Media *Media)
char PathMedPrivTmp[PATH_MAX + 1]; char PathMedPrivTmp[PATH_MAX + 1];
char PathMedPriv[PATH_MAX + 1]; char PathMedPriv[PATH_MAX + 1];
/***** Check trivial cases *****/
if (Media->Type == Med_TYPE_NONE)
Lay_ShowErrorAndExit ("Wrong media type.");
if (Media->Type == Med_YOUTUBE)
return; // Nothing to do with files
/***** Build temporary path *****/ /***** Build temporary path *****/
snprintf (PathMedPrivTmp,sizeof (PathMedPrivTmp), snprintf (PathMedPrivTmp,sizeof (PathMedPrivTmp),
"%s/%s/%s", "%s/%s/%s",
@ -907,57 +1222,68 @@ void Med_ShowMedia (struct Media *Media,
char PathMedPriv[PATH_MAX + 1]; char PathMedPriv[PATH_MAX + 1];
/***** If no media to show ==> nothing to do *****/ /***** If no media to show ==> nothing to do *****/
if (!Media->Name) if (Media->Status != Med_STORED_IN_DB)
return; return;
if (!Media->Name[0]) if (Media->Type == Med_TYPE_NONE)
return;
if (Media->Type == Med_NONE)
return;
if (Media->Status != Med_NAME_STORED_IN_DB)
return; return;
/***** 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)
fprintf (Gbl.F.Out," MED_VIDEO_CONT");
fprintf (Gbl.F.Out,"\">");
/***** Start optional link to external URL *****/ if (Media->Type == Med_YOUTUBE)
PutLink = false; /***** Show media *****/
if (Media->URL) Med_ShowYoutube (Media,ClassMedia);
if (Media->URL[0]) else // Uploaded file
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 ();
/***** Build path to private directory with the media *****/
snprintf (PathMedPriv,sizeof (PathMedPriv),
"%s/%s/%c%c",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,
Media->Name[0],
Media->Name[1]);
/***** Show media *****/
switch (Media->Type)
{ {
case Med_JPG: /***** If no media to show ==> nothing to do *****/
Med_ShowJPG (Media,PathMedPriv,ClassMedia); if (!Media->Name)
break; return;
case Med_GIF: if (!Media->Name[0])
Med_ShowGIF (Media,PathMedPriv,ClassMedia); return;
break;
case Med_MP4:
case Med_WEBM:
case Med_OGG:
Med_ShowVideo (Media,PathMedPriv,ClassMedia);
break;
default:
break;
}
/***** End optional link to external URL *****/ /***** Start optional link to external URL *****/
if (PutLink) PutLink = false;
fprintf (Gbl.F.Out,"</a>"); 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 ();
/***** Build path to private directory with the media *****/
snprintf (PathMedPriv,sizeof (PathMedPriv),
"%s/%s/%c%c",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,
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;
}
/***** End optional link to external URL *****/
if (PutLink)
fprintf (Gbl.F.Out,"</a>");
}
/***** End media container *****/ /***** End media container *****/
fprintf (Gbl.F.Out,"</div>"); fprintf (Gbl.F.Out,"</div>");
@ -1107,7 +1433,7 @@ static void Med_ShowGIF (struct Media *Media,
} }
/*****************************************************************************/ /*****************************************************************************/
/************************** Show a user uploaded MP4 *************************/ /************************ Show a user uploaded video *************************/
/*****************************************************************************/ /*****************************************************************************/
static void Med_ShowVideo (struct Media *Media, static void Med_ShowVideo (struct Media *Media,
@ -1162,6 +1488,39 @@ static void Med_ShowVideo (struct Media *Media,
fprintf (Gbl.F.Out,"%s",Txt_File_not_found); fprintf (Gbl.F.Out,"%s",Txt_File_not_found);
} }
/*****************************************************************************/
/*************************** Show an embed media *****************************/
/*****************************************************************************/
static void Med_ShowYoutube (struct Media *Media,
const char *ClassMedia)
{
/***** Check if embed URL exists *****/
if (Media->URL[0]) // Embed URL
{
/***** Show linked external media *****/
// Example of code give by YouTube:
// <iframe width="560" height="315"
// src="https://www.youtube.com/embed/xu9IbeF9CBw"
// frameborder="0"
// allow="accelerometer; autoplay; encrypted-media;
// gyroscope; picture-in-picture" allowfullscreen>
// </iframe>
fprintf (Gbl.F.Out,"<iframe src=\"%s\""
" frameborder=\"0\""
" allow=\"accelerometer; autoplay; encrypted-media;"
" gyroscope; picture-in-picture\""
" 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>");
}
}
/*****************************************************************************/ /*****************************************************************************/
/*** Remove private files with an image/video, given the image/video name ****/ /*** Remove private files with an image/video, given the image/video name ****/
/*****************************************************************************/ /*****************************************************************************/
@ -1193,6 +1552,12 @@ void Med_RemoveMediaFiles (const char *Name,Med_Type_t Type)
char PathMedPriv[PATH_MAX + 1]; char PathMedPriv[PATH_MAX + 1];
char FullPathMediaPriv[PATH_MAX + 1]; char FullPathMediaPriv[PATH_MAX + 1];
/***** Trivial cases *****/
if (Type == Med_TYPE_NONE)
Lay_ShowErrorAndExit ("Wrong media type.");
if (Type == Med_YOUTUBE)
return;
/***** 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/%s/%c%c", "%s/%s/%c%c",
@ -1236,8 +1601,7 @@ void Med_RemoveMediaFiles (const char *Name,Med_Type_t Type)
unlink (FullPathMediaPriv); unlink (FullPathMediaPriv);
break; break;
case Med_NONE: default:
Lay_ShowErrorAndExit ("Wrong media type.");
break; break;
} }
@ -1259,7 +1623,7 @@ Med_Type_t Med_GetTypeFromStrInDB (const char *Str)
if (!strcasecmp (Str,Med_StringsTypeDB[Type])) if (!strcasecmp (Str,Med_StringsTypeDB[Type]))
return Type; return Type;
return Med_NONE; return Med_TYPE_NONE;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1317,7 +1681,7 @@ static Med_Type_t Med_GetTypeFromExtAndMIME (const char *Extension,
!strcmp (MIMEType,"application/octet" )) !strcmp (MIMEType,"application/octet" ))
return Med_OGG; return Med_OGG;
return Med_NONE; return Med_TYPE_NONE;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1328,7 +1692,7 @@ const char *Med_GetStringTypeForDB (Med_Type_t Type)
{ {
/***** Check if type is out of valid range *****/ /***** Check if type is out of valid range *****/
if (Type > (Med_Type_t) (Med_NUM_TYPES - 1)) if (Type > (Med_Type_t) (Med_NUM_TYPES - 1))
return Med_StringsTypeDB[Med_NONE]; return Med_StringsTypeDB[Med_TYPE_NONE];
/***** Get string from type *****/ /***** Get string from type *****/
return Med_StringsTypeDB[Type]; return Med_StringsTypeDB[Type];

View File

@ -47,10 +47,10 @@
#define Med_NUM_ACTIONS 4 #define Med_NUM_ACTIONS 4
typedef enum typedef enum
{ {
Med_ACTION_NEW_MEDIA, // Upload new image/video Med_ACTION_NEW_MEDIA, // Upload new media
Med_ACTION_KEEP_MEDIA, // Keep current image/video unchanged Med_ACTION_KEEP_MEDIA, // Keep current media unchanged
Med_ACTION_CHANGE_MEDIA, // Change existing image/video by a new one Med_ACTION_CHANGE_MEDIA, // Change existing media by a new one
Med_ACTION_NO_MEDIA, // Do not use image/video (remove current image/video if exists) Med_ACTION_NO_MEDIA, // Do not use media (remove current media if exists)
} Med_Action_t; } Med_Action_t;
#define Med_ACTION_DEFAULT Med_ACTION_NO_MEDIA #define Med_ACTION_DEFAULT Med_ACTION_NO_MEDIA
@ -81,29 +81,30 @@ xx-unique-name: a unique name encrypted starting by two random chars xx
*/ */
typedef enum typedef enum
{ {
Med_FILE_NONE, Med_STATUS_NONE,
Med_FILE_RECEIVED, Med_RECEIVED,
Med_FILE_PROCESSED, Med_PROCESSED,
Med_FILE_MOVED, Med_FILE_MOVED,
Med_NAME_STORED_IN_DB, Med_STORED_IN_DB,
} Med_FileStatus_t; } Med_Status_t;
#define Med_NUM_TYPES 6 #define Med_NUM_TYPES 7
typedef enum typedef enum
{ {
Med_NONE, Med_TYPE_NONE,
Med_JPG, Med_JPG,
Med_GIF, Med_GIF,
Med_MP4, Med_MP4,
Med_WEBM, Med_WEBM,
Med_OGG, Med_OGG,
Med_YOUTUBE,
} Med_Type_t; } Med_Type_t;
/***** Struct used to get images/videos from forms *****/ /***** Struct used to get images/videos from forms *****/
struct Media struct Media
{ {
Med_Action_t Action; Med_Action_t Action;
Med_FileStatus_t Status; Med_Status_t Status;
char Name[Med_BYTES_NAME + 1]; char Name[Med_BYTES_NAME + 1];
Med_Type_t Type; Med_Type_t Type;
char *Title; // Title/attribution (it must be initialized to NULL char *Title; // Title/attribution (it must be initialized to NULL
@ -120,10 +121,10 @@ struct Media
#define Med_MAX_BYTES_PARAM_UPLOAD_MEDIA (16 - 1) #define Med_MAX_BYTES_PARAM_UPLOAD_MEDIA (16 - 1)
struct ParamUploadMedia struct ParamUploadMedia
{ {
char Action[Med_MAX_BYTES_PARAM_UPLOAD_MEDIA + 1]; char Action [Med_MAX_BYTES_PARAM_UPLOAD_MEDIA + 1];
char File [Med_MAX_BYTES_PARAM_UPLOAD_MEDIA + 1]; char File [Med_MAX_BYTES_PARAM_UPLOAD_MEDIA + 1];
char Title [Med_MAX_BYTES_PARAM_UPLOAD_MEDIA + 1]; char Title [Med_MAX_BYTES_PARAM_UPLOAD_MEDIA + 1];
char URL [Med_MAX_BYTES_PARAM_UPLOAD_MEDIA + 1]; char URL [Med_MAX_BYTES_PARAM_UPLOAD_MEDIA + 1];
}; };
/*****************************************************************************/ /*****************************************************************************/

View File

@ -1282,7 +1282,7 @@ static long Msg_InsertNewMsg (const char *Subject,const char *Content,
/***** Check if image is received and processed *****/ /***** Check if image is received and processed *****/
if (Media->Action == Med_ACTION_NEW_MEDIA && // Upload new image if (Media->Action == Med_ACTION_NEW_MEDIA && // Upload new image
Media->Status == Med_FILE_PROCESSED) // The new image received has been processed Media->Status == Med_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */ /* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (Media); Med_MoveMediaToDefinitiveDir (Media);

View File

@ -67,10 +67,11 @@ static int Str_ReadCharAndSkipCommentsBackward (FILE *FileSrc,Str_SkipHTMLCommen
/***** Conversion to Base64URL *****/ /***** Conversion to Base64URL *****/
// base64url is described in document http://tools.ietf.org/html/rfc4648. // base64url is described in document http://tools.ietf.org/html/rfc4648.
// It uses '-' and '_' because they are safe for URL/parameters (without enconding) and for filenames. // It uses '-' and '_' because they are safe for URL/parameters (without enconding) and for filenames.
const char Str_BIN_TO_BASE64URL[64] = const char Str_BIN_TO_BASE64URL[64 + 1] =
{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'0','1','2','3','4','5','6','7','8','9','-','_'}; '0','1','2','3','4','5','6','7','8','9','-','_',
'\0'}; // NULL-terminated string
static const char Str_LF[2] = {10,0}; static const char Str_LF[2] = {10,0};
static const char Str_CR[2] = {13,0}; static const char Str_CR[2] = {13,0};

View File

@ -6005,7 +6005,7 @@ bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (void)
if ((Gbl.Test.Media.Action == Med_ACTION_NEW_MEDIA || // Upload new image if ((Gbl.Test.Media.Action == Med_ACTION_NEW_MEDIA || // Upload new image
Gbl.Test.Media.Action == Med_ACTION_CHANGE_MEDIA) && // Replace existing image by new image Gbl.Test.Media.Action == Med_ACTION_CHANGE_MEDIA) && // Replace existing image by new image
Gbl.Test.Media.Status != Med_FILE_PROCESSED) Gbl.Test.Media.Status != Med_PROCESSED)
{ {
Ale_ShowAlert (Ale_WARNING,Txt_Error_receiving_or_processing_image); Ale_ShowAlert (Ale_WARNING,Txt_Error_receiving_or_processing_image);
return false; return false;
@ -6187,7 +6187,7 @@ static void Tst_MoveMediaToDefinitiveDirectories (void)
if ((Gbl.Test.Media.Action == Med_ACTION_NEW_MEDIA || // Upload new image if ((Gbl.Test.Media.Action == Med_ACTION_NEW_MEDIA || // Upload new image
Gbl.Test.Media.Action == Med_ACTION_CHANGE_MEDIA) && // Replace existing image by new image Gbl.Test.Media.Action == Med_ACTION_CHANGE_MEDIA) && // Replace existing image by new image
Gbl.Test.Media.Status == Med_FILE_PROCESSED) // The new image received has been processed Gbl.Test.Media.Status == Med_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */ /* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (&Gbl.Test.Media); Med_MoveMediaToDefinitiveDir (&Gbl.Test.Media);
@ -6207,7 +6207,7 @@ static void Tst_MoveMediaToDefinitiveDirectories (void)
if ((Gbl.Test.Answer.Options[NumOpt].Media.Action == Med_ACTION_NEW_MEDIA || // Upload new image if ((Gbl.Test.Answer.Options[NumOpt].Media.Action == Med_ACTION_NEW_MEDIA || // Upload new image
Gbl.Test.Answer.Options[NumOpt].Media.Action == Med_ACTION_CHANGE_MEDIA) && // Replace existing image by new image Gbl.Test.Answer.Options[NumOpt].Media.Action == Med_ACTION_CHANGE_MEDIA) && // Replace existing image by new image
Gbl.Test.Answer.Options[NumOpt].Media.Status == Med_FILE_PROCESSED) // The new image received has been processed Gbl.Test.Answer.Options[NumOpt].Media.Status == Med_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */ /* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (&Gbl.Test.Answer.Options[NumOpt].Media); Med_MoveMediaToDefinitiveDir (&Gbl.Test.Answer.Options[NumOpt].Media);
} }
@ -6560,10 +6560,9 @@ static void Tst_InsertOrUpdateQstIntoDB (void)
Gbl.Test.Media.Title ? Gbl.Test.Media.Title : "", Gbl.Test.Media.Title ? Gbl.Test.Media.Title : "",
Gbl.Test.Media.URL ? Gbl.Test.Media.URL : ""); Gbl.Test.Media.URL ? Gbl.Test.Media.URL : "");
/* Update image status */ /* Update media status */
if (Gbl.Test.Media.Name[0] && if (Gbl.Test.Media.Type != Med_TYPE_NONE)
Gbl.Test.Media.Type != Med_NONE) Gbl.Test.Media.Status = Med_STORED_IN_DB;
Gbl.Test.Media.Status = Med_NAME_STORED_IN_DB;
} }
else // It's an existing question else // It's an existing question
{ {
@ -6586,10 +6585,9 @@ static void Tst_InsertOrUpdateQstIntoDB (void)
Gbl.Test.Media.URL ? Gbl.Test.Media.URL : "", Gbl.Test.Media.URL ? Gbl.Test.Media.URL : "",
Gbl.Test.QstCod,Gbl.CurrentCrs.Crs.CrsCod); Gbl.Test.QstCod,Gbl.CurrentCrs.Crs.CrsCod);
/* Update image status */ /* Update media status */
if (Gbl.Test.Media.Name[0] && if (Gbl.Test.Media.Type != Med_TYPE_NONE)
Gbl.Test.Media.Type != Med_NONE) Gbl.Test.Media.Status = Med_STORED_IN_DB;
Gbl.Test.Media.Status = Med_NAME_STORED_IN_DB;
/* Remove answers and tags from this test question */ /* Remove answers and tags from this test question */
Tst_RemAnsFromQst (); Tst_RemAnsFromQst ();
@ -6661,7 +6659,7 @@ static void Tst_InsertAnswersIntoDB (void)
"'','%s','','','Y')", "'','%s','','','Y')",
Gbl.Test.QstCod, Gbl.Test.QstCod,
Gbl.Test.Answer.Integer, Gbl.Test.Answer.Integer,
Med_GetStringTypeForDB (Med_NONE)); Med_GetStringTypeForDB (Med_TYPE_NONE));
break; break;
case Tst_ANS_FLOAT: case Tst_ANS_FLOAT:
Str_SetDecimalPointToUS (); // To print the floating point as a dot Str_SetDecimalPointToUS (); // To print the floating point as a dot
@ -6677,7 +6675,7 @@ static void Tst_InsertAnswersIntoDB (void)
"'','%s','','','Y')", "'','%s','','','Y')",
Gbl.Test.QstCod,i, Gbl.Test.QstCod,i,
Gbl.Test.Answer.FloatingPoint[i], Gbl.Test.Answer.FloatingPoint[i],
Med_GetStringTypeForDB (Med_NONE)); Med_GetStringTypeForDB (Med_TYPE_NONE));
Str_SetDecimalPointToLocal (); // Return to local system Str_SetDecimalPointToLocal (); // Return to local system
break; break;
case Tst_ANS_TRUE_FALSE: case Tst_ANS_TRUE_FALSE:
@ -6690,7 +6688,7 @@ static void Tst_InsertAnswersIntoDB (void)
"'','%s','','','Y')", "'','%s','','','Y')",
Gbl.Test.QstCod, Gbl.Test.QstCod,
Gbl.Test.Answer.TF, Gbl.Test.Answer.TF,
Med_GetStringTypeForDB (Med_NONE)); Med_GetStringTypeForDB (Med_TYPE_NONE));
break; break;
case Tst_ANS_UNIQUE_CHOICE: case Tst_ANS_UNIQUE_CHOICE:
case Tst_ANS_MULTIPLE_CHOICE: case Tst_ANS_MULTIPLE_CHOICE:
@ -6718,9 +6716,8 @@ static void Tst_InsertAnswersIntoDB (void)
'N'); 'N');
/* Update image status */ /* Update image status */
if (Gbl.Test.Answer.Options[NumOpt].Media.Name[0] && if (Gbl.Test.Answer.Options[NumOpt].Media.Type != Med_TYPE_NONE)
Gbl.Test.Answer.Options[NumOpt].Media.Type != Med_NONE) Gbl.Test.Answer.Options[NumOpt].Media.Status = Med_STORED_IN_DB;
Gbl.Test.Answer.Options[NumOpt].Media.Status = Med_NAME_STORED_IN_DB;
} }
break; break;
default: default:

View File

@ -3569,23 +3569,23 @@ const char *Txt_Change_IDs =
const char *Txt_Change_image = const char *Txt_Change_image =
#if L==1 // ca #if L==1 // ca
"Canviar imatge"; "Canviar imatge / v&iacute;deo";
#elif L==2 // de #elif L==2 // de
"Abbild &auml;ndern"; "Abbild / Video &auml;ndern";
#elif L==3 // en #elif L==3 // en
"Change image"; "Change image / video";
#elif L==4 // es #elif L==4 // es
"Cambiar imagen"; "Cambiar imagen / v&iacute;deo";
#elif L==5 // fr #elif L==5 // fr
"Changer image"; "Changer image / vid&eacute;o";
#elif L==6 // gn #elif L==6 // gn
"Moambue ta'&atilde;nga"; "Moambue ta'&atilde;nga / video";
#elif L==7 // it #elif L==7 // it
"Cambiare immagine"; "Cambiare immagine / video";
#elif L==8 // pl #elif L==8 // pl
"Zmie&nacute; obraz"; "Zmie&nacute; obraz / wideo";
#elif L==9 // pt #elif L==9 // pt
"Alterar imagem"; "Alterar imagem / v&iacute;deo";
#endif #endif
const char *Txt_Change_logo = const char *Txt_Change_logo =
@ -6616,23 +6616,23 @@ const char *Txt_Current_email =
const char *Txt_Current_image = const char *Txt_Current_image =
#if L==1 // ca #if L==1 // ca
"Imatge actual"; "Imatge / v&iacute;deo actual";
#elif L==2 // de #elif L==2 // de
"Aktuelles Abbild"; "Aktuelles Abbild / Video";
#elif L==3 // en #elif L==3 // en
"Current image"; "Current image / video";
#elif L==4 // es #elif L==4 // es
"Imagen actual"; "Imagen / v&iacute;deo actual";
#elif L==5 // fr #elif L==5 // fr
"Image actuelle"; "Image / vid&eacute;o actuelle";
#elif L==6 // gn #elif L==6 // gn
"Imagen actual"; // Okoteve traducción "Imagen / v&iacute;deo actual"; // Okoteve traducción
#elif L==7 // it #elif L==7 // it
"Immagine corrente"; "Immagine / video corrente";
#elif L==8 // pl #elif L==8 // pl
"Bie&zdot;&aogon;cy obraz"; "Bie&zdot;&aogon;cy obraz / wideo";
#elif L==9 // pt #elif L==9 // pt
"Imagem atual"; "Imagem / v&iacute;deo atual";
#endif #endif
const char *Txt_Current_nickname = const char *Txt_Current_nickname =
@ -24650,23 +24650,23 @@ const char *Txt_No_holidays =
const char *Txt_No_image = // Without any image const char *Txt_No_image = // Without any image
#if L==1 // ca #if L==1 // ca
"Sense imatge"; "Sense imatge / v&iacute;deo";
#elif L==2 // de #elif L==2 // de
"Ohne Abbild"; "Ohne Abbild / Video";
#elif L==3 // en #elif L==3 // en
"No image"; "No image / video";
#elif L==4 // es #elif L==4 // es
"Sin imagen"; "Sin imagen / v&iacute;deo";
#elif L==5 // fr #elif L==5 // fr
"Pas d'image"; "Pas d'image / vid&eacute;o";
#elif L==6 // gn #elif L==6 // gn
"Sin imagen"; // Okoteve traducción "Sin imagen / v&iacute;deo"; // Okoteve traducción
#elif L==7 // it #elif L==7 // it
"Nessuna immagine"; "Nessuna immagine / video";
#elif L==8 // pl #elif L==8 // pl
"Brak obrazka"; "Brak obrazka / wideo";
#elif L==9 // pt #elif L==9 // pt
"Sem imagem"; "Sem imagem / v&iacute;deo";
#endif #endif
const char *Txt_No_INDEX = // Short version of "Number" (as an index)... const char *Txt_No_INDEX = // Short version of "Number" (as an index)...

View File

@ -2472,12 +2472,12 @@ static long TL_ReceivePost (void)
Media.Quality = TL_IMAGE_SAVED_QUALITY; Media.Quality = TL_IMAGE_SAVED_QUALITY;
Med_GetMediaFromForm (-1,&Media,NULL); Med_GetMediaFromForm (-1,&Media,NULL);
if (Content[0] || // Text not empty if (Content[0] || // Text not empty
(Media.Name[0] && Media.Type != Med_NONE)) // A media is attached Media.Status == Med_PROCESSED) // A media is attached
{ {
/***** Check if image is received and processed *****/ /***** Check if image is received and processed *****/
if (Media.Action == Med_ACTION_NEW_MEDIA && // Upload new image if (Media.Action == Med_ACTION_NEW_MEDIA && // Upload new image
Media.Status == Med_FILE_PROCESSED) // The new image received has been processed Media.Status == Med_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */ /* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (&Media); Med_MoveMediaToDefinitiveDir (&Media);
@ -2494,10 +2494,8 @@ static long TL_ReceivePost (void)
Content, Content,
Media.Name, Media.Name,
Med_GetStringTypeForDB (Media.Type), Med_GetStringTypeForDB (Media.Type),
(Media.Name[0] && // Save image title only if image attached Media.Title ? Media.Title : "",
Media.Title) ? Media.Title : "", Media.URL ? Media.URL : "");
(Media.Name[0] && // Save image URL only if image attached
Media.URL ) ? Media.URL : "");
/* Insert post in notes */ /* Insert post in notes */
TL_StoreAndPublishNote (TL_NOTE_POST,PstCod,&SocPub); TL_StoreAndPublishNote (TL_NOTE_POST,PstCod,&SocPub);
@ -2655,7 +2653,7 @@ static void TL_WriteCommentsInNote (const struct TL_Note *SocNot)
// Never hide only one comment // Never hide only one comment
// So, the number of comments initially hidden must be 0 or >= 2 // So, the number of comments initially hidden must be 0 or >= 2
NumCommentsInitiallyHidden = (NumComments <= TL_NUM_VISIBLE_COMMENTS + 1) ? 0 : // Show all NumCommentsInitiallyHidden = (NumComments <= TL_NUM_VISIBLE_COMMENTS + 1) ? 0 : // Show all
NumComments - TL_NUM_VISIBLE_COMMENTS; NumComments - TL_NUM_VISIBLE_COMMENTS;
if (NumCommentsInitiallyHidden) if (NumCommentsInitiallyHidden)
{ {
/***** Create unique id for list of hidden comments *****/ /***** Create unique id for list of hidden comments *****/
@ -3200,12 +3198,12 @@ static long TL_ReceiveComment (void)
Media.Quality = TL_IMAGE_SAVED_QUALITY; Media.Quality = TL_IMAGE_SAVED_QUALITY;
Med_GetMediaFromForm (-1,&Media,NULL); Med_GetMediaFromForm (-1,&Media,NULL);
if (Content[0] || // Text not empty if (Content[0] || // Text not empty
(Media.Name[0] && Media.Type != Med_NONE)) // A media is attached Media.Status == Med_PROCESSED) // A media is attached
{ {
/***** Check if image is received and processed *****/ /***** Check if image is received and processed *****/
if (Media.Action == Med_ACTION_NEW_MEDIA && // Upload new image if (Media.Action == Med_ACTION_NEW_MEDIA && // Upload new image
Media.Status == Med_FILE_PROCESSED) // The new image received has been processed Media.Status == Med_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */ /* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (&Media); Med_MoveMediaToDefinitiveDir (&Media);
@ -3228,10 +3226,8 @@ static long TL_ReceiveComment (void)
Content, Content,
Media.Name, Media.Name,
Med_GetStringTypeForDB (Media.Type), Med_GetStringTypeForDB (Media.Type),
(Media.Name[0] && // Save image title only if image attached Media.Title ? Media.Title : "",
Media.Title) ? Media.Title : "", Media.URL ? Media.URL : "");
(Media.Name[0] && // Save image URL only if image attached
Media.URL ) ? Media.URL : "");
/***** Store notifications about the new comment *****/ /***** Store notifications about the new comment *****/
Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_TIMELINE_COMMENT,SocPub.PubCod); Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_TIMELINE_COMMENT,SocPub.PubCod);
@ -5118,6 +5114,7 @@ static void Str_AnalyzeTxtAndStoreNotifyEventToMentionedUsrs (long PubCod,const
{ {
/* Copy nickname */ /* Copy nickname */
strncpy (UsrDat.Nickname,Nickname.PtrStart,Nickname.Length); strncpy (UsrDat.Nickname,Nickname.PtrStart,Nickname.Length);
UsrDat.Nickname[Nickname.Length] = '\0';
if ((UsrDat.UsrCod = Nck_GetUsrCodFromNickname (UsrDat.Nickname)) > 0) if ((UsrDat.UsrCod = Nck_GetUsrCodFromNickname (UsrDat.Nickname)) > 0)
{ {

View File

@ -120,7 +120,7 @@ cp -f /home/acanas/swad/swad/swad /var/www/cgi-bin/
/*****************************************************************************/ /*****************************************************************************/
extern struct Globals Gbl; extern struct Globals Gbl;
extern const char Str_BIN_TO_BASE64URL[64]; extern const char Str_BIN_TO_BASE64URL[64 + 1];
/*****************************************************************************/ /*****************************************************************************/
/***************************** Private constants *****************************/ /***************************** Private constants *****************************/
@ -3452,7 +3452,7 @@ static int Svc_SendMessageToUsr (long OriginalMsgCod,
" ('%s','%s'," " ('%s','%s',"
"'','%s','','')", "'','%s','','')",
Subject,Content, Subject,Content,
Med_GetStringTypeForDB (Med_NONE)); Med_GetStringTypeForDB (Med_TYPE_NONE));
/* Insert message in sent messages */ /* Insert message in sent messages */
DB_QueryINSERT ("can not create message", DB_QueryINSERT ("can not create message",