Merge branch 'dev' into NCBACK-33
# Conflicts: # src/main/java/ru/soune/nocopy/entity/file/ImageProtection.java # src/main/java/ru/soune/nocopy/entity/user/User.java # src/main/java/ru/soune/nocopy/handler/ImageFoundRequestHandler.java # src/main/java/ru/soune/nocopy/repository/AuthTokenRepository.java # src/main/java/ru/soune/nocopy/service/file/impl/FileUploadServiceImpl.java
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package ru.soune.nocopy.controller;
|
||||
|
||||
import com.vrt.NoCopyFileService;
|
||||
import com.vrt.fileprotection.FileProtector;
|
||||
import com.vrt.fileprotection.NoCopyCheckResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -21,6 +24,7 @@ import ru.soune.nocopy.dto.file.*;
|
||||
import ru.soune.nocopy.dto.register.RegAnswer;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.entity.file.FileStatus;
|
||||
import ru.soune.nocopy.entity.file.ProtectionStatus;
|
||||
import ru.soune.nocopy.entity.file.UploadStatus;
|
||||
import ru.soune.nocopy.exception.*;
|
||||
import ru.soune.nocopy.handler.*;
|
||||
@@ -29,7 +33,9 @@ import ru.soune.nocopy.service.FileSimilarityService;
|
||||
import ru.soune.nocopy.service.register.AuthService;
|
||||
import ru.soune.nocopy.service.file.FileEntityService;
|
||||
import ru.soune.nocopy.service.file.FileUploadService;
|
||||
import ru.soune.nocopy.util.FileUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -57,6 +63,10 @@ public class ApiController {
|
||||
|
||||
private final FileEntityRepository fileEntityRepository;
|
||||
|
||||
private final NoCopyFileService noCopyFileService;
|
||||
|
||||
private final FileUtil fileUtil;
|
||||
|
||||
@PostMapping("/v{version}/data")
|
||||
public ResponseEntity<?> handlePostRequest(@RequestBody BaseRequest request,
|
||||
@PathVariable("version") int version) {
|
||||
@@ -103,7 +113,8 @@ public class ApiController {
|
||||
@PathVariable("version") int version,
|
||||
@RequestParam(value = "upload_id", required = false) String uploadId,
|
||||
@RequestParam(value = "chunk_number", required = false) Integer chunkNumber,
|
||||
@RequestParam(value = "chunk", required = false) MultipartFile chunk) {
|
||||
@RequestParam(value = "chunk", required = false) MultipartFile chunk,
|
||||
@RequestParam(value = "findSimilar", required = false) Integer findSimilar) {
|
||||
try {
|
||||
if (chunk == null || chunk.isEmpty()) {
|
||||
return buildErrorResponse(uploadId, chunkNumber, "Chunk file null or empty");
|
||||
@@ -115,39 +126,54 @@ public class ApiController {
|
||||
return buildErrorResponse(uploadId, chunkNumber, "Valid chunk number is required");
|
||||
}
|
||||
|
||||
fileUploadService.uploadChunk(uploadId, chunkNumber, chunk);
|
||||
UploadProgressResponse uploadProgressResponse = fileUploadService.uploadChunk(uploadId, chunkNumber,
|
||||
chunk, findSimilar);
|
||||
|
||||
return buildSuccessResponse(uploadId, chunkNumber, chunk);
|
||||
return buildSuccessResponse(uploadId, chunkNumber, chunk,
|
||||
fileEntityService.findFileIdByPath(uploadProgressResponse.getFilePath()));
|
||||
} catch (DuplicateImageException e) {
|
||||
return ResponseEntity.ok().body(new BaseResponse(20004, MessageCode.DUPLICATE_FILE_UPLOAD.getCode(),
|
||||
Map<String, Object> duplicateData = new HashMap<>();
|
||||
duplicateData.put("duplicateFileId", e.duplicateFileId());
|
||||
duplicateData.put("userId", e.userId());
|
||||
duplicateData.put("message", e.getMessage());
|
||||
|
||||
if (uploadId != null) {
|
||||
duplicateData.put("uploadId", uploadId);
|
||||
}
|
||||
|
||||
return ResponseEntity.ok().body(new BaseResponse(
|
||||
20004,
|
||||
MessageCode.DUPLICATE_FILE_UPLOAD.getCode(),
|
||||
MessageCode.DUPLICATE_FILE_UPLOAD.getDescription(),
|
||||
Map.of("duplicateOwnerId", e.userId(), "duplicateFileId", e.duplicateFileId())));
|
||||
duplicateData
|
||||
));
|
||||
} catch (Exception e) {
|
||||
log.error("Error uploading chunk", e);
|
||||
return buildErrorResponse(uploadId, chunkNumber, "Failed to upload chunk: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/v{version}/files/{fileId}/similar")
|
||||
@GetMapping("/v{version}/files/{fileId}/similar/{authToken}")
|
||||
public ResponseEntity<BaseResponse> findSimilarFiles(
|
||||
@PathVariable("version") int version,
|
||||
@PathVariable String fileId,
|
||||
@PathVariable(required = false) String authToken,
|
||||
@RequestParam(required = false) List<String> similarityLevels,
|
||||
@PageableDefault(size = 20, sort = "hammingDistance") Pageable pageable) {
|
||||
SimilarityFilter filter = SimilarityFilter.builder()
|
||||
.similarityLevels(similarityLevels)
|
||||
.build();
|
||||
Page<SimilarFileResponse> similarFiles = fileSimilarityService.findSimilarFiles(fileId, filter, pageable);
|
||||
Page<SimilarFileDTO> similarFiles = fileSimilarityService.findSimilarFiles(fileId, filter, pageable, authToken);
|
||||
|
||||
String messageDesc;
|
||||
MessageCode success;
|
||||
|
||||
if (similarFiles.isEmpty()) {
|
||||
messageDesc = MessageCode.FILE_NOT_FOUND.getDescription();
|
||||
success = MessageCode.FILE_NOT_FOUND;
|
||||
success = MessageCode.SUCCESS;
|
||||
} else {
|
||||
messageDesc = MessageCode.SIMILAR_FILES_FOUND.getDescription();
|
||||
success = MessageCode.SIMILAR_FILES_FOUND;
|
||||
success = MessageCode.SUCCESS;
|
||||
}
|
||||
|
||||
Map<String, Object> responseData = new HashMap<>();
|
||||
@@ -193,7 +219,8 @@ public class ApiController {
|
||||
.uploadId(uploadId)
|
||||
.build();
|
||||
|
||||
return ResponseEntity.ok().body(new BaseResponse(20004, MessageCode.FILE_UPLOAD_ERROR.getCode(),
|
||||
return ResponseEntity.ok().body(new BaseResponse(
|
||||
20004, MessageCode.FILE_UPLOAD_ERROR.getCode(),
|
||||
"Failed to get upload progress: " + e.getMessage(), responseBody));
|
||||
}
|
||||
}
|
||||
@@ -352,6 +379,45 @@ public class ApiController {
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/protect/{fileId}")
|
||||
public ResponseEntity<?> protect( @PathVariable(required = false) String fileId) {
|
||||
Optional<FileEntity> optionalFileEntity = fileEntityRepository.findById(fileId);
|
||||
|
||||
if (!optionalFileEntity.isPresent()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
FileEntity fileEntity = optionalFileEntity.get();
|
||||
FileProtector.FileInfo fileInfo = fileUtil.createFileInfo(fileEntity);
|
||||
|
||||
noCopyFileService.addFile(fileInfo);
|
||||
|
||||
fileEntity.setProtectionStatus(ProtectionStatus.PROCESSING);
|
||||
fileEntityRepository.save(fileEntity);
|
||||
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
@GetMapping("/check/{fileId}/{type}")
|
||||
public ResponseEntity<?> check(@PathVariable(required = false) String fileId,
|
||||
@PathVariable(required = false) String type) {
|
||||
Optional<FileEntity> optionalFileEntity = fileEntityRepository.findById(fileId);
|
||||
if (!optionalFileEntity.isPresent()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
FileEntity fileEntity = optionalFileEntity.get();
|
||||
|
||||
Path path = type.toLowerCase().equals("image") ? Paths.get(fileEntity.getFilePath()) :
|
||||
Paths.get(fileEntity.getProtectedFilePath());
|
||||
|
||||
File file = path.toFile();
|
||||
|
||||
NoCopyCheckResult noCopyCheckResult = noCopyFileService.checkFile(file,
|
||||
FileProtector.Type.valueOf(type.toUpperCase()));
|
||||
|
||||
return ResponseEntity.ok().body(noCopyCheckResult);
|
||||
}
|
||||
|
||||
private ResponseEntity<BaseResponse> checkForDuplicates(String uploadId) throws IOException {
|
||||
Optional<FileEntity> uploadedFile = fileEntityRepository.findByUploadSessionId(uploadId);
|
||||
|
||||
@@ -360,7 +426,7 @@ public class ApiController {
|
||||
}
|
||||
|
||||
FileEntity fileEntity = uploadedFile.get();
|
||||
List<SimilarFileResponse> similarFiles = fileSimilarityService.findSimilarFiles(fileEntity.getId());
|
||||
List<SimilarFileDTO> similarFiles = fileSimilarityService.findSimilarFiles(fileEntity.getId());
|
||||
|
||||
if (hasDuplicate(similarFiles)) {
|
||||
return handleDuplicate(fileEntity, similarFiles);
|
||||
@@ -369,11 +435,11 @@ public class ApiController {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasDuplicate(List<SimilarFileResponse> similarFiles) {
|
||||
private boolean hasDuplicate(List<SimilarFileDTO> similarFiles) {
|
||||
return similarFiles.stream().anyMatch(f -> f.getHammingDistance() <= 5);
|
||||
}
|
||||
|
||||
private ResponseEntity<BaseResponse> handleDuplicate(FileEntity fileEntity, List<SimilarFileResponse> similarFiles)
|
||||
private ResponseEntity<BaseResponse> handleDuplicate(FileEntity fileEntity, List<SimilarFileDTO> similarFiles)
|
||||
throws IOException {
|
||||
fileEntityService.deleteFromDisk(fileEntity);
|
||||
|
||||
@@ -396,11 +462,13 @@ public class ApiController {
|
||||
return null;
|
||||
}
|
||||
|
||||
private ResponseEntity<BaseResponse> buildSuccessResponse(String uploadId, Integer chunkNumber, MultipartFile chunk) {
|
||||
private ResponseEntity<BaseResponse> buildSuccessResponse(String uploadId, Integer chunkNumber, MultipartFile chunk,
|
||||
String fileId) {
|
||||
ChunkUploadResponse responseBody = ChunkUploadResponse.builder()
|
||||
.uploadId(uploadId)
|
||||
.chunkNumber(chunkNumber)
|
||||
.chunkSize(chunk.getSize())
|
||||
.fileId(fileId)
|
||||
.message("Chunk uploaded successfully")
|
||||
.build();
|
||||
|
||||
@@ -459,16 +527,4 @@ public class ApiController {
|
||||
}
|
||||
return contentType;
|
||||
}
|
||||
|
||||
private boolean isPreviewSupported(String mimeType) {
|
||||
if (mimeType == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mimeType.startsWith("image") ||
|
||||
mimeType.startsWith("text") ||
|
||||
mimeType.equals("pdf") ||
|
||||
mimeType.startsWith("video") ||
|
||||
mimeType.startsWith("audio");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user