Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test-server-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ jobs:
- name: Test with Gradle
# 테스트 단계에서 RabbitMQ 연결을 위한 환경 변수 설정
env:
SPRING_PROFILES_ACTIVE: test
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
SPRING_RABBITMQ_HOST: localhost
SPRING_RABBITMQ_USERNAME: guest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class ApiV1NewsController {
private final NewsAPIService newsSearchService;
private final NewsService newsService;


/**
* 최신 뉴스 목록을 조회하는 API
* 한번에 100개를 조회 합니다.
Expand Down Expand Up @@ -98,4 +99,33 @@ public Mono<ResponseEntity<RsData<ResBodyForNaverNews>>> searchNewsByRecommends(
response
)));
}

/**
* 공유 아카이브의 폴더 내부의 자료를 기반으로 키워드를 추천해서 검색하는 뉴스 API
* HTTP METHOD: GET
* 한번에 100개를 조회 합니다.
* @param userDetails 로그인한 사용자
* @param spaceId 대상 스페이스 id
* @param folderId 대상 폴더 id
*/
@GetMapping("/recommends/shared/{spaceId}/{folderId}")
@Operation(summary = "공유 아카이브 뉴스 추천")
public Mono<ResponseEntity<RsData<ResBodyForNaverNews>>> searchNewsByRecommends(
@AuthenticationPrincipal CustomUserDetails userDetails,
@PathVariable Integer spaceId,
@PathVariable Integer folderId
) {
Member member = userDetails.getMember();
List<String> frequency = newsService.getTagFrequencyFromFilesInSharing(spaceId, member.getId(), folderId);
String query = String.join(" ", frequency);

return newsSearchService.searchNews(query, "sim")
.map(response -> ResponseEntity
.status(HttpStatus.OK)
.body(new RsData<>(
"200",
"키워드 기반 뉴스 목록을 조회했습니다.",
response
)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import org.tuna.zoopzoop.backend.domain.archive.folder.service.PersonalArchiveFolderService;
import org.tuna.zoopzoop.backend.domain.datasource.dto.FileSummary;
import org.tuna.zoopzoop.backend.domain.datasource.dto.FolderFilesDto;
import org.tuna.zoopzoop.backend.domain.member.entity.Member;
import org.tuna.zoopzoop.backend.domain.member.service.MemberService;
import org.tuna.zoopzoop.backend.domain.space.archive.service.SpaceArchiveFolderService;

import java.util.Comparator;
import java.util.List;
Expand All @@ -15,6 +18,8 @@
@RequiredArgsConstructor
public class NewsService {
private final PersonalArchiveFolderService folderService;
private final SpaceArchiveFolderService spaceArchiveFolderService;
private final MemberService memberService;

public List<String> getTagFrequencyFromFiles(Integer memberId, Integer folderId) {
FolderFilesDto folderFilesDto = folderService.getFilesInFolder(memberId, folderId);
Expand All @@ -39,4 +44,29 @@ public List<String> getTagFrequencyFromFiles(Integer memberId, Integer folderId)

return frequency;
}

public List<String> getTagFrequencyFromFilesInSharing(Integer spaceId, Integer memberId, Integer folderId) {
Member member = memberService.findById(memberId);
FolderFilesDto folderFilesDto = spaceArchiveFolderService.getFilesInFolder(spaceId, member, folderId);

List<FileSummary> files = folderFilesDto.files();

Map<String, Long> tags = files.stream()
.flatMap(file -> {
List<String> ts = file.tags();
return (ts == null ? List.<String>of() : ts).stream();
})
.collect(Collectors.groupingBy(
tagName -> tagName,
Collectors.counting()
));

List<String> frequency = tags.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.limit(3)
.map(Map.Entry::getKey)
.toList();

return frequency;
}
}
70 changes: 16 additions & 54 deletions src/main/resources/application-secrets.yml.template
Original file line number Diff line number Diff line change
@@ -1,55 +1,17 @@
spring:
security:
oauth2:
client:
registration:
kakao:
client-id: {KAKAO_CLIENT_ID}
client-secret: ""
redirect-uri: {KAKAO_REDIRECT_URL}
scope:
- {SCOPE_LIST}
authorization-grant-type: {AUTHORIZATION_GRANT_TYPE}
google:
client-id: {GOOGLE_CLIENT_ID}
client-secret: {GOOGLE_SECRET}
redirect-uri: {GOOGLE_REDIRECT_URL}
scope:
- {SCOPE_LIST}
authorization-grant-type: {AUTHORIZATION_GRANT_TYPE}
provider:
kakao:
authorization-uri: https://kauth.kakao.com/oauth/authorize
token-uri: https://kauth.kakao.com/oauth/token
user-info-uri: https://kapi.kakao.com/v2/user/me
user-name-attribute: id
google:
authorization-uri: https://accounts.google.com/o/oauth2/v2/auth
token-uri: https://oauth2.googleapis.com/token
user-info-uri: https://www.googleapis.com/oauth2/v3/userinfo
user-name-attribute: sub
cloud:
aws:
credentials:
access-key: {AWS_ACCESS_KEY}
secret-key: {AWS_SECRET_KEY}
region:
static: {AWS_REGION}
s3:
bucket: {AWS_S3_BUCKET_NAME}
stack:
auto: false
OPENAI_API_KEY: {YOUR_VALUE}
KAKAO_CLIENT_ID: {YOUR_VALUE}
GOOGLE_CLIENT_ID: {YOUR_VALUE}
GOOGLE_CLIENT_SECRET: {YOUR_VALUE}
AWS_ACCESS_KEY_ID: {YOUR_VALUE}
AWS_SECRET_ACCESS_KEY: {YOUR_VALUE}
AWS_S3_BUCKET_NAME: {YOUR_VALUE}
SENTRY_DSN: {YOUR_VALUE}
JWT_SECRET_KEY: {YOUR_VALUE}
JWT_ACCESS_TOKEN_VALIDITY: {YOUR_VALUE}
JWT_REFRESH_TOKEN_VALIDITY: {YOUR_VALUE}
NAVER_CLIENT_ID: {YOUR_VALUE}
NAVER_CLIENT_SECRET: {YOUR_VALUE}
LIVEBLOCKS_SECRET_KEY: {YOUR_VALUE}
REDIRECT_DOMAIN: {YOUR_VALUE}

naver:
client_id: {NAVER_CLIENT_ID}
client_secret: {NAVER_CLIENT_SECRET}

jwt:
secret-key: {JWT_SECRET_KEY}
access-token-validity: {ACCESSTOKEN_VALIDITY}
refresh-token-validity: {REFRESHTOKEN_VALIDITY}

OPENAI_API_KEY: {OPENAI_API_KEY}

liveblocks:
secret-key: {LIVEBLOCKS_SECRET_KEY}
#SENTRY_AUTH_TOKEN -> 따로 시스템 환경 변수로 설정.