var http = require("http"); | var http = require("http"); | ||||
var https = require("https"); | var https = require("https"); | ||||
var fs = require("fs"); | var fs = require("fs"); | ||||
var loader = require("./lib/loader.js"); | |||||
var Context = require("./lib/context.js"); | var Context = require("./lib/context.js"); | ||||
var Db = require("./lib/db.js"); | var Db = require("./lib/db.js"); | ||||
"/viewer/style.css": "viewer/style.css" | "/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 to run on each request | ||||
function onRequest(req, res) { | function onRequest(req, res) { | ||||
console.log("Request for "+req.url); | 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 the file doesn't exist, we 404. | ||||
if (!ep) { | if (!ep) { | ||||
ep = endpoints["/404"]; | |||||
ep = loaded.endpoints["/404"]; | |||||
res.writeHead(404); | res.writeHead(404); | ||||
} | } | ||||
ep(new Context({ | ep(new Context({ | ||||
req: req, | req: req, | ||||
res: res, | res: res, | ||||
templates: templates, | |||||
views: views, | |||||
templates: loaded.templates, | |||||
views: loaded.views, | |||||
conf: conf | conf: conf | ||||
})); | })); | ||||
} else { | } else { |
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; | |||||
} |
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; | |||||
} |
var minify = require("html-minifier").minify; | |||||
exports.html = function(src) { | |||||
return src; | |||||
return minify(src, { | |||||
removeComments: true, | |||||
collapseWhitespace: true, | |||||
}); | |||||
} |
}, | }, | ||||
"license": "GPLv2", | "license": "GPLv2", | ||||
"dependencies": { | "dependencies": { | ||||
"html-minifier": "^0.7.2", | |||||
"pg": "^4.4.0" | "pg": "^4.4.0" | ||||
} | } | ||||
} | } |
<div class="navbar navbar-default navbar-fixed-top"> | |||||
<div class="navbar navbar-default"> | |||||
<div class="navbar-inner"> | <div class="navbar-inner"> | ||||
<div class="container-fluid"> | <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"> | <ul class="nav navbar-nav navbar-right"> | ||||
{{profile}} | {{profile}} | ||||
</ul> | </ul> |
<title>{{conf#title}}</title> | |||||
<meta charset="utf-8"> | <meta charset="utf-8"> | ||||
<meta name="viewport" content="width=device-width"> | <meta name="viewport" content="width=device-width"> | ||||
<link rel="stylesheet" href="/global.css"> | <link rel="stylesheet" href="/global.css"> |
<div class="submit-container"> | <div class="submit-container"> | ||||
<button type="submit" class="btn btn-default">Log In</button> | <button type="submit" class="btn btn-default">Log In</button> | ||||
</div> | </div> | ||||
</form> | |||||
</li></ul> | </li></ul> | ||||
</li> | </li> |
<html> | <html> | ||||
<head> | <head> | ||||
{{head}} | {{head}} | ||||
<link rel="stylesheet" href="/index/style.css"> | |||||
</head> | </head> | ||||
<body> | <body> | ||||
{{global}} | {{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> | <script src="/index/script.js"></script> | ||||
</body> | </body> | ||||
</html> | </html> |
<html> | <html> | ||||
<head> | <head> | ||||
{{head}} | {{head}} | ||||
<link rel="stylesheet" href="/viewer/style.css"> | |||||
</head> | </head> | ||||
<body> | <body> | ||||
{{global}} | {{global}} | ||||
<script src="/viewer/script.js"></script> | |||||
</body> | </body> | ||||
</html> | </html> |
.hidden { | |||||
display: none; | |||||
} | |||||
.navbar .navbar-nav { | .navbar .navbar-nav { | ||||
margin-bottom: 0px; | margin-bottom: 0px; | ||||
} | } |
$(document).ready(function() { | |||||
(function() { | |||||
window.util = {}; | window.util = {}; | ||||
util.notify = function notify(title, body) { | util.notify = function notify(title, body) { | ||||
elem.removeClass("active"); | elem.removeClass("active"); | ||||
}, 5000); | }, 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, """); | |||||
} | |||||
})(); |
(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); | |||||
}); | |||||
})(); |
#uploader-list .file { | |||||
text-align: right !important; | |||||
} | |||||
#uploader-list .file .name { | |||||
float: left; | |||||
margin-top: 6px; | |||||
} | |||||
#uploader-upload { | |||||
float: right; | |||||
} |