diff --git a/src/main/java/ru/soune/nocopy/controller/ApiController.java b/src/main/java/ru/soune/nocopy/controller/ApiController.java index 529f163..ad12fce 100644 --- a/src/main/java/ru/soune/nocopy/controller/ApiController.java +++ b/src/main/java/ru/soune/nocopy/controller/ApiController.java @@ -2,6 +2,7 @@ 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; @@ -38,6 +39,7 @@ 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; @@ -380,6 +382,25 @@ public class ApiController { return ResponseEntity.ok().build(); } + @GetMapping("/check/{fileId}/{type}") + public ResponseEntity check(@PathVariable(required = false) String fileId, + @PathVariable(required = false) String type) { + Optional optionalFileEntity = fileEntityRepository.findById(fileId); + if (!optionalFileEntity.isPresent()) { + return ResponseEntity.notFound().build(); + } + + FileEntity fileEntity = optionalFileEntity.get(); + + Path path = Paths.get(fileEntity.getFilePath()); + File file = path.toFile(); + + NoCopyCheckResult noCopyCheckResult = noCopyFileService.checkFile(file, + FileProtector.Type.valueOf(type.toUpperCase())); + + return ResponseEntity.ok().body(noCopyCheckResult); + } + private ResponseEntity checkForDuplicates(String uploadId) throws IOException { Optional uploadedFile = fileEntityRepository.findByUploadSessionId(uploadId); diff --git a/src/main/java/ru/soune/nocopy/entity/file/ImageHashEntity.java b/src/main/java/ru/soune/nocopy/entity/file/ImageHashEntity.java index 37f1b5a..f18a572 100644 --- a/src/main/java/ru/soune/nocopy/entity/file/ImageHashEntity.java +++ b/src/main/java/ru/soune/nocopy/entity/file/ImageHashEntity.java @@ -26,10 +26,10 @@ public class ImageHashEntity { private FileEntity file; @Column(name = "hash64_hi") - private Integer hash64Hi; + private Long hash64Hi; @Column(name = "hash64_lo") - private Integer hash64Lo; + private Long hash64Lo; @Column(name = "hash_algorithm", nullable = false) private String hashAlgorithm; diff --git a/src/main/java/ru/soune/nocopy/repository/ImageHashRepository.java b/src/main/java/ru/soune/nocopy/repository/ImageHashRepository.java index c0d8d7f..48b4378 100644 --- a/src/main/java/ru/soune/nocopy/repository/ImageHashRepository.java +++ b/src/main/java/ru/soune/nocopy/repository/ImageHashRepository.java @@ -10,5 +10,5 @@ import java.util.List; public interface ImageHashRepository extends JpaRepository { void deleteByFileId(String fileId); List findByFileId(String fileId); - ImageHashEntity findByHash64HiAndHash64Lo(Integer hash64Hi, Integer hash64Lo); + ImageHashEntity findByHash64HiAndHash64Lo(Long hash64Hi, Long hash64Lo); } diff --git a/src/main/java/ru/soune/nocopy/repository/ImageSimilarityRepository.java b/src/main/java/ru/soune/nocopy/repository/ImageSimilarityRepository.java index a6ef973..cd57871 100644 --- a/src/main/java/ru/soune/nocopy/repository/ImageSimilarityRepository.java +++ b/src/main/java/ru/soune/nocopy/repository/ImageSimilarityRepository.java @@ -48,7 +48,7 @@ public interface ImageSimilarityRepository """, nativeQuery = true) List findExactDuplicates( - @Param("hash64Hi") Integer hash64_hi, - @Param("hash64Lo") Integer hash64_lo); + @Param("hash64Hi") Long hash64_hi, + @Param("hash64Lo") Long hash64_lo); } diff --git a/src/main/java/ru/soune/nocopy/repository/SimilarImageProjection.java b/src/main/java/ru/soune/nocopy/repository/SimilarImageProjection.java index ed2fdb4..c098789 100644 --- a/src/main/java/ru/soune/nocopy/repository/SimilarImageProjection.java +++ b/src/main/java/ru/soune/nocopy/repository/SimilarImageProjection.java @@ -1,8 +1,8 @@ package ru.soune.nocopy.repository; public interface SimilarImageProjection { - Integer getHash64Hi(); - Integer getHash64Lo(); + Long getHash64Hi(); + Long getHash64Lo(); String getFileId(); Long getUserId(); String getOriginalFileName(); diff --git a/src/main/java/ru/soune/nocopy/service/FileSimilarityService.java b/src/main/java/ru/soune/nocopy/service/FileSimilarityService.java index 51f1808..0b6a7d9 100644 --- a/src/main/java/ru/soune/nocopy/service/FileSimilarityService.java +++ b/src/main/java/ru/soune/nocopy/service/FileSimilarityService.java @@ -32,15 +32,15 @@ public class FileSimilarityService { var imageHashEntity = hashRepository.findById(fileId) .orElseThrow(() -> new RuntimeException("Hash not found")); - Integer hash64Hi = imageHashEntity.getHash64Hi(); - Integer hash64Lo = imageHashEntity.getHash64Lo(); + Long hash64Hi = imageHashEntity.getHash64Hi(); + Long hash64Lo = imageHashEntity.getHash64Lo(); List candidates = repository.findCandidates(fileId); return candidates.stream() .map(c -> { - Integer cHi = c.getHash64Hi(); - Integer cLo = c.getHash64Lo(); + Long cHi = c.getHash64Hi(); + Long cLo = c.getHash64Lo(); int hamming = fileUtil.hamming64(hash64Hi, hash64Lo, cHi, cLo); @@ -73,13 +73,13 @@ public class FileSimilarityService { var imageHashEntity = hashRepository.findById(fileId) .orElseThrow(() -> new RuntimeException("Hash not found")); - Integer hash64Hi = imageHashEntity.getHash64Hi(); - Integer hash64Lo = imageHashEntity.getHash64Lo(); + Long hash64Hi = imageHashEntity.getHash64Hi(); + Long hash64Lo = imageHashEntity.getHash64Lo(); return candidates.stream() .map(c -> { - Integer cHi = c.getHash64Hi(); - Integer cLo = c.getHash64Lo(); + Long cHi = c.getHash64Hi(); + Long cLo = c.getHash64Lo(); int hamming = fileUtil.hamming64(hash64Hi, hash64Lo, cHi, cLo); @@ -112,7 +112,7 @@ public class FileSimilarityService { .toList(); } - public List findDuplicatedByHash(Integer hash64Hi, Integer hash64Lo) { + public List findDuplicatedByHash(Long hash64Hi, Long hash64Lo) { List duplicates = repository.findExactDuplicates(hash64Hi,hash64Lo); if (duplicates.isEmpty()) { @@ -126,8 +126,8 @@ public class FileSimilarityService { var imageHashEntity = hashRepository.findById(fileId) .orElseThrow(() -> new RuntimeException("Hash not found")); - Integer hash64Hi = imageHashEntity.getHash64Hi(); - Integer hash64Lo = imageHashEntity.getHash64Lo(); + Long hash64Hi = imageHashEntity.getHash64Hi(); + Long hash64Lo = imageHashEntity.getHash64Lo(); List candidates = repository.findCandidates(fileId); @@ -154,9 +154,9 @@ public class FileSimilarityService { } private SimilarFileDTO createSimilarFileResponse(SimilarImageProjection similarImageProjection, - Integer hash64Hi, Integer hash64Lo) { - Integer imageProjectionHash64Hi = similarImageProjection.getHash64Hi(); - Integer similarImageProjectionHash64Lo = similarImageProjection.getHash64Lo(); + Long hash64Hi, Long hash64Lo) { + Long imageProjectionHash64Hi = similarImageProjection.getHash64Hi(); + Long similarImageProjectionHash64Lo = similarImageProjection.getHash64Lo(); int hamming = fileUtil.hamming64(hash64Hi, hash64Lo, imageProjectionHash64Hi, similarImageProjectionHash64Lo); diff --git a/src/main/java/ru/soune/nocopy/service/ImageHashService.java b/src/main/java/ru/soune/nocopy/service/ImageHashService.java index 7df67bc..672bf78 100644 --- a/src/main/java/ru/soune/nocopy/service/ImageHashService.java +++ b/src/main/java/ru/soune/nocopy/service/ImageHashService.java @@ -22,19 +22,19 @@ public class ImageHashService { private final ImageHashRepository repository; - public Map calculateHash(Path imagePath) throws IOException { + public Map calculateHash(Path imagePath) throws IOException { File file = imagePath.toFile(); PHash pHash = PerceptualHashHelper.INSTANCE.generateDCTPerceptualHash(file); Long firstPart = pHash.getFirstPart(); Long secondPart = pHash.getSecondPart(); - Map hash = Map.of( - "hi", Math.toIntExact(firstPart), - "low", Math.toIntExact(secondPart)); + Map hash = Map.of( + "hi", firstPart, + "low", secondPart); return hash; } - public void create(FileEntity file, Map stringIntegerMap) { + public void create(FileEntity file, Map stringIntegerMap) { ImageHashEntity entity = ImageHashEntity.builder() .file(file) .hash64Hi(stringIntegerMap.get("hi")) diff --git a/src/main/java/ru/soune/nocopy/service/file/FileEntityService.java b/src/main/java/ru/soune/nocopy/service/file/FileEntityService.java index 4522691..1970cb2 100644 --- a/src/main/java/ru/soune/nocopy/service/file/FileEntityService.java +++ b/src/main/java/ru/soune/nocopy/service/file/FileEntityService.java @@ -49,7 +49,7 @@ public class FileEntityService { throw new IOException("File not found on disk: " + filePath); } - Map imageHash = Map.of(); + Map imageHash = Map.of(); if (session.getFileType().startsWith("image")) { imageHash = imageHashService.calculateHash(filePath); diff --git a/src/main/java/ru/soune/nocopy/service/file/impl/FileUploadServiceImpl.java b/src/main/java/ru/soune/nocopy/service/file/impl/FileUploadServiceImpl.java index cb4fa3b..1daadda 100644 --- a/src/main/java/ru/soune/nocopy/service/file/impl/FileUploadServiceImpl.java +++ b/src/main/java/ru/soune/nocopy/service/file/impl/FileUploadServiceImpl.java @@ -283,12 +283,16 @@ public class FileUploadServiceImpl implements FileUploadService { FileEntity saved = fileEntityRepository.save(fileEntity); - Map hash = imageHashService.calculateHash(filePath); + if (session.getFileType().equals("image")) { + Map hash = imageHashService.calculateHash(filePath); - imageHashService.create(saved, hash); + imageHashService.create(saved, hash); + } cleanupSessionFiles(session); + noCopyFileService.addFile(fileUtil.createFileInfo(fileEntity)); + log.info("File processing completed for session: {}", session.getUploadId()); } catch (Exception e) { @@ -380,7 +384,8 @@ public class FileUploadServiceImpl implements FileUploadService { private void checkForDuplicatesSynchronously(String filePath) throws IOException { Path path = Paths.get(filePath); - Map hash = imageHashService.calculateHash(path); + Map hash = imageHashService.calculateHash(path); + List duplicates = fileSimilarityService.findDuplicatedByHash( hash.get("hi"), hash.get("low")); diff --git a/src/main/java/ru/soune/nocopy/service/file/impl/ImageLocalSearchImpl.java b/src/main/java/ru/soune/nocopy/service/file/impl/ImageLocalSearchImpl.java index 1ecf8c7..79b8963 100644 --- a/src/main/java/ru/soune/nocopy/service/file/impl/ImageLocalSearchImpl.java +++ b/src/main/java/ru/soune/nocopy/service/file/impl/ImageLocalSearchImpl.java @@ -44,8 +44,8 @@ public class ImageLocalSearchImpl implements ImageLocalSearch { @Override public @Nullable FileProtector.FileInfo findByPHash(@NotNull PHash pHash) { ImageHashEntity imageHashEntity = - imageHashRepository.findByHash64HiAndHash64Lo(Math.toIntExact(pHash.getFirstPart()), - Math.toIntExact(pHash.getSecondPart())); + imageHashRepository.findByHash64HiAndHash64Lo(pHash.getFirstPart(), + pHash.getSecondPart()); FileEntity file = fileEntityRepository.findByFileId(imageHashEntity.getFileId()); return new FileProtector.FileInfo(FileProtector.Type.IMAGE, imageHashEntity.getFileId(), diff --git a/src/main/java/ru/soune/nocopy/service/file/impl/ProtectionFileProviderImpl.java b/src/main/java/ru/soune/nocopy/service/file/impl/ProtectionFileProviderImpl.java index 62c9aa1..57323a0 100644 --- a/src/main/java/ru/soune/nocopy/service/file/impl/ProtectionFileProviderImpl.java +++ b/src/main/java/ru/soune/nocopy/service/file/impl/ProtectionFileProviderImpl.java @@ -10,12 +10,18 @@ import org.springframework.stereotype.Component; import ru.soune.nocopy.service.file.FileEntityService; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; @Slf4j @Component @RequiredArgsConstructor public class ProtectionFileProviderImpl implements FileProtector.FileProvider { + private static final Path SIGNATURE_FILE_PATH = Paths.get("/data/uploads/signature"); + private final FileEntityService fileEntityService; @Nullable @@ -38,9 +44,41 @@ public class ProtectionFileProviderImpl implements FileProtector.FileProvider { @Override public @Nullable File getSignature() { + log.info(" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! GET SIGNATURE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + File signatureFile = SIGNATURE_FILE_PATH.toFile(); + + if (signatureFile.exists() && signatureFile.isFile() && signatureFile.length() > 0) { + return signatureFile; + } + return null; } + @Override + public @NotNull OperationResult writeSignature(@NotNull byte[] bytes) { + log.info(" !!!!!!!!!!!!!!!!!!!!!!!!!!! WRITING SIGNATURE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + log.info(" !!!!!!!!!!!!!!!!!!!!!!!!!!! WRITING SIGNATURE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + log.info(" !!!!!!!!!!!!!!!!!!!!!!!!!!! WRITING SIGNATURE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + log.info(" !!!!!!!!!!!!!!!!!!!!!!!!!!! WRITING SIGNATURE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + log.info(" !!!!!!!!!!!!!!!!!!!!!!!!!!! WRITING SIGNATURE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + log.info(" !!!!!!!!!!!!!!!!!!!!!!!!!!! WRITING SIGNATURE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + log.info(" !!!!!!!!!!!!!!!!!!!!!!!!!!! WRITING SIGNATURE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + log.info(" !!!!!!!!!!!!!!!!!!!!!!!!!!! WRITING SIGNATURE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + try { + Path directory = SIGNATURE_FILE_PATH.getParent(); + + if (directory != null && !Files.exists(directory)) { + Files.createDirectories(directory); + } + + Files.write(SIGNATURE_FILE_PATH, bytes); + + return OperationResult.Companion.success(); + } catch (IOException e) { + return OperationResult.Companion.failure("Not saved signature file"); + } + } + @NotNull @Override public com.vrt.fileprotection.OperationResult writeAudioFile(@NotNull String id, @NotNull byte[] data, @Nullable String fileExt) { @@ -76,9 +114,4 @@ public class ProtectionFileProviderImpl implements FileProtector.FileProvider { return OperationResult.Companion.failure("Failed to create protected file"); } } - - @Override - public @NotNull OperationResult writeSignature(@NotNull byte[] bytes) { - return null; - } } diff --git a/src/main/java/ru/soune/nocopy/util/FileUtil.java b/src/main/java/ru/soune/nocopy/util/FileUtil.java index bad535d..192e1d3 100644 --- a/src/main/java/ru/soune/nocopy/util/FileUtil.java +++ b/src/main/java/ru/soune/nocopy/util/FileUtil.java @@ -25,9 +25,9 @@ public class FileUtil { return new FileProtector.FileInfo(type, fileEntity.getId(), String.valueOf(fileEntity.getUserId())); } - public int hamming64(int aHi, int aLo, int bHi, int bLo) { - return Integer.bitCount(aHi ^ bHi) - + Integer.bitCount(aLo ^ bLo); + public int hamming64(long aHi, long aLo, long bHi, long bLo) { + return Long.bitCount(aHi ^ bHi) + + Long.bitCount(aLo ^ bLo); } private FileProtector.Type determineFileType(String mimeType) {