teknolis / app /Services /PollinationsImageService.php
OpenAI Codex
Fix storage symlink and adapt cron status for Spaces
1501522
Raw
History Blame Contribute Delete
2.16 kB
<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use RuntimeException;
class PollinationsImageService
{
public function generate(string $prompt, string $aspect = 'landscape', int $count = 1): array
{
$baseUrl = rtrim((string) config('services.pollinations.base_url', 'https://image.pollinations.ai/prompt'), '/');
$model = (string) config('services.pollinations.model', 'flux');
$apiKey = trim((string) config('services.pollinations.api_key'));
$timeout = max(15, (int) config('services.pollinations.timeout', 45));
$count = in_array($count, [1, 2, 4, 6], true) ? $count : 1;
[$width, $height] = $this->sizeFromAspect($aspect);
$encodedPrompt = rawurlencode(trim($prompt));
$urls = [];
for ($i = 0; $i < $count; $i++) {
$params = [
'width' => $width,
'height' => $height,
'model' => $model,
'seed' => random_int(1, 999999999),
'nologo' => 'true',
'enhance' => 'false',
];
if ($apiKey !== '') {
$params['key'] = $apiKey;
}
$query = http_build_query($params);
$url = "{$baseUrl}/{$encodedPrompt}?{$query}";
$probe = Http::timeout($timeout)
->withHeaders(['Accept' => 'image/*'])
->get($url);
if (! $probe->successful()) {
$body = Str::limit(trim($probe->body()), 200, '...');
if ($probe->status() === 401) {
throw new RuntimeException('Pollinations butuh API key. Isi POLLINATIONS_API_KEY di .env.');
}
throw new RuntimeException('Pollinations gagal: '.$probe->status().' - '.$body);
}
$urls[] = $url;
}
return $urls;
}
private function sizeFromAspect(string $aspect): array
{
return match ($aspect) {
'portrait' => [768, 1344],
'square' => [1024, 1024],
default => [1344, 768],
};
}
}