Deploy HickLab3D Dashboard / Deploy to production (push) Successful in 28s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
87 lines
3.4 KiB
PHP
87 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
use RuntimeException;
|
|
use Throwable;
|
|
|
|
class Bambuddy
|
|
{
|
|
public function __construct(private IntegrationSettings $settings, private IntegrationCache $cache) {}
|
|
|
|
public function url(): string
|
|
{
|
|
return (string) ($this->settings->for('bambuddy')['url'] ?? '');
|
|
}
|
|
|
|
public function configured(): bool
|
|
{
|
|
return filled($this->url()) && filled($this->settings->for('bambuddy')['api_key'] ?? null);
|
|
}
|
|
|
|
public function printers(): array
|
|
{
|
|
if (! $this->configured()) {
|
|
throw new RuntimeException('BamBuddy API key is not configured.');
|
|
}
|
|
|
|
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<int, array<string, mixed>> Spools in the BamBuddy inventory. */
|
|
public function spools(): array
|
|
{
|
|
return $this->cache->remember('bambuddy.spools.'.md5($this->url()), 300, fn (): array => collect($this->get('inventory/spools'))
|
|
->filter(fn ($spool): bool => is_array($spool))->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 = [], int $timeout = 8): array
|
|
{
|
|
if (! $this->configured()) {
|
|
throw new RuntimeException('BamBuddy API key is not configured.');
|
|
}
|
|
$base = preg_replace('#/api(/v1)?$#', '', rtrim(trim($this->url()), '/'));
|
|
|
|
return Http::withHeaders(['X-API-Key' => trim((string) $this->settings->for('bambuddy')['api_key'])])
|
|
->acceptJson()->connectTimeout(3)->timeout($timeout)
|
|
->get($base.'/api/v1/'.ltrim($path, '/'), $query)->throw()->json() ?? [];
|
|
}
|
|
|
|
private function fetchPrinters(): array
|
|
{
|
|
return collect($this->get('printers/'))->filter(fn ($printer) => is_array($printer) && isset($printer['id']))
|
|
->take(20)->map(function (array $printer): array {
|
|
try {
|
|
return $printer + ['live' => $this->get('printers/'.(int) $printer['id'].'/status', timeout: 5)];
|
|
} catch (Throwable $exception) {
|
|
report($exception);
|
|
|
|
return $printer + ['live' => []];
|
|
}
|
|
})->values()->all();
|
|
}
|
|
}
|