From 7c4c02fac4dd9848cbc1526c9fb600a238266076 Mon Sep 17 00:00:00 2001 From: Sergio Brighenti Date: Tue, 20 Nov 2018 18:46:39 +0100 Subject: [PATCH] Improved user gallery Improved public view --- app/Controllers/UploadController.php | 31 +++--- app/helpers.php | 67 +++++++++++- bootstrap/app.php | 1 + composer.json | 3 +- composer.lock | 137 +++++++++++++++++++++++- resources/templates/dashboard/home.twig | 32 +++--- resources/templates/upload/public.twig | 31 ++++-- src/css/app.css | 27 ++++- src/js/app.js | 8 +- 9 files changed, 281 insertions(+), 56 deletions(-) diff --git a/app/Controllers/UploadController.php b/app/Controllers/UploadController.php index 66d821a..c0dd2ad 100644 --- a/app/Controllers/UploadController.php +++ b/app/Controllers/UploadController.php @@ -5,6 +5,7 @@ namespace App\Controllers; use App\Exceptions\UnauthorizedException; use App\Web\Session; +use Intervention\Image\ImageManagerStatic as Image; use League\Flysystem\FileExistsException; use League\Flysystem\FileNotFoundException; use League\Flysystem\Filesystem; @@ -89,18 +90,15 @@ class UploadController extends Controller $filesystem = $this->getStorage(); - if (stristr($request->getHeaderLine('User-Agent'), 'TelegramBot') || - stristr($request->getHeaderLine('User-Agent'), 'facebookexternalhit/') || - stristr($request->getHeaderLine('User-Agent'), 'Discordbot/') || - stristr($request->getHeaderLine('User-Agent'), 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Firefox/38.0') || // The discord service bot? - stristr($request->getHeaderLine('User-Agent'), 'Facebot')) { + if (isBot($request->getHeaderLine('User-Agent'))) { return $this->streamMedia($request, $response, $filesystem, $media); } else { try { - $mime = $filesystem->getMimetype($media->storage_path); + $media->mimetype = $filesystem->getMimetype($media->storage_path); + $media->size = humanFileSize($filesystem->getSize($media->storage_path)); - $type = explode('/', $mime)[0]; + $type = explode('/', $media->mimetype)[0]; if ($type === 'text') { $media->text = $filesystem->read($media->storage_path); } else if (in_array($type, ['image', 'video'])) { @@ -119,7 +117,6 @@ class UploadController extends Controller return $this->view->render($response, 'upload/public.twig', [ 'delete_token' => isset($args['token']) ? $args['token'] : null, 'media' => $media, - 'type' => $mime, 'extension' => pathinfo($media->filename, PATHINFO_EXTENSION), ]); } @@ -319,21 +316,17 @@ class UploadController extends Controller if ($request->getParam('width') !== null && explode('/', $mime)[0] === 'image') { - $image = imagecreatefromstring($storage->read($media->storage_path)); - $scaled = imagescale($image, $request->getParam('width'), $request->getParam('height') !== null ? $request->getParam('height') : -1); - imagedestroy($image); - - ob_start(); - imagepng($scaled, null, 9); - - $imagedata = ob_get_contents(); - ob_end_clean(); - imagedestroy($scaled); + $image = Image::make($storage->readStream($media->storage_path)) + ->resizeCanvas( + $request->getParam('width'), + $request->getParam('height'), + 'center') + ->encode('png'); return $response ->withHeader('Content-Type', 'image/png') ->withHeader('Content-Disposition', $disposition . ';filename="scaled-' . pathinfo($media->filename)['filename'] . '.png"') - ->write($imagedata); + ->write($image); } else { ob_end_clean(); return $response diff --git a/app/helpers.php b/app/helpers.php index 5ea30d2..4886edf 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -13,7 +13,7 @@ if (!function_exists('humanFileSize')) { { for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) { } - return round($size, $precision) . ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][$i]; + return round($size, $precision) . ' ' . ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][$i]; } } @@ -77,7 +77,7 @@ if (!function_exists('urlFor')) { * @param string $path * @return string */ - function urlFor(string $path) + function urlFor(string $path): string { global $app; $baseUrl = $app->getContainer()->get('settings')['base_url']; @@ -92,7 +92,7 @@ if (!function_exists('route')) { * @param array $args * @return string */ - function route(string $path, array $args = []) + function route(string $path, array $args = []): string { global $app; $uri = $app->getContainer()->get('router')->pathFor($path, $args); @@ -106,8 +106,67 @@ if (!function_exists('lang')) { * @param array $args * @return string */ - function lang(string $key, $args = []) + function lang(string $key, $args = []): string { return \App\Web\Lang::getInstance()->get($key, $args); } +} + +if (!function_exists('isBot')) { + /** + * @param string $userAgent + * @return boolean + */ + function isBot(string $userAgent) + { + $bots = [ + 'TelegramBot', + 'facebookexternalhit/', + 'Discordbot/', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Firefox/38.0', // The discord service bot? + 'Facebot', + ]; + + foreach ($bots as $bot) { + if (stripos($userAgent, $bot) !== false) { + return true; + } + } + + return false; + } +} + +if (!function_exists('mime2font')) { + function mime2font($mime) + { + $classes = [ + 'image' => 'fa-file-image', + 'audio' => 'fa-file-audio', + 'video' => 'fa-file-video', + 'application/pdf' => 'fa-file-pdf', + 'application/msword' => 'fa-file-word', + 'application/vnd.ms-word' => 'fa-file-word', + 'application/vnd.oasis.opendocument.text' => 'fa-file-word', + 'application/vnd.openxmlformats-officedocument.wordprocessingml' => 'fa-file-word', + 'application/vnd.ms-excel' => 'fa-file-excel', + 'application/vnd.openxmlformats-officedocument.spreadsheetml' => 'fa-file-excel', + 'application/vnd.oasis.opendocument.spreadsheet' => 'fa-file-excel', + 'application/vnd.ms-powerpoint' => 'fa-file-powerpoint', + 'application/vnd.openxmlformats-officedocument.presentationml' => 'fa-file-powerpoint', + 'application/vnd.oasis.opendocument.presentation' => 'fa-file-powerpoint', + 'text/plain' => 'fa-file-alt', + 'text/html' => 'fa-file-code', + 'application/json' => 'fa-file-code', + 'application/gzip' => 'fa-file-archive', + 'application/zip' => 'fa-file-archive', + ]; + + foreach ($classes as $fullMime => $class) { + if (strpos($mime, $fullMime) === 0) { + return $class; + } + } + return 'fa-file'; + } } \ No newline at end of file diff --git a/bootstrap/app.php b/bootstrap/app.php index 964256d..5bdf8b1 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -83,6 +83,7 @@ $container['view'] = function ($container) use (&$config) { $view->getEnvironment()->addFunction(new Twig_Function('route', 'route')); $view->getEnvironment()->addFunction(new Twig_Function('lang', 'lang')); $view->getEnvironment()->addFunction(new Twig_Function('urlFor', 'urlFor')); + $view->getEnvironment()->addFunction(new Twig_Function('mime2font', 'mime2font')); return $view; }; diff --git a/composer.json b/composer.json index 5c177be..e765812 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "sergix44/xbackbone", - "version": "2.2", + "version": "2.3", "description": "A lightweight ShareX PHP backend", "type": "project", "require": { @@ -9,6 +9,7 @@ "slim/twig-view": "^2.4", "league/flysystem": "^1.0.45", "monolog/monolog": "^1.23", + "intervention/image": "^2.4", "ext-json": "*", "ext-gd": "*", "ext-pdo": "*" diff --git a/composer.lock b/composer.lock index 54df080..ce43ee6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "0273ad770ec6dd004ae0d12f9db81ed4", + "content-hash": "61a3ac382bb0960dd8e44736c0be5178", "packages": [ { "name": "container-interop/container-interop", @@ -37,6 +37,141 @@ "homepage": "https://github.com/container-interop/container-interop", "time": "2017-02-14T19:40:03+00:00" }, + { + "name": "guzzlehttp/psr7", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2017-03-20T17:10:46+00:00" + }, + { + "name": "intervention/image", + "version": "2.4.2", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "e82d274f786e3d4b866a59b173f42e716f0783eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/e82d274f786e3d4b866a59b173f42e716f0783eb", + "reference": "e82d274f786e3d4b866a59b173f42e716f0783eb", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.2", + "phpunit/phpunit": "^4.8 || ^5.7" + }, + "suggest": { + "ext-gd": "to use GD library based image processing.", + "ext-imagick": "to use Imagick based image processing.", + "intervention/imagecache": "Caching extension for the Intervention Image library" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + }, + "laravel": { + "providers": [ + "Intervention\\Image\\ImageServiceProvider" + ], + "aliases": { + "Image": "Intervention\\Image\\Facades\\Image" + } + } + }, + "autoload": { + "psr-4": { + "Intervention\\Image\\": "src/Intervention/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@olivervogel.com", + "homepage": "http://olivervogel.com/" + } + ], + "description": "Image handling and manipulation library with support for Laravel integration", + "homepage": "http://image.intervention.io/", + "keywords": [ + "gd", + "image", + "imagick", + "laravel", + "thumbnail", + "watermark" + ], + "time": "2018-05-29T14:19:03+00:00" + }, { "name": "league/flysystem", "version": "1.0.48", diff --git a/resources/templates/dashboard/home.twig b/resources/templates/dashboard/home.twig index bc1bd56..51bf97a 100644 --- a/resources/templates/dashboard/home.twig +++ b/resources/templates/dashboard/home.twig @@ -13,35 +13,33 @@
{% if media.mimetype starts with 'image' %} - - {{ media.filename }} - + Card image {% else %} - -
-
+
{% endif %} -
-

{{ media.filename }} - {{ media.size }} -

-
-
- {% if media.published %} - + {% else %} - + {% endif %} -
- {{ media.timestamp|date("d/m/Y H:i:s") }}
+
{% endfor %} diff --git a/resources/templates/upload/public.twig b/resources/templates/upload/public.twig index 414904b..218b77d 100644 --- a/resources/templates/upload/public.twig +++ b/resources/templates/upload/public.twig @@ -37,7 +37,7 @@ {% endif %} - {% if type starts with 'image' %} + {% if media.mimetype starts with 'image' %}
{{ media.filename }} @@ -48,7 +48,7 @@ {{ media.filename }}
- {% elseif type starts with 'text' %} + {% elseif media.mimetype starts with 'text' %}
{{ media.text }}
@@ -59,24 +59,37 @@ {{ media.filename }}
- {% elseif type starts with 'video' %} -
-