mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-21 20:48:00 +01:00
Merge branch 'master' into laravel-upgrades
This commit is contained in:
commit
081202e7e2
4 changed files with 166 additions and 38 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -12,3 +12,4 @@ _ide_helper.php
|
|||
resources/views/emails/html
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
/composer.phar
|
||||
|
|
|
@ -145,7 +145,9 @@ class UploadTrackCommand extends CommandBase
|
|||
|
||||
$input = Request::all();
|
||||
$input['track'] = $trackFile;
|
||||
if (!$this->_isReplacingTrack) {
|
||||
|
||||
// Prevent the setting of the cover index for validation
|
||||
if (!$this->_isReplacingTrack && isset($coverFile)) {
|
||||
$input['cover'] = $coverFile;
|
||||
}
|
||||
|
||||
|
@ -159,7 +161,7 @@ class UploadTrackCommand extends CommandBase
|
|||
. 'audio_channels:1,2',
|
||||
];
|
||||
if (!$this->_isReplacingTrack) {
|
||||
array_push($rules, [
|
||||
array_merge($rules, [
|
||||
'cover' => 'image|mimes:png,jpeg|min_width:350|min_height:350',
|
||||
'auto_publish' => 'boolean',
|
||||
'title' => 'string',
|
||||
|
@ -198,6 +200,12 @@ class UploadTrackCommand extends CommandBase
|
|||
$this->_track->source = $this->_customTrackSource ?? $source;
|
||||
$this->_track->save();
|
||||
|
||||
// If the cover was null, and not included, add it back in as null so that
|
||||
// other commands do not encounter a undefined index.
|
||||
if (! isset($input['cover'])) {
|
||||
$input['cover'] = null;
|
||||
}
|
||||
|
||||
if (!$this->_isReplacingTrack) {
|
||||
// Parse any tags in the uploaded files.
|
||||
$parseTagsCommand = new ParseTrackTagsCommand($this->_track, $trackFile, $input);
|
||||
|
|
78
app/Console/Commands/RebuildImages.php
Normal file
78
app/Console/Commands/RebuildImages.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
/**
|
||||
* Pony.fm - A community for pony fan music.
|
||||
* Copyright (C) 2017 Isaac Avram
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Poniverse\Ponyfm\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Poniverse\Ponyfm\Models\Image;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\File\File;
|
||||
|
||||
class RebuildImages extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'rebuild:images';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Resizes all images to fit the specifications in Models/Image';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->info("Regenerating Images");
|
||||
$progressBar = $this->output->createProgressBar(Image::count());
|
||||
|
||||
Image::chunk(1000, function($images) use ($progressBar) {
|
||||
foreach ($images as $image) {
|
||||
try {
|
||||
$image->buildCovers();
|
||||
} catch (FileNotFoundException $e) {
|
||||
$name = $image->filename;
|
||||
$id = $image->id;
|
||||
|
||||
$this->error("Unable to process image $name (id: $id): ".$e->getMessage());
|
||||
}
|
||||
|
||||
$progressBar->advance();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -24,6 +24,8 @@ use External;
|
|||
use Illuminate\Database\Eloquent\Model;
|
||||
use Config;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
|
||||
use Symfony\Component\HttpFoundation\File\File;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
/**
|
||||
|
@ -57,12 +59,14 @@ class Image extends Model
|
|||
const SMALL = 4;
|
||||
|
||||
public static $ImageTypes = [
|
||||
self::NORMAL => ['id' => self::NORMAL, 'name' => 'normal', 'width' => 350, 'height' => 350],
|
||||
self::ORIGINAL => ['id' => self::ORIGINAL, 'name' => 'original', 'width' => null, 'height' => null],
|
||||
self::SMALL => ['id' => self::SMALL, 'name' => 'small', 'width' => 100, 'height' => 100],
|
||||
self::THUMBNAIL => ['id' => self::THUMBNAIL, 'name' => 'thumbnail', 'width' => 50, 'height' => 50]
|
||||
self::NORMAL => ['id' => self::NORMAL, 'name' => 'normal', 'width' => 350, 'height' => 350, 'geometry' => '350'],
|
||||
self::ORIGINAL => ['id' => self::ORIGINAL, 'name' => 'original', 'width' => null, 'height' => null, 'geometry' => null],
|
||||
self::SMALL => ['id' => self::SMALL, 'name' => 'small', 'width' => 100, 'height' => 100, 'geometry' => '100x100^'],
|
||||
self::THUMBNAIL => ['id' => self::THUMBNAIL, 'name' => 'thumbnail', 'width' => 50, 'height' => 50, 'geometry' => '50x50^']
|
||||
];
|
||||
|
||||
const MIME_JPEG = 'image/jpeg';
|
||||
|
||||
public static function getImageTypeFromName($name)
|
||||
{
|
||||
foreach (self::$ImageTypes as $cover) {
|
||||
|
@ -95,17 +99,7 @@ class Image extends Model
|
|||
|
||||
if ($image) {
|
||||
if ($forceReupload) {
|
||||
// delete existing versions of the image
|
||||
$filenames = scandir($image->getDirectory());
|
||||
$imagePrefix = $image->id.'_';
|
||||
|
||||
$filenames = array_filter($filenames, function (string $filename) use ($imagePrefix) {
|
||||
return Str::startsWith($filename, $imagePrefix);
|
||||
});
|
||||
|
||||
foreach ($filenames as $filename) {
|
||||
unlink($image->getDirectory().'/'.$filename);
|
||||
}
|
||||
$image->clearExisting(true);
|
||||
} else {
|
||||
return $image;
|
||||
}
|
||||
|
@ -124,27 +118,7 @@ class Image extends Model
|
|||
|
||||
$image->ensureDirectoryExists();
|
||||
foreach (self::$ImageTypes as $coverType) {
|
||||
if ($coverType['id'] === self::ORIGINAL && $image->mime === 'image/jpeg') {
|
||||
$command = 'cp "'.$file->getPathname().'" '.$image->getFile($coverType['id']);
|
||||
} else {
|
||||
// ImageMagick options reference: http://www.imagemagick.org/script/command-line-options.php
|
||||
$command = 'convert 2>&1 "'.$file->getPathname().'" -background white -alpha remove -alpha off -strip';
|
||||
|
||||
if ($image->mime === 'image/jpeg') {
|
||||
$command .= ' -quality 100 -format jpeg';
|
||||
} else {
|
||||
$command .= ' -quality 95 -format png';
|
||||
}
|
||||
|
||||
if (isset($coverType['width']) && isset($coverType['height'])) {
|
||||
$command .= " -thumbnail ${coverType['width']}x${coverType['height']}^ -gravity center -extent ${coverType['width']}x${coverType['height']}";
|
||||
}
|
||||
|
||||
$command .= ' "'.$image->getFile($coverType['id']).'"';
|
||||
}
|
||||
|
||||
External::execute($command);
|
||||
chmod($image->getFile($coverType['id']), 0644);
|
||||
self::processFile($file, $image->getFile($coverType['id']), $coverType);
|
||||
}
|
||||
|
||||
return $image;
|
||||
|
@ -154,6 +128,37 @@ class Image extends Model
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the image into the specified cover type to the specified path.
|
||||
*
|
||||
* @param File $image The image file to be processed
|
||||
* @param string $path The path to save the processed image file
|
||||
* @param array $coverType The type to process the image to
|
||||
*/
|
||||
private static function processFile(File $image, string $path, $coverType) {
|
||||
if ($coverType['id'] === self::ORIGINAL && $image->getMimeType() === self::MIME_JPEG) {
|
||||
$command = 'cp "'.$image->getPathname().'" '.$path;
|
||||
} else {
|
||||
// ImageMagick options reference: http://www.imagemagick.org/script/command-line-options.php
|
||||
$command = 'convert 2>&1 "'.$image->getPathname().'" -background white -alpha remove -alpha off -strip';
|
||||
|
||||
if ($image->getMimeType() === self::MIME_JPEG) {
|
||||
$command .= ' -quality 100 -format jpeg';
|
||||
} else {
|
||||
$command .= ' -quality 95 -format png';
|
||||
}
|
||||
|
||||
if (isset($coverType['geometry'])) {
|
||||
$command .= " -gravity center -thumbnail ${coverType['geometry']} -extent ${coverType['geometry']}";
|
||||
}
|
||||
|
||||
$command .= ' "'.$path.'"';
|
||||
}
|
||||
|
||||
External::execute($command);
|
||||
chmod($path, 0644);
|
||||
}
|
||||
|
||||
protected $table = 'images';
|
||||
|
||||
public function getUrl($type = self::NORMAL)
|
||||
|
@ -191,4 +196,40 @@ class Image extends Model
|
|||
mkdir($destination, 0777, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes any generated files if they exist
|
||||
* @param bool $includeOriginal Set to true if the original image should be deleted as well.
|
||||
*/
|
||||
public function clearExisting(bool $includeOriginal = false) {
|
||||
$files = scandir($this->getDirectory());
|
||||
$filePrefix = $this->id.'_';
|
||||
$originalName = $filePrefix.Image::$ImageTypes[Image::ORIGINAL]['name'];
|
||||
|
||||
$files = array_filter($files, function($file) use ($originalName, $includeOriginal, $filePrefix) {
|
||||
if (Str::startsWith($file,$originalName) && !$includeOriginal) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return (Str::startsWith($file, $filePrefix));
|
||||
}
|
||||
});
|
||||
|
||||
foreach ($files as $file) {
|
||||
unlink($this->getDirectory().'/'.$file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the cover images for the image, overwriting if needed.
|
||||
*
|
||||
* @throws FileNotFoundException If the original file cannot be found.
|
||||
*/
|
||||
public function buildCovers() {
|
||||
$originalFile = new File($this->getFile(self::ORIGINAL));
|
||||
|
||||
foreach (self::$ImageTypes as $imageType) {
|
||||
self::processFile($originalFile, $this->getFile($imageType['id']), $imageType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue