From 4041a57559d63d0711b3d969f7faff3f68163659 Mon Sep 17 00:00:00 2001 From: Trevor Slocum Date: Sat, 5 Jul 2014 12:27:18 -0700 Subject: [PATCH] Add optional SWF support, make picture support optional, add text board mode --- README.md | 4 +-- imgboard.php | 66 ++++++++++++++++++---------------- inc/defines.php | 6 ++++ inc/functions.php | 30 ++++++++++++++++ inc/html.php | 84 ++++++++++++++++++++++++++++++++----------- settings.default.php | 2 ++ swf_thumbnail.png | Bin 0 -> 9000 bytes 7 files changed, 139 insertions(+), 53 deletions(-) create mode 100644 swf_thumbnail.png diff --git a/README.md b/README.md index 79f184e..c298b4f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ For demos see the [TinyIB Installations](https://github.com/tslocum/TinyIB/wiki) Features ------------ - - GIF, JPG, PNG and WebA/WebM upload. + - GIF, JPG, PNG, SWF and WebA/WebM upload. - Reference links >>### - Delete post via password. - Management panel: @@ -33,11 +33,11 @@ Installing - `git clone git://github.com/tslocum/TinyIB.git ./` 4. Copy **settings.default.php** to **settings.php** 5. Configure **settings.php** + - To remove the play icon from .SWF/.WebM thumbnails, delete or rename **video_overlay.png**. - To allow WebA/WebM upload: - Ensure your web host is running Linux. - Install [mediainfo](http://mediaarea.net/en/MediaInfo) and [ffmpegthumbnailer](https://code.google.com/p/ffmpegthumbnailer/). On Ubuntu, run ``sudo apt-get install mediainfo ffmpegthumbnailer``. - Set ``TINYIB_WEBM`` to ``true``. - - To remove the play icon from thumbnails, delete or rename **video_overlay.png**. 6. [CHMOD](http://en.wikipedia.org/wiki/Chmod) write permissions to these directories: - ./ (the directory containing TinyIB) - ./src/ diff --git a/imgboard.php b/imgboard.php index 4ce6fdc..882da8f 100644 --- a/imgboard.php +++ b/imgboard.php @@ -102,6 +102,7 @@ if (isset($_POST['message']) || isset($_POST['file'])) { $post['file_size'] = $_FILES['file']['size']; $post['file_size_formatted'] = convertBytes($post['file_size']); + // Uploaded file type $file_type = strtolower(preg_replace('/.*(\..+)/', '\1', $_FILES['file']['name'])); if ($file_type == '.jpeg') { $file_type = '.jpg'; @@ -110,9 +111,19 @@ if (isset($_POST['message']) || isset($_POST['file'])) { $file_type = '.webm'; } + // Thumbnail type + if ($file_type == '.webm') { + $thumb_type = '.jpg'; + } else if ($file_type == '.swf') { + $thumb_type = '.png'; + } else { + $thumb_type = $file_type; + } + $file_name = time() . substr(microtime(), 2, 3); $post['file'] = $file_name . $file_type; - $post['thumb'] = $file_name . "s" . ($file_type == '.webm' ? '.jpg' : $file_type); + $post['thumb'] = $file_name . "s" . $thumb_type; + $file_location = "src/" . $post['file']; $thumb_location = "thumb/" . $post['thumb']; @@ -136,9 +147,9 @@ if (isset($_POST['message']) || isset($_POST['file'])) { $file_mime = $file_info['mime']; } - if (!($file_mime == "image/jpeg" || $file_mime == "image/gif" || $file_mime == "image/png" || (TINYIB_WEBM && ($file_mime == "video/webm" || $file_mime == "audio/webm")))) { + if (!($file_mime == "image/jpeg" || $file_mime == "image/gif" || $file_mime == "image/png" || (TINYIB_WEBM && ($file_mime == "video/webm" || $file_mime == "audio/webm")) || (TINYIB_SWF && ($file_mime == "application/x-shockwave-flash")))) { @unlink($file_location); - fancyDie("Only " . (TINYIB_WEBM ? "GIF, JPG, PNG, and WEBM" : "GIF, JPG, and PNG") . " files are allowed."); + fancyDie(supportedFileTypes()); } if ($_FILES['file']['size'] != filesize($file_location)) { @@ -175,24 +186,7 @@ if (isset($_POST['message']) || isset($_POST['file'])) { fancyDie("Sorry, your video appears to be corrupt."); } - if (file_exists('video_overlay.png')) { - $thumbnail = imagecreatefromjpeg($thumb_location); - list($width, $height, $type, $attr) = getimagesize($thumb_location); - - $overlay_play = imagecreatefrompng('video_overlay.png'); - imagealphablending($overlay_play, false); - imagesavealpha($overlay_play, true); - list($overlay_width, $overlay_height, $overlay_type, $overlay_attr) = getimagesize('video_overlay.png'); - - $new_thumbnail = imagecreatetruecolor($width, $height); - imagecopyresampled($new_thumbnail, $thumbnail, 0, 0, 0, 0, $width, $height, $width, $height); - imagecopyresampled($new_thumbnail, $overlay_play, ($width / 2) - ($overlay_width / 2), ($height / 2) - ($overlay_height / 2), 0, 0, $overlay_width, $overlay_width, $overlay_width, $overlay_height); - imagejpeg($new_thumbnail, $thumb_location); - - $thumb_info = getimagesize($thumb_location); - $post['thumb_width'] = $thumb_info[0]; - $post['thumb_height'] = $thumb_info[1]; - } + addVideoOverlay($thumb_location); } $duration = intval(shell_exec('mediainfo --Inform="' . ($file_mime == 'video/webm' ? 'Video' : 'Audio') . ';%Duration%" ' . $file_location)); @@ -206,25 +200,35 @@ if (isset($_POST['message']) || isset($_POST['file'])) { $post['image_width'] = $file_info[0]; $post['image_height'] = $file_info[1]; - list($thumb_maxwidth, $thumb_maxheight) = thumbnailDimensions($post); + if ($file_mime == "application/x-shockwave-flash") { + if (!copy('swf_thumbnail.png', $thumb_location)) { + @unlink($file_location); + fancyDie("Could not create thumbnail."); + } - if (!createThumbnail($file_location, $thumb_location, $thumb_maxwidth, $thumb_maxheight)) { - fancyDie("Could not create thumbnail."); + addVideoOverlay($thumb_location); + } else { + list($thumb_maxwidth, $thumb_maxheight) = thumbnailDimensions($post); + + if (!createThumbnail($file_location, $thumb_location, $thumb_maxwidth, $thumb_maxheight)) { + @unlink($file_location); + fancyDie("Could not create thumbnail."); + } } - - $thumb_info = getimagesize($thumb_location); - $post['thumb_width'] = $thumb_info[0]; - $post['thumb_height'] = $thumb_info[1]; } + + $thumb_info = getimagesize($thumb_location); + $post['thumb_width'] = $thumb_info[0]; + $post['thumb_height'] = $thumb_info[1]; } } if ($post['file'] == '') { // No file uploaded - if ($post['parent'] == TINYIB_NEWTHREAD) { - fancyDie("An image is required to start a thread."); + if ($post['parent'] == TINYIB_NEWTHREAD && (TINYIB_PIC || TINYIB_SWF || TINYIB_WEBM)) { + fancyDie("A file is required to start a thread."); } if (str_replace('
', '', $post['message']) == "") { - fancyDie("Please enter a message and/or upload an image to make a reply."); + fancyDie("Please enter a message" . ((TINYIB_PIC || TINYIB_SWF || TINYIB_WEBM) ? " and/or upload a file" : "") . "."); } } else { echo $post['file_original'] . ' uploaded.
'; diff --git a/inc/defines.php b/inc/defines.php index 13959d2..098d8b7 100644 --- a/inc/defines.php +++ b/inc/defines.php @@ -18,6 +18,12 @@ if (!defined('TINYIB_MAXWOP')) { if (!defined('TINYIB_MAXHOP')) { define('TINYIB_MAXHOP', TINYIB_MAXH); } +if (!defined('TINYIB_PIC')) { + define('TINYIB_PIC', true); +} +if (!defined('TINYIB_SWF')) { + define('TINYIB_SWF', false); +} if (!defined('TINYIB_WEBM')) { define('TINYIB_WEBM', false); } diff --git a/inc/functions.php b/inc/functions.php index 984dc8b..b1ea56a 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -374,6 +374,36 @@ function fastImageCopyResampled(&$dst_image, &$src_image, $dst_x, $dst_y, $src_x return true; } +function addVideoOverlay($thumb_location) { + if (file_exists('video_overlay.png')) { + if (substr($thumb_location, -4) == ".jpg") { + $thumbnail = imagecreatefromjpeg($thumb_location); + } else { + $thumbnail = imagecreatefrompng($thumb_location); + } + list($width, $height, $type, $attr) = getimagesize($thumb_location); + + $overlay_play = imagecreatefrompng('video_overlay.png'); + imagealphablending($overlay_play, false); + imagesavealpha($overlay_play, true); + list($overlay_width, $overlay_height, $overlay_type, $overlay_attr) = getimagesize('video_overlay.png'); + + if (substr($thumb_location, -4) == ".png") { + imagecolortransparent($thumbnail, imagecolorallocatealpha($thumbnail, 0, 0, 0, 127)); + imagealphablending($thumbnail, true); + imagesavealpha($thumbnail, true); + } + + imagecopy($thumbnail, $overlay_play, ($width / 2) - ($overlay_width / 2), ($height / 2) - ($overlay_height / 2), 0, 0, $overlay_width, $overlay_height); + + if (substr($thumb_location, -4) == ".jpg") { + imagejpeg($thumbnail, $thumb_location); + } else { + imagepng($thumbnail, $thumb_location); + } + } +} + function strallpos($haystack, $needle, $offset = 0) { $result = array(); for ($i = $offset; $i < strlen($haystack); $i++) { diff --git a/inc/html.php b/inc/html.php index 815cd27..020cc77 100644 --- a/inc/html.php +++ b/inc/html.php @@ -35,6 +35,36 @@ function pageFooter() { EOF; } +function supportedFileTypes() { + $types_allowed = array(); + if (TINYIB_PIC) { + array_push($types_allowed, "GIF", "JPG", "PNG"); + } + if (TINYIB_SWF) { + array_push($types_allowed, "SWF"); + } + if (TINYIB_WEBM) { + array_push($types_allowed, "WebM"); + } + + $i = 0; + $types_count = count($types_allowed); + $types_formatted = ""; + foreach ($types_allowed as $type) { + if (++$i >= $types_count - 1) { + $types_formatted .= $type . ($i == $types_count - 1 && $types_count > 1 ? " and " : ""); + } else { + $types_formatted .= $type . ", "; + } + } + + if ($types_formatted != "") { + return "Supported file type" . ($types_count != 1 ? "s are " : " is ") . $types_formatted . "."; + } + + return $types_formatted; +} + function buildPost($post, $res) { $return = ""; $threadid = ($post['parent'] == TINYIB_NEWTHREAD) ? $post['id'] : $post['parent']; @@ -165,21 +195,42 @@ EOF; $postingmode = '[Return]
Posting mode: Reply
'; } - $filetypes = (TINYIB_WEBM ? "GIF, JPG, PNG, and WEBM" : "GIF, JPG, and PNG"); - + $max_file_size_input_html = ''; + $max_file_size_rules_html = ''; + $filetypes_html = ''; + $file_input_html = ''; $unique_posts_html = ''; + + if (TINYIB_PIC || TINYIB_WEBM || TINYIB_SWF) { + if (TINYIB_MAXKB > 0) { + $max_file_size_input_html = ''; + $max_file_size_rules_html = '
  • Maximum file size allowed is ' . TINYIB_MAXKBDESC . '.
  • '; + } + + $filetypes_html = '
  • ' . supportedFileTypes() . '
  • '; + + $file_input_html = << + + File + + + + + +EOF; + } + + $thumbnails_html = ''; + if (TINYIB_PIC) { + $thumbnails_html = "
  • Images greater than $maxdimensions will be thumbnailed.
  • "; + } + $unique_posts = uniquePosts(); if ($unique_posts > 0) { $unique_posts_html = "
  • Currently $unique_posts unique user posts.
  • \n"; } - $max_file_size_input = ''; - $max_file_size_html = ''; - if (TINYIB_MAXKB > 0) { - $max_file_size_input_html = ''; - $max_file_size_rules_html = '
  • Maximum file size allowed is ' . TINYIB_MAXKBDESC . '.
  • '; - } - $body = <<
    @@ -193,7 +244,7 @@ EOF; $postingmode
    - $max_file_size_input + $max_file_size_input_html @@ -230,14 +281,7 @@ EOF; - - - - + $file_input_html diff --git a/settings.default.php b/settings.default.php index 658e7eb..b8fe2e8 100644 --- a/settings.default.php +++ b/settings.default.php @@ -8,6 +8,8 @@ define('TINYIB_PREVIEWREPLIES', 3); // Amount of replies previewed on index page define('TINYIB_MAXREPLIES', 0); // Maximum replies before a thread stops bumping [0 to disable] 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_PIC', true); // Enable .jpg, .png and .gif image file upload +define('TINYIB_SWF', false); // Enable .swf Flash file upload define('TINYIB_WEBM', false); // Enable .weba and .webm audio/video file upload (see README for instructions) define('TINYIB_MAXW', 250); // Maximum image width (reply) - Images exceeding these sizes will be thumbnailed define('TINYIB_MAXH', 250); // Maximum image height (reply) diff --git a/swf_thumbnail.png b/swf_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..d56c2084e414651c7fc9bc1baa1ba1b955e78f85 GIT binary patch literal 9000 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 C?2noN literal 0 HcmV?d00001
    - File - - -
    Password @@ -249,9 +293,9 @@ EOF;
      -
    • Supported file types are $filetypes.
    • + $filetypes_html $max_file_size_rules_html -
    • Images greater than $maxdimensions will be thumbnailed.
    • + $thumbnails_html $unique_posts_html