Skip to content

Commit

Permalink
Merge pull request #85 from CSID-DGU/backend/fix/CheatingDB
Browse files Browse the repository at this point in the history
BE: [Feature] 부정행위 영상 저장 #6, #26
  • Loading branch information
JongbeomLee623 authored Dec 1, 2024
2 parents 84b2875 + 27c79e4 commit c4a5a8c
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.fortune.eyesee.config;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AmazonS3Config {

@Value("${aws.accessKey}")
private String accessKey;

@Value("${aws.secretKey}")
private String secretKey;

@Value("${aws.region}")
private String region;

@Bean
public AmazonS3 amazonS3() {
// AWS 자격 증명 생성
BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);

// AmazonS3 클라이언트 생성 및 반환
return AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
"/api/sessions/join",
"/api/sessions/student",
"/api/cheatings",
"/api/exams/cheating-types"
"/api/exams/*/cheating-types",
"/api/video"

).permitAll() // 인증 불필요 경로
.anyRequest().authenticated() // 나머지 요청은 인증 필요
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.fortune.eyesee.controller;

import com.fortune.eyesee.service.VideoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

@Slf4j
@RestController
@RequestMapping("/api/video")
public class VideoController {

private final VideoService videoService;

public VideoController(VideoService videoService) {
this.videoService = videoService;
}


@PostMapping
public ResponseEntity<String> uploadVideo(
@RequestParam("userId") Integer userId,
@RequestParam("startOffset") String startOffset, // ISO 8601 형식 문자열
@RequestParam("endOffset") String endOffset, // ISO 8601 형식 문자열
@RequestPart("video") MultipartFile videoFile) {
try {
System.out.println("컨트롤러 호출됨 - userId: " + userId);
System.out.println("파일 크기: " + videoFile.getSize());

// ISO 8601 문자열을 LocalDateTime으로 변환
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME; // ISO 8601 형식 지원
LocalDateTime startDateTime = LocalDateTime.parse(startOffset, formatter);
LocalDateTime endDateTime = LocalDateTime.parse(endOffset, formatter);

System.out.println("시작 시간: " + startDateTime);
System.out.println("종료 시간: " + endDateTime);

String videoUrl = videoService.saveVideo(userId, startDateTime, endDateTime, videoFile);

return ResponseEntity.ok(videoUrl);
} catch (DateTimeParseException e) {
e.printStackTrace();
log.error("날짜 형식 변환 오류: ", e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("잘못된 날짜 형식입니다.");
} catch (Exception e) {
e.printStackTrace();
log.error("Failed to upload video", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to upload video");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.fortune.eyesee.service;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.UUID;

@Service
public class VideoService {

@Value("${aws.bucketName}")
private String bucketName;

private final AmazonS3 amazonS3;

public VideoService(AmazonS3 amazonS3) {
this.amazonS3 = amazonS3;
}

public String saveVideo(Integer userId, LocalDateTime startOffset, LocalDateTime endOffset, MultipartFile videoFile) throws IOException {
String fileName = generateFileName(userId);
String key = "videos/" + userId + "/" + fileName;

try {
// S3에 업로드
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(videoFile.getContentType());
metadata.setContentLength(videoFile.getSize());

amazonS3.putObject(bucketName, key, videoFile.getInputStream(), metadata);

// S3 URL 반환
return amazonS3.getUrl(bucketName, key).toString();

} catch (Exception e) {
throw new IOException("Failed to upload video to S3", e);
}
}

private String generateFileName(Integer userId) {
return userId + "_" + UUID.randomUUID() + ".webm";
}
}

0 comments on commit c4a5a8c

Please sign in to comment.