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;
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 */
{
width:16px;
height:16px;
margin:0 5px;
margin:5px 20px;
vertical-align:middle;
}
.MED_UPL_FIL /* Upload file */
{
display:none;
}
.MED_UPL_NAM /* Upload filename */
{
color:#808080;
font-size:12pt;
}
.MED_PLAY
{
position:relative;
}
/* The icon inside the overlay is positioned in the middle vertically and horizontally */
.MED_PLAY_ICO
{
@ -2757,6 +2747,25 @@ a:hover img.CENTRE_PHOTO_SHOW
color:white;
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_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;
}
/*****************************************************************************/
/****************************** 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 ***********************/
/*****************************************************************************/
@ -1102,15 +1136,6 @@ function disableDetailedClicks () {
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 *************************/
/*****************************************************************************/

View File

@ -560,7 +560,7 @@ CREATE TABLE IF NOT EXISTS forum_post (
Subject TEXT NOT NULL,
Content LONGTEXT NOT NULL,
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 '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(PstCod),
@ -809,7 +809,7 @@ CREATE TABLE IF NOT EXISTS msg_content (
Subject TEXT NOT NULL,
Content LONGTEXT NOT NULL,
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 '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(MsgCod),
@ -822,7 +822,7 @@ CREATE TABLE IF NOT EXISTS msg_content_deleted (
Subject TEXT NOT NULL,
Content LONGTEXT NOT NULL,
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 '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(MsgCod),
@ -1026,7 +1026,7 @@ CREATE TABLE IF NOT EXISTS social_comments (
PubCod BIGINT NOT NULL,
Content LONGTEXT NOT NULL,
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 '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(PubCod),
@ -1075,7 +1075,7 @@ CREATE TABLE IF NOT EXISTS social_posts (
PstCod INT NOT NULL AUTO_INCREMENT,
Content LONGTEXT NOT NULL,
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 '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '',
UNIQUE INDEX(PstCod),
@ -1204,7 +1204,7 @@ CREATE TABLE IF NOT EXISTS tst_answers (
Answer TEXT NOT NULL,
Feedback TEXT NOT NULL,
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 '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '',
Correct ENUM('N','Y') NOT NULL,
@ -1265,7 +1265,7 @@ CREATE TABLE IF NOT EXISTS tst_questions (
Stem TEXT NOT NULL,
Feedback TEXT NOT NULL,
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 '',
MediaURL VARCHAR(255) NOT NULL DEFAULT '',
NumHits INT NOT NULL DEFAULT 0,

View File

@ -450,10 +450,23 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
#define Log_PLATFORM_VERSION "SWAD 18.76.2 (2019-03-14)"
#define CSS_FILE "swad18.68.3.css"
#define JS_FILE "swad18.75.js"
#define Log_PLATFORM_VERSION "SWAD 18.77 (2019-03-15)"
#define CSS_FILE "swad18.77.css"
#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.1: Mar 13, 2019 Changes in video tag. (239810 lines)
Version 18.76: Mar 13, 2019 Video allowed as multimedia. (239814 lines)

View File

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

View File

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

View File

@ -25,8 +25,10 @@
/*********************************** Headers *********************************/
/*****************************************************************************/
#define _GNU_SOURCE // For strcasestr, asprintf
#include <linux/limits.h> // For PATH_MAX
#include <stdbool.h> // For boolean type
#include <stdio.h> // For asprintf
#include <stdlib.h> // For exit, system, malloc, free, etc
#include <string.h> // For string functions
#include <sys/stat.h> // For lstat
@ -57,6 +59,7 @@ const char *Med_StringsTypeDB[Med_NUM_TYPES] =
"mp4", // Med_MP4
"webm", // Med_WEBM
"ogg", // Med_OGG
"youtube", // Med_YOUTUBE
};
const char *Med_Extensions[Med_NUM_TYPES] =
@ -67,6 +70,7 @@ const char *Med_Extensions[Med_NUM_TYPES] =
"mp4", // Med_MP4
"webm", // Med_WEBM
"ogg", // Med_OGG
"", // Med_YOUTUBE
};
#define Med_MAX_SIZE_GIF (5UL * 1024UL * 1024UL) // 5 MiB
@ -76,6 +80,15 @@ const char *Med_Extensions[Med_NUM_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 ****************/
/*****************************************************************************/
@ -91,8 +104,11 @@ extern struct Globals Gbl;
/*****************************************************************************/
static Med_Action_t Med_GetMediaActionFromForm (const char *ParamAction);
static void Med_GetAndProcessFileFromForm (struct Media *Media,
const char *ParamFile);
static Med_FormType_t Usr_GetFormTypeFromForm (void);
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,
const char PathMedPrivTmp[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],
const char PathFileProcessed[PATH_MAX + 1]);
static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
struct Media *Media);
static bool Med_MoveTmpFileToDefDir (struct Media *Media,
const char PathMedPrivTmp[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,
const char PathMedPriv[PATH_MAX + 1],
const char *ClassMedia);
static void Med_ShowYoutube (struct Media *Media,
const char *ClassMedia);
static Med_Type_t Med_GetTypeFromExtAndMIME (const char *Extension,
const char *MIMEType);
@ -151,9 +172,9 @@ void Med_MediaConstructor (struct Media *Media)
void Med_ResetMediaExceptTitleAndURL (struct Media *Media)
{
Media->Action = Med_ACTION_NO_MEDIA;
Media->Status = Med_FILE_NONE;
Media->Status = Med_STATUS_NONE;
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);
/***** Set status of media file *****/
Media->Status = (Media->Name[0] &&
Media->Type != Med_NONE) ? Med_NAME_STORED_IN_DB :
Med_FILE_NONE;
Media->Status = (Media->Type != Med_TYPE_NONE) ? Med_STORED_IN_DB :
Med_STATUS_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 *****/
// 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,
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)
{
extern const char *Txt_Image_video;
extern const char *Txt_optional;
extern const char *Txt_Title_attribution;
extern const char *Txt_Link;
struct ParamUploadMedia ParamUploadMedia;
@ -274,48 +293,88 @@ void Med_PutMediaUploader (int NumMediaInForm,const char *ClassMediaTitURL)
Frm_SetUniqueId (Id);
/***** 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 *****/
Par_PutHiddenParamUnsigned (ParamUploadMedia.Action,(unsigned) Med_ACTION_NEW_MEDIA);
/***** Media file *****/
fprintf (Gbl.F.Out,"<label class=\"MED_UPL_BUT\">"
"<img src=\"%s/camera.svg\""
" alt=\"%s\" title=\"%s (%s)\""
" class=\"MED_UPL_ICO\" />"
"<input type=\"file\" name=\"%s\""
" accept=\"image/,video/\""
" class=\"MED_UPL_FIL\""
" onchange=\"mediaUploadOnSelectFile (this,'%s');\" />"
"<span id=\"%s_fil\" class=\"MED_UPL_NAM\" />"
"</span>"
"</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;\">",
/***** Upload icon *****/
fprintf (Gbl.F.Out,"<div id=\"%s_ico_upl\"" // <id>_ico_upl
" class=\"MED_UPL_ICO_CON\">"
"<img src=\"%s/file-image.svg\""
" alt=\"%s\" title=\"%s\""
" class=\"MED_UPL_ICO ICO_HIGHLIGHT\""
" onclick=\"mediaActivateUpload('%s');\" />"
"</div>", // <id>_ico_upl
Id,
Gbl.Prefs.URLIcons,
Txt_Image_video,Txt_Image_video,
Id);
fprintf (Gbl.F.Out,"<input type=\"text\" name=\"%s\""
" placeholder=\"%s (%s)\""
" class=\"%s\" maxlength=\"%u\" value=\"\" />",
ParamUploadMedia.Title,
Txt_Title_attribution,Txt_optional,
ClassMediaTitURL,Med_MAX_CHARS_TITLE);
fprintf (Gbl.F.Out,"<br />"
"<input type=\"url\" name=\"%s\""
" placeholder=\"%s (%s)\""
" class=\"%s\" maxlength=\"%u\" value=\"\" />",
/***** Form type *****/
fprintf (Gbl.F.Out,"<input type=\"hidden\""
" id=\"%s_par_upl\"" // <id>_par_upl
" name=\"FormType\" value=\"%u\""
" disabled=\"disabled\" />",
Id,
(unsigned) Med_FORM_FILE);
/***** 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,
Txt_Link,Txt_optional,
Txt_Link,
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 *****/
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))
{
struct ParamUploadMedia ParamUploadMedia;
char Title[Med_MAX_BYTES_TITLE + 1];
char URL[Cns_MAX_BYTES_WWW + 1];
size_t Length;
Med_FormType_t FormType;
/***** Set names of parameters depending on number of media in form *****/
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) *****/
Media->Action = Med_GetMediaActionFromForm (ParamUploadMedia.Action);
Media->Status = Med_FILE_NONE;
Media->Status = Med_STATUS_NONE;
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)
{
case Med_ACTION_NEW_MEDIA: // Upload new image/video
/***** Get new media (if present ==> process and create temporary file) *****/
Med_GetAndProcessFileFromForm (Media,ParamUploadMedia.File);
switch (Media->Status)
/***** Get new media *****/
switch (FormType)
{
case Med_FILE_NONE: // No new image/video received
Media->Action = Med_ACTION_NO_MEDIA;
Media->Name[0] = '\0';
Media->Type = Med_NONE;
case Med_FORM_FILE:
/***** Get image/video (if present ==> process and create temporary file) *****/
Med_GetAndProcessFileFromForm (ParamUploadMedia.File,Media);
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;
case Med_FILE_RECEIVED: // New image/video received, but not processed
Media->Status = Med_FILE_NONE;
Media->Name[0] = '\0';
Media->Type = Med_NONE;
case Med_FORM_EMBED:
/***** Get and process embed URL from form *****/
Med_GetAndProcessEmbedFromForm (ParamUploadMedia.URL,Media);
break;
default:
break;
@ -370,9 +446,29 @@ void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media,
GetMediaFromDB (NumMediaInForm,Media);
break;
case Med_ACTION_CHANGE_MEDIA: // Replace old image/video by new one
/***** Get new image/video (if present ==> process and create temporary file) *****/
Med_GetAndProcessFileFromForm (Media,ParamUploadMedia.File);
if (Media->Status != Med_FILE_PROCESSED && // No new media received-processed successfully
switch (FormType)
{
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)
/* Get media (image/video) name */
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)
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);
}
/*****************************************************************************/
/********************* 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 ****************************/
/*****************************************************************************/
static void Med_GetAndProcessFileFromForm (struct Media *Media,
const char *ParamFile)
static void Med_GetAndProcessFileFromForm (const char *ParamFile,
struct Media *Media)
{
struct Param *Param;
char FileNameImgSrc[PATH_MAX + 1];
@ -478,8 +606,8 @@ static void Med_GetAndProcessFileFromForm (struct Media *Media,
char PathMedPrivTmp[PATH_MAX + 1];
char PathFileOrg[PATH_MAX + 1]; // Full name of original uploaded file
/***** Set media file status *****/
Media->Status = Med_FILE_NONE;
/***** Set media status *****/
Media->Status = Med_STATUS_NONE;
/***** Get filename and MIME type *****/
Param = Fil_StartReceptionOfFile (ParamFile,FileNameImgSrc,MIMEType);
@ -501,7 +629,7 @@ static void Med_GetAndProcessFileFromForm (struct Media *Media,
/* Check extension */
Media->Type = Med_GetTypeFromExtAndMIME (PtrExtension,MIMEType);
if (Media->Type == Med_NONE)
if (Media->Type == Med_TYPE_NONE)
return;
/***** 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
(it may be very big) into a temporary file *****/
Media->Status = Med_FILE_NONE;
Media->Status = Med_STATUS_NONE;
snprintf (PathFileOrg,sizeof (PathFileOrg),
"%s/%s_original.%s",
PathMedPrivTmp,Media->Name,PtrExtension);
if (Fil_EndReceptionOfFile (PathFileOrg,Param)) // Success
{
Media->Status = Med_FILE_RECEIVED;
Media->Status = Med_RECEIVED;
/***** Detect if animated GIF *****/
if (Media->Type == Med_GIF)
@ -626,7 +754,7 @@ static void Med_ProcessJPG (struct Media *Media,
PathMedPrivTmp,Media->Name,Med_Extensions[Med_JPG]);
if (Med_ResizeImage (Media,PathFileOrg,PathFileJPGTmp) == 0) // On success ==> 0 is returned
/* Success */
Media->Status = Med_FILE_PROCESSED;
Media->Status = Med_PROCESSED;
else // Error processing media
{
/* 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);
}
else // Success
Media->Status = Med_FILE_PROCESSED;
Media->Status = Med_PROCESSED;
}
else // Error getting first frame
{
@ -736,7 +864,7 @@ static void Med_ProcessVideo (struct Media *Media,
/* Show error alert */
Ale_ShowAlert (Ale_ERROR,Txt_The_file_could_not_be_processed_successfully);
else // Success
Media->Status = Med_FILE_PROCESSED;
Media->Status = Med_PROCESSED;
}
else // Size exceeded
{
@ -805,6 +933,187 @@ static int Med_GetFirstFrame (const char PathFileOriginal[PATH_MAX + 1],
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 ****/
/*****************************************************************************/
@ -814,6 +1123,12 @@ void Med_MoveMediaToDefinitiveDir (struct Media *Media)
char PathMedPrivTmp[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 *****/
snprintf (PathMedPrivTmp,sizeof (PathMedPrivTmp),
"%s/%s/%s",
@ -907,57 +1222,68 @@ void Med_ShowMedia (struct Media *Media,
char PathMedPriv[PATH_MAX + 1];
/***** If no media to show ==> nothing to do *****/
if (!Media->Name)
if (Media->Status != Med_STORED_IN_DB)
return;
if (!Media->Name[0])
return;
if (Media->Type == Med_NONE)
return;
if (Media->Status != Med_NAME_STORED_IN_DB)
if (Media->Type == Med_TYPE_NONE)
return;
/***** 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 *****/
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 ();
/***** 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)
if (Media->Type == Med_YOUTUBE)
/***** Show media *****/
Med_ShowYoutube (Media,ClassMedia);
else // Uploaded file
{
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;
}
/***** If no media to show ==> nothing to do *****/
if (!Media->Name)
return;
if (!Media->Name[0])
return;
/***** End optional link to external URL *****/
if (PutLink)
fprintf (Gbl.F.Out,"</a>");
/***** 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 ();
/***** 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 *****/
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,
@ -1162,6 +1488,39 @@ static void Med_ShowVideo (struct Media *Media,
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 ****/
/*****************************************************************************/
@ -1193,6 +1552,12 @@ void Med_RemoveMediaFiles (const char *Name,Med_Type_t Type)
char PathMedPriv[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 *****/
snprintf (PathMedPriv,sizeof (PathMedPriv),
"%s/%s/%c%c",
@ -1236,8 +1601,7 @@ void Med_RemoveMediaFiles (const char *Name,Med_Type_t Type)
unlink (FullPathMediaPriv);
break;
case Med_NONE:
Lay_ShowErrorAndExit ("Wrong media type.");
default:
break;
}
@ -1259,7 +1623,7 @@ Med_Type_t Med_GetTypeFromStrInDB (const char *Str)
if (!strcasecmp (Str,Med_StringsTypeDB[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" ))
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 *****/
if (Type > (Med_Type_t) (Med_NUM_TYPES - 1))
return Med_StringsTypeDB[Med_NONE];
return Med_StringsTypeDB[Med_TYPE_NONE];
/***** Get string from type *****/
return Med_StringsTypeDB[Type];

View File

@ -47,10 +47,10 @@
#define Med_NUM_ACTIONS 4
typedef enum
{
Med_ACTION_NEW_MEDIA, // Upload new image/video
Med_ACTION_KEEP_MEDIA, // Keep current image/video unchanged
Med_ACTION_CHANGE_MEDIA, // Change existing image/video by a new one
Med_ACTION_NO_MEDIA, // Do not use image/video (remove current image/video if exists)
Med_ACTION_NEW_MEDIA, // Upload new media
Med_ACTION_KEEP_MEDIA, // Keep current media unchanged
Med_ACTION_CHANGE_MEDIA, // Change existing media by a new one
Med_ACTION_NO_MEDIA, // Do not use media (remove current media if exists)
} Med_Action_t;
#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
{
Med_FILE_NONE,
Med_FILE_RECEIVED,
Med_FILE_PROCESSED,
Med_STATUS_NONE,
Med_RECEIVED,
Med_PROCESSED,
Med_FILE_MOVED,
Med_NAME_STORED_IN_DB,
} Med_FileStatus_t;
Med_STORED_IN_DB,
} Med_Status_t;
#define Med_NUM_TYPES 6
#define Med_NUM_TYPES 7
typedef enum
{
Med_NONE,
Med_TYPE_NONE,
Med_JPG,
Med_GIF,
Med_MP4,
Med_WEBM,
Med_OGG,
Med_YOUTUBE,
} Med_Type_t;
/***** Struct used to get images/videos from forms *****/
struct Media
{
Med_Action_t Action;
Med_FileStatus_t Status;
Med_Status_t Status;
char Name[Med_BYTES_NAME + 1];
Med_Type_t Type;
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)
struct ParamUploadMedia
{
char Action[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 URL [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 Title [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 *****/
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 */
Med_MoveMediaToDefinitiveDir (Media);

View File

@ -67,10 +67,11 @@ static int Str_ReadCharAndSkipCommentsBackward (FILE *FileSrc,Str_SkipHTMLCommen
/***** Conversion to Base64URL *****/
// 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.
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',
'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_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
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);
return false;
@ -6187,7 +6187,7 @@ static void Tst_MoveMediaToDefinitiveDirectories (void)
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.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 */
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
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 */
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.URL ? Gbl.Test.Media.URL : "");
/* Update image status */
if (Gbl.Test.Media.Name[0] &&
Gbl.Test.Media.Type != Med_NONE)
Gbl.Test.Media.Status = Med_NAME_STORED_IN_DB;
/* Update media status */
if (Gbl.Test.Media.Type != Med_TYPE_NONE)
Gbl.Test.Media.Status = Med_STORED_IN_DB;
}
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.QstCod,Gbl.CurrentCrs.Crs.CrsCod);
/* Update image status */
if (Gbl.Test.Media.Name[0] &&
Gbl.Test.Media.Type != Med_NONE)
Gbl.Test.Media.Status = Med_NAME_STORED_IN_DB;
/* Update media status */
if (Gbl.Test.Media.Type != Med_TYPE_NONE)
Gbl.Test.Media.Status = Med_STORED_IN_DB;
/* Remove answers and tags from this test question */
Tst_RemAnsFromQst ();
@ -6661,7 +6659,7 @@ static void Tst_InsertAnswersIntoDB (void)
"'','%s','','','Y')",
Gbl.Test.QstCod,
Gbl.Test.Answer.Integer,
Med_GetStringTypeForDB (Med_NONE));
Med_GetStringTypeForDB (Med_TYPE_NONE));
break;
case Tst_ANS_FLOAT:
Str_SetDecimalPointToUS (); // To print the floating point as a dot
@ -6677,7 +6675,7 @@ static void Tst_InsertAnswersIntoDB (void)
"'','%s','','','Y')",
Gbl.Test.QstCod,i,
Gbl.Test.Answer.FloatingPoint[i],
Med_GetStringTypeForDB (Med_NONE));
Med_GetStringTypeForDB (Med_TYPE_NONE));
Str_SetDecimalPointToLocal (); // Return to local system
break;
case Tst_ANS_TRUE_FALSE:
@ -6690,7 +6688,7 @@ static void Tst_InsertAnswersIntoDB (void)
"'','%s','','','Y')",
Gbl.Test.QstCod,
Gbl.Test.Answer.TF,
Med_GetStringTypeForDB (Med_NONE));
Med_GetStringTypeForDB (Med_TYPE_NONE));
break;
case Tst_ANS_UNIQUE_CHOICE:
case Tst_ANS_MULTIPLE_CHOICE:
@ -6718,9 +6716,8 @@ static void Tst_InsertAnswersIntoDB (void)
'N');
/* Update image status */
if (Gbl.Test.Answer.Options[NumOpt].Media.Name[0] &&
Gbl.Test.Answer.Options[NumOpt].Media.Type != Med_NONE)
Gbl.Test.Answer.Options[NumOpt].Media.Status = Med_NAME_STORED_IN_DB;
if (Gbl.Test.Answer.Options[NumOpt].Media.Type != Med_TYPE_NONE)
Gbl.Test.Answer.Options[NumOpt].Media.Status = Med_STORED_IN_DB;
}
break;
default:

View File

@ -3569,23 +3569,23 @@ const char *Txt_Change_IDs =
const char *Txt_Change_image =
#if L==1 // ca
"Canviar imatge";
"Canviar imatge / v&iacute;deo";
#elif L==2 // de
"Abbild &auml;ndern";
"Abbild / Video &auml;ndern";
#elif L==3 // en
"Change image";
"Change image / video";
#elif L==4 // es
"Cambiar imagen";
"Cambiar imagen / v&iacute;deo";
#elif L==5 // fr
"Changer image";
"Changer image / vid&eacute;o";
#elif L==6 // gn
"Moambue ta'&atilde;nga";
"Moambue ta'&atilde;nga / video";
#elif L==7 // it
"Cambiare immagine";
"Cambiare immagine / video";
#elif L==8 // pl
"Zmie&nacute; obraz";
"Zmie&nacute; obraz / wideo";
#elif L==9 // pt
"Alterar imagem";
"Alterar imagem / v&iacute;deo";
#endif
const char *Txt_Change_logo =
@ -6616,23 +6616,23 @@ const char *Txt_Current_email =
const char *Txt_Current_image =
#if L==1 // ca
"Imatge actual";
"Imatge / v&iacute;deo actual";
#elif L==2 // de
"Aktuelles Abbild";
"Aktuelles Abbild / Video";
#elif L==3 // en
"Current image";
"Current image / video";
#elif L==4 // es
"Imagen actual";
"Imagen / v&iacute;deo actual";
#elif L==5 // fr
"Image actuelle";
"Image / vid&eacute;o actuelle";
#elif L==6 // gn
"Imagen actual"; // Okoteve traducción
"Imagen / v&iacute;deo actual"; // Okoteve traducción
#elif L==7 // it
"Immagine corrente";
"Immagine / video corrente";
#elif L==8 // pl
"Bie&zdot;&aogon;cy obraz";
"Bie&zdot;&aogon;cy obraz / wideo";
#elif L==9 // pt
"Imagem atual";
"Imagem / v&iacute;deo atual";
#endif
const char *Txt_Current_nickname =
@ -24650,23 +24650,23 @@ const char *Txt_No_holidays =
const char *Txt_No_image = // Without any image
#if L==1 // ca
"Sense imatge";
"Sense imatge / v&iacute;deo";
#elif L==2 // de
"Ohne Abbild";
"Ohne Abbild / Video";
#elif L==3 // en
"No image";
"No image / video";
#elif L==4 // es
"Sin imagen";
"Sin imagen / v&iacute;deo";
#elif L==5 // fr
"Pas d'image";
"Pas d'image / vid&eacute;o";
#elif L==6 // gn
"Sin imagen"; // Okoteve traducción
"Sin imagen / v&iacute;deo"; // Okoteve traducción
#elif L==7 // it
"Nessuna immagine";
"Nessuna immagine / video";
#elif L==8 // pl
"Brak obrazka";
"Brak obrazka / wideo";
#elif L==9 // pt
"Sem imagem";
"Sem imagem / v&iacute;deo";
#endif
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;
Med_GetMediaFromForm (-1,&Media,NULL);
if (Content[0] || // Text not empty
(Media.Name[0] && Media.Type != Med_NONE)) // A media is attached
if (Content[0] || // Text not empty
Media.Status == Med_PROCESSED) // A media is attached
{
/***** Check if image is received and processed *****/
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 */
Med_MoveMediaToDefinitiveDir (&Media);
@ -2494,10 +2494,8 @@ static long TL_ReceivePost (void)
Content,
Media.Name,
Med_GetStringTypeForDB (Media.Type),
(Media.Name[0] && // Save image title only if image attached
Media.Title) ? Media.Title : "",
(Media.Name[0] && // Save image URL only if image attached
Media.URL ) ? Media.URL : "");
Media.Title ? Media.Title : "",
Media.URL ? Media.URL : "");
/* Insert post in notes */
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
// So, the number of comments initially hidden must be 0 or >= 2
NumCommentsInitiallyHidden = (NumComments <= TL_NUM_VISIBLE_COMMENTS + 1) ? 0 : // Show all
NumComments - TL_NUM_VISIBLE_COMMENTS;
NumComments - TL_NUM_VISIBLE_COMMENTS;
if (NumCommentsInitiallyHidden)
{
/***** Create unique id for list of hidden comments *****/
@ -3200,12 +3198,12 @@ static long TL_ReceiveComment (void)
Media.Quality = TL_IMAGE_SAVED_QUALITY;
Med_GetMediaFromForm (-1,&Media,NULL);
if (Content[0] || // Text not empty
(Media.Name[0] && Media.Type != Med_NONE)) // A media is attached
if (Content[0] || // Text not empty
Media.Status == Med_PROCESSED) // A media is attached
{
/***** Check if image is received and processed *****/
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 */
Med_MoveMediaToDefinitiveDir (&Media);
@ -3228,10 +3226,8 @@ static long TL_ReceiveComment (void)
Content,
Media.Name,
Med_GetStringTypeForDB (Media.Type),
(Media.Name[0] && // Save image title only if image attached
Media.Title) ? Media.Title : "",
(Media.Name[0] && // Save image URL only if image attached
Media.URL ) ? Media.URL : "");
Media.Title ? Media.Title : "",
Media.URL ? Media.URL : "");
/***** Store notifications about the new comment *****/
Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_TIMELINE_COMMENT,SocPub.PubCod);
@ -5118,6 +5114,7 @@ static void Str_AnalyzeTxtAndStoreNotifyEventToMentionedUsrs (long PubCod,const
{
/* Copy nickname */
strncpy (UsrDat.Nickname,Nickname.PtrStart,Nickname.Length);
UsrDat.Nickname[Nickname.Length] = '\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 const char Str_BIN_TO_BASE64URL[64];
extern const char Str_BIN_TO_BASE64URL[64 + 1];
/*****************************************************************************/
/***************************** Private constants *****************************/
@ -3452,7 +3452,7 @@ static int Svc_SendMessageToUsr (long OriginalMsgCod,
" ('%s','%s',"
"'','%s','','')",
Subject,Content,
Med_GetStringTypeForDB (Med_NONE));
Med_GetStringTypeForDB (Med_TYPE_NONE));
/* Insert message in sent messages */
DB_QueryINSERT ("can not create message",