diff --git a/pom.xml b/pom.xml
index 0d00270..4ff01c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,11 +41,23 @@
2.9
- commons-io
+ commons-io
commons-io
2.18.0
+
+ org.apache.commons
+ commons-compress
+ 1.27.1
+
+
+ com.github.luben
+ zstd-jni
+ 1.5.6-10
+
+
+
org.slf4j
slf4j-api
diff --git a/src/main/java/eu/m724/blog/BlogBuilder.java b/src/main/java/eu/m724/blog/BlogBuilder.java
index 74510d8..143a4e3 100644
--- a/src/main/java/eu/m724/blog/BlogBuilder.java
+++ b/src/main/java/eu/m724/blog/BlogBuilder.java
@@ -1,9 +1,12 @@
package eu.m724.blog;
+import eu.m724.blog.compress.FileCompressor;
import eu.m724.blog.data.Feed;
import eu.m724.blog.data.Post;
import eu.m724.blog.data.Site;
import eu.m724.blog.template.TemplateRenderer;
+import org.apache.commons.compress.compressors.CompressorException;
+import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.commons.io.file.PathUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.RepositoryBuilder;
@@ -14,6 +17,8 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -115,17 +120,35 @@ public class BlogBuilder {
* @throws IOException if an I/O error occurs
*/
public void build() throws IOException {
+ System.out.println("Loading site...");
if (site == null)
this.site = Site.fromConfig(workingDirectory.resolve("site-config.yml"));
if (template == null)
this.template = new TemplateRenderer(templateDirectory);
- copyIfExists(workingDirectory.resolve("assets"), outputDirectory.resolve("assets"));
- copyIfExists(templateDirectory.resolve("static"), outputDirectory.resolve("static"));
+ System.out.println("Copying assets...");
+ copyTree(workingDirectory.resolve("assets"), outputDirectory.resolve("assets"));
+ copyTree(templateDirectory.resolve("static"), outputDirectory.resolve("static"));
+ System.out.println("Rendering posts...");
+ var posts = renderPosts();
+
+ System.out.println("Rendering meta...");
+ posts.sort(Comparator.comparing(Post::createdAt).reversed());
+ Files.writeString(outputDirectory.resolve("index.html"), template.renderIndex(site, posts));
+
+ Files.writeString(outputDirectory.resolve("posts.rss"), Feed.generateRss(site, posts));
+
+
+ System.out.println("Compressing...");
+ compressOutput();
+ }
+
+ private List renderPosts() throws IOException {
Files.createDirectory(outputDirectory.resolve("post"));
var postDirectory = workingDirectory.resolve("posts");
+
var posts = new ArrayList();
try (var stream = Files.walk(postDirectory)) {
@@ -158,20 +181,35 @@ public class BlogBuilder {
}
}
- posts.sort(Comparator.comparing(Post::createdAt).reversed());
- Files.writeString(outputDirectory.resolve("index.html"), template.renderIndex(site, posts));
+ return posts;
+ }
- Files.writeString(outputDirectory.resolve("posts.rss"), Feed.generateRss(site, posts));
+ private void compressOutput() throws IOException {
+ var compressors = new FileCompressor[] {
+ new FileCompressor(CompressorStreamFactory.GZIP),
+ new FileCompressor(CompressorStreamFactory.ZSTANDARD)
+ };
+
+ Set tree;
+ try (var walk = Files.walk(outputDirectory)) {
+ tree = walk.filter(Files::isRegularFile).collect(Collectors.toSet());
+ }
+
+ for (var compressor : compressors) {
+ for (var path : tree) {
+ try {
+ compressor.compress(path);
+ } catch (CompressorException e) {
+ System.err.printf("Exception compressing %s to %s: %s%n", path, compressor.getAlgorithm(), e.getMessage());
+ }
+ }
+ }
}
/* Internal functions */
- private boolean copyTree(Path srcDir, Path destDir) throws IOException {
- if (!Files.isDirectory(srcDir)) {
- return false;
- }
-
+ private void copyTree(Path srcDir, Path destDir) throws IOException {
try (var walk = Files.walk(srcDir)) {
for (var src : walk.collect(Collectors.toSet())) {
var rel = srcDir.relativize(src);
@@ -188,17 +226,5 @@ public class BlogBuilder {
}
}
}
-
- return true;
- }
-
- private void copyIfExists(Path srcDir, Path destDir) throws IOException {
- System.out.print(srcDir);
-
- if (copyTree(srcDir, destDir)) {
- System.out.println(" copied");
- } else {
- System.out.println(" doesn't exist, not copying");
- }
}
}
diff --git a/src/main/java/eu/m724/blog/Main.java b/src/main/java/eu/m724/blog/Main.java
index a5b1ed1..6ae747d 100644
--- a/src/main/java/eu/m724/blog/Main.java
+++ b/src/main/java/eu/m724/blog/Main.java
@@ -36,7 +36,10 @@ public class Main {
.renderDrafts(renderDrafts);
builder.mkdirs(force);
+
+ System.out.println("---- START BUILD ----");
builder.build();
+ System.out.println("----- END BUILD -----");
var end = System.nanoTime();
System.out.printf("Exported to %s (%.2f ms)\n", outputDirectory, (end - start) / 1000000.0);
diff --git a/src/main/java/eu/m724/blog/compress/FileCompressor.java b/src/main/java/eu/m724/blog/compress/FileCompressor.java
new file mode 100644
index 0000000..3b1ec3c
--- /dev/null
+++ b/src/main/java/eu/m724/blog/compress/FileCompressor.java
@@ -0,0 +1,36 @@
+package eu.m724.blog.compress;
+
+import org.apache.commons.compress.compressors.CompressorException;
+import org.apache.commons.compress.compressors.CompressorStreamFactory;
+
+import java.io.IOException;
+import java.nio.file.*;
+
+public class FileCompressor {
+ private final String algorithm;
+
+ public FileCompressor(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ public void compress(Path source) throws IOException, CompressorException {
+ var destination = source.resolveSibling(source.getFileName() + "." + algorithm);
+ compress(source, destination);
+ }
+
+ public void compress(Path source, Path destination) throws IOException, CompressorException {
+ if (Files.exists(destination))
+ throw new FileAlreadyExistsException(destination.toString());
+
+ try (
+ var outputStream = new CompressorStreamFactory()
+ .createCompressorOutputStream(algorithm, Files.newOutputStream(destination))
+ ) {
+ Files.copy(source, outputStream);
+ }
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+}
diff --git a/src/main/java/eu/m724/blog/template/TemplateRenderer.java b/src/main/java/eu/m724/blog/template/TemplateRenderer.java
index ce52b8c..cf9fe15 100644
--- a/src/main/java/eu/m724/blog/template/TemplateRenderer.java
+++ b/src/main/java/eu/m724/blog/template/TemplateRenderer.java
@@ -9,7 +9,7 @@ import io.pebbletemplates.pebble.template.PebbleTemplate;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Path;
-import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
/**
@@ -46,7 +46,7 @@ public class TemplateRenderer {
* @return the rendered index HTML page as a string
* @throws IOException if an error occurs during the template evaluation
*/
- public String renderIndex(Site site, ArrayList posts) throws IOException {
+ public String renderIndex(Site site, List posts) throws IOException {
Map context = Map.of(
"site", site,
"articles", posts