[Embed] Resize thumbnails fetched by Embed to avoid keeping original images when we need only 128x128. Size configurable in config.php

This commit is contained in:
Miguel Dantas 2019-07-23 11:07:47 +01:00 committed by Diogo Cordeiro
parent ba15724a62
commit 6d552f15b6
4 changed files with 32 additions and 11 deletions

View File

@ -342,7 +342,6 @@ class File extends Managed_DataObject
public static function getSafeExtension(string $filename) { public static function getSafeExtension(string $filename) {
if (preg_match('/^.+?\.([A-Za-z0-9]+)$/', $filename, $matches) === 1) { if (preg_match('/^.+?\.([A-Za-z0-9]+)$/', $filename, $matches) === 1) {
// we matched on a file extension, so let's see if it means something. // we matched on a file extension, so let's see if it means something.
common_debug("MATCHES EXT: " . print_r($matches, true));
$ext = mb_strtolower($matches[1]); $ext = mb_strtolower($matches[1]);
$blacklist = common_config('attachments', 'extblacklist'); $blacklist = common_config('attachments', 'extblacklist');
// If we got an extension from $filename we want to check if it's in a blacklist // If we got an extension from $filename we want to check if it's in a blacklist

View File

@ -372,6 +372,10 @@ class ImageFile extends MediaFile
$box['h'] $box['h']
); );
if ($this->filepath === $outpath) {
@unlink($outpath);
}
$type = $this->preferredType(); $type = $this->preferredType();
switch ($type) { switch ($type) {

View File

@ -256,8 +256,6 @@ class MediaFile
throw new ClientException(_('Blacklisted file extension.')); throw new ClientException(_('Blacklisted file extension.'));
} }
common_debug("EXT: " . print_r($ext, true));
if (!empty($ext)) { if (!empty($ext)) {
// Remove dots if we have them (make sure they're not repeated) // Remove dots if we have them (make sure they're not repeated)
$ext = preg_replace('/^\.+/', '', $ext); $ext = preg_replace('/^\.+/', '', $ext);

View File

@ -53,6 +53,10 @@ class EmbedPlugin extends Plugin
public $append_whitelist = []; // fill this array as domain_whitelist to add more trusted sources public $append_whitelist = []; // fill this array as domain_whitelist to add more trusted sources
public $check_whitelist = false; // security/abuse precaution public $check_whitelist = false; // security/abuse precaution
public $thumbnail_width = 128;
public $thumbnail_height = 128;
public $thumbnail_crop = true;
protected $imgData = []; protected $imgData = [];
/** /**
@ -295,7 +299,7 @@ class EmbedPlugin extends Plugin
$out->elementStart('article', ['class'=>'h-entry embed']); $out->elementStart('article', ['class'=>'h-entry embed']);
$out->elementStart('header'); $out->elementStart('header');
try { try {
$thumb = $file->getThumbnail(128, 128); $thumb = $file->getThumbnail($this->thumbnail_width, $this->thumbnail_height);
$out->element('img', $thumb->getHtmlAttrs(['class'=>'u-photo embed'])); $out->element('img', $thumb->getHtmlAttrs(['class'=>'u-photo embed']));
unset($thumb); unset($thumb);
} catch (FileNotFoundException $e) { } catch (FileNotFoundException $e) {
@ -398,8 +402,8 @@ class EmbedPlugin extends Plugin
} }
try { try {
// If we have proper Embed data, there should be an entry in the File_embed // If we have proper Embed data, there should be an entry in the File_thumbnail table.
// and File_thumbnail tables respectively. If not, we're not going to do anything. // If not, we're not going to do anything.
$thumbnail = File_thumbnail::byFile($file); $thumbnail = File_thumbnail::byFile($file);
} catch (NoResultException $e) { } catch (NoResultException $e) {
// Not Embed data, or at least nothing we either can or want to use. // Not Embed data, or at least nothing we either can or want to use.
@ -466,7 +470,7 @@ class EmbedPlugin extends Plugin
$headers = $head->getHeader(); $headers = $head->getHeader();
$headers = array_change_key_case($headers, CASE_LOWER); $headers = array_change_key_case($headers, CASE_LOWER);
} }
return $headers['content-length'] ?: false; return isset($headers['content-length']) ? $headers['content-length'] : false;
} catch (Exception $err) { } catch (Exception $err) {
common_log(LOG_ERR, __CLASS__.': getRemoteFileSize on URL : '._ve($url). common_log(LOG_ERR, __CLASS__.': getRemoteFileSize on URL : '._ve($url).
' threw exception: '.$err->getMessage()); ' threw exception: '.$err->getMessage());
@ -541,6 +545,8 @@ class EmbedPlugin extends Plugin
)); ));
$imgData = HTTPClient::quickGet($url); $imgData = HTTPClient::quickGet($url);
$info = @getimagesizefromstring($imgData); $info = @getimagesizefromstring($imgData);
// array indexes documented on php.net:
// https://php.net/manual/en/function.getimagesize.php
if ($info === false) { if ($info === false) {
throw new UnsupportedMediaException(_('Remote file format was not identified as an image.'), $url); throw new UnsupportedMediaException(_('Remote file format was not identified as an image.'), $url);
} elseif (!$info[0] || !$info[1]) { } elseif (!$info[0] || !$info[1]) {
@ -548,6 +554,8 @@ class EmbedPlugin extends Plugin
} }
$filehash = hash(File::FILEHASH_ALG, $imgData); $filehash = hash(File::FILEHASH_ALG, $imgData);
$width = min($info[0], $this->thumbnail_width);
$height = min($info[1], $this->thumbnail_height);
try { try {
$original_name = HTTPClient::get_filename($url, $headers); $original_name = HTTPClient::get_filename($url, $headers);
@ -566,6 +574,18 @@ class EmbedPlugin extends Plugin
$url $url
); );
} }
// If the image is not of the desired size, resize it
if ($info[0] !== $this->thumbnail_width || $info[1] !== $this->thumbnail_height) {
// Temporary object, not stored in DB
$img = new ImageFile(-1, $fullpath);
$box = $img->scaleToFit($width, $height, $this->thumbnail_crop);
$outpath = $img->resizeTo($fullpath, $box);
$filename = basename($outpath);
if ($fullpath !== $outpath) {
@unlink($fullpath);
}
}
} else { } else {
throw new AlreadyFulfilledException('A thumbnail seems to already exist for remote file with id==' . throw new AlreadyFulfilledException('A thumbnail seems to already exist for remote file with id==' .
$thumbnail->file_id . ' at path ' . $fullpath); $thumbnail->file_id . ' at path ' . $fullpath);
@ -581,14 +601,14 @@ class EmbedPlugin extends Plugin
} }
try { try {
// Updated our database for the file record // Update our database for the file record
$orig = clone($thumbnail); $orig = clone($thumbnail);
$thumbnail->filename = $filename; $thumbnail->filename = $filename;
$thumbnail->width = $info[0]; // array indexes documented on php.net: $thumbnail->width = $width;
$thumbnail->height = $info[1]; // https://php.net/manual/en/function.getimagesize.php $thumbnail->height = $height;
// Throws exception on failure. // Throws exception on failure.
$thumbnail->updateWithKeys($orig); $thumbnail->updateWithKeys($orig);
} catch (exception $err) { } catch (Exception $err) {
common_log(LOG_ERR, "Went to write a thumbnail entry to the database in " . common_log(LOG_ERR, "Went to write a thumbnail entry to the database in " .
"EmbedPlugin::storeRemoteThumbnail but encountered error: ".$err); "EmbedPlugin::storeRemoteThumbnail but encountered error: ".$err);
return $err; return $err;