Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97b1fb7d85 | ||
|
|
22e9d6c9db | ||
|
|
8bad5a4619 | ||
|
|
3b04cc8907 | ||
|
|
ebbd69b452 | ||
|
|
47bed4149a | ||
|
|
e788b062b8 | ||
|
|
db606284cb | ||
|
|
de32f9b4d1 |
@@ -11,6 +11,7 @@ import org.springframework.http.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
import ru.soune.nocopy.dto.file.CheckStatus;
|
||||
import ru.soune.nocopy.dto.file.FileEntityResponse;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.entity.file.ProtectionStatus;
|
||||
import ru.soune.nocopy.entity.user.ProtectedFileCheck;
|
||||
@@ -19,8 +20,10 @@ import ru.soune.nocopy.repository.FileEntityRepository;
|
||||
import ru.soune.nocopy.repository.UserRepository;
|
||||
import ru.soune.nocopy.service.file.CheckCounterService;
|
||||
import ru.soune.nocopy.service.file.ZipService;
|
||||
import ru.soune.nocopy.service.file.*;
|
||||
import ru.soune.nocopy.service.file.cloud.CloudStorageService;
|
||||
import ru.soune.nocopy.util.FileUtil;
|
||||
import software.amazon.awssdk.services.mq.model.NotFoundException;
|
||||
import software.amazon.awssdk.services.s3.model.NoSuchKeyException;
|
||||
|
||||
import java.io.*;
|
||||
@@ -39,6 +42,8 @@ public class FileController {
|
||||
|
||||
private UserRepository userRepository;
|
||||
|
||||
private final FileEntityService fileEntityService;
|
||||
|
||||
private NoCopyFileService noCopyFileService;
|
||||
|
||||
private FileUtil fileUtil;
|
||||
@@ -85,6 +90,24 @@ public class FileController {
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/public/file-info/{fileId}")
|
||||
public ResponseEntity<FileEntityResponse> getPublicFileInfo(@PathVariable String fileId) {
|
||||
return handleGetFileInfo(fileId);
|
||||
}
|
||||
|
||||
private ResponseEntity<FileEntityResponse> handleGetFileInfo(String fileId) {
|
||||
try {
|
||||
FileEntityResponse fileInfo = fileEntityService.getById(fileId, 1);
|
||||
|
||||
return ResponseEntity
|
||||
.ok()
|
||||
.body(fileInfo);
|
||||
} catch (NotFoundException e) {
|
||||
return ResponseEntity
|
||||
.notFound().build();
|
||||
}
|
||||
}
|
||||
|
||||
private MediaType getMediaType(FileEntity fileEntity) {
|
||||
try {
|
||||
return MediaType.parseMediaType(fileEntity.getMimeType());
|
||||
@@ -113,13 +136,6 @@ public class FileController {
|
||||
|
||||
String filePath = type.equals("thumbnail") ? fileEntity.getThumbnailPath(): fileEntity.getFilePath();
|
||||
|
||||
// InputStream file = cloudStorageService.readFileFromStorage(filePath);
|
||||
|
||||
// if (file == null || !file.exists()) {
|
||||
// log.error("File not found in storage: {}", fileEntity.getFilePath());
|
||||
// return ResponseEntity.notFound().build();
|
||||
// }
|
||||
|
||||
if (fileEntity.getProtectionStatus() == ProtectionStatus.NOT_PROTECTED ||
|
||||
fileEntity.getProtectionStatus() == ProtectionStatus.PROCESSING) {
|
||||
throw new RuntimeException("File is not protected");
|
||||
|
||||
@@ -78,4 +78,10 @@ public class FileEntityRequest {
|
||||
|
||||
@JsonProperty("permissions")
|
||||
private Map<String, Boolean> permissions;
|
||||
|
||||
@JsonProperty("is_appeal")
|
||||
private Boolean isAppeal;
|
||||
|
||||
@JsonProperty("statuses")
|
||||
private List<String> statuses;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import ru.soune.nocopy.entity.file.FileStatus;
|
||||
import ru.soune.nocopy.entity.file.permission.PermissionType;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@@ -45,4 +46,5 @@ public class FileEntityResponse {
|
||||
private LocalDateTime fileUploadDate;
|
||||
private String monitoring;
|
||||
private Map<PermissionType, Boolean> permissions;
|
||||
private List<Map<String, Object>> appealInfos;
|
||||
}
|
||||
|
||||
@@ -36,4 +36,7 @@ public class FileListResponse {
|
||||
|
||||
@JsonProperty("total_size")
|
||||
private Long totalSize;
|
||||
|
||||
@JsonProperty("statuses")
|
||||
private List<String> statuses;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package ru.soune.nocopy.dto.file;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import ru.soune.nocopy.entity.file.FileAppeal;
|
||||
import ru.soune.nocopy.entity.file.FileStatus;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -16,5 +17,5 @@ public class FileModerationInfo {
|
||||
private FileStatus currentStatus;
|
||||
private LocalDateTime uploadDate;
|
||||
private Boolean hasActiveAppeal;
|
||||
private AppealInfo activeAppeal;
|
||||
private FileAppeal activeAppeal;
|
||||
}
|
||||
|
||||
@@ -279,10 +279,14 @@ public class FileEntityHandler implements RequestHandler {
|
||||
String[] searchTerms = searchQuery.split("\\s+");
|
||||
String filterType = fileRequest.getType();
|
||||
String dateFilter = fileRequest.getDateFilter();
|
||||
List<String> statuses = fileRequest.getStatuses();
|
||||
Boolean isAppeal = fileRequest.getIsAppeal();
|
||||
|
||||
List<FileEntityResponse> filteredFiles = allFiles.getFiles().stream()
|
||||
.filter(f -> matchesSearch(f, searchTerms, searchQuery, filterType))
|
||||
.filter(f -> matchesDateFilter(f, dateFilter))
|
||||
.filter(f -> matchesStatuses(f, statuses))
|
||||
.filter(f -> matchesAppeal(f, isAppeal))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Comparator<FileEntityResponse> comparator = getComparator(sortBy, sortOrder);
|
||||
@@ -309,6 +313,8 @@ public class FileEntityHandler implements RequestHandler {
|
||||
.pageSize(pageSize)
|
||||
.sortBy(sortBy)
|
||||
.sortOrder(sortOrder.getValue())
|
||||
.statuses(List.of(FileStatus.BLOCKED.name(), FileStatus.ACTIVE.name(),
|
||||
FileStatus.MODERATION.name()))
|
||||
.build();
|
||||
|
||||
return new BaseResponse(request.getMsgId(),
|
||||
@@ -348,6 +354,22 @@ public class FileEntityHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean matchesStatuses(FileEntityResponse file, List<String> statuses) {
|
||||
if (statuses == null || statuses.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return statuses.contains(file.getStatus().name());
|
||||
}
|
||||
|
||||
private boolean matchesAppeal(FileEntityResponse file, Boolean isAppeal) {
|
||||
if (isAppeal == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !file.getAppealInfos().isEmpty() == isAppeal;
|
||||
}
|
||||
|
||||
private boolean matchesSearch(FileEntityResponse file, String[] searchTerms, String fullQuery, String type) {
|
||||
String fileName = getSafeString(file.getFileName());
|
||||
String originalFileName = getSafeString(file.getOriginalFileName());
|
||||
|
||||
@@ -14,6 +14,7 @@ import ru.soune.nocopy.dto.file.AppealResponse;
|
||||
import ru.soune.nocopy.dto.file.FileEntityRequest;
|
||||
import ru.soune.nocopy.dto.file.FileModerationInfo;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.entity.file.FileStatus;
|
||||
import ru.soune.nocopy.service.file.moderation.ModerationService;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -71,9 +72,11 @@ public class FileInteranlInfoHandler implements RequestHandler {
|
||||
try {
|
||||
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 0;
|
||||
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
|
||||
List<String> statuses = fileRequest.getStatuses() == null ? List.of(FileStatus.MODERATION.name(),
|
||||
FileStatus.BLOCKED.name(), FileStatus.ACTIVE.name()): fileRequest.getStatuses();
|
||||
|
||||
Page<FileEntity> files = moderationService.getFilesForModeration(page, pageSize,
|
||||
fileRequest.getSortOrder(), fileRequest.getSortBy());
|
||||
fileRequest.getSortOrder(), fileRequest.getSortBy(), statuses, fileRequest.getIsAppeal());
|
||||
|
||||
List<Map<String, Object>> filesWithInfo = files.getContent().stream()
|
||||
.map(file -> {
|
||||
@@ -92,11 +95,8 @@ public class FileInteranlInfoHandler implements RequestHandler {
|
||||
moderationInfoMap.put("hasActiveAppeal", info != null && info.getHasActiveAppeal());
|
||||
|
||||
if (info != null && info.getActiveAppeal() != null) {
|
||||
Map<String, Object> appealInfoMap = new HashMap<>();
|
||||
appealInfoMap.put("appealId", info.getActiveAppeal().getAppealId());
|
||||
appealInfoMap.put("status", info.getActiveAppeal().getStatus());
|
||||
appealInfoMap.put("createdAt", info.getActiveAppeal().getCreatedAt());
|
||||
moderationInfoMap.put("appealInfo", appealInfoMap);
|
||||
AppealResponse appealResponse = moderationService.convertToResponse(info.getActiveAppeal());
|
||||
moderationInfoMap.put("appealInfo", appealResponse);
|
||||
} else {
|
||||
moderationInfoMap.put("appealInfo", null);
|
||||
}
|
||||
@@ -112,6 +112,7 @@ public class FileInteranlInfoHandler implements RequestHandler {
|
||||
"totalCount", files.getTotalElements(),
|
||||
"totalPages", files.getTotalPages(),
|
||||
"currentPage", page,
|
||||
"statuses",List.of(FileStatus.ACTIVE.name(), FileStatus.BLOCKED.name(), FileStatus.MODERATION.name()),
|
||||
"pageSize", pageSize
|
||||
);
|
||||
|
||||
|
||||
@@ -76,6 +76,13 @@ public interface FileEntityRepository extends JpaRepository<FileEntity, String>
|
||||
|
||||
Page<FileEntity> findByStatusIn(List<FileStatus> statuses, Pageable pageable);
|
||||
|
||||
@Query("SELECT f FROM FileEntity f WHERE f.status IN :statuses")
|
||||
Page<FileEntity> findByStatusInAndSorted(@Param("statuses") List<String> statuses, Pageable pageable);
|
||||
|
||||
|
||||
@Query("SELECT f FROM FileEntity f JOIN FileAppeal fa ON fa.fileId = f.id WHERE f.status IN :statuses")
|
||||
Page<FileEntity> findByStatusInAndSortedWithAppeal(@Param("statuses") List<String> statuses, Pageable pageable);
|
||||
|
||||
List<FileEntity> findByUserIdAndStatusIn(Long userId, List<FileStatus> statuses);
|
||||
|
||||
@Query("SELECT f FROM FileEntity f WHERE f.userId = :userId AND f.status IN :statuses")
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.FileAppeal;
|
||||
import ru.soune.nocopy.entity.file.FileEntity;
|
||||
import ru.soune.nocopy.entity.file.FileStatus;
|
||||
import ru.soune.nocopy.entity.file.ProtectionStatus;
|
||||
@@ -16,11 +17,13 @@ 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.FileEntityNotFoundException;
|
||||
import ru.soune.nocopy.repository.FileAppealRepository;
|
||||
import ru.soune.nocopy.repository.FileEntityRepository;
|
||||
import ru.soune.nocopy.repository.FileMonitoringRepository;
|
||||
import ru.soune.nocopy.repository.UserRepository;
|
||||
import ru.soune.nocopy.service.file.cloud.CloudStorageService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
@@ -29,9 +32,7 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@@ -47,6 +48,8 @@ public class FileEntityService {
|
||||
|
||||
private final CloudStorageService cloudStorageService;
|
||||
|
||||
private final FileAppealRepository fileAppealRepository;
|
||||
|
||||
@Value("${server.baseurl}")
|
||||
private String baseUrl;
|
||||
|
||||
@@ -387,6 +390,8 @@ public class FileEntityService {
|
||||
name = fileName.substring(0, lastDotIndex);
|
||||
}
|
||||
|
||||
List<Map<String, Object>> appeals = getFileAppeals(fileEntity.getId());
|
||||
|
||||
return FileEntityResponse.builder()
|
||||
.id(fileEntity.getId())
|
||||
.userId(fileEntity.getUserId())
|
||||
@@ -417,6 +422,30 @@ public class FileEntityService {
|
||||
.protectedFilePath(fileEntity.getProtectedFilePath())
|
||||
.thumbnailFileUrl(baseUrl + "/api/files/protected/" + fileEntity.getId() + "/thumbnail")
|
||||
.permissions(fileEntity.getPermissions())
|
||||
.appealInfos(appeals)
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> getFileAppeals(String fileId) {
|
||||
List<FileAppeal> appeals = fileAppealRepository.findByFileId(fileId);
|
||||
if (appeals == null || appeals.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return appeals.stream()
|
||||
.map(appeal -> {
|
||||
Map<String, Object> appealMap = new HashMap<>();
|
||||
appealMap.put("id", appeal.getId());
|
||||
appealMap.put("userId", appeal.getUserId());
|
||||
appealMap.put("appealReason", appeal.getAppealReason());
|
||||
appealMap.put("additionalInfo", appeal.getAdditionalInfo());
|
||||
appealMap.put("status", appeal.getStatus() != null ? appeal.getStatus().name() : null);
|
||||
appealMap.put("adminComment", appeal.getAdminComment());
|
||||
appealMap.put("moderatorId", appeal.getModeratorId());
|
||||
appealMap.put("createdAt", appeal.getCreatedAt());
|
||||
appealMap.put("resolvedAt", appeal.getResolvedAt());
|
||||
return appealMap;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -207,12 +207,7 @@ public class ModerationService {
|
||||
.currentStatus(file.getStatus())
|
||||
.uploadDate(file.getCreatedAt())
|
||||
.hasActiveAppeal(activeAppeal != null)
|
||||
.activeAppeal(activeAppeal != null ?
|
||||
AppealInfo.builder()
|
||||
.appealId(activeAppeal.getId())
|
||||
.status(activeAppeal.getStatus().name())
|
||||
.createdAt(activeAppeal.getCreatedAt())
|
||||
.build() : null)
|
||||
.activeAppeal(activeAppeal)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -229,7 +224,8 @@ public class ModerationService {
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<FileEntity> getFilesForModeration(int page, int size, String sortDirection, String sortBy) {
|
||||
public Page<FileEntity> getFilesForModeration(int page, int size, String sortDirection, String sortBy,
|
||||
List<String> statuses, Boolean isAppeal) {
|
||||
if (sortDirection == null || sortDirection.isEmpty()) {
|
||||
sortDirection = "desc";
|
||||
}
|
||||
@@ -240,7 +236,8 @@ public class ModerationService {
|
||||
|
||||
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.fromString(sortDirection), sortBy));
|
||||
|
||||
return fileEntityRepository.findByStatusIn(Arrays.asList(FileStatus.MODERATION, FileStatus.BLOCKED), pageable);
|
||||
return isAppeal != null ? fileEntityRepository.findByStatusInAndSortedWithAppeal(statuses, pageable):
|
||||
fileEntityRepository.findByStatusInAndSorted(statuses, pageable);
|
||||
}
|
||||
|
||||
|
||||
@@ -268,7 +265,7 @@ public class ModerationService {
|
||||
.map(this::convertToResponse);
|
||||
}
|
||||
|
||||
private AppealResponse convertToResponse(FileAppeal appeal) {
|
||||
public AppealResponse convertToResponse(FileAppeal appeal) {
|
||||
return AppealResponse.builder()
|
||||
.appealId(appeal.getId())
|
||||
.fileId(appeal.getFileId())
|
||||
|
||||
Reference in New Issue
Block a user