gutendex integration, phase 6
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Jobs\ImportBookFromGutendex;
|
||||
use App\Models\Book;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SyncBookFromGutendex extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'gutendex:sync-book
|
||||
{gutenberg_id : The Gutenberg book ID to import}
|
||||
{--force : Force re-import even if book exists}
|
||||
{--no-summary : Skip summary generation}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Import or update a specific book from Gutendex by its ID';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$gutenbergId = (int) $this->argument('gutenberg_id');
|
||||
$force = $this->option('force');
|
||||
$generateSummary = !$this->option('no-summary');
|
||||
|
||||
if ($gutenbergId <= 0) {
|
||||
$this->error('Invalid Gutenberg ID. Must be a positive integer.');
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->info("Syncing book from Gutendex (ID: {$gutenbergId})");
|
||||
$this->newLine();
|
||||
|
||||
// Check if book already exists
|
||||
$existingBook = Book::where('gutenberg_id', $gutenbergId)->first();
|
||||
|
||||
if ($existingBook && !$force) {
|
||||
$this->warn('Book already exists in the database!');
|
||||
$this->newLine();
|
||||
$this->table(
|
||||
['Field', 'Value'],
|
||||
[
|
||||
['Database ID', $existingBook->id],
|
||||
['Title', $existingBook->title],
|
||||
['Author', $existingBook->author],
|
||||
['Slug', $existingBook->slug],
|
||||
['Category', $existingBook->category->name ?? 'N/A'],
|
||||
['Has Summary', $existingBook->summary ? 'Yes' : 'No'],
|
||||
['Summary Status', $existingBook->summary->processing_status ?? 'N/A'],
|
||||
]
|
||||
);
|
||||
$this->newLine();
|
||||
|
||||
if (!$this->confirm('Use --force to re-import. Continue anyway?', false)) {
|
||||
$this->info('Operation cancelled.');
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
// Delete existing book to re-import
|
||||
$this->warn('Deleting existing book...');
|
||||
$existingBook->delete();
|
||||
$this->info('✓ Existing book deleted.');
|
||||
$this->newLine();
|
||||
}
|
||||
|
||||
// Fetch book info from Gutendex first to show details
|
||||
$this->info('Fetching book details from Gutendex...');
|
||||
$gutendexClient = app(\App\Services\GutendexClient::class);
|
||||
$gutendexBook = $gutendexClient->getBook($gutenbergId);
|
||||
|
||||
if (!$gutendexBook) {
|
||||
$this->error("Failed to fetch book {$gutenbergId} from Gutendex API.");
|
||||
$this->comment('The book may not exist or the API may be unavailable.');
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
// Display book info
|
||||
$this->info('✓ Book found on Gutendex');
|
||||
$this->newLine();
|
||||
$this->table(
|
||||
['Field', 'Value'],
|
||||
[
|
||||
['Gutenberg ID', $gutendexBook->id],
|
||||
['Title', $gutendexBook->title],
|
||||
['Author(s)', $gutendexBook->getAuthorNamesString()],
|
||||
['Language', $gutendexBook->getPrimaryLanguage()],
|
||||
['Public Domain', $gutendexBook->isPublicDomain() ? 'Yes' : 'No'],
|
||||
['Plain Text Available', $gutendexBook->getPlainTextUrl() ? 'Yes' : 'No'],
|
||||
['Download Count', number_format($gutendexBook->downloadCount)],
|
||||
]
|
||||
);
|
||||
$this->newLine();
|
||||
|
||||
// Validate book
|
||||
if (!$gutendexBook->isPublicDomain()) {
|
||||
$this->error('This book is not in the public domain and cannot be imported.');
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
if (!$gutendexBook->getPlainTextUrl()) {
|
||||
$this->error('This book does not have a plain text version available.');
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
// Dispatch import job
|
||||
$this->info('Dispatching import job...');
|
||||
ImportBookFromGutendex::dispatch($gutenbergId, $generateSummary);
|
||||
|
||||
$this->newLine();
|
||||
$this->info('✓ Import job dispatched successfully!');
|
||||
$this->newLine();
|
||||
$this->comment('The book will be imported in the background.');
|
||||
$this->comment('Run the queue worker: php artisan queue:work');
|
||||
|
||||
if ($generateSummary) {
|
||||
$this->comment('Summary will be generated automatically after import.');
|
||||
} else {
|
||||
$this->comment('Summary generation was skipped (--no-summary flag).');
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user