Skip to content

Commit 4ccaa5f

Browse files
committed
Merge branch 'refs/heads/development'
2 parents 4d5099d + e993b2f commit 4ccaa5f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+745
-648
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
/*
4+
* Copyright (C) 2014 - 2026, Biospex
5+
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
namespace App\Console\Commands;
22+
23+
use App\Models\Expedition;
24+
use App\Models\Subject;
25+
use App\Services\DarwinCore\DwcValidationService;
26+
use Illuminate\Console\Command;
27+
28+
class AppClearSubjectsCommand extends Command
29+
{
30+
/**
31+
* The name and signature of the console command.
32+
*
33+
* @var string
34+
*/
35+
protected $signature = 'app:clear-subjects {uuid : The UUID of the expedition} {--dry-run : Display the count without updating}';
36+
37+
/**
38+
* The console command description.
39+
*
40+
* @var string
41+
*/
42+
protected $description = 'Clear the OCR data from every subject assigned to an expedition';
43+
44+
/**
45+
* Execute the console command.
46+
*/
47+
public function handle(DwcValidationService $validationService): int
48+
{
49+
$uuid = $this->argument('uuid');
50+
51+
if (! $validationService->isValidUuid($uuid)) {
52+
$this->error('Invalid UUID format provided.');
53+
54+
return self::FAILURE;
55+
}
56+
57+
$expedition = Expedition::where('uuid', $uuid)->first();
58+
59+
if (! $expedition) {
60+
$this->error("Expedition with UUID {$uuid} not found.");
61+
62+
return self::FAILURE;
63+
}
64+
65+
// MongoDB is type sensitive; expedition_ids contains integers in this app
66+
$expeditionId = (int) $expedition->id;
67+
68+
$query = Subject::where('expedition_ids', $expeditionId);
69+
$subjectCount = $query->count();
70+
71+
if ($subjectCount === 0) {
72+
$this->info('No subjects found for this expedition.');
73+
74+
return self::SUCCESS;
75+
}
76+
77+
if ($this->option('dry-run')) {
78+
$this->info("Dry run: {$subjectCount} subjects would have their OCR cleared.");
79+
80+
return self::SUCCESS;
81+
}
82+
83+
if (! $this->confirm("Are you sure you want to clear OCR for {$subjectCount} subjects in '{$expedition->title}'?")) {
84+
$this->info('Operation cancelled.');
85+
86+
return self::SUCCESS;
87+
}
88+
89+
$this->info("Clearing OCR for {$subjectCount} subjects...");
90+
91+
/**
92+
* Using the Subject model (mongodb/laravel-mongodb) to perform a bulk update.
93+
* The 'where' clause on an array field like 'expedition_ids' in MongoDB
94+
* automatically checks for existence of the value.
95+
*/
96+
$query->update(['ocr' => '']);
97+
98+
$this->info('OCR data cleared successfully.');
99+
100+
return self::SUCCESS;
101+
}
102+
}

app/Console/Commands/AppFileDeploymentCommand.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Illuminate\Console\Command;
2525
use Illuminate\Support\Collection;
2626
use Illuminate\Support\Facades\File;
27+
use Illuminate\Support\Facades\Log;
2728
use Illuminate\Support\Facades\Storage;
2829
use Illuminate\Support\Str;
2930
use Symfony\Component\Console\Command\Command as CommandAlias;
@@ -94,8 +95,6 @@ private function getSourceFiles(): Collection
9495
throw new Exception("No supervisor template files found in: {$supervisorPath}");
9596
}
9697

97-
\Log::info('Found '.count($files).' supervisor template file(s)');
98-
9998
return collect($files);
10099
}
101100

@@ -201,6 +200,7 @@ private function getTargetPath($sourceFile): string
201200
*/
202201
private function writeTargetFile(string $targetPath, string $content): void
203202
{
203+
204204
$dir = dirname($targetPath);
205205

206206
if (! File::isDirectory($dir)) {
@@ -232,10 +232,6 @@ private function showDryRunChanges(string $filename, string $original, string $p
232232
$changes++;
233233
}
234234
}
235-
236-
if ($changes === 0) {
237-
\Log::info(' <fg=gray>No replacements needed</>');
238-
}
239235
}
240236
}
241237

@@ -281,7 +277,7 @@ private function getReplacementValue(string $field): ?string
281277
if (str_starts_with($field, 'AWS_SQS_')) {
282278
$value = strtolower(str_replace('AWS_SQS_', '', $field));
283279

284-
return config('services.aws.queues.'.$value);
280+
return config('services.aws.sqs.'.$value);
285281
}
286282

287283
if ($field === 'REVERB_DEBUG') {

app/Console/Commands/CleanEfsDirsCommand.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ private function cleanDirectory(string $path): int
7070

7171
if ($lastModified->lessThan($threshold)) {
7272
File::delete($file); // Use the File facade to delete
73-
\Log::info("Deleted file: $file");
7473
$deletedFiles++;
7574
}
7675
}

app/Console/Commands/ExportQueueCommand.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,15 @@ public function handle(): void
6868
$expeditionId = $this->argument('expeditionId');
6969

7070
try {
71-
is_null($expeditionId)
72-
? $this->queueService->processNextQueue()
73-
: $this->cleanupService->resetExpeditionExport($expeditionId);
71+
if (is_null($expeditionId)) {
72+
// 1. Check for finished image processing
73+
$this->queueService->checkActiveQueuesForCompletion();
74+
75+
// 2. Process the next waiting queue
76+
$this->queueService->processNextQueue();
77+
} else {
78+
$this->cleanupService->resetExpeditionExport($expeditionId);
79+
}
7480
} catch (\Throwable $e) {
7581
$this->fail($e);
7682
}

app/Console/Commands/ExportQueueStageCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ public function handle()
8787
$queue->error = 0;
8888
$queue->save();
8989

90-
\Artisan::call('update:listen-controller start');
91-
90+
// Start both the specific update listener and the shared DLQ listener
91+
\Artisan::call('sqs:control export_update image_trigger_dlq --action=start');
9292
try {
9393
match ($queue->stage) {
9494
1 => ZooniverseExportProcessImagesJob::dispatch($queue),

app/Console/Commands/PurgeAwsQueues.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function handle()
6161
return 1;
6262
}
6363

64-
$queues = config('services.aws.queues');
64+
$queues = config('services.aws.sqs');
6565

6666
$this->info("Purging queues for environment: <comment>{$env}</comment>");
6767

app/Console/Commands/SqsControllerBatchCommand.php

Lines changed: 0 additions & 67 deletions
This file was deleted.

app/Console/Commands/SqsControllerOcrCommand.php renamed to app/Console/Commands/SqsControllerCommand.php

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

33
/*
4-
* Copyright (C) 2014 - 2025, Biospex
4+
* Copyright (C) 2014 - 2026, Biospex
55
66
*
77
* This program is free software: you can redistribute it and/or modify
@@ -22,31 +22,21 @@
2222

2323
use App\Services\SupervisorControlService;
2424
use Illuminate\Console\Command;
25+
use Illuminate\Support\Facades\Config;
2526

2627
/**
27-
* Command to control OCR listeners via Supervisor
28-
*
29-
* @author Biospex <[email protected]>
28+
* Unified command to control any SQS listener via Supervisor.
29+
* Usage: php artisan sqs:control export_update start
3030
*/
31-
class SqsControllerOcrCommand extends Command
31+
class SqsControllerCommand extends Command
3232
{
3333
/**
3434
* The console command signature.
35-
*
36-
* @var string
3735
*/
38-
protected $signature = 'ocr:listen-controller {action=start|stop|restart}';
36+
protected $signature = 'sqs:control {queue_keys*} {--action=start : start|stop|restart}';
3937

40-
/**
41-
* The console command description.
42-
*
43-
* @var string
44-
*/
45-
protected $description = 'Start/stop/restart OCR listeners via Supervisor (environment-neutral)';
38+
protected $description = 'Control one or more SQS listeners via Supervisor by providing config queue keys';
4639

47-
/**
48-
* Create a new command instance.
49-
*/
5040
public function __construct(protected SupervisorControlService $service)
5141
{
5242
parent::__construct();
@@ -57,14 +47,32 @@ public function __construct(protected SupervisorControlService $service)
5747
*/
5848
public function handle(): int
5949
{
50+
$keys = $this->argument('queue_keys');
51+
$action = $this->option('action');
52+
53+
$queueNames = [];
54+
foreach ($keys as $key) {
55+
$name = Config::get("services.aws.sqs.{$key}");
56+
if (empty($name)) {
57+
$this->warn("Invalid queue key: '{$key}' - skipping.");
58+
59+
continue;
60+
}
61+
$queueNames[] = $name;
62+
}
63+
64+
if (empty($queueNames)) {
65+
$this->error('No valid queue names found to control.');
66+
67+
return self::FAILURE;
68+
}
69+
6070
try {
61-
$this->service->control([
62-
config('services.aws.queues.ocr_update'),
63-
], $this->argument('action'));
71+
$this->service->control($queueNames, $action);
6472

6573
return self::SUCCESS;
6674
} catch (\Throwable $e) {
67-
$this->error('Failed to control OCR listeners: '.$e->getMessage());
75+
$this->error('Supervisor Control Failed: '.$e->getMessage());
6876

6977
return self::FAILURE;
7078
}

0 commit comments

Comments
 (0)