From 3fe73be465193028470a09298fb8af434aac9f69 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Thu, 17 Oct 2024 07:59:47 +0200 Subject: [PATCH] Clone v-thumbnails and sprites if data exists --- app/Jobs/CloneImagesOrVideos.php | 1 + app/Jobs/ProcessNewVolumeFiles.php | 32 +++++++++++++++- tests/php/Jobs/ProcessNewVolumeFilesTest.php | 40 ++++++++++++++++---- 3 files changed, 65 insertions(+), 8 deletions(-) diff --git a/app/Jobs/CloneImagesOrVideos.php b/app/Jobs/CloneImagesOrVideos.php index c94064c7c..aa87dcd8b 100644 --- a/app/Jobs/CloneImagesOrVideos.php +++ b/app/Jobs/CloneImagesOrVideos.php @@ -316,6 +316,7 @@ private function copyVideos($volume, $copy, $selectedVideoIds) $original['volume_id'] = $copy->id; $original['uuid'] = (string)Uuid::uuid4(); unset($original['id']); + $this->uuidMap[$original['uuid']] = $video->uuid; return $original; }) ->chunk(1000) diff --git a/app/Jobs/ProcessNewVolumeFiles.php b/app/Jobs/ProcessNewVolumeFiles.php index 0cf3dcb6a..3678cc022 100644 --- a/app/Jobs/ProcessNewVolumeFiles.php +++ b/app/Jobs/ProcessNewVolumeFiles.php @@ -29,6 +29,11 @@ class ProcessNewVolumeFiles extends Job implements ShouldQueue */ protected $only; + /** + * Array maps uuid of copied file to uuid of original files. + * + * @var array + */ protected $uuidMap; /** @@ -44,6 +49,8 @@ class ProcessNewVolumeFiles extends Job implements ShouldQueue * @param Volume $volume The volume for which the files should be processed. * @param array $only (optional) Array of image/video IDs to restrict processing to. * If it is empty, all files of the volume will be taken. + * @param array $uuidMap Array to map copied file uuid to the original file uuid during cloning process. + * It is empty, if a volume is created, but not cloned. * * @return void */ @@ -66,6 +73,7 @@ public function handle() if ($this->volume->isImageVolume()) { $query->eachById(function (Image $img) { + // Process new image, if volume is just created if (!$this->uuidMap) { ProcessNewImage::dispatch($img); return; @@ -85,7 +93,29 @@ public function handle() }); } else { $queue = config('videos.process_new_video_queue'); - $query->eachById(fn (Video $v) => ProcessNewVideo::dispatch($v)->onQueue($queue)); + $query->eachById( + function (Video $video) use ($queue) { + // Process new video, if volume is just created + if (!$this->uuidMap) { + ProcessNewVideo::dispatch($video)->onQueue($queue); + return; + } + + $prefix = fragment_uuid_path($this->uuidMap[$video->uuid]); + $copyPrefix = fragment_uuid_path($video->uuid); + + $nbrFiles = count(Storage::disk(config('videos.thumbnail_storage_disk'))->files($prefix)); + $nbrSprites = count(array_filter(Storage::disk(config('videos.thumbnail_storage_disk'))->files($prefix), fn ($f) => str_contains($f, 'sprite'))); + + $hasThumbnails = $nbrFiles - $nbrSprites > 0; + $hasSprites = $nbrSprites > 0; + if ($hasThumbnails && $hasSprites) { + CloneVideoThumbnails::dispatch($prefix, $copyPrefix)->onQueue($queue); + } else { + ProcessNewVideo::dispatch($video)->onQueue($queue); + } + } + ); } } } diff --git a/tests/php/Jobs/ProcessNewVolumeFilesTest.php b/tests/php/Jobs/ProcessNewVolumeFilesTest.php index d03dcdd7e..bd213287d 100644 --- a/tests/php/Jobs/ProcessNewVolumeFilesTest.php +++ b/tests/php/Jobs/ProcessNewVolumeFilesTest.php @@ -2,17 +2,18 @@ namespace Biigle\Tests\Jobs; -use Biigle\Jobs\CloneImageThumbnails; -use Biigle\Jobs\ProcessNewImage; -use Biigle\Jobs\ProcessNewVideo; -use Biigle\Jobs\ProcessNewVolumeFiles; +use Queue; +use Storage; +use TestCase; use Biigle\MediaType; use Biigle\Tests\ImageTest; use Biigle\Tests\VideoTest; use Biigle\Tests\VolumeTest; -use Queue; -use Storage; -use TestCase; +use Biigle\Jobs\ProcessNewImage; +use Biigle\Jobs\ProcessNewVideo; +use Biigle\Jobs\CloneImageThumbnails; +use Biigle\Jobs\CloneVideoThumbnails; +use Biigle\Jobs\ProcessNewVolumeFiles; class ProcessNewVolumeFilesTest extends TestCase { @@ -88,6 +89,31 @@ public function testHandleVideos() Queue::assertPushed(ProcessNewVideo::class, fn ($job) => $job->video->id === $v2->id); } + public function testHandleVideoWithThumbnails() + { + $disk = Storage::fake('test-thumbs'); + config(['videos.thumbnail_storage_disk' => 'test-thumbs']); + + $volume = VolumeTest::create(['media_type_id' => MediaType::videoId()]); + $v1 = VideoTest::create(['volume_id' => $volume->id, 'filename' => 'a.jpg']); + $prefix = fragment_uuid_path($v1->uuid); + + $copy = VolumeTest::create(['media_type_id' => MediaType::videoId()]); + $v2 = VideoTest::create(['volume_id' => $copy->id, 'filename' => 'a.jpg']); + $copyPrefix = fragment_uuid_path($v2->uuid); + + $disk->put($prefix.'/thumb.jpg', ''); + $disk->put($prefix.'/sprite_1.webp', ''); + + $map = [$v2->uuid => $v1->uuid]; + + Queue::fake(); + + with(new ProcessNewVolumeFiles($copy, [], $map))->handle(); + + Queue::assertPushed(CloneVideoThumbnails::class, fn ($job) => $job->prefix === $prefix && $job->copyPrefix === $copyPrefix); + } + public function testHandleVideosWithOnly() { $volume = VolumeTest::create(['media_type_id' => MediaType::videoId()]);