@@ -1,6 +1,7 @@ | |||
var http = require("http"); | |||
var https = require("https"); | |||
var fs = require("fs"); | |||
var loader = require("./lib/loader.js"); | |||
var Context = require("./lib/context.js"); | |||
var Db = require("./lib/db.js"); | |||
@@ -25,56 +26,17 @@ var endpoints = { | |||
"/viewer/style.css": "viewer/style.css" | |||
} | |||
//Prepare endpoints | |||
var errs = false; | |||
Object.keys(endpoints).forEach(function(i) { | |||
try { | |||
//The endpoint is a function if the file ends with .node.js | |||
if (/\.node\.js$/.test(endpoints[i])) { | |||
endpoints[i] = require("./"+conf.webroot+"/"+endpoints[i]); | |||
//If it doesn't end with .node.js, it's a regular text file and will | |||
//just be served as is | |||
} else { | |||
endpoints[i] = fs.readFileSync(conf.webroot+"/"+endpoints[i]); | |||
} | |||
//Errors will usually be because an endpoint doesn't exist | |||
} catch (err) { | |||
if (err.code == "ENOENT") { | |||
console.log(err.toString()); | |||
errs = true; | |||
} else { | |||
throw err; | |||
} | |||
} | |||
}); | |||
//No need to proceed if some endpoints don't exist | |||
if (errs) process.exit(); | |||
//Prepare all templates | |||
var templates = {}; | |||
fs.readdirSync("templates").forEach(function(f) { | |||
templates[f.replace(/\.html$/, "")] = fs.readFileSync("templates/"+f, "utf8"); | |||
}); | |||
//Prepare all views | |||
var views = {}; | |||
fs.readdirSync("views").forEach(function(f) { | |||
views[f.replace(/\.html$/, "")] = fs.readFileSync("views/"+f, "utf8"); | |||
}); | |||
var loaded = loader.load(endpoints, conf); | |||
//Function to run on each request | |||
function onRequest(req, res) { | |||
console.log("Request for "+req.url); | |||
var ep = endpoints[req.url]; | |||
var ep = loaded.endpoints[req.url]; | |||
//If the file doesn't exist, we 404. | |||
if (!ep) { | |||
ep = endpoints["/404"]; | |||
ep = loaded.endpoints["/404"]; | |||
res.writeHead(404); | |||
} | |||
@@ -83,8 +45,8 @@ function onRequest(req, res) { | |||
ep(new Context({ | |||
req: req, | |||
res: res, | |||
templates: templates, | |||
views: views, | |||
templates: loaded.templates, | |||
views: loaded.views, | |||
conf: conf | |||
})); | |||
} else { |
@@ -0,0 +1,14 @@ | |||
var fs = require("fs"); | |||
var minify = require("./minify"); | |||
module.exports = function(path, conf) { | |||
var html = fs.readFileSync(path, "utf8"); | |||
for (var i in conf) { | |||
html = html.split("{{conf#"+i+"}}").join(conf[i]); | |||
} | |||
html = minify.html(html); | |||
return html; | |||
} |
@@ -0,0 +1,62 @@ | |||
var fs = require("fs"); | |||
var minify = require("./minify.js"); | |||
var includeHtml = require("./includeHtml.js"); | |||
exports.load = function(endpoints, conf) { | |||
var res = { | |||
endpoints: {}, | |||
templates: {}, | |||
views: {} | |||
} | |||
//Prepare endpoints | |||
var errs = false; | |||
Object.keys(endpoints).forEach(function(i) { | |||
var ep = endpoints[i]; | |||
try { | |||
//The endpoint is a function if the file ends with .node.js | |||
if (/\.node\.js$/.test(ep)) { | |||
res.endpoints[i] = require("../"+conf.webroot+"/"+ep); | |||
//If it doesn't end with .node.js, it's a regular text file and will | |||
//just be served as is | |||
} else { | |||
res.endpoints[i] = fs.readFileSync(conf.webroot+"/"+ep, "utf8"); | |||
//If it's an HTML file, we minify it | |||
if (/\.html$/.test(ep)) { | |||
res.endpoints[i] = minify.html(res.endpoints[i]); | |||
} | |||
} | |||
//Errors will usually be because an endpoint doesn't exist | |||
} catch (err) { | |||
if (err.code == "ENOENT") { | |||
console.log(err.toString()); | |||
errs = true; | |||
} else { | |||
throw err; | |||
} | |||
} | |||
}); | |||
//No need to proceed if some endpoints don't exist | |||
if (errs) process.exit(); | |||
//Prepare all templates | |||
var templates = {}; | |||
fs.readdirSync("templates").forEach(function(f) { | |||
var name = f.replace(/\.html$/, ""); | |||
res.templates[name] = includeHtml("templates/"+f, conf.web); | |||
}); | |||
//Prepare all views | |||
var views = {}; | |||
fs.readdirSync("views").forEach(function(f) { | |||
var name = f.replace(/\.html$/, ""); | |||
res.views[name] = includeHtml("views/"+f, conf.web); | |||
}); | |||
return res; | |||
} |
@@ -0,0 +1,9 @@ | |||
var minify = require("html-minifier").minify; | |||
exports.html = function(src) { | |||
return src; | |||
return minify(src, { | |||
removeComments: true, | |||
collapseWhitespace: true, | |||
}); | |||
} |
@@ -14,6 +14,7 @@ | |||
}, | |||
"license": "GPLv2", | |||
"dependencies": { | |||
"html-minifier": "^0.7.2", | |||
"pg": "^4.4.0" | |||
} | |||
} |
@@ -1,7 +1,7 @@ | |||
<div class="navbar navbar-default navbar-fixed-top"> | |||
<div class="navbar navbar-default"> | |||
<div class="navbar-inner"> | |||
<div class="container-fluid"> | |||
<a class="navbar-brand" href="/">Mimg</a> | |||
<a class="navbar-brand" href="/">{{conf#title}}</a> | |||
<ul class="nav navbar-nav navbar-right"> | |||
{{profile}} | |||
</ul> |
@@ -1,3 +1,4 @@ | |||
<title>{{conf#title}}</title> | |||
<meta charset="utf-8"> | |||
<meta name="viewport" content="width=device-width"> | |||
<link rel="stylesheet" href="/global.css"> |
@@ -18,5 +18,6 @@ | |||
<div class="submit-container"> | |||
<button type="submit" class="btn btn-default">Log In</button> | |||
</div> | |||
</form> | |||
</li></ul> | |||
</li> |
@@ -2,9 +2,17 @@ | |||
<html> | |||
<head> | |||
{{head}} | |||
<link rel="stylesheet" href="/index/style.css"> | |||
</head> | |||
<body> | |||
{{global}} | |||
<div id="uploader" class="container"> | |||
<input type="file" id="uploader-input" class="hidden" multiple> | |||
<button class="btn btn-default" onclick="$('#uploader-input').click()">Select Files</button> | |||
<button class="btn btn-default" id="uploader-upload">Upload</button> | |||
<ul class="list-group" id="uploader-list"></ul> | |||
</div> | |||
<script src="/index/script.js"></script> | |||
</body> | |||
</html> |
@@ -2,8 +2,11 @@ | |||
<html> | |||
<head> | |||
{{head}} | |||
<link rel="stylesheet" href="/viewer/style.css"> | |||
</head> | |||
<body> | |||
{{global}} | |||
<script src="/viewer/script.js"></script> | |||
</body> | |||
</html> |
@@ -1,3 +1,7 @@ | |||
.hidden { | |||
display: none; | |||
} | |||
.navbar .navbar-nav { | |||
margin-bottom: 0px; | |||
} |
@@ -1,4 +1,4 @@ | |||
$(document).ready(function() { | |||
(function() { | |||
window.util = {}; | |||
util.notify = function notify(title, body) { | |||
@@ -12,13 +12,22 @@ $(document).ready(function() { | |||
elem.removeClass("active"); | |||
}, 5000); | |||
} | |||
$("#notify-box").on("mouseenter", function() { | |||
clearTimeout(util.notify.timeout); | |||
}); | |||
$(document).ready(function() { | |||
$("#notify-box").on("mouseenter", function() { | |||
clearTimeout(util.notify.timeout); | |||
}); | |||
$("#login-form").on("submit", function(evt) { | |||
evt.stopPropagation(); | |||
evt.preventDefault(); | |||
util.notify("Feature Not Implemented", "This feature is not implemented."); | |||
$("#login-form").on("submit", function(evt) { | |||
evt.stopPropagation(); | |||
evt.preventDefault(); | |||
util.notify("Feature Not Implemented", "This feature is not implemented."); | |||
}); | |||
}); | |||
}); | |||
util.htmlEntities = function(str) { | |||
return str.replace(/&/g, "&") | |||
.replace(/</g, "<") | |||
.replace(/>/g, "<") | |||
.replace(/"/g, """); | |||
} | |||
})(); |
@@ -0,0 +1,40 @@ | |||
(function() { | |||
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) { | |||
notify("Your Browser Sucks."); | |||
} | |||
function draw(files) { | |||
var output = []; | |||
files.forEach(function(f, i) { | |||
output.push( | |||
'<li class="file list-group-item" data-index='+i+'>'+ | |||
'<span class="name">'+util.htmlEntities(f.name)+'</span>'+ | |||
'<button class="btn delete" onclick="uploaderDelete(this.parentNode)">X</button>'+ | |||
'</li>' | |||
); | |||
}); | |||
$("#uploader-list").html(output.join("")); | |||
} | |||
var files = []; | |||
$("#uploader-input").on("change", function(evt) { | |||
var inputFiles = evt.target.files; | |||
for (var i = 0; i < inputFiles.length; ++i) { | |||
files.push(inputFiles[i]); | |||
} | |||
draw(files); | |||
}); | |||
window.uploaderDelete = function(elem) { | |||
var index = elem.getAttribute("data-index"); | |||
delete files[index]; | |||
draw(files); | |||
} | |||
$("#uploader-upload").on("click", function(evt) { | |||
console.log(output); | |||
}); | |||
})(); |
@@ -0,0 +1,11 @@ | |||
#uploader-list .file { | |||
text-align: right !important; | |||
} | |||
#uploader-list .file .name { | |||
float: left; | |||
margin-top: 6px; | |||
} | |||
#uploader-upload { | |||
float: right; | |||
} |