From 842c0345258842eedaa0bd6cd58cac01227ace8b Mon Sep 17 00:00:00 2001 From: hou27 Date: Sat, 30 Sep 2023 15:31:08 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EC=84=9C=EB=B9=84=EC=8A=A4?= =?UTF-8?q?=EC=9A=A9=20auto=20categorize=20method=20=EC=B6=94=EA=B0=80=20-?= =?UTF-8?q?=20#207?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/contents/contents.controller.ts | 17 +++++++- src/contents/contents.service.ts | 65 +++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/contents/contents.controller.ts b/src/contents/contents.controller.ts index 02ba2c2..dfbff5a 100644 --- a/src/contents/contents.controller.ts +++ b/src/contents/contents.controller.ts @@ -335,7 +335,7 @@ export class TestController { async autoCategorize( @Body() autoCategorizeBody: AutoCategorizeBodyDto, ): Promise { - return this.categoryService.autoCategorize(autoCategorizeBody); + return this.categoryService.autoCategorizeForTest(autoCategorizeBody); } } @@ -459,4 +459,19 @@ export class CategoryController { ): Promise { return this.categoryService.loadFrequentCategories(user); } + + @ApiOperation({ + summary: '아티클 카테고리 자동 지정', + description: + '아티클에 적절한 카테고리를 유저의 카테고리 목록에서 찾는 메서드', + }) + @ApiBearerAuth('Authorization') + @UseGuards(JwtAuthGuard) + @Get('auto-categorize') + async autoCategorize( + @AuthUser() user: User, + @Query('link') link: string, + ): Promise { + return this.categoryService.autoCategorize(user, link); + } } diff --git a/src/contents/contents.service.ts b/src/contents/contents.service.ts index ade637f..009c4a0 100644 --- a/src/contents/contents.service.ts +++ b/src/contents/contents.service.ts @@ -806,6 +806,71 @@ export class CategoryService { } async autoCategorize( + user: User, + link: string, + ): Promise { + try { + const userInDb = await this.userRepository.findOneWithCategories(user.id); + if (!userInDb) { + throw new NotFoundException('User not found'); + } + + if (!userInDb.categories) { + throw new NotFoundException('Categories not found'); + } + const categories = userInDb.categories; + const { title, siteName, description } = + await this.contentUtil.getLinkInfo(link); + + const content = await this.contentUtil.getLinkContent(link); + + let questionLines = [ + "You are now auto categorizing machine. You can only answer a single category name or None. Here is the article's information:", + ]; + + if (title) { + questionLines.push(`The title is "${title.trim()}"`); + } + + if (content) { + const contentLength = content.length / 2; + questionLines.push( + `The opening 150 characters of the article read, "${content + .replace(/\s/g, '') + .slice(contentLength - 150, contentLength + 150) + .trim()}"`, + ); + } + + if (description) { + questionLines.push(`The description is ${description.trim()}"`); + } + + if (siteName) { + questionLines.push(`The site's name is "${siteName.trim()}"`); + } + + // Add the category options to the end of the list + questionLines.push( + `Please tell me the most appropriate category among the following. If none are suitable, return None. Here is Category options: [${categories.join( + ', ', + )}]`, + ); + + // Join all lines together into a single string + const question = questionLines.join(' '); + + const response = await this.openaiService.createChatCompletion({ + question, + }); + + return { category: response.choices[0].message?.content || 'None' }; + } catch (e) { + throw e; + } + } + + async autoCategorizeForTest( autoCategorizeBody: AutoCategorizeBodyDto, ): Promise { try { From 1010afcfec7065227ff80677eaca1421fba7fb51 Mon Sep 17 00:00:00 2001 From: hou27 Date: Sat, 30 Sep 2023 16:15:45 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=EC=B5=9C=EC=83=81=EC=9C=84=20?= =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=EB=AA=85=EC=9D=B4=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=EB=90=98=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80=20-?= =?UTF-8?q?=20#207?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/contents/contents.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/contents/contents.service.ts b/src/contents/contents.service.ts index 009c4a0..fa562a5 100644 --- a/src/contents/contents.service.ts +++ b/src/contents/contents.service.ts @@ -493,7 +493,8 @@ export class CategoryService { // check if category exists in user's categories(check if category name is duplicated in same level too) const category = userInDb.categories?.find( (category) => - category.slug === categorySlug && category.parentId === parentId, + category.slug === categorySlug && + (category.parentId === parentId || (!parentId && !category.parentId)), ); // if category doesn't exist, create it From 11225ca4bdb40cac8fd431b0d09c0e30d652f565 Mon Sep 17 00:00:00 2001 From: hou27 Date: Sat, 30 Sep 2023 16:20:54 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20user=EC=9D=98=20category=EB=AA=85?= =?UTF-8?q?=EB=93=A4=EC=9D=84=20=EB=B0=B0=EC=97=B4=EB=A1=9C=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EC=96=B4=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20-=20#207?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit object 배열로 받고 있었기 때문에 정상적으로 동작하지 않았었음 --- src/contents/contents.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contents/contents.service.ts b/src/contents/contents.service.ts index fa562a5..e1435e8 100644 --- a/src/contents/contents.service.ts +++ b/src/contents/contents.service.ts @@ -819,7 +819,7 @@ export class CategoryService { if (!userInDb.categories) { throw new NotFoundException('Categories not found'); } - const categories = userInDb.categories; + const categories = userInDb.categories.map((category) => category.name); const { title, siteName, description } = await this.contentUtil.getLinkInfo(link); From d8614ea519bd914aaaf1c2f364199ae4ce4dcd4c Mon Sep 17 00:00:00 2001 From: hou27 Date: Sat, 30 Sep 2023 16:30:49 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20main=20category=EB=A7=8C=EC=9D=84?= =?UTF-8?q?=20=EB=8C=80=EC=83=81=EC=9C=BC=EB=A1=9C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20#207?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/contents/contents.service.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/contents/contents.service.ts b/src/contents/contents.service.ts index e1435e8..0c61ae4 100644 --- a/src/contents/contents.service.ts +++ b/src/contents/contents.service.ts @@ -819,7 +819,12 @@ export class CategoryService { if (!userInDb.categories) { throw new NotFoundException('Categories not found'); } - const categories = userInDb.categories.map((category) => category.name); + const categories: string[] = []; + userInDb.categories.forEach((category) => { + if (!category.parentId) { + categories.push(category.name); + } + }); const { title, siteName, description } = await this.contentUtil.getLinkInfo(link);