From 78698d28733ad7768482319f944456526ca53b28 Mon Sep 17 00:00:00 2001 From: vladp Date: Tue, 17 Feb 2026 13:57:38 +0700 Subject: [PATCH] dev delete config --- .../nocopy/controller/ApiController.java | 198 +++++++++++++++--- .../nocopy/service/FileSimilarityService.java | 164 ++++++--------- 2 files changed, 235 insertions(+), 127 deletions(-) diff --git a/src/main/java/ru/soune/nocopy/controller/ApiController.java b/src/main/java/ru/soune/nocopy/controller/ApiController.java index 29435a6..45a0721 100644 --- a/src/main/java/ru/soune/nocopy/controller/ApiController.java +++ b/src/main/java/ru/soune/nocopy/controller/ApiController.java @@ -1,5 +1,10 @@ package ru.soune.nocopy.controller; +import com.vrt.NoCopyFileService; +import com.vrt.fileprotection.FileProtector; +import com.vrt.fileprotection.NoCopyCheckResult; +import com.vrt.fileprotection.audio.AudioCheckResult; +import com.vrt.fileprotection.documents.DocumentCheckResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.FileSystemResource; @@ -33,14 +38,12 @@ 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; import java.nio.file.Paths; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; @Slf4j @@ -152,40 +155,179 @@ public class ApiController { } } + private final NoCopyFileService noCopyFileService; + +// @GetMapping("/v{version}/files/{fileId}/similar") +// public ResponseEntity findSimilarFiles( +// @PathVariable("version") int version, +// @PathVariable String fileId, +// @RequestParam(value = "auth_token",required = false) String authToken, +// @RequestParam(required = false) List similarityLevels, +// @PageableDefault(size = 20, sort = "hammingDistance") Pageable pageable) throws Exception { +// SimilarityFilter filter = SimilarityFilter.builder() +// .similarityLevels(similarityLevels) +// .build(); +// FileEntity fileEntity = fileEntityRepository.findByFileId(fileId); +// Page similarFiles = null; +// List allResults = null; +// List errors = new ArrayList<>(); +// +// if (fileEntity.getMimeType().equals("image")) { +// similarFiles = fileSimilarityService.findSimilarFiles(fileId, filter, pageable, authToken); +// } else { +// File file = new File(fileEntity.getFilePath()); +// FileProtector.Type type = fileEntity.getMimeType().equals("document") ? FileProtector.Type.DOC : +// FileProtector.Type.AUDIO; +// +// NoCopyCheckResult noCopyCheckResult = noCopyFileService.checkFile(file, type); +// FileEntity entity = fileEntityRepository.findByFileId(fileId); +// +// switch (noCopyCheckResult) { +// case DocumentCheckResult.Success success -> { +// FileProtector.FileInfo info = success.getInfo(); +// allResults.add(fileSimilarityService.buildDTO(fileEntityRepository.findByFileId(info.getId()))); +// log.debug("File processed successfully: {}", entity.getFilePath()); +// } +// case AudioCheckResult.Success success -> { +// FileProtector.FileInfo info = success.getInfo(); +// +// allResults.add(fileSimilarityService.buildDTO(fileEntityRepository.findByFileId(info.getId()))); +// log.debug("File processed successfully: {}", entity.getFilePath()); +// } +// case DocumentCheckResult.Failed failed -> { +// String errorMessage = String.format("Document check failed for %s: %s", +// entity.getFilePath(), failed.getMessage()); +// log.warn(errorMessage); +// errors.add(errorMessage); +// } +// case AudioCheckResult.Failed failed -> { +// String errorMessage = String.format("Audio check failed for %s: %s", +// entity.getFilePath(), failed.getMessage()); +// log.warn(errorMessage); +// errors.add(errorMessage); +// } +// default -> throw new IllegalStateException("Unexpected result type: " + +// noCopyCheckResult.getClass().getSimpleName()); +// } +// +// } +// +// +// String messageDesc; +// MessageCode success; +// Map responseData = new HashMap<>(); +// +// assert similarFiles != null; +// if (similarFiles.isEmpty()) { +// messageDesc = MessageCode.FILE_NOT_FOUND.getDescription(); +// success = MessageCode.SUCCESS; +// responseData.put("content", similarFiles.getContent()); +// responseData.put("page", similarFiles.getNumber()); +// responseData.put("size", similarFiles.getSize()); +// responseData.put("totalElements", similarFiles.getTotalElements()); +// responseData.put("totalPages", similarFiles.getTotalPages()); +// responseData.put("hasNext", similarFiles.hasNext()); +// responseData.put("hasPrevious", similarFiles.hasPrevious()); +// } else { +// messageDesc = MessageCode.SIMILAR_FILES_FOUND.getDescription(); +// success = MessageCode.SUCCESS; +// responseData.put("content", allResults); +// } +// +// +// return ResponseEntity.ok() +// .body(new BaseResponse(20004, success.getCode(), messageDesc, responseData)); +// } + @GetMapping("/v{version}/files/{fileId}/similar") public ResponseEntity findSimilarFiles( @PathVariable("version") int version, @PathVariable String fileId, - @RequestParam(value = "auth_token",required = false) String authToken, + @RequestParam(value = "auth_token", required = false) String authToken, @RequestParam(required = false) List similarityLevels, - @PageableDefault(size = 20, sort = "hammingDistance") Pageable pageable) throws Exception { - SimilarityFilter filter = SimilarityFilter.builder() - .similarityLevels(similarityLevels) - .build(); - Page similarFiles = fileSimilarityService.findSimilarFiles(fileId, filter, pageable, authToken); + @PageableDefault(size = 20, sort = "hammingDistance") Pageable pageable) { - String messageDesc; - MessageCode success; + try { + FileEntity fileEntity = fileEntityRepository.findByFileId(fileId); + if (fileEntity == null) { + return ResponseEntity.ok().body(new BaseResponse(0, MessageCode.INVALID_FIELD.getCode(), + MessageCode.INVALID_FIELD.getDescription(), null)); + } - if (similarFiles.isEmpty()) { - messageDesc = MessageCode.FILE_NOT_FOUND.getDescription(); - success = MessageCode.SUCCESS; - } else { - messageDesc = MessageCode.SIMILAR_FILES_FOUND.getDescription(); - success = MessageCode.SUCCESS; + BaseResponse response; + if ("image".equals(fileEntity.getMimeType())) { + Page similarFilesPage = fileSimilarityService.findSimilarFiles( + fileId, similarityLevels, pageable, authToken); + response = buildSuccessResponse(similarFilesPage, MessageCode.SIMILAR_FILES_FOUND); + } else { + List results = processNonImageFile(fileEntity, authToken); + response = buildSuccessResponse(results, MessageCode.SIMILAR_FILES_FOUND); + } + + return ResponseEntity.ok(response); + + } catch (Exception e) { + log.error("Error finding similar files: {}", e.getMessage(), e); + return ResponseEntity.ok().body(new BaseResponse(0, MessageCode.INVALID_FIELD.getCode(), + MessageCode.INVALID_FIELD.getDescription(), null)); + } + } + + private List processNonImageFile(FileEntity fileEntity, String authToken) { + List results = new ArrayList<>(); + + File file = new File(fileEntity.getFilePath()); + FileProtector.Type type = "document".equals(fileEntity.getMimeType()) ? + FileProtector.Type.DOC : FileProtector.Type.AUDIO; + + NoCopyCheckResult checkResult = noCopyFileService.checkFile(file, type); + + switch (checkResult) { + case DocumentCheckResult.Success success -> { + FileProtector.FileInfo info = success.getInfo(); + FileEntity entity = fileEntityRepository.findByFileId(info.getId()); + if (entity != null) { + results.add(fileSimilarityService.buildDTO(entity)); + } + } + case AudioCheckResult.Success success -> { + FileProtector.FileInfo info = success.getInfo(); + FileEntity entity = fileEntityRepository.findByFileId(info.getId()); + if (entity != null) { + results.add(fileSimilarityService.buildDTO(entity)); + } + } + case DocumentCheckResult.Failed failed -> + log.warn("Document check failed: {}", failed.getMessage()); + case AudioCheckResult.Failed failed -> + log.warn("Audio check failed: {}", failed.getMessage()); + default -> log.warn("Unexpected result type: {}", checkResult.getClass().getSimpleName()); } - Map responseData = new HashMap<>(); - responseData.put("content", similarFiles.getContent()); - responseData.put("page", similarFiles.getNumber()); - responseData.put("size", similarFiles.getSize()); - responseData.put("totalElements", similarFiles.getTotalElements()); - responseData.put("totalPages", similarFiles.getTotalPages()); - responseData.put("hasNext", similarFiles.hasNext()); - responseData.put("hasPrevious", similarFiles.hasPrevious()); + return results; + } - return ResponseEntity.ok() - .body(new BaseResponse(20004, success.getCode(), messageDesc, responseData)); + private BaseResponse buildSuccessResponse(Page page, MessageCode messageCode) { + Map responseData = new HashMap<>(); + responseData.put("content", page.getContent()); + responseData.put("page", page.getNumber()); + responseData.put("size", page.getSize()); + responseData.put("totalElements", page.getTotalElements()); + responseData.put("totalPages", page.getTotalPages()); + responseData.put("hasNext", page.hasNext()); + responseData.put("hasPrevious", page.hasPrevious()); + + return new BaseResponse(20004, messageCode.getCode(), + messageCode.getDescription(), responseData); + } + + private BaseResponse buildSuccessResponse(List list, MessageCode messageCode) { + Map responseData = new HashMap<>(); + responseData.put("content", list); + responseData.put("totalElements", list.size()); + + return new BaseResponse(20004, messageCode.getCode(), + messageCode.getDescription(), responseData); } @GetMapping("/v{version}/files/progress/{uploadId}") diff --git a/src/main/java/ru/soune/nocopy/service/FileSimilarityService.java b/src/main/java/ru/soune/nocopy/service/FileSimilarityService.java index 2cf7a5c..8d809f7 100644 --- a/src/main/java/ru/soune/nocopy/service/FileSimilarityService.java +++ b/src/main/java/ru/soune/nocopy/service/FileSimilarityService.java @@ -46,8 +46,8 @@ public class FileSimilarityService { private final FileEntityRepository fileEntityRepository; - @Lazy - private final NoCopyFileService noCopyFileService; +// @Lazy +// private final NoCopyFileService noCopyFileService; @Value("${server.baseurl}") private String baseUrl; @@ -164,114 +164,80 @@ public class FileSimilarityService { } } - public Page findSimilarFiles(String fileId, SimilarityFilter filter, Pageable pageable, - String authToken) throws Exception { - FileEntity fileEntity = fileEntityRepository.findByFileId(fileId); - String mimeType = fileEntity.getMimeType(); - List allResults = new ArrayList<>(); +// public Page findSimilarFiles(String fileId, SimilarityFilter filter, Pageable pageable, +// String authToken) throws Exception { +// +// var imageHashEntity = hashRepository.findById(fileId) +// .orElseThrow(() -> new RuntimeException("Hash not found")); +// +// Long hash64Hi = imageHashEntity.getHash64Hi(); +// Long hash64Lo = imageHashEntity.getHash64Lo(); +// List candidates = authToken.equals("all") ? repository.findCandidates(fileId): +// repository.findCandidatesFromUserFiles(fileId, authTokenRepository.findUserIdByToken(authToken)); +// +// List similarityLevels = (filter != null && filter.getSimilarityLevels() != null) +// ? filter.getSimilarityLevels() +// : List.of("DUPLICATE", "SIMILAR", "DIFFERENT"); +// +// List allResults = candidates.stream() +// .map(c -> createSimilarFileResponse(c, hash64Hi, hash64Lo)) +// .filter(response -> similarityLevels.contains(response.getSimilarityLevel())) +// .sorted(Comparator.comparingInt(SimilarFileDTO::getHammingDistance)) +// .collect(Collectors.toList()); +// +// int total = allResults.size(); +// int page = (pageable != null) ? pageable.getPageNumber() : 0; +// int size = (pageable != null) ? pageable.getPageSize() : 20; +// +// int fromIndex = Math.min(page * size, total); +// int toIndex = Math.min(fromIndex + size, total); +// +// List pageContent = allResults.subList(fromIndex, toIndex); +// +// return new PageImpl<>(pageContent, pageable, total); +// } - if (mimeType.equals("image")) { + public Page findSimilarFiles( + String fileId, + List similarityLevels, + Pageable pageable, + String authToken) { + + try { var imageHashEntity = hashRepository.findById(fileId) - .orElseThrow(() -> new RuntimeException("Hash not found")); + .orElseThrow(() -> new RuntimeException("Hash not found for file: " + fileId)); - Long hash64Hi = imageHashEntity.getHash64Hi(); - Long hash64Lo = imageHashEntity.getHash64Lo(); - List candidates = authToken.equals("all") ? repository.findCandidates(fileId): - repository.findCandidatesFromUserFiles(fileId, authTokenRepository.findUserIdByToken(authToken)); + List candidates; + if (authToken == null || "all".equals(authToken)) { + candidates = repository.findCandidates(fileId); + } else { + Long userId = authTokenRepository.findUserIdByToken(authToken); + candidates = repository.findCandidatesFromUserFiles(fileId, userId); + } - List similarityLevels = (filter != null && filter.getSimilarityLevels() != null) - ? filter.getSimilarityLevels() + List levels = (similarityLevels != null && !similarityLevels.isEmpty()) + ? similarityLevels : List.of("DUPLICATE", "SIMILAR", "DIFFERENT"); - allResults = candidates.stream() - .map(c -> createSimilarFileResponse(c, hash64Hi, hash64Lo)) - .filter(response -> similarityLevels.contains(response.getSimilarityLevel())) + List allResults = candidates.stream() + .map(c -> createSimilarFileResponse(c, + imageHashEntity.getHash64Hi(), + imageHashEntity.getHash64Lo())) + .filter(dto -> levels.contains(dto.getSimilarityLevel())) .sorted(Comparator.comparingInt(SimilarFileDTO::getHammingDistance)) .collect(Collectors.toList()); - } else { -// Long userId = fileEntity.getUserId(); -// List fileEntityList = fileEntityRepository.findByUserIdAndMimeType(userId, mimeType); -// NoCopyCheckResult noCopyCheckResult; -// -// for (FileEntity file : fileEntityList) { -// Path path = Paths.get(file.getFilePath()); -// if (mimeType.equals("document")) { -// noCopyCheckResult = (DocumentCheckResult) noCopyFileService.checkFile( -// path.toFile(), FileProtector.Type.valueOf(file.getMimeType().toUpperCase())); -// } else { -// noCopyCheckResult = (AudioCheckResult) noCopyFileService.checkFile( -// path.toFile(), FileProtector.Type.valueOf(file.getMimeType().toUpperCase())); -// } -// -// switch (noCopyCheckResult) { -// case DocumentCheckResult.Success success -> { -// FileProtector.FileInfo info = success.getInfo(); -// allResults.add(buildDTO(file)); -// } -// case DocumentCheckResult.Failed failed -> { -// String message = failed.getMessage(); -// } -// default -> throw new IllegalStateException("Unexpected result"); -// } -// } - Long userId = fileEntity.getUserId(); - List fileEntityList = fileEntityRepository.findByUserIdAndMimeType(userId, mimeType); - List errors = new ArrayList<>(); + int start = (int) pageable.getOffset(); + int end = Math.min((start + pageable.getPageSize()), allResults.size()); + List pageContent = start < allResults.size() ? + allResults.subList(start, end) : Collections.emptyList(); - for (FileEntity file : fileEntityList) { - try { - Path path = Paths.get(file.getFilePath()); + return new PageImpl<>(pageContent, pageable, allResults.size()); - FileProtector.Type fileType = file.getMimeType().equals("document") ? FileProtector.Type.DOC: - FileProtector.Type.AUDIO; - - NoCopyCheckResult noCopyCheckResult = noCopyFileService.checkFile(path.toFile(), fileType); - - switch (noCopyCheckResult) { - case DocumentCheckResult.Success success -> { - FileProtector.FileInfo info = success.getInfo(); - allResults.add(buildDTO(file)); - log.debug("File processed successfully: {}", file.getFilePath()); - } - case AudioCheckResult.Success success -> { - FileProtector.FileInfo info = success.getInfo(); - allResults.add(buildDTO(file)); - log.debug("File processed successfully: {}", file.getFilePath()); - } - case DocumentCheckResult.Failed failed -> { - String errorMessage = String.format("Document check failed for %s: %s", - file.getFilePath(), failed.getMessage()); - log.warn(errorMessage); - errors.add(errorMessage); - } - case AudioCheckResult.Failed failed -> { - String errorMessage = String.format("Audio check failed for %s: %s", - file.getFilePath(), failed.getMessage()); - log.warn(errorMessage); - errors.add(errorMessage); - } - default -> throw new IllegalStateException("Unexpected result type: " + noCopyCheckResult.getClass().getSimpleName()); - } - } catch (Exception e) { - String errorMessage = String.format("Error processing file %s: %s", - file.getFilePath(), e.getMessage()); - log.error(errorMessage, e); - errors.add(errorMessage); - } - } + } catch (Exception e) { + log.error("Error finding similar files for fileId: {}", fileId, e); + return new PageImpl<>(Collections.emptyList(), pageable, 0); } - - int total = allResults.size(); - int page = (pageable != null) ? pageable.getPageNumber() : 0; - int size = (pageable != null) ? pageable.getPageSize() : 20; - - int fromIndex = Math.min(page * size, total); - int toIndex = Math.min(fromIndex + size, total); - - List pageContent = allResults.subList(fromIndex, toIndex); - - return new PageImpl<>(pageContent, pageable, total); } @@ -322,7 +288,7 @@ public class FileSimilarityService { .build(); } - private SimilarFileDTO buildDTO(FileEntity fileEntity) { + public SimilarFileDTO buildDTO(FileEntity fileEntity) { return SimilarFileDTO.builder() .fileId(fileEntity.getId()) .ownerId(fileEntity.getUserId())