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> 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> */ 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> 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 */ public function stats(): array { return $this->cache->remember('bambuddy.stats.'.md5($this->url()), 300, fn (): array => $this->get('archives/stats')); } /** @param array $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(); } }