diff --git a/.yarn/cache/@types-node-npm-18.17.12-b09ca14003-79f8bcca30.zip b/.yarn/cache/@types-node-npm-18.17.12-b09ca14003-79f8bcca30.zip deleted file mode 100644 index 45ec760a..00000000 Binary files a/.yarn/cache/@types-node-npm-18.17.12-b09ca14003-79f8bcca30.zip and /dev/null differ diff --git a/apps/backend/src/app/app.controller.ts b/apps/backend/src/app/app.controller.ts index 508e4375..278201a1 100644 --- a/apps/backend/src/app/app.controller.ts +++ b/apps/backend/src/app/app.controller.ts @@ -6,6 +6,7 @@ import { Param, ParseIntPipe, Post, + Query, UseGuards, } from '@nestjs/common'; @@ -23,11 +24,14 @@ import { } from './app.model'; import { ApiResponse } from '@nestjs/swagger'; +import { firefox } from 'playwright'; +import { Page as PlayPage } from 'playwright'; + @Controller() export class AppController { constructor( private readonly appService: AppService, - private readonly lovDb: LovDb + private readonly lovDb: LovDb, ) {} @Get() @@ -41,6 +45,57 @@ export class AppController { return 'test'; } + @Get('play') + async play(@Query('url') url: string) { + if (!url) { + throw new HttpException('url is required', 400); + } + + const browser = await firefox.launch({ headless: false }); + const context = await browser.newContext(); + const page = await context.newPage(); + + await page.goto(url, { + waitUntil: 'domcontentloaded', + timeout: 60000, + }); + + await page.waitForTimeout(4000); + + async function getRedfinPropertyValueFromPage(page: PlayPage) { + const scriptEls = await page.$$('script[type="application/ld+json"]'); + const elTexts = await Promise.all( + scriptEls.map(async (el) => { + const text = await el.innerText(); + console.log('text', text); + try { + const json = JSON.parse(text); + + return json; + } catch (e) { + return; + } + }), + ); + + console.log('elTexts', elTexts); + + const sfrPropertyEl = elTexts + .filter((el) => el) + .find((el) => { + const type = el['@type']; + + return type?.[0] === 'Product'; + }); + + return sfrPropertyEl.offers.price; + } + + const price = await getRedfinPropertyValueFromPage(page); + + return price; + } + @ApiResponse({ type: Page, status: 201 }) @Post('page') async createPage(@Body() input: CreatePageInput): Promise { @@ -104,7 +159,7 @@ export class AppController { @ApiResponse({ type: PageWithQuestions, status: 200 }) @Get('page/:id/questions') async getPageQuestions( - @Param('id', ParseIntPipe) pageId: number + @Param('id', ParseIntPipe) pageId: number, ): Promise { const page = await this.lovDb.page.findUnique({ where: { @@ -166,7 +221,7 @@ export class AppController { @ApiResponse({ type: Answer, status: 200, isArray: true }) @Get('question/:id/answers') async getQuestionAnswers( - @Param('id', ParseIntPipe) questionId: number + @Param('id', ParseIntPipe) questionId: number, ): Promise { const answers = await this.lovDb.answer.findMany({ where: { diff --git a/package.json b/package.json index ef20e8fa..f5fb1496 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "axios": "^1.0.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", + "playwright": "^1.40.1", "posthog-js": "^1.42.2", "prisma": "^5.1.1", "reflect-metadata": "^0.1.13", diff --git a/yarn.lock b/yarn.lock index f1bbd55e..7cfed2d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8577,7 +8577,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": +"fsevents@npm:2.3.2, fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.2 resolution: "fsevents@npm:2.3.2" dependencies: @@ -8587,7 +8587,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": +"fsevents@patch:fsevents@2.3.2#~builtin, fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.2 resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=df0bf1" dependencies: @@ -12913,6 +12913,30 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.40.1": + version: 1.40.1 + resolution: "playwright-core@npm:1.40.1" + bin: + playwright-core: cli.js + checksum: 84d92fb9b86e3c225b16b6886bf858eb5059b4e60fa1205ff23336e56a06dcb2eac62650992dede72f406c8e70a7b6a5303e511f9b4bc0b85022ede356a01ee0 + languageName: node + linkType: hard + +"playwright@npm:^1.40.1": + version: 1.40.1 + resolution: "playwright@npm:1.40.1" + dependencies: + fsevents: 2.3.2 + playwright-core: 1.40.1 + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 9e36791c1b4a649c104aa365fdd9d049924eeb518c5967c0e921aa38b9b00994aa6ee54784d6c2af194b3b494b6f69772673081ef53c6c4a4b2065af9955c4ba + languageName: node + linkType: hard + "pluralize@npm:8.0.0": version: 8.0.0 resolution: "pluralize@npm:8.0.0" @@ -16096,6 +16120,7 @@ __metadata: jest: 29.6.4 jest-environment-jsdom: 29.6.4 nx: ^16.0.0 + playwright: ^1.40.1 posthog-js: ^1.42.2 prettier: ^3.0.0 prettier-plugin-svelte: ^3.0.0