Allow files to be uploaded via URL

Resolves #82.
This commit is contained in:
Trevor Slocum 2020-10-08 11:02:25 -07:00
parent f155e1d4ad
commit 409b91e861
5 changed files with 193 additions and 151 deletions

View File

@ -25,6 +25,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
use Gettext\Translator;
use Gettext\Translations;
@ -62,7 +63,7 @@ if (!file_exists('settings.php')) {
}
require 'settings.php';
if (TINYIB_LOCALE == '') {
if (!defined('TINYIB_LOCALE') || TINYIB_LOCALE == '') {
function __($string) {
return $string;
}
@ -175,9 +176,27 @@ if (!isset($_GET['delete']) && !isset($_GET['manage']) && (isset($_POST['name'])
list($service, $embed) = getEmbed(trim($_POST['embed']));
if (empty($embed) || !isset($embed['html']) || !isset($embed['title']) || !isset($embed['thumbnail_url'])) {
if (!TINYIB_UPLOADVIAURL) {
fancyDie(sprintf(__('Invalid embed URL. Only %s URLs are supported.'), implode('/', array_keys($tinyib_embeds))));
}
$headers = get_headers(trim($_POST['embed']), true);
if (TINYIB_MAXKB > 0 && intval($headers['Content-Length']) > (TINYIB_MAXKB * 1024)) {
fancyDie(sprintf(__('That file is larger than %s.'), TINYIB_MAXKBDESC));
}
$data = url_get_contents(trim($_POST['embed']));
if (strlen($data) == 0) {
fancyDie(__('Failed to download file at specified URL.'));
}
$filepath = 'src/' . time() . substr(microtime(), 2, 3) . rand(1000, 9999) . '.txt';
if (!file_put_contents($filepath, $data)) {
@unlink($filepath);
fancyDie(__('Failed to download file at specified URL.'));
}
$post = attachFile($post, $filepath, basename(parse_url(trim($_POST['embed']), PHP_URL_PATH)), false);
} else {
$post['file_hex'] = $service;
$temp_file = time() . substr(microtime(), 2, 3);
$file_location = "thumb/" . $temp_file;
@ -213,116 +232,11 @@ if (!isset($_GET['delete']) && !isset($_GET['manage']) && (isset($_POST['name'])
$post['file_original'] = cleanString($embed['title']);
$post['file'] = str_ireplace(array('src="https://', 'src="http://'), 'src="//', $embed['html']);
} else if (isset($_FILES['file']) && ($rawpost || !in_array('file', $hide_fields))) {
if ($_FILES['file']['name'] != "") {
}
} else if (isset($_FILES['file']) && $_FILES['file']['name'] != "" && ($rawpost || !in_array('file', $hide_fields))) {
validateFileUpload();
if (!is_file($_FILES['file']['tmp_name']) || !is_readable($_FILES['file']['tmp_name'])) {
fancyDie(__('File transfer failure. Please retry the submission.'));
}
if ((TINYIB_MAXKB > 0) && (filesize($_FILES['file']['tmp_name']) > (TINYIB_MAXKB * 1024))) {
fancyDie(sprintf(__('That file is larger than %s.'), TINYIB_MAXKBDESC));
}
$post['file_original'] = trim(htmlentities(substr($_FILES['file']['name'], 0, 50), ENT_QUOTES));
$post['file_hex'] = md5_file($_FILES['file']['tmp_name']);
$post['file_size'] = $_FILES['file']['size'];
$post['file_size_formatted'] = convertBytes($post['file_size']);
checkDuplicateFile($post['file_hex']);
$file_mime_split = explode(' ', trim(mime_content_type($_FILES['file']['tmp_name'])));
if (count($file_mime_split) > 0) {
$file_mime = strtolower(array_pop($file_mime_split));
} else {
if (!@getimagesize($_FILES['file']['tmp_name'])) {
fancyDie(__('Failed to read the MIME type and size of the uploaded file. Please retry the submission.'));
}
$file_info = getimagesize($_FILES['file']['tmp_name']);
$file_mime = mime_content_type($_FILES['file']['tmp_name']);
}
if (empty($file_mime) || !isset($tinyib_uploads[$file_mime])) {
fancyDie(supportedFileTypes());
}
$file_name = time() . substr(microtime(), 2, 3);
$post['file'] = $file_name . "." . $tinyib_uploads[$file_mime][0];
$file_location = "src/" . $post['file'];
if (!move_uploaded_file($_FILES['file']['tmp_name'], $file_location)) {
fancyDie(__('Could not copy uploaded file.'));
}
if ($_FILES['file']['size'] != filesize($file_location)) {
@unlink($file_location);
fancyDie(__('File transfer failure. Please go back and try again.'));
}
if ($file_mime == "audio/webm" || $file_mime == "video/webm" || $file_mime == "audio/mp4" || $file_mime == "video/mp4") {
$post['image_width'] = max(0, intval(shell_exec('mediainfo --Inform="Video;%Width%" ' . $file_location)));
$post['image_height'] = max(0, intval(shell_exec('mediainfo --Inform="Video;%Height%" ' . $file_location)));
if ($post['image_width'] > 0 && $post['image_height'] > 0) {
list($thumb_maxwidth, $thumb_maxheight) = thumbnailDimensions($post);
$post['thumb'] = $file_name . "s.jpg";
shell_exec("ffmpegthumbnailer -s " . max($thumb_maxwidth, $thumb_maxheight) . " -i $file_location -o thumb/{$post['thumb']}");
$thumb_info = getimagesize("thumb/" . $post['thumb']);
$post['thumb_width'] = $thumb_info[0];
$post['thumb_height'] = $thumb_info[1];
if ($post['thumb_width'] <= 0 || $post['thumb_height'] <= 0) {
@unlink($file_location);
@unlink("thumb/" . $post['thumb']);
fancyDie(__('Sorry, your video appears to be corrupt.'));
}
addVideoOverlay("thumb/" . $post['thumb']);
}
$duration = intval(shell_exec('mediainfo --Inform="General;%Duration%" ' . $file_location));
if ($duration > 0) {
$mins = floor(round($duration / 1000) / 60);
$secs = str_pad(floor(round($duration / 1000) % 60), 2, "0", STR_PAD_LEFT);
$post['file_original'] = "$mins:$secs" . ($post['file_original'] != '' ? (', ' . $post['file_original']) : '');
}
} else if (in_array($file_mime, array('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif', 'application/x-shockwave-flash'))) {
$file_info = getimagesize($file_location);
$post['image_width'] = $file_info[0];
$post['image_height'] = $file_info[1];
}
if (isset($tinyib_uploads[$file_mime][1])) {
$thumbfile_split = explode(".", $tinyib_uploads[$file_mime][1]);
$post['thumb'] = $file_name . "s." . array_pop($thumbfile_split);
if (!copy($tinyib_uploads[$file_mime][1], "thumb/" . $post['thumb'])) {
@unlink($file_location);
fancyDie(__('Could not create thumbnail.'));
}
if ($file_mime == "application/x-shockwave-flash") {
addVideoOverlay("thumb/" . $post['thumb']);
}
} else if (in_array($file_mime, array('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif'))) {
$post['thumb'] = $file_name . "s." . $tinyib_uploads[$file_mime][0];
list($thumb_maxwidth, $thumb_maxheight) = thumbnailDimensions($post);
if (!createThumbnail($file_location, "thumb/" . $post['thumb'], $thumb_maxwidth, $thumb_maxheight)) {
@unlink($file_location);
fancyDie(__('Could not create thumbnail.'));
}
}
if ($post['thumb'] != '') {
$thumb_info = getimagesize("thumb/" . $post['thumb']);
$post['thumb_width'] = $thumb_info[0];
$post['thumb_height'] = $thumb_info[1];
}
}
$post = attachFile($post, $_FILES['file']['tmp_name'], $_FILES['file']['name'], true);
}
if ($post['file'] == '') { // No file uploaded

View File

@ -28,6 +28,9 @@ if (!defined('TINYIB_MAXHOP')) {
if (!defined('TINYIB_THUMBNAIL')) {
define('TINYIB_THUMBNAIL', 'gd');
}
if (!defined('TINYIB_UPLOADVIAURL')) {
define('TINYIB_UPLOADVIAURL', false);
}
if (!defined('TINYIB_NOFILEOK')) {
define('TINYIB_NOFILEOK', false);
}

View File

@ -639,6 +639,126 @@ function getEmbed($url) {
return array('', array());
}
function attachFile($post, $filepath, $filename, $uploaded) {
global $tinyib_uploads;
if (!is_file($filepath) || !is_readable($filepath)) {
@unlink($filepath);
fancyDie(__('File transfer failure. Please retry the submission.'));
}
$filesize = filesize($filepath);
if (TINYIB_MAXKB > 0 && $filesize > (TINYIB_MAXKB * 1024)) {
@unlink($filepath);
fancyDie(sprintf(__('That file is larger than %s.'), TINYIB_MAXKBDESC));
}
$post['file_original'] = trim(htmlentities(substr($filename, 0, 50), ENT_QUOTES));
$post['file_hex'] = md5_file($filepath);
$post['file_size'] = $filesize;
$post['file_size_formatted'] = convertBytes($post['file_size']);
checkDuplicateFile($post['file_hex']);
$file_mime_split = explode(' ', trim(mime_content_type($filepath)));
if (count($file_mime_split) > 0) {
$file_mime = strtolower(array_pop($file_mime_split));
} else {
if (!@getimagesize($filepath)) {
@unlink($filepath);
fancyDie(__('Failed to read the MIME type and size of the uploaded file. Please retry the submission.'));
}
$file_mime = mime_content_type($filepath);
}
if (empty($file_mime) || !isset($tinyib_uploads[$file_mime])) {
fancyDie(supportedFileTypes());
}
$file_name = time() . substr(microtime(), 2, 3);
$post['file'] = $file_name . '.' . $tinyib_uploads[$file_mime][0];
$file_location = 'src/' . $post['file'];
if ($uploaded) {
if (!move_uploaded_file($filepath, $file_location)) {
fancyDie(__('Could not copy uploaded file.'));
}
} else {
if (!rename($filepath, $file_location)) {
@unlink($filepath);
fancyDie(__('Could not copy uploaded file.'));
}
}
if (filesize($file_location) != $filesize) {
@unlink($file_location);
fancyDie(__('File transfer failure. Please go back and try again.'));
}
if ($file_mime == 'audio/webm' || $file_mime == 'video/webm' || $file_mime == 'audio/mp4' || $file_mime == 'video/mp4') {
$post['image_width'] = max(0, intval(shell_exec('mediainfo --Inform="Video;%Width%" ' . $file_location)));
$post['image_height'] = max(0, intval(shell_exec('mediainfo --Inform="Video;%Height%" ' . $file_location)));
if ($post['image_width'] > 0 && $post['image_height'] > 0) {
list($thumb_maxwidth, $thumb_maxheight) = thumbnailDimensions($post);
$post['thumb'] = $file_name . 's.jpg';
shell_exec("ffmpegthumbnailer -s " . max($thumb_maxwidth, $thumb_maxheight) . " -i $file_location -o thumb/{$post['thumb']}");
$thumb_info = getimagesize('thumb/' . $post['thumb']);
$post['thumb_width'] = $thumb_info[0];
$post['thumb_height'] = $thumb_info[1];
if ($post['thumb_width'] <= 0 || $post['thumb_height'] <= 0) {
@unlink($file_location);
@unlink('thumb/' . $post['thumb']);
fancyDie(__('Sorry, your video appears to be corrupt.'));
}
addVideoOverlay('thumb/' . $post['thumb']);
}
$duration = intval(shell_exec('mediainfo --Inform="General;%Duration%" ' . $file_location));
if ($duration > 0) {
$mins = floor(round($duration / 1000) / 60);
$secs = str_pad(floor(round($duration / 1000) % 60), 2, '0', STR_PAD_LEFT);
$post['file_original'] = "$mins:$secs" . ($post['file_original'] != '' ? (', ' . $post['file_original']) : '');
}
} else if (in_array($file_mime, array('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif', 'application/x-shockwave-flash'))) {
$file_info = getimagesize($file_location);
$post['image_width'] = $file_info[0];
$post['image_height'] = $file_info[1];
}
if (isset($tinyib_uploads[$file_mime][1])) {
$thumbfile_split = explode('.', $tinyib_uploads[$file_mime][1]);
$post['thumb'] = $file_name . 's.' . array_pop($thumbfile_split);
if (!copy($tinyib_uploads[$file_mime][1], 'thumb/' . $post['thumb'])) {
@unlink($file_location);
fancyDie(__('Could not create thumbnail.'));
}
if ($file_mime == 'application/x-shockwave-flash') {
addVideoOverlay('thumb/' . $post['thumb']);
}
} else if (in_array($file_mime, array('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif'))) {
$post['thumb'] = $file_name . 's.' . $tinyib_uploads[$file_mime][0];
list($thumb_maxwidth, $thumb_maxheight) = thumbnailDimensions($post);
if (!createThumbnail($file_location, 'thumb/' . $post['thumb'], $thumb_maxwidth, $thumb_maxheight)) {
@unlink($file_location);
fancyDie(__('Could not create thumbnail.'));
}
}
if ($post['thumb'] != '') {
$thumb_info = getimagesize('thumb/' . $post['thumb']);
$post['thumb_width'] = $thumb_info[0];
$post['thumb_height'] = $thumb_info[1];
}
return $post;
}
function installedViaGit() {
return is_dir('.git');
}

View File

@ -189,9 +189,13 @@ EOF;
EOF;
}
if (!empty($tinyib_embeds) && ($raw_post || !in_array('embed', $hide_fields))) {
$embeds_enabled = !empty($tinyib_embeds) && ($raw_post || !in_array('embed', $hide_fields));
if (TINYIB_UPLOADVIAURL || $embeds_enabled) {
$txt_embed = __('Embed');
$txt_embed_help = '';
if ($embeds_enabled) {
$txt_embed_help = __('(paste a YouTube URL)');
}
$embed_input_html = <<<EOF
<tr>
<td class="postblock">
@ -222,7 +226,7 @@ EOF;
$unique_posts = uniquePosts();
if ($unique_posts > 0) {
$unique_posts_html = '<li>' . printf(__('Currently %s unique user posts.'), $unique_posts) . '</li>' . "\n";
$unique_posts_html = '<li>' . sprintf(__('Currently %s unique user posts.'), $unique_posts) . '</li>' . "\n";
}
$output = <<<EOF

View File

@ -75,6 +75,7 @@ $tinyib_embeds = array('SoundCloud' => 'https://soundcloud.com/oembed?format=jso
define('TINYIB_MAXKB', 2048); // Maximum file size in kilobytes [0 to disable]
define('TINYIB_MAXKBDESC', '2 MB'); // Human-readable representation of the maximum file size
define('TINYIB_THUMBNAIL', 'gd'); // Thumbnail method to use: gd / imagemagick (see README for instructions)
define('TINYIB_UPLOADVIAURL', false); // Allow files to be uploaded via URL
define('TINYIB_NOFILEOK', false); // Allow the creation of new threads without uploading a file
// Thumbnail size - new thread