1
0
cms11/app/Console/Commands/Bundle/Describe.php

175 lines
5.3 KiB
PHP
Raw Normal View History

<?php
namespace App\Console\Commands\Bundle;
use App\Classes\AttachmentsManager;
use App\Classes\Bundle;
use App\Console\Commands\Bundle\Traits\ReadsBundles;
use App\Console\Commands\Bundle\Traits\SelectsDisks;
use App\Services\Ollama;
use App\Services\Translator;
use Illuminate\Console\Command;
use Intervention\Image\Laravel\Facades\Image;
use function Laravel\Prompts\progress;
use function Laravel\Prompts\select;
use function Laravel\Prompts\textarea;
class Describe extends Command
{
use ReadsBundles;
use SelectsDisks;
/**
* The console command description.
*
* @var string
*/
protected $description = 'Add description to bundles';
public function __construct()
{
$this->signature = 'bundle:describe
{ --r|recursive : Also upgrade sub-bundles }
{ --source-disk= : Use specified content disk - Defaults to <info>' . env('CONTENT_DISK') . '</info> }
{ path? : Path to a specific bundle to upgrade - Default to <info>/</info> }
';
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()), '', $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());
// $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;
}
}
}
}
}