Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STT S3 저장 기능 구현 #46

Merged
merged 14 commits into from
Nov 11, 2023
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
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