coryd.dev/api/book-import.php

109 lines
3.1 KiB
PHP

<?php
require_once __DIR__.'/../bootstrap.php';
use App\Classes\ApiHandler;
use GuzzleHttp\Client;
class BookImportHandler extends ApiHandler
{
private string $bookImportToken;
public function __construct()
{
parent::__construct();
$this->ensureCliAccess();
$this->bookImportToken = $_ENV['BOOK_IMPORT_TOKEN'] ?? getenv('BOOK_IMPORT_TOKEN');
}
public function handleRequest(): void
{
$input = json_decode(file_get_contents('php://input'), true);
if (! $input) {
$this->sendErrorResponse('Invalid or missing JSON body', 400);
}
$providedToken = $input['token'] ?? null;
$isbn = $input['isbn'] ?? null;
if ($providedToken !== $this->bookImportToken) {
$this->sendErrorResponse('Unauthorized access', 401);
}
if (! $isbn) {
$this->sendErrorResponse('isbn parameter is required', 400);
}
try {
$bookData = $this->fetchBookData($isbn);
$this->processBook($bookData);
$this->sendResponse(['message' => 'Book imported successfully'], 200);
} catch (\Exception $e) {
$this->sendErrorResponse('Error: '.$e->getMessage(), 500);
}
}
private function fetchBookData(string $isbn): array
{
$client = new Client();
$response = $client->get('https://openlibrary.org/api/books', [
'query' => [
'bibkeys' => "ISBN:{$isbn}",
'format' => 'json',
'jscmd' => 'data',
],
'headers' => ['Accept' => 'application/json'],
]);
$data = json_decode($response->getBody(), true);
$bookKey = "ISBN:{$isbn}";
if (empty($data[$bookKey])) {
throw new \Exception("Book data not found for ISBN: {$isbn}");
}
return $data[$bookKey];
}
private function processBook(array $bookData): void
{
$isbn =
$bookData['identifiers']['isbn_13'][0] ??
($bookData['identifiers']['isbn_10'][0] ?? null);
$title = $bookData['title'] ?? null;
$author = $bookData['authors'][0]['name'] ?? null;
$description = $bookData['description'] ?? ($bookData['notes'] ?? '');
if (! $isbn || ! $title || ! $author) {
throw new \Exception('Missing essential book data (title, author, or ISBN).');
}
$existingBook = $this->getBookByISBN($isbn);
if ($existingBook) {
throw new \Exception("Book with ISBN {$isbn} already exists.");
}
$bookPayload = [
'isbn' => $isbn,
'title' => $title,
'author' => $author,
'description' => $description,
'read_status' => 'want to read',
'slug' => '/reading/books/'.$isbn,
];
$this->makeRequest('POST', 'books', ['json' => $bookPayload]);
}
private function getBookByISBN(string $isbn): ?array
{
$response = $this->fetchFromApi('books', 'isbn=eq.'.urlencode($isbn));
return $response[0] ?? null;
}
}
$handler = new BookImportHandler();
$handler->handleRequest();