bug fixes
This commit is contained in:
@@ -3,35 +3,24 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enum\HttpResponseCodes;
|
||||
use App\Jobs\MediaJob;
|
||||
use App\Jobs\MediaWorkerJob;
|
||||
use App\Jobs\MoveMediaJob;
|
||||
use App\Jobs\StoreUploadedFileJob;
|
||||
use App\Traits\Uuids;
|
||||
use Exception;
|
||||
use FFMpeg\Coordinate\TimeCode;
|
||||
use FFMpeg\FFMpeg;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\InvalidCastException;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Intervention\Image\Exception\NotSupportedException;
|
||||
use Intervention\Image\Exception\NotWritableException;
|
||||
use ImagickException;
|
||||
use Intervention\Image\Facades\Image;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use SplFileInfo;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class Media extends Model
|
||||
@@ -59,7 +48,6 @@ class Media extends Model
|
||||
'description',
|
||||
'name',
|
||||
'size',
|
||||
'status',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -367,7 +355,7 @@ class Media extends Model
|
||||
public function moveToStorage(string $storage): void
|
||||
{
|
||||
if ($storage !== $this->storage && Config::has("filesystems.disks.$storage") === true) {
|
||||
$this->status = "Processing media";
|
||||
// $this->status = "Processing media";
|
||||
MoveMediaJob::dispatch($this, $storage)->onQueue('media');
|
||||
$this->save();
|
||||
}
|
||||
@@ -376,36 +364,26 @@ class Media extends Model
|
||||
/**
|
||||
* Transform the media through the Media Job Queue
|
||||
*
|
||||
* @param array $transform The transform data.
|
||||
* @param boolean $silent Update the medium progress through its status field.
|
||||
* @return void
|
||||
* @param array $transform The transform data.
|
||||
* @return MediaJob
|
||||
*/
|
||||
public function transform(array $transform, bool $silent = false): void
|
||||
public function transform(array $transform): MediaJob
|
||||
{
|
||||
foreach ($transform as $key => $value) {
|
||||
if (is_string($value) === true) {
|
||||
if (preg_match('/^rotate-(-?\d+)$/', $value, $matches) !== false) {
|
||||
unset($transform[$key]);
|
||||
$transform['rotate'] = $matches[1];
|
||||
} elseif (preg_match('/^flip-([vh]|vh|hv)$/', $value, $matches) !== false) {
|
||||
unset($transform[$key]);
|
||||
$transform['flip'] = $matches[1];
|
||||
} elseif (preg_match('/^crop-(\d+)-(\d+)$/', $value, $matches) !== false) {
|
||||
unset($transform[$key]);
|
||||
$transform['crop'] = ['width' => $matches[1], 'height' => $matches[2]];
|
||||
} elseif (preg_match('/^crop-(\d+)-(\d+)-(\d+)-(\d+)$/', $value, $matches) !== false) {
|
||||
unset($transform[$key]);
|
||||
$transform['crop'] = ['width' => $matches[1], 'height' => $matches[2], 'x' => $matches[3], 'y' => $matches[4]];
|
||||
}
|
||||
}
|
||||
}
|
||||
$mediaJob = new MediaJob([
|
||||
'media_id' => $this->media,
|
||||
'user_id' => auth()->user()?->id,
|
||||
'data' => json_encode(['transform' => $transform]),
|
||||
]);
|
||||
|
||||
try {
|
||||
MediaJob::dispatch($this, $transform, $silent)->onQueue('media');
|
||||
MediaWorkerJob::dispatch($mediaJob)->onQueue('media');
|
||||
return $mediaJob;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Failed to transform media');
|
||||
throw $e;
|
||||
}//end try
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -498,8 +476,8 @@ class Media extends Model
|
||||
|
||||
if (
|
||||
static::fileNameHasSuffix($fileName) === true ||
|
||||
static::fileExistsInStorage("$fileName.$extension") === true ||
|
||||
Media::where('name', "$fileName.$extension")->where('status', 'not like', 'failed%')->exists() === true
|
||||
static::fileExistsInStorage("$fileName.$extension") === true //||
|
||||
// Media::where('name', "$fileName.$extension")->where('status', 'not like', 'failed%')->exists() === true
|
||||
) {
|
||||
$fileName .= '-';
|
||||
for ($i = 1; $i < $maxTries; $i++) {
|
||||
@@ -507,7 +485,7 @@ class Media extends Model
|
||||
if (
|
||||
static::fileExistsInStorage("$fileNameIndex.$extension") !== true &&
|
||||
Media::where('name', "$fileNameIndex.$extension")
|
||||
->where('status', 'not like', 'Failed%')
|
||||
// ->where('status', 'not like', 'Failed%')
|
||||
->exists() !== true
|
||||
) {
|
||||
return "$fileNameIndex.$extension";
|
||||
@@ -721,32 +699,34 @@ class Media extends Model
|
||||
*/
|
||||
public function saveStagingFile(bool $delete = true, bool $silent = false): void
|
||||
{
|
||||
if (strlen($this->storage) > 0 && strlen($this->name) > 0) {
|
||||
if (Storage::disk($this->storage)->exists($this->name) === true) {
|
||||
Storage::disk($this->storage)->delete($this->name);
|
||||
if ($this->stagingFilePath !== '') {
|
||||
if (strlen($this->storage) > 0 && strlen($this->name) > 0) {
|
||||
if (Storage::disk($this->storage)->exists($this->name) === true) {
|
||||
Storage::disk($this->storage)->delete($this->name);
|
||||
}
|
||||
|
||||
/** @var Illuminate\Filesystem\FilesystemAdapter */
|
||||
$fileSystem = Storage::disk($this->storage);
|
||||
// if ($silent === false) {
|
||||
// $this->status('Uploading to CDN');
|
||||
// }
|
||||
$fileSystem->putFileAs('/', $this->stagingFilePath, $this->name);
|
||||
}
|
||||
|
||||
/** @var Illuminate\Filesystem\FilesystemAdapter */
|
||||
$fileSystem = Storage::disk($this->storage);
|
||||
if ($silent === false) {
|
||||
$this->status('Uploading to CDN');
|
||||
// if ($silent === false) {
|
||||
// $this->status('Generating Thumbnail');
|
||||
// }
|
||||
$this->generateThumbnail();
|
||||
|
||||
// if ($silent === false) {
|
||||
// $this->status('Generating Variants');
|
||||
// }
|
||||
$this->generateVariants();
|
||||
|
||||
if ($delete === true) {
|
||||
$this->deleteStagingFile();
|
||||
}
|
||||
$fileSystem->putFileAs('/', $this->stagingFilePath, $this->name);
|
||||
}
|
||||
|
||||
if ($silent === false) {
|
||||
$this->status('Generating Thumbnail');
|
||||
}
|
||||
$this->generateThumbnail();
|
||||
|
||||
if ($silent === false) {
|
||||
$this->status('Generating Variants');
|
||||
}
|
||||
$this->generateVariants();
|
||||
|
||||
if ($delete === true) {
|
||||
$this->deleteStagingFile();
|
||||
}
|
||||
}//end if
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -777,6 +757,16 @@ class Media extends Model
|
||||
$this->stagingFilePath = $newFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a staging file present
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasStagingFile(): bool
|
||||
{
|
||||
return $this->stagingFilePath !== "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Thumbnail for this media.
|
||||
*
|
||||
@@ -1019,7 +1009,7 @@ class Media extends Model
|
||||
*/
|
||||
public function ok(): void
|
||||
{
|
||||
$this->status = "OK";
|
||||
// $this->status = "OK";
|
||||
$this->save();
|
||||
}
|
||||
|
||||
@@ -1030,7 +1020,7 @@ class Media extends Model
|
||||
*/
|
||||
public function error(string $error = ""): void
|
||||
{
|
||||
$this->status = "Error" . ($error !== "" ? ": {$error}" : "");
|
||||
// $this->status = "Error" . ($error !== "" ? ": {$error}" : "");
|
||||
$this->save();
|
||||
}
|
||||
|
||||
@@ -1041,7 +1031,7 @@ class Media extends Model
|
||||
*/
|
||||
public function status(string $status = ""): void
|
||||
{
|
||||
$this->status = "Info: " . $status;
|
||||
// $this->status = "Info: " . $status;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,73 +13,147 @@ class MediaJob extends Model
|
||||
use HasFactory;
|
||||
use Uuids;
|
||||
|
||||
public function setStatusFailed(string $statusText = ''): void {
|
||||
|
||||
/**
|
||||
* The default attributes.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $attributes = [
|
||||
'user_id' => null,
|
||||
'media_id' => null,
|
||||
'status' => '',
|
||||
'status_text' => '',
|
||||
'progress' => 0,
|
||||
'data' => '',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Set MediaJob status to failed.
|
||||
*
|
||||
* @param string $statusText The failed reason.
|
||||
* @return void
|
||||
*/
|
||||
public function setStatusFailed(string $statusText = ''): void
|
||||
{
|
||||
$this->setStatus('failed', $statusText, 0);
|
||||
}
|
||||
|
||||
public function setStatusQueued(): void {
|
||||
/**
|
||||
* Set MediaJob status to queued.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setStatusQueued(): void
|
||||
{
|
||||
$this->setStatus('queued', '', 0);
|
||||
}
|
||||
|
||||
public function setStatusWaiting(): void {
|
||||
/**
|
||||
* Set MediaJob status to waiting.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setStatusWaiting(): void
|
||||
{
|
||||
$this->setStatus('waiting', '', 0);
|
||||
}
|
||||
|
||||
public function setStatusProcessing(int $progress = 0, string $statusText = ''): void {
|
||||
if($statusText === '') {
|
||||
/**
|
||||
* Set MediaJob status to processing.
|
||||
*
|
||||
* @param integer $progress The processing percentage.
|
||||
* @param string $statusText The processing status text.
|
||||
* @return void
|
||||
*/
|
||||
public function setStatusProcessing(int $progress = 0, string $statusText = ''): void
|
||||
{
|
||||
if ($statusText === '') {
|
||||
$statusText = $this->status_text;
|
||||
}
|
||||
|
||||
$this->setStatus('processing', $statusText, $progress);
|
||||
}
|
||||
|
||||
public function setStatusComplete(): void {
|
||||
/**
|
||||
* Set MediaJob status to complete.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setStatusComplete(): void
|
||||
{
|
||||
$this->setStatus('complete');
|
||||
}
|
||||
|
||||
public function setStatusInvalid(): void {
|
||||
$this->setStatus('invalid');
|
||||
/**
|
||||
* Set MediaJon status to invalid.
|
||||
*
|
||||
* @param string $text The status text.
|
||||
* @return void
|
||||
*/
|
||||
public function setStatusInvalid(string $text = ''): void
|
||||
{
|
||||
$this->setStatus('invalid', $text);
|
||||
}
|
||||
|
||||
public function setStatus(string $status, string $text = '', int $progress = 0): void {
|
||||
/**
|
||||
* Set MediaJob status details.
|
||||
*
|
||||
* @param string $status The status string.
|
||||
* @param string $text The status text.
|
||||
* @param integer $progress The status percentage.
|
||||
* @return void
|
||||
*/
|
||||
protected function setStatus(string $status, string $text = '', int $progress = 0): void
|
||||
{
|
||||
$this->status = $status;
|
||||
$this->status_text = $text;
|
||||
$this->progress = $progress;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the MediaJob.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(): void
|
||||
{
|
||||
$data = json_decode($this->data, true);
|
||||
if($data !== null) {
|
||||
if(array_key_exists('chunks', $data) === true) {
|
||||
if(array_key_exists('chunk_count', $data) === false || array_key_exists('name', $data) === false) {
|
||||
$this->setStatusInvalid();
|
||||
if ($data !== null) {
|
||||
if (array_key_exists('chunks', $data) === true) {
|
||||
if (array_key_exists('chunk_count', $data) === false) {
|
||||
$this->setStatusInvalid('chunk_count is missing');
|
||||
return;
|
||||
}
|
||||
|
||||
if (array_key_exists('name', $data) === false) {
|
||||
$this->setStatusInvalid('name is missing');
|
||||
return;
|
||||
}
|
||||
|
||||
$numChunks = count($data['chunks']);
|
||||
$maxChunks = intval($data['chunk_count']);
|
||||
if($numChunks >= $maxChunks) {
|
||||
if ($numChunks >= $maxChunks) {
|
||||
// merge file and dispatch
|
||||
$percentage = 0;
|
||||
$percentageStep = 100 / $maxChunks;
|
||||
$percentageStep = (100 / $maxChunks);
|
||||
$this->setStatusProcessing($percentage, 'combining chunks');
|
||||
|
||||
$newFile = generateTempFilePath(pathinfo($data['name'], PATHINFO_EXTENSION));
|
||||
$failed = false;
|
||||
|
||||
for($index = 1; $index <= $maxChunks; $index++) {
|
||||
if(array_key_exists($index, $data['chunks']) === false) {
|
||||
$failed = true;
|
||||
|
||||
for ($index = 1; $index <= $maxChunks; $index++) {
|
||||
if (array_key_exists($index, $data['chunks']) === false) {
|
||||
$failed = `{$index} chunk is missing`;
|
||||
} else {
|
||||
$tempFileName = $data['chunks'][$index];
|
||||
|
||||
if($failed === false) {
|
||||
if ($failed === false) {
|
||||
$chunkContents = file_get_contents($tempFileName);
|
||||
if($chunkContents === false) {
|
||||
$failed = true;
|
||||
if ($chunkContents === false) {
|
||||
$failed = `{$index} chunk is empty`;
|
||||
} else {
|
||||
file_put_contents($newFile, $chunkContents, FILE_APPEND);
|
||||
}
|
||||
@@ -93,67 +167,29 @@ class MediaJob extends Model
|
||||
unset($data['chunks']);
|
||||
$this->data = json_encode($data);
|
||||
|
||||
if($failed === false) {
|
||||
$this->setStatusInvalid();
|
||||
if ($failed !== false) {
|
||||
$this->setStatusInvalid($failed);
|
||||
} else {
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$mime = finfo_file($finfo, $newFile);
|
||||
finfo_close($finfo);
|
||||
|
||||
$data['file']['path'] = $newFile;
|
||||
$data['file']['size'] = filesize($newFile);
|
||||
$data['file']['mime_type'] = $mime;
|
||||
|
||||
|
||||
$data['file'] = $newFile;
|
||||
$data['size'] = filesize($newFile);
|
||||
$data['mime_type'] = $mime;
|
||||
|
||||
$this->data = json_encode($data);
|
||||
$this->setStatusQueued();
|
||||
MediaWorkerJob::dispatch($this);
|
||||
MediaWorkerJob::dispatch($this)->onQueue('media');
|
||||
}
|
||||
}
|
||||
} else if(array_key_exists('file', $data) || array_key_exists('transform', $data)) {
|
||||
}//end if
|
||||
} else {
|
||||
$this->setStatusQueued();
|
||||
MediaWorkerJob::dispatch($this);
|
||||
}
|
||||
}
|
||||
MediaWorkerJob::dispatch($this)->onQueue('media');
|
||||
}//end if
|
||||
}//end if
|
||||
}
|
||||
|
||||
// public const INVALID_FILE_ERROR = 1;
|
||||
// public const FILE_SIZE_EXCEEDED_ERROR = 2;
|
||||
// public const FILE_NAME_EXISTS_ERROR = 3;
|
||||
// public const TEMP_FILE_ERROR = 4;
|
||||
|
||||
// /**
|
||||
// * Set the Media Job to failed
|
||||
// *
|
||||
// * @var string $msg The status message to save.
|
||||
// * @return void
|
||||
// */
|
||||
// public function failed(string $msg = ''): void
|
||||
// {
|
||||
// $data = [];
|
||||
|
||||
// try {
|
||||
// $data = json_decode($this->data, true);
|
||||
// } catch(\Exception $e) {
|
||||
// /* empty */
|
||||
// }
|
||||
|
||||
// if(array_key_exists('chunks', $data) === true) {
|
||||
// foreach($data['chunks'] as $num => $path) {
|
||||
// if(file_exists($path) === true) {
|
||||
// unlink($path);
|
||||
// }
|
||||
// }
|
||||
|
||||
// unset($data['chunks']);
|
||||
// $this->data = json_encode($data);
|
||||
// }
|
||||
|
||||
// $this->status = 'failed';
|
||||
// $this->status_text = $msg;
|
||||
// $this->progress = 0;
|
||||
// $this->save();
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Return the job owner
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user