Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
Hot-dong committed Jul 3, 2023
2 parents 0581bea + 29deb90 commit 9ac1fbd
Show file tree
Hide file tree
Showing 12 changed files with 2,687 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.khpt.projectkim.controller.api;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.TextNode;
import com.khpt.projectkim.csv.CsvReader;
import com.khpt.projectkim.entity.User;
import com.khpt.projectkim.functions.ApiRequest;
import com.khpt.projectkim.service.ApiRequestService;
import com.khpt.projectkim.service.ChatService;
import com.khpt.projectkim.service.SimplifyJsonService;
import com.khpt.projectkim.service.UserService;
import com.theokanning.openai.completion.chat.*;
import com.theokanning.openai.service.FunctionExecutor;
Expand All @@ -20,12 +22,13 @@
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;

import static com.khpt.projectkim.service.SimplifyJsonService.simplifyJobs;
import static com.khpt.projectkim.service.SimplifyJsonService.simplifyJobs2;
import static com.theokanning.openai.service.OpenAiService.defaultObjectMapper;

@RestController
Expand Down Expand Up @@ -56,7 +59,7 @@ public void init() {
}

@GetMapping("/events")
public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws IOException {
public SseEmitter getChatEvents(HttpSession session, HttpServletResponse response) {
if (session.getAttribute("user") == null) {
System.out.println("Get chat events failed. No session");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Expand All @@ -81,6 +84,8 @@ public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request,
try {
emitter.send(SseEmitter.event().name("info").data("Processing ChatGPT request..."));

List<String> apiResponseRecord = new ArrayList<>();

final List<ChatFunction> functions = Collections.singletonList(ChatFunction.builder()
.name("get_job_info")
.description("Search list of job posting information with given keywords.")
Expand All @@ -92,10 +97,26 @@ public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request,
if (user.getType() != null) params.put("job_type", user.getType());
if (user.getEducation() != null) params.put("edu_lv", user.getEducation());
if (user.getRegion() != null) params.put("loc_mcd", user.getRegion());
params.put("count", "20");
params.put("count", "1");
params.put("access-key", saramin_key);

return apiRequestService.getApiResponseAsString("https://oapi.saramin.co.kr/job-search", params);
String apiResponse;
try {
apiResponse = apiRequestService.getApiResponseAsString("https://oapi.saramin.co.kr/job-search", params);
ObjectMapper mapper = new ObjectMapper();
SimplifyJsonService.Root root = mapper.readValue(apiResponse, SimplifyJsonService.Root.class);

Map<String, List<Map<String, Object>>> simplifiedJobs = simplifyJobs(root);
System.out.println("api res:");
System.out.println(apiResponse);

apiResponseRecord.add(apiResponse);

System.out.println(simplifiedJobs);
return mapper.writeValueAsString(simplifiedJobs);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
// TODO 요청 100개중 커리어가 맞는거 20개 고르기
})
.build());
Expand All @@ -106,6 +127,7 @@ public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request,
.model("gpt-3.5-turbo-16k-0613")
.messages(chatMessages)
.n(1)
.maxTokens(512)
.functions(functionExecutor.getFunctions())
.logitBias(new HashMap<>())
.build();
Expand Down Expand Up @@ -141,7 +163,7 @@ public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request,

ChatMessage message = chunk.getChoices().get(0).getMessage();
if (message.getContent() != null) {
emitter.send(SseEmitter.event().name("message").data(message.getContent().replaceAll(" ", "%20")));
emitter.send(SseEmitter.event().name("message").data(message.getContent().replaceAll(" ", "%20").replaceAll("\n", "%0A")));
} else if (message.getFunctionCall() != null) {
emitter.send(SseEmitter.event().name("function").data("prepare"));
}
Expand All @@ -162,17 +184,35 @@ public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request,
if (accumulatedMessage.getFunctionCall() != null) {
emitter.send(SseEmitter.event().name("function").data("processing"));

if (!(user.getType() != null && user.getRegion() != null && user.getEducation() != null && user.getCategory() != null)) {
emitter.send(SseEmitter.event().name("error").data("사전정보를 입력해주세요")); // TODO add prev error msg to front
emitter.send(SseEmitter.event().name("complete").data("error executing function"));
emitter.complete();
return;
}

ChatMessage callResponse = functionExecutor.executeAndConvertToMessageHandlingExceptions(accumulatedMessage.getFunctionCall());
if (callResponse.getName().equals("error")) {
emitter.send(SseEmitter.event().name("function").data("error"));
emitter.send(SseEmitter.event().name("error").data("사람인 API 요청을 실패하였습니다."));
emitter.send(SseEmitter.event().name("complete").data("error executing function"));
emitter.complete();
return;
}

JsonNode jobDataResponse = functionExecutor.executeAndConvertToJson(accumulatedMessage.getFunctionCall());
System.out.println(jobDataResponse);
// send result
ObjectMapper mapper = new ObjectMapper();
SimplifyJsonService.Root root = mapper.readValue(apiResponseRecord.get(0), SimplifyJsonService.Root.class);
Map<String, List<Map<String, Object>>> simplifiedJobs = simplifyJobs2(root);
String jobDataResponse = mapper.writeValueAsString(simplifiedJobs);
emitter.send(SseEmitter.event().name("result").data(jobDataResponse));
userService.setUserResults(userId, simplifiedJobs);


// TODO add job codes table
chatMessages.add(new ChatMessage(
ChatMessageRole.SYSTEM.value(),
CsvReader.getDetailedJobCode(user.getCategory())
));

chatMessages.add(accumulatedMessage);
chatMessages.add(callResponse);
Expand All @@ -181,6 +221,7 @@ public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request,
.builder()
.model("gpt-3.5-turbo-16k-0613")
.messages(chatMessages)
.maxTokens(512)
.functions(functionExecutor.getFunctions())
.logitBias(new HashMap<>())
.build();
Expand Down Expand Up @@ -216,7 +257,7 @@ public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request,

ChatMessage message = chunk.getChoices().get(0).getMessage();
if (message.getContent() != null) {
emitter.send(SseEmitter.event().name("message").data(message.getContent().replaceAll(" ", "%20")));
emitter.send(SseEmitter.event().name("message").data(message.getContent().replaceAll(" ", "%20").replaceAll("\n", "%0A")));
}
} catch (IOException e) {
throw new RuntimeException(e);
Expand All @@ -227,6 +268,7 @@ public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request,
// onComplete
() -> {
try {
// Save GPT response to DB
chatService.addUserChats(userId, accumulatedMessage2);

emitter.send(SseEmitter.event().name("info").data("ChatGPT processing complete."));
Expand Down Expand Up @@ -261,7 +303,7 @@ public SseEmitter getChatEvents(HttpSession session, HttpServletRequest request,

// (프론트에서 채팅 보내기 클릭 하면 이 함수에 모든 채팅 기록을 줌)
@PostMapping
public ResponseEntity<Void> sendChat(HttpSession session, HttpServletRequest request, HttpServletResponse response, @RequestBody ChatMessage chatMessage) throws IOException {
public ResponseEntity<Void> sendChat(HttpSession session, HttpServletResponse response, @RequestBody ChatMessage chatMessage) {
if (session.getAttribute("user") == null) {
System.out.println("Send chat failed. No session");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Expand Down Expand Up @@ -296,4 +338,11 @@ public String newChat(HttpSession session) {

return "chat";
}

@GetMapping("/test")
public String test(@RequestParam("cd") String cd) {
String result = CsvReader.getDetailedJobCode(cd);
System.out.println(result);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import com.khpt.projectkim.dto.ResultDto;
import com.khpt.projectkim.service.ApiRequestService;
import com.khpt.projectkim.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
Expand All @@ -20,45 +23,17 @@ public class ResultRestController {

private final ApiRequestService apiRequestService;

@GetMapping("/api/chat")
public SseEmitter result() {
final SseEmitter emitter = new SseEmitter();

// Run in separate thread to avoid request timeout
new Thread(() -> {
try {
// Start processing and send initial status to frontend
emitter.send(SseEmitter.event().name("message").data("Processing ChatGPT request..."));

String chatGptResponse = apiRequestService.testService();
emitter.send(SseEmitter.event().name("message").data("ChatGPT processing complete. Weather API processing..."));

String weatherApiResponse = apiRequestService.testService();
emitter.send(SseEmitter.event().name("message").data("Weather API processing complete."));

// Send the responses to the frontend
emitter.send(SseEmitter.event().name("message").data(chatGptResponse));
emitter.send(SseEmitter.event().name("message").data(weatherApiResponse));

emitter.send(SseEmitter.event().name("complete").data("Processing complete"));
emitter.complete();
} catch (IOException e) {
emitter.completeWithError(e);
}
}).start();

return emitter;
}
private final UserService userService;

@GetMapping("/result")
public List<ResultDto> getResult_test(HttpSession session) {
ResultDto responseChat1 = new ResultDto("https://google.com", "comp", "제목", "지역", "대충급여", "대충형태", "대충시간", "몰?루", "경력");
ResultDto responseChat2 = new ResultDto("https://google.com", "comp2", "제목2", "지역2", "대충급여2", "대충형태22", "대충시간22", "몰?루22", "경력22");
ResultDto responseChat3 = new ResultDto("https://google.com", "comp3", "제목3", "지역3", "대충급여3", "대충형태33", "대충시간33", "몰?루33", "경력33");
List<ResultDto> chats = new ArrayList<>();
chats.add(responseChat1);
chats.add(responseChat2);
chats.add(responseChat3);
return chats;
public List<ResultDto> getResult(HttpSession session, HttpServletResponse response) {
if (session.getAttribute("user") == null) {
System.out.println("Get chat failed. No session");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return null;
}
String userId = session.getAttribute("user").toString();

return userService.getUserResultsAsDto(userId);
}
}
57 changes: 57 additions & 0 deletions src/main/java/com/khpt/projectkim/csv/CsvReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.khpt.projectkim.csv;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class CsvReader {
public static String getDetailedJobCode(String job_mid_code) {
String csvFile = "src/main/java/com/khpt/projectkim/csv/job_cd.csv"; // Replace with the actual path to your CSV file
String line;
String csvSplitBy = ",";
StringBuilder extractedRowsString = new StringBuilder();

try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(csvFile), StandardCharsets.UTF_8))) {
// Read the header row
String header = br.readLine();
String[] headers = header.split(csvSplitBy);

// Find the column indices of 'job_mid_cd', 'code', and 'keyword'
int jobMidCdIndex = -1;
int codeIndex = -1;
int keywordIndex = -1;

for (int i = 0; i < headers.length; i++) {
if (headers[i].equals("job_mid_cd")) {
jobMidCdIndex = i;
} else if (headers[i].equals("code")) {
codeIndex = i;
} else if (headers[i].equals("keyword")) {
keywordIndex = i;
}
}

// Print the extracted rows
System.out.println(extractedRowsString.toString());

extractedRowsString.append("code,keyword\n");

// Extract rows where 'job_mid_cd' column is 16
while ((line = br.readLine()) != null) {
String[] row = line.split(csvSplitBy);
if (row.length > jobMidCdIndex && row[jobMidCdIndex].equals(job_mid_code)) {
// Extract 'code' and 'keyword' columns
String code = row[codeIndex];
String keyword = row[keywordIndex];

// Append the extracted row to the result string
extractedRowsString.append(code).append(",").append(keyword).append("\n");
}
}
} catch (IOException e) {
e.printStackTrace();
}

// Print the extracted rows
return extractedRowsString.toString();
}
}
Loading

0 comments on commit 9ac1fbd

Please sign in to comment.