package ru.soune.nocopy.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import ru.soune.nocopy.dto.file.CheckStatus; import ru.soune.nocopy.entity.file.FileEntity; import ru.soune.nocopy.entity.file.ProtectionStatus; import ru.soune.nocopy.entity.user.ProtectedFileCheck; import ru.soune.nocopy.entity.user.User; import ru.soune.nocopy.repository.FileEntityRepository; import ru.soune.nocopy.repository.UserRepository; import ru.soune.nocopy.service.file.CheckCounterService; import ru.soune.nocopy.service.file.FileStorageService; import org.springframework.http.ContentDisposition; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.io.IOException; @RestController @RequestMapping("/api/files") @Slf4j public class FileController { @Autowired private FileStorageService fileStorageService; @Autowired private FileEntityRepository fileRepository; @Autowired private CheckCounterService checkCounterService; @Autowired private UserRepository userRepository; @GetMapping("/public/{fileId}") public ResponseEntity getPublicFile( @PathVariable String fileId) throws IOException { FileEntity fileEntity = fileRepository.findById(fileId) .orElseThrow(() -> new RuntimeException("File not found")); Resource resource = fileStorageService.loadFileAsResource(fileEntity.getFilePath()); ContentDisposition contentDisposition = ContentDisposition.inline() .filename(fileEntity.getOriginalFileName(), StandardCharsets.UTF_8) .build(); return ResponseEntity.ok() .contentType(new MediaType(fileEntity.getMimeType(), fileEntity.getFileExtension())) .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString()) .body(resource); } @GetMapping("/protected/{fileId}") public ResponseEntity getProtectedFile( @PathVariable String fileId) throws IOException { FileEntity fileEntity = fileRepository.findById(fileId) .orElseThrow(() -> new RuntimeException("File not found")); Resource resource = fileStorageService.loadFileAsResource(fileEntity.getProtectedFilePath()); if (fileEntity.getProtectionStatus() == ProtectionStatus.NOT_PROTECTED || fileEntity.getProtectionStatus() == ProtectionStatus.PROCESSING) { throw new RuntimeException("File is not protected"); } String fileName = fileEntity.getOriginalFileName(); String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8) .replace("+", "%20"); return ResponseEntity.ok() .contentType(new MediaType(fileEntity.getMimeType(), fileEntity.getFileExtension())) .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename*=UTF-8''" + encodedFileName) .body(resource); } @GetMapping("check-file/status/{userId}") public ResponseEntity getStatus(@PathVariable Long userId) { CheckStatus status = checkCounterService.getCurrentStatus(userId); return ResponseEntity.ok(status); } @PostMapping("check-file/update-limit/{userId}/{limit}") public ResponseEntity getStatus(@PathVariable Long userId, @PathVariable Integer limit) { User user = userRepository.findById(userId).orElseThrow(); ProtectedFileCheck protectedFileCheck = checkCounterService.updateLimit(user, limit); return ResponseEntity .ok() .body(protectedFileCheck); } }