Merge branch 'dev' into NCBACK-35
# Conflicts: # README.md # src/main/java/ru/soune/nocopy/controller/ApiController.java # src/main/java/ru/soune/nocopy/handler/FileEntityHandler.java # src/main/java/ru/soune/nocopy/service/file/FileCleanupService.java # src/main/java/ru/soune/nocopy/service/file/FileEntityService.java # src/main/java/ru/soune/nocopy/service/file/impl/FileUploadServiceImpl.java # src/main/java/ru/soune/nocopy/service/file/impl/ProtectionFileProviderImpl.java
This commit is contained in:
@@ -2,19 +2,20 @@ package ru.soune.nocopy.service.file;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import ru.soune.nocopy.dto.file.FileEntityResponse;
|
||||
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.entity.monitoring.FileMonitoringEntity;
|
||||
import ru.soune.nocopy.entity.monitoring.MonitoringType;
|
||||
import ru.soune.nocopy.entity.user.User;
|
||||
import ru.soune.nocopy.exception.DuplicateImageException;
|
||||
import ru.soune.nocopy.exception.FileEntityNotFoundException;
|
||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||
import ru.soune.nocopy.repository.SimilarImageProjection;
|
||||
import ru.soune.nocopy.repository.FileMonitoringRepository;
|
||||
import ru.soune.nocopy.repository.UserRepository;
|
||||
import ru.soune.nocopy.service.FileSimilarityService;
|
||||
import ru.soune.nocopy.service.ImageHashService;
|
||||
@@ -27,7 +28,7 @@ import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@@ -37,70 +38,14 @@ public class FileEntityService {
|
||||
|
||||
private final FileEntityRepository fileEntityRepository;
|
||||
|
||||
private final ImageHashService imageHashService;
|
||||
|
||||
private final FileSimilarityService fileSimilarityService;
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
private final ImageResizeService imageResizeService;
|
||||
|
||||
private final CloudStorageService cloudStorageService;
|
||||
|
||||
@Transactional(noRollbackFor = DuplicateImageException.class)
|
||||
public FileEntity createFromUploadSession(FileUploadSession session, String checksum) {
|
||||
log.info("Creating FileEntity for upload session: {}", session.getUploadId());
|
||||
|
||||
try {
|
||||
Path filePath = Paths.get(session.getFilePath());
|
||||
|
||||
if (!Files.exists(filePath)) {
|
||||
throw new IOException("File not found on disk: " + filePath);
|
||||
}
|
||||
|
||||
Map<String, Long> imageHash = Map.of();
|
||||
|
||||
if (!session.getFileType().startsWith("video")) {
|
||||
imageHash = imageHashService.calculateHash(filePath);
|
||||
List<SimilarImageProjection> duplicatedByHash = fileSimilarityService.findDuplicatedByHash(
|
||||
imageHash.get("hi"), imageHash.get("low"));
|
||||
|
||||
if (!duplicatedByHash.isEmpty()) {
|
||||
SimilarImageProjection similarImageProjection = duplicatedByHash.get(0);
|
||||
|
||||
throw new DuplicateImageException("Duplicate", similarImageProjection.getId(),
|
||||
similarImageProjection.getUserId());
|
||||
}
|
||||
}
|
||||
|
||||
long fileSize = Files.size(filePath);
|
||||
String originalName = session.getFileName();
|
||||
String storedName = filePath.getFileName().toString();
|
||||
|
||||
FileEntity fileEntity = FileEntity.builder()
|
||||
.userId(session.getUserId())
|
||||
.originalFileName(originalName)
|
||||
.storedFileName(storedName)
|
||||
.filePath(session.getFilePath())
|
||||
.fileSize(fileSize)
|
||||
.mimeType(session.getFileType())
|
||||
.fileExtension(session.getExtension())
|
||||
.checksum(checksum)
|
||||
.uploadSessionId(session.getUploadId())
|
||||
.status(FileStatus.ACTIVE)
|
||||
.build();
|
||||
|
||||
FileEntity saved = fileEntityRepository.save(fileEntity);
|
||||
|
||||
if (!imageHash.isEmpty()) {
|
||||
imageHashService.create(saved, imageHash);
|
||||
}
|
||||
|
||||
return saved;
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to create FileEntity for session {}: {}",
|
||||
session.getUploadId(), e.getMessage(), e);
|
||||
throw new RuntimeException("Failed to create file entity: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
@Value("${server.baseurl}")
|
||||
private String baseUrl;
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public FileEntityResponse getById(String fileId, int version) {
|
||||
@@ -119,6 +64,34 @@ 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 List<FileEntity> getAllUserFiles(Long userId) {
|
||||
User user = userRepository.findById(userId).orElseThrow();
|
||||
List<FileEntity> allFiles = new ArrayList<>();
|
||||
|
||||
if (user.getCompany() != null) {
|
||||
for (Long uId : userRepository.findByCompanyId(user.getCompany().getId()).stream()
|
||||
.map(User::getId)
|
||||
.toList()) {
|
||||
allFiles.addAll(fileEntityRepository.findByUserIdAndStatusIn(uId,
|
||||
List.of(FileStatus.ACTIVE, FileStatus.BLOCKED)));
|
||||
}
|
||||
} else {
|
||||
allFiles = fileEntityRepository.findByUserIdAndStatusIn(userId,
|
||||
List.of(FileStatus.ACTIVE, FileStatus.BLOCKED));
|
||||
}
|
||||
|
||||
return allFiles;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public FileResponse getUserFiles(Long userId, int page, int pageSize, int version) {
|
||||
User user = userRepository.findById(userId).orElseThrow();
|
||||
@@ -128,12 +101,13 @@ public class FileEntityService {
|
||||
for (Long uId : userRepository.findByCompanyId(user.getCompany().getId()).stream()
|
||||
.map(User::getId)
|
||||
.toList()) {
|
||||
allFiles.addAll(fileEntityRepository.findByUserIdAndStatus(uId, FileStatus.ACTIVE));
|
||||
allFiles.addAll(fileEntityRepository.findByUserIdAndStatusIn(uId,
|
||||
List.of(FileStatus.ACTIVE, FileStatus.BLOCKED)));
|
||||
}
|
||||
|
||||
} else {
|
||||
allFiles = fileEntityRepository.findByUserIdAndStatus(
|
||||
userId, FileStatus.ACTIVE);
|
||||
allFiles = fileEntityRepository.findByUserIdAndStatusIn(userId,
|
||||
List.of(FileStatus.ACTIVE, FileStatus.BLOCKED));
|
||||
}
|
||||
|
||||
int start = (page - 1) * pageSize;
|
||||
@@ -175,13 +149,13 @@ public class FileEntityService {
|
||||
fileEntity.setImageHash(null);
|
||||
}
|
||||
|
||||
fileEntity.setStatus(FileStatus.DELETED);
|
||||
fileEntity.setStatus(FileStatus.REMOVED);
|
||||
fileEntity.setUpdatedAt(LocalDateTime.now());
|
||||
fileEntity.setProtectionStatus(ProtectionStatus.NOT_PROTECTED);
|
||||
// fileEntity.setProtectionStatus(ProtectionStatus.NOT_PROTECTED);
|
||||
|
||||
Path path = Paths.get(fileEntity.getProtectedFilePath());
|
||||
Files.deleteIfExists(path);
|
||||
fileEntity.setProtectedFilePath("");
|
||||
// Path path = Paths.get(fileEntity.getProtectedFilePath());
|
||||
// Files.deleteIfExists(path);
|
||||
// fileEntity.setProtectedFilePath("");
|
||||
|
||||
fileEntityRepository.save(fileEntity);
|
||||
}
|
||||
@@ -196,7 +170,7 @@ public class FileEntityService {
|
||||
return totalSize != null ? totalSize : 0L;
|
||||
}
|
||||
|
||||
public void changeStatus(ProtectionStatus newStatus, String fileId) {
|
||||
public void changeProtectionStatus(ProtectionStatus newStatus, String fileId) {
|
||||
FileEntity fileEntity = fileEntityRepository.findById(fileId)
|
||||
.orElseThrow(() -> new FileEntityNotFoundException(fileId));
|
||||
fileEntity.setProtectionStatus(newStatus);
|
||||
@@ -204,6 +178,14 @@ public class FileEntityService {
|
||||
fileEntityRepository.save(fileEntity);
|
||||
}
|
||||
|
||||
public void changeFileStatus(FileStatus newStatus, String fileId) {
|
||||
FileEntity fileEntity = fileEntityRepository.findById(fileId)
|
||||
.orElseThrow(() -> new FileEntityNotFoundException(fileId));
|
||||
fileEntity.setStatus(newStatus);
|
||||
|
||||
fileEntityRepository.save(fileEntity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public FileEntity writeProtectedFile(String id, byte[] data, String fileExt) throws IOException {
|
||||
FileEntity fileEntity = fileEntityRepository.findById(id)
|
||||
@@ -218,6 +200,10 @@ public class FileEntityService {
|
||||
|
||||
Files.write(protectedFilePath, data);
|
||||
|
||||
if (imageResizeService.isImage(extension)) {
|
||||
imageResizeService.generateSizes(fileEntity, data);
|
||||
}
|
||||
|
||||
fileEntity.setProtectedFilePath(protectedFilePath.toString());
|
||||
fileEntity.setProtectedAt(LocalDateTime.now());
|
||||
fileEntity.setUpdatedAt(LocalDateTime.now());
|
||||
@@ -308,14 +294,29 @@ public class FileEntityService {
|
||||
}
|
||||
}
|
||||
|
||||
private final FileMonitoringRepository fileMonitoringRepository;
|
||||
|
||||
private FileEntityResponse convertToResponse(FileEntity fileEntity, int version) {
|
||||
boolean existsOnDisk = checkFileExistsOnDisk(fileEntity.getFilePath());
|
||||
User user = userRepository.findById(fileEntity.getUserId()).get();
|
||||
String fileName = fileEntity.getOriginalFileName();
|
||||
String name = fileName;
|
||||
Optional<FileMonitoringEntity> fileMonitoringRepositoryByFileId =
|
||||
fileMonitoringRepository.findByFileId(fileEntity.getId());
|
||||
|
||||
String monitoring = fileMonitoringRepositoryByFileId.map(fileMonitoringEntity ->
|
||||
fileMonitoringEntity.getMonitoringType().name())
|
||||
.orElseGet(MonitoringType.NONE::name);
|
||||
|
||||
int lastDotIndex = fileName.lastIndexOf(".");
|
||||
if (lastDotIndex > 0) {
|
||||
name = fileName.substring(0, lastDotIndex);
|
||||
}
|
||||
|
||||
return FileEntityResponse.builder()
|
||||
.id(fileEntity.getId())
|
||||
.userId(fileEntity.getUserId())
|
||||
.originalFileName(fileEntity.getOriginalFileName())
|
||||
.originalFileName(name + "." + fileEntity.getFileExtension())
|
||||
.storedFileName(fileEntity.getStoredFileName())
|
||||
.filePath(fileEntity.getProtectedFilePath())
|
||||
.fileSize(fileEntity.getFileSize())
|
||||
@@ -331,16 +332,16 @@ public class FileEntityService {
|
||||
.existsOnDisk(existsOnDisk)
|
||||
.supportId(fileEntity.getSupportId())
|
||||
.protectStatus(fileEntity.getProtectionStatus().toString())
|
||||
.fileName(fileEntity.getOriginalFileName().replace("." +
|
||||
fileEntity.getFileExtension(), "") + "_nocopy_protected" +
|
||||
"." + fileEntity.getFileExtension())
|
||||
.fileName(name + "_nocopy_protected" + "." + fileEntity.getFileExtension())
|
||||
.ownerName(user.getFullName())
|
||||
.ownerEmail(user.getEmail())
|
||||
.ownerCompany(user.getCompanyName())
|
||||
.monitoring(monitoring)
|
||||
//TODO fix after add logic for check for protect file
|
||||
.checksCount(0)
|
||||
.fileUploadDate(fileEntity.getCreatedAt())
|
||||
.protectedFilePath(fileEntity.getProtectedFilePath())
|
||||
.thumbnailFileUrl(baseUrl + "/api/files/protected/" + fileEntity.getId() + "/thumbnail")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user