mirror of
https://github.com/RoastSlav/quickdrop.git
synced 2025-12-21 14:29:33 -06:00
Deleting download logs for deleted files
This commit is contained in:
@@ -2,6 +2,7 @@ package org.rostislav.quickdrop.repository;
|
||||
|
||||
import org.rostislav.quickdrop.entity.DownloadLog;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import java.util.List;
|
||||
@@ -14,4 +15,8 @@ public interface DownloadLogRepository extends JpaRepository<DownloadLog, Long>
|
||||
long countDownloadsByFileId(String uuid);
|
||||
|
||||
List<DownloadLog> findByFileUuid(String fileUUID);
|
||||
|
||||
@Modifying
|
||||
@Query("DELETE FROM DownloadLog dl WHERE dl.file.id = :id")
|
||||
void deleteByFileId(Long id);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.rostislav.quickdrop.service;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.rostislav.quickdrop.entity.DownloadLog;
|
||||
import org.rostislav.quickdrop.entity.FileEntity;
|
||||
import org.rostislav.quickdrop.model.FileEntityView;
|
||||
@@ -20,7 +21,10 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@@ -148,6 +152,10 @@ public class FileService {
|
||||
logger.info("File received: {}", file.getName());
|
||||
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
while (fileRepository.findByUUID(uuid).isPresent()) {
|
||||
uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
Path targetPath = Path.of(applicationSettingsService.getFileStoragePath(), uuid);
|
||||
|
||||
FileEntity fileEntity = populateFileEntity(file, fileUploadRequest, uuid);
|
||||
@@ -215,6 +223,7 @@ public class FileService {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public boolean deleteFile(String uuid) {
|
||||
Optional<FileEntity> referenceById = fileRepository.findByUUID(uuid);
|
||||
if (referenceById.isEmpty()) {
|
||||
@@ -223,6 +232,7 @@ public class FileService {
|
||||
|
||||
FileEntity fileEntity = referenceById.get();
|
||||
fileRepository.delete(fileEntity);
|
||||
downloadLogRepository.deleteByFileId(fileEntity.id);
|
||||
return deleteFileFromFileSystem(fileEntity.uuid);
|
||||
}
|
||||
|
||||
@@ -468,21 +478,6 @@ public class FileService {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void writeFileToStream(String uuid, OutputStream outputStream) {
|
||||
Path path = Path.of(applicationSettingsService.getFileStoragePath(), uuid);
|
||||
try (FileInputStream inputStream = new FileInputStream(path.toFile())) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
outputStream.flush();
|
||||
} catch (
|
||||
Exception e) {
|
||||
logger.error("Error writing file to stream: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void logDownload(FileEntity fileEntity, HttpServletRequest request) {
|
||||
String forwardedFor = request.getHeader("X-Forwarded-For");
|
||||
String realIp = request.getHeader("X-Real-IP");
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.rostislav.quickdrop.service;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.rostislav.quickdrop.entity.FileEntity;
|
||||
import org.rostislav.quickdrop.repository.DownloadLogRepository;
|
||||
import org.rostislav.quickdrop.repository.FileRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -19,13 +21,15 @@ public class ScheduleService {
|
||||
private final FileRepository fileRepository;
|
||||
private final FileService fileService;
|
||||
private final ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
|
||||
private final DownloadLogRepository downloadLogRepository;
|
||||
private ScheduledFuture<?> scheduledTask;
|
||||
|
||||
public ScheduleService(FileRepository fileRepository, FileService fileService) {
|
||||
public ScheduleService(FileRepository fileRepository, FileService fileService, DownloadLogRepository downloadLogRepository) {
|
||||
this.fileRepository = fileRepository;
|
||||
this.fileService = fileService;
|
||||
taskScheduler.setPoolSize(1);
|
||||
taskScheduler.initialize();
|
||||
this.downloadLogRepository = downloadLogRepository;
|
||||
}
|
||||
|
||||
public void updateSchedule(String cronExpression, long maxFileLifeTime) {
|
||||
@@ -39,6 +43,7 @@ public class ScheduleService {
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteOldFiles(long maxFileLifeTime) {
|
||||
logger.info("Deleting old files");
|
||||
LocalDate thresholdDate = LocalDate.now().minusDays(maxFileLifeTime);
|
||||
@@ -48,6 +53,7 @@ public class ScheduleService {
|
||||
boolean deleted = fileService.deleteFileFromFileSystem(file.uuid);
|
||||
if (deleted) {
|
||||
fileRepository.delete(file);
|
||||
downloadLogRepository.deleteByFileId(file.id);
|
||||
} else {
|
||||
logger.error("Failed to delete file: {}", file);
|
||||
}
|
||||
@@ -55,12 +61,14 @@ public class ScheduleService {
|
||||
logger.info("Deleted {} files", filesForDeletion.size());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Scheduled(cron = "0 0 3 * * *")
|
||||
public void cleanDatabaseFromDeletedFiles() {
|
||||
logger.info("Cleaning database from deleted files");
|
||||
fileRepository.findAll().forEach(file -> {
|
||||
if (!fileService.fileExistsInFileSystem(file.uuid)) {
|
||||
fileRepository.delete(file);
|
||||
downloadLogRepository.deleteByFileId(file.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h5>Total Downloads</h5>
|
||||
<h5 class="mb-0">Total Downloads</h5>
|
||||
<small class="text-muted">Doesn't count deleted files</small>
|
||||
<p class="text-muted" th:text="${analytics.totalDownloads}">0</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
|
||||
Reference in New Issue
Block a user