Barton's Picturelinux counter image.

How It Works Page


The application is written for 'node.js' using 'express.js' and some other modules. Express is a framework used to create a server and router. The 'express' directory hierarchy looks like this:

In the project root is the 'app.js' file which looks like this:

// BLP 2017-03-07 -- This is a nodjs experment. It creates the
// www.bartonlp.org:7000 webpage.

const express = require('express');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const favicon = require('serve-favicon');
const count = require('./routes/utilfunctions.js').count;

// get the two routing units

const routes = require('./routes/index');
const applitec = require('./routes/applitec');

const app = express();

// view engine setup

// NOTE we are using 'views.old' which is the 'jade' implementation not
// 'view' which uses 'pug'!!

app.set('views', path.join(__dirname, 'views.old'));
app.set('view engine', 'jade');

//app.use(logger('combined')); // Logs info to the console.log in 'development' mode

app.use(logger('[:date[clf]] :remote-addr :remote-user :method :url :status :res[content-length] ":user-agent"'));

// Catch all

app.use(function(req, res, next) {
  if(req.hostname != 'www.bartonlp.org') {
    console.log("headers.host: ", req.headers.host);
    console.log("Hostname: ", req.hostname);
    console.log("Org Url: %s, Url: %s", req.originalUrl, req.url);
    console.log("ERROR: Return");
    next(new Error('Bad Route'));
  }
  next();
});

/* Catch all. This goes before any router methods. This does the
 * counter and bots logic.
 */

app.use(function(req, res, next) {
  // Get the originalUrl and grab what is after the first / which will
  // be the name of the site jade file.

  count(req, function(err, cnt) {
    if(err) {
      next(err);
      return;
    }

    // Put the count into the req property as cnt.

    req.cnt = cnt;
    next();
  });
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

// Now override this with the 'routes' to .../routes/index.js

app.use('/', routes);
app.use('/applitec', applitec);
// Set the document root to 'public'

app.use(express.static(path.join(__dirname, 'public')));
app.use(favicon(path.join(__dirname, 'public', 'favicon.png'))); // favicon.png is a sprocket icon.

// catch 404 and forward to error handler

app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace

//app.set('env', '');

if(app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    if(err.status != 404) {
      req.url = null;
    }

    res.render('error', {
      message: err.message,
      url: req.url,
      status: err.status,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user

app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  if(err.status != 404) {
    req.url = null;
  }
  console.log("MSG: %s", err.message);
  console.log("URL: %s", req.url);
  console.log("ERROR: ", err);
  
  res.render('error', {
    message: err.message,
    url: req.url,
    status: err.status,
    error: {}
  });
});

module.exports = app;

We load ./routes/index.js' and then we app.use('/', routes).

In the 'routes' directory the file 'index.js' does the routing for the application.

/* index.js */

const express = require('express');
const router = express.Router();
const fs = require('fs');
const dns = require('dns');
const request = require('request');

const utilfunctions = require("./utilfunctions.js");
const query = utilfunctions.query;
const count = utilfunctions.count;
const mtime = utilfunctions.mtime;
const run = utilfunctions.run;
const robots = utilfunctions.robots;

var args = {
  copyright: "2017 Barton Phillips",
  author: "Barton Phillips http://www.bartonphillips.com",
  desc: "node.js example",
  msg: "Counter Reset: Feb. 4, 2017",
  site: "Node",
};

/* GET home page. */

router.get(['/','/index(\.(html|php))?'], function(req, res, next) {
  const port = req.headers.host.match(/:(.*)/)[1];
  args.footer = req.cnt;

  return run(function *(resume) {
    var address = yield   dns.lookup('bartonphillips.dyndns.org', resume);
    console.log("ADDRESS:", address);
    
    if(address == '23.242.170.142') {
      var admin = yield request.get('http://www.bartonlp.com/adminsites.txt', resume);
      args.adminStuff = admin.body;
      console.log("adminStuff: ", args.adminStuff);
    }
  
    var sql = "select filename, site, ip, agent, count, concat(date(lasttime), ' ', time(lasttime)) as lasttime "+
              "from barton.counter where lasttime>current_date() order by lasttime desc";

    query(sql, function(err, result) {
      if(err) {
        //console.log("query: ", err);
        next(err); //new Error('Error: '+err));
        return;
      };

      args.title = 'Node.js';
      args.banner = "Node.js Page";
      args.port = port;
      args.mtime = mtime("index");

      res.render('index', {
        result: result,
        args: args,
      });
    });
  });
});
    
/* GET howitworks */

router.get('/howitworks', function(req, res, next) {
  args.footer = req.cnt;
  return run(function *(resume) {
    try {
      var app = yield fs.readFile("app.js", resume);
      var index = yield fs.readFile("routes/index.js", resume);
    } catch(err) {
      return next(err); //new Error("Error: "+err));
    }
    args.title = 'How It Works';
    args.banner = 'How It Works Page';
    args.mtime = mtime("howitworks");

    res.render('howitworks', {
      args: args,
      code1: app,
      code2: index,
    });
  });
});

/* GET query */

router.get('/query', function(req, res, next) {
  args.footer = req.cnt;
  args.title = 'Query';
  args.banner = 'Query Page';
  args.mtime = mtime("query");
    
  res.render('query', {
    args: args,
    sql: ''
  });
});

/* POST query
 * params: database
 * params: sql
*/

router.post('/query', function(req, res, next) {
  args.footer = req.cnt;
  var sql = req.body.sql;
  
  query(sql, function(err, result) {
    if(err) {
      //console.log("p query: ", err);
      return next(err); //new Error(err));
    }

    console.log("RESULT: ", result);
    
    var type;

    if(Array.isArray(result)) {
      type = "Array";
    } else {
      type = "Object";
    }

    args.title = 'Query';
    args.banner = 'Query Page';
    args.mtime = mtime("query");

    res.render('query', {
      type: type,
      sql: sql,
      result: result,
      args: args
    });
  });
});

// Robots.txt

router.get("/robots.txt", function(req, res, next) {
  console.log("Robots Node");
  robots(args.site, req, function(err, robottxt) {
    res.send("<pre>" + robottxt + "</pre>");
    res.end();
  });
});

// About website

router.get('/aboutwebsite', function(req, res, next) {
  args.mtime = mtime("aboutwebsite");
  args.footer = req.cnt;

  res.render('aboutwebsite', {
    args: args,
  });
});

// Markdown

router.get('/markdown', function(req, res, next) {
  args.mtime = mtime('markdown');
  args.footer = req.cnt;

  res.render("markdown", {
    args: args,
  });
});

module.exports = router;