Merge pull request #56 from shawly/main

feat(download): add file size calculation for DownloadService
This commit is contained in:
Simon
2022-10-20 11:12:40 +02:00
committed by GitHub
4 changed files with 40 additions and 4 deletions
@@ -5,11 +5,16 @@ import de.grimsi.gameyfin.entities.DetectedGame;
import de.grimsi.gameyfin.service.DownloadService;
import de.grimsi.gameyfin.service.GameService;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
@@ -50,10 +55,21 @@ public class GamesController {
DetectedGame game = gameService.getDetectedGame(slug);
String downloadFileName = downloadService.getDownloadFileName(game);
long downloadFileSize = downloadService.getDownloadFileSize(game);
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"%s\"".formatted(downloadFileName));
headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
headers.add(HttpHeaders.PRAGMA, "no-cache");
headers.add(HttpHeaders.EXPIRES, "0");
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
if (downloadFileSize > 0) {
headers.setContentLength(downloadFileSize);
}
return ResponseEntity
.ok()
.header("Content-Disposition", "attachment; filename=\"%s\"".formatted(downloadFileName))
.headers(headers)
.body(out -> downloadService.sendGamefilesToClient(game, out));
}
@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
@@ -34,6 +35,23 @@ public class DownloadService {
return getFilenameWithExtension(path) + ".zip";
}
public long getDownloadFileSize(DetectedGame game) {
Path path = Path.of(game.getPath());
try {
if (!path.toFile().isDirectory()) {
long fileSize = filesystemService.getSizeOnDisk(path);
log.info("Calculated file size for {} ({} MB).", path, Math.divideExact(fileSize, 1000000L));
return fileSize;
} else {
// return zero since we cannot set content length for ZipOutputStreams that are used to archive directories
return 0;
}
} catch (IOException e) {
throw new DownloadAbortedException();
}
}
public Resource sendImageToClient(String imageId) {
String filename = "%s.png".formatted(imageId);
return filesystemService.getFileFromCache(filename);
@@ -78,6 +96,7 @@ public class DownloadService {
}
private void sendGamefilesAsZipToClient(Path path, OutputStream outputStream) {
log.info("Archiving game path {} for download...", path);
ZipOutputStream zos = new ZipOutputStream(outputStream) {{
def.setLevel(Deflater.NO_COMPRESSION);
}};
@@ -87,6 +106,7 @@ public class DownloadService {
@SneakyThrows
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
zos.putNextEntry(new ZipEntry(path.relativize(file).toString()));
log.debug("Adding file {} to archive...", file);
Files.copy(file, zos);
zos.closeEntry();
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "frontend",
"version": "1.2.3-SNAPSHOT",
"version": "1.2.4-SNAPSHOT",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "frontend",
"version": "1.2.3-SNAPSHOT",
"version": "1.2.4-SNAPSHOT",
"dependencies": {
"@angular/animations": "^14.0.0",
"@angular/cdk": "^14.1.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "frontend",
"version": "1.2.3-SNAPSHOT",
"version": "1.2.4-SNAPSHOT",
"scripts": {
"ng": "ng",
"start": "ng serve",