Add Download ability
This commit is contained in:
parent
ae367797bb
commit
1791fd909d
5 changed files with 110 additions and 17 deletions
|
@ -6,12 +6,9 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import ru.redrise.marinesco.data.InpEntryRepository;
|
||||
import ru.redrise.marinesco.library.Author;
|
||||
import ru.redrise.marinesco.library.InpEntry;
|
||||
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/book")
|
||||
public class BookController {
|
||||
|
|
89
src/main/java/ru/redrise/marinesco/DownloadController.java
Normal file
89
src/main/java/ru/redrise/marinesco/DownloadController.java
Normal file
|
@ -0,0 +1,89 @@
|
|||
package ru.redrise.marinesco;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.http.ContentDisposition;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import jakarta.servlet.ServletOutputStream;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import ru.redrise.marinesco.settings.ApplicationSettings;
|
||||
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/download")
|
||||
public class DownloadController {
|
||||
|
||||
private String filesLocation;
|
||||
|
||||
public DownloadController(ApplicationSettings applicationSettings) {
|
||||
this.filesLocation = applicationSettings.getFilesLocation();
|
||||
}
|
||||
|
||||
@GetMapping(value = "/")
|
||||
public void getMethodName(@RequestParam String container,
|
||||
@RequestParam String file,
|
||||
HttpServletResponse response) throws Exception {
|
||||
|
||||
final FileSystemResource libraryLocation = new FileSystemResource(filesLocation + File.separator + container);
|
||||
try (ZipInputStream zipInputStream = new ZipInputStream(libraryLocation.getInputStream())) {
|
||||
ZipEntry zipEntry = zipInputStream.getNextEntry();
|
||||
|
||||
while (zipEntry != null) {
|
||||
if (zipEntry.getName().contains(file)) {
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, ContentDisposition.attachment()
|
||||
.filename(file+".fb2", StandardCharsets.UTF_8) //TODO: fix
|
||||
.build()
|
||||
.toString());
|
||||
ServletOutputStream outStream = response.getOutputStream();
|
||||
sendFile(zipEntry.getSize(), zipInputStream, outStream);
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
return;
|
||||
}
|
||||
|
||||
zipEntry = zipInputStream.getNextEntry();
|
||||
}
|
||||
}
|
||||
throw new Exception("file not found " +
|
||||
filesLocation + File.separator + container + " → " + file);
|
||||
}
|
||||
|
||||
private void sendFile(long fileSize,
|
||||
ZipInputStream zipInputStream,
|
||||
ServletOutputStream outStream) throws Exception {
|
||||
|
||||
int blockSize = 0x200;
|
||||
|
||||
if (fileSize < 0x200)
|
||||
blockSize = (int) fileSize;
|
||||
|
||||
byte[] block = new byte[blockSize];
|
||||
long i = 0;
|
||||
|
||||
while (true) {
|
||||
int actuallyRead = zipInputStream.read(block);
|
||||
outStream.write(block, 0, actuallyRead);
|
||||
i += actuallyRead;
|
||||
if ((i + blockSize) > fileSize) {
|
||||
blockSize = (int) (fileSize - i);
|
||||
if (blockSize == 0)
|
||||
break;
|
||||
block = new byte[blockSize];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -17,27 +17,29 @@ import ru.redrise.marinesco.data.AuthorRepository;
|
|||
import ru.redrise.marinesco.data.GenreRepository;
|
||||
import ru.redrise.marinesco.data.InpEntryRepository;
|
||||
import ru.redrise.marinesco.data.LibraryMetadataRepository;
|
||||
import ru.redrise.marinesco.settings.ApplicationSettings;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "marinesco.library")
|
||||
public class InpxScanner implements Runnable {
|
||||
|
||||
private static volatile Thread parser;
|
||||
private static volatile String lastRunErrors;
|
||||
|
||||
private String filesLocation = "";
|
||||
|
||||
private LibraryMetadata libraryMetadata;
|
||||
private LibraryMetadataRepository libraryMetadataRepository;
|
||||
private AuthorRepository authorRepository;
|
||||
private GenreRepository genreRepository;
|
||||
private InpEntryRepository inpEntryRepository;
|
||||
|
||||
public InpxScanner(AuthorRepository authorRepository,
|
||||
private String filesLocation;
|
||||
|
||||
public InpxScanner(ApplicationSettings applicationSettings,
|
||||
AuthorRepository authorRepository,
|
||||
GenreRepository genreRepository,
|
||||
InpEntryRepository inpEntryRepository,
|
||||
LibraryMetadataRepository libraryMetadataRepository) {
|
||||
this.filesLocation = applicationSettings.getFilesLocation();
|
||||
this.authorRepository = authorRepository;
|
||||
this.genreRepository = genreRepository;
|
||||
this.inpEntryRepository = inpEntryRepository;
|
||||
|
@ -47,7 +49,7 @@ public class InpxScanner implements Runnable {
|
|||
/*
|
||||
* @return true if executed, false if already running
|
||||
*/
|
||||
public boolean reScan(){
|
||||
public boolean reScan() {
|
||||
if (parser == null || !parser.isAlive()) {
|
||||
parser = new Thread(this);
|
||||
parser.start();
|
||||
|
@ -190,14 +192,6 @@ public class InpxScanner implements Runnable {
|
|||
return i + 1 < content.length && (content[i + 1] == '\r');
|
||||
}
|
||||
|
||||
public String getFilesLocation() {
|
||||
return filesLocation;
|
||||
}
|
||||
|
||||
public void setFilesLocation(String location) {
|
||||
filesLocation = location;
|
||||
}
|
||||
|
||||
public static String getLastRunErrors() {
|
||||
return lastRunErrors;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package ru.redrise.marinesco.settings;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "marinesco.library")
|
||||
public class ApplicationSettings {
|
||||
private static final String ALLOW_REGISTRATION = "allow_registration";
|
||||
|
||||
private String filesLocation = "";
|
||||
|
||||
private KeyValueRepository keyValueRepository;
|
||||
|
||||
|
@ -34,4 +38,13 @@ public class ApplicationSettings {
|
|||
public synchronized boolean isRegistrationAllowed() {
|
||||
return registrationAllowed;
|
||||
}
|
||||
|
||||
public String getFilesLocation() {
|
||||
return filesLocation;
|
||||
}
|
||||
|
||||
public void setFilesLocation(String location) {
|
||||
filesLocation = location;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<br /><span th:if="${book.addedDate} != null" th:text="${'Added : ' + book.addedDate}"></span>
|
||||
<br /><span th:text="${'Size: ' + book.fileSize + ' bytes'}"></span>
|
||||
<p>
|
||||
<a th:href="'/'" th:text="Download"></a>
|
||||
<a th:href="${'/download/?container=' + book.container + '&file=' + book.fsFileName}" th:text="Download"></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue