[Media] Document recently added settings and add some more

Fix some buggy ones, especially Embed crop
This commit is contained in:
Diogo Peralta Cordeiro 2021-02-19 12:10:37 +00:00
parent 5e3fa2bba1
commit ee872b5e44
6 changed files with 93 additions and 46 deletions

View File

@ -679,7 +679,7 @@ set too low (it's optional, so it may not be there at all).
* `file_quota`: maximum size for a single file upload in bytes. A user can send * `file_quota`: maximum size for a single file upload in bytes. A user can send
any amount of notices with attachments as long as each attachment any amount of notices with attachments as long as each attachment
is smaller than file_quota. is smaller than file_quota. Defaults to PHP's configured upload limit.
* `user_quota`: total size in bytes a user can store on this server. Each user * `user_quota`: total size in bytes a user can store on this server. Each user
can store any number of files as long as their total size does can store any number of files as long as their total size does
@ -717,6 +717,28 @@ set too low (it's optional, so it may not be there at all).
* `filename_base`: for new files, choose one: 'upload', 'hash'. Defaults to hash. * `filename_base`: for new files, choose one: 'upload', 'hash'. Defaults to hash.
* `memory_limit`: PHP's memory limit to use temporarily when handling images. Defaults to `1024M`.
* `prefer_remote`: when a user uploads a file, if the first time this file was
retrieved was from an URL, prefer redirect to the attachment with the first known URL.
thumbnail
-------------------------------------------------------------------------------
The software lets users upload media with their notes. You can configure
the way thumbnails are generated for them.
* `dir`: Where to store, defaults to `File::path('thumb')` (equivalent to `['attachments']['dir']/thumb/`).
* `path`: URL path, relative to the server, to find thumbnails. Defaults to `File::url('thumb/$filename')` (equivalent to `['attachments']['path']/thumb/`).
* `server`: Only used if `['thumbnail']['path']` is NOT empty. In which case it defaults to `['site']['server']`, schema is decided from `GNUsocial::useHTTPS()`
* `crop`: Crop to the size (not preserving aspect ratio). Defaults to false.
* `maxsize`: Thumbs with an edge larger than this will not be generated. Defaults to 1000.
* `width`: Max width for the thumbnail. Defaults to 450.
* `height`: Max height for the thumbnail. Defaults to 600.
* `upscale`: Whether or not to scale smaller images up to larger thumbnail sizes. Defaults to false.
* `animated`: `null` means use file as thumbnail. `false` means that a still frame can be used. `true` requires `ImageMagickPlugin`. Defaults to false.
group group
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View File

@ -450,12 +450,22 @@ class MediaFile
return MediaFile::fromFileObject($file); return MediaFile::fromFileObject($file);
} }
} }
var_dump($file);die; // Assert: If we got to this line, then we only traversed URLs on the while loop above.
// If no exception is thrown then this file was already uploaded by a local actor once, so we'll use that and just add redirections. if (common_config('attachments', 'prefer_remote')) {
// but if the _actual_ locally stored file doesn't exist, getPath will throw FileNotFoundException // Was this file imported from a remote source already?
$filepath = $file->getPath(); $filepath = $file->getPath(); // This function will throw FileNotFoundException if not.
// Assert: If we got to this line, then we can use this file and just add redirections.
$mimetype = $file->mimetype; $mimetype = $file->mimetype;
$fileid = $file->getID(); $fileid = $file->getID();
} else {
throw new FileNotFoundException('This isn\'t a path.'); // A bit of dadaist art.
// It's natural that a sysadmin prefers to not add redirections to the first remote link of an
// attachment, it's not a very consistent thing to do. On the other hand, lack of space can drive
// a person crazy.
// Also note that if one configured StoreRemoteMedia to not save original images (very likely), then
// having prefer_remote enabled will never store the original attachment (sort of the idea here).
}
} catch (FileNotFoundException | NoResultException $e) { } catch (FileNotFoundException | NoResultException $e) {
// We have to save the upload as a new local file. This is the normal course of action. // We have to save the upload as a new local file. This is the normal course of action.
if ($scoped instanceof Profile) { if ($scoped instanceof Profile) {

View File

@ -55,9 +55,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_width = null;
public $thumbnail_height = 128; public $thumbnail_height = null;
public $thumbnail_crop = true; public $crop = true;
public $max_size = null;
protected $imgData = []; protected $imgData = [];
@ -71,6 +72,11 @@ class EmbedPlugin extends Plugin
parent::initialize(); parent::initialize();
$this->domain_whitelist = array_merge($this->domain_whitelist, $this->append_whitelist); $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');
} }
/** /**
@ -563,15 +569,21 @@ class EmbedPlugin extends Plugin
} }
// If the image is not of the desired size, resize it // If the image is not of the desired size, resize it
if ($info[0] > $this->thumbnail_width || $info[1] > $this->thumbnail_height) { if ($this->crop && ($info[0] > $this->thumbnail_width || $info[1] > $this->thumbnail_height)) {
// Temporary object, not stored in DB // Temporary object, not stored in DB
$img = new ImageFile(-1, $fullpath); $img = new ImageFile(-1, $fullpath);
$box = $img->scaleToFit($this->thumbnail_width, $this->thumbnail_height, $this->thumbnail_crop); list($width, $height, $x, $y, $w, $h) = $img->scaleToFit($this->thumbnail_width, $this->thumbnail_height, $this->crop);
$outpath = $img->resizeTo($fullpath, $box);
$filename = basename($outpath); // The boundary box for our resizing
if ($fullpath !== $outpath) { $box = [
@unlink($fullpath); 'width' => $width, 'height' => $height,
} 'x' => $x, 'y' => $y,
'w' => $w, 'h' => $h,
];
$width = $box['width'];
$height = $box['height'];
$img->resizeTo($fullpath, $box);
} }
} else { } else {
throw new AlreadyFulfilledException('A thumbnail seems to already exist for remote file' . throw new AlreadyFulfilledException('A thumbnail seems to already exist for remote file' .
@ -622,11 +634,10 @@ class EmbedPlugin extends Plugin
try { try {
$is_image = $this->isRemoteImage($url, $headers); $is_image = $this->isRemoteImage($url, $headers);
if ($is_image == true) { if ($is_image == true) {
$max_size = common_get_preferred_php_upload_limit();
$file_size = $this->getRemoteFileSize($url, $headers); $file_size = $this->getRemoteFileSize($url, $headers);
if (($file_size!=false) && ($file_size > $max_size)) { if (($file_size!=false) && ($file_size > $this->max_size)) {
common_debug("Went to store remote thumbnail of size " . $file_size . common_debug("Went to store remote thumbnail of size " . $file_size .
" but the upload limit is " . $max_size . " so we aborted."); " but the upload limit is " . $this->max_size . " so we aborted.");
return false; return false;
} }
} else { } else {

View File

@ -8,11 +8,17 @@ This plugin is enabled by default.
Settings Settings
======== ========
width: Maximum width of the thumbnail in pixels. * `domain_whitelist`: Array of regular expressions. Always escape your dots and end your strings.
height: Maximum height of the thumbnail in pixels. * `check_whitelist`: Whether to check the domain_whitelist.
show_html: Whether to show HTML oEmbed data. * `thumbnail_width`: Maximum width of the thumbnail in pixels. Defaults to global `[thumbnail][width]`.
domain_whitelist: Array of regular expressions. Always escape your dots and end your strings. * `thumbnail_height`: Maximum height of the thumbnail in pixels. Defaults to global `[thumbnail][height]`.
check_whitelist: Whether to check the domain_whitelist. * `crop`: Crop to the thumbnail size and don't preserve the original file. Defaults to true.
* `max_size`: Max media size. Anything bigger than this is rejected. Defaults to global `[attachments][file_quota]`.
Relevant GNU social global settings
===================================
* `[attachments][show_html]`: Whether to show HTML oEmbed data.
Example Example
======= =======

View File

@ -9,14 +9,17 @@ to the bottom of your config.php
Settings Settings
======== ========
domain_whitelist: Array of regular expressions. Always escape your dots and end your strings. * `domain_whitelist`: Array of regular expressions. Always escape your dots and end your strings.
check_whitelist: Whether to check the domain_whitelist. * `check_whitelist`: Whether to check the domain_whitelist.
max_size: Max media size. Anything bigger than this is rejected. 10MiB by default.
When check_whitelist is set, only images from URLs matching a regex in the When check_whitelist is set, only images from URLs matching a regex in the
domain_whitelist array are accepted for local storage. 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.
* `max_size`: Max media size. Anything bigger than this is rejected. Defaults to global `[attachments][file_quota]`.
Example Example
======= =======

View File

@ -41,10 +41,11 @@ class StoreRemoteMediaPlugin 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 $store_original = true; // Whether to maintain a copy of the original media or only a thumbnail of it
public $thumbnail_width = null; public $thumbnail_width = null;
public $thumbnail_height = 128; public $thumbnail_height = null;
public $thumbnail_crop = true; public $crop = false;
public $max_size = 10 * 1024 * 1024; // 10MiB max image size by default public $max_size = null;
protected $imgData = []; protected $imgData = [];
@ -57,12 +58,10 @@ class StoreRemoteMediaPlugin extends Plugin
{ {
parent::initialize(); parent::initialize();
if (is_null($this->thumbnail_width)) { // Load global configuration if specific not provided
$this->thumbnail_width = common_config('thumbnail', 'width'); $this->thumbnail_width = $this->thumbnail_width ?? common_config('thumbnail', 'width');
$this->thumbnail_height = common_config('thumbnail', 'height'); $this->thumbnail_height = $this->thumbnail_height ?? common_config('thumbnail', 'height');
$this->thumbnail_crop = common_config('thumbnail', 'crop'); $this->max_size = $this->max_size ?? common_config('attachments', 'file_quota');
$this->max_size = common_get_preferred_php_upload_limit();
}
$this->domain_whitelist = array_merge($this->domain_whitelist, $this->append_whitelist); $this->domain_whitelist = array_merge($this->domain_whitelist, $this->append_whitelist);
} }
@ -275,14 +274,10 @@ class StoreRemoteMediaPlugin extends Plugin
} }
// If the image is not of the desired size, resize it // If the image is not of the desired size, resize it
if ($info[0] > $this->thumbnail_width || $info[1] > $this->thumbnail_height) { if ($this->crop && ($info[0] > $this->thumbnail_width || $info[1] > $this->thumbnail_height)) {
// Temporary object, not stored in DB // Temporary object, not stored in DB
$img = new ImageFile(-1, $filepath); $img = new ImageFile(-1, $filepath);
// Get proper aspect ratio width and height before lookup list($width, $height, $x, $y, $w, $h) = $img->scaleToFit($this->thumbnail_width, $this->thumbnail_height, $this->crop);
// We have to do it through an ImageFile object because of orientation etc.
// Only other solution would've been to rotate + rewrite uploaded files
// which we don't want to do because we like original, untouched data!
list($width, $height, $x, $y, $w, $h) = $img->scaleToFit($this->thumbnail_width, $this->thumbnail_height, $this->thumbnail_crop);
// The boundary box for our resizing // The boundary box for our resizing
$box = [ $box = [