Skip to content

Commit

Permalink
Merge pull request #46 from SWM-SMART/feat/#45
Browse files Browse the repository at this point in the history
STT S3 저장 기능 구현
  • Loading branch information
noparamin authored Nov 11, 2023
2 parents c805bce + e60fe55 commit 459cc6f
Show file tree
Hide file tree
Showing 17 changed files with 356 additions and 155 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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")
Expand All @@ -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);
Expand All @@ -48,18 +54,29 @@ public ResponseEntity<?> uploadAudioFile(@PathVariable(value = "documentID") lon
//String sttResult = sttService.getSTT(path);
ResponseEntity<String> 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<SttData> data = sttService.getSTTData(sttResponseEntity);
lectureNoteService.createLectureNote(documentId, data, sttResult);
//noteService.createNote(documentId, sttResult);

ResponseEntity<KeywordsBodyDto> responseEntity = requestService.requestSTTKeywords(sttResult);
ResponseEntity<KeywordsBodyDto> responseEntity = requestService.requestSTTKeywords(textPdfPath);
List<String> keywords = keywordService.createKeywords(responseEntity, documentId);

// 요약본 요청
String summary = requestService.requestSTTSummary(sttResult);
summaryService.createSummary(documentId, summary);
ResponseEntity<SummaryDto> 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");
Expand All @@ -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);

Expand All @@ -78,12 +95,25 @@ public ResponseEntity<?> updateAudioFile(@PathVariable(value = "documentID") lon
List<SttData> data = sttService.getSTTData(sttResponseEntity);
lectureNoteService.updateLectureNote(documentId, data, sttResult);

ResponseEntity<KeywordsBodyDto> 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<KeywordsBodyDto> responseEntity = requestService.requestSTTKeywords(textPdfPath);
List<String> keywords = keywordService.renewKeywords(responseEntity, documentId); // update

// 요약본 요청
String summary = requestService.requestSTTSummary(sttResult);
summaryService.updateSummary(documentId, summary); // update
ResponseEntity<SummaryDto> summary = requestService.requestSTTSummary(sttResult);
summaryService.updateSummary(documentId, summary.getBody().getSummary()); // update
UploadDto uploadDto = new UploadDto(keywords, data);

whiteboardService.setDataType(documentId, "audio");
Expand Down Expand Up @@ -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<String> 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<KeywordsBodyDto> responseEntity = requestService.requestPdfKeywords(path);
System.out.println(responseEntity.getBody());
ResponseEntity<SummaryDto> responseEntity = requestService.requestPdfSummary(path);
System.out.println(responseEntity.getBody().getSummary());
return new ResponseEntity<>(HttpStatus.OK);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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<String> responseEntity = requestService.requestAnswer(documentId, keywordLabel);
ResponseEntity<AnswerDto> responseEntity = requestService.requestAnswer(documentId, keywordLabel);

return new ResponseEntity<>(responseEntity, HttpStatus.OK);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -41,8 +38,8 @@ public ResponseEntity<?> uploadLearningFile(@PathVariable(value = "documentID")
ResponseEntity<KeywordsBodyDto> responseEntity = requestService.requestPdfKeywords(path);
keywordService.createKeywords(responseEntity, documentId);

String summary = requestService.requestPdfSummary(path);
summaryService.createSummary(documentId, summary);
ResponseEntity<SummaryDto> summary = requestService.requestPdfSummary(path);
summaryService.createSummary(documentId, summary.getBody().getSummary());
whiteboardService.setDataType(documentId, "pdf");

return new ResponseEntity<>(responseEntity.getBody(), HttpStatus.OK);
Expand All @@ -55,8 +52,8 @@ public ResponseEntity<?> updateLearningFile(@PathVariable(value = "documentID")
ResponseEntity<KeywordsBodyDto> responseEntity = requestService.requestPdfKeywords(path);
keywordService.renewKeywords(responseEntity, documentId);

String summary = requestService.requestPdfSummary(path);
summaryService.updateSummary(documentId, summary);
ResponseEntity<SummaryDto> summary = requestService.requestPdfSummary(path);
summaryService.updateSummary(documentId, summary.getBody().getSummary());
whiteboardService.setDataType(documentId, "pdf");

return new ResponseEntity<>(responseEntity.getBody(), HttpStatus.OK);
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/com/smart/watchboard/domain/Note.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/com/smart/watchboard/dto/AnswerDto.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
6 changes: 6 additions & 0 deletions src/main/java/com/smart/watchboard/dto/KeywordsBodyDto.java
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -10,4 +12,8 @@
public class KeywordsBodyDto {
private List<String> keywords;

@JsonCreator
public KeywordsBodyDto(@JsonProperty("keywords") List<String> keywords) {
this.keywords = keywords;
}
}
22 changes: 22 additions & 0 deletions src/main/java/com/smart/watchboard/dto/MindmapRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.smart.watchboard.dto;

import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Getter
@Setter
public class MindmapRequestDto {
private String key;
private String dataType;
private List<String> keywords;
private Long documentId;

public MindmapRequestDto(String key, String dataType, List<String> keywords, Long documentId) {
this.key = key;
this.dataType = dataType;
this.keywords = keywords;
this.documentId = documentId;
}
}
Loading

0 comments on commit 459cc6f

Please sign in to comment.