diff --git a/src/LargoServiceProvider.php b/src/LargoServiceProvider.php index 99975c44..b583fc19 100644 --- a/src/LargoServiceProvider.php +++ b/src/LargoServiceProvider.php @@ -9,6 +9,7 @@ use Biigle\Modules\Largo\Listeners\AttachLabelListener; use Biigle\Modules\Largo\Listeners\ImagesCleanupListener; use Biigle\Modules\Largo\Listeners\VideosCleanupListener; +use Biigle\Modules\Largo\Listeners\VolumeClonedListener; use Biigle\Modules\Largo\Observers\ImageAnnotationObserver; use Biigle\Modules\Largo\Observers\VideoAnnotationObserver; use Biigle\Services\Modules; @@ -52,6 +53,7 @@ public function boot(Modules $modules, Router $router) Event::listen(ImagesDeleted::class, ImagesCleanupListener::class); Event::listen(VideosDeleted::class, VideosCleanupListener::class); Event::listen(AnnotationLabelAttached::class, AttachLabelListener::class); + Event::listen('volume.cloned', VolumeClonedListener::class); $modules->register('largo', [ 'viewMixins' => [ diff --git a/src/Listeners/VolumeClonedListener.php b/src/Listeners/VolumeClonedListener.php new file mode 100644 index 00000000..445388ab --- /dev/null +++ b/src/Listeners/VolumeClonedListener.php @@ -0,0 +1,33 @@ +addSeconds(30); + + $volume->images() + ->whereHas('annotations') + ->eachById(function ($image) use ($delay) { + ProcessAnnotatedImage::dispatch($image) + ->delay($delay) + ->onQueue(config('largo.generate_annotation_patch_queue')); + }); + + $volume->videos() + ->whereHas('annotations') + ->eachById(function ($video) use ($delay) { + ProcessAnnotatedVideo::dispatch($video) + ->delay($delay) + ->onQueue(config('largo.generate_annotation_patch_queue')); + }); + } +} diff --git a/tests/Listeners/VolumeClonedListenerTest.php b/tests/Listeners/VolumeClonedListenerTest.php new file mode 100644 index 00000000..53eabd9c --- /dev/null +++ b/tests/Listeners/VolumeClonedListenerTest.php @@ -0,0 +1,66 @@ +create(); + + $volume = Volume::factory()->create([ + 'media_type_id' => MediaType::imageId(), + 'created_at' => '2022-11-09 14:37:00', + 'updated_at' => '2022-11-09 14:37:00', + ])->fresh();// Use fresh() to load even the null fields. + $copy = $volume->replicate(); + $copy->save(); + + $oldImage = Image::factory()->create(['volume_id' => $volume->id])->fresh(); + $oldAnnotation = ImageAnnotation::factory()->create(['image_id' => $oldImage->id]); + ImageAnnotationLabel::factory()->create(['annotation_id' => $oldAnnotation->id]); + + Queue::fake(); + event('volume.cloned', $volume); + + Queue::assertPushed(ProcessAnnotatedImage::class); + } + + public function testHandleVideoAnnotationPatches() + { + // The target project. + $project = Project::factory()->create(); + + $volume = Volume::factory()->create([ + 'media_type_id' => MediaType::videoId(), + 'created_at' => '2022-11-09 14:37:00', + 'updated_at' => '2022-11-09 14:37:00', + ])->fresh();// Use fresh() to load even the null fields. + $copy = $volume->replicate(); + $copy->save(); + + $oldVideo = Video::factory()->create(['volume_id' => $volume->id])->fresh(); + $oldAnnotation = VideoAnnotation::factory()->create(['video_id' => $oldVideo->id]); + VideoAnnotationLabel::factory()->create(['annotation_id' => $oldAnnotation->id]); + + Queue::fake(); + event('volume.cloned', $volume); + + Queue::assertPushed(ProcessAnnotatedVideo::class); + } +}