Permalink
Browse files

Add support for caching pages using Redis backend

  • Loading branch information...
ibuclaw committed Jul 30, 2014
1 parent f5d0a8d commit 03607e0c834e1950fa2b9c697b2cd17e38547812
Showing with 263 additions and 47 deletions.
  1. +1 −1 dub.json
  2. +31 −35 src/gdcproject/app.d
  3. +35 −11 src/gdcproject/downloads.d
  4. +196 −0 src/gdcproject/render.d
View
@@ -4,7 +4,7 @@
"copyright": "Copyright © 2014, Iain Buclaw",
"authors": ["Iain Buclaw"],
"dependencies": {
"vibe-d": ">=0.7.19",
"vibe-d": "~master",
"mustache-d": "~master"
},
"versions": ["VibeDefaultMain"]
View
@@ -56,7 +56,7 @@
// any of the todo listed items below.
//-----------------------------------------------------------------------------
// TODO:
// - Use Redis as a memstore for caching files until they change content.
// - Add in server-side logging facilities.
// - Make all (hard coded) components configurable.
// - Add support for /news, which would be a dynamic blog-style set
// of content pages.
@@ -65,34 +65,9 @@
module gdcproject.app;
import vibe.d;
import gdcproject.downloads;
// Read and return as a string the (hard coded) header template.
// The template is assumed to be in html format.
string readHeader()
{
scope(failure) return "<html><body>";
return readContents("templates/header.inc");
}
// Read and return as a string the (hard coded) footer template.
// The template is assumed to be in html format.
string readFooter()
{
scope(failure) return "</body></hmtl>";
return readContents("templates/footer.inc");
}
// Read return as a string the contents of the file in 'path'.
string readContents(string path)
{
import std.file : read;
return cast(string) read(path);
}
import gdcproject.downloads;
import gdcproject.render;
// Handle any kind of GET request on the server.
// The paths /style, /images and /downloads are forwarded to the
@@ -102,7 +77,6 @@ string readContents(string path)
void handleRequest(HTTPServerRequest req, HTTPServerResponse res)
{
import std.array : appender;
import std.string : chomp;
scope(failure) return;
@@ -115,7 +89,7 @@ void handleRequest(HTTPServerRequest req, HTTPServerResponse res)
// Render download page from template
if (requestURL == "/downloads" || requestURL == "/downloads/index.html")
return renderDownloadPage(req, res);
return serveDownloadsPage(req, res);
if (requestURL.length >= 11 && requestURL[0..11] == "/downloads/")
return serveStaticFiles("downloads/")(req, res);
@@ -128,13 +102,10 @@ void handleRequest(HTTPServerRequest req, HTTPServerResponse res)
requestPath = "views" ~ requestURL ~ ".md";
// Build up the content.
auto content = appender!string();
content ~= readHeader();
content ~= filterMarkdown(readContents(requestPath));
content ~= readFooter();
string content = renderPage(requestPath, &readContents);
// Send the page data to the client.
res.writeBody(content.data, "text/html; charset=UTF-8");
res.writeBody(content, "text/html; charset=UTF-8");
}
// Handle an error on the server.
@@ -156,15 +127,40 @@ void handleError(HTTPServerRequest req, HTTPServerResponse res, HTTPServerErrorI
res.writeBody(content.data, "text/html; charset=UTF-8");
}
shared static this()
{
import core.thread : Thread;
// Set (hard coded) server settings.
auto settings = new HTTPServerSettings;
settings.port = 8080;
settings.bindAddresses = ["::1", "127.0.0.1"];
settings.errorPageHandler = toDelegate(&handleError);
//
buildCache();
// Start the watcher task on template files.
static Thread templateWatcher = null;
if (templateWatcher is null)
{
templateWatcher = new Thread(&waitForTemplateChanges);
templateWatcher.isDaemon(true);
templateWatcher.start();
}
// Start the watcher task on individual pages.
static Thread pageWatcher = null;
if (pageWatcher is null)
{
pageWatcher = new Thread(&waitForViewChanges);
pageWatcher.isDaemon(true);
pageWatcher.start();
}
// Start listening.
// Catch all GET requests and push them through our main handler.
listenHTTP(settings, toDelegate(&handleRequest));
}
View
@@ -1,7 +1,28 @@
module gdcproject.downloads;
// Copyright (C) 2014 Iain Buclaw
// Written by Johannes Pfau
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3.0 of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, see
// <http://www.gnu.org/licenses/lgpl-3.0.txt>.
// The gdcproject website powered by vibe.d
// This file serves the downloads page.
module gdcproject.downloads;
import vibe.d;
import gdcproject.app;
import gdcproject.render;
struct Download
{
@@ -21,17 +42,16 @@ struct Host
DownloadSet[] sets;
}
void renderDownloadPage(HTTPServerRequest req, HTTPServerResponse res)
string renderDownloadsPage(string path)
{
import mustache;
scope(failure) return;
alias MustacheEngine!(string) Mustache;
Mustache engine;
auto context = new Mustache.Context();
Host[] hosts;
auto jsonData = readContents("views/downloads.json");
auto jsonData = readContents(path ~ ".json");
deserializeJson(hosts, parseJson(jsonData));
foreach(host; hosts)
@@ -67,13 +87,17 @@ void renderDownloadPage(HTTPServerRequest req, HTTPServerResponse res)
}
engine.level = Mustache.CacheLevel.no;
string mdbody = engine.render("views/downloads", context);
return engine.render(path, context);
}
void serveDownloadsPage(HTTPServerRequest req, HTTPServerResponse res)
{
scope(failure) return;
auto content = appender!string();
content ~= readHeader();
content ~= filterMarkdown(mdbody);
content ~= readFooter();
// Build up the content.
string content = renderPage("views/downloads", &renderDownloadsPage);
// Send the page data to the client.
res.writeBody(content.data, "text/html; charset=UTF-8");
res.writeBody(content, "text/html; charset=UTF-8");
}
Oops, something went wrong.

0 comments on commit 03607e0

Please sign in to comment.