dev add violation notion
Test Workflow / test (push) Successful in 5s

This commit is contained in:
vladp
2026-03-19 18:03:44 +07:00
parent c5f060d269
commit 795b255613
5 changed files with 286 additions and 18 deletions
@@ -34,4 +34,10 @@ public class FileEntityRequest {
@JsonProperty("token")
private String token;
@JsonProperty("sort_by")
private String sortBy;
@JsonProperty("sort_order")
private String sortOrder;
}
@@ -30,4 +30,10 @@ public class FileListResponse {
@JsonProperty("page_size")
private Integer pageSize;
@JsonProperty("sort_by")
private String sortBy;
@JsonProperty("sort_order")
private String sortOrder;
}
@@ -0,0 +1,25 @@
package ru.soune.nocopy.dto.file;
import lombok.Getter;
@Getter
public enum SortOrder {
ASC("asc"),
DESC("desc");
private final String value;
SortOrder(String value) {
this.value = value;
}
public static SortOrder fromString(String value) {
if (value == null) return ASC;
for (SortOrder order : SortOrder.values()) {
if (order.value.equalsIgnoreCase(value)) {
return order;
}
}
return ASC;
}
}
@@ -16,9 +16,8 @@ import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.file.FileEntityService;
import ru.soune.nocopy.service.file.FileStatsService;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Component
@@ -183,53 +182,285 @@ public class FileEntityHandler implements RequestHandler {
}
}
// private BaseResponse handleSearchFiles(BaseRequest request, FileEntityRequest fileRequest) {
// try {
// Long userId = authService.useUserAuthToken(fileRequest.getToken());
// int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
// int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
//
// if (fileRequest.getQuery() == null || fileRequest.getQuery().isBlank()) {
// return handleGetUserFiles(request, fileRequest);
// }
//
// FileResponse allFiles = fileEntityService.getUserFiles(userId, 1, 1000, request.getVersion());
//
// var filteredFiles = allFiles.getFiles().stream()
// .filter(f -> (f.getOriginalFileName() + f.getFileExtension()).toLowerCase()
// .contains(fileRequest.getQuery().toLowerCase()))
// .toList();
//
// int start = (page - 1) * pageSize;
// int end = Math.min(start + pageSize, filteredFiles.size());
// List<FileEntityResponse> fileEntityResponses = filteredFiles.subList(start, Math.min(end, filteredFiles.size()));
// long sumSize = fileEntityResponses.stream()
// .mapToLong(FileEntityResponse::getFileSize)
// .sum();
//
// FileListResponse response = FileListResponse.builder()
// .files(fileEntityResponses)
// .totalCount(filteredFiles.size())
// .totalSize(sumSize)
// .formattedTotalSize(fileEntityService.formatFileSize(sumSize))
// .page(page)
// .pageSize(pageSize)
// .build();
//
// return new BaseResponse(request.getMsgId(),
// MessageCode.SUCCESS.getCode(),
// MessageCode.SUCCESS.getDescription(),
// response);
// } catch (NotFoundAuthToken e) {
// return new BaseResponse(request.getMsgId(), MessageCode.INVALID_TOKEN.getCode(),
// "Authentication required", null);
// } catch (Exception e) {
// log.error("Error searching files", e);
// return new BaseResponse(request.getMsgId(), MessageCode.FILE_UPLOAD_ERROR.getCode(),
// "Failed to search files: " + e.getMessage(), null);
// }
// }
private BaseResponse handleSearchFiles(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = authService.useUserAuthToken(fileRequest.getToken());
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
String sortBy = fileRequest.getSortBy() != null ? fileRequest.getSortBy() : "fileName";
SortOrder sortOrder = SortOrder.fromString(fileRequest.getSortOrder());
if (fileRequest.getQuery() == null || fileRequest.getQuery().isBlank()) {
return handleGetUserFiles(request, fileRequest);
return handleGetUserFilesWithSort(request, fileRequest, sortBy, sortOrder);
}
FileResponse allFiles = fileEntityService.getUserFiles(userId, 1, 1000, request.getVersion());
var filteredFiles = allFiles.getFiles().stream()
.filter(f -> (f.getOriginalFileName() + f.getFileExtension()).toLowerCase()
.contains(fileRequest.getQuery().toLowerCase()))
.toList();
String searchQuery = fileRequest.getQuery().toLowerCase().trim();
String[] searchTerms = searchQuery.split("\\s+");
List<FileEntityResponse> filteredFiles = allFiles.getFiles().stream()
.filter(f -> matchesSearch(f, searchTerms, searchQuery))
.collect(Collectors.toList());
Comparator<FileEntityResponse> comparator = getComparator(sortBy, sortOrder);
filteredFiles.sort(comparator);
int start = (page - 1) * pageSize;
int end = Math.min(start + pageSize, filteredFiles.size());
List<FileEntityResponse> fileEntityResponses = filteredFiles.subList(start, Math.min(end, filteredFiles.size()));
long sumSize = fileEntityResponses.stream()
if (start >= filteredFiles.size()) {
return createEmptyResponse(request, page, pageSize, sortBy, sortOrder.getValue());
}
List<FileEntityResponse> paginatedFiles = filteredFiles.subList(start, end);
long totalSize = paginatedFiles.stream()
.mapToLong(FileEntityResponse::getFileSize)
.sum();
FileListResponse response = FileListResponse.builder()
.files(fileEntityResponses)
.files(paginatedFiles)
.totalCount(filteredFiles.size())
.totalSize(sumSize)
.formattedTotalSize(fileEntityService.formatFileSize(sumSize))
.totalSize(totalSize)
.formattedTotalSize(fileEntityService.formatFileSize(totalSize))
.page(page)
.pageSize(pageSize)
.sortBy(sortBy)
.sortOrder(sortOrder.getValue())
.build();
return new BaseResponse(request.getMsgId(),
MessageCode.SUCCESS.getCode(),
MessageCode.SUCCESS.getDescription(),
response);
} catch (NotFoundAuthToken e) {
return new BaseResponse(request.getMsgId(), MessageCode.INVALID_TOKEN.getCode(),
return new BaseResponse(request.getMsgId(),
MessageCode.INVALID_TOKEN.getCode(),
"Authentication required", null);
} catch (Exception e) {
log.error("Error searching files", e);
return new BaseResponse(request.getMsgId(), MessageCode.FILE_UPLOAD_ERROR.getCode(),
return new BaseResponse(request.getMsgId(),
MessageCode.FILE_UPLOAD_ERROR.getCode(),
"Failed to search files: " + e.getMessage(), null);
}
}
private boolean matchesSearch(FileEntityResponse file, String[] searchTerms, String fullQuery) {
String fileName = getSafeString(file.getFileName());
String originalFileName = getSafeString(file.getOriginalFileName());
String fileFormat = getSafeString(file.getFileFormat());
String fullFileName = fileName + " " + originalFileName;
if (fullFileName.toLowerCase().contains(fullQuery)) {
return true;
}
for (String term : searchTerms) {
if (term.length() < 2) continue;
if (fullFileName.toLowerCase().contains(term)) {
return true;
}
}
if (fileFormat.toLowerCase().contains(fullQuery)) {
return true;
}
String fileNameWithExtension = fileName;
if (!fileFormat.isEmpty() && !fileName.toLowerCase().endsWith("." + fileFormat.toLowerCase())) {
fileNameWithExtension = fileName + "." + fileFormat;
if (fileNameWithExtension.toLowerCase().contains(fullQuery)) {
return true;
}
}
return false;
}
private String getSafeString(String value) {
return value != null ? value : "";
}
private Comparator<FileEntityResponse> getComparator(String sortBy, SortOrder sortOrder) {
Comparator<FileEntityResponse> comparator;
switch (sortBy) {
case "fileSize":
comparator = Comparator.comparingLong(
FileEntityResponse::getFileSize
);
break;
case "createdAt":
comparator = Comparator.comparing(
FileEntityResponse::getCreatedAt,
Comparator.nullsLast(Comparator.naturalOrder())
);
break;
case "updatedAt":
comparator = Comparator.comparing(
FileEntityResponse::getUpdatedAt,
Comparator.nullsLast(Comparator.naturalOrder())
);
break;
case "fileName":
comparator = Comparator.comparing(
f -> getSafeString(f.getFileName()).toLowerCase(),
Comparator.nullsLast(Comparator.naturalOrder())
);
break;
case "protectStatus":
comparator = Comparator.comparing(
f -> getSafeString(f.getProtectStatus()).toLowerCase(),
Comparator.nullsLast(Comparator.naturalOrder())
);
break;
case "supportId":
comparator = Comparator.comparing(
FileEntityResponse::getSupportId,
Comparator.nullsLast(Comparator.naturalOrder())
);
break;
default:
comparator = Comparator.comparing(
f -> getSafeString(f.getFileName()).toLowerCase(),
Comparator.nullsLast(Comparator.naturalOrder())
);
break;
}
return sortOrder == SortOrder.DESC ? comparator.reversed() : comparator;
}
private BaseResponse createEmptyResponse(BaseRequest request, int page, int pageSize,
String sortBy, String sortOrder) {
FileListResponse emptyResponse = FileListResponse.builder()
.files(Collections.emptyList())
.totalCount(0)
.totalSize(0L)
.formattedTotalSize("0 B")
.page(page)
.pageSize(pageSize)
.sortBy(sortBy)
.sortOrder(sortOrder)
.build();
return new BaseResponse(request.getMsgId(),
MessageCode.SUCCESS.getCode(),
MessageCode.SUCCESS.getDescription(),
emptyResponse);
}
private BaseResponse handleGetUserFilesWithSort(BaseRequest request, FileEntityRequest fileRequest,
String sortBy, SortOrder sortOrder) {
try {
Long userId = authService.useUserAuthToken(fileRequest.getToken());
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
FileResponse allFiles = fileEntityService.getUserFiles(userId, 1, 1000, request.getVersion());
List<FileEntityResponse> files = new ArrayList<>(allFiles.getFiles());
Comparator<FileEntityResponse> comparator = getComparator(sortBy, sortOrder);
files.sort(comparator);
int start = (page - 1) * pageSize;
int end = Math.min(start + pageSize, files.size());
if (start >= files.size()) {
return createEmptyResponse(request, page, pageSize, sortBy, sortOrder.getValue());
}
List<FileEntityResponse> paginatedFiles = files.subList(start, end);
long totalSize = paginatedFiles.stream()
.mapToLong(FileEntityResponse::getFileSize)
.sum();
FileListResponse response = FileListResponse.builder()
.files(paginatedFiles)
.totalCount(files.size())
.totalSize(totalSize)
.formattedTotalSize(fileEntityService.formatFileSize(totalSize))
.page(page)
.pageSize(pageSize)
.sortBy(sortBy)
.sortOrder(sortOrder.getValue())
.build();
return new BaseResponse(request.getMsgId(),
MessageCode.SUCCESS.getCode(),
MessageCode.SUCCESS.getDescription(),
response);
} catch (NotFoundAuthToken e) {
return new BaseResponse(request.getMsgId(),
MessageCode.INVALID_TOKEN.getCode(),
"Authentication required", null);
} catch (Exception e) {
log.error("Error getting user files with sort", e);
return new BaseResponse(request.getMsgId(),
MessageCode.FILE_UPLOAD_ERROR.getCode(),
"Failed to get files: " + e.getMessage(),
null);
}
}
private BaseResponse handleGetStorageUsage(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = authService.useUserAuthToken(fileRequest.getToken());
@@ -32,11 +32,11 @@ public class SearchImageService {
private final OkHttpClient googleHttpClient;
public SearchImageService() {
Proxy proxy = new Proxy(Proxy.Type.HTTP,
new InetSocketAddress("193.46.217.94", 3128));
// Proxy proxy = new Proxy(Proxy.Type.HTTP,
// new InetSocketAddress("193.46.217.94", 3128));
this.yandexHttpClient = new OkHttpClient.Builder()
.proxy(proxy)
// .proxy(proxy)
.connectTimeout(35, TimeUnit.SECONDS)
.writeTimeout(35, TimeUnit.SECONDS)
.readTimeout(35, TimeUnit.SECONDS)