From f96713c51be0c9d1cdaa59e6d4304982d7cf44ea Mon Sep 17 00:00:00 2001
From: Kai Reinhard <K.Reinhard@micromata.de>
Date: Sun, 16 Dec 2018 23:35:46 +0000
Subject: [PATCH] ...

---
 borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java               |    8 ++--
 borgbutler-core/src/main/java/de/micromata/borgbutler/utils/DirUtils.java             |   42 +++++++++++++++++++++
 borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ArchivesRest.java |   64 +++++++++++++++++++++++++++++--
 3 files changed, 105 insertions(+), 9 deletions(-)

diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
index 773a0a9..4b7d3b8 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
@@ -138,8 +138,8 @@
         ;
     }
 
-    public static List<BorgFilesystemItem> listArchiveContent(BorgRepoConfig repoConfig, String archiveId) {
-        Context context = new Context().setRepoConfig(repoConfig).setCommand("list").setArchive(archiveId)
+    public static List<BorgFilesystemItem> listArchiveContent(BorgRepoConfig repoConfig, String archive) {
+        Context context = new Context().setRepoConfig(repoConfig).setCommand("list").setArchive(archive)
                 .setParams("--json-lines");
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         execute(outputStream, context);
@@ -157,10 +157,10 @@
         return content;
     }
 
-    public static Path extractFiles(BorgRepoConfig repoConfig, String archiveId, String path) throws IOException {
+    public static Path extractFiles(BorgRepoConfig repoConfig, String archive, String path) throws IOException {
         Path tempDirWithPrefix = Files.createTempDirectory("borbutler");
         Context context = new Context().setWorkingDir(tempDirWithPrefix.toFile()).setRepoConfig(repoConfig)
-                .setCommand("extract").setArchive(archiveId).setArgs(path);
+                .setCommand("extract").setArchive(archive).setArgs(path);
         execute(context);
         return tempDirWithPrefix;
     }
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/utils/DirUtils.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/utils/DirUtils.java
new file mode 100644
index 0000000..a8f38c6
--- /dev/null
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/utils/DirUtils.java
@@ -0,0 +1,42 @@
+package de.micromata.borgbutler.utils;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public final class DirUtils {
+    public static void zipDirectory(Path srcPath, Path outputFile) throws IOException {
+        List<Path> files = listFiles(srcPath);
+        try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(outputFile.toFile()))) {
+            for (Path path : files) {
+                ZipEntry entry = new ZipEntry(path.toString());
+                zipOutputStream.putNextEntry(entry);
+               // FileInputStream in = new FileInputStream(Paths.get(rootDir, sourceDir, file.getName()).toString());
+               // IOUtils.copy(in, out);
+               // IOUtils.closeQuietly(in);
+            }
+        }
+    }
+
+    public static List<Path> listFiles(Path path) throws IOException {
+        return listFiles(new ArrayList<>(), path);
+    }
+
+    private static List<Path> listFiles(List<Path> files, Path path) throws IOException {
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
+            for (Path entry : stream) {
+                if (Files.isDirectory(entry)) {
+                    listFiles(files, entry);
+                }
+                files.add(entry);
+            }
+        }
+        return files;
+    }
+}
\ No newline at end of file
diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ArchivesRest.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ArchivesRest.java
index 04e69dd..e275c89 100644
--- a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ArchivesRest.java
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ArchivesRest.java
@@ -1,11 +1,18 @@
 package de.micromata.borgbutler.server.rest;
 
+import de.micromata.borgbutler.BorgCommands;
 import de.micromata.borgbutler.cache.ButlerCache;
+import de.micromata.borgbutler.config.BorgRepoConfig;
+import de.micromata.borgbutler.config.ConfigurationHandler;
 import de.micromata.borgbutler.data.Archive;
 import de.micromata.borgbutler.data.FileSystemFilter;
 import de.micromata.borgbutler.data.Repository;
 import de.micromata.borgbutler.json.JsonUtils;
 import de.micromata.borgbutler.json.borg.BorgFilesystemItem;
+import de.micromata.borgbutler.utils.DirUtils;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -16,6 +23,8 @@
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import java.io.File;
+import java.io.IOException;
 import java.util.List;
 
 @Path("/archives")
@@ -77,14 +86,59 @@
      * {@link #getArchiveFileLIst(String, String, String, boolean, boolean)}
      */
     public Response downloadFilebyPath(@QueryParam("archiveId") String archiveId, @QueryParam("fileNumber") int fileNumber) {
-        log.info("Downloading file #" + fileNumber + " of archive '" + archiveId + "'.");
-        return null;
-/*        byte[] byteArray = result.getAsByteArrayOutputStream().toByteArray();
+        log.info("Requesting file #" + fileNumber + " of archive '" + archiveId + "'.");
+        FileSystemFilter filter = new FileSystemFilter().setFileNumber(fileNumber);
+        List<BorgFilesystemItem> items = ButlerCache.getInstance().getArchiveContent(archiveId, false,
+                filter);
+        if (CollectionUtils.isEmpty(items)) {
+            log.error("Requested file #" + fileNumber + " not found in archive '" + archiveId
+                    + ". (May-be the archive content isn't yet loaded to the cache.");
+            Response.ResponseBuilder builder = Response.status(404);
+            return builder.build();
+        }
+        if (items.size() != 1) {
+            log.error("Requested file #" + fileNumber + " found multiple times (" + items.size() + ") in archive '" + archiveId
+                    + "! Please remove the archive files (may-be corrupted).");
+            Response.ResponseBuilder builder = Response.status(404);
+            return builder.build();
+        }
+        BorgFilesystemItem item = items.get(0);
+        Archive archive = ButlerCache.getInstance().getArchive(archiveId);
+        if (archive == null) {
+            Response.ResponseBuilder builder = Response.status(404);
+            return builder.build();
+        }
+        BorgRepoConfig repoConfig = ConfigurationHandler.getConfiguration().getRepoConfig(archive.getRepoId());
+        java.nio.file.Path path = null;
+        try {
+            java.nio.file.Path directory = BorgCommands.extractFiles(repoConfig, archive.getName(), item.getPath());
+            List<java.nio.file.Path> files = DirUtils.listFiles(directory);
+            if (CollectionUtils.isEmpty(files)) {
+                log.error("No file extracted.");
+                Response.ResponseBuilder builder = Response.status(404);
+                return builder.build();
+            }
+            path = files.get(0);
+        } catch (IOException ex) {
+            log.error("No file extracted: " + ex.getMessage(), ex);
+            Response.ResponseBuilder builder = Response.status(404);
+            return builder.build();
+        }
+        // ButlerCache.getInstance().getArchiveContent()
+        File file = path.toFile();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            FileUtils.copyFile(file, baos);
+        } catch (IOException ex) {
+            log.error(ex.getMessage(), ex);
+        }
+        file = new File(item.getPath());
+        byte[] byteArray = baos.toByteArray();//result.getAsByteArrayOutputStream().toByteArray();
         Response.ResponseBuilder builder = Response.ok(byteArray);
-        builder.header("Content-Disposition", "attachment; filename=" + filename);
+        builder.header("Content-Disposition", "attachment; filename=" + file.getName());
         // Needed to get the Content-Disposition by client:
         builder.header("Access-Control-Expose-Headers", "Content-Disposition");
         Response response = builder.build();
-        return response;*/
+        return response;
     }
 }

--
Gitblit v1.10.0