<commit_before>var express = require('express');
var app = express();
var mongoose = require('mongoose');
var listen_port = 9981;

/* database connection */
mongoose.connect('mongodb://localhost:27017/shoplist');

/* configuration */
app.configure(function() {
    app.use(express.static(__dirname + '/app'));
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
});

/* database model */
var ShopList = mongoose.model('ShopList', {
    text: String,
    star: Boolean
});

/* endpoints */
app.get('/api/shoplist', function(req, res) {
    ShopList.find(function(err, list) {
        if(err) {
            res.send(err);
        }
        res.json(list);
    });
});

app.post('/api/shoplist', function(req, res) {
    ShopList.create({
        text: req.body.text
    }, function(err, list){
        if(err) {
            res.send(err);
        }
        //retrieve the whole list
        ShopList.find(function(err, list) {
            if(err){
                res.send(err);
            }
            res.json(list);
        });
    });
});

app.put('/api/shoplist/:item', function(req, res) {
    console.log(req.body);
    ShopList.findById({
        _id: req.params.item
    }, function(err, found){
        if(err) {
            res.send(err);
        }
        //update the found item
        found.text = req.body.text;
        found.star = !req.body.star;
        console.log("saving:" + found)
        found.save(function(err, found){
            if (err) {
                res.send(err);
            }
        }) /* save() returns promises */
        .then(function(){
            //retrieve the whole list
            ShopList.find(function (err, list) {
                if (err) {
                    res.send(err);
                }
                console.log("Found:" + list);
                res.json(list);
            });
        });
    });
});

app.delete('/api/shoplist/:item', function(req, res) {
    ShopList.remove({
        _id: req.params.item
    }, function(err, item) {
        if(err){
            res.send(err);
        }
        //retrieve the whole list
        ShopList.find(function(err, list) {
            if(err){
                res.send(err);
            }
            res.json(list);
        });

    })
});

//define where the index is placed
app.get('*', function(req, res) {
    res.sendfile('./app/index.html');
});

/* run */
app.listen(listen_port, function() {
    console.log('App listening on port ' + listen_port);
});
<commit_msg>Remove useless console logs<commit_after>var express = require('express');
var app = express();
var mongoose = require('mongoose');
var listen_port = 9981;

/* database connection */
mongoose.connect('mongodb://localhost:27017/shoplist');

/* configuration */
app.configure(function() {
    app.use(express.static(__dirname + '/app'));
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
});

/* database model */
var ShopList = mongoose.model('ShopList', {
    text: String,
    star: Boolean
});

/* endpoints */
app.get('/api/shoplist', function(req, res) {
    ShopList.find(function(err, list) {
        if(err) {
            res.send(err);
        }
        res.json(list);
    });
});

app.post('/api/shoplist', function(req, res) {
    ShopList.create({
        text: req.body.text
    }, function(err, list){
        if(err) {
            res.send(err);
        }
        //retrieve the whole list
        ShopList.find(function(err, list) {
            if(err){
                res.send(err);
            }
            res.json(list);
        });
    });
});

app.put('/api/shoplist/:item', function(req, res) {
    ShopList.findById({
        _id: req.params.item
    }, function(err, found){
        if(err) {
            res.send(err);
        }
        //update the found item
        found.text = req.body.text;
        found.star = !req.body.star;
        found.save(function(err, found){
            if (err) {
                res.send(err);
            }
        }) /* save() returns promises */
        .then(function(){
            //retrieve the whole list
            ShopList.find(function (err, list) {
                if (err) {
                    res.send(err);
                }
                res.json(list);
            });
        });
    });
});

app.delete('/api/shoplist/:item', function(req, res) {
    ShopList.remove({
        _id: req.params.item
    }, function(err, item) {
        if(err){
            res.send(err);
        }
        //retrieve the whole list
        ShopList.find(function(err, list) {
            if(err){
                res.send(err);
            }
            res.json(list);
        });

    })
});

//define where the index is placed
app.get('*', function(req, res) {
    res.sendfile('./app/index.html');
});

/* run */
app.listen(listen_port, function() {
    console.log('App listening on port ' + listen_port);
});
<|endoftext|>


<commit_before>;(function($, window, document, undefined) {

    var MINE = 64;

    $.mines = function(el, options) {
        var base = this;

        // Access to jQuery and DOM versions of the element
        base.$el = $(el);
        base.el = el;

        // Add a reverse reference to the DOM object
        base.$el.data('mines', base);

        base.init = function() {
            base.options = $.extend({}, $.mines.default, options);

            // Check the dimensions
            if (base.options.size.x < 1 || base.options.size.y < 1) {
                console.error('illegal dimensions: (' +
                    base.options.size.x + ',' +
                    base.options.size.y + ')');
                return;
            }

            // Check the number of mines
            if (base.options.mines < 1 ||
                    base.options.mines > (base.options.size.x *
                        base.options.size.y) / 2) {
                console.error('illegal number of mines: ' +
                    base.options.mines);
                return;
            }

            // Set dimensions of board
            base.$el.css({
                height: (base.options.tileSize.height) * base.options.size.y,
                width: (base.options.tileSize.width) * base.options.size.x
            });

            // Disable context menu for the board
            base.$el.bind('contextmenu', function() { return false; });

            base.noTiles = base.options.size.x * base.options.size.y;

            base.getBoard(
                base.options.size.x,
                base.options.size.y,
                base.options.mines
            );

            base.buildBoard(base.options.size.x, base.options.size.y);
        }

        base.openField = function(x, y) {
            var xMin = Math.max(x - 1, 0);
            var xMax = Math.min(x + 1, base.options.size.x - 1);
            var yMin = Math.max(y - 1, 0);
            var yMax = Math.min(y + 1, base.options.size.y - 1);
            for (var i = yMin; i <= yMax; i++) {
                for (var j = xMin; j <= xMax; j++) {
                    base.tileBoard[j][i].mousedown();
                }
            }
        }

        base.clickTile = function(event) {
            $tile = $(this);
            if ($tile.hasClass('mines-clicked')) {
                return;
            }
            if (event.which === 3) {
                console.log('toggle flag');
                $tile.toggleClass('mines-flag');
                return;
            }
            if ($tile.hasClass('mines-flag')) {
                return;
            }
            $tile.addClass('mines-clicked');
            var tileX = $tile.data('x');
            var tileY = $tile.data('y');
            var nMines = base.board[tileX][tileY];
            if (nMines === 0) {
                base.openField(tileX, tileY);
            } else if ((nMines & MINE) !== 0) {
                // Die
                console.log('die!');
                $tile.append('');
            } else {
                // Show no. neighboring mines
                $tile.append(base.board[tileX][tileY]);
            }
            base.checkVictory();
        }

        base.checkVictory = function() {
            if ($('.mines-clicked').length === base.noTiles - base.options.mines) {
                console.log('You won!');
            }
        }

        base.incrementNeighbors = function(x, y) {
            for (var i = y - 1; i <= y + 1; i++) {
                for (var j = x - 1; j <= x + 1; j++) {
                    if (j === x && i === y) {
                        continue;
                    }
                    if (j + 1 > base.options.size.x || j < 0) {
                        continue;
                    }
                    if (i + 1 > base.options.size.y || i < 0) {
                        continue;
                    }
                    if ((base.board[i][j] & MINE) !== MINE) {
                        base.board[i][j]++;
                    }
                }
            }
        }

        base.getBoard = function(x, y, mines) {
            base.board = [];
            for (var i = 0; i < y; i++) {
                var row = [];
                for (var j = 0; j < x; j++) {
                    row.push(0);
                }
                base.board.push(row);
            }

            var placedMines = 0;
            while (placedMines < mines) {
                var randX = Math.floor(Math.random() * x);
                var randY = Math.floor(Math.random() * y);
                // If there isn'a a mine at this random position, place it
                if ((MINE & base.board[randY][randX]) === 0) {
                    base.board[randY][randX] = MINE;
                    placedMines++;
                    // Add to all neighbors that aren't mines
                    base.incrementNeighbors(randX, randY);
                }
            }
        }

        base.buildBoard = function(x, y) {
            base.tileBoard = [];
            for (var i = 0; i < y; i++) {
                var row = [];
                for (var j = 0; j < x; j++) {
                    row.push(null);
                }
                base.tileBoard.push(row);
            }
            // Fill the boards with tiles
            for (var y = 0; y < base.options.size.y; y++) {
                for (var x = 0; x < base.options.size.x; x++) {
                    var $tile = $('<div/>')
                        .css(base.options.tileSize)
                        .addClass('mines-tile')
                        .data('x', x)
                        .data('y', y)
                        .mousedown(base.clickTile);
                    base.tileBoard[x][y] = $tile;
                    base.$el.append($tile);
                }
            }
        }

        // Run init
        base.init();
    };

    $.mines.default = {
        mines: 10,
        tileSize: {
            height: 20,
            width: 20,
        },
        size: {
            x: 8,
            y: 8
        }
    };

    $.fn.mines = function(options) {
        return this.each(function() {
            (new $.mines(this, options));
        });
    };
})(jQuery, window, document);
<commit_msg>fixed coordinate inconsistency<commit_after>;(function($, window, document, undefined) {

    var MINE = 64;

    $.mines = function(el, options) {
        var base = this;

        // Access to jQuery and DOM versions of the element
        base.$el = $(el);
        base.el = el;

        // Add a reverse reference to the DOM object
        base.$el.data('mines', base);

        base.init = function() {
            base.options = $.extend({}, $.mines.default, options);

            // Check the dimensions
            if (base.options.size.x < 1 || base.options.size.y < 1) {
                console.error('illegal dimensions: (' +
                    base.options.size.x + ',' +
                    base.options.size.y + ')');
                return;
            }

            // Check the number of mines
            if (base.options.mines < 1 ||
                    base.options.mines > (base.options.size.x *
                        base.options.size.y) / 2) {
                console.error('illegal number of mines: ' +
                    base.options.mines);
                return;
            }

            // Set dimensions of board
            base.$el.css({
                height: (base.options.tileSize.height) * base.options.size.y,
                width: (base.options.tileSize.width) * base.options.size.x
            });

            // Disable context menu for the board
            base.$el.bind('contextmenu', function() { return false; });

            base.noTiles = base.options.size.x * base.options.size.y;

            base.getBoard(
                base.options.size.x,
                base.options.size.y,
                base.options.mines
            );

            base.buildBoard(base.options.size.x, base.options.size.y);
        }

        base.openField = function(x, y) {
            var xMin = Math.max(x - 1, 0);
            var xMax = Math.min(x + 1, base.options.size.x - 1);
            var yMin = Math.max(y - 1, 0);
            var yMax = Math.min(y + 1, base.options.size.y - 1);
            for (var i = yMin; i <= yMax; i++) {
                for (var j = xMin; j <= xMax; j++) {
                    base.tileBoard[i][j].mousedown();
                }
            }
        }

        base.clickTile = function(event) {
            $tile = $(this);
            if ($tile.hasClass('mines-clicked')) {
                return;
            }
            if (event.which === 3) {
                console.log('toggle flag');
                $tile.toggleClass('mines-flag');
                return;
            }
            if ($tile.hasClass('mines-flag')) {
                return;
            }
            $tile.addClass('mines-clicked');
            var tileX = $tile.data('x');
            var tileY = $tile.data('y');
            var nMines = base.board[tileY][tileX];
            if (nMines === 0) {
                base.openField(tileX, tileY);
            } else if ((nMines & MINE) !== 0) {
                // Die
                console.log('die!');
                $tile.append('');
            } else {
                // Show no. neighboring mines
                $tile.append(base.board[tileY][tileX]);
            }
            base.checkVictory();
        }

        base.checkVictory = function() {
            if ($('.mines-clicked').length === base.noTiles - base.options.mines) {
                console.log('You won!');
            }
        }

        base.incrementNeighbors = function(x, y) {
            for (var i = y - 1; i <= y + 1; i++) {
                for (var j = x - 1; j <= x + 1; j++) {
                    if (j === x && i === y) {
                        continue;
                    }
                    if (j + 1 > base.options.size.x || j < 0) {
                        continue;
                    }
                    if (i + 1 > base.options.size.y || i < 0) {
                        continue;
                    }
                    if ((base.board[i][j] & MINE) !== MINE) {
                        base.board[i][j]++;
                    }
                }
            }
        }

        base.getBoard = function(x, y, mines) {
            base.board = [];
            for (var i = 0; i < y; i++) {
                var row = [];
                for (var j = 0; j < x; j++) {
                    row.push(0);
                }
                base.board.push(row);
            }

            var placedMines = 0;
            while (placedMines < mines) {
                var randX = Math.floor(Math.random() * x);
                var randY = Math.floor(Math.random() * y);
                // If there isn'a a mine at this random position, place it
                if ((MINE & base.board[randY][randX]) === 0) {
                    base.board[randY][randX] = MINE;
                    placedMines++;
                    // Add to all neighbors that aren't mines
                    base.incrementNeighbors(randX, randY);
                }
            }
        }

        base.buildBoard = function(x, y) {
            base.tileBoard = [];
            for (var i = 0; i < y; i++) {
                var row = [];
                for (var j = 0; j < x; j++) {
                    row.push(null);
                }
                base.tileBoard.push(row);
            }
            // Fill the boards with tiles
            for (var y = 0; y < base.options.size.y; y++) {
                for (var x = 0; x < base.options.size.x; x++) {
                    var $tile = $('<div/>')
                        .css(base.options.tileSize)
                        .addClass('mines-tile')
                        .data('x', x)
                        .data('y', y)
                        .mousedown(base.clickTile);
                    base.tileBoard[y][x] = $tile;
                    base.$el.append($tile);
                }
            }
        }

        // Run init
        base.init();
    };

    $.mines.default = {
        mines: 10,
        tileSize: {
            height: 20,
            width: 20,
        },
        size: {
            x: 8,
            y: 8
        }
    };

    $.fn.mines = function(options) {
        return this.each(function() {
            (new $.mines(this, options));
        });
    };
})(jQuery, window, document);
<|endoftext|>


<commit_before>require('babel/register')({
  ignore: /node_modules|public/
})

// modules
var koa = require('koa'),
  qs = require('koa-qs'),
  csrf = require('koa-csrf'),
  mount = require('koa-mount'),
  serve = require('koa-static'),
  session = require('koa-session'),
  compress = require('koa-compress'),
  debug = require('debug')('bshed:server'),
  responseTime = require('koa-response-time')

// application modules
debug('loading modules')
var config = require('./config'),
  models = require('./models'),
  s3 = require('./lib/s3'),
  api = require('./api'),
  client = require('./client/renderer/middleware')

// initialization
debug('initializing modules')
s3 = s3(config.aws)
models = models({
  config: config.database
})
api = api({
  config: config.api,
  models: models,
  s3: s3
})
client = client({
  assetPath: config.server.assets
})

/**
 * SERVER
 */
var server = qs(koa())
server.name = config.server.name
server.env = config.server.env
server.keys = config.secret
server.config = config
server.models = models
server.api = api

/**
 * MIDDLEWARE
 */
if (server.env === 'development')
  server.use(require('koa-logger')()) // request logging
server.use(responseTime()) // x-response-time
server.use(compress()) // compression
server.use(serve(config.server.assets, config.server.middleware.serve)) // assets
server.use(session(config.server.middleware.session, server)) // sessions
server.use(csrf()) // csrf

// set csrf cookie token
server.use(function* setCsrfCookie (next) {
  this.cookies.set('XSRF-TOKEN', this.csrf)
  yield next
})

/**
 * APPLICATIONS
 */
debug('mounting modules')
server.use(mount(api))
server.use(mount(client))

/**
 * SERVER INITIALIZER
 *
 * Listen for connections
 * returns server instance
 */
server.init = function init (port=config.server.port) {
  debug('initializing server using port %d', port)
  server.server = server.listen(port, () => debug('listening on port %d', port))
  return server.server
}

// export the server so it can be started externally
module.exports = server

// initialize server if called directly
if (require.main === module)
  server.init()
<commit_msg>Use var per line<commit_after>require('babel/register')({
  ignore: /node_modules|public/
})

// modules
var koa = require('koa')
var qs = require('koa-qs')
var csrf = require('koa-csrf')
var mount = require('koa-mount')
var serve = require('koa-static')
var session = require('koa-session')
var compress = require('koa-compress')
var debug = require('debug')('bshed:server')
var responseTime = require('koa-response-time')

// application modules
debug('loading modules')
var config = require('./config')
var models = require('./models')
var s3 = require('./lib/s3')
var api = require('./api')
var client = require('./client/renderer/middleware')

// initialization
debug('initializing modules')
s3 = s3(config.aws)
models = models({
  config: config.database
})
api = api({
  config: config.api,
  models: models,
  s3: s3
})
client = client({
  assetPath: config.server.assets
})

/**
 * SERVER
 */
var server = qs(koa())
server.name = config.server.name
server.env = config.server.env
server.keys = config.secret
server.config = config
server.models = models
server.api = api

/**
 * MIDDLEWARE
 */
if (server.env === 'development')
  server.use(require('koa-logger')()) // request logging
server.use(responseTime()) // x-response-time
server.use(compress()) // compression
server.use(serve(config.server.assets, config.server.middleware.serve)) // assets
server.use(session(config.server.middleware.session, server)) // sessions
server.use(csrf()) // csrf

// set csrf cookie token
server.use(function* setCsrfCookie (next) {
  this.cookies.set('XSRF-TOKEN', this.csrf)
  yield next
})

/**
 * APPLICATIONS
 */
debug('mounting modules')
server.use(mount(api))
server.use(mount(client))

/**
 * SERVER INITIALIZER
 *
 * Listen for connections
 * returns server instance
 */
server.init = function init (port=config.server.port) {
  debug('initializing server using port %d', port)
  server.server = server.listen(port, () => debug('listening on port %d', port))
  return server.server
}

// export the server so it can be started externally
module.exports = server

// initialize server if called directly
if (require.main === module)
  server.init()
<|endoftext|>


<commit_before>var DOSAGEPUTURL = "https://lumohacks-med-disp.firebaseio.com/patients/jeffrey_leung/dosage.json";
var ALERTPUT = "https://lumohacks-med-disp.firebaseio.com/patients/jeffrey_leung/alert.json";

var PATIENTSURL = "https://lumohacks-med-disp.firebaseio.com/patients.json"

$(document).ready(function() {
  $('expand tr').each(function(){
      $(this).click(function(){
          $(this).siblings('tr').slideToggle(300);
      });
  });
	$.get({
		url: PATIENTSURL
	}).done(function (data) {
		console.log("Data: ", data);
	 	var js = 1
		for (i in data){
			console.log("js: " + js)
			console.log("js%2: " + js%2)
			console.log("js%2===0: " , (js%2)===0)
			if(js%2===1){
				var patientRow = $('#dummy-patient-row2').clone();
			}else{
				var patientRow = $('#dummy-patient-row').clone();
			}
			js++
			var hiddenRow = $('#dummy-hidden-row').clone();
			hiddenRow.data('patient-data',data[i]);
			patientRow.attr('href',"#".concat(i));
			patientRow.attr('aria-controls',i);
			patientRow.find('.patient-id').text(i)
			patientRow.find('.patient-name').text(data[i].name)
			patientRow.find('.patient-nMedication').text(data[i].dosage)

			hiddenRow.find('.n-dosage').text(data[i].dosage)
			hiddenRow.find('.dosageInput').val(data[i].dosage)
			hiddenRow.find('.collapse').attr("id", i);

			patientRow.attr('id',"");
			hiddenRow.attr('id',"");
			$('#patient_data > tbody').append(patientRow)
			$('#patient_data > tbody').append(hiddenRow)

		}
		// Input onchange
		$('.dosageInput').change( function(e){
			e.preventDefault();
			$(this).parents('.patient-subdata').find('.n-dosage').text($(this).val())
			// $('msg').innerText = document.getElementById('dosageInput').value;
		})
		// Done appending; attach click functions
		$('.dosageDispense').on('click', function(e){
			e.preventDefault();
			$.ajax({
				method: "PUT",
				url: DOSAGEPUTURL,
				data: $(this).prevAll('input').val()
			}).done(function(data){
				$.ajax({
					method: "PUT",
					url: ALERTPUT,
					data: "true"
				}).done(function(data){
					alert("Dosage Dispensed");
				})
			})
		})

	})
});
<commit_msg>Replace temporary name with patient number<commit_after>var DOSAGEPUTURL = "https://lumohacks-med-disp.firebaseio.com/patients/197214/dosage.json";
var ALERTPUT = "https://lumohacks-med-disp.firebaseio.com/patients/197214/alert.json";

var PATIENTSURL = "https://lumohacks-med-disp.firebaseio.com/patients.json"

$(document).ready(function() {
  $('expand tr').each(function(){
      $(this).click(function(){
          $(this).siblings('tr').slideToggle(300);
      });
  });
	$.get({
		url: PATIENTSURL
	}).done(function (data) {
		console.log("Data: ", data);
	 	var js = 1
		for (i in data){
			console.log("js: " + js)
			console.log("js%2: " + js%2)
			console.log("js%2===0: " , (js%2)===0)
			if(js%2===1){
				var patientRow = $('#dummy-patient-row2').clone();
			}else{
				var patientRow = $('#dummy-patient-row').clone();
			}
			js++
			var hiddenRow = $('#dummy-hidden-row').clone();
			hiddenRow.data('patient-data',data[i]);
			patientRow.attr('href',"#".concat(i));
			patientRow.attr('aria-controls',i);
			patientRow.find('.patient-id').text(i)
			patientRow.find('.patient-name').text(data[i].name)
			patientRow.find('.patient-nMedication').text(data[i].dosage)

			hiddenRow.find('.n-dosage').text(data[i].dosage)
			hiddenRow.find('.dosageInput').val(data[i].dosage)
			hiddenRow.find('.collapse').attr("id", i);

			patientRow.attr('id',"");
			hiddenRow.attr('id',"");
			$('#patient_data > tbody').append(patientRow)
			$('#patient_data > tbody').append(hiddenRow)

		}
		// Input onchange
		$('.dosageInput').change( function(e){
			e.preventDefault();
			$(this).parents('.patient-subdata').find('.n-dosage').text($(this).val())
			// $('msg').innerText = document.getElementById('dosageInput').value;
		})
		// Done appending; attach click functions
		$('.dosageDispense').on('click', function(e){
			e.preventDefault();
			$.ajax({
				method: "PUT",
				url: DOSAGEPUTURL,
				data: $(this).prevAll('input').val()
			}).done(function(data){
				$.ajax({
					method: "PUT",
					url: ALERTPUT,
					data: "true"
				}).done(function(data){
					alert("Dosage Dispensed");
				})
			})
		})

	})
});
<|endoftext|>


<commit_before>// Dependencies
var Barbe = require("barbe")
  , Fs = require("fs")
  , Path = require("path")
  , JxUtils = require("jxutils")
  , MarkDox = require("markdox")
  , IsThere = require("is-there")
  , ReadJson = require("r-json")
  , WriteJson = require("w-json")
  , ParentSearch = require("parent-search")
  , Streamp = require("streamp")
  , Ul = require("ul")
  , SameTime = require("same-time")
  , Deffy = require("deffy")
  , Ejs = require("ejs")
  , Ncp = require("ncp")
  ;

// Constants
const BLAH_DIR = ".blah"
    , BLAH_TEMPLATES = ".blah-templates"
    , TEMPLATES = "templates"
    , PACKAGE_JSON = "package.json"
    , DOCUMENTATION_NAME = "DOCUMENTATION.md"
    , DOCUMENTATION_TMPL = "docs.ejs"
    , CONTRIBUTING_TMPL = "CONTRIBUTING.ejs"
    , CONTRIBUTING_NAME = "CONTRIBUTING.md"
    , README_TMPL = "README.ejs"
    , README_NAME = "README.md"
    , LICENSE_NAME = "LICENSE"
    , GITIGNORE = ".gitignore"
    ;

/**
 * Blah
 * Creates a new `Blah` instance.
 *
 * @name Blah
 * @function
 * @param {String} path The Blah working directory (default: `process.cwd()`).
 */
function Blah(path) {

    // Blah working directory
    this.path = Deffy(path, process.cwd());

    // .blah/
    this.blah_dir = Path.join(this.path, BLAH_DIR);

    // ~/.blah-templates
    this.usr_templates = Path.join(Ul.USER_DIR, BLAH_TEMPLATES);

    // templates/
    this.lib_templates = Path.join(__dirname, TEMPLATES);

    this.templates = {};
    this.pack = {};
    this.paths = {};
}

/**
 * search
 * Searches a file in the blah directories.
 *
 * @name search
 * @function
 * @param {String} file The relative path to a file to search in the templates
 * directories (in the following order: local `.blah` directory,
 * `~/.blah-templates`, library templates).
 * @param {Function} callback The callback function.
 */
Blah.prototype.search = function (file, callback) {

    if (typeof file === "function") {
        callback = file;
        file = "";
    }

    var self = this
      , tries = [

            // Local .blah/file
            Path.join(self.blah_dir, file)

            // Templates: ~/.blah-templates/file
          , Path.join(self.usr_templates, file)

            // Library templates: templates/file
          , Path.join(self.lib_templates, file)
        ]
      ;

    SameTime(tries.map(function (cPath) {
        return function (cb) {
            IsThere(cPath, function (exists) {
                cb(null, cPath, exists);
            });
        }
    }), function (err, fields, exists) {
        if (err) { return callback(err); }
        for (var i = 0; i < exists.length; ++i) {
            if (exists[i]) {
                return callback(null, fields[i]);
            }
        }
        callback(new Error("Cannot find searched file: " + file));
    });
};

/**
 * prepare
 * Prepares the Blah data.
 *
 * @name prepare
 * @function
 * @param {Function} callback The callback function.
 */
Blah.prototype.prepare = function (callback) {
    var self = this;

    // Find the paths
    SameTime([
        self.search.bind(self, DOCUMENTATION_TMPL)
      , self.search.bind(self, README_TMPL)
      , self.search.bind(self, GITIGNORE)
      , self.search.bind(self, CONTRIBUTING_TMPL)
      , function (cb) {
            ParentSearch(self.path, PACKAGE_JSON, cb.bind(this, null));
        }
    ], function (err, data) {
        if (err) { return callback(err); }

        self.paths.markdox = data[0];
        self.paths.readme = data[1];
        self.paths.gitignore = data[2];
        self.paths.contributing = data[3];
        self.paths.pack = data[4];

        // Read the template data
        SameTime([
            function (cb) {
                if (!self.paths.pack) {
                    return cb(null, {});
                }
                ReadJson(self.paths.pack, function (err, pack) {
                    pack = Deffy(pack, {});
                    cb(null, pack);
                });
            }
        ], function (err, data) {
            if (err) { return callback(err); }
            self.pack = data[0];
            self.pack.blah = Deffy(self.pack.blah, {});
            self.copyright = {
                fullname: self.pack.author
              , year: new Date().getFullYear()
              , project: self.pack.name
              , description: self.pack.description
            };
            callback();
        });
    });
};

/**
 * init
 * Inits the `.blah` directory in the current project.
 *
 * @name init
 * @function
 * @param {Function} callback The callback function.
 */
Blah.prototype.init = function (callback) {
    var self = this;
    self.prepare(function (err) {
        if (err) { return callback(err); }
        self.search(function (err, path_templates) {
            if (err) { return callback(err); }
            if (path_templates === self.blah_dir) {
                return callback(new Error("Refusing to override existing templates."));
            }
            Ncp(path_templates, self.blah_dir, callback);
        });
    });
};

/**
 * docs
 * Generates the DOCUMENTATION.md file, parsing the input files.
 *
 * @name docs
 * @function
 * @param {String} input Input file name (default: main file from package.json)
 * @param {String} output Output file name (default: `DOCUMENTATION.md`)
 * @param {Function} callback The callback function.
 */
Blah.prototype.docs = function (input, output, callback) {
    var self = this;

    if (typeof output === "function") {
        callback = output;
        output = Path.join(self.path, DOCUMENTATION_NAME);
    }

    self.prepare(function (err) {
        if (err) { return callback(err); }
        MarkDox.process(input, {
            template: self.paths.markdox
        }, function (err, content) {
            if (err) { return callback(err); }
            content = content.split("\n").map(function (c) {
                return c.trimRight();
            }).join("\n");
            Fs.writeFile(output, content, callback);
        });
    });
};

/**
 * readme
 * Creates the `README.md` file.
 *
 * @name readme
 * @function
 * @param {Function} callback The callback function
 */
Blah.prototype.readme = function (callback) {

    var self = this;

    self.prepare(function (err) {
        if (err) { return callback(err); }
        SameTime([
            function (cb) {
                IsThere(self.pack.main, function (exists) {
                    if (!exists) { return cb(null, ""); }
                    MarkDox.process(self.pack.main, {
                        template: self.paths.markdox
                    }, function (err, docs) {
                        if (docs) {
                            docs = docs.split("\n").map(function (c) {
                                return c.trimRight();
                            }).join("\n");
                        }
                        cb(err, docs);
                    });
                });
            }
        ], function (err, data) {
            if (err) { return callback(err); }

            self.render(self.paths.readme, {
                docs: data[0]
            }, function (err, content) {
                if (err) { return callback(err); }
                Fs.writeFile(
                    Path.join(self.path, README_NAME)
                  , content.replace(/^\s+|\s+$/g, "").replace(/\n{3,}/g, "\n\n")
                  , callback
                );
            });
        });
    });
};

/**
 * gitignore
 * Creates the `.gitignore` file.
 *
 * @name gitignore
 * @function
 * @param {Function} callback The callback function.
 */
Blah.prototype.gitignore = function (callback) {
    var self = this;
    self.prepare(function (err) {
        if (err) { return callback(err); }
        Ncp(self.paths.gitignore, Path.join(self.path, GITIGNORE), callback);
    });
};

/**
 * license
 * Creates the `LICENSE` file.
 *
 * @name license
 * @function
 * @param {String} license The license name.
 * @param {Function} callback The callback function.
 */
Blah.prototype.license = function (license, callback) {
    var self = this;
    self.prepare(function (err) {
        if (err) { return callback(err); }
        var licensePath = Path.join(__dirname, "/licenses/", license.toLowerCase(), ".txt");
        if (!IsThere(licensePath)) {
            return callback(new Error("There is no license named " + license));
        }
        if (!self.copyright.fullname) {
            return callback(new Error("Cannot find the author name. Is the package.json file missing?"));
        }
        Fs.readFile(licensePath, "utf-8", function (err, content) {
            if (err) { return callback(err); }
            content = Barbe(content, ["[", "]"], self.copyright);
            Fs.writeFile(Path.join(self.path, "LICENSE"), content, callback);
        });
    });
};

/**
 * render
 * Renders a template from file.
 *
 * @name render
 * @function
 * @param {String} path The template path.
 * @param {Object} data Additional data to merge into the template data.
 * @param {Function} callback The callback function.
 */
Blah.prototype.render = function (path, data, callback) {
    var self = this;

    if (typeof data === "function") {
        callback = data;
        data = {};
    }

    Ejs.renderFile(path, Ul.merge({
        _: self
      , require: require
    }, data), callback);
};

/**
 * contributing
 * Generates the `CONTRIBUTING.md` file.
 *
 * @name contributing
 * @function
 * @param {Function} callback The callback function.
 */
Blah.prototype.contributing = function (callback) {
    var self = this;
    self.prepare(function (err) {
        if (err) { return callback(err); }
        self.render(self.paths.contributing, function (err, content) {
            if (err) { return callback(err); }
            Fs.writeFile(
                Path.join(self.path, CONTRIBUTING_NAME)
              , content.replace(/^\s+|\s+$/g, "").replace(/\n{3,}/g, "\n\n")
              , callback
            );
        });
    });
};

/**
 * version
 * Bumps the provided version.
 *
 * @name version
 * @function
 * @param {String} what The version which should be bumped. It takes one of the following values: `"major"`, `"minor"`, `"patch"`. The default is `"patch"`.
 * @param {Function} callback The callback function.
 */
Blah.prototype.version = function (what, callback) {
    var self = this;

    if (typeof what === "function") {
        callback = what;
        what = "patch";
    }

    if (!/^major|minor|patch$/.test(what)) {
        return callback(new Error("Invalid version: " + what));
    }

    self.prepare(function (err) {
        if (err) { return callback(err); }
        var version = self.pack.version;
        if (!version) {
            return callback(new Error("Cannot find the version in the package.json file."));
        }

        version = self.pack.version.split(".").map(function (x) {
            return parseInt(x, 10);
        });

        switch (what) {
            case "major":
                ++version[0];
                version[1] = 0;
                version[2] = 0;
                break;
            case "minor":
                ++version[1];
                version[2] = 0;
                break;
            case "patch":
                ++version[2];
                break;
                break;
        }

        self.pack.version = version.join(".");
        if (!Object.keys(self.pack.blah).length) {
            delete self.pack.blah;
        }

        WriteJson(self.paths.pack, self.pack, callback);
    });
};

module.exports = Blah;
<commit_msg>Check if the main field exists<commit_after>// Dependencies
var Barbe = require("barbe")
  , Fs = require("fs")
  , Path = require("path")
  , JxUtils = require("jxutils")
  , MarkDox = require("markdox")
  , IsThere = require("is-there")
  , ReadJson = require("r-json")
  , WriteJson = require("w-json")
  , ParentSearch = require("parent-search")
  , Streamp = require("streamp")
  , Ul = require("ul")
  , SameTime = require("same-time")
  , Deffy = require("deffy")
  , Ejs = require("ejs")
  , Ncp = require("ncp")
  ;

// Constants
const BLAH_DIR = ".blah"
    , BLAH_TEMPLATES = ".blah-templates"
    , TEMPLATES = "templates"
    , PACKAGE_JSON = "package.json"
    , DOCUMENTATION_NAME = "DOCUMENTATION.md"
    , DOCUMENTATION_TMPL = "docs.ejs"
    , CONTRIBUTING_TMPL = "CONTRIBUTING.ejs"
    , CONTRIBUTING_NAME = "CONTRIBUTING.md"
    , README_TMPL = "README.ejs"
    , README_NAME = "README.md"
    , LICENSE_NAME = "LICENSE"
    , GITIGNORE = ".gitignore"
    ;

/**
 * Blah
 * Creates a new `Blah` instance.
 *
 * @name Blah
 * @function
 * @param {String} path The Blah working directory (default: `process.cwd()`).
 */
function Blah(path) {

    // Blah working directory
    this.path = Deffy(path, process.cwd());

    // .blah/
    this.blah_dir = Path.join(this.path, BLAH_DIR);

    // ~/.blah-templates
    this.usr_templates = Path.join(Ul.USER_DIR, BLAH_TEMPLATES);

    // templates/
    this.lib_templates = Path.join(__dirname, TEMPLATES);

    this.templates = {};
    this.pack = {};
    this.paths = {};
}

/**
 * search
 * Searches a file in the blah directories.
 *
 * @name search
 * @function
 * @param {String} file The relative path to a file to search in the templates
 * directories (in the following order: local `.blah` directory,
 * `~/.blah-templates`, library templates).
 * @param {Function} callback The callback function.
 */
Blah.prototype.search = function (file, callback) {

    if (typeof file === "function") {
        callback = file;
        file = "";
    }

    var self = this
      , tries = [

            // Local .blah/file
            Path.join(self.blah_dir, file)

            // Templates: ~/.blah-templates/file
          , Path.join(self.usr_templates, file)

            // Library templates: templates/file
          , Path.join(self.lib_templates, file)
        ]
      ;

    SameTime(tries.map(function (cPath) {
        return function (cb) {
            IsThere(cPath, function (exists) {
                cb(null, cPath, exists);
            });
        }
    }), function (err, fields, exists) {
        if (err) { return callback(err); }
        for (var i = 0; i < exists.length; ++i) {
            if (exists[i]) {
                return callback(null, fields[i]);
            }
        }
        callback(new Error("Cannot find searched file: " + file));
    });
};

/**
 * prepare
 * Prepares the Blah data.
 *
 * @name prepare
 * @function
 * @param {Function} callback The callback function.
 */
Blah.prototype.prepare = function (callback) {
    var self = this;

    // Find the paths
    SameTime([
        self.search.bind(self, DOCUMENTATION_TMPL)
      , self.search.bind(self, README_TMPL)
      , self.search.bind(self, GITIGNORE)
      , self.search.bind(self, CONTRIBUTING_TMPL)
      , function (cb) {
            ParentSearch(self.path, PACKAGE_JSON, cb.bind(this, null));
        }
    ], function (err, data) {
        if (err) { return callback(err); }

        self.paths.markdox = data[0];
        self.paths.readme = data[1];
        self.paths.gitignore = data[2];
        self.paths.contributing = data[3];
        self.paths.pack = data[4];

        // Read the template data
        SameTime([
            function (cb) {
                if (!self.paths.pack) {
                    return cb(null, {});
                }
                ReadJson(self.paths.pack, function (err, pack) {
                    pack = Deffy(pack, {});
                    cb(null, pack);
                });
            }
        ], function (err, data) {
            if (err) { return callback(err); }
            self.pack = data[0];
            self.pack.blah = Deffy(self.pack.blah, {});
            self.copyright = {
                fullname: self.pack.author
              , year: new Date().getFullYear()
              , project: self.pack.name
              , description: self.pack.description
            };
            callback();
        });
    });
};

/**
 * init
 * Inits the `.blah` directory in the current project.
 *
 * @name init
 * @function
 * @param {Function} callback The callback function.
 */
Blah.prototype.init = function (callback) {
    var self = this;
    self.prepare(function (err) {
        if (err) { return callback(err); }
        self.search(function (err, path_templates) {
            if (err) { return callback(err); }
            if (path_templates === self.blah_dir) {
                return callback(new Error("Refusing to override existing templates."));
            }
            Ncp(path_templates, self.blah_dir, callback);
        });
    });
};

/**
 * docs
 * Generates the DOCUMENTATION.md file, parsing the input files.
 *
 * @name docs
 * @function
 * @param {String} input Input file name (default: main file from package.json)
 * @param {String} output Output file name (default: `DOCUMENTATION.md`)
 * @param {Function} callback The callback function.
 */
Blah.prototype.docs = function (input, output, callback) {
    var self = this;

    if (typeof output === "function") {
        callback = output;
        output = Path.join(self.path, DOCUMENTATION_NAME);
    }

    self.prepare(function (err) {
        if (err) { return callback(err); }
        MarkDox.process(input, {
            template: self.paths.markdox
        }, function (err, content) {
            if (err) { return callback(err); }
            content = content.split("\n").map(function (c) {
                return c.trimRight();
            }).join("\n");
            Fs.writeFile(output, content, callback);
        });
    });
};

/**
 * readme
 * Creates the `README.md` file.
 *
 * @name readme
 * @function
 * @param {Function} callback The callback function
 */
Blah.prototype.readme = function (callback) {

    var self = this;

    self.prepare(function (err) {
        if (err) { return callback(err); }
        SameTime([
            function (cb) {
                if (!self.pack.main) {
                    return cb(null, "")
                }
                IsThere(self.pack.main, function (exists) {
                    if (!exists) { return cb(null, ""); }
                    MarkDox.process(self.pack.main, {
                        template: self.paths.markdox
                    }, function (err, docs) {
                        if (docs) {
                            docs = docs.split("\n").map(function (c) {
                                return c.trimRight();
                            }).join("\n");
                        }
                        cb(err, docs);
                    });
                });
            }
        ], function (err, data) {
            if (err) { return callback(err); }

            self.render(self.paths.readme, {
                docs: data[0]
            }, function (err, content) {
                if (err) { return callback(err); }
                Fs.writeFile(
                    Path.join(self.path, README_NAME)
                  , content.replace(/^\s+|\s+$/g, "").replace(/\n{3,}/g, "\n\n")
                  , callback
                );
            });
        });
    });
};

/**
 * gitignore
 * Creates the `.gitignore` file.
 *
 * @name gitignore
 * @function
 * @param {Function} callback The callback function.
 */
Blah.prototype.gitignore = function (callback) {
    var self = this;
    self.prepare(function (err) {
        if (err) { return callback(err); }
        Ncp(self.paths.gitignore, Path.join(self.path, GITIGNORE), callback);
    });
};

/**
 * license
 * Creates the `LICENSE` file.
 *
 * @name license
 * @function
 * @param {String} license The license name.
 * @param {Function} callback The callback function.
 */
Blah.prototype.license = function (license, callback) {
    var self = this;
    self.prepare(function (err) {
        if (err) { return callback(err); }
        var licensePath = Path.join(__dirname, "/licenses/", license.toLowerCase() + ".txt");
        if (!IsThere(licensePath)) {
            return callback(new Error("There is no license named " + license));
        }
        if (!self.copyright.fullname) {
            return callback(new Error("Cannot find the author name. Is the package.json file missing?"));
        }
        Fs.readFile(licensePath, "utf-8", function (err, content) {
            if (err) { return callback(err); }
            content = Barbe(content, ["[", "]"], self.copyright);
            Fs.writeFile(Path.join(self.path, "LICENSE"), content, callback);
        });
    });
};

/**
 * render
 * Renders a template from file.
 *
 * @name render
 * @function
 * @param {String} path The template path.
 * @param {Object} data Additional data to merge into the template data.
 * @param {Function} callback The callback function.
 */
Blah.prototype.render = function (path, data, callback) {
    var self = this;

    if (typeof data === "function") {
        callback = data;
        data = {};
    }

    Ejs.renderFile(path, Ul.merge({
        _: self
      , require: require
    }, data), callback);
};

/**
 * contributing
 * Generates the `CONTRIBUTING.md` file.
 *
 * @name contributing
 * @function
 * @param {Function} callback The callback function.
 */
Blah.prototype.contributing = function (callback) {
    var self = this;
    self.prepare(function (err) {
        if (err) { return callback(err); }
        self.render(self.paths.contributing, function (err, content) {
            if (err) { return callback(err); }
            Fs.writeFile(
                Path.join(self.path, CONTRIBUTING_NAME)
              , content.replace(/^\s+|\s+$/g, "").replace(/\n{3,}/g, "\n\n")
              , callback
            );
        });
    });
};

/**
 * version
 * Bumps the provided version.
 *
 * @name version
 * @function
 * @param {String} what The version which should be bumped. It takes one of the following values: `"major"`, `"minor"`, `"patch"`. The default is `"patch"`.
 * @param {Function} callback The callback function.
 */
Blah.prototype.version = function (what, callback) {
    var self = this;

    if (typeof what === "function") {
        callback = what;
        what = "patch";
    }

    if (!/^major|minor|patch$/.test(what)) {
        return callback(new Error("Invalid version: " + what));
    }

    self.prepare(function (err) {
        if (err) { return callback(err); }
        var version = self.pack.version;
        if (!version) {
            return callback(new Error("Cannot find the version in the package.json file."));
        }

        version = self.pack.version.split(".").map(function (x) {
            return parseInt(x, 10);
        });

        switch (what) {
            case "major":
                ++version[0];
                version[1] = 0;
                version[2] = 0;
                break;
            case "minor":
                ++version[1];
                version[2] = 0;
                break;
            case "patch":
                ++version[2];
                break;
                break;
        }

        self.pack.version = version.join(".");
        if (!Object.keys(self.pack.blah).length) {
            delete self.pack.blah;
        }

        WriteJson(self.paths.pack, self.pack, callback);
    });
};

module.exports = Blah;
<|endoftext|>


<commit_before>var events = require("eventemitter2"),
    util   = require("util"),
    fs     = require("fs"),
    jf     = require("jsonfile"),
    extend = require("extend");

var isJS = /^([a-z0-9]+)\.js$/i;
var c = function() {
  events.EventEmitter2.call(this, {
    wildcard: true,
    delimeter: ".",
    newListener: false,
    maxListeners: 48
  });

  var self     = this;
  // object, keyed by the name of the plugin, value is the instantiated plugin
  this.plugins = {};

  // object, keyed by the name of the plugin, value is the state of the plugin
  this.state   = {};

  var files    = fs.readdirSync("plugins");
  for (var i = files.length - 1; i >= 0; i--) {
    var file  = files[i],
        match = file.match(isJS);

    if (!match)
      continue;

    var name   = match[1];
    var plugin = require("./plugins/" + file);

    /*
     * Plugins are expected to export an object with three members:
     *   - init, a function taking three arguments, the first is the core
     *     the second is the config, the third is the state
     *     this is mandatory
     *
     *   - config, an object that represents the default config for the plugin
     *     this is optional, if the plugin needs an API key to function for example
     *     this is where we copy the file into the config/nameofplugin.json file
     *     and that is where the user should customize it
     *
     *   - state, an object representing the default state for the plugin
     *     this is optional, used for example storing banned links, anything
     *     that needs to be persisted
     *
     */
    var defaultconfig = plugin.config || {};
    var confpath      = "./config/" + name + ".json";
    var config        = fs.existsSync(confpath)? jf.readFileSync(confpath): defaultconfig;
    config            = extend(config, defaultconfig);

    /*
     * Pass the state, plugins should only modify the state, never override it
     * because it is meant to be a reference, the core periodically saves
     * the state it has a reference to
     * TLDR; no state = {}, but yes state.justmodifying = ['foo']
     *       AKA only ever just using the state that we pass
     *
     */
    var defaultstate = plugin.state || {};
    var statepath    = "./.state/" + name + ".json";
    var state        = fs.existsSync(statepath) ? jf.readFileSync(statepath) : defaultstate;
    state            = extend(state, defaultstate);

    this.plugins[name] = new plugin.init(this, config, state);
    this.state[name]   = state;
  };

  this.on("save", function(name) {
    if (name && self.plugins[name])
      return saveState(name, this.state[name]);

    for (var name in self.state) {
      if (!self.state.hasOwnProperty(name))
        continue;

      saveState(name, self.state[name]);
    };
  });

  // expose a logging function
  this.log = util.log; // TODO make it "better"
  // expose a convenience function for the most used action
  this.say = function(text) {
    self.send("MSG", {data: text})
  };
  // decouple how the protocol expects its events with this function
  // any new protocol needs to handle sending of messages this way
  this.send = function(action, payload) {
    self.emit("send." + action, payload);
  };
};

var saveState = function(name, state) {
  // do not save the state if the state is empty or falsey
  if (!state || !Object.keys(state).length)
    return;

  var statepath = "./.state/" + name + ".json";
  var temppath  = statepath + '.temp';
  jf.writeFileSync(temppath, state);
  fs.renameSync(temppath, statepath);
};

util.inherits(c, events.EventEmitter2);

module.exports = {init: c};
<commit_msg>fix bug with defaults overriding actually set state and config<commit_after>var events = require("eventemitter2"),
    util   = require("util"),
    fs     = require("fs"),
    jf     = require("jsonfile"),
    extend = require("extend");

var isJS = /^([a-z0-9]+)\.js$/i;
var c = function() {
  events.EventEmitter2.call(this, {
    wildcard: true,
    delimeter: ".",
    newListener: false,
    maxListeners: 48
  });

  var self     = this;
  // object, keyed by the name of the plugin, value is the instantiated plugin
  this.plugins = {};

  // object, keyed by the name of the plugin, value is the state of the plugin
  this.state   = {};

  var files    = fs.readdirSync("plugins");
  for (var i = files.length - 1; i >= 0; i--) {
    var file  = files[i],
        match = file.match(isJS);

    if (!match)
      continue;

    var name   = match[1];
    var plugin = require("./plugins/" + file);

    /*
     * Plugins are expected to export an object with three members:
     *   - init, a function taking three arguments, the first is the core
     *     the second is the config, the third is the state
     *     this is mandatory
     *
     *   - config, an object that represents the default config for the plugin
     *     this is optional, if the plugin needs an API key to function for example
     *     this is where we copy the file into the config/nameofplugin.json file
     *     and that is where the user should customize it
     *
     *   - state, an object representing the default state for the plugin
     *     this is optional, used for example storing banned links, anything
     *     that needs to be persisted
     *
     */
    var defaultconfig = plugin.config || {};
    var confpath      = "./config/" + name + ".json";
    var config        = fs.existsSync(confpath) ? jf.readFileSync(confpath) : defaultconfig;
    config            = extend(defaultconfig, config);

    /*
     * Pass the state, plugins should only modify the state, never override it
     * because it is meant to be a reference, the core periodically saves
     * the state it has a reference to
     * TLDR; no state = {}, but yes state.justmodifying = ['foo']
     *       AKA only ever just using the state that we pass
     *
     */
    var defaultstate = plugin.state || {};
    var statepath    = "./.state/" + name + ".json";
    var state        = fs.existsSync(statepath) ? jf.readFileSync(statepath) : defaultstate;
    state            = extend(defaultstate, state);

    this.plugins[name] = new plugin.init(this, config, state);
    this.state[name]   = state;
  };

  this.on("save", function(name) {
    if (name && self.plugins[name])
      return saveState(name, this.state[name]);

    for (var name in self.state) {
      if (!self.state.hasOwnProperty(name))
        continue;

      saveState(name, self.state[name]);
    };
  });

  // expose a logging function
  this.log = util.log; // TODO make it "better"
  // expose a convenience function for the most used action
  this.say = function(text) {
    self.send("MSG", {data: text})
  };
  // decouple how the protocol expects its events with this function
  // any new protocol needs to handle sending of messages this way
  this.send = function(action, payload) {
    self.emit("send." + action, payload);
  };
};

var saveState = function(name, state) {
  // do not save the state if the state is empty or falsey
  if (!state || !Object.keys(state).length)
    return;

  var statepath = "./.state/" + name + ".json";
  var temppath  = statepath + '.temp';
  jf.writeFileSync(temppath, state);
  fs.renameSync(temppath, statepath);
};

util.inherits(c, events.EventEmitter2);

module.exports = {init: c};
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp'),
  lazypipe = require('lazypipe'),
  runSequence = require('run-sequence'),
  bump = require('gulp-bump'),
  watch = require('gulp-watch'),
  karma = require('gulp-karma'),
  coveralls = require('gulp-coveralls'),
  shell = require('gulp-shell'),
  ghpages = require('gulp-gh-pages'),
  gls = require('gulp-live-server'),
  exit = require('gulp-exit'),
  mocha = require('gulp-mocha'),
  git = require('gulp-git'),
  tagVersion = require('gulp-tag-version'),
  jshint = require('gulp-jshint');

var testServer;

function getJSHintPipe(rc) {
  return lazypipe()
    .pipe(jshint, rc || '.jshintrc')
    .pipe(jshint.reporter, 'jshint-stylish')
    .pipe(jshint.reporter, 'fail');
}

function jsSourcePipe() {
  return gulp.src('src/**/*.js');
}

gulp.task('karma:server-start', function(cb) {
  testServer = gls.new('test/spec/server.js');

  testServer.start().then(function(s) {
    cb();
  }, function(err) {
    cb(err);
  });
});

gulp.task('karma:server-stop', function(cb) {
  if (!testServer) {
    cb('Server not started');
  }

  testServer.stop().then(function() {
    cb();
  }, function(err) {
    cb(err);
  });

  testServer = undefined;
});

function karmaPipe(action) {
  return gulp.src('test/spec/**/*.js')
    .pipe(karma({
      configFile: 'karma.conf.js',
      action: action
    })).on('error', function(err) {
      throw err;
    });
}

gulp.task('karma:watch', ['karma:server-start'], function() {
  return karmaPipe('watch');
});

gulp.task('karma:run', function() {
  return karmaPipe('run');
});

gulp.task('karma', function(cb) {
  runSequence(
    'karma:server-start',
    'karma:run',
    'karma:server-stop',
    cb
  );
});

gulp.task('jshint', ['jshint:src', 'jshint:test', 'jshint:gulpfile']);

gulp.task('jshint:src', function() {
  return jsSourcePipe()
    .pipe(getJSHintPipe()());
});

gulp.task('jshint:test', function() {
  return gulp.src('test/**/*.js')
    .pipe(getJSHintPipe('test/.jshintrc')());
});

gulp.task('jshint:gulpfile', function() {
  return gulp.src('gulpfile.js')
    .pipe(getJSHintPipe()());
});

gulp.task('test:watch', function() {
  return gulp.watch(['test/*.js', 'src/**/*.js'], ['test']);
});

gulp.task('jsdoc:watch', function() {
  return gulp.watch(['src/**/*.js', 'tutorials/*'], ['jsdoc']);
});

gulp.task('jsdoc', shell.task(['./node_modules/jsdoc/jsdoc.js . -c ./conf.json']));

gulp.task('bump', function() {
  return gulp.src('package.json')
    .pipe(bump({ type: gulp.env.type || 'patch' }))
    .pipe(gulp.dest('./'));
});

gulp.task('bump-commit', function() {
  var version = require('./package.json').version;
  return gulp.src(['package.json'])
    .pipe(git.commit('Release v' + version));
});

gulp.task('tag', function() {
  return gulp.src('package.json')
    .pipe(tagVersion());
});

gulp.task('release', function(cb) {
  runSequence(
    'jshint',
    'bump',
    'bump-commit',
    'tag',
    cb
  );
});

gulp.task('gh-pages', ['jsdoc'], function() {
  return gulp.src('doc/**/*')
    .pipe(ghpages());
});

gulp.task('default', function(cb) {
  runSequence('jshint', 'karma', cb);
});

gulp.task('coverage', function() {
  gulp.src('coverage/**/lcov.info')
    .pipe(shell([
      'cat "<%= file.path %>" | ./node_modules/codecov.io/.bin/codecov'
    ]));
    //.pipe(coveralls());
});

gulp.task('ci', function(cb) {
  runSequence('default', ['coverage', 'jsdoc'], cb);
});
<commit_msg>Proper path to codecov executable.<commit_after>'use strict';

var gulp = require('gulp'),
  lazypipe = require('lazypipe'),
  runSequence = require('run-sequence'),
  bump = require('gulp-bump'),
  watch = require('gulp-watch'),
  karma = require('gulp-karma'),
  coveralls = require('gulp-coveralls'),
  shell = require('gulp-shell'),
  ghpages = require('gulp-gh-pages'),
  gls = require('gulp-live-server'),
  exit = require('gulp-exit'),
  mocha = require('gulp-mocha'),
  git = require('gulp-git'),
  tagVersion = require('gulp-tag-version'),
  jshint = require('gulp-jshint');

var testServer;

function getJSHintPipe(rc) {
  return lazypipe()
    .pipe(jshint, rc || '.jshintrc')
    .pipe(jshint.reporter, 'jshint-stylish')
    .pipe(jshint.reporter, 'fail');
}

function jsSourcePipe() {
  return gulp.src('src/**/*.js');
}

gulp.task('karma:server-start', function(cb) {
  testServer = gls.new('test/spec/server.js');

  testServer.start().then(function(s) {
    cb();
  }, function(err) {
    cb(err);
  });
});

gulp.task('karma:server-stop', function(cb) {
  if (!testServer) {
    cb('Server not started');
  }

  testServer.stop().then(function() {
    cb();
  }, function(err) {
    cb(err);
  });

  testServer = undefined;
});

function karmaPipe(action) {
  return gulp.src('test/spec/**/*.js')
    .pipe(karma({
      configFile: 'karma.conf.js',
      action: action
    })).on('error', function(err) {
      throw err;
    });
}

gulp.task('karma:watch', ['karma:server-start'], function() {
  return karmaPipe('watch');
});

gulp.task('karma:run', function() {
  return karmaPipe('run');
});

gulp.task('karma', function(cb) {
  runSequence(
    'karma:server-start',
    'karma:run',
    'karma:server-stop',
    cb
  );
});

gulp.task('jshint', ['jshint:src', 'jshint:test', 'jshint:gulpfile']);

gulp.task('jshint:src', function() {
  return jsSourcePipe()
    .pipe(getJSHintPipe()());
});

gulp.task('jshint:test', function() {
  return gulp.src('test/**/*.js')
    .pipe(getJSHintPipe('test/.jshintrc')());
});

gulp.task('jshint:gulpfile', function() {
  return gulp.src('gulpfile.js')
    .pipe(getJSHintPipe()());
});

gulp.task('test:watch', function() {
  return gulp.watch(['test/*.js', 'src/**/*.js'], ['test']);
});

gulp.task('jsdoc:watch', function() {
  return gulp.watch(['src/**/*.js', 'tutorials/*'], ['jsdoc']);
});

gulp.task('jsdoc', shell.task(['./node_modules/jsdoc/jsdoc.js . -c ./conf.json']));

gulp.task('bump', function() {
  return gulp.src('package.json')
    .pipe(bump({ type: gulp.env.type || 'patch' }))
    .pipe(gulp.dest('./'));
});

gulp.task('bump-commit', function() {
  var version = require('./package.json').version;
  return gulp.src(['package.json'])
    .pipe(git.commit('Release v' + version));
});

gulp.task('tag', function() {
  return gulp.src('package.json')
    .pipe(tagVersion());
});

gulp.task('release', function(cb) {
  runSequence(
    'jshint',
    'bump',
    'bump-commit',
    'tag',
    cb
  );
});

gulp.task('gh-pages', ['jsdoc'], function() {
  return gulp.src('doc/**/*')
    .pipe(ghpages());
});

gulp.task('default', function(cb) {
  runSequence('jshint', 'karma', cb);
});

gulp.task('coverage', function() {
  gulp.src('coverage/**/lcov.info')
    .pipe(shell([
      'cat "<%= file.path %>" | ./node_modules/.bin/codecov'
    ]));
    //.pipe(coveralls());
});

gulp.task('ci', function(cb) {
  runSequence('default', ['coverage', 'jsdoc'], cb);
});
<|endoftext|>


<commit_before>
process.env.NO_PROXY = "localhost";

var SERVICES_ROOT = "http://www.ga.gov.au/explorer-web";
var NSW_METADATA_TEMPLATE = "https://s3-ap-southeast-2.amazonaws.com/nsw.elvis/z5${zone}/Metadata/";

var START_ABSTRACT_SENTINEL = "
Abstract:
";
var START_ABSTRACT_SENTINEL_LENGTH = START_ABSTRACT_SENTINEL.length;
var END_ABSTRACT_SENTINEL = "
";
var TOUCHPATH = os.homedir() + "touched/touched";

var config = require("./lib/config");
var express = require("express");
var fs = require("fs");
var request = require('request');
var mappers = require("./lib/mapper-picker");

// For positioning. We need a token
var Token = require("./lib/token");
var token = new Token(config.fmeToken);

request.gzip = false;

//var httpProxy = require('http-proxy');
var app = express();
var url = require('url');
var X2JS = require('x2js');

var StringDecoder = require('string_decoder').StringDecoder;
var yargs = require('yargs').options({
    'port': {
        'default': 3000,
        'description': 'Port to listen on.'
    },
    'public': {
        'type': 'boolean',
        'description': 'Run a public server that listens on all interfaces.'
    },
    'upstream-proxy': {
        'description': 'A standard proxy server that will be used to retrieve data.  Specify a URL including port, e.g. "http://proxy:8000".'
    },
    'bypass-upstream-proxy-hosts': {
        'description': 'A comma separated list of hosts that will bypass the specified upstream_proxy, e.g. "lanhost1,lanhost2"'
    },
    'help': {
        'alias': 'h',
        'type': 'boolean',
        'description': 'Show this help.'
    }
});
var argv = yargs.argv;
var port = process.env.PORT || argv.port;
var dontProxyHeaderRegex = /^(?:Host|Proxy-Connection|Accept-Encoding|Connection|Keep-Alive|Transfer-Encoding|TE|Trailer|Proxy-Authorization|Proxy-Authenticate|Upgrade)$/i;
// There should only ever be a couple. We do a contains on the requested host.
var validHosts = config.validHosts;
var upstreamProxy = argv['upstream-proxy'];

// eventually this mime type configuration will need to change
// https://github.com/visionmedia/send/commit/d2cb54658ce65948b0ed6e5fb5de69d022bef941
var mime = express.static.mime;
mime.define({
    'application/json': ['czml', 'json', 'geojson', 'topojson'],
    'model/vnd.gltf+json': ['gltf'],
    'model/vnd.gltf.binary': ['bgltf'],
    'text/plain': ['glsl']
});

// serve static files
app.use(express.static("dist"));
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.all('/service/*', function (req, res, next) {
    var method, r;

    method = req.method.toLowerCase();

    console.log("URL: " + method + " " + SERVICES_ROOT + req.url);

    switch (method) {
        case "get":
            r = request.get({
                uri: SERVICES_ROOT + req.url,
                json: req.body
            });
            break;
        case "put":
            r = request.put({
                uri: SERVICES_ROOT + req.url,
                json: req.body
            });
            break;
        case "post":
            r = request.post({
                uri: SERVICES_ROOT + req.url,
                json: req.body
            });
            break;
        case "delete":
            r = request.del({
                uri: SERVICES_ROOT + req.url,
                json: req.body
            });
            break;
        default:
            return res.send("invalid method");
    }
    return req.pipe(r).pipe(res);
});

app.get('/refreshToken', function(req, res) {
   token.refresh().then((data) => {
      res.header({
         "Content-Type": "application/json;charset=UTF-8"
      });
      res.status(200).send(data);
   });
});

app.get('/token', function(req, res) {
   token.value.then((data) => {
      res.header({
         "Content-Type": "application/json;charset=UTF-8"
      });
      res.status(200).send(data);
   });
});

// This doesn't refresh Solr straight away. It simply touches a file and it is up to something else to react to the touch
app.get('/touch', function(req, res) {
   fs.closeSync(fs.openSync(TOUCHPATH, 'w'));
   res.header({
      "Content-Type": "application/json;charset=UTF-8"
   });
   res.status(200).send({status: "success"});
});

app.get('/xml2js/*', function (req, res, next) {
    // look for request like http://localhost:8080/proxy/http://example.com/file?query=1
    var remoteUrl = getRemoteUrlFromParam(req);
    if (!remoteUrl) {
        // look for request like http://localhost:8080/proxy/?http%3A%2F%2Fexample.com%2Ffile%3Fquery%3D1
        remoteUrl = Object.keys(req.query)[0];
        if (remoteUrl) {
            remoteUrl = url.parse(remoteUrl);
        }
    }

    if (!remoteUrl) {
        return res.status(400).send('No url specified.');
    }

    // We only want a very few requests to get through. Via the whitelist.
    var host = remoteUrl.host;
    if (!validHosts.some((valid) => {
        return host.indexOf(valid) > -1;
    })) {
        return res.status(403).send('Not a white listed host. Go away!');
    }

    if (!remoteUrl.protocol) {
        remoteUrl.protocol = 'http:';
    }

    var proxy;
    if (upstreamProxy && !(remoteUrl.host in bypassUpstreamProxyHosts)) {
        proxy = upstreamProxy;
    }

    // encoding : null means "body" passed to the callback will be raw bytes

    request.get({
        url: url.format(remoteUrl),
        headers: filterHeaders(req, req.headers),
        encoding: null,
        proxy: proxy
    }, function (error, response, body) {
        var code = 500;
        var x2js, text, headers, decoder = new StringDecoder('utf8');
        if(error) {
            console.log("Err", error);
        }
        if (body) {
            code = response.statusCode;
            headers = filterHeaders(req, response.headers);
            headers['Content-Type'] = 'application/json';
            res.header(headers);
            text = body.toString();
            x2js = new X2JS();
            res.status(code).send(x2js.xml2js(body.toString()));
        } else {
            console.log("No body!")
            res.status(code).send('{"error":{"code": ' + code + '}}');
        }
    });
});

app.get('/gazetteer/json', function (req, res, next) {
   console.log(JSON.stringify(req.params));
   let id = req.param("id");

   let mapper = mappers.findById(id);

   let url = mapper.createPath(id);

    request.get({
        url: url,
        headers: filterHeaders(req, req.headers),
        encoding: null
    }, function (error, response, body) {
        var code = response.statusCode;
        var x2js, text, headers, decoder = new StringDecoder('utf8');
        if(error) {
            console.log("Err", error);
        }
        if (code === 200) {
            headers = filterHeaders(req, response.headers);
            headers['Content-Type'] = 'application/json';
            res.header(headers);
            text = body.toString();
            x2js = new X2JS();
            res.status(code).send(mapper.transform(x2js.xml2js(text)));
        } else {
            console.log("No body!")
            res.status(code).send('{"error":{"code": ' + code + '}}');
        }
    });
});

app.get('/gazetteer/wfs', function (req, res, next) {
   let id = req.param("id");
   let mapper = mappers.findById(id);

   let url = mapper.createPath(id);

    request.get({
        url: url,
        headers: filterHeaders(req, req.headers),
        encoding: null
    }, function (error, response, body) {
        var code = 500;
        var text, headers, decoder = new StringDecoder('utf8');
        if(error) {
            console.log("Err", error);
        }
        if (body) {
            code = response.statusCode;
            headers = filterHeaders(req, response.headers);
            headers['Content-Type'] = 'application/xml';
            res.header(headers);
            text = body.toString();
            res.status(code).send(text);
        } else {
            console.log("No body!")
            res.status(code).send('{"error":{"code": ' + code + '}}');
        }
    });
});

app.get('/select', function (req, res, next) {
    //var solrSelect = "http://localhost:8983/solr/placenames";
    var solrSelect = "http://192.168.0.24:8983/solr/placenames";

    // encoding : null means "body" passed to the callback will be raw bytes
    request.get(solrSelect + req.url, function (error, response, body) {
        var code = 500;

        if (response) {
            code = response.statusCode;
            res.header(filterHeaders(req, response.headers));
        }

        res.status(code).send(body);
    });
});

app.get('/proxy/*', function (req, res, next) {
    // look for request like http://localhost:8080/proxy/http://example.com/file?query=1

    var remoteUrl = getRemoteUrlFromParam(req);
    if (!remoteUrl) {
        // look for request like http://localhost:8080/proxy/?http%3A%2F%2Fexample.com%2Ffile%3Fquery%3D1
        remoteUrl = Object.keys(req.query)[0];
        if (remoteUrl) {
            remoteUrl = url.parse(remoteUrl);
        }
    }

    if (!remoteUrl) {
        return res.status(400).send('No url specified.');
    }

    // We only want a very few requests to get through. Via the whitelist.
    var host = remoteUrl.host;
    if (!validHosts.some((valid) => {
        return host.indexOf(valid) > -1;
    })) {
        return res.status(403).send('Not a white listed host. Go away!');
    }

    if (!remoteUrl.protocol) {
        remoteUrl.protocol = 'http:';
    }

    var proxy;
    if (upstreamProxy && !(remoteUrl.host in bypassUpstreamProxyHosts)) {
        proxy = upstreamProxy;
    }

    // encoding : null means "body" passed to the callback will be raw bytes

    request.get({
        url: url.format(remoteUrl),
        headers: filterHeaders(req, req.headers),
        encoding: null,
        proxy: proxy
    }, function (error, response, body) {
        var code = 500;

        if (response) {
            code = response.statusCode;
            res.header(filterHeaders(req, response.headers));
        }

        res.status(code).send(body);
    });
});

app.listen(port, function (err) {
    console.log("running server on port " + port);
});

function getRemoteUrlFromParam(req) {
    var remoteUrl = req.params[0];
    if (remoteUrl) {
        // add http:// to the URL if no protocol is present
        if (!/^https?:\/\//.test(remoteUrl)) {
            remoteUrl = 'http://' + remoteUrl;
        }
        remoteUrl = url.parse(remoteUrl);
        // copy query string
        remoteUrl.search = url.parse(req.url).search;
    }
    return remoteUrl;
}

function filterHeaders(req, headers) {
    var result = {};
    // filter out headers that are listed in the regex above
    Object.keys(headers).forEach(function (name) {
        if (!dontProxyHeaderRegex.test(name)) {
            result[name] = headers[name];
        }
    });
    return result;
}<commit_msg>Add require for os<commit_after>
process.env.NO_PROXY = "localhost";

var SERVICES_ROOT = "http://www.ga.gov.au/explorer-web";
var NSW_METADATA_TEMPLATE = "https://s3-ap-southeast-2.amazonaws.com/nsw.elvis/z5${zone}/Metadata/";

var START_ABSTRACT_SENTINEL = "
Abstract:
";
var START_ABSTRACT_SENTINEL_LENGTH = START_ABSTRACT_SENTINEL.length;
var END_ABSTRACT_SENTINEL = "
";
var TOUCHPATH = os.homedir() + "touched/touched";

var config = require("./lib/config");
var express = require("express");
var fs = require("fs");
var os = require('os');
var request = require('request');
var mappers = require("./lib/mapper-picker");

// For positioning. We need a token
var Token = require("./lib/token");
var token = new Token(config.fmeToken);

request.gzip = false;

//var httpProxy = require('http-proxy');
var app = express();
var url = require('url');
var X2JS = require('x2js');

var StringDecoder = require('string_decoder').StringDecoder;
var yargs = require('yargs').options({
    'port': {
        'default': 3000,
        'description': 'Port to listen on.'
    },
    'public': {
        'type': 'boolean',
        'description': 'Run a public server that listens on all interfaces.'
    },
    'upstream-proxy': {
        'description': 'A standard proxy server that will be used to retrieve data.  Specify a URL including port, e.g. "http://proxy:8000".'
    },
    'bypass-upstream-proxy-hosts': {
        'description': 'A comma separated list of hosts that will bypass the specified upstream_proxy, e.g. "lanhost1,lanhost2"'
    },
    'help': {
        'alias': 'h',
        'type': 'boolean',
        'description': 'Show this help.'
    }
});
var argv = yargs.argv;
var port = process.env.PORT || argv.port;
var dontProxyHeaderRegex = /^(?:Host|Proxy-Connection|Accept-Encoding|Connection|Keep-Alive|Transfer-Encoding|TE|Trailer|Proxy-Authorization|Proxy-Authenticate|Upgrade)$/i;
// There should only ever be a couple. We do a contains on the requested host.
var validHosts = config.validHosts;
var upstreamProxy = argv['upstream-proxy'];

// eventually this mime type configuration will need to change
// https://github.com/visionmedia/send/commit/d2cb54658ce65948b0ed6e5fb5de69d022bef941
var mime = express.static.mime;
mime.define({
    'application/json': ['czml', 'json', 'geojson', 'topojson'],
    'model/vnd.gltf+json': ['gltf'],
    'model/vnd.gltf.binary': ['bgltf'],
    'text/plain': ['glsl']
});

// serve static files
app.use(express.static("dist"));
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.all('/service/*', function (req, res, next) {
    var method, r;

    method = req.method.toLowerCase();

    console.log("URL: " + method + " " + SERVICES_ROOT + req.url);

    switch (method) {
        case "get":
            r = request.get({
                uri: SERVICES_ROOT + req.url,
                json: req.body
            });
            break;
        case "put":
            r = request.put({
                uri: SERVICES_ROOT + req.url,
                json: req.body
            });
            break;
        case "post":
            r = request.post({
                uri: SERVICES_ROOT + req.url,
                json: req.body
            });
            break;
        case "delete":
            r = request.del({
                uri: SERVICES_ROOT + req.url,
                json: req.body
            });
            break;
        default:
            return res.send("invalid method");
    }
    return req.pipe(r).pipe(res);
});

app.get('/refreshToken', function(req, res) {
   token.refresh().then((data) => {
      res.header({
         "Content-Type": "application/json;charset=UTF-8"
      });
      res.status(200).send(data);
   });
});

app.get('/token', function(req, res) {
   token.value.then((data) => {
      res.header({
         "Content-Type": "application/json;charset=UTF-8"
      });
      res.status(200).send(data);
   });
});

// This doesn't refresh Solr straight away. It simply touches a file and it is up to something else to react to the touch
app.get('/touch', function(req, res) {
   fs.closeSync(fs.openSync(TOUCHPATH, 'w'));
   res.header({
      "Content-Type": "application/json;charset=UTF-8"
   });
   res.status(200).send({status: "success"});
});

app.get('/xml2js/*', function (req, res, next) {
    // look for request like http://localhost:8080/proxy/http://example.com/file?query=1
    var remoteUrl = getRemoteUrlFromParam(req);
    if (!remoteUrl) {
        // look for request like http://localhost:8080/proxy/?http%3A%2F%2Fexample.com%2Ffile%3Fquery%3D1
        remoteUrl = Object.keys(req.query)[0];
        if (remoteUrl) {
            remoteUrl = url.parse(remoteUrl);
        }
    }

    if (!remoteUrl) {
        return res.status(400).send('No url specified.');
    }

    // We only want a very few requests to get through. Via the whitelist.
    var host = remoteUrl.host;
    if (!validHosts.some((valid) => {
        return host.indexOf(valid) > -1;
    })) {
        return res.status(403).send('Not a white listed host. Go away!');
    }

    if (!remoteUrl.protocol) {
        remoteUrl.protocol = 'http:';
    }

    var proxy;
    if (upstreamProxy && !(remoteUrl.host in bypassUpstreamProxyHosts)) {
        proxy = upstreamProxy;
    }

    // encoding : null means "body" passed to the callback will be raw bytes

    request.get({
        url: url.format(remoteUrl),
        headers: filterHeaders(req, req.headers),
        encoding: null,
        proxy: proxy
    }, function (error, response, body) {
        var code = 500;
        var x2js, text, headers, decoder = new StringDecoder('utf8');
        if(error) {
            console.log("Err", error);
        }
        if (body) {
            code = response.statusCode;
            headers = filterHeaders(req, response.headers);
            headers['Content-Type'] = 'application/json';
            res.header(headers);
            text = body.toString();
            x2js = new X2JS();
            res.status(code).send(x2js.xml2js(body.toString()));
        } else {
            console.log("No body!")
            res.status(code).send('{"error":{"code": ' + code + '}}');
        }
    });
});

app.get('/gazetteer/json', function (req, res, next) {
   console.log(JSON.stringify(req.params));
   let id = req.param("id");

   let mapper = mappers.findById(id);

   let url = mapper.createPath(id);

    request.get({
        url: url,
        headers: filterHeaders(req, req.headers),
        encoding: null
    }, function (error, response, body) {
        var code = response.statusCode;
        var x2js, text, headers, decoder = new StringDecoder('utf8');
        if(error) {
            console.log("Err", error);
        }
        if (code === 200) {
            headers = filterHeaders(req, response.headers);
            headers['Content-Type'] = 'application/json';
            res.header(headers);
            text = body.toString();
            x2js = new X2JS();
            res.status(code).send(mapper.transform(x2js.xml2js(text)));
        } else {
            console.log("No body!")
            res.status(code).send('{"error":{"code": ' + code + '}}');
        }
    });
});

app.get('/gazetteer/wfs', function (req, res, next) {
   let id = req.param("id");
   let mapper = mappers.findById(id);

   let url = mapper.createPath(id);

    request.get({
        url: url,
        headers: filterHeaders(req, req.headers),
        encoding: null
    }, function (error, response, body) {
        var code = 500;
        var text, headers, decoder = new StringDecoder('utf8');
        if(error) {
            console.log("Err", error);
        }
        if (body) {
            code = response.statusCode;
            headers = filterHeaders(req, response.headers);
            headers['Content-Type'] = 'application/xml';
            res.header(headers);
            text = body.toString();
            res.status(code).send(text);
        } else {
            console.log("No body!")
            res.status(code).send('{"error":{"code": ' + code + '}}');
        }
    });
});

app.get('/select', function (req, res, next) {
    //var solrSelect = "http://localhost:8983/solr/placenames";
    var solrSelect = "http://192.168.0.24:8983/solr/placenames";

    // encoding : null means "body" passed to the callback will be raw bytes
    request.get(solrSelect + req.url, function (error, response, body) {
        var code = 500;

        if (response) {
            code = response.statusCode;
            res.header(filterHeaders(req, response.headers));
        }

        res.status(code).send(body);
    });
});

app.get('/proxy/*', function (req, res, next) {
    // look for request like http://localhost:8080/proxy/http://example.com/file?query=1

    var remoteUrl = getRemoteUrlFromParam(req);
    if (!remoteUrl) {
        // look for request like http://localhost:8080/proxy/?http%3A%2F%2Fexample.com%2Ffile%3Fquery%3D1
        remoteUrl = Object.keys(req.query)[0];
        if (remoteUrl) {
            remoteUrl = url.parse(remoteUrl);
        }
    }

    if (!remoteUrl) {
        return res.status(400).send('No url specified.');
    }

    // We only want a very few requests to get through. Via the whitelist.
    var host = remoteUrl.host;
    if (!validHosts.some((valid) => {
        return host.indexOf(valid) > -1;
    })) {
        return res.status(403).send('Not a white listed host. Go away!');
    }

    if (!remoteUrl.protocol) {
        remoteUrl.protocol = 'http:';
    }

    var proxy;
    if (upstreamProxy && !(remoteUrl.host in bypassUpstreamProxyHosts)) {
        proxy = upstreamProxy;
    }

    // encoding : null means "body" passed to the callback will be raw bytes

    request.get({
        url: url.format(remoteUrl),
        headers: filterHeaders(req, req.headers),
        encoding: null,
        proxy: proxy
    }, function (error, response, body) {
        var code = 500;

        if (response) {
            code = response.statusCode;
            res.header(filterHeaders(req, response.headers));
        }

        res.status(code).send(body);
    });
});

app.listen(port, function (err) {
    console.log("running server on port " + port);
});

function getRemoteUrlFromParam(req) {
    var remoteUrl = req.params[0];
    if (remoteUrl) {
        // add http:// to the URL if no protocol is present
        if (!/^https?:\/\//.test(remoteUrl)) {
            remoteUrl = 'http://' + remoteUrl;
        }
        remoteUrl = url.parse(remoteUrl);
        // copy query string
        remoteUrl.search = url.parse(req.url).search;
    }
    return remoteUrl;
}

function filterHeaders(req, headers) {
    var result = {};
    // filter out headers that are listed in the regex above
    Object.keys(headers).forEach(function (name) {
        if (!dontProxyHeaderRegex.test(name)) {
            result[name] = headers[name];
        }
    });
    return result;
}<|endoftext|>