From 1036c731ad855e4a21d2214c0c60ff4c27afd0de Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 18 Jun 2021 09:49:19 -0500 Subject: [PATCH] When performing a download, if there is only 1 file, don't zip it and send back the raw file. (#315) --- API/Controllers/DownloadController.cs | 45 ++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/API/Controllers/DownloadController.cs b/API/Controllers/DownloadController.cs index 67d23ac8e..f0a006120 100644 --- a/API/Controllers/DownloadController.cs +++ b/API/Controllers/DownloadController.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; +using API.Entities; using API.Extensions; using API.Interfaces; using API.Interfaces.Services; @@ -9,6 +11,7 @@ using API.Services; using Kavita.Common; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.StaticFiles; namespace API.Controllers { @@ -17,11 +20,13 @@ namespace API.Controllers { private readonly IUnitOfWork _unitOfWork; private readonly IArchiveService _archiveService; + private readonly IDirectoryService _directoryService; - public DownloadController(IUnitOfWork unitOfWork, IArchiveService archiveService) + public DownloadController(IUnitOfWork unitOfWork, IArchiveService archiveService, IDirectoryService directoryService) { _unitOfWork = unitOfWork; _archiveService = archiveService; + _directoryService = directoryService; } [HttpGet("volume-size")] @@ -51,25 +56,51 @@ namespace API.Controllers var files = await _unitOfWork.VolumeRepository.GetFilesForVolume(volumeId); try { + if (files.Count == 1) + { + return await GetFirstFileDownload(files); + } var (fileBytes, zipPath) = await _archiveService.CreateZipForDownload(files.Select(c => c.FilePath), $"download_{User.GetUsername()}_v{volumeId}"); - return File(fileBytes, "application/zip", Path.GetFileName(zipPath)); + return File(fileBytes, "application/zip", Path.GetFileNameWithoutExtension(zipPath) + ".zip"); } catch (KavitaException ex) { return BadRequest(ex.Message); } } - + + private async Task GetFirstFileDownload(IEnumerable files) + { + var firstFile = files.Select(c => c.FilePath).First(); + var fileProvider = new FileExtensionContentTypeProvider(); + // Figures out what the content type should be based on the file name. + if (!fileProvider.TryGetContentType(firstFile, out var contentType)) + { + contentType = Path.GetExtension(firstFile).ToLowerInvariant() switch + { + ".cbz" => "application/zip", + ".cbr" => "application/vnd.rar", + _ => contentType + }; + } + + return File(await _directoryService.ReadFileAsync(firstFile), contentType, Path.GetFileNameWithoutExtension(firstFile)); + } + [HttpGet("chapter")] public async Task DownloadChapter(int chapterId) { var files = await _unitOfWork.VolumeRepository.GetFilesForChapter(chapterId); try { + if (files.Count == 1) + { + return await GetFirstFileDownload(files); + } var (fileBytes, zipPath) = await _archiveService.CreateZipForDownload(files.Select(c => c.FilePath), $"download_{User.GetUsername()}_c{chapterId}"); - return File(fileBytes, "application/zip", Path.GetFileName(zipPath)); + return File(fileBytes, "application/zip", Path.GetFileNameWithoutExtension(zipPath) + ".zip"); } catch (KavitaException ex) { @@ -83,9 +114,13 @@ namespace API.Controllers var files = await _unitOfWork.SeriesRepository.GetFilesForSeries(seriesId); try { + if (files.Count == 1) + { + return await GetFirstFileDownload(files); + } var (fileBytes, zipPath) = await _archiveService.CreateZipForDownload(files.Select(c => c.FilePath), $"download_{User.GetUsername()}_s{seriesId}"); - return File(fileBytes, "application/zip", Path.GetFileName(zipPath)); + return File(fileBytes, "application/zip", Path.GetFileNameWithoutExtension(zipPath) + ".zip"); } catch (KavitaException ex) {