client->isConfigured(); } /** * @return array{url: string, metadata: array} */ public function payloadForArtwork(Artwork $artwork): array { $url = $this->imageUrl->fromArtwork($artwork); if ($url === null || $url === '') { throw new RuntimeException('No vision image URL could be generated for artwork ' . (int) $artwork->id . '.'); } return [ 'url' => $url, 'metadata' => $this->metadata->forArtwork($artwork), ]; } /** * @return array{url: string, metadata: array} */ public function upsertArtwork(Artwork $artwork): array { $payload = $this->payloadForArtwork($artwork); $filePayload = $this->downloadArtworkImage($artwork, $payload['url']); if ($filePayload === null) { throw new RuntimeException('Unable to download artwork image bytes for vector upsert for artwork ' . (int) $artwork->id . '.'); } $this->client->upsertByFileContents($filePayload['contents'], $filePayload['filename'], (int) $artwork->id, $payload['metadata']); $artwork->forceFill([ 'last_vector_indexed_at' => now(), ])->save(); return $payload; } /** * @return array{contents: string, filename: string}|null */ private function downloadArtworkImage(Artwork $artwork, string $url): ?array { $response = Http::accept('*/*') ->connectTimeout(5) ->timeout(20) ->retry(1, 200, throw: false) ->get($url); if (! $response->ok()) { return null; } $contents = $response->body(); if ($contents === '') { return null; } $ext = strtolower(ltrim((string) ($artwork->thumb_ext ?: 'webp'), '.')); return [ 'contents' => $contents, 'filename' => sprintf('artwork-%d.%s', (int) $artwork->id, $ext !== '' ? $ext : 'webp'), ]; } }