Add BamBuddy AMS, queue, history and stats to the print farm page
Deploy HickLab3D Dashboard / Deploy to production (push) Successful in 28s
Deploy HickLab3D Dashboard / Deploy to production (push) Successful in 28s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
f7e3c8fe16
commit
b11538944f
@@ -36,6 +36,9 @@ class RefreshIntegrationCache extends Command
|
||||
|
||||
if ($bambuddy->configured()) {
|
||||
$this->refresh('bambuddy printers', fn () => $bambuddy->printers());
|
||||
$this->refresh('bambuddy queue', fn () => $bambuddy->queue());
|
||||
$this->refresh('bambuddy recent prints', fn () => $bambuddy->recentPrints());
|
||||
$this->refresh('bambuddy stats', fn () => $bambuddy->stats());
|
||||
}
|
||||
|
||||
if ($dryer->configured()) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\Bambuddy;
|
||||
use Closure;
|
||||
use Illuminate\View\View;
|
||||
use Throwable;
|
||||
|
||||
@@ -20,6 +21,27 @@ class BambuddyController extends Controller
|
||||
$integrationError = 'BamBuddy is unavailable. Check its API key and connection.';
|
||||
}
|
||||
|
||||
return view('printers.index', compact('printers', 'integrationError') + ['bambuddyUrl' => $bambuddy->url()]);
|
||||
$queue = $printers === [] ? [] : $this->optional(fn (): array => $bambuddy->queue());
|
||||
$recentPrints = $printers === [] ? [] : $this->optional(fn (): array => $bambuddy->recentPrints());
|
||||
$stats = $printers === [] ? [] : $this->optional(fn (): array => $bambuddy->stats());
|
||||
|
||||
return view('printers.index', compact('printers', 'integrationError', 'queue', 'recentPrints', 'stats') + ['bambuddyUrl' => $bambuddy->url()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load secondary page data without letting a failure hide the printers.
|
||||
*
|
||||
* @param Closure(): array<mixed> $load
|
||||
* @return array<mixed>
|
||||
*/
|
||||
private function optional(Closure $load): array
|
||||
{
|
||||
try {
|
||||
return $load();
|
||||
} catch (Throwable $exception) {
|
||||
report($exception);
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,39 @@ class Bambuddy
|
||||
return $this->cache->remember('bambuddy.printers.'.md5($this->url()), 45, fn (): array => $this->fetchPrinters());
|
||||
}
|
||||
|
||||
/** @return array<int, array<string, mixed>> Jobs still waiting or running in the BamBuddy queue. */
|
||||
public function queue(): array
|
||||
{
|
||||
return $this->cache->remember('bambuddy.queue.'.md5($this->url()), 45, fn (): array => collect($this->get('queue/'))
|
||||
->filter(fn ($item): bool => is_array($item) && empty($item['completed_at']) && in_array($item['status'] ?? 'pending', ['pending', 'printing', 'queued', 'waiting'], true))
|
||||
->sortBy('position')->values()->all());
|
||||
}
|
||||
|
||||
/** @return array<int, array<string, mixed>> */
|
||||
public function recentPrints(int $limit = 10): array
|
||||
{
|
||||
return $this->cache->remember('bambuddy.archives.'.md5($this->url()).'.'.$limit, 120, fn (): array => collect($this->get('archives/', ['limit' => $limit]))
|
||||
->filter(fn ($archive): bool => is_array($archive))->values()->all());
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
public function stats(): array
|
||||
{
|
||||
return $this->cache->remember('bambuddy.stats.'.md5($this->url()), 300, fn (): array => $this->get('archives/stats'));
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $query */
|
||||
private function get(string $path, array $query = []): array
|
||||
{
|
||||
if (! $this->configured()) {
|
||||
throw new RuntimeException('BamBuddy API key is not configured.');
|
||||
}
|
||||
|
||||
return Http::withHeaders(['X-API-Key' => $this->settings->for('bambuddy')['api_key']])
|
||||
->acceptJson()->connectTimeout(3)->timeout(8)
|
||||
->get(rtrim($this->url(), '/').'/api/v1/'.ltrim($path, '/'), $query)->throw()->json() ?? [];
|
||||
}
|
||||
|
||||
private function fetchPrinters(): array
|
||||
{
|
||||
$url = rtrim($this->url(), '/').'/api/v1/printers';
|
||||
|
||||
@@ -93,6 +93,17 @@ class Display
|
||||
));
|
||||
}
|
||||
|
||||
/** Format a number of seconds as a short duration such as "2h 1m". */
|
||||
public function duration(int|float|null $seconds): string
|
||||
{
|
||||
if ($seconds === null || $seconds <= 0) {
|
||||
return '—';
|
||||
}
|
||||
$minutes = (int) round($seconds / 60);
|
||||
|
||||
return $minutes >= 60 ? intdiv($minutes, 60).'h '.($minutes % 60).'m' : $minutes.'m';
|
||||
}
|
||||
|
||||
/** Format an API date or date-time as a readable string, dropping the time when it is midnight. */
|
||||
public function dateTime(string|int|null $value): string
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user