From 03064b45227ba7b9ac1183286984bc2476685daa Mon Sep 17 00:00:00 2001 From: Sergio Mendolia Date: Thu, 28 Nov 2024 19:34:35 +0100 Subject: [PATCH] Fixes for kobo sync and proxy --- .../Kobo/KoboInitializationController.php | 9 ++++++++- src/Controller/Kobo/KoboSyncController.php | 7 +++++-- src/EventSubscriber/KoboRequestSubscriber.php | 2 +- src/Kobo/Proxy/KoboProxyLogger.php | 19 ++++++++++++++++++- src/Kobo/Response/ReadingStateResponse.php | 6 +++--- src/Kobo/Response/SyncResponse.php | 10 +++++++--- 6 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/Controller/Kobo/KoboInitializationController.php b/src/Controller/Kobo/KoboInitializationController.php index 2b5c6e65..ec307b7d 100644 --- a/src/Controller/Kobo/KoboInitializationController.php +++ b/src/Controller/Kobo/KoboInitializationController.php @@ -52,8 +52,15 @@ public function initialization(Request $request, KoboDevice $kobo): Response $jsonData['Resources']['image_url_template'] = $base.'/image/{ImageId}/{width}/{height}/{Quality}/isGreyscale/image.jpg'; $jsonData['Resources']['image_url_quality_template'] = $base.'/{ImageId}/{width}/{height}/false/image.jpg'; + foreach ($jsonData['Resources'] as $key => $url) { + if (!is_string($url)) { + continue; + } + $jsonData['Resources'][$key] = str_replace('https://storeapi.kobo.com', $base, $url); + } + // Reading services - $jsonData['Resources']['reading_services_host'] = rtrim($this->generateUrl('app_dashboard', [], UrlGenerator::ABSOLUTE_URL), '/'); + $jsonData['Resources']['reading_services_host'] = str_replace('https://', '', rtrim($this->generateUrl('app_dashboard', [], UrlGenerator::ABSOLUTE_URL), '/')); $response = new JsonResponse($jsonData); $response->headers->set('kobo-api-token', 'e30='); diff --git a/src/Controller/Kobo/KoboSyncController.php b/src/Controller/Kobo/KoboSyncController.php index 2c8f7083..c3cc49b0 100644 --- a/src/Controller/Kobo/KoboSyncController.php +++ b/src/Controller/Kobo/KoboSyncController.php @@ -9,6 +9,7 @@ use App\Kobo\Response\SyncResponseFactory; use App\Kobo\SyncToken; use App\Repository\BookRepository; +use App\Repository\KoboDeviceRepository; use App\Repository\KoboSyncedBookRepository; use App\Repository\ShelfRepository; use App\Service\KoboSyncTokenExtractor; @@ -31,8 +32,9 @@ public function __construct( protected KoboSyncedBookRepository $koboSyncedBookRepository, protected ShelfRepository $shelfRepository, protected LoggerInterface $logger, - protected SyncResponseFactory $syncResponseFactory) - { + protected KoboDeviceRepository $koboDeviceRepository, + protected SyncResponseFactory $syncResponseFactory, + ) { } /** @@ -55,6 +57,7 @@ public function apiEndpoint(KoboDevice $kobo, SyncToken $syncToken, Request $req $this->logger->debug('Force sync for Kobo {id}', ['id' => $kobo->getId()]); $this->koboSyncedBookRepository->deleteAllSyncedBooks($kobo); $kobo->setForceSync(false); + $this->koboDeviceRepository->save($kobo); $syncToken->currentDate = new \DateTime('now'); } $this->logger->debug('First sync for Kobo {id}', ['id' => $kobo->getId()]); diff --git a/src/EventSubscriber/KoboRequestSubscriber.php b/src/EventSubscriber/KoboRequestSubscriber.php index 7037317a..de8fc0e7 100644 --- a/src/EventSubscriber/KoboRequestSubscriber.php +++ b/src/EventSubscriber/KoboRequestSubscriber.php @@ -33,7 +33,7 @@ public function onKernelResponse(ResponseEvent $event): void $content = $event->getResponse()->getContent(); } - $this->koboLogger->info('Response from '.$event->getRequest()->getPathInfo(), ['response' => $content, 'headers' => $event->getResponse()->headers->all()]); + $this->koboLogger->info('Response given '.$event->getRequest()->getPathInfo(), ['response' => $content, 'headers' => $event->getResponse()->headers->all()]); } public function onKernelController(ControllerEvent $event): void diff --git a/src/Kobo/Proxy/KoboProxyLogger.php b/src/Kobo/Proxy/KoboProxyLogger.php index 02ac2272..925303fd 100644 --- a/src/Kobo/Proxy/KoboProxyLogger.php +++ b/src/Kobo/Proxy/KoboProxyLogger.php @@ -54,10 +54,27 @@ protected function onFailure(RequestInterface $request): \Closure private function log(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): void { - $this->logger->info(sprintf('Proxied: %s', (string) $request->getUri()), [ + try { + $requestContent = json_decode($request->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException $e) { + $requestContent = $request->getBody()->getContents(); + } + $responseContent = $response?->getBody()->getContents(); + if ($responseContent !== null) { + try { + $responseContent = json_decode($responseContent, true, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException) { + } + } + + $this->logger->info(sprintf($request->getMethod().': %s', (string) $request->getUri()), [ 'method' => $request->getMethod(), 'status' => $response?->getStatusCode(), 'token_hash' => md5($this->accessToken), + 'request' => $requestContent, + 'response' => $responseContent, + 'request_headers' => $request->getHeaders(), + 'response_headers' => $response?->getHeaders(), ]); if ($error instanceof \Throwable) { diff --git a/src/Kobo/Response/ReadingStateResponse.php b/src/Kobo/Response/ReadingStateResponse.php index 1a665670..8b007368 100644 --- a/src/Kobo/Response/ReadingStateResponse.php +++ b/src/Kobo/Response/ReadingStateResponse.php @@ -22,7 +22,7 @@ public function __construct( } /** - * @return array + * @return array> */ public function createReadingState(): array { @@ -31,7 +31,7 @@ public function createReadingState(): array $lastModified = $this->syncToken->maxLastModified($book->getUpdated(), $this->syncToken->currentDate, $book->getLastInteraction($this->kobo->getUser())?->getUpdated()); - return [ + return [[ 'EntitlementId' => $uuid, 'Created' => $this->syncToken->maxLastCreated($book->getCreated(), $this->syncToken->currentDate, $book->getLastInteraction($this->kobo->getUser())?->getCreated()), 'LastModified' => $lastModified, @@ -48,7 +48,7 @@ public function createReadingState(): array // "Statistics"=> get_statistics_response(kobo_reading_state.statistics), 'CurrentBookmark' => $this->createBookmark($this->kobo->getUser()->getBookmarkForBook($book)), - ]; + ]]; } /** diff --git a/src/Kobo/Response/SyncResponse.php b/src/Kobo/Response/SyncResponse.php index e9d96cc5..5d2c320b 100644 --- a/src/Kobo/Response/SyncResponse.php +++ b/src/Kobo/Response/SyncResponse.php @@ -16,7 +16,7 @@ /** * @phpstan-type BookEntitlement array * @phpstan-type BookMetadata array - * @phpstan-type BookReadingState array + * @phpstan-type BookReadingState array> * @phpstan-type BookTag array */ class SyncResponse @@ -217,10 +217,12 @@ private function createBookTagFromShelf(Shelf $shelf): array private function createBookEntitlement(Book $book): array { + $rs = $this->createReadingState($book); + $rs = reset($rs); return [ 'BookEntitlement' => $this->createEntitlement($book), 'BookMetadata' => $this->metadataResponse->fromBook($book, $this->kobo, $this->syncToken), - 'ReadingState' => $this->createReadingState($book), + 'ReadingState' => $rs, ]; } @@ -235,7 +237,9 @@ private function getChangedReadingState(): array return array_map(function (Book $book) { $response = new \stdClass(); - $response->ChangedReadingState = $this->createReadingState($book); + $rs = $this->createReadingState($book); + $rs = reset($rs); + $response->ChangedReadingState = $rs; return $response; }, $books);