[MEDIA] Allow thumbnail only entries

This commit is contained in:
Diogo Peralta Cordeiro 2021-02-21 10:35:02 +00:00
parent 4deaaa8dbe
commit 422b82d3be
7 changed files with 69 additions and 39 deletions

View File

@ -74,6 +74,6 @@ class Attachment_thumbnailAction extends Attachment_viewAction
// script execution, and we don't want to have any more errors until then, so don't reset it
@ini_set('display_errors', 0);
common_send_file($filepath, $this->mimetype, $filename, 'inline');
common_send_file($filepath, image_type_to_mime_type(IMAGETYPE_WEBP), $filename, 'inline');
}
}

View File

@ -100,11 +100,15 @@ class File_thumbnail extends Managed_DataObject
case 'image/svg+xml':
throw new UseFileAsThumbnailException($file);
}
} else {
throw new ServerException("This remote file has no local thumbnail.");
}
}
try {
$image = ImageFile::fromFileObject($file);
} catch (InvalidFilenameException $e) {
// Not having an original local file doesn't mean we don't have a thumbnail.
$existing_thumb = File_thumbnail::byFile($file);
$image = new ImageFile($file->getID(), $existing_thumb->getPath(), null, $existing_thumb->url);
}
$imgPath = $image->getPath();
$media = common_get_mime_media($file->mimetype);
if (Event::handle('CreateFileImageThumbnailSource', [$file, &$imgPath, $media])) {
@ -280,7 +284,7 @@ class File_thumbnail extends Managed_DataObject
public function getUrl()
{
$url = common_local_url('attachment_thumbnail', ['filehash' => $this->getFile()->filehash]);
$url = common_local_url('attachment_thumbnail', ['attachment' => $this->getFile()->getID()]);
if (strpos($url, '?') === false) {
$url .= '?';
}

View File

@ -228,10 +228,14 @@ class Router
['action' => 'attachment'],
['attachment' => '[0-9]+']);
// Retrieve thumbnail
$m->connect("thumbnail/:attachment",
['action' => 'attachment_thumbnail'],
['attachment' => '[0-9]+']);
// Retrieve local file
foreach (['/view' => 'attachment_view',
'/download' => 'attachment_download',
'/thumbnail' => 'attachment_thumbnail'] as $postfix => $action) {
'/download' => 'attachment_download'] as $postfix => $action) {
$m->connect("attachment/:filehash{$postfix}",
['action' => $action],
['filehash' => '[A-Za-z0-9._-]{64}']);

View File

@ -57,7 +57,7 @@ class EmbedPlugin extends Plugin
public $thumbnail_width = null;
public $thumbnail_height = null;
public $crop = true;
public $crop = null;
public $max_size = null;
protected $imgData = [];
@ -77,6 +77,7 @@ class EmbedPlugin extends Plugin
$this->thumbnail_width = $this->thumbnail_width ?? common_config('thumbnail', 'width');
$this->thumbnail_height = $this->thumbnail_height ?? common_config('thumbnail', 'height');
$this->max_size = $this->max_size ?? common_config('attachments', 'file_quota');
$this->crop = $this->crop ?? common_config('thumbnail', 'crop');
}
/**
@ -617,7 +618,7 @@ class EmbedPlugin extends Plugin
);
}
$url = $thumbnail->getUrl();
$url = $thumbnail->url; // Important not to use the getter here.
if (substr($url, 0, 7) == 'file://') {
$filename = substr($url, 7);
@ -675,7 +676,7 @@ class EmbedPlugin extends Plugin
}
try {
// Update our database for the file record
// Update our database for the thumbnail record
$orig = clone($thumbnail);
$thumbnail->filename = $filename;
$thumbnail->width = $width;

View File

@ -12,7 +12,7 @@ Settings
* `check_whitelist`: Whether to check the domain_whitelist.
* `thumbnail_width`: Maximum width of the thumbnail in pixels. Defaults to global `[thumbnail][width]`.
* `thumbnail_height`: Maximum height of the thumbnail in pixels. Defaults to global `[thumbnail][height]`.
* `crop`: Crop to the thumbnail size and don't preserve the original file. Defaults to true.
* `crop`: Crop to the size (not preserving aspect ratio). Defaults to global `[thumbnail][crop]`.
* `max_size`: Max media size. Anything bigger than this is rejected. Defaults to global `[attachments][file_quota]`.
Relevant GNU social global settings

View File

@ -17,8 +17,9 @@ domain_whitelist array are accepted for local storage.
* `thumbnail_width`: Maximum width of the thumbnail in pixels. Defaults to global `[thumbnail][width]`.
* `thumbnail_height`: Maximum height of the thumbnail in pixels. Defaults to global `[thumbnail][height]`.
* `crop`: Crop to the thumbnail size and don't preserve the original file. Defaults to false.
* `crop`: Crop to the size (not preserving aspect ratio). Defaults to global `[thumbnail][crop]`.
* `max_size`: Max media size. Anything bigger than this is rejected. Defaults to global `[attachments][file_quota]`.
* `store_original`: Whether to maintain a copy of the original media or only a thumbnail of it. Defaults to false.
Example
=======

View File

@ -41,10 +41,10 @@ class StoreRemoteMediaPlugin extends Plugin
public $append_whitelist = []; // fill this array as domain_whitelist to add more trusted sources
public $check_whitelist = false; // security/abuse precaution
public $store_original = true; // Whether to maintain a copy of the original media or only a thumbnail of it
public $store_original = false; // Whether to maintain a copy of the original media or only a thumbnail of it
public $thumbnail_width = null;
public $thumbnail_height = null;
public $crop = false;
public $crop = null;
public $max_size = null;
protected $imgData = [];
@ -58,12 +58,13 @@ class StoreRemoteMediaPlugin extends Plugin
{
parent::initialize();
$this->domain_whitelist = array_merge($this->domain_whitelist, $this->append_whitelist);
// Load global configuration if specific not provided
$this->thumbnail_width = $this->thumbnail_width ?? common_config('thumbnail', 'width');
$this->thumbnail_height = $this->thumbnail_height ?? common_config('thumbnail', 'height');
$this->max_size = $this->max_size ?? common_config('attachments', 'file_quota');
$this->domain_whitelist = array_merge($this->domain_whitelist, $this->append_whitelist);
$this->crop = $this->crop ?? common_config('thumbnail', 'crop');
}
/**
@ -103,7 +104,7 @@ class StoreRemoteMediaPlugin extends Plugin
// We can move on
}
$url = $file->getUrl();
$url = $file->getUrl(false);
if (substr($url, 0, 7) == 'file://') {
$filename = substr($url, 7);
@ -160,6 +161,7 @@ class StoreRemoteMediaPlugin extends Plugin
}
}
if ($this->store_original) {
try {
// Update our database for the file record
$orig = clone($file);
@ -170,10 +172,28 @@ class StoreRemoteMediaPlugin extends Plugin
// Throws exception on failure.
$file->updateWithKeys($orig);
} catch (Exception $err) {
common_log(LOG_ERR, "Went to update a file entry to the database in " .
"StoreRemoteMediaPlugin::storeRemoteThumbnail but encountered error: ".$err);
common_log(LOG_ERR, "Went to update a file entry on the database in " .
"StoreRemoteMediaPlugin::storeRemoteThumbnail but encountered error: " . $err);
throw $err;
}
} else {
try {
// Insert a thumbnail record for this file
$data = new stdClass();
$data->thumbnail_url = $url;
$data->thumbnail_width = $width;
$data->thumbnail_height = $height;
File_thumbnail::saveNew($data, $file->getID());
$ft = File_thumbnail::byFile($file);
$orig = clone($ft);
$ft->filename = $filename;
$ft->updateWithKeys($orig);
} catch (Exception $err) {
common_log(LOG_ERR, "Went to write a thumbnail entry to the database in " .
"StoreRemoteMediaPlugin::storeRemoteThumbnail but encountered error: " . $err);
throw $err;
}
}
// Out
$imgPath = $file->getPath();
@ -258,15 +278,15 @@ class StoreRemoteMediaPlugin extends Plugin
$original_name = HTTPClient::get_filename($url, $headers);
}
$filename = MediaFile::encodeFilename($original_name ?? _m('Untitled attachment'), $filehash);
$filepath = File::path($filename);
$fullpath = $this->store_original ? File::path($filename) : File_thumbnail::path($filename);
// Write the file to disk. Throw Exception on failure
if (!file_exists($filepath)) {
if (strpos($filepath, INSTALLDIR) !== 0 || file_put_contents($filepath, $imgData) === false) {
if (!file_exists($fullpath)) {
if (strpos($fullpath, INSTALLDIR) !== 0 || file_put_contents($fullpath, $imgData) === false) {
throw new ServerException(_m('Could not write downloaded file to disk.'));
}
if (common_get_mime_media(MediaFile::getUploadedMimeType($filepath)) !== 'image') {
@unlink($filepath);
if (common_get_mime_media(MediaFile::getUploadedMimeType($fullpath)) !== 'image') {
@unlink($fullpath);
throw new UnsupportedMediaException(
_m('Remote file format was not identified as an image.'),
$url
@ -274,9 +294,9 @@ class StoreRemoteMediaPlugin extends Plugin
}
// If the image is not of the desired size, resize it
if ($this->crop && ($info[0] > $this->thumbnail_width || $info[1] > $this->thumbnail_height)) {
if (!$this->store_original && $this->crop && ($info[0] > $this->thumbnail_width || $info[1] > $this->thumbnail_height)) {
// Temporary object, not stored in DB
$img = new ImageFile(-1, $filepath);
$img = new ImageFile(-1, $fullpath);
list($width, $height, $x, $y, $w, $h) = $img->scaleToFit($this->thumbnail_width, $this->thumbnail_height, $this->crop);
// The boundary box for our resizing
@ -288,11 +308,11 @@ class StoreRemoteMediaPlugin extends Plugin
$width = $box['width'];
$height = $box['height'];
$img->resizeTo($filepath, $box);
$img->resizeTo($fullpath, $box);
}
} else {
throw new AlreadyFulfilledException('A thumbnail seems to already exist for remote file' .
($file_id ? 'with id==' . $file_id : '') . ' at path ' . $filepath);
($file_id ? 'with id==' . $file_id : '') . ' at path ' . $fullpath);
}
} catch (AlreadyFulfilledException $e) {
// Carry on