From 8ac848e8f1fd280a30218c5ae58ba411da7a7abc Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 20 Jun 2025 15:40:08 +0000 Subject: [PATCH] Changed library search via API to use search context. --- .../src/library/library.consumer.ts | 2 +- .../contexts/google.search.context.ts | 18 +++++++++++--- .../src/providers/contexts/search.context.ts | 5 ++-- .../contexts/simplified-search-context.ts | 24 +++++++++++++++++++ .../src/providers/google/google.service.ts | 3 +-- .../src/providers/providers.controller.ts | 10 ++++---- 6 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 backend/nestjs-seshat-api/src/providers/contexts/simplified-search-context.ts diff --git a/backend/nestjs-seshat-api/src/library/library.consumer.ts b/backend/nestjs-seshat-api/src/library/library.consumer.ts index 5c17abc..ea83968 100644 --- a/backend/nestjs-seshat-api/src/library/library.consumer.ts +++ b/backend/nestjs-seshat-api/src/library/library.consumer.ts @@ -54,7 +54,7 @@ export class LibraryConsumer extends WorkerHost { const series: SeriesSubscriptionJobDto = job.data; const existingBooks = await this.library.findBooksFromSeries(series); const existingVolumes = existingBooks.map(b => b.volume); - const lastPublishedBook = existingBooks.sort((a, b) => b.publishedAt.getTime() - a.publishedAt.getTime())[0]; + const lastPublishedBook = existingBooks.reduce((a, b) => a.publishedAt.getTime() > b.publishedAt.getTime() ? a : b); const books = await this.search(job, series, lastPublishedBook?.publishedAt); let counter = 0; diff --git a/backend/nestjs-seshat-api/src/providers/contexts/google.search.context.ts b/backend/nestjs-seshat-api/src/providers/contexts/google.search.context.ts index 615e032..50d7eb0 100644 --- a/backend/nestjs-seshat-api/src/providers/contexts/google.search.context.ts +++ b/backend/nestjs-seshat-api/src/providers/contexts/google.search.context.ts @@ -6,7 +6,7 @@ export class GoogleSearchContext extends SearchContext { } - generateQueryParams() { + generateQueryParams(): string { const filterParams = ['maxResults', 'startIndex', 'orderBy']; const searchParams = ['intitle', 'inauthor', 'inpublisher', 'subject', 'isbn']; @@ -120,12 +120,24 @@ export class GoogleSearchContext extends SearchContext { } } - next() { + previous(pageCount: number = 1): GoogleSearchContext { + if (pageCount > 0) + return this.update(-pageCount); + return this; + } + + next(pageCount: number = 1): GoogleSearchContext { + if (pageCount > 0) + return this.update(pageCount); + return this; + } + + private update(pageChange: number): GoogleSearchContext { const resultsPerPage = this.params['maxResults'] ? parseInt(this.params['maxResults']) : 10; const index = this.params['startIndex'] ? parseInt(this.params['startIndex']) : 0; const data = { ...this.params }; - data['startIndex'] = (index + resultsPerPage).toString(); + data['startIndex'] = Math.max(0, index + resultsPerPage * pageChange).toString(); return new GoogleSearchContext(this.search, data); } diff --git a/backend/nestjs-seshat-api/src/providers/contexts/search.context.ts b/backend/nestjs-seshat-api/src/providers/contexts/search.context.ts index 3884fcc..0702b8b 100644 --- a/backend/nestjs-seshat-api/src/providers/contexts/search.context.ts +++ b/backend/nestjs-seshat-api/src/providers/contexts/search.context.ts @@ -9,6 +9,7 @@ export abstract class SearchContext { this.params = params; } - abstract generateQueryParams(); - abstract next(); + abstract generateQueryParams(): string; + abstract previous(pageCount: number): SearchContext; + abstract next(pageCount: number): SearchContext; } \ No newline at end of file diff --git a/backend/nestjs-seshat-api/src/providers/contexts/simplified-search-context.ts b/backend/nestjs-seshat-api/src/providers/contexts/simplified-search-context.ts new file mode 100644 index 0000000..edd8e53 --- /dev/null +++ b/backend/nestjs-seshat-api/src/providers/contexts/simplified-search-context.ts @@ -0,0 +1,24 @@ +import { GoogleSearchContext } from "./google.search.context"; +import { SearchContext } from "./search.context"; + +export class SimplifiedSearchContext { + values: { [key: string]: string }; + + constructor(values: { [key: string]: string }) { + this.values = values; + } + + toSearchContext(): SearchContext | null { + const provider = this.values['provider']?.toString().toLowerCase(); + const search = this.values['search']?.toString(); + const valuesCopy = { ...this.values }; + delete valuesCopy['provider']; + delete valuesCopy['search']; + + if (provider == 'google') { + return new GoogleSearchContext(search, valuesCopy) + } + console.log('abc4') + return null; + } +} \ No newline at end of file diff --git a/backend/nestjs-seshat-api/src/providers/google/google.service.ts b/backend/nestjs-seshat-api/src/providers/google/google.service.ts index e83e678..e60c99a 100644 --- a/backend/nestjs-seshat-api/src/providers/google/google.service.ts +++ b/backend/nestjs-seshat-api/src/providers/google/google.service.ts @@ -12,7 +12,7 @@ export class GoogleService { ) { } async searchRaw(searchQuery: string): Promise { - const queryParams = 'langRestrict=en&printType=books&maxResults=10&fields=items(kind,id,volumeInfo(title,description,authors,publisher,publishedDate,industryIdentifiers,language,categories,maturityRating,imageLinks,canonicalVolumeLink,seriesInfo))&q='; + const queryParams = 'langRestrict=en&printType=books&maxResults=20&fields=items(kind,id,volumeInfo(title,description,authors,publisher,publishedDate,industryIdentifiers,language,categories,maturityRating,imageLinks,canonicalVolumeLink,seriesInfo))&q='; return await firstValueFrom( this.http.get('https://www.googleapis.com/books/v1/volumes?' + queryParams + searchQuery) @@ -46,7 +46,6 @@ export class GoogleService { } return response.data.items - //.filter(item => item.volumeInfo?.canonicalVolumeLink?.startsWith('https://play.google.com/store/books/details')) .map(item => this.extract(item)); } diff --git a/backend/nestjs-seshat-api/src/providers/providers.controller.ts b/backend/nestjs-seshat-api/src/providers/providers.controller.ts index 08da0f0..8537edb 100644 --- a/backend/nestjs-seshat-api/src/providers/providers.controller.ts +++ b/backend/nestjs-seshat-api/src/providers/providers.controller.ts @@ -1,7 +1,7 @@ -import { Body, Controller, Get, UseGuards } from '@nestjs/common'; +import { Controller, Get, Query, UseGuards } from '@nestjs/common'; import { ProvidersService } from './providers.service'; -import { BookSearchInputDto } from './dto/book-search-input.dto'; import { JwtAccessGuard } from 'src/auth/guards/jwt-access.guard'; +import { SimplifiedSearchContext } from './contexts/simplified-search-context'; @Controller('providers') export class ProvidersController { @@ -12,8 +12,10 @@ export class ProvidersController { @UseGuards(JwtAccessGuard) @Get('search') async Search( - @Body() body: BookSearchInputDto, + @Query() context, ) { - return await this.providers.searchRaw(body.provider, body.query); + const simplified = new SimplifiedSearchContext(context); + const searchContext = simplified.toSearchContext(); + return await this.providers.search(searchContext); } }