[Media] Fix issues with database file storage
Fixed file quota as well.
There can be more than one file for the same filehash IF the url are different.
Possible states:
- A file with no url and with filename is a local file.
- A file with an url but no filename is a remote file that wasn't fetched,
not even the thumbnail.
- A file with an url and filename is a fetched remote file (maybe just a
thumbnail of it).
- A file with no filename nor url is a redirect.
Routes:
Given these states, updated routes so that an attachment can only be
retrieved by id and a file by filehash.
Major API changes:
File::getByHash now returns a yield of files
Major UI changes:
- Now remote non stored files are presented.
- /view became preferred
- Redirects to remote originals are preferred.
Many other minor bug fixes...
This commit is contained in:
@@ -59,6 +59,69 @@ class File_thumbnail extends Managed_DataObject
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachment's thumbnail record, if any or generate one.
|
||||
*
|
||||
* @param File $file
|
||||
* @param int|null $width Max width of thumbnail in pixels. (if null, use common_config values)
|
||||
* @param int|null $height Max height of thumbnail in pixels. (if null, square-crop to $width)
|
||||
* @param bool $crop Crop to the max-values' aspect ratio
|
||||
* @param bool $force_still Don't allow fallback to showing original (such as animated GIF)
|
||||
* @param bool|null $upscale Whether or not to scale smaller images up to larger thumbnail sizes. (null = site default)
|
||||
*
|
||||
* @return File_thumbnail
|
||||
*
|
||||
* @throws ClientException
|
||||
* @throws FileNotFoundException
|
||||
* @throws FileNotStoredLocallyException
|
||||
* @throws InvalidFilenameException
|
||||
* @throws NoResultException
|
||||
* @throws ServerException on various other errors
|
||||
* @throws UnsupportedMediaException if, despite trying, we can't understand how to make a thumbnail for this format
|
||||
* @throws UseFileAsThumbnailException if the file is considered an image itself and should be itself as thumbnail
|
||||
*/
|
||||
public static function fromFileObject (File $file, ?int $width = null, ?int $height = null, bool $crop = false, bool $force_still = true, ?bool $upscale = null): File_thumbnail
|
||||
{
|
||||
if (is_null($file->filename)) {
|
||||
throw new FileNotFoundException("This remote file has no local thumbnail.");
|
||||
}
|
||||
$image = ImageFile::fromFileObject($file);
|
||||
$imgPath = $image->getPath();
|
||||
$media = common_get_mime_media($file->mimetype);
|
||||
if (Event::handle('CreateFileImageThumbnailSource', [$file, &$imgPath, $media])) {
|
||||
if (!file_exists($imgPath)) {
|
||||
throw new FileNotFoundException($imgPath);
|
||||
}
|
||||
|
||||
// First some mimetype specific exceptions
|
||||
switch ($file->mimetype) {
|
||||
case 'image/svg+xml':
|
||||
throw new UseFileAsThumbnailException($file);
|
||||
}
|
||||
}
|
||||
|
||||
if ($image->animated && !common_config('thumbnail', 'animated')) {
|
||||
// null means "always use file as thumbnail"
|
||||
// false means you get choice between frozen frame or original when calling getThumbnail
|
||||
if (is_null(common_config('thumbnail', 'animated')) || !$force_still) {
|
||||
try {
|
||||
// remote files with animated GIFs as thumbnails will match this
|
||||
return File_thumbnail::byFile($file);
|
||||
} catch (NoResultException $e) {
|
||||
// and if it's not a remote file, it'll be safe to use the locally stored File
|
||||
throw new UseFileAsThumbnailException($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $image->getFileThumbnail(
|
||||
$width,
|
||||
$height,
|
||||
$crop,
|
||||
!is_null($upscale) ? $upscale : common_config('thumbnail', 'upscale')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save oEmbed-provided thumbnail data
|
||||
*
|
||||
@@ -128,8 +191,8 @@ class File_thumbnail extends Managed_DataObject
|
||||
$tn->file_id = $file_id;
|
||||
$tn->url = $url;
|
||||
$tn->filename = $filename;
|
||||
$tn->width = intval($width);
|
||||
$tn->height = intval($height);
|
||||
$tn->width = (int)$width;
|
||||
$tn->height = (int)$height;
|
||||
$tn->insert();
|
||||
return $tn;
|
||||
}
|
||||
@@ -148,30 +211,6 @@ class File_thumbnail extends Managed_DataObject
|
||||
return $dir . $filename;
|
||||
}
|
||||
|
||||
public static function url($filename)
|
||||
{
|
||||
File::tryFilename($filename);
|
||||
|
||||
// FIXME: private site thumbnails?
|
||||
|
||||
$path = common_config('thumbnail', 'path');
|
||||
if (empty($path)) {
|
||||
return File::url('thumb')."/{$filename}";
|
||||
}
|
||||
|
||||
$protocol = (GNUsocial::useHTTPS() ? 'https' : 'http');
|
||||
$server = common_config('thumbnail', 'server') ?: common_config('site', 'server');
|
||||
|
||||
if ($path[mb_strlen($path)-1] != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
if ($path[0] != '/') {
|
||||
$path = '/'.$path;
|
||||
}
|
||||
|
||||
return $protocol.'://'.$server.$path.$filename;
|
||||
}
|
||||
|
||||
public function getFilename()
|
||||
{
|
||||
return File::tryFilename($this->filename);
|
||||
@@ -222,17 +261,11 @@ class File_thumbnail extends Managed_DataObject
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
if (!empty($this->filename) || $this->getFile()->isLocal()) {
|
||||
// A locally stored File, so we can dynamically generate a URL.
|
||||
$url = common_local_url('attachment_thumbnail', array('attachment'=>$this->file_id));
|
||||
if (strpos($url, '?') === false) {
|
||||
$url .= '?';
|
||||
}
|
||||
return $url . http_build_query(array('w'=>$this->width, 'h'=>$this->height));
|
||||
$url = common_local_url('attachment_thumbnail', ['filehash' => $this->getFile()->filehash]);
|
||||
if (strpos($url, '?') === false) {
|
||||
$url .= '?';
|
||||
}
|
||||
|
||||
// No local filename available, return the remote URL we have stored
|
||||
return $this->url;
|
||||
return $url . http_build_query(['w'=>$this->width, 'h'=>$this->height]);
|
||||
}
|
||||
|
||||
public function getHeight()
|
||||
@@ -272,7 +305,7 @@ class File_thumbnail extends Managed_DataObject
|
||||
return parent::delete($useWhere);
|
||||
}
|
||||
|
||||
public function getFile()
|
||||
public function getFile(): File
|
||||
{
|
||||
return File::getByID($this->file_id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user