z-nomp/libs/website.js

206 lines
6.1 KiB
JavaScript
Raw Normal View History

/* TODO
2014-03-12 23:37:27 -07:00
Need to condense the entire website into a single html page. Embedding the javascript and css is easy. For images,
hopefully we can only use svg which can be embedded - otherwise we can convert the image into a data-url that can
be embedded, Favicon can also be a data-url which some javascript kungfu can display in browser. I'm focusing on
this mainly to help mitigate ddos and other kinds of attacks - and to just have a badass blazing fast project.
2014-03-12 23:37:27 -07:00
Don't worry about doing any of that condensing yourself - go head and keep all the resources as separate files.
I will write a script for when the server starts to read all the files in the /website folder and minify and condense
it all together into one file, saved in memory. We will have 1 persistent condensed file that servers as our "template"
file that contains things like:
<div>Hashrate: {{=stats.hashrate}</div>
2014-03-12 23:37:27 -07:00
And then on some caching interval (maybe 5 seconds?) we will apply the template engine to generate the real html page
that we serve and hold in in memory - this is the file we serve to seo-bots (googlebot) and users when they first load
the page.
Once the user loads the page we will have server-side event source connected to the portal api where it receives
updated stats on some interval (probably 5 seconds like template cache updater) and applies the changes to the already
displayed page.
We will use fs.watch to detect changes to anything in the /website folder and update our stuff in memory.
*/
2014-03-14 00:18:51 -07:00
var fs = require('fs');
var path = require('path');
2014-03-12 23:37:27 -07:00
2014-03-14 00:18:51 -07:00
var async = require('async');
2014-03-12 23:37:27 -07:00
var dot = require('dot');
var express = require('express');
2014-03-19 13:24:29 -07:00
var stats = require('./stats.js');
2014-03-12 23:37:27 -07:00
2014-03-13 14:03:28 -07:00
2014-03-12 23:37:27 -07:00
module.exports = function(logger){
var portalConfig = JSON.parse(process.env.portalConfig);
var poolConfigs = JSON.parse(process.env.pools);
2014-03-18 23:54:18 -07:00
var websiteConfig = portalConfig.website;
2014-03-14 00:18:51 -07:00
2014-03-19 13:24:29 -07:00
var portalStats = new stats(logger, portalConfig, poolConfigs);
2014-03-14 00:18:51 -07:00
2014-03-12 23:37:27 -07:00
var logIdentify = 'Website';
var websiteLogger = {
debug: function(key, text){
logger.logDebug(logIdentify, key, text);
},
warning: function(key, text){
logger.logWarning(logIdentify, key, text);
},
error: function(key, text){
logger.logError(logIdentify, key, text);
}
};
2014-03-18 23:54:18 -07:00
var pageFiles = {
'index.html': 'index',
'home.html': '',
'getting_started.html': 'getting_started',
'stats.html': 'stats',
'api.html': 'api'
2014-03-14 00:18:51 -07:00
};
2014-03-18 23:54:18 -07:00
var pageTemplates = {};
var pageProcessed = {};
2014-03-14 00:18:51 -07:00
2014-03-18 23:54:18 -07:00
var processTemplates = function(){
for (var pageName in pageTemplates){
pageProcessed[pageName] = pageTemplates[pageName]({
poolsConfigs: poolConfigs,
2014-03-19 13:24:29 -07:00
stats: portalStats.stats,
2014-03-19 00:26:20 -07:00
portalConfig: portalConfig
2014-03-18 23:54:18 -07:00
});
}
};
2014-03-14 00:18:51 -07:00
2014-03-18 23:54:18 -07:00
var readPageFiles = function(){
async.each(Object.keys(pageFiles), function(fileName, callback){
fs.readFile('website/' + fileName, 'utf8', function(err, data){
var pTemp = dot.template(data);
pageTemplates[pageFiles[fileName]] = pTemp
callback();
});
}, function(err){
if (err){
console.log('error reading files for creating dot templates: '+ JSON.stringify(err));
return;
}
processTemplates();
2014-03-14 00:18:51 -07:00
});
};
2014-03-18 23:54:18 -07:00
fs.watch('website', function(event, filename){
if (event === 'change' && filename in pageFiles)
readPageFiles();
});
2014-03-19 13:24:29 -07:00
portalStats.getStats(function(){
2014-03-18 23:54:18 -07:00
readPageFiles(Object.keys(pageFiles));
2014-03-14 00:18:51 -07:00
});
2014-03-18 23:54:18 -07:00
var buildUpdatedWebsite = function(){
2014-03-19 13:24:29 -07:00
portalStats.getStats(function(){
2014-03-18 23:54:18 -07:00
processTemplates();
2014-03-19 13:24:29 -07:00
var statData = 'data: ' + JSON.stringify(portalStats.stats) + '\n\n';
for (var uid in liveStatConnections){
var res = liveStatConnections[uid];
res.write(statData);
}
2014-03-18 23:54:18 -07:00
});
};
setInterval(buildUpdatedWebsite, websiteConfig.statUpdateInterval * 1000);
2014-03-14 00:18:51 -07:00
2014-03-12 23:37:27 -07:00
var app = express();
2014-03-18 23:54:18 -07:00
var getPage = function(pageId){
if (pageId in pageProcessed){
var requestedPage = pageProcessed[pageId];
return requestedPage;
}
};
var route = function(req, res, next){
var pageId = req.params.page || '';
var requestedPage = getPage(pageId);
if (requestedPage){
var data = pageTemplates.index({
page: requestedPage,
selected: pageId,
2014-03-19 13:24:29 -07:00
stats: portalStats.stats,
2014-03-19 00:26:20 -07:00
poolConfigs: poolConfigs,
portalConfig: portalConfig
2014-03-18 23:54:18 -07:00
});
2014-03-19 13:24:29 -07:00
res.end(data);
2014-03-18 23:54:18 -07:00
}
else
next();
2014-03-14 00:18:51 -07:00
2014-03-18 23:54:18 -07:00
};
2014-03-14 00:18:51 -07:00
2014-03-19 13:24:29 -07:00
var liveStatConnections = {};
2014-03-18 23:54:18 -07:00
app.get('/:page', route);
app.get('/', route);
2014-03-14 00:18:51 -07:00
2014-03-18 23:54:18 -07:00
app.get('/api/:method', function(req, res, next){
2014-03-14 00:18:51 -07:00
2014-03-18 23:54:18 -07:00
switch(req.params.method){
case 'get_page':
var requestedPage = getPage(req.query.id);
if (requestedPage){
2014-03-19 13:24:29 -07:00
res.end(requestedPage);
2014-03-18 23:54:18 -07:00
return;
}
2014-03-19 13:24:29 -07:00
case 'live_stats':
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
res.write('\n');
var uid = Math.random().toString();
liveStatConnections[uid] = res;
req.on("close", function() {
delete liveStatConnections[uid];
});
return;
2014-03-18 23:54:18 -07:00
default:
next();
}
2014-03-19 13:24:29 -07:00
//res.send('you did api method ' + req.params.method);
2014-03-12 23:37:27 -07:00
});
2014-03-18 23:54:18 -07:00
app.use('/static', express.static('website'));
2014-03-12 23:37:27 -07:00
app.use(function(err, req, res, next){
console.error(err.stack);
2014-03-19 13:24:29 -07:00
res.end(500, 'Something broke!');
2014-03-12 23:37:27 -07:00
});
app.listen(portalConfig.website.port, function(){
websiteLogger.debug('system', 'Website started on port ' + portalConfig.website.port);
});
};