Merge branch 'NCBACK-25' into dev
# Conflicts: # src/main/java/ru/soune/nocopy/repository/SimilarImageProjection.java # src/main/java/ru/soune/nocopy/service/FileSimilarityService.java
This commit is contained in:
@@ -9,6 +9,7 @@ import ru.soune.nocopy.dto.file.FileResponse;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.entity.file.FileStatus;
|
||||
import ru.soune.nocopy.entity.file.FileUploadSession;
|
||||
import ru.soune.nocopy.entity.file.ProtectionStatus;
|
||||
import ru.soune.nocopy.exception.DuplicateImageException;
|
||||
import ru.soune.nocopy.exception.FileEntityNotFoundException;
|
||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||
@@ -16,6 +17,7 @@ import ru.soune.nocopy.repository.SimilarImageProjection;
|
||||
import ru.soune.nocopy.service.FileSimilarityService;
|
||||
import ru.soune.nocopy.service.ImageHashService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -47,7 +49,7 @@ public class FileEntityService {
|
||||
throw new IOException("File not found on disk: " + filePath);
|
||||
}
|
||||
|
||||
Map<String, Integer> imageHash = Map.of();
|
||||
Map<String, Long> imageHash = Map.of();
|
||||
|
||||
if (session.getFileType().startsWith("image")) {
|
||||
imageHash = imageHashService.calculateHash(filePath);
|
||||
@@ -110,6 +112,39 @@ public class FileEntityService {
|
||||
return convertToResponse(fileEntity, version);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public FileEntityResponse getByFilePath(String filePath, int version) {
|
||||
FileEntity fileEntity = fileEntityRepository.findByFilePath(filePath)
|
||||
.orElseThrow(() -> new FileEntityNotFoundException("Path: " + filePath));
|
||||
|
||||
return convertToResponse(fileEntity, version);
|
||||
}
|
||||
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public FileResponse getAllUserFiles(Long userId, int version) {
|
||||
List<FileEntity> fileEntities = fileEntityRepository.findByUserIdAndStatus(
|
||||
userId, FileStatus.ACTIVE);
|
||||
|
||||
List<FileEntityResponse> files = fileEntities.stream()
|
||||
.map(file -> convertToResponse(file, version))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
long totalSize = fileEntities.stream()
|
||||
.mapToLong(FileEntity::getFileSize)
|
||||
.sum();
|
||||
|
||||
return FileResponse.builder()
|
||||
.files(files)
|
||||
.totalCount(files.size())
|
||||
.totalSize(totalSize)
|
||||
.formattedTotalSize(formatFileSize(totalSize))
|
||||
.page(1)
|
||||
.pageSize(files.size())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public FileResponse getUserFiles(Long userId, int page, int pageSize, int version) {
|
||||
List<FileEntity> allFiles = fileEntityRepository.findByUserIdAndStatus(
|
||||
@@ -178,6 +213,95 @@ public class FileEntityService {
|
||||
return totalSize != null ? totalSize : 0L;
|
||||
}
|
||||
|
||||
public void changeStatus(ProtectionStatus newStatus, String fileId) {
|
||||
FileEntity fileEntity = fileEntityRepository.findById(fileId)
|
||||
.orElseThrow(() -> new FileEntityNotFoundException(fileId));
|
||||
fileEntity.setProtectionStatus(newStatus);
|
||||
|
||||
fileEntityRepository.save(fileEntity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void writeProtectedFile(String id, byte[] data, String fileExt) throws IOException {
|
||||
FileEntity fileEntity = fileEntityRepository.findById(id)
|
||||
.orElseThrow(() -> new RuntimeException("File not found: " + id));
|
||||
|
||||
String extension = determineFileExtension(fileExt, fileEntity);
|
||||
Path protectedFilePath = prepareProtectedPath(fileEntity, extension);
|
||||
|
||||
if (Files.exists(protectedFilePath)) {
|
||||
Files.delete(protectedFilePath);
|
||||
}
|
||||
|
||||
Files.write(protectedFilePath, data);
|
||||
|
||||
fileEntity.setProtectedFilePath(protectedFilePath.toString());
|
||||
fileEntity.setProtectedAt(LocalDateTime.now());
|
||||
fileEntity.setUpdatedAt(LocalDateTime.now());
|
||||
fileEntity.setFileExtension(extension);
|
||||
fileEntity.setProtectionStatus(ProtectionStatus.PROTECTED);
|
||||
|
||||
fileEntityRepository.save(fileEntity);
|
||||
}
|
||||
|
||||
public FileEntity findBySignature(String signature) {
|
||||
return fileEntityRepository.findBySignature(signature);
|
||||
}
|
||||
|
||||
public File getFileById(String id) {
|
||||
try {
|
||||
FileEntity fileEntity = fileEntityRepository.findById(id).orElseThrow(() ->
|
||||
new RuntimeException("File not found: " + id));
|
||||
|
||||
File file = new File(fileEntity.getFilePath());
|
||||
|
||||
if (!file.exists()) {
|
||||
throw new RuntimeException("File not found on disk: " + fileEntity.getFilePath());
|
||||
}
|
||||
|
||||
return file;
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting file: {}", id, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Path prepareProtectedPath(FileEntity fileEntity, String extension) throws IOException {
|
||||
Path originalPath = Paths.get(fileEntity.getFilePath());
|
||||
|
||||
String pathStr = originalPath.toString();
|
||||
pathStr = pathStr.replaceFirst("/uploads/uploads/", "/uploads/protected/");
|
||||
|
||||
Path protectedPath = Paths.get(pathStr);
|
||||
String fileName = protectedPath.getFileName().toString();
|
||||
|
||||
if (extension != null) {
|
||||
String nameWithoutExt = fileName;
|
||||
int lastDotIndex = fileName.lastIndexOf('.');
|
||||
if (lastDotIndex > 0) {
|
||||
nameWithoutExt = fileName.substring(0, lastDotIndex);
|
||||
}
|
||||
fileName = nameWithoutExt + "." + extension;
|
||||
|
||||
protectedPath = protectedPath.getParent().resolve(fileName);
|
||||
}
|
||||
|
||||
Files.createDirectories(protectedPath.getParent());
|
||||
|
||||
return protectedPath;
|
||||
}
|
||||
|
||||
public void updateSignature(String signature, String fileId) throws IOException {
|
||||
FileEntity fileEntity = fileEntityRepository.findByFileId(fileId);
|
||||
fileEntity.setSignature(signature);
|
||||
fileEntity.setProtectionStatus(ProtectionStatus.PROTECTED);
|
||||
fileEntity.setUpdatedAt(LocalDateTime.now());
|
||||
fileEntity.setProtectedAt(LocalDateTime.now());
|
||||
fileEntity.setProtectedFilePath(prepareProtectedPath(fileEntity, fileEntity.getFileExtension()).toString());
|
||||
|
||||
fileEntityRepository.save(fileEntity);
|
||||
}
|
||||
|
||||
private boolean checkFileExistsOnDisk(String filePath) {
|
||||
try {
|
||||
return Files.exists(Paths.get(filePath));
|
||||
@@ -187,6 +311,14 @@ public class FileEntityService {
|
||||
}
|
||||
}
|
||||
|
||||
private String determineFileExtension(String fileExt, FileEntity fileEntity) {
|
||||
if (fileExt != null && !fileExt.trim().isEmpty()) {
|
||||
return fileExt;
|
||||
} else {
|
||||
return fileEntity.getFileExtension();
|
||||
}
|
||||
}
|
||||
|
||||
private FileEntityResponse convertToResponse(FileEntity fileEntity, int version) {
|
||||
boolean existsOnDisk = checkFileExistsOnDisk(fileEntity.getFilePath());
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package ru.soune.nocopy.service.file;
|
||||
|
||||
import com.vrt.NoCopyFileService;
|
||||
import com.vrt.fileprotection.FileProtector;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.entity.file.ProtectionStatus;
|
||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||
import ru.soune.nocopy.util.FileUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class FileProcessingOrchestrator {
|
||||
|
||||
private final NoCopyFileService noCopyFileService;
|
||||
|
||||
private final FileEntityRepository fileRepository;
|
||||
|
||||
private final FileUtil fileUtil;
|
||||
|
||||
public void initializeProcessingQueue() {
|
||||
List<FileEntity> filesToProtect = fileRepository.findByProtectionStatus(ProtectionStatus.NOT_PROTECTED);
|
||||
|
||||
for (FileEntity fileEntity : filesToProtect) {
|
||||
try {
|
||||
FileProtector.FileInfo fileInfo = fileUtil.createFileInfo(fileEntity);
|
||||
|
||||
noCopyFileService.addFile(fileInfo);
|
||||
|
||||
log.info("Add to query: {}", fileEntity.getOriginalFileName());
|
||||
} catch (Exception e) {
|
||||
log.error("Fail add to query: {}", fileEntity.getId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 120000)
|
||||
public void checkNewFilesForProtection() {
|
||||
List<FileEntity> newFiles = fileRepository.findAllActiveFilesAndNotProtected();
|
||||
|
||||
for (FileEntity fileEntity : newFiles) {
|
||||
FileProtector.FileInfo fileInfo = fileUtil.createFileInfo(fileEntity);
|
||||
|
||||
noCopyFileService.addFile(fileInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package ru.soune.nocopy.service.file.impl;
|
||||
|
||||
import com.vrt.AudioFilePathProvider;
|
||||
import com.vrt.fileprotection.FileProtector;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||
import ru.soune.nocopy.service.file.FileEntityService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AudioFilePathProviderImpl implements AudioFilePathProvider {
|
||||
|
||||
private final FileEntityService fileEntityService;
|
||||
|
||||
private final FileEntityRepository fileEntityRepository;
|
||||
|
||||
@Override
|
||||
public @NotNull String providePath(@NotNull FileProtector.FileInfo fileInfo) {
|
||||
String filePath;
|
||||
Optional<FileEntity> optionalFileEntity = fileEntityRepository.findById(fileInfo.getId());
|
||||
|
||||
if (optionalFileEntity.isEmpty()) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
FileEntity fileEntity = optionalFileEntity.get();
|
||||
|
||||
try {
|
||||
filePath = fileEntityService.prepareProtectedPath(fileEntity, fileEntity.getFileExtension()).toString();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package ru.soune.nocopy.service.file.impl;
|
||||
|
||||
import com.vrt.fileprotection.FileProtector;
|
||||
import com.vrt.fileprotection.audio.AudioLocalSearch;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.service.file.FileEntityService;
|
||||
import ru.soune.nocopy.util.FileUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AudioLocalSearchImpl implements AudioLocalSearch {
|
||||
|
||||
private final FileEntityService fileEntityService;
|
||||
|
||||
private final FileUtil fileUtil;
|
||||
|
||||
@Override
|
||||
public @Nullable FileProtector.FileInfo findBySignature(@NotNull String signature) {
|
||||
FileEntity fileEntity = fileEntityService.findBySignature(signature);
|
||||
|
||||
return fileUtil.createFileInfo(fileEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSignature(@NotNull String signature, @NotNull FileProtector.FileInfo fileInfo) {
|
||||
try {
|
||||
fileEntityService.updateSignature(signature, fileInfo.getId());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+26
-5
@@ -1,5 +1,7 @@
|
||||
package ru.soune.nocopy.service.file;
|
||||
package ru.soune.nocopy.service.file.impl;
|
||||
|
||||
import com.vrt.NoCopyFileService;
|
||||
import com.vrt.fileprotection.FileProtector;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -23,6 +25,9 @@ import ru.soune.nocopy.repository.FileUploadSessionRepository;
|
||||
import ru.soune.nocopy.repository.SimilarImageProjection;
|
||||
import ru.soune.nocopy.service.FileSimilarityService;
|
||||
import ru.soune.nocopy.service.ImageHashService;
|
||||
import ru.soune.nocopy.service.file.FileEntityService;
|
||||
import ru.soune.nocopy.service.file.FileUploadService;
|
||||
import ru.soune.nocopy.util.FileUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
@@ -73,6 +78,10 @@ public class FileUploadServiceImpl implements FileUploadService {
|
||||
@Autowired
|
||||
private FileEntityService fileEntityService;
|
||||
|
||||
private final NoCopyFileService noCopyFileService;
|
||||
|
||||
private final FileUtil fileUtil;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
try {
|
||||
@@ -274,11 +283,16 @@ public class FileUploadServiceImpl implements FileUploadService {
|
||||
|
||||
FileEntity saved = fileEntityRepository.save(fileEntity);
|
||||
|
||||
Map<String, Integer> hash = imageHashService.calculateHash(filePath);
|
||||
imageHashService.create(saved, hash);
|
||||
if (session.getFileType().equals("image")) {
|
||||
Map<String, Long> hash = imageHashService.calculateHash(filePath);
|
||||
|
||||
imageHashService.create(saved, hash);
|
||||
}
|
||||
|
||||
cleanupSessionFiles(session);
|
||||
|
||||
noCopyFileService.addFile(fileUtil.createFileInfo(fileEntity));
|
||||
|
||||
log.info("File processing completed for session: {}", session.getUploadId());
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -370,7 +384,8 @@ public class FileUploadServiceImpl implements FileUploadService {
|
||||
private void checkForDuplicatesSynchronously(String filePath)
|
||||
throws IOException {
|
||||
Path path = Paths.get(filePath);
|
||||
Map<String, Integer> hash = imageHashService.calculateHash(path);
|
||||
Map<String, Long> hash = imageHashService.calculateHash(path);
|
||||
|
||||
List<SimilarImageProjection> duplicates = fileSimilarityService.findDuplicatedByHash(
|
||||
hash.get("hi"), hash.get("low"));
|
||||
|
||||
@@ -482,11 +497,17 @@ public class FileUploadServiceImpl implements FileUploadService {
|
||||
session.setChecksum(checksum);
|
||||
session.setStatus(UploadStatus.COMPLETED);
|
||||
session.setCompletedAt(LocalDateTime.now());
|
||||
|
||||
sessionRepository.save(session);
|
||||
log.info("Upload session updated to COMPLETED: {}", session.getUploadId());
|
||||
|
||||
try {
|
||||
fileEntityService.createFromUploadSession(session, checksum);
|
||||
FileEntity fileEntity = fileEntityService.createFromUploadSession(session, checksum);
|
||||
|
||||
FileProtector.FileInfo fileInfo = fileUtil.createFileInfo(fileEntity);
|
||||
|
||||
noCopyFileService.addFile(fileInfo);
|
||||
|
||||
log.info("FileEntity successfully created for session: {}",
|
||||
session.getUploadId());
|
||||
} catch (DuplicateImageException e) {
|
||||
@@ -0,0 +1,54 @@
|
||||
package ru.soune.nocopy.service.file.impl;
|
||||
|
||||
import com.vrt.fileprotection.FileProtector;
|
||||
import com.vrt.fileprotection.image.ImageLocalSearch;
|
||||
import com.vrt.fileprotection.image.phash.PHash;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.soune.nocopy.dto.file.SimilarFileDTO;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.entity.file.ImageHashEntity;
|
||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||
import ru.soune.nocopy.repository.ImageHashRepository;
|
||||
import ru.soune.nocopy.service.FileSimilarityService;
|
||||
import ru.soune.nocopy.util.FileUtil;
|
||||
|
||||
import java.util.List;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ImageLocalSearchImpl implements ImageLocalSearch {
|
||||
|
||||
private final FileSimilarityService fileSimilarityService;
|
||||
|
||||
private final ImageHashRepository imageHashRepository;
|
||||
|
||||
private final FileUtil fileUtil;
|
||||
|
||||
private final FileEntityRepository fileEntityRepository;
|
||||
|
||||
@Override
|
||||
public @NotNull List<Result> find(@NotNull FileProtector.FileInfo fileInfo) {
|
||||
List<SimilarFileDTO> duplicateByHammingDistance =
|
||||
fileSimilarityService.findDuplicateByHammingDistance(fileInfo.getId(), 10,
|
||||
5, 10);
|
||||
|
||||
return duplicateByHammingDistance.stream()
|
||||
.map(fileUtil::convertToResult)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FileProtector.FileInfo findByPHash(@NotNull PHash pHash) {
|
||||
ImageHashEntity imageHashEntity =
|
||||
imageHashRepository.findByHash64HiAndHash64Lo(pHash.getFirstPart(),
|
||||
pHash.getSecondPart());
|
||||
FileEntity file = fileEntityRepository.findByFileId(imageHashEntity.getFileId());
|
||||
|
||||
return new FileProtector.FileInfo(FileProtector.Type.IMAGE, imageHashEntity.getFileId(),
|
||||
String.valueOf(file.getUserId()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package ru.soune.nocopy.service.file.impl;
|
||||
|
||||
import com.vrt.fileprotection.FileProtector;
|
||||
import com.vrt.fileprotection.OperationResult;
|
||||
import com.vrt.fileprotection.image.ImageUniqueCheck;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.soune.nocopy.dto.file.SimilarFileDTO;
|
||||
import ru.soune.nocopy.service.FileSimilarityService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ImageUniqueCheckImpl implements ImageUniqueCheck {
|
||||
|
||||
private final FileSimilarityService fileSimilarityService;
|
||||
|
||||
@Override
|
||||
public @NotNull OperationResult check(@NotNull FileProtector.FileInfo fileInfo) {
|
||||
String fileId = fileInfo.getId();
|
||||
List<SimilarFileDTO> duplicateByHammingDistance =
|
||||
fileSimilarityService.findDuplicateByHammingDistance(fileId, 3, 3, 4);
|
||||
|
||||
if (duplicateByHammingDistance == null || duplicateByHammingDistance.isEmpty()) {
|
||||
return OperationResult.Companion.success();
|
||||
} else {
|
||||
return OperationResult.Companion.failure("Duplicate file");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package ru.soune.nocopy.service.file.impl;
|
||||
|
||||
import com.vrt.fileprotection.FileProtector;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.soune.nocopy.entity.file.ProtectionStatus;
|
||||
import ru.soune.nocopy.service.file.FileEntityService;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class NoCopyProcessingListenerImpl implements FileProtector.ProcessingListener {
|
||||
|
||||
private final FileEntityService fileEntityService;
|
||||
|
||||
@Override
|
||||
public void onStartProcessing(FileProtector.FileInfo fileInfo) {
|
||||
fileEntityService.changeStatus(ProtectionStatus.PROCESSING, fileInfo.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProcessingFailed(FileProtector.FileInfo fileInfo) {
|
||||
fileEntityService.changeStatus(ProtectionStatus.FAILED, fileInfo.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSavingFailed(FileProtector.FileInfo fileInfo) {
|
||||
fileEntityService.changeStatus(ProtectionStatus.FAILED_SAVE, fileInfo.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish(FileProtector.FileInfo fileInfo) {
|
||||
fileEntityService.changeStatus(ProtectionStatus.PROTECTED, fileInfo.getId());;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package ru.soune.nocopy.service.file.impl;
|
||||
|
||||
import com.vrt.fileprotection.FileProtector;
|
||||
import com.vrt.fileprotection.OperationResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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
|
||||
@Override
|
||||
public File getImageFile(@NotNull String id) {
|
||||
return fileEntityService.getFileById(id);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public File getVideoFile(@NotNull String id) {
|
||||
return fileEntityService.getFileById(id);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public File getAudioFile(@NotNull String id) {
|
||||
return fileEntityService.getFileById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable File getSignature() {
|
||||
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) {
|
||||
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) {
|
||||
try {
|
||||
fileEntityService.writeProtectedFile(id, data, fileExt);
|
||||
return OperationResult.Companion.success();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to create protected file: {}", id, e);
|
||||
return OperationResult.Companion.failure("Failed to create protected file");
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public com.vrt.fileprotection.OperationResult writeVideoFile(@NotNull String id, @NotNull byte[] data, @Nullable String fileExt) {
|
||||
try {
|
||||
fileEntityService.writeProtectedFile(id, data, fileExt);
|
||||
return OperationResult.Companion.success();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to create protected file: {}", id, e);
|
||||
return OperationResult.Companion.failure("Failed to create protected file");
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public com.vrt.fileprotection.OperationResult writeImageFile(@NotNull String id, @NotNull byte[] data, @Nullable String fileExt) {
|
||||
try {
|
||||
fileEntityService.writeProtectedFile(id, data, fileExt);
|
||||
return OperationResult.Companion.success();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to create protected file: {}", id, e);
|
||||
return OperationResult.Companion.failure("Failed to create protected file");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user