From 138711be866a0595a2534c081fb6319eba205b6e Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 21:17:34 +0900 Subject: [PATCH 01/14] :sparkles: feat: create pdf converter feature #45 --- .../common/support/PdfConverter.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/main/java/com/smart/watchboard/common/support/PdfConverter.java diff --git a/src/main/java/com/smart/watchboard/common/support/PdfConverter.java b/src/main/java/com/smart/watchboard/common/support/PdfConverter.java new file mode 100644 index 0000000..51d9924 --- /dev/null +++ b/src/main/java/com/smart/watchboard/common/support/PdfConverter.java @@ -0,0 +1,39 @@ +package com.smart.watchboard.common.support; + +import com.itextpdf.text.Document; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Paragraph; +import com.itextpdf.text.pdf.PdfWriter; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +public class PdfConverter { + public static File convertStringToPdf(String content, String fileName) throws DocumentException, IOException { + Document document = new Document(); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + try { + PdfWriter.getInstance(document, byteArrayOutputStream); + document.open(); + document.add(new Paragraph(content)); + } finally { + document.close(); + } + + byte[] pdfBytes = byteArrayOutputStream.toByteArray(); + return saveByteArrayToFile(pdfBytes, fileName); + } + + public static File saveByteArrayToFile(byte[] bytes, String fileName) throws IOException { + File outputFile = new File(fileName); + System.out.println(outputFile.getName()); + try (FileOutputStream fos = new FileOutputStream(outputFile)) { + fos.write(bytes); + } + System.out.println(outputFile); + return outputFile; + } +} From 401607e2440abe18962032821cdd29360ccbb906 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 21:18:15 +0900 Subject: [PATCH 02/14] :sparkles: feat: create summaryDto #45 --- .../com/smart/watchboard/dto/SummaryDto.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/com/smart/watchboard/dto/SummaryDto.java diff --git a/src/main/java/com/smart/watchboard/dto/SummaryDto.java b/src/main/java/com/smart/watchboard/dto/SummaryDto.java new file mode 100644 index 0000000..9a5ab33 --- /dev/null +++ b/src/main/java/com/smart/watchboard/dto/SummaryDto.java @@ -0,0 +1,18 @@ +package com.smart.watchboard.dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class SummaryDto { + + private String summary; + + @JsonCreator + public SummaryDto(@JsonProperty("summary") String summary) { + this.summary = summary; + } +} From d834310a16af6c0eee5650995790a2c9f29052bf Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 21:19:07 +0900 Subject: [PATCH 03/14] :sparkles: feat: create answerDto for deserializing ai server response #45 --- .../com/smart/watchboard/dto/AnswerDto.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/com/smart/watchboard/dto/AnswerDto.java diff --git a/src/main/java/com/smart/watchboard/dto/AnswerDto.java b/src/main/java/com/smart/watchboard/dto/AnswerDto.java new file mode 100644 index 0000000..12e9647 --- /dev/null +++ b/src/main/java/com/smart/watchboard/dto/AnswerDto.java @@ -0,0 +1,17 @@ +package com.smart.watchboard.dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AnswerDto { + private String text; + + @JsonCreator + public AnswerDto(@JsonProperty("text") String text) { + this.text = text; + } +} From f5309685628ea883b06b43edc85a84f8e8056873 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 21:20:28 +0900 Subject: [PATCH 04/14] :sparkles: feat: create dto for request #45 --- .../watchboard/dto/RequestBodyToServerDto.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/com/smart/watchboard/dto/RequestBodyToServerDto.java diff --git a/src/main/java/com/smart/watchboard/dto/RequestBodyToServerDto.java b/src/main/java/com/smart/watchboard/dto/RequestBodyToServerDto.java new file mode 100644 index 0000000..6cca8f6 --- /dev/null +++ b/src/main/java/com/smart/watchboard/dto/RequestBodyToServerDto.java @@ -0,0 +1,16 @@ +package com.smart.watchboard.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class RequestBodyToServerDto { + private String key; + private String dataType; + + public RequestBodyToServerDto(String key, String dataType) { + this.key = key; + this.dataType = dataType; + } +} From 6b52610a320e3ed3829220aeafc4ca42af413d00 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 21:21:06 +0900 Subject: [PATCH 05/14] :sparkles: feat: create dto for deserializing ai server response #45 --- .../watchboard/dto/MindmapResponseDto.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/com/smart/watchboard/dto/MindmapResponseDto.java diff --git a/src/main/java/com/smart/watchboard/dto/MindmapResponseDto.java b/src/main/java/com/smart/watchboard/dto/MindmapResponseDto.java new file mode 100644 index 0000000..fe01592 --- /dev/null +++ b/src/main/java/com/smart/watchboard/dto/MindmapResponseDto.java @@ -0,0 +1,24 @@ +package com.smart.watchboard.dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class MindmapResponseDto { + private int root; + private List keywords; + private Map> graph; + + @JsonCreator + public MindmapResponseDto(@JsonProperty("root") int root, @JsonProperty("keywords") List keywords, @JsonProperty("graph") Map> graph) { + this.root = root; + this.keywords = keywords; + this.graph = graph; + } +} From 96b4ebfb6dab3dea57bf7a76f3c0572c7578feef Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 21:22:24 +0900 Subject: [PATCH 06/14] :wrench: feat: add itexpdf #45 --- build.gradle | 2 ++ .../java/com/smart/watchboard/dto/MindmapRequestDto.java | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 src/main/java/com/smart/watchboard/dto/MindmapRequestDto.java diff --git a/build.gradle b/build.gradle index 29b9333..764993f 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,8 @@ dependencies { implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' + implementation 'com.itextpdf:itextpdf:5.5.13.3' + compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' diff --git a/src/main/java/com/smart/watchboard/dto/MindmapRequestDto.java b/src/main/java/com/smart/watchboard/dto/MindmapRequestDto.java new file mode 100644 index 0000000..68f2f5f --- /dev/null +++ b/src/main/java/com/smart/watchboard/dto/MindmapRequestDto.java @@ -0,0 +1,9 @@ +package com.smart.watchboard.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MindmapRequestDto { +} From 9ccd60200de495d4a84303f5d170f6d17dff0d62 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 21:27:50 +0900 Subject: [PATCH 07/14] :hammer: feat: add dto #45 --- .../com/smart/watchboard/dto/MindmapRequestDto.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/com/smart/watchboard/dto/MindmapRequestDto.java b/src/main/java/com/smart/watchboard/dto/MindmapRequestDto.java index 68f2f5f..1238370 100644 --- a/src/main/java/com/smart/watchboard/dto/MindmapRequestDto.java +++ b/src/main/java/com/smart/watchboard/dto/MindmapRequestDto.java @@ -3,7 +3,20 @@ import lombok.Getter; import lombok.Setter; +import java.util.List; + @Getter @Setter public class MindmapRequestDto { + private String key; + private String dataType; + private List keywords; + private Long documentId; + + public MindmapRequestDto(String key, String dataType, List keywords, Long documentId) { + this.key = key; + this.dataType = dataType; + this.keywords = keywords; + this.documentId = documentId; + } } From 85f4e96c9420cd778a5fc21cca0cd54b7a7d1879 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 21:36:44 +0900 Subject: [PATCH 08/14] :hammer: feat: add constructor for deserializing #45 --- src/main/java/com/smart/watchboard/dto/KeywordsBodyDto.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/smart/watchboard/dto/KeywordsBodyDto.java b/src/main/java/com/smart/watchboard/dto/KeywordsBodyDto.java index c6bf557..c1e73a4 100644 --- a/src/main/java/com/smart/watchboard/dto/KeywordsBodyDto.java +++ b/src/main/java/com/smart/watchboard/dto/KeywordsBodyDto.java @@ -1,5 +1,7 @@ package com.smart.watchboard.dto; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; @@ -10,4 +12,8 @@ public class KeywordsBodyDto { private List keywords; + @JsonCreator + public KeywordsBodyDto(@JsonProperty("keywords") List keywords) { + this.keywords = keywords; + } } From aa3297dd641b54f3361f5496c97ba05122ac4241 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 22:23:28 +0900 Subject: [PATCH 09/14] :sparkles: feat: add text to pdf feature #45 --- .../controller/AudioFileController.java | 78 +++++++++++++------ 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/smart/watchboard/controller/AudioFileController.java b/src/main/java/com/smart/watchboard/controller/AudioFileController.java index d7e9d47..e121e79 100644 --- a/src/main/java/com/smart/watchboard/controller/AudioFileController.java +++ b/src/main/java/com/smart/watchboard/controller/AudioFileController.java @@ -1,6 +1,7 @@ package com.smart.watchboard.controller; import com.fasterxml.jackson.core.JsonProcessingException; +import com.itextpdf.text.DocumentException; import com.smart.watchboard.common.support.AwsS3Uploader; import com.smart.watchboard.domain.Document; import com.smart.watchboard.domain.LectureNote; @@ -13,14 +14,19 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.sound.sampled.UnsupportedAudioFileException; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import static com.smart.watchboard.common.support.PdfConverter.convertStringToPdf; + @RestController @RequestMapping("/documents") @Tag(name = "강의 녹음파일 API", description = "강의 녹음파일 관련 API") @@ -39,7 +45,7 @@ public class AudioFileController { private final KeywordService keywordService; @PostMapping("/{documentID}/audio") - public ResponseEntity uploadAudioFile(@PathVariable(value = "documentID") long documentId, @RequestParam("audio") MultipartFile audioFile, @RequestHeader("Authorization") String accessToken) throws UnsupportedAudioFileException, IOException { + public ResponseEntity uploadAudioFile(@PathVariable(value = "documentID") long documentId, @RequestParam("audio") MultipartFile audioFile, @RequestHeader("Authorization") String accessToken) throws UnsupportedAudioFileException, IOException, DocumentException { // 토큰 검증 // s3에 오디오 파일 저장 S3Dto s3Dto = new S3Dto(audioFile, documentId); @@ -48,18 +54,29 @@ public ResponseEntity uploadAudioFile(@PathVariable(value = "documentID") lon //String sttResult = sttService.getSTT(path); ResponseEntity sttResponseEntity = sttService.getSTT(path); String sttResult = sttService.getText(sttResponseEntity); + // convert + String sttFileName = "sttResult.pdf"; + File textPdfFile = convertStringToPdf(sttResult, sttFileName); + + String contentType = "application/pdf"; + String originalFilename = textPdfFile.getName(); + String name = textPdfFile.getName(); + + FileInputStream fileInputStream = new FileInputStream(textPdfFile); + MultipartFile multipartFile = new MockMultipartFile(name, originalFilename, contentType, fileInputStream); + S3Dto s3DtoForSTT = new S3Dto(multipartFile, 26L); + String textPdfPath = awsS3Uploader.uploadTextPdfFile(s3DtoForSTT); + List data = sttService.getSTTData(sttResponseEntity); lectureNoteService.createLectureNote(documentId, data, sttResult); - //noteService.createNote(documentId, sttResult); - ResponseEntity responseEntity = requestService.requestSTTKeywords(sttResult); + ResponseEntity responseEntity = requestService.requestSTTKeywords(textPdfPath); List keywords = keywordService.createKeywords(responseEntity, documentId); // 요약본 요청 - String summary = requestService.requestSTTSummary(sttResult); - summaryService.createSummary(documentId, summary); + ResponseEntity summary = requestService.requestSTTSummary(textPdfPath); + summaryService.createSummary(documentId, summary.getBody().getSummary()); - //String body = fileService.createResponseBody(responseEntity, sttResult); UploadDto uploadDto = new UploadDto(keywords, data); whiteboardService.setDataType(documentId, "audio"); @@ -69,7 +86,7 @@ public ResponseEntity uploadAudioFile(@PathVariable(value = "documentID") lon } @PutMapping("/{documentID}/audio") - public ResponseEntity updateAudioFile(@PathVariable(value = "documentID") long documentId, @RequestParam("audio") MultipartFile audioFile, @RequestHeader("Authorization") String accessToken) throws UnsupportedAudioFileException, IOException { + public ResponseEntity updateAudioFile(@PathVariable(value = "documentID") long documentId, @RequestParam("audio") MultipartFile audioFile, @RequestHeader("Authorization") String accessToken) throws UnsupportedAudioFileException, IOException, DocumentException { S3Dto s3Dto = new S3Dto(audioFile, documentId); String path = awsS3Uploader.uploadFile(s3Dto); @@ -78,12 +95,25 @@ public ResponseEntity updateAudioFile(@PathVariable(value = "documentID") lon List data = sttService.getSTTData(sttResponseEntity); lectureNoteService.updateLectureNote(documentId, data, sttResult); - ResponseEntity responseEntity = requestService.requestSTTKeywords(sttResult); + // convert + String sttFileName = "sttResult.pdf"; + File textPdfFile = convertStringToPdf(sttResult, sttFileName); + + String contentType = "application/pdf"; + String originalFilename = textPdfFile.getName(); + String name = textPdfFile.getName(); + + FileInputStream fileInputStream = new FileInputStream(textPdfFile); + MultipartFile multipartFile = new MockMultipartFile(name, originalFilename, contentType, fileInputStream); + S3Dto s3DtoForSTT = new S3Dto(multipartFile, 26L); + String textPdfPath = awsS3Uploader.uploadTextPdfFile(s3DtoForSTT); + + ResponseEntity responseEntity = requestService.requestSTTKeywords(textPdfPath); List keywords = keywordService.renewKeywords(responseEntity, documentId); // update // 요약본 요청 - String summary = requestService.requestSTTSummary(sttResult); - summaryService.updateSummary(documentId, summary); // update + ResponseEntity summary = requestService.requestSTTSummary(sttResult); + summaryService.updateSummary(documentId, summary.getBody().getSummary()); // update UploadDto uploadDto = new UploadDto(keywords, data); whiteboardService.setDataType(documentId, "audio"); @@ -113,22 +143,26 @@ public ResponseEntity getAudioFile(@PathVariable(value = "documentID") long d } @PostMapping("/testffff") - public ResponseEntity test(@RequestHeader("Authorization") String accessToken) throws UnsupportedAudioFileException, IOException { + public ResponseEntity test(@RequestHeader("Authorization") String accessToken) throws UnsupportedAudioFileException, IOException, DocumentException { String body = """ {"keywords":["eatssss","food","today"]} """; - //ResponseEntity ss = new ResponseEntity<>(body, HttpStatus.OK); -// S3Dto s3Dto = new S3Dto(audioFile, 26L); -// String path = awsS3Uploader.uploadFile(s3Dto); -// int startIndex = path.indexOf("application/pdf/") + "application/pdf/".length(); -// String extractedString = path.substring(startIndex); -// System.out.println(extractedString); -// String path = fileService.getPath(26L); -// Document document = whiteboardService.findDoc(26L); -// String text = lectureNoteService.getText(26L); +// String sttResult = "안녕하세요 Hello!!!!"; +// String sttFileName = "sttResult.pdf"; +// File textPdfFile = convertStringToPdf(sttResult, sttFileName); +// String contentType = "application/pdf"; +// String originalFilename = textPdfFile.getName(); +// String name = textPdfFile.getName(); +// +// +// FileInputStream fileInputStream = new FileInputStream(textPdfFile); +// MultipartFile multipartFile = new MockMultipartFile(name, originalFilename, contentType, fileInputStream); +// S3Dto s3Dto = new S3Dto(multipartFile, 26L); +// String path = awsS3Uploader.uploadTextPdfFile(s3Dto); +// System.out.println(path); String path = "https://s3.ap-northeast-2.amazonaws.com/watchboard-record-bucket/application/pdf/감정분류.pdf"; - ResponseEntity responseEntity = requestService.requestPdfKeywords(path); - System.out.println(responseEntity.getBody()); + ResponseEntity responseEntity = requestService.requestPdfSummary(path); + System.out.println(responseEntity.getBody().getSummary()); return new ResponseEntity<>(HttpStatus.OK); } From eafea2d6bc3eeb368f321987f3490b8f3d3a1e78 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 22:24:16 +0900 Subject: [PATCH 10/14] :hammer: feat: add objectKey #45 --- .../com/smart/watchboard/domain/Note.java | 9 +++++--- .../smart/watchboard/service/NoteService.java | 23 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/smart/watchboard/domain/Note.java b/src/main/java/com/smart/watchboard/domain/Note.java index 85d7dae..e51495c 100644 --- a/src/main/java/com/smart/watchboard/domain/Note.java +++ b/src/main/java/com/smart/watchboard/domain/Note.java @@ -18,10 +18,13 @@ public class Note { @Column(name = "note_id") private Long id; - @Column(length = 16000) - private String content; + private String fileName; + private String objectKey; - //private Long size; + @Column(columnDefinition = "varchar(1000)", nullable = false) + private String path; + + private Long size; private Instant createdAt; private Instant modifiedAt; private boolean isDelete; diff --git a/src/main/java/com/smart/watchboard/service/NoteService.java b/src/main/java/com/smart/watchboard/service/NoteService.java index 9b17476..ba08669 100644 --- a/src/main/java/com/smart/watchboard/service/NoteService.java +++ b/src/main/java/com/smart/watchboard/service/NoteService.java @@ -1,7 +1,9 @@ package com.smart.watchboard.service; import com.smart.watchboard.domain.Document; +import com.smart.watchboard.domain.File; import com.smart.watchboard.domain.Note; +import com.smart.watchboard.dto.FileDto; import com.smart.watchboard.repository.NoteRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -17,10 +19,13 @@ public class NoteService { private final NoteRepository noteRepository; private final WhiteboardService whiteboardService; - public void createNote(Long documentId, String stt) { - Document document = whiteboardService.findDoc(documentId); + public void createNote(FileDto fileDto) { + Document document = whiteboardService.findDoc(fileDto.getDocumentId()); + String key = fileDto.getFileType() + "/" + fileDto.getDocumentId() + "." + fileDto.getFile().getOriginalFilename(); Note note = Note.builder() - .content(stt) + .fileName(fileDto.getFile().getOriginalFilename()) + .objectKey(key) + .path(fileDto.getPath()) .createdAt(Instant.now()) .modifiedAt(Instant.now()) .isDelete(false) @@ -30,10 +35,11 @@ public void createNote(Long documentId, String stt) { noteRepository.save(note); } - public void updateNote(Long documentId, String stt) { - Document document = whiteboardService.findDoc(documentId); + public void updateNote(FileDto fileDto) { + Document document = whiteboardService.findDoc(fileDto.getDocumentId()); Note note = findNote(document); - note.setContent(stt); + note.setFileName(fileDto.getFile().getOriginalFilename()); + note.setPath(fileDto.getPath()); note.setModifiedAt(Instant.now()); noteRepository.save(note); @@ -48,4 +54,9 @@ public void deleteNote(Long documentId) { public Note findNote(Document document) { return noteRepository.findByDocument(document); } + + public Note findByDocument(Long documentId) { + Document document = whiteboardService.findDoc(documentId); + return noteRepository.findByDocument(document); + } } From 0f6f110f4aa6e8e226030d1005cd20dfb00138f0 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 22:25:23 +0900 Subject: [PATCH 11/14] :hammer: feat: add uploadTextPdfFile #45 --- .../common/support/AwsS3Uploader.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/main/java/com/smart/watchboard/common/support/AwsS3Uploader.java b/src/main/java/com/smart/watchboard/common/support/AwsS3Uploader.java index aa1fda0..3e7f4db 100644 --- a/src/main/java/com/smart/watchboard/common/support/AwsS3Uploader.java +++ b/src/main/java/com/smart/watchboard/common/support/AwsS3Uploader.java @@ -4,9 +4,11 @@ import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.*; import com.smart.watchboard.domain.File; +import com.smart.watchboard.domain.Note; import com.smart.watchboard.dto.FileDto; import com.smart.watchboard.dto.S3Dto; import com.smart.watchboard.service.FileService; +import com.smart.watchboard.service.NoteService; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -27,6 +29,7 @@ public class AwsS3Uploader { private static final String S3_BUCKET_DIRECTORY_NAME = "file"; private final AmazonS3Client amazonS3Client; private final FileService fileService; + private final NoteService noteService; @Value("${cloud.aws.s3.bucket}") private String bucket; @@ -58,6 +61,33 @@ public String uploadFile(S3Dto s3Dto) { return amazonS3Client.getUrl(bucket, fileName).toString(); } + public String uploadTextPdfFile(S3Dto s3Dto) { + ObjectMetadata objectMetadata = new ObjectMetadata(); + objectMetadata.setContentType(s3Dto.getFile().getContentType()); + objectMetadata.setContentLength(s3Dto.getFile().getSize()); + + String directoryName = s3Dto.getFile().getContentType(); + String fileName = directoryName + "/" + s3Dto.getDocumentId() + "." + s3Dto.getFile().getOriginalFilename(); + + try (InputStream inputStream = s3Dto.getFile().getInputStream()) { + amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, inputStream, objectMetadata) + .withCannedAcl(CannedAccessControlList.PublicRead)); + + String path = amazonS3Client.getResourceUrl(bucket, fileName); + FileDto fileDto = new FileDto(s3Dto.getFile(), path, s3Dto.getFile().getContentType(), s3Dto.getDocumentId()); + Note note = noteService.findByDocument(s3Dto.getDocumentId()); + if (note == null) { + noteService.createNote(fileDto); + } else if (note != null) { + noteService.updateNote(fileDto); + } + } catch (IOException e) { + log.error("S3 파일 업로드에 실패했습니다. {}", e.getMessage()); + throw new IllegalStateException("S3 파일 업로드에 실패했습니다."); + } + return amazonS3Client.getUrl(bucket, fileName).toString(); + } + public byte[] getFileContent(Long fileId) throws IOException { String objectKey = fileService.findFile(fileId).get().getObjectKey(); S3Object s3Object = amazonS3Client.getObject(bucket, objectKey); From 95749bb5fa9bc7aa816fb32b9538adbe826d8aee Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 22:26:39 +0900 Subject: [PATCH 12/14] :hammer: feat: change responseDto #45 --- .../watchboard/controller/GraphController.java | 3 ++- .../controller/LearningFileController.java | 13 +++++-------- .../com/smart/watchboard/service/SseService.java | 10 ++++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/smart/watchboard/controller/GraphController.java b/src/main/java/com/smart/watchboard/controller/GraphController.java index f24a00d..ce0e88c 100644 --- a/src/main/java/com/smart/watchboard/controller/GraphController.java +++ b/src/main/java/com/smart/watchboard/controller/GraphController.java @@ -1,6 +1,7 @@ package com.smart.watchboard.controller; import com.fasterxml.jackson.core.JsonProcessingException; +import com.smart.watchboard.dto.AnswerDto; import com.smart.watchboard.dto.KeywordsBodyDto; import com.smart.watchboard.dto.KeywordsDto; import com.smart.watchboard.dto.MindmapDto; @@ -69,7 +70,7 @@ public ResponseEntity updateKeywords(@PathVariable(value = "documentID") long @GetMapping("/documents/{documentID}/mindmap/keyword/{keywordLabel}") @Operation(summary = "키워드 질문", description = "키워드 AI에 질문") public ResponseEntity getAnswer(@PathVariable(value = "documentID") long documentId, @PathVariable String keywordLabel, @RequestHeader("Authorization") String accessToken) throws JsonProcessingException { - ResponseEntity responseEntity = requestService.requestAnswer(documentId, keywordLabel); + ResponseEntity responseEntity = requestService.requestAnswer(documentId, keywordLabel); return new ResponseEntity<>(responseEntity, HttpStatus.OK); } diff --git a/src/main/java/com/smart/watchboard/controller/LearningFileController.java b/src/main/java/com/smart/watchboard/controller/LearningFileController.java index 6e08b68..e38d96e 100644 --- a/src/main/java/com/smart/watchboard/controller/LearningFileController.java +++ b/src/main/java/com/smart/watchboard/controller/LearningFileController.java @@ -3,10 +3,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.smart.watchboard.common.support.AwsS3Uploader; import com.smart.watchboard.domain.File; -import com.smart.watchboard.dto.FileDto; -import com.smart.watchboard.dto.KeywordsBodyDto; -import com.smart.watchboard.dto.KeywordsDto; -import com.smart.watchboard.dto.S3Dto; +import com.smart.watchboard.dto.*; import com.smart.watchboard.service.*; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -41,8 +38,8 @@ public ResponseEntity uploadLearningFile(@PathVariable(value = "documentID") ResponseEntity responseEntity = requestService.requestPdfKeywords(path); keywordService.createKeywords(responseEntity, documentId); - String summary = requestService.requestPdfSummary(path); - summaryService.createSummary(documentId, summary); + ResponseEntity summary = requestService.requestPdfSummary(path); + summaryService.createSummary(documentId, summary.getBody().getSummary()); whiteboardService.setDataType(documentId, "pdf"); return new ResponseEntity<>(responseEntity.getBody(), HttpStatus.OK); @@ -55,8 +52,8 @@ public ResponseEntity updateLearningFile(@PathVariable(value = "documentID") ResponseEntity responseEntity = requestService.requestPdfKeywords(path); keywordService.renewKeywords(responseEntity, documentId); - String summary = requestService.requestPdfSummary(path); - summaryService.updateSummary(documentId, summary); + ResponseEntity summary = requestService.requestPdfSummary(path); + summaryService.updateSummary(documentId, summary.getBody().getSummary()); whiteboardService.setDataType(documentId, "pdf"); return new ResponseEntity<>(responseEntity.getBody(), HttpStatus.OK); diff --git a/src/main/java/com/smart/watchboard/service/SseService.java b/src/main/java/com/smart/watchboard/service/SseService.java index 42b9c51..75863fe 100644 --- a/src/main/java/com/smart/watchboard/service/SseService.java +++ b/src/main/java/com/smart/watchboard/service/SseService.java @@ -1,5 +1,7 @@ package com.smart.watchboard.service; +import com.smart.watchboard.domain.Note; +import com.smart.watchboard.dto.MindmapResponseDto; import com.smart.watchboard.repository.EmitterRepository; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -18,7 +20,7 @@ public class SseService { private final WhiteboardService whiteboardService; private final RequestService requestService; private final LectureNoteService lectureNoteService; - private final STTService sttService; + private final NoteService noteService; public SseEmitter subscribe(Long documentId) { SseEmitter emitter = createEmitter(documentId); @@ -49,11 +51,11 @@ private void sendToClient(Long documentId, List keywords) { try { if (whiteboardService.isPdfType(documentId)) { String path = fileService.getPdfUrl(documentId); - ResponseEntity body = requestService.requestPdfMindmap(path, documentId, keywords); + ResponseEntity body = requestService.requestPdfMindmap(path, documentId, keywords); emitter.send(SseEmitter.event().id(String.valueOf(documentId)).name("sse").data(body.getBody())); } else if (whiteboardService.isAudioType(documentId)) { - String text = lectureNoteService.getText(documentId); - ResponseEntity body = requestService.requestSTTMindmap(text, documentId, keywords); + Note note = noteService.findByDocument(documentId); + ResponseEntity body = requestService.requestSTTMindmap(note.getPath(), documentId, keywords); emitter.send(SseEmitter.event().id(String.valueOf(documentId)).name("sse").data(body.getBody())); } } catch (IOException exception) { From 1d00359c5c8e438d1e0d75835d8292d561a476b5 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 22:27:30 +0900 Subject: [PATCH 13/14] :hammer: feat: change String to dto #45 --- .../watchboard/service/RequestService.java | 169 ++++++++---------- 1 file changed, 77 insertions(+), 92 deletions(-) diff --git a/src/main/java/com/smart/watchboard/service/RequestService.java b/src/main/java/com/smart/watchboard/service/RequestService.java index 7e9362f..6da3fee 100644 --- a/src/main/java/com/smart/watchboard/service/RequestService.java +++ b/src/main/java/com/smart/watchboard/service/RequestService.java @@ -1,10 +1,8 @@ package com.smart.watchboard.service; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.smart.watchboard.domain.Summary; -import com.smart.watchboard.dto.KeywordsBodyDto; +import com.smart.watchboard.dto.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -13,6 +11,7 @@ import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; +import java.io.UnsupportedEncodingException; import java.util.List; @@ -36,24 +35,21 @@ public ResponseEntity requestPdfKeywords(String filePath) { HttpHeaders headers = new HttpHeaders(); headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE); - // 요청 본문 추가 - String requestBody = """ - { - "dbInfo": { - "key": "%s", - "db": "s3" - } - } - """.formatted(fileName); - - HttpEntity requestEntity = new HttpEntity<>(requestBody, headers); +// // 요청 본문 추가 +// String requestBody = """ +// { +// "dbInfo": { +// "key": "%s", +// "dataType": "pdf" +// } +// } +// """.formatted(fileName); + RequestBodyToServerDto requestBodyToServerDto = new RequestBodyToServerDto(fileName, "audio"); + HttpEntity requestEntity = new HttpEntity<>(requestBodyToServerDto, headers); // 요청 보내기 try { ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, KeywordsBodyDto.class); //ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); - - System.out.println(responseEntity.getBody()); - //return new ResponseEntity<>(HttpStatus.OK); return responseEntity; } catch (HttpClientErrorException e) { // 에러 응답 처리 @@ -71,24 +67,18 @@ public ResponseEntity requestPdfKeywords(String filePath) { } // 수정필요 - public ResponseEntity requestSTTKeywords(String text) { + public ResponseEntity requestSTTKeywords(String filePath) { + int startIndex = filePath.indexOf("application/pdf/") + "application/pdf/".length(); + String fileName = filePath.substring(startIndex); + RestTemplate restTemplate = new RestTemplate(); String url = aiUrl + "/keywords"; // 요청 헤더 추가 HttpHeaders headers = new HttpHeaders(); headers.set("Content-Type", "application/json"); - // 요청 본문 추가 - //String requestBody = "{\"key\": \"" + filePath + "\", \"db\": \"mysql\"}"; - String requestBody = """ - { - "dbInfo": { - "key": "%s", - "db": "mysql" - } - } - """.formatted(text); - HttpEntity requestEntity = new HttpEntity<>(requestBody, headers); + RequestBodyToServerDto requestBodyToServerDto = new RequestBodyToServerDto(fileName, "pdf"); + HttpEntity requestEntity = new HttpEntity<>(requestBodyToServerDto, headers); // 요청 보내기 ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, KeywordsBodyDto.class); @@ -96,39 +86,44 @@ public ResponseEntity requestSTTKeywords(String text) { return responseEntity; } - public String requestPdfSummary(String filePath) throws JsonProcessingException { + public ResponseEntity requestPdfSummary(String filePath) throws JsonProcessingException, UnsupportedEncodingException { int startIndex = filePath.indexOf("application/pdf/") + "application/pdf/".length(); String fileName = filePath.substring(startIndex); + System.out.println(fileName); RestTemplate restTemplate = new RestTemplate(); String url = aiUrl + "/summary"; //String url = "http://echo.jsontest.com/key/value/one/two"; // 요청 헤더 추가 HttpHeaders headers = new HttpHeaders(); - headers.set("Content-Type", "application/json"); + headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE); - // 요청 본문 추가 - String requestBody = """ - { - "dbInfo": { - "key": "%s", - "db": "s3" - } - } - """.formatted(fileName); - HttpEntity requestEntity = new HttpEntity<>(requestBody, headers); +// // 요청 본문 추가 +// String requestBody = """ +// { +// "key": "%s", +// "dataType": "pdf" +// } +// """.formatted(fileName); + + RequestBodyToServerDto requestBodyToServerDto = new RequestBodyToServerDto(fileName, "pdf"); + HttpEntity requestEntity = new HttpEntity<>(requestBodyToServerDto, headers); // 요청 보내기 - ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, SummaryDto.class); //ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); - ObjectMapper objectMapper = new ObjectMapper(); - JsonNode jsonNode = objectMapper.readTree(responseEntity.getBody()); - String text = jsonNode.get("summary").asText(); +// responseEntity.getBody(). +// ObjectMapper objectMapper = new ObjectMapper(); +// JsonNode jsonNode = objectMapper.readTree(responseEntity.getBody()); +// String text = jsonNode.get("summary").asText(); - return text; + return responseEntity; } - public String requestSTTSummary(String sttResult) throws JsonProcessingException { + public ResponseEntity requestSTTSummary(String filePath) throws JsonProcessingException { + int startIndex = filePath.indexOf("application/pdf/") + "application/pdf/".length(); + String fileName = filePath.substring(startIndex); + RestTemplate restTemplate = new RestTemplate(); String url = aiUrl + "/summary"; //String url = "http://echo.jsontest.com/key/value/one/two"; @@ -136,31 +131,26 @@ public String requestSTTSummary(String sttResult) throws JsonProcessingException HttpHeaders headers = new HttpHeaders(); headers.set("Content-Type", "application/json"); - // 요청 본문 추가 - String requestBody = """ - { - "dbInfo": { - "key": "%s", - "db": "mysql" - } - } - """.formatted(sttResult); - HttpEntity requestEntity = new HttpEntity<>(requestBody, headers); + RequestBodyToServerDto requestBodyToServerDto = new RequestBodyToServerDto(fileName, "audio"); + HttpEntity requestEntity = new HttpEntity<>(requestBodyToServerDto, headers); // 요청 보내기 - ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, SummaryDto.class); //ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); - ObjectMapper objectMapper = new ObjectMapper(); - JsonNode jsonNode = objectMapper.readTree(responseEntity.getBody()); - String text = jsonNode.get("summary").asText(); +// ObjectMapper objectMapper = new ObjectMapper(); +// JsonNode jsonNode = objectMapper.readTree(responseEntity.getBody()); +// String text = jsonNode.get("summary").asText(); //return responseEntity; - return text; + return responseEntity; } - public ResponseEntity requestPdfMindmap(String filePath, Long documentId, List keywords) throws JsonProcessingException { + public ResponseEntity requestPdfMindmap(String filePath, Long documentId, List keywords) throws JsonProcessingException { + int startIndex = filePath.indexOf("application/pdf/") + "application/pdf/".length(); + String fileName = filePath.substring(startIndex); + RestTemplate restTemplate = new RestTemplate(); String url = aiUrl + "/mindmap"; //String url = "http://echo.jsontest.com/key/value/one/two"; @@ -168,21 +158,23 @@ public ResponseEntity requestPdfMindmap(String filePath, Long documentId HttpHeaders headers = new HttpHeaders(); headers.set("Content-Type", "application/json"); - // 요청 본문 추가 - String requestBody = """ - { - "dbInfo": { - "key": "%s", - "db": "s3" - }, - "keywords": "%s", - "documentId": %d - } - """.formatted(filePath, keywords.toString(), documentId); - HttpEntity requestEntity = new HttpEntity<>(requestBody, headers); +// // 요청 본문 추가 +// String requestBody = """ +// { +// "dbInfo": { +// "key": "%s", +// "dataType": "pdf" +// }, +// "keywords": "%s", +// "documentId": %d +// } +// """.formatted(filePath, keywords.toString(), documentId); +// HttpEntity requestEntity = new HttpEntity<>(requestBody, headers); + MindmapRequestDto mindmapRequestDto = new MindmapRequestDto(fileName, "pdf", keywords, documentId); + HttpEntity requestEntity = new HttpEntity<>(mindmapRequestDto, headers); // 요청 보내기 - ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, MindmapResponseDto.class); // 마인드맵 mongoDB에 저장 mindmapService.createMindmap(responseEntity, documentId); @@ -190,7 +182,10 @@ public ResponseEntity requestPdfMindmap(String filePath, Long documentId return responseEntity; } - public ResponseEntity requestSTTMindmap(String stt, Long documentId, List keywords) throws JsonProcessingException { + public ResponseEntity requestSTTMindmap(String filePath, Long documentId, List keywords) throws JsonProcessingException { + int startIndex = filePath.indexOf("application/pdf/") + "application/pdf/".length(); + String fileName = filePath.substring(startIndex); + RestTemplate restTemplate = new RestTemplate(); String url = aiUrl + "/mindmap"; //String url = "http://echo.jsontest.com/key/value/one/two"; @@ -198,28 +193,18 @@ public ResponseEntity requestSTTMindmap(String stt, Long documentId, Lis HttpHeaders headers = new HttpHeaders(); headers.set("Content-Type", "application/json"); - // 요청 본문 추가 - String requestBody = """ - { - "dbInfo": { - "key": "%s", - "db": "mysql" - }, - "keywords": "%s", - "documentId": %d - } - """.formatted(stt, keywords.toString(), documentId); - HttpEntity requestEntity = new HttpEntity<>(requestBody, headers); + MindmapRequestDto mindmapRequestDto = new MindmapRequestDto(fileName, "pdf", keywords, documentId); + HttpEntity requestEntity = new HttpEntity<>(mindmapRequestDto, headers); // 요청 보내기 - ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, MindmapResponseDto.class); mindmapService.createMindmap(responseEntity, documentId); return responseEntity; } - public ResponseEntity requestAnswer(Long documentId, String keywordLabel) throws JsonProcessingException { + public ResponseEntity requestAnswer(Long documentId, String keywordLabel) throws JsonProcessingException { Summary summary = summaryService.findSummary(documentId); RestTemplate restTemplate = new RestTemplate(); String url = aiUrl + "/question"; @@ -235,7 +220,7 @@ public ResponseEntity requestAnswer(Long documentId, String keywordLabel """.formatted(summary.getContent(), keywordLabel); HttpEntity requestEntity = new HttpEntity<>(requestBody, headers); - ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, AnswerDto.class); return responseEntity; } From e60fe5556122750214246fe1e2d911fe8215c8e2 Mon Sep 17 00:00:00 2001 From: kms Date: Sat, 11 Nov 2023 22:27:45 +0900 Subject: [PATCH 14/14] :hammer: feat: change String to dto #45 --- .../watchboard/service/MindmapService.java | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/smart/watchboard/service/MindmapService.java b/src/main/java/com/smart/watchboard/service/MindmapService.java index 0a8e989..6dcede6 100644 --- a/src/main/java/com/smart/watchboard/service/MindmapService.java +++ b/src/main/java/com/smart/watchboard/service/MindmapService.java @@ -1,13 +1,10 @@ package com.smart.watchboard.service; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.smart.watchboard.domain.Document; import com.smart.watchboard.domain.Mindmap; -import com.smart.watchboard.dto.KeywordsDto; import com.smart.watchboard.dto.MindmapDto; +import com.smart.watchboard.dto.MindmapResponseDto; import com.smart.watchboard.repository.MindmapRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -15,9 +12,6 @@ import org.springframework.stereotype.Service; import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import java.util.Optional; @Service @@ -28,16 +22,16 @@ public class MindmapService { private final MindmapRepository mindmapRepository; private final WhiteboardService whiteboardService; - public void createMindmap(ResponseEntity responseEntity, Long documentId) throws JsonProcessingException { + public void createMindmap(ResponseEntity responseEntity, Long documentId) throws JsonProcessingException { Document document = whiteboardService.findDoc(documentId); - ObjectMapper objectMapper = new ObjectMapper(); - JsonNode jsonNode = objectMapper.readTree(responseEntity.getBody()); - Integer root = jsonNode.get("root").asInt(); - JsonNode keywordsNode = jsonNode.get("keywords"); - List keywords = objectMapper.convertValue(keywordsNode, new TypeReference>() {}); - JsonNode graphNode = jsonNode.get("graph"); - Map> graphMap = objectMapper.convertValue(graphNode, new TypeReference>>() {}); +// ObjectMapper objectMapper = new ObjectMapper(); +// JsonNode jsonNode = objectMapper.readTree(responseEntity.getBody()); +// Integer root = jsonNode.get("root").asInt(); +// JsonNode keywordsNode = jsonNode.get("keywords"); +// List keywords = objectMapper.convertValue(keywordsNode, new TypeReference>() {}); +// JsonNode graphNode = jsonNode.get("graph"); +// Map> graphMap = objectMapper.convertValue(graphNode, new TypeReference>>() {}); Optional formerMindmap = mindmapRepository.findByDocumentId(documentId); if (formerMindmap.isPresent()) { @@ -47,8 +41,8 @@ public void createMindmap(ResponseEntity responseEntity, Long documentId .documentName(document.getDocumentName()) .createdAt(formerMindmap.get().getCreatedAt()) .modifiedAt(Instant.now()) - .root(root) - .graph(graphMap) + .root(responseEntity.getBody().getRoot()) + .graph(responseEntity.getBody().getGraph()) .build(); mindmapRepository.save(mindmap); } else if (!formerMindmap.isPresent()) { @@ -57,8 +51,8 @@ public void createMindmap(ResponseEntity responseEntity, Long documentId .documentName(document.getDocumentName()) .createdAt(Instant.now()) .modifiedAt(Instant.now()) - .root(root) - .graph(graphMap) + .root(responseEntity.getBody().getRoot()) + .graph(responseEntity.getBody().getGraph()) .build(); mindmapRepository.save(mindmap); }