diff --git a/src/main/java/me/mrletsplay/mdblog/MdBlog.java b/src/main/java/me/mrletsplay/mdblog/MdBlog.java index e681776..cf12fa6 100644 --- a/src/main/java/me/mrletsplay/mdblog/MdBlog.java +++ b/src/main/java/me/mrletsplay/mdblog/MdBlog.java @@ -6,15 +6,21 @@ import java.nio.file.StandardWatchEventKinds; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import me.mrletsplay.mdblog.blog.Post; +import me.mrletsplay.simplehttpserver.dom.html.HtmlDocument; +import me.mrletsplay.simplehttpserver.dom.html.HtmlElement; import me.mrletsplay.simplehttpserver.http.HttpRequestMethod; +import me.mrletsplay.simplehttpserver.http.HttpStatusCodes; import me.mrletsplay.simplehttpserver.http.document.FileDocument; import me.mrletsplay.simplehttpserver.http.request.HttpRequestContext; +import me.mrletsplay.simplehttpserver.http.response.TextResponse; import me.mrletsplay.simplehttpserver.http.server.HttpServer; public class MdBlog { @@ -34,6 +40,10 @@ public class MdBlog { .port(3706) .create()); + server.getDocumentProvider().registerPattern(HttpRequestMethod.GET, "/posts", () -> { + createPostsIndex(POSTS_PATH); + }); + server.getDocumentProvider().registerPattern(HttpRequestMethod.GET, "/posts/{path...}", () -> { HttpRequestContext ctx = HttpRequestContext.getCurrentContext(); String path = ctx.getPathParameters().get("path"); @@ -44,13 +54,19 @@ public class MdBlog { } Path resolved = POSTS_PATH.resolve(path).normalize(); - if(!resolved.startsWith(POSTS_PATH) || resolved.getFileName().toString().endsWith(".md")) { + if(!resolved.startsWith(POSTS_PATH)) { server.getDocumentProvider().getNotFoundDocument().createContent(); return; } if(!Files.isRegularFile(resolved)) { - server.getDocumentProvider().getNotFoundDocument().createContent(); + if(!Files.isDirectory(resolved)) { + server.getDocumentProvider().getNotFoundDocument().createContent(); + return; + } + + createPostsIndex(resolved); + return; } @@ -62,6 +78,7 @@ public class MdBlog { }); extractAndRegister("style/base.css"); + extractAndRegister("style/index.css"); extractAndRegister("style/post.css"); server.start(); @@ -92,6 +109,41 @@ public class MdBlog { } } + private static void createPostsIndex(Path directory) { + try { + // Generate posts index + List inDir = Files.list(directory) + .filter(p -> Files.isDirectory(p) || posts.values().stream().anyMatch(post -> post.getFilePath().equals(p))) + .collect(Collectors.toList()); + Collections.sort(inDir); + + HtmlDocument index = new HtmlDocument(); + index.setTitle("Index of " + directory.getFileName()); + index.addStyleSheet("/style/index.css"); + + HtmlElement ul = new HtmlElement("ul"); + for(Path p : inDir) { + HtmlElement li = new HtmlElement("li"); + HtmlElement a = new HtmlElement("a"); + String relPath = directory.relativize(p).toString(); + if(Files.isRegularFile(p)) relPath = relPath.substring(0, relPath.length() - Post.FILE_EXTENSION.length()); + // TODO: only works with trailing / + a.setAttribute("href", relPath); + a.setText(relPath); + li.appendChild(a); + ul.appendChild(li); + } + + index.getBodyNode().appendChild(ul); + + index.createContent(); + }catch(IOException e) { + e.printStackTrace(); + HttpRequestContext ctx = HttpRequestContext.getCurrentContext(); + ctx.respond(HttpStatusCodes.INTERNAL_SERVER_ERROR_500, new TextResponse("Failed to create index")); + } + } + private static void extractAndRegister(String path) throws IOException { Path filePath = FILES_PATH.resolve(path); if(!Files.exists(filePath)) { @@ -111,12 +163,12 @@ public class MdBlog { Files.walk(POSTS_PATH) .filter(Files::isRegularFile) - .filter(f -> f.getFileName().toString().endsWith(".md")) + .filter(f -> f.getFileName().toString().endsWith(Post.FILE_EXTENSION)) .filter(f -> posts.values().stream().noneMatch(p -> p.getFilePath().equals(f))) .forEach(f -> { try { String path = POSTS_PATH.relativize(f).toString(); - path = path.substring(0, path.length() - ".md".length()); + path = path.substring(0, path.length() - Post.FILE_EXTENSION.length()); posts.put(path, new Post(f)); } catch (IOException e) {} }); diff --git a/src/main/java/me/mrletsplay/mdblog/blog/Post.java b/src/main/java/me/mrletsplay/mdblog/blog/Post.java index 1059cac..479e121 100644 --- a/src/main/java/me/mrletsplay/mdblog/blog/Post.java +++ b/src/main/java/me/mrletsplay/mdblog/blog/Post.java @@ -13,6 +13,8 @@ import me.mrletsplay.simplehttpserver.dom.html.HtmlDocument; public class Post { + public static final String FILE_EXTENSION = ".md"; + private static final MessageDigest MD_5; private static final MdRenderer RENDERER = new MdRenderer(); @@ -39,6 +41,11 @@ public class Post { return filePath; } + public String getName() { + String fileName = filePath.getFileName().toString(); + return fileName.substring(0, fileName.length() - FILE_EXTENSION.length()); + } + public PostMetadata getMetadata() { return metadata; } diff --git a/src/main/resources/style/index.css b/src/main/resources/style/index.css new file mode 100644 index 0000000..c61c55d --- /dev/null +++ b/src/main/resources/style/index.css @@ -0,0 +1,7 @@ +ul { + +} + +li { + +} \ No newline at end of file