diff --git a/src/main/java/ru/redrise/marinesco/BookController.java b/src/main/java/ru/redrise/marinesco/BookController.java
index 63d46aa..0cca2eb 100644
--- a/src/main/java/ru/redrise/marinesco/BookController.java
+++ b/src/main/java/ru/redrise/marinesco/BookController.java
@@ -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 {
diff --git a/src/main/java/ru/redrise/marinesco/DownloadController.java b/src/main/java/ru/redrise/marinesco/DownloadController.java
new file mode 100644
index 0000000..70be12d
--- /dev/null
+++ b/src/main/java/ru/redrise/marinesco/DownloadController.java
@@ -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];
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/ru/redrise/marinesco/library/InpxScanner.java b/src/main/java/ru/redrise/marinesco/library/InpxScanner.java
index 4b715e6..f58a577 100644
--- a/src/main/java/ru/redrise/marinesco/library/InpxScanner.java
+++ b/src/main/java/ru/redrise/marinesco/library/InpxScanner.java
@@ -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;
}
diff --git a/src/main/java/ru/redrise/marinesco/settings/ApplicationSettings.java b/src/main/java/ru/redrise/marinesco/settings/ApplicationSettings.java
index b59f35c..0f3471c 100644
--- a/src/main/java/ru/redrise/marinesco/settings/ApplicationSettings.java
+++ b/src/main/java/ru/redrise/marinesco/settings/ApplicationSettings.java
@@ -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;
+ }
+
}
diff --git a/src/main/resources/templates/book.html b/src/main/resources/templates/book.html
index ed58289..54ec738 100644
--- a/src/main/resources/templates/book.html
+++ b/src/main/resources/templates/book.html
@@ -29,7 +29,7 @@