SmartCane/laravel_app/app/Jobs/ProjectMosiacGeneratorJob.php
2024-09-02 11:51:12 +02:00

125 lines
4.2 KiB
PHP

<?php
namespace App\Jobs;
use App\Models\Project;
use App\Models\ProjectMosaic;
use App\ProjectLogger;
use Carbon\Carbon;
use Illuminate\Bus\Batchable;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Process\Exceptions\ProcessFailedException;
use Illuminate\Process\Exceptions\ProcessTimedOutException;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Symfony\Component\Process\Process;
use Illuminate\Support\Facades\Process as ProcessNew;
/**
*
*/
class ProjectMosiacGeneratorJob implements ShouldQueue
{
use Batchable, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public ProjectMosaic $mosaic;
public $timeout = 220;
/**
* Create a new job instance.
*/
public function __construct(ProjectMosaic $mosaic)
{
$this->mosaic = $mosaic;
}
/**
* Execute the job.
*/
/**
* Execute the job.
*/
public function handle(): void
{
$projectFolder = base_path('../');
$project = $this->mosaic->project;
$command = [
sprintf('%sbuild_mosaic.sh', $projectFolder),
sprintf('--end_date=%s', $this->mosaic->end_date->format('Y-m-d')),
sprintf('--offset=%s', $this->mosaic->offset),
sprintf('--data_dir=%s', $this->mosaic->project->download_path),
sprintf('--file_name_tif=%s', basename($this->mosaic->path)),
];
ProjectLogger::log($project, 'command:'. print_r($command, true));
$currentPath = '/usr/bin:/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin/Users/mfolkerts/anaconda3/bin:/Library/Apple/usr/bin';
try {
$process = ProcessNew::timeout(220)
->env(['PATH' => $currentPath.':/usr/local/Cellar/pandoc/3.1.8/bin/pandoc'])
->start($command, function (string $type, string $output) use ($project) {
ProjectLogger::log($project, $output);
$this->throwIfOutputContainsError($output);
});
$results = $process->wait();
if ($results->successful()) {
$this->mosaic->setStatusSuccess();
}
} catch (\RuntimeException|ProcessTimedOutException|ProcessFailedException $e) {
ProjectLogger::log($project, $e->getMessage());
$this->mosaic->setStatusFailed();
}
}
/**
* Check if the project has a mosaic for given period.
*/
public static function handleFor(Project $project, Carbon $endDate, int $offset): NullJob|ProjectMosiacGeneratorJob
{
$endDate = $endDate->clone();
ProjectLogger::log($project, "ProjectMosiacGeneratorJob::handleFor($endDate, $offset)");
if ($project->hasInvalidMosaicFor($endDate, $offset)) {
ProjectLogger::log($project,"ProjecMosaicGeneratorJob::handleFor(end_date: $endDate, offset: $offset): InvalidMosaic.");
return new NullJob();
}
ProjectLogger::log($project, __CLASS__."::".__METHOD__."::Project->mail_day::".$project->mail_day);
if (Carbon::parse($project->mail_day)->dayOfWeek < $endDate->dayOfWeek) {
$endDate->next($project->mail_day);
}
/**
* @var ProjectMosaic $mosaic
*/
$mosaic = $project->mosaics()->updateOrCreate(
[
'name' => sprintf('Week_%s_%s', $endDate->week, $endDate->year),
],
[
'name' => sprintf('Week_%s_%s', $endDate->week, $endDate->year),
'path' => sprintf('%s/%s/%s',
$project->download_path,
'mosaics',
sprintf('week_%s_%s.tif', $endDate->week, $endDate->year)
),
'end_date' => $endDate->format('Y-m-d'),
'offset' => $offset,
]);
return new self($mosaic);
}
private function throwIfOutputContainsError(string $output)
{
if (str_contains($output, 'No images available this week, empty mosaic created')) {
throw new \RuntimeException( $output);
}
return true;
}
}