signature = 'bundle:describe { --r|recursive : Also upgrade sub-bundles } { --source-disk= : Use specified content disk - Defaults to ' . env('CONTENT_DISK') . ' } { path? : Path to a specific bundle to upgrade - Default to / } '; parent::__construct(); } /** * Execute the console command. */ public function handle() { $this->selectDisk() ->selectBundles() ->perform(); } private function perform() { progress('Updating bundles...', $this->bundles, function (Bundle $bundle, $progress) { $this->handleBundle($bundle, $progress); }); } private function handleBundle(Bundle $bundle, $progress) { $allowedSections = [ '/blog/', '/critiques/', ]; if (!in_array($bundle->getSection()->getPath(), $allowedSections)) { return; } $this->describeContent($bundle, $progress); $this->describeAttachments($bundle, $progress); } private function describeContent(Bundle $bundle, $progress) { $bundle->load(); if ($bundle->metadata()->has('description')) { return; } $content = $bundle->markdown()->get(); if (empty($content)) { return; } $selected = false; $fresh = false; while (!$selected) { if (!$fresh) { $text = Ollama::summarizeText($bundle->getArticleTitle(), $content); // $sentence = Translator::translate($sentence); } else { $text = ''; } $description = textarea(sprintf('Description for %s', $bundle->getPath()), '', trim($text)); $selection = select( 'What should we do?', [ 'keep' => 'Use current description', 'generate' => 'Generate new description', 'fresh' => 'Write own description', 'none' => 'Use no text at all', ], $description !== $text ? 'keep' : 'generate' ); if ($selection === 'keep' || $selection === 'none') { $bundle->metadata()->set('description', $selection === 'keep' ? $description : ''); $bundle->metadata()->save(); $selected = true; } elseif ($selection === 'fresh') { $fresh = true; } else { $fresh = false; } } } private function describeAttachments(Bundle $bundle, $progress) { $attachmentsManager = $bundle->attachments(AttachmentsManager::Images); foreach ($attachmentsManager->manager()->get('files') ?? [] as $ref => $data) { if (array_key_exists('alt', $data)) { continue; } $selected = false; $fresh = false; $fullPath = $attachmentsManager->getAttachmentFullPath($ref); $content = $this->sourceDisk->get($fullPath); $content = Image::read($content)->toJpeg(); $base64 = base64_encode($content); while (!$selected) { if (!$fresh) { $text = Ollama::describeImage([$base64], $bundle->getArticleTitle(), json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); // $sentence = Translator::translate($sentence); } else { $text = ''; } $description = textarea(sprintf('Image description for %s', $fullPath), '', $text); $selection = select( 'What should we do?', [ 'keep' => 'Use current description', 'generate' => 'Generate new description', 'fresh' => 'Write own description', 'none' => 'Use no text at all', ], $description !== $text ? 'keep' : 'generate' ); if ($selection === 'keep' || $selection === 'none') { $attachmentsManager->manager()->set(sprintf('files.%s.alt', $ref), $selection === 'keep' ? $description : ''); $attachmentsManager->manager()->save(); $selected = true; } elseif ($selection === 'fresh') { $fresh = true; } else { $fresh = false; } } } } }