<commit_before>var app = require('express')();
var http = require('http').Server(app);
var express = require('express');
var io = require('socket.io')(http);
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//var redirect = require('express-redirect');

//redirect(app);
app.use(express.static(__dirname + '/public'));

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

app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());

var un = 0;
var g = {
	complete:false
};

app.get('/game/:gameId/player/:playerN',function(req,res){
	if(g.complete)
		res.redirect('/');
	if(un===2)
		g.complete = true;
	if(req.params.playerN > 2){
		res.sendStatus(403);
	}else{
		res.render('game');
	}
	io.on('connection', function(socket){
		//console.log(rooms);
		socket.join(req.params.gameId);
		console.log(io.sockets.adapter.rooms);
		console.log('------------CONNECTION------------');
		socket.on('moved'+req.params.gameId,function(m){
			io.to(req.params.gameId).emit('move'+req.params.gameId,m);
		});
		// FOR CHECKMATE
		socket.on('cm'+req.params.gameId,function(m){
			io.to(req.params.gameId).emit('checkMate'+req.params.gameId,m);
		});
		socket.on('disconnect',function(){
		console.log(io.sockets.adapter.rooms);
		console.log('------------DISCONNECTION------------');

			//console.log(rooms);
			//console.log(rooms);
			console.log(socket.id);
			io.to(req.params.gameId).emit('dcnt'+req.params.gameId,'I left');
		});
		socket.on('user_disconnected'+req.params.gameId,function(m){
			socket.leave(req.params.gameId);
			deleteElement(req.params.gameId);
			//console.log('Disconecting from: '+req.params.gameId);
		});

	});

});

app.get('/',function(req,res){
	//res.sendFile(__dirname+'/index.html');
	res.render('index',{id:'my id 33333'});
});

var rooms = [];

var entrance = function(id){
	for(i in rooms){
		if(id === rooms[i].id){
			if(rooms[i].un!==2){
				rooms[i].un = rooms[i].un + 1;
				return [true,rooms[i].un];
			}else{
				return [false];
			}
		}
	}
	rooms.push({id:id,un:1});
	return [true,1];
}

var deleteElement = function(query){
	var oldObject = rooms;
	rooms = [];
	for(var i = 0; i < oldObject.lenght ;i++){
		if(oldObject[i].id!==query){
			cosnole.log(oldObject[i]);
			rooms.push(oldObject[i]);
		}
	}
};

app.post('/validation',function(req,res){
	//res.redirect('/game/:gameId');

	var watchman = entrance(req.body.idName);

	if(!watchman[0]){
		res.sendStatus(403);
	}else{
		res.redirect('/game/'+req.body.idName+'/player/'+watchman[1]);
	}

});

app.post('/disconnection',function(req,res){
	res.redirect('/');
});

http.listen(process.env.PORT || 5000);

/*http.listen(3000, function(){
	console.log('listening on 3000');
});*/
<commit_msg>fixing disconnections<commit_after>var app = require('express')();
var http = require('http').Server(app);
var express = require('express');
var io = require('socket.io')(http);
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//var redirect = require('express-redirect');

//redirect(app);
app.use(express.static(__dirname + '/public'));

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

app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());

var un = 0;
var g = {
	complete:false
};

var loginR = function(player,room){
	for(var i in rooms){
		if(rooms[i].id === room){
			//console.log('room id: '+room);
			//console.log(rooms[i].id + ' = ' + room);
			if(rooms[i].players.length <= 1){
				rooms[i].players.push(player);
			}
			return;
		}
	}
}

var roomName = function(query){
	for(var i in rooms){
		for(var j in rooms[i].players){
			if(rooms[i].players[j]===query){
				return rooms[i].id;
			}
		}
	}
}

var isConnected = function(player){
	for(var i in rooms){
		for(var j in rooms[i].players){
			if(rooms[i].players[j] === player){
				console.log('already connected');
				return true;
			}
		}
	}
	return false;
}

app.get('/game/:gameId/player/:playerN',function(req,res){
	if(g.complete)
		res.redirect('/');
	if(un===2)
		g.complete = true;
	if(req.params.playerN > 2){
		res.sendStatus(403);
	}else{
		res.render('game');
	}
	io.on('connection', function(socket){
		console.log(socket.id);
		if(!isConnected(socket.id)){
			loginR(socket.id,req.params.gameId);
		//console.log(rooms);
//			console.log(rooms);
			socket.join(req.params.gameId);
		}
		//console.log(rooms);
//		console.log(io.sockets.adapter.rooms);
//		console.log('------------CONNECTION------------');
		socket.on('moved'+req.params.gameId,function(m){
			io.to(req.params.gameId).emit('move'+req.params.gameId,m);
		});
		// FOR CHECKMATE
		socket.on('cm'+req.params.gameId,function(m){
			io.to(req.params.gameId).emit('checkMate'+req.params.gameId,m);
		});
		socket.on('disconnect',function(){
		//console.log(io.sockets.adapter.rooms);
			//console.log('------------DISCONNECTION------------');

			//console.log(rooms);
			//console.log(rooms);
			//console.log(socket.id);
			//io.to(req.params.gameId).emit('dcnt'+req.params.gameId,'I left');
		});
		socket.on('user_disconnected'+req.params.gameId,function(m){
			//socket.leave(req.params.gameId);
			//deleteElement(req.params.gameId);
			//console.log('Disconecting from: '+req.params.gameId);
		});

	});

});

app.get('/',function(req,res){
	//res.sendFile(__dirname+'/index.html');
	res.render('index',{id:'my id 33333'});
});

var rooms = [];

var entrance = function(id){
	for(i in rooms){
		if(id === rooms[i].id){
			if(rooms[i].un!==2){
				rooms[i].un = rooms[i].un + 1;
				return [true,rooms[i].un];
			}else{
				return [false];
			}
		}
	}
	rooms.push({id:id,un:1,players:[]});
	return [true,1];
}

var deleteElement = function(query){
	var oldObject = rooms;
	rooms = [];
	for(var i = 0; i < oldObject.lenght ;i++){
		if(oldObject[i].id!==query){
			cosnole.log(oldObject[i]);
			rooms.push(oldObject[i]);
		}
	}
};

app.post('/validation',function(req,res){
	//res.redirect('/game/:gameId');

	var watchman = entrance(req.body.idName);

	if(!watchman[0]){
		res.sendStatus(403);
	}else{
		res.redirect('/game/'+req.body.idName+'/player/'+watchman[1]);
	}

});

app.post('/disconnection',function(req,res){
	res.redirect('/');
});

http.listen(process.env.PORT || 5000);

/*http.listen(3000, function(){
	console.log('listening on 3000');
});*/
<|endoftext|>


<commit_before>var mkdirp = require('mkdirp');
var url = require('url');
var fs = require('fs');
var ffmpeg = require('fluent-ffmpeg');
var creds = require(process.env.HOME + '/.spotifyCreds.json');

var spotifyBackend = {};
spotifyBackend.spotify = require('node-spotify')({
    appkeyFile: process.env.HOME + '/.spotify_appkey.key'
});

var config, player;

// TODO: seeking
var encodeSong = function(origStream, seek, songID, callback, errCallback) {
    var incompletePath = config.songCachePath + '/spotify/incomplete/' + songID + '.opus';
    var encodedPath = config.songCachePath + '/spotify/' + songID + '.opus';

    var command = ffmpeg(origStream)
        .noVideo()
        .inputFormat('s16le')
        .inputOption('-ac 2')
        .audioCodec('libopus')
        .audioBitrate('192')
        .on('end', function() {
            console.log('successfully transcoded ' + songID);

            // atomically (I hope so) move result to encodedPath
            fs.renameSync(incompletePath, encodedPath);
            callback();
        })
    .on('error', function(err) {
        console.log('spotify: error while transcoding ' + songID + ': ' + err);
        if(fs.existsSync(incompletePath))
            fs.unlinkSync(incompletePath);
        errCallback();
    })
    .save(incompletePath);

    console.log('transcoding ' + songID + '...');
    return function(err) {
        command.kill();
        console.log('spotify: canceled preparing: ' + songID + ': ' + err);
        if(fs.existsSync(incompletePath))
            fs.unlinkSync(incompletePath);
        errCallback();
    };
};

var spotifyDownload = function(songID, callback, errCallback) {
    var track = spotifyBackend.spotify.createFromLink(songID);
    var cancelCallback;

    var stream = require('stream');
    var bufStream = new stream.PassThrough();

    var audioHandler = function(err, buffer) {
        if(err) {
            console.log('error from spotify audioHandler' + err);
            cancelCallback();
            errCallback(err);
        } else {
            bufStream.push(buffer);
            return true;
        }
    };
    spotifyBackend.spotify.useNodejsAudio(audioHandler);
    spotifyBackend.spotify.player.play(track);
    spotifyBackend.spotify.player.on({'endOfTrack': function() {
        bufStream.end();
    }});

    cancelCallback = encodeSong(bufStream, 0, songID, callback, errCallback);
    return cancelCallback;
};

// cache songID to disk.
// on success: callback must be called
// on failure: errCallback must be called with error message
spotifyBackend.prepareSong = function(songID, callback, errCallback) {
    var filePath = config.songCachePath + '/spotify/' + songID + '.opus';

    if(fs.existsSync(filePath)) {
        // song was found from cache
        if(callback)
            callback();
        return;
    } else {
        return spotifyDownload(songID, callback, errCallback);
    }
};
spotifyBackend.search = function(query, callback, errCallback) {
    var results = {};
    results.songs = {};

    var offset = 0;
    var search = new spotifyBackend.spotify.Search(query.terms, offset, config.searchResultCnt);
    search.execute(function(err, searchResult) {
        if(err) {
            errCallback('error while searching spotify: ' + err);
        } else {
            for(var i = 0; i < searchResult.numTracks; i++) {
                var track = searchResult.getTrack(i);
                results.songs[track.link] = {
                    artist: track.artists ? track.artists[0].name : null,
                    title: track.name,
                    album: track.album ? track.album.name : null,
                    albumArt: null, // TODO
                    duration: track.duration * 1000,
                    songID: track.link,
                    score: track.popularity,
                    backendName: 'spotify',
                    format: 'opus'
                };
            }

            callback(results);
        }
    });
};

spotifyBackend.init = function(_player, callback, errCallback) {
    player = _player;
    config = _player.config;

    mkdirp(config.songCachePath + '/spotify/incomplete');

    // initialize google play music backend
    spotifyBackend.spotify.on({
        ready: callback,
        logout: errCallback
    });
    spotifyBackend.spotify.login(creds.login, creds.password, false, false);
};
module.exports = spotifyBackend;
<commit_msg>set backend.name<commit_after>var mkdirp = require('mkdirp');
var url = require('url');
var fs = require('fs');
var ffmpeg = require('fluent-ffmpeg');
var creds = require(process.env.HOME + '/.spotifyCreds.json');

var spotifyBackend = {};
spotifyBackend.name = 'spotify';
spotifyBackend.spotify = require('node-spotify')({
    appkeyFile: process.env.HOME + '/.spotify_appkey.key'
});

var config, player;

// TODO: seeking
var encodeSong = function(origStream, seek, songID, callback, errCallback) {
    var incompletePath = config.songCachePath + '/spotify/incomplete/' + songID + '.opus';
    var encodedPath = config.songCachePath + '/spotify/' + songID + '.opus';

    var command = ffmpeg(origStream)
        .noVideo()
        .inputFormat('s16le')
        .inputOption('-ac 2')
        .audioCodec('libopus')
        .audioBitrate('192')
        .on('end', function() {
            console.log('successfully transcoded ' + songID);

            // atomically (I hope so) move result to encodedPath
            fs.renameSync(incompletePath, encodedPath);
            callback();
        })
    .on('error', function(err) {
        console.log('spotify: error while transcoding ' + songID + ': ' + err);
        if(fs.existsSync(incompletePath))
            fs.unlinkSync(incompletePath);
        errCallback();
    })
    .save(incompletePath);

    console.log('transcoding ' + songID + '...');
    return function(err) {
        command.kill();
        console.log('spotify: canceled preparing: ' + songID + ': ' + err);
        if(fs.existsSync(incompletePath))
            fs.unlinkSync(incompletePath);
        errCallback();
    };
};

var spotifyDownload = function(songID, callback, errCallback) {
    var track = spotifyBackend.spotify.createFromLink(songID);
    var cancelCallback;

    var stream = require('stream');
    var bufStream = new stream.PassThrough();

    var audioHandler = function(err, buffer) {
        if(err) {
            console.log('error from spotify audioHandler' + err);
            cancelCallback();
            errCallback(err);
        } else {
            bufStream.push(buffer);
            return true;
        }
    };
    spotifyBackend.spotify.useNodejsAudio(audioHandler);
    spotifyBackend.spotify.player.play(track);
    spotifyBackend.spotify.player.on({'endOfTrack': function() {
        bufStream.end();
    }});

    cancelCallback = encodeSong(bufStream, 0, songID, callback, errCallback);
    return cancelCallback;
};

// cache songID to disk.
// on success: callback must be called
// on failure: errCallback must be called with error message
spotifyBackend.prepareSong = function(songID, callback, errCallback) {
    var filePath = config.songCachePath + '/spotify/' + songID + '.opus';

    if(fs.existsSync(filePath)) {
        // song was found from cache
        if(callback)
            callback();
        return;
    } else {
        return spotifyDownload(songID, callback, errCallback);
    }
};
spotifyBackend.search = function(query, callback, errCallback) {
    var results = {};
    results.songs = {};

    var offset = 0;
    var search = new spotifyBackend.spotify.Search(query.terms, offset, config.searchResultCnt);
    search.execute(function(err, searchResult) {
        if(err) {
            errCallback('error while searching spotify: ' + err);
        } else {
            for(var i = 0; i < searchResult.numTracks; i++) {
                var track = searchResult.getTrack(i);
                results.songs[track.link] = {
                    artist: track.artists ? track.artists[0].name : null,
                    title: track.name,
                    album: track.album ? track.album.name : null,
                    albumArt: null, // TODO
                    duration: track.duration * 1000,
                    songID: track.link,
                    score: track.popularity,
                    backendName: spotifyBackend.name,
                    format: 'opus'
                };
            }

            callback(results);
        }
    });
};

spotifyBackend.init = function(_player, callback, errCallback) {
    player = _player;
    config = _player.config;

    mkdirp(config.songCachePath + '/spotify/incomplete');

    // initialize google play music backend
    spotifyBackend.spotify.on({
        ready: callback,
        logout: errCallback
    });
    spotifyBackend.spotify.login(creds.login, creds.password, false, false);
};
module.exports = spotifyBackend;
<|endoftext|>


<commit_before>'use strict';
var fs = require('fs');
var path = require('path');
var Readable = require('stream').Readable;
var glob = require('glob');
var dargs = require('dargs');
var slash = require('slash');
var mkdirp = require('mkdirp');
var rimraf = require('rimraf');
var md5Hex = require('md5-hex');
var spawn = require('win-spawn');
var gutil = require('gulp-util');
var assign = require('object-assign');
var convert = require('convert-source-map');
var eachAsync = require('each-async');
var osTmpdir = require('os-tmpdir');
var pathExists = require('path-exists');

var logger = require('./logger');

function emitErr (stream, err) {
	stream.emit('error', new gutil.PluginError('gulp-ruby-sass', err));
}

// for now, source is only a single directory or a single file
function gulpRubySass (source, options) {
	var stream = new Readable({objectMode: true});
	var cwd = process.cwd();
	var defaults = {
		tempDir: osTmpdir(),
		verbose: false,
		sourcemap: false,
		emitCompileError: false
	};
	var command;
	var args;
	var base;
	var intermediateDir;
	var dest;
	var compileMappings;

	// redundant but necessary
	stream._read = function () {};

	options = assign(defaults, options);

	// sourcemap can only be true or false; warn those trying to pass a Sass string option
	if (typeof options.sourcemap !== 'boolean') {
		throw new Error('The sourcemap option must be true or false. See the readme for instructions on using Sass sourcemaps with gulp.');
	}

	// deprecation message for `container`.
	if (options.container) {
		gutil.log(gutil.colors.yellow(
			'The container option has been deprecated. Simultanious tasks work automatically now!\n' +
		  'This will become an error in gulp-ruby-sass 2.0'
	  ));
	}

	// reassign options.sourcemap boolean to one of our two acceptable Sass arguments
	options.sourcemap = options.sourcemap === true ? 'file' : 'none';

	// create temporary directory path for the task using current working
	// directory, source and options
	// sass options need unix style slashes
	intermediateDir = slash(path.join(
		options.tempDir,
		'gulp-ruby-sass-' + md5Hex(process.cwd()) + md5Hex(source + JSON.stringify(options))
	));

	// directory source
	if (path.extname(source) === '') {
		base = path.join(cwd, source);
		compileMappings = source + ':' + intermediateDir;
		options.update = true;
	}
	// single file source
	else {
		base = path.join(cwd, path.dirname(source));

		// sass options need unix style slashes
		dest = slash(path.join(
			intermediateDir,
			gutil.replaceExtension(path.basename(source), '.css')
		));

		compileMappings = [ source, dest ];

		// sass's single file compilation doesn't create a destination directory, so
		// we have to ourselves
		mkdirp(intermediateDir);
	}
	// TODO: implement glob file source

	args = dargs(options, [
		'bundleExec',
		'watch',
		'poll',
		'tempDir',
		'verbose',
		'emitCompileError',
		'container'
	]).concat(compileMappings);

	if (options.bundleExec) {
		command = 'bundle';
		args.unshift('exec', 'sass');
	} else {
		command = 'sass';
	}

	// plugin logging
	if (options.verbose) {
		logger.verbose(command, args);
	}

	var sass = spawn(command, args);

	sass.stdout.setEncoding('utf8');
	sass.stderr.setEncoding('utf8');

	sass.stdout.on('data', function (data) {
		logger.stdout(data, intermediateDir, stream);
	});

	sass.stderr.on('data', function (data) {
		logger.stderr(data, intermediateDir, stream);
	});

	sass.on('error', function (err) {
		logger.error(err, stream);
	});

	sass.on('close', function (code) {
		if (options.emitCompileError && code !== 0) {
			emitErr(stream, 'Sass compilation failed. See console output for more information.');
		}

		glob(path.join(intermediateDir, '**', '*'), function (err, files) {
			if (err) {
				emitErr(stream, err);
			}

			eachAsync(files, function (file, i, next) {
				if (fs.statSync(file).isDirectory() || path.extname(file) === '.map') {
					next();
					return;
				}

				fs.readFile(file, function (err, data) {
					if (err) {
						emitErr(stream, err);
						next();
						return;
					}

					// rewrite file paths so gulp thinks the files came from cwd, not the
					// OS temp directory
					var vinylFile = new gutil.File({
						cwd: cwd,
						base: base,
						path: file.replace(intermediateDir, base)
					});
					var sourcemap;

					// if we are managing sourcemaps and the sourcemap exists
					if (options.sourcemap === 'file' && pathExists.sync(file + '.map')) {
						// remove Sass sourcemap comment; gulp-sourcemaps will add it back in
						data = new Buffer( convert.removeMapFileComments(data.toString()) );
						sourcemap = JSON.parse(fs.readFileSync(file + '.map', 'utf8'));

						// create relative paths for sources
						sourcemap.sources = sourcemap.sources.map(function (sourcemapSource) {
							var absoluteSourcePath = decodeURI(path.resolve('/', sourcemapSource.replace('file:///', '')))
							return path.relative(base, absoluteSourcePath);
						});

						vinylFile.sourceMap = sourcemap;
					}

					vinylFile.contents = data;
					stream.push(vinylFile);
					next();
					return;
				});
			}, function () {
				// cleanup previously generated files for next run
				// TODO: This kills caching. Keeping will push files through that are not in
				// the current gulp.src. We need to decide whether to use a Sass style caching
				// strategy, or a gulp style strategy, and what each would look like.
				rimraf(intermediateDir, function () {
					stream.push(null);
				});
			});
		});
	});

	return stream;
};

gulpRubySass.logError = function logError(err) {
  var message = new gutil.PluginError('gulp-ruby-sass', err);
  process.stderr.write(message + '\n');
  this.emit('end');
};

module.exports = gulpRubySass
<commit_msg>Remove redundant comment<commit_after>'use strict';
var fs = require('fs');
var path = require('path');
var Readable = require('stream').Readable;
var glob = require('glob');
var dargs = require('dargs');
var slash = require('slash');
var mkdirp = require('mkdirp');
var rimraf = require('rimraf');
var md5Hex = require('md5-hex');
var spawn = require('win-spawn');
var gutil = require('gulp-util');
var assign = require('object-assign');
var convert = require('convert-source-map');
var eachAsync = require('each-async');
var osTmpdir = require('os-tmpdir');
var pathExists = require('path-exists');

var logger = require('./logger');

function emitErr (stream, err) {
	stream.emit('error', new gutil.PluginError('gulp-ruby-sass', err));
}

function gulpRubySass (source, options) {
	var stream = new Readable({objectMode: true});
	var cwd = process.cwd();
	var defaults = {
		tempDir: osTmpdir(),
		verbose: false,
		sourcemap: false,
		emitCompileError: false
	};
	var command;
	var args;
	var base;
	var intermediateDir;
	var dest;
	var compileMappings;

	// redundant but necessary
	stream._read = function () {};

	options = assign(defaults, options);

	// sourcemap can only be true or false; warn those trying to pass a Sass string option
	if (typeof options.sourcemap !== 'boolean') {
		throw new Error('The sourcemap option must be true or false. See the readme for instructions on using Sass sourcemaps with gulp.');
	}

	// deprecation message for `container`.
	if (options.container) {
		gutil.log(gutil.colors.yellow(
			'The container option has been deprecated. Simultanious tasks work automatically now!\n' +
		  'This will become an error in gulp-ruby-sass 2.0'
	  ));
	}

	// reassign options.sourcemap boolean to one of our two acceptable Sass arguments
	options.sourcemap = options.sourcemap === true ? 'file' : 'none';

	// create temporary directory path for the task using current working
	// directory, source and options
	// sass options need unix style slashes
	intermediateDir = slash(path.join(
		options.tempDir,
		'gulp-ruby-sass-' + md5Hex(process.cwd()) + md5Hex(source + JSON.stringify(options))
	));

	// directory source
	if (path.extname(source) === '') {
		base = path.join(cwd, source);
		compileMappings = source + ':' + intermediateDir;
		options.update = true;
	}
	// single file source
	else {
		base = path.join(cwd, path.dirname(source));

		// sass options need unix style slashes
		dest = slash(path.join(
			intermediateDir,
			gutil.replaceExtension(path.basename(source), '.css')
		));

		compileMappings = [ source, dest ];

		// sass's single file compilation doesn't create a destination directory, so
		// we have to ourselves
		mkdirp(intermediateDir);
	}
	// TODO: implement glob file source

	args = dargs(options, [
		'bundleExec',
		'watch',
		'poll',
		'tempDir',
		'verbose',
		'emitCompileError',
		'container'
	]).concat(compileMappings);

	if (options.bundleExec) {
		command = 'bundle';
		args.unshift('exec', 'sass');
	} else {
		command = 'sass';
	}

	// plugin logging
	if (options.verbose) {
		logger.verbose(command, args);
	}

	var sass = spawn(command, args);

	sass.stdout.setEncoding('utf8');
	sass.stderr.setEncoding('utf8');

	sass.stdout.on('data', function (data) {
		logger.stdout(data, intermediateDir, stream);
	});

	sass.stderr.on('data', function (data) {
		logger.stderr(data, intermediateDir, stream);
	});

	sass.on('error', function (err) {
		logger.error(err, stream);
	});

	sass.on('close', function (code) {
		if (options.emitCompileError && code !== 0) {
			emitErr(stream, 'Sass compilation failed. See console output for more information.');
		}

		glob(path.join(intermediateDir, '**', '*'), function (err, files) {
			if (err) {
				emitErr(stream, err);
			}

			eachAsync(files, function (file, i, next) {
				if (fs.statSync(file).isDirectory() || path.extname(file) === '.map') {
					next();
					return;
				}

				fs.readFile(file, function (err, data) {
					if (err) {
						emitErr(stream, err);
						next();
						return;
					}

					// rewrite file paths so gulp thinks the files came from cwd, not the
					// OS temp directory
					var vinylFile = new gutil.File({
						cwd: cwd,
						base: base,
						path: file.replace(intermediateDir, base)
					});
					var sourcemap;

					// if we are managing sourcemaps and the sourcemap exists
					if (options.sourcemap === 'file' && pathExists.sync(file + '.map')) {
						// remove Sass sourcemap comment; gulp-sourcemaps will add it back in
						data = new Buffer( convert.removeMapFileComments(data.toString()) );
						sourcemap = JSON.parse(fs.readFileSync(file + '.map', 'utf8'));

						// create relative paths for sources
						sourcemap.sources = sourcemap.sources.map(function (sourcemapSource) {
							var absoluteSourcePath = decodeURI(path.resolve('/', sourcemapSource.replace('file:///', '')))
							return path.relative(base, absoluteSourcePath);
						});

						vinylFile.sourceMap = sourcemap;
					}

					vinylFile.contents = data;
					stream.push(vinylFile);
					next();
					return;
				});
			}, function () {
				// cleanup previously generated files for next run
				// TODO: This kills caching. Keeping will push files through that are not in
				// the current gulp.src. We need to decide whether to use a Sass style caching
				// strategy, or a gulp style strategy, and what each would look like.
				rimraf(intermediateDir, function () {
					stream.push(null);
				});
			});
		});
	});

	return stream;
};

gulpRubySass.logError = function logError(err) {
  var message = new gutil.PluginError('gulp-ruby-sass', err);
  process.stderr.write(message + '\n');
  this.emit('end');
};

module.exports = gulpRubySass
<|endoftext|>


<commit_before>var Hapi = require('hapi'),
    async = require('async'),
    hostname = 'francesanddavid.com',
    port = 80;

console.dir(process.argv);
if (process.argv[2] === 'localhost') {
    hostname = 'localhost';
}

if (process.argv[3] === '8000') {
    port = 8000;
}

var server = new Hapi.Server();
server.connection({
    host: hostname,
    port: port
});

server.route({
    path: "/",
    method: "GET",
    handler: {
        view: {
            template: 'index',
            context: {
                title: 'Frances and David dot com'
            }
        }
    }
});

//program route
server.route({
    path: "/program",
    method: "GET",
    handler: {
        view: {
            template: 'program',
            context: {
                title: 'Frances and David\'s wedding program'
            }
        }
    }
});

// Setup views
server.views({
    engines: {
        html: require('handlebars')
    },
    path: './views'
});

// Setup static files
server.route({
    method: 'GET',
    path: '/assets/{param*}',
    handler: {
        directory: {
            path: 'assets'
        }
    }
});

server.start(function() {
    console.log("Hapi server started @", server.info.uri);
});
<commit_msg>Updating index.js with latest<commit_after>'use strict'

const hostname = 'francesanddavid.com';
const port = 80;
const Hapi = require('@hapi/hapi');
const hbs = require('hbs');

const init = async () => {
    const server = Hapi.server({
        port: port,
        host: hostname
    });

    await server.register(require('@hapi/inert'));
    await server.register(require('@hapi/vision'));

    server.views({
        engines: {
            html: hbs
        },
        relativeTo: __dirname,
        path: 'views'
    });

    server.route({
        path: "/",
        method: "GET",
        handler: {
            view: {
                template: 'index',
                context: {
                    title: 'Frances and David dot com'
                }
            }
        }
    });

    //program route
    server.route({
        path: "/program",
        method: "GET",
        handler: {
            view: {
                template: 'program',
                context: {
                    title: 'Frances and David\'s wedding program'
                }
            }
        }
    });

    // Setup static files
    server.route({
        method: 'GET',
        path: '/assets/{param*}',
        handler: {
            directory: {
                path: 'assets'
            }
        }
    });
    await server.start()
    console.log("Hapi server started @", server.info.uri);
};

process.on('unhandledRejection', (err) => {
        console.log(err);
        process.exit(1);
});

init();
<|endoftext|>


<commit_before>const validator = require('email-validator');

const validators = {
	v: {
		required: true,
		// termPattern: /^v$/,
		description: 'Protocol version',
		validate(term, value) {
			if (value !== 'DMARC1') {
				throw new Error(`Invalid DMARC version: '${value}'`);
			}
		}
	},
	fo: {
		// termPattern: /^fo$/,
		description: 'Forensic reporting options. Possible values: "0" to generate reports if all underlying authentication mechanisms fail to produce a DMARC pass result, "1" to generate reports if any mechanisms fail, "d" to generate report if DKIM signature failed to verify, "s" if SPF failed.',
		validate(term, value) {
			if (!/^([01ds])$/.test(value)) {
				throw new Error(`Invalid value for '${term}': '${value}', must be one of: 0, 1, d, s`);
			}
		}
	},
	p: {
		description: 'Policy to apply to email that fails the DMARC check. Can be "none", "quarantine", or "reject". "none" is used to collect feedback and gain visibility into email streams without impacting existing flows.',
		validate(term, value) {
			if (!/^(none|quarantine|reject)$/.test(value)) {
				throw new Error(`Invalid value for '${term}': '${value}', must be one of: none, quarantine, reject`);
			}
		}
	},
	pct: {
		description: `Percentage of messages from the Domain Owner's mail stream to which the DMARC policy is to be applied.`,
		validate(term, value) {
			if (!/^\d+$/.test(value)) {
				throw new Error(`Invalid value for '${term}': ${value}, must be a positive integer`);
			}
			else if (parseInt(value, 10) > 100 || parseInt(value, 10) < 0) {
				throw new Error(`Invalid value for '${term}': ${value}, must be an integer between 0 and 100`);
			}
		}
	},
	rf: {
		description: `Format to be used for message-specific failure reports (colon-separated plain-text list of values)`,
		validate(term, value) {
			// The RFC says the values are colon-separated but a lot of examples/docs around the net show commas... so we'll do both
			let values = value.split(/,|:/).map(x => x.trim());

			for (let val of values) {
				if (!/^(afrf|iodef)$/.test(val)) {
					throw new Error(`Invalid value for '${term}': '${value}', must be one or more of these values: afrf, iodef. Multiple values must be separated by a comma or colon`);
				}
			}
		}
	},
	ri: {
		description: 'Interval (in seconds) requested between aggregate reports (plain-text 32-bit unsigned integer; default is 86400)',
		validate(term, value) {
			if (!/^\d+$/.test(value)) {
				throw new Error(`Invalid value for '${term}': ${value}, must be an unsigned integer`);
			}
		}
	},
	rua: {
		description: 'Addresses to which aggregate feedback is to be sent (comma-separated plain-text list of DMARC URIs',
		validate(term, value) {
			let values = value.split(/,/).map(x => x.trim());

			for (let val of values) {
				let matches = val.match(/^mailto:(.+)$/);
				if (!matches) {
					throw new Error(`Invalid value for '${term}': ${value}, must be a list of DMARC URIs such as 'mailto:some.email@somedomain.com'`);
				}
				let email = matches[1];
				if (!validator.validate(email)) {
					throw new Error(`Invalid email address in '${term}': '${email}'`);
				}
			}
		}
	},
	ruf: {
		description: 'Addresses to which message-specific failure information is to be reported (comma-separated plain-text list of DMARC URIs)',
		validate(term, value) {
			let values = value.split(/,/).map(x => x.trim());

			for (let val of values) {
				let matches = val.match(/^mailto:(.+)$/);
				if (!matches) {
					throw new Error(`Invalid value for '${term}': ${value}, must be a list of DMARC URIs such as 'mailto:some.email@somedomain.com'`);
				}
				let email = matches[1];
				if (!validator.validate(email)) {
					throw new Error(`Invalid email address in '${term}': '${email}'`);
				}
			}
		}
	},
	sp: {
		description: 'Requested Mail Receiver policy for all subdomains. Can be "none", "quarantine", or "reject".',
		validate(term, value) {
			if (!/^(none|quarantine|reject)$/.test(value)) {
				throw new Error(`Invalid value for '${term}': '${value}', must be one of: none, quarantine, reject`);
			}
		}
	}
};

function parse(policy) {
  // Steps
  // 1. Split policy string on semicolons into term pairs
  // 2. Process and validate each term pair

	let terms = policy.split(/;/);

	let rules = terms.map(
    x => x.split(/[=]/)
          .map(p => p.trim())
  );

	let retval = {
		tags: {},
		messages: []
	};

	// Make sure `v` is the first tag
	if (rules[0][0] !== 'v') {
		retval.messages.push(`First tag in a DMARC policy must be 'v', but found: '${rules[0][0]}'`);
		return retval;
	}

	for (let rule of rules) {
		let term = rule[0];
		let value = rule[1];

		let found = false;

		for (let validatorTerm of Object.keys(validators)) {
			let settings = validators[validatorTerm];

			// Term matches validaor
			if (term === validatorTerm) {
				found = true;

				let tag = {
					// tag: term,
					description: settings.description
				};

				if (settings.validate) {
					try {
						settings.validate.call(settings, term, value);
						tag.value = value;
						retval.tags[term] = tag;
					}
					catch (err) {
						retval.messages.push(err.message);
					}
				}

				break;
			}
		}

		if (!found) {
			retval.messages.push(`Unknown tag '${term}'`);
		}
	}

	// Remove "messages"
	if (retval.messages.length === 0) {
		delete retval.messages;
	}

	return retval;
}

module.exports = parse;
<commit_msg>Add use strict<commit_after>'use strict';

const validator = require('email-validator');

const validators = {
	v: {
		required: true,
		// termPattern: /^v$/,
		description: 'Protocol version',
		validate(term, value) {
			if (value !== 'DMARC1') {
				throw new Error(`Invalid DMARC version: '${value}'`);
			}
		}
	},
	fo: {
		// termPattern: /^fo$/,
		description: 'Forensic reporting options. Possible values: "0" to generate reports if all underlying authentication mechanisms fail to produce a DMARC pass result, "1" to generate reports if any mechanisms fail, "d" to generate report if DKIM signature failed to verify, "s" if SPF failed.',
		validate(term, value) {
			if (!/^([01ds])$/.test(value)) {
				throw new Error(`Invalid value for '${term}': '${value}', must be one of: 0, 1, d, s`);
			}
		}
	},
	p: {
		description: 'Policy to apply to email that fails the DMARC check. Can be "none", "quarantine", or "reject". "none" is used to collect feedback and gain visibility into email streams without impacting existing flows.',
		validate(term, value) {
			if (!/^(none|quarantine|reject)$/.test(value)) {
				throw new Error(`Invalid value for '${term}': '${value}', must be one of: none, quarantine, reject`);
			}
		}
	},
	pct: {
		description: `Percentage of messages from the Domain Owner's mail stream to which the DMARC policy is to be applied.`,
		validate(term, value) {
			if (!/^\d+$/.test(value)) {
				throw new Error(`Invalid value for '${term}': ${value}, must be a positive integer`);
			}
			else if (parseInt(value, 10) > 100 || parseInt(value, 10) < 0) {
				throw new Error(`Invalid value for '${term}': ${value}, must be an integer between 0 and 100`);
			}
		}
	},
	rf: {
		description: `Format to be used for message-specific failure reports (colon-separated plain-text list of values)`,
		validate(term, value) {
			// The RFC says the values are colon-separated but a lot of examples/docs around the net show commas... so we'll do both
			let values = value.split(/,|:/).map(x => x.trim());

			for (let val of values) {
				if (!/^(afrf|iodef)$/.test(val)) {
					throw new Error(`Invalid value for '${term}': '${value}', must be one or more of these values: afrf, iodef. Multiple values must be separated by a comma or colon`);
				}
			}
		}
	},
	ri: {
		description: 'Interval (in seconds) requested between aggregate reports (plain-text 32-bit unsigned integer; default is 86400)',
		validate(term, value) {
			if (!/^\d+$/.test(value)) {
				throw new Error(`Invalid value for '${term}': ${value}, must be an unsigned integer`);
			}
		}
	},
	rua: {
		description: 'Addresses to which aggregate feedback is to be sent (comma-separated plain-text list of DMARC URIs',
		validate(term, value) {
			let values = value.split(/,/).map(x => x.trim());

			for (let val of values) {
				let matches = val.match(/^mailto:(.+)$/);
				if (!matches) {
					throw new Error(`Invalid value for '${term}': ${value}, must be a list of DMARC URIs such as 'mailto:some.email@somedomain.com'`);
				}
				let email = matches[1];
				if (!validator.validate(email)) {
					throw new Error(`Invalid email address in '${term}': '${email}'`);
				}
			}
		}
	},
	ruf: {
		description: 'Addresses to which message-specific failure information is to be reported (comma-separated plain-text list of DMARC URIs)',
		validate(term, value) {
			let values = value.split(/,/).map(x => x.trim());

			for (let val of values) {
				let matches = val.match(/^mailto:(.+)$/);
				if (!matches) {
					throw new Error(`Invalid value for '${term}': ${value}, must be a list of DMARC URIs such as 'mailto:some.email@somedomain.com'`);
				}
				let email = matches[1];
				if (!validator.validate(email)) {
					throw new Error(`Invalid email address in '${term}': '${email}'`);
				}
			}
		}
	},
	sp: {
		description: 'Requested Mail Receiver policy for all subdomains. Can be "none", "quarantine", or "reject".',
		validate(term, value) {
			if (!/^(none|quarantine|reject)$/.test(value)) {
				throw new Error(`Invalid value for '${term}': '${value}', must be one of: none, quarantine, reject`);
			}
		}
	}
};

function parse(policy) {
  // Steps
  // 1. Split policy string on semicolons into term pairs
  // 2. Process and validate each term pair

	let terms = policy.split(/;/);

	let rules = terms.map(
    x => x.split(/[=]/)
          .map(p => p.trim())
  );

	let retval = {
		tags: {},
		messages: []
	};

	// Make sure `v` is the first tag
	if (rules[0][0] !== 'v') {
		retval.messages.push(`First tag in a DMARC policy must be 'v', but found: '${rules[0][0]}'`);
		return retval;
	}

	for (let rule of rules) {
		let term = rule[0];
		let value = rule[1];

		let found = false;

		for (let validatorTerm of Object.keys(validators)) {
			let settings = validators[validatorTerm];

			// Term matches validaor
			if (term === validatorTerm) {
				found = true;

				let tag = {
					// tag: term,
					description: settings.description
				};

				if (settings.validate) {
					try {
						settings.validate.call(settings, term, value);
						tag.value = value;
						retval.tags[term] = tag;
					}
					catch (err) {
						retval.messages.push(err.message);
					}
				}

				break;
			}
		}

		if (!found) {
			retval.messages.push(`Unknown tag '${term}'`);
		}
	}

	// Remove "messages"
	if (retval.messages.length === 0) {
		delete retval.messages;
	}

	return retval;
}

module.exports = parse;
<|endoftext|>


<commit_before>'use strict';

/**
 * Simplified http request.
 * (C) 2013-2014 MediaSmart Mobile.
 */

// requires
var http = require('http');
var https = require('https');
var urlLib = require('url');

/**
 * Access a URL, send to callback. Parameters:
 *	- url: the URL to access.
 *	- json: optional contents to send, defaults to nothing.
 *	- params: optional additional parameters, currently supported:
 *		- retries: number of times to retry in case of error, default none.
 *		- timeout: time to wait for response in ms.
 *		- headers: object with headers.
 *		- agent: for repeated requests, see https://nodejs.org/api/http.html#http_class_http_agent.
 *		- buffer: if true, return raw buffer
 *	- callback(error, body): error is null only if result is 200.
 *		If there is an error, the body can contain the following attributes:
 *		- statusCode: if status code is not 200.
 *		- readingResponse: if response could not be read.
 */
exports.get = function(url, json, params, callback)
{
	if (typeof params == 'function')
	{
		callback = params;
		params = json;
		json = null;
	}
	return send(url, 'GET', json, params, callback);
};

/**
 * Post to a URL, send to callback. Parameters:
 *	- url: the URL to access.
 *	- json: optional object to send, can be a JSON string.
 *	- params: same as above.
 *	- callback(error, body): same as above.
 */
exports.post = function(url, json, params, callback)
{
	return send(url, 'POST', json, params, callback);
};

/**
 * Put to a URL, send to callback. Parameters:
 *	- url: the URL to access.
 *	- json: optional object to send, can be a JSON string.
 *	- params: same as above.
 *	- callback(error, body): same as above.
 */
exports.put = function(url, json, params, callback)
{
	return send(url, 'PUT', json, params, callback);
};

/**
 * Get the response to parse yourself. Parameters:
 *	- url: the URL to access.
 *	- method: string with the method to use ('GET', 'POST'...).
 *	- json: optional object to send, can be a JSON string.
 *	- params: same as above.
 *	- callback(error, body): same as above.
 */
exports.getResponse = function(url, method, json, params, callback)
{
	if (typeof params == 'function')
	{
		callback = params;
		params = {};
	}
	else if (typeof json == 'function')
	{
		callback = json;
		params = {};
		json = null;
	}
	callback = callback || function() {};
	getResponse(url, method, json, params, callback);
}

function send(url, method, json, params, callback)
{
	if (typeof params == 'function')
	{
		callback = params;
		params = {};
	}
	else if (typeof json == 'function')
	{
		callback = json;
		params = {};
		json = null;
	} else if (!params) {
		params = {}
	}
	if (callback)
	{
		return sendWithRetries(params.retries, url, method, json, params, callback);
	}
	return new Promise((resolve, reject) => {
		sendWithRetries(params.retries, url, method, json, params, (error, result) => {
			if (error) return reject(new RequestError(error, result))
			return resolve(result)
		});
	})
}

class RequestError extends Error
{
	constructor(message, result)
	{
		super(message)
		this.name = this.constructor.name
		for (const key in result)
		{
			this[key] = result[key]
		}
	}
}

function sendWithRetries(retries, url, method, json, params, callback)
{
	sendWithResponse(url, method, json, params, function(error, result)
	{
		if (error)
		{
			if (retries)
			{
				return sendWithRetries(retries - 1, url, method, json, params, callback);
			}
			return callback(error, result);
		}
		return callback(null, result)
	});
}

function sendWithResponse(url, method, json, params, callback)
{
	getResponse(url, method, json, params, function(error, response)
	{
		if (error) return callback(error, response);
		if (!response)
		{
			return callback(null, null)
		}
		var finished = false;
		var body = [];
		response.on('data', function (chunk)
		{
			body.push(chunk);
		});
		response.on('error', function(error)
		{
			if (finished) return;
			finished = true;
			return callback('Error reading response: ' + error, {readingResponse: true});
		});
		response.on('aborted', function()
		{
			if (finished) return;
			finished = true;
			return callback('Response aborted', {responseAborted: true});
		});
		response.on('end', function()
		{
			if (finished) return;
			finished = true;
			return callback(null, getResult(body, params, response));
		});
		response.on('close', function()
		{
			if (finished) return;
			finished = true;
			return callback(null, getResult(body, params, response));
		});

	})
}

function getResponse(url, method, json, params, callback)
{
	var options = urlLib.parse(url);
	options.method = method;
	options.headers = {};
	if (json)
	{
		if (typeof json == 'object')
		{
			params.body = JSON.stringify(json);
			options.headers = {
				'Content-Type': 'application/json',
				'Content-Length': params.body.length,
			};
		}
		else
		{
			params.body = json;
			options.headers = {
				'Content-Type': 'text/plain',
				'Content-Length': params.body.length,
			};
		}
	}
	options.headers['user-agent'] = 'node.js basic-request bot';
	for (var key in params.headers)
	{
		options.headers[key] = params.headers[key];
	}
	options.agent = params.agent || null;
	var finished = false;
	var protocol = http;
	if (options.protocol == 'https:')
	{
		protocol = https;
	}
	var request = protocol.request(options, function(response)
	{
		if (response.statusCode == 301 || response.statusCode == 302)
		{
			// follow redirection
			var location = response.headers.location;
			request.abort();
			return getResponse(location, method, json, params, callback)
		}
		if (response.statusCode == 204)
		{
			if (finished) return;
			finished = true;
			return callback(null, null);
		}
		if (response.statusCode != 200)
		{
			if (finished) return;
			finished = true;
			request.abort();
			return callback('Invalid status code ' + response.statusCode, {statusCode: response.statusCode});
		}
		if (params.timeout)
		{
			response.setTimeout(params.timeout, function()
			{
				if (finished) return;
				finished = true;
				return callback('Timeout while reading response', {responseTimeout: true});
			});
		}
		return callback(null, response);
	});
	request.setNoDelay();
	if (params.timeout)
	{
		request.setTimeout(params.timeout, function()
		{
			if (finished) return;
			finished = true;
			return callback('Timeout while sending request', {requestTimeout: true});
		});
	}
	request.on('error', function(error)
	{
		if (finished) return;
		finished = true;
		return callback('Error sending request: ' + error, {sendingRequest: true});
	});
	request.on('aborted', function()
	{
		if (finished) return;
		finished = true;
		return callback('Request aborted', {requestAborted: true});
	});
	if (params.body)
	{
		request.write(params.body, 'utf8');
	}
	request.end();
}

function getResult(body, params, response)
{
	const contentType = response.headers['content-type']
	if (contentType && contentType.includes('application/json'))
	{
		try {
			return JSON.parse(body)
		} catch(error) {
			return {error, body}
		}
	}
	var buffer = Buffer.concat(body)
	if (params.buffer) return buffer;
	return String(buffer);
}

// show API if invoked directly
if (__filename == process.argv[1])
{
	console.log('Use in your code as:');
	console.log('  request.get(url, function(error, body) {});');
}

<commit_msg>Fix: concatenate buffers before parsing.<commit_after>'use strict';

/**
 * Simplified http request.
 * (C) 2013-2014 MediaSmart Mobile.
 */

// requires
var http = require('http');
var https = require('https');
var urlLib = require('url');

/**
 * Access a URL, send to callback. Parameters:
 *	- url: the URL to access.
 *	- json: optional contents to send, defaults to nothing.
 *	- params: optional additional parameters, currently supported:
 *		- retries: number of times to retry in case of error, default none.
 *		- timeout: time to wait for response in ms.
 *		- headers: object with headers.
 *		- agent: for repeated requests, see https://nodejs.org/api/http.html#http_class_http_agent.
 *		- buffer: if true, return raw buffer
 *	- callback(error, body): error is null only if result is 200.
 *		If there is an error, the body can contain the following attributes:
 *		- statusCode: if status code is not 200.
 *		- readingResponse: if response could not be read.
 */
exports.get = function(url, json, params, callback)
{
	if (typeof params == 'function')
	{
		callback = params;
		params = json;
		json = null;
	}
	return send(url, 'GET', json, params, callback);
};

/**
 * Post to a URL, send to callback. Parameters:
 *	- url: the URL to access.
 *	- json: optional object to send, can be a JSON string.
 *	- params: same as above.
 *	- callback(error, body): same as above.
 */
exports.post = function(url, json, params, callback)
{
	return send(url, 'POST', json, params, callback);
};

/**
 * Put to a URL, send to callback. Parameters:
 *	- url: the URL to access.
 *	- json: optional object to send, can be a JSON string.
 *	- params: same as above.
 *	- callback(error, body): same as above.
 */
exports.put = function(url, json, params, callback)
{
	return send(url, 'PUT', json, params, callback);
};

/**
 * Get the response to parse yourself. Parameters:
 *	- url: the URL to access.
 *	- method: string with the method to use ('GET', 'POST'...).
 *	- json: optional object to send, can be a JSON string.
 *	- params: same as above.
 *	- callback(error, body): same as above.
 */
exports.getResponse = function(url, method, json, params, callback)
{
	if (typeof params == 'function')
	{
		callback = params;
		params = {};
	}
	else if (typeof json == 'function')
	{
		callback = json;
		params = {};
		json = null;
	}
	callback = callback || function() {};
	getResponse(url, method, json, params, callback);
}

function send(url, method, json, params, callback)
{
	if (typeof params == 'function')
	{
		callback = params;
		params = {};
	}
	else if (typeof json == 'function')
	{
		callback = json;
		params = {};
		json = null;
	} else if (!params) {
		params = {}
	}
	if (callback)
	{
		return sendWithRetries(params.retries, url, method, json, params, callback);
	}
	return new Promise((resolve, reject) => {
		sendWithRetries(params.retries, url, method, json, params, (error, result) => {
			if (error) return reject(new RequestError(error, result))
			return resolve(result)
		});
	})
}

class RequestError extends Error
{
	constructor(message, result)
	{
		super(message)
		this.name = this.constructor.name
		for (const key in result)
		{
			this[key] = result[key]
		}
	}
}

function sendWithRetries(retries, url, method, json, params, callback)
{
	sendWithResponse(url, method, json, params, function(error, result)
	{
		if (error)
		{
			if (retries)
			{
				return sendWithRetries(retries - 1, url, method, json, params, callback);
			}
			return callback(error, result);
		}
		return callback(null, result)
	});
}

function sendWithResponse(url, method, json, params, callback)
{
	getResponse(url, method, json, params, function(error, response)
	{
		if (error) return callback(error, response);
		if (!response)
		{
			return callback(null, null)
		}
		var finished = false;
		var body = [];
		response.on('data', function (chunk)
		{
			body.push(chunk);
		});
		response.on('error', function(error)
		{
			if (finished) return;
			finished = true;
			return callback('Error reading response: ' + error, {readingResponse: true});
		});
		response.on('aborted', function()
		{
			if (finished) return;
			finished = true;
			return callback('Response aborted', {responseAborted: true});
		});
		response.on('end', function()
		{
			if (finished) return;
			finished = true;
			return callback(null, getResult(body, params, response));
		});
		response.on('close', function()
		{
			if (finished) return;
			finished = true;
			return callback(null, getResult(body, params, response));
		});

	})
}

function getResponse(url, method, json, params, callback)
{
	var options = urlLib.parse(url);
	options.method = method;
	options.headers = {};
	if (json)
	{
		if (typeof json == 'object')
		{
			params.body = JSON.stringify(json);
			options.headers = {
				'Content-Type': 'application/json',
				'Content-Length': params.body.length,
			};
		}
		else
		{
			params.body = json;
			options.headers = {
				'Content-Type': 'text/plain',
				'Content-Length': params.body.length,
			};
		}
	}
	options.headers['user-agent'] = 'node.js basic-request bot';
	for (var key in params.headers)
	{
		options.headers[key] = params.headers[key];
	}
	options.agent = params.agent || null;
	var finished = false;
	var protocol = http;
	if (options.protocol == 'https:')
	{
		protocol = https;
	}
	var request = protocol.request(options, function(response)
	{
		if (response.statusCode == 301 || response.statusCode == 302)
		{
			// follow redirection
			var location = response.headers.location;
			request.abort();
			return getResponse(location, method, json, params, callback)
		}
		if (response.statusCode == 204)
		{
			if (finished) return;
			finished = true;
			return callback(null, null);
		}
		if (response.statusCode != 200)
		{
			if (finished) return;
			finished = true;
			request.abort();
			return callback('Invalid status code ' + response.statusCode, {statusCode: response.statusCode});
		}
		if (params.timeout)
		{
			response.setTimeout(params.timeout, function()
			{
				if (finished) return;
				finished = true;
				return callback('Timeout while reading response', {responseTimeout: true});
			});
		}
		return callback(null, response);
	});
	request.setNoDelay();
	if (params.timeout)
	{
		request.setTimeout(params.timeout, function()
		{
			if (finished) return;
			finished = true;
			return callback('Timeout while sending request', {requestTimeout: true});
		});
	}
	request.on('error', function(error)
	{
		if (finished) return;
		finished = true;
		return callback('Error sending request: ' + error, {sendingRequest: true});
	});
	request.on('aborted', function()
	{
		if (finished) return;
		finished = true;
		return callback('Request aborted', {requestAborted: true});
	});
	if (params.body)
	{
		request.write(params.body, 'utf8');
	}
	request.end();
}

function getResult(body, params, response)
{
	var buffer = Buffer.concat(body)
	const contentType = response.headers['content-type']
	if (contentType && contentType.includes('application/json'))
	{
		try {
			return JSON.parse(buffer)
		} catch(error) {
			return {error, body: String(buffer)}
		}
	}
	if (params.buffer) return buffer;
	return String(buffer);
}

// show API if invoked directly
if (__filename == process.argv[1])
{
	console.log('Use in your code as:');
	console.log('  request.get(url, function(error, body) {});');
}

<|endoftext|>


<commit_before>'use strict';

var url = require('url');
var path = require('path');
var fs = require('fs');
var ejs = require('ejs');

module.exports = function(opt) {

  opt = opt || {};
  var ext = opt.ext || '.ejs';
  var config = opt.ejs || {};
  var baseDir = opt.baseDir || __dirname;

  return function(req, res, next) {
    var file = req.url === '/' ? ('/index' + ext) : req.url;
    var pathname = path.join(baseDir, url.parse(file).pathname);

    if (path.extname(pathname) === ext && fs.existsSync(pathname)) {

      var contents = fs.readFileSync(pathname).toString();

      config.query = url.parse(req.url, true).query;
      config.filename = pathname;

      contents = ejs.render(contents, config);

      if (opt.browserSync) {
        contents = contents.replace(/<\/head>/, '');
      }

      res.write(contents);

      res.end();
    } else {
      next();
    }
  };
};
<commit_msg>update bs client script to 1.3.7<commit_after>'use strict';

var url = require('url');
var path = require('path');
var fs = require('fs');
var ejs = require('ejs');

module.exports = function(opt) {

  opt = opt || {};
  var ext = opt.ext || '.ejs';
  var config = opt.ejs || {};
  var baseDir = opt.baseDir || __dirname;

  return function(req, res, next) {
    var file = req.url === '/' ? ('/index' + ext) : req.url;
    var pathname = path.join(baseDir, url.parse(file).pathname);

    if (path.extname(pathname) === ext && fs.existsSync(pathname)) {

      var contents = fs.readFileSync(pathname).toString();

      config.query = url.parse(req.url, true).query;
      config.filename = pathname;

      contents = ejs.render(contents, config);

      if (opt.browserSync) {
        contents = contents.replace(/<\/head>/, '');
      }

      res.write(contents);

      res.end();
    } else {
      next();
    }
  };
};
<|endoftext|>


<commit_before>var reader = require('./lib/reader'),
    formatter = require('./lib/formatter'),
    absorb = require('absorb'),
    widget = require('./lib/widget'),
    server = require('./lib/http-server'),
    colors = require('colors/safe'),
    shell = require('shelljs'),
    path = require('./lib/path'),
    yaml = require('js-yaml'),
    Hexo = require('hexo'),
    glob = require('glob'),
    json = require('jsonfile'),
    fs = require('fs');

var fromModule = function(targetPath) {
    return __dirname + '/' + path.trimLeft(targetPath);
};

var fromProcess = function(targetPath) {
    return process.cwd() + '/' + path.trimRight(path.trimLeft(targetPath));
};

var conf = yaml.safeLoad(fs.readFileSync('./a-pollo.yml', 'utf-8'));
var packageJSON = json.readFileSync(fromModule('package.json'));
var hexoConfig, mergedConfig;

var checkPath = function(path) {
    if (shell.test('-e', path)) {
        return true;
    } else {
        console.error(colors.bgBlack(colors.red(' ERROR: ' + path + ' ')) + ' in your ' + colors.bgBlack(colors.yellow(' a-pollo.yml ')) + ' config not found.');
        return false;
    }
};

var copyHexoModule = function(moduleName) {
    shell.cp('-R', fromModule('/node_modules/' + moduleName), fromModule('/hexo/node_modules'));
};

var hexoModule = function() {
    if (!shell.test('-e', fromModule('/hexo/node_modules'))) {
        console.log('Preparing node modules');
        shell.mkdir('-p', fromModule('/hexo/node_modules'));
        copyHexoModule('hexo');
        copyHexoModule('hexo-deployer-rsync');
        copyHexoModule('hexo-generator-archive');
        copyHexoModule('hexo-generator-category');
        copyHexoModule('hexo-generator-index');
        copyHexoModule('hexo-generator-tag');
        copyHexoModule('hexo-renderer-ejs');
        copyHexoModule('hexo-renderer-marked');
        copyHexoModule('hexo-renderer-stylus');
        copyHexoModule('hexo-server');
        console.log('Done.');
    } else {
        shell.rm('-Rf', fromModule('/hexo/node_modules'));
    }
};

var prepareFiles = function() {

    hexoConfig   = yaml.safeLoad(fs.readFileSync(fromModule('/hexo/_default_config.yml'), 'utf-8'));

    if (shell.test('-e', fromProcess(conf.public_dir))) {
        shell.rm('-Rf', fromProcess(conf.public_dir));
    }

    mergedConfig = absorb(hexoConfig, conf);

    fs.writeFileSync(fromModule('/hexo/_config.yml'), yaml.safeDump(mergedConfig));

    shell.mkdir('-p', fromModule('/hexo/source'));
    shell.mkdir('-p', fromModule('/hexo/source/_posts'));
    shell.mkdir('-p', fromModule('/source'));

    if (conf.pages !== undefined) {
        if (checkPath(fromProcess(conf.pages))) {
            shell.cp('-R', path.inside(fromProcess(conf.pages)), fromModule('/hexo/source'));
        }
    } else {
        shell.cp('-R', fromModule('/hexo/_default_source/*'), fromModule('/hexo/source'));
    }

    shell.mkdir('-p', fromModule('/hexo/source/css/theme'));
    shell.mkdir('-p', fromModule('/hexo/source/css/theme/img'));
    shell.mkdir('-p', fromModule('/hexo/source/css/theme/fonts'));
    if (checkPath(fromProcess(conf.style.images))) {
        shell.cp('-R', path.inside(fromProcess(conf.style.images)), fromModule('/hexo/source/css/theme/img'));
    }
    if (checkPath(fromProcess(conf.style.fonts))) {
        shell.cp('-R', path.inside(fromProcess(conf.style.fonts)), fromModule('/hexo/source/css/theme/fonts'));
    }
};

var checkTheme = function() {
    if (!shell.test('-e', fromModule('/hexo/themes/' + conf.theme))) {
        console.log('Theme ' + colors.bgBlack(colors.yellow(' ' + conf.theme + ' ')) + ' not installed, searching on project folder');
        if (!shell.test('-e', fromProcess(conf.theme))) {
            console.log('Theme ' + colors.bgBlack(colors.yellow(' ' + conf.theme + ' ')) + ' not found, will be used ' + colors.bgBlack(colors.yellow(' apollo ')) + ' as default theme');
            conf.theme = 'apollo';
        } else {
            console.log('Installing found theme ' + colors.bgBlack(colors.yellow(' ' + conf.theme + ' ')));
            shell.cp('-R', path.inside(fromProcess(conf.theme)), fromModule('/hexo/themes/' + conf.theme));
        }
    } else {
        console.log('Using selected theme ' + colors.bgBlack(colors.yellow(' ' + conf.theme + ' ')));
    }
};

var generateDocs = function () {
    shell.mv('-f', fromProcess('/source/_posts'), fromModule('/hexo/source'));
    shell.exec('cd ' + fromModule('/hexo') + ' && ../node_modules/.bin/hexo generate');
    shell.mv('-f', fromModule('/hexo/' + path.trimLeft(conf.public_dir)), fromProcess(conf.public_dir));
};

var removeFiles = function() {
    if (shell.test('-e', fromModule('/hexo/source'))) { shell.rm('-Rf', fromModule('/hexo/source')); }
    if (shell.test('-e', fromModule('/hexo/node_modules'))) { shell.rm('-Rf', fromModule('/hexo/node_modules')); }
    if (shell.test('-e', fromModule('/source'))) { shell.rm('-Rf', fromModule('/source')); }
    if (shell.test('-e', fromModule('/hexo/_config.yml'))) { shell.rm('-f', fromModule('/hexo/_config.yml')); }
};

var prepareHTTP = function() {
    setTimeout(function(){
        removeFiles();
    }, 500);
    if (conf.http_server !== undefined || conf.http_server) {
        server.start(conf.public_dir, conf.url);
    }
};

var postCreated = function(widgetFilesLength) {
    var posts = glob.sync(fromProcess('/source/_posts/**/*.md'));
    if (posts.length === widgetFilesLength) {
        generateDocs();
        setTimeout(function(){
            prepareHTTP();
        }, 1000);
    } else {
        setTimeout(function(){
            postCreated(widgetFilesLength);
        }, 500);
    }
};

var copyThemeAssets = function() {
    var cssFileData;
    if (checkPath(fromProcess(conf.style.css))) {
        console.log('Copying CSS theme assets');
        cssFileData = fs.readFileSync(fromProcess(conf.style.css), 'utf8');
        cssFileData = cssFileData.replace(/url\("(.*\/)(.*)"\)/g, 'url("/css/theme/img/$2")');
        fs.writeFileSync(fromModule('/hexo/source/css/theme/theme.css'), cssFileData);
    } else {
        return false;
    }
};

var runBuild = function() {
    var hexo, widgetFiles;

    console.log('Starting ' + colors.bgBlack(colors.yellow(' Apollo ')) + ' ' + packageJSON.version);

    removeFiles();
    checkTheme();
    hexoModule();
    prepareFiles();

    console.log('Loading data from ' + colors.bgBlack(colors.yellow(' ' + conf.style.docs + ' ')) + ' folder');
    widgetFiles = reader.load(fromProcess(conf.style.docs));

    copyThemeAssets();

    console.log('Initializing ' + colors.bgBlack(colors.blue(' Hexo ')));

    if (checkPath(fromModule('/hexo/_config.yml'))) {
        console.log('Loading ' + colors.bgBlack(colors.blue(' Hexo ')) + ' configuration');
    }

    hexo = new Hexo(process.cwd(), {
        debug: false,
        config: fromModule('/hexo/_config.yml')
    });

    hexo.init().then(function(){
        var postData;
        console.log('Crunching ' + colors.bgBlack(colors.yellow(' Apollo ')) + ' annotations to ' + colors.bgBlack(colors.blue(' Hexo ')) + ' posts...');
        for (var i = 0; i < widgetFiles.length; i += 1) {
            console.log('Creating post for ' + colors.bgBlack(colors.yellow(' ' + widgetFiles[i][0].file + ' ')));
            postData = formatter.toHexo(widgetFiles[i]);
            postData.content = widget.toMarkdown(widgetFiles[i], conf);
            hexo.post.create(postData, true);
        }
        console.log('Waiting for ' + colors.bgBlack(colors.blue(' Hexo ')) + ' to finish posts creation...');
        postCreated(widgetFiles.length);
    });
};

runBuild();
<commit_msg>Change theme assets folders to make file loadig easier<commit_after>var reader = require('./lib/reader'),
    formatter = require('./lib/formatter'),
    absorb = require('absorb'),
    widget = require('./lib/widget'),
    server = require('./lib/http-server'),
    colors = require('colors/safe'),
    shell = require('shelljs'),
    path = require('./lib/path'),
    yaml = require('js-yaml'),
    Hexo = require('hexo'),
    glob = require('glob'),
    json = require('jsonfile'),
    fs = require('fs');

var fromModule = function(targetPath) {
    return __dirname + '/' + path.trimLeft(targetPath);
};

var fromProcess = function(targetPath) {
    return process.cwd() + '/' + path.trimRight(path.trimLeft(targetPath));
};

var conf = yaml.safeLoad(fs.readFileSync('./a-pollo.yml', 'utf-8'));
var packageJSON = json.readFileSync(fromModule('package.json'));
var hexoConfig, mergedConfig;

var checkPath = function(path) {
    if (shell.test('-e', path)) {
        return true;
    } else {
        console.error(colors.bgBlack(colors.red(' ERROR: ' + path + ' ')) + ' in your ' + colors.bgBlack(colors.yellow(' a-pollo.yml ')) + ' config not found.');
        return false;
    }
};

var copyHexoModule = function(moduleName) {
    shell.cp('-R', fromModule('/node_modules/' + moduleName), fromModule('/hexo/node_modules'));
};

var hexoModule = function() {
    if (!shell.test('-e', fromModule('/hexo/node_modules'))) {
        console.log('Preparing node modules');
        shell.mkdir('-p', fromModule('/hexo/node_modules'));
        copyHexoModule('hexo');
        copyHexoModule('hexo-deployer-rsync');
        copyHexoModule('hexo-generator-archive');
        copyHexoModule('hexo-generator-category');
        copyHexoModule('hexo-generator-index');
        copyHexoModule('hexo-generator-tag');
        copyHexoModule('hexo-renderer-ejs');
        copyHexoModule('hexo-renderer-marked');
        copyHexoModule('hexo-renderer-stylus');
        copyHexoModule('hexo-server');
        console.log('Done.');
    } else {
        shell.rm('-Rf', fromModule('/hexo/node_modules'));
    }
};

var prepareFiles = function() {

    hexoConfig   = yaml.safeLoad(fs.readFileSync(fromModule('/hexo/_default_config.yml'), 'utf-8'));

    if (shell.test('-e', fromProcess(conf.public_dir))) {
        shell.rm('-Rf', fromProcess(conf.public_dir));
    }

    mergedConfig = absorb(hexoConfig, conf);

    fs.writeFileSync(fromModule('/hexo/_config.yml'), yaml.safeDump(mergedConfig));

    shell.mkdir('-p', fromModule('/hexo/source'));
    shell.mkdir('-p', fromModule('/hexo/source/_posts'));
    shell.mkdir('-p', fromModule('/source'));

    if (conf.pages !== undefined) {
        if (checkPath(fromProcess(conf.pages))) {
            shell.cp('-R', path.inside(fromProcess(conf.pages)), fromModule('/hexo/source'));
        }
    } else {
        shell.cp('-R', fromModule('/hexo/_default_source/*'), fromModule('/hexo/source'));
    }

    shell.mkdir('-p', fromModule('/hexo/source/css/theme'));
    shell.mkdir('-p', fromModule('/hexo/source/css/theme/img'));
    shell.mkdir('-p', fromModule('/hexo/source/css/theme/fonts'));

    console.log('Copying CSS theme images and fonts');

    if (checkPath(fromProcess(conf.style.images))) {
        shell.cp('-R', path.inside(fromProcess(conf.style.images)), fromModule('/hexo/source/css/theme/assets'));
    }
    if (checkPath(fromProcess(conf.style.fonts))) {
        shell.cp('-R', path.inside(fromProcess(conf.style.fonts)), fromModule('/hexo/source/css/theme/assets'));
    }
};

var checkTheme = function() {
    if (!shell.test('-e', fromModule('/hexo/themes/' + conf.theme))) {
        console.log('Theme ' + colors.bgBlack(colors.yellow(' ' + conf.theme + ' ')) + ' not installed, searching on project folder');
        if (!shell.test('-e', fromProcess(conf.theme))) {
            console.log('Theme ' + colors.bgBlack(colors.yellow(' ' + conf.theme + ' ')) + ' not found, will be used ' + colors.bgBlack(colors.yellow(' apollo ')) + ' as default theme');
            conf.theme = 'apollo';
        } else {
            console.log('Installing found theme ' + colors.bgBlack(colors.yellow(' ' + conf.theme + ' ')));
            shell.cp('-R', path.inside(fromProcess(conf.theme)), fromModule('/hexo/themes/' + conf.theme));
        }
    } else {
        console.log('Using selected theme ' + colors.bgBlack(colors.yellow(' ' + conf.theme + ' ')));
    }
};

var generateDocs = function () {
    shell.mv('-f', fromProcess('/source/_posts'), fromModule('/hexo/source'));
    shell.exec('cd ' + fromModule('/hexo') + ' && ../node_modules/.bin/hexo generate');
    shell.mv('-f', fromModule('/hexo/' + path.trimLeft(conf.public_dir)), fromProcess(conf.public_dir));
};

var removeFiles = function() {
    if (shell.test('-e', fromModule('/hexo/source'))) { shell.rm('-Rf', fromModule('/hexo/source')); }
    if (shell.test('-e', fromModule('/hexo/node_modules'))) { shell.rm('-Rf', fromModule('/hexo/node_modules')); }
    if (shell.test('-e', fromModule('/source'))) { shell.rm('-Rf', fromModule('/source')); }
    if (shell.test('-e', fromModule('/hexo/_config.yml'))) { shell.rm('-f', fromModule('/hexo/_config.yml')); }
};

var prepareHTTP = function() {
    setTimeout(function(){
        removeFiles();
    }, 500);
    if (conf.http_server !== undefined || conf.http_server) {
        server.start(conf.public_dir, conf.url);
    }
};

var postCreated = function(widgetFilesLength) {
    var posts = glob.sync(fromProcess('/source/_posts/**/*.md'));
    if (posts.length === widgetFilesLength) {
        generateDocs();
        setTimeout(function(){
            prepareHTTP();
        }, 1000);
    } else {
        setTimeout(function(){
            postCreated(widgetFilesLength);
        }, 500);
    }
};

var copyThemeAssets = function() {
    var cssFileData;
    if (checkPath(fromProcess(conf.style.css))) {
        console.log('Copying CSS theme');
        cssFileData = fs.readFileSync(fromProcess(conf.style.css), 'utf8');
        cssFileData = cssFileData.replace(/url\("(.*\/)(.*)"\)/g, 'url("/css/theme/assets/$2")');
        fs.writeFileSync(fromModule('/hexo/source/css/theme/theme.css'), cssFileData);
    } else {
        return false;
    }
};

var runBuild = function() {
    var hexo, widgetFiles;

    console.log('Starting ' + colors.bgBlack(colors.yellow(' Apollo ')) + ' ' + packageJSON.version);

    removeFiles();
    checkTheme();
    hexoModule();
    prepareFiles();

    console.log('Loading data from ' + colors.bgBlack(colors.yellow(' ' + conf.style.docs + ' ')) + ' folder');
    widgetFiles = reader.load(fromProcess(conf.style.docs));

    copyThemeAssets();

    console.log('Initializing ' + colors.bgBlack(colors.blue(' Hexo ')));

    if (checkPath(fromModule('/hexo/_config.yml'))) {
        console.log('Loading ' + colors.bgBlack(colors.blue(' Hexo ')) + ' configuration');
    }

    hexo = new Hexo(process.cwd(), {
        debug: false,
        config: fromModule('/hexo/_config.yml')
    });

    hexo.init().then(function(){
        var postData;
        console.log('Crunching ' + colors.bgBlack(colors.yellow(' Apollo ')) + ' annotations to ' + colors.bgBlack(colors.blue(' Hexo ')) + ' posts...');
        for (var i = 0; i < widgetFiles.length; i += 1) {
            console.log('Creating post for ' + colors.bgBlack(colors.yellow(' ' + widgetFiles[i][0].file + ' ')));
            postData = formatter.toHexo(widgetFiles[i]);
            postData.content = widget.toMarkdown(widgetFiles[i], conf);
            // console.log(postData.docs[0].htmlSnippet)
            hexo.post.create(postData, true);
        }
        console.log('Waiting for ' + colors.bgBlack(colors.blue(' Hexo ')) + ' to finish posts creation...');
        postCreated(widgetFiles.length);
    });
};

runBuild();
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014-2015, CKSource - Frederico Knabben. All rights reserved.
 * Licensed under the terms of the MIT License (see LICENSE.md).
 */

'use strict';

var path = require( 'path' ),
	sinonPath = path.join( require.resolve( 'sinon' ), '../../pkg/sinon.js' ),
	sinonIEPath = path.join( require.resolve( 'sinon' ), '../../pkg/sinon-ie.js' );

module.exports = {
	name: 'bender-sinon',

	attach: function() {
		this.pagebuilders.add( 'sinon', build, this.pagebuilders.getPriority( 'html' ) - 1 );
		this.plugins.addFiles( [ sinonPath, sinonIEPath ] );

		function build( data ) {
			data.parts.push(
				'<head>' +
					'<script src="' + path.join( '/plugins', sinonPath ).split( path.sep ).join( '/' ) + '"></script>' +
					// IE8- need additional care to make timers and XHR work.
					'<!--[if lte IE 8]>' +
						'<script src="' + path.join( '/plugins', sinonIEPath ).split( path.sep ).join( '/' ) + '"></script>' +
					'<![endif]-->' +
				'</head>'
			);

			return data;
		}
	}
};
<commit_msg>Let's expose sinon globally even when running in an AMD environment.<commit_after>/**
 * Copyright (c) 2014-2015, CKSource - Frederico Knabben. All rights reserved.
 * Licensed under the terms of the MIT License (see LICENSE.md).
 */

'use strict';

var path = require( 'path' ),
	sinonPath = path.join( require.resolve( 'sinon' ), '../../pkg/sinon.js' ),
	sinonIEPath = path.join( require.resolve( 'sinon' ), '../../pkg/sinon-ie.js' ),
	prefixedSinonPath = path.join( '/plugins', sinonPath ).split( path.sep ).join( '/' ),
	prefixedSinonIEPath = path.join( '/plugins', sinonIEPath ).split( path.sep ).join( '/' );

module.exports = {
	name: 'bender-sinon',

	attach: function() {
		this.pagebuilders.add( 'sinon', build, this.pagebuilders.getPriority( 'html' ) - 1 );
		this.plugins.addFiles( [ sinonPath, sinonIEPath ] );

		function build( data ) {
			data.parts.push(
				`<head>
					<script src="${ prefixedSinonPath }"></script>
					// IE8- need additional care to make timers and XHR work.
					<!--[if lte IE 8]>
						<script src="${ prefixedSinonIEPath }"></script>
					<![endif]-->
					<script>
						// Expose Sinon if we are in an AMD environment.
						if ( typeof define == 'function' && define.amd && typeof sinon == 'undefined' ) {
							var done = bender.defer();

							( function() {
								require( [ 'sinon' ], function( sinon ) {
									window.sinon = sinon;
									done();
								} );
							} )();
						}
					</script>
				</head>`
			);

			return data;
		}
	}
};
<|endoftext|>


<commit_before>var nunjucks = require('nunjucks');

nunjucks.installJinjaCompat();
/**
 * Themeleon template helper, using consolidate.js module.
 *
 * See <https://github.com/themeleon/themeleon>.
 * See <https://github.com/tj/consolidate.js>.
 */
var themeleon = require('themeleon')().use('consolidate');

/**
 * Utility function we will use to merge a default configuration
 * with the user object.
 */
var extend = require('extend');

/**
 * SassDoc extras (providing Markdown and other filters, and different way to
 * index SassDoc data).
 *
 * See <https://github.com/SassDoc/sassdoc-extras>.
 */
var extras = require('sassdoc-extras');

/**
 * The theme function. You can directly export it like this:
 *
 *     module.exports = themeleon(__dirname, function (t) {});
 *
 * ... but here we want more control on the template variables, so there
 * is a little bit of preprocessing below.
 *
 * The theme function describes the steps to render the theme.
 */
var theme = themeleon(__dirname, function (t) {
  t.copy('assets');

  // Configure Nunjucks views basePath and options.
  // See https://mozilla.github.io/nunjucks/api.html#configure
  nunjucks.configure('views');
  // Compile a Nunjucks view as `index.html` in destination directory
  t.nunjucks('index.html', 'dist/index.html');
});

/**
 * Actual theme function. It takes the destination directory `dest`
 * (that will be handled by Themeleon), and the context variables `ctx`.
 *
 * Here, we will modify the context to have a `view` key defaulting to
 * a literal object, but that can be overriden by the user's
 * configuration.
 */
module.exports = function (dest, ctx) {
  var def = {
    display: {
      annotations: {
        function: ["description", "parameter", "return", "example", "throw", "require", "usedby", "since", "see", "todo", "link", "author"],
        mixin: ["description", "parameter", "content", "output", "example", "throw", "require", "usedby", "since", "see", "todo", "link", "author"],
        placeholder: ["description", "example", "throw", "require", "usedby", "since", "see", "todo", "link", "author"],
        variable: ["description", "type", "property", "require", "example", "usedby", "since", "see", "todo", "link", "author"]
      },
      access: ['public', 'private'],
      alias: false,
      watermark: true,
    },
    groups: {
      'undefined': 'General',
    },
    shortcutIcon: 'http://ffoodd.github.io/a11y.css/static/favicon.ico',
  };

  // Apply default values for groups and display.
  ctx.groups = extend(def.groups, ctx.groups);
  ctx.display = extend(def.display, ctx.display);

  // Extend top-level context keys.
  ctx = extend({}, def, ctx);

  /**
   * Parse text data (like descriptions) as Markdown, and put the
   * rendered HTML in `html*` variables.
   *
   * For example, `ctx.package.description` will be parsed as Markdown
   * in `ctx.package.htmlDescription`.
   *
   * See <http://sassdoc.com/extra-tools/#markdown>.
   */
  extras.markdown(ctx);

  /**
   * Add a `display` property for each data item regarding of display
   * configuration (hide private items and aliases for example).
   *
   * You'll need to add default values in your `.sassdocrc` before
   * using this filter:
   *
   *     {
   *       "display": {
   *         "access": ["public", "private"],
   *         "alias": false
   *       }
   *     }
   *
   * See <http://sassdoc.com/extra-tools/#display-toggle>.
   */
  extras.display(ctx);

  /**
   * Allow the user to give a name to the documentation groups.
   *
   * We can then have `@group slug` in the docblock, and map `slug`
   * to `Some title string` in the theme configuration.
   *
   * **Note:** all items without a group are in the `undefined` group.
   *
   * See <http://sassdoc.com/extra-tools/#groups-aliases>.
   */
  extras.groupName(ctx);

  /**
   * Use SassDoc indexer to index the data by group and type, so we
   * have the following structure:
   *
   *     {
   *       "group-slug": {
   *         "function": [...],
   *         "mixin": [...],
   *         "variable": [...]
   *       },
   *       "another-group": {
   *         "function": [...],
   *         "mixin": [...],
   *         "variable": [...]
   *       }
   *     }
   *
   * You can then use `data.byGroupAndType` instead of `data` in your
   * templates to manipulate the indexed object.
   */
  ctx.data.byGroupAndType = extras.byGroupAndType(ctx.data);

  /**
   * Now we have prepared the data, we can proxy to the Themeleon
   * generated theme function.
   */
  return theme.apply(this, arguments);
};
<commit_msg>v0.2.5 WTF Nunjucks?<commit_after>var nunjucks = require('nunjucks');

nunjucks.installJinjaCompat();
/**
 * Themeleon template helper, using consolidate.js module.
 *
 * See <https://github.com/themeleon/themeleon>.
 * See <https://github.com/tj/consolidate.js>.
 */
var themeleon = require('themeleon')().use('consolidate');

/**
 * Utility function we will use to merge a default configuration
 * with the user object.
 */
var extend = require('extend');

/**
 * SassDoc extras (providing Markdown and other filters, and different way to
 * index SassDoc data).
 *
 * See <https://github.com/SassDoc/sassdoc-extras>.
 */
var extras = require('sassdoc-extras');

/**
 * The theme function. You can directly export it like this:
 *
 *     module.exports = themeleon(__dirname, function (t) {});
 *
 * ... but here we want more control on the template variables, so there
 * is a little bit of preprocessing below.
 *
 * The theme function describes the steps to render the theme.
 */
var theme = themeleon(__dirname, function (t) {
  t.copy('assets');

  // Configure Nunjucks views basePath and options.
  // See https://mozilla.github.io/nunjucks/api.html#configure
  nunjucks.configure('views');
  // Compile a Nunjucks view as `index.html` in destination directory
  t.nunjucks('views/index.html', 'dist/index.html');
});

/**
 * Actual theme function. It takes the destination directory `dest`
 * (that will be handled by Themeleon), and the context variables `ctx`.
 *
 * Here, we will modify the context to have a `view` key defaulting to
 * a literal object, but that can be overriden by the user's
 * configuration.
 */
module.exports = function (dest, ctx) {
  var def = {
    display: {
      annotations: {
        function: ["description", "parameter", "return", "example", "throw", "require", "usedby", "since", "see", "todo", "link", "author"],
        mixin: ["description", "parameter", "content", "output", "example", "throw", "require", "usedby", "since", "see", "todo", "link", "author"],
        placeholder: ["description", "example", "throw", "require", "usedby", "since", "see", "todo", "link", "author"],
        variable: ["description", "type", "property", "require", "example", "usedby", "since", "see", "todo", "link", "author"]
      },
      access: ['public', 'private'],
      alias: false,
      watermark: true,
    },
    groups: {
      'undefined': 'General',
    },
    shortcutIcon: 'http://ffoodd.github.io/a11y.css/static/favicon.ico',
  };

  // Apply default values for groups and display.
  ctx.groups = extend(def.groups, ctx.groups);
  ctx.display = extend(def.display, ctx.display);

  // Extend top-level context keys.
  ctx = extend({}, def, ctx);

  /**
   * Parse text data (like descriptions) as Markdown, and put the
   * rendered HTML in `html*` variables.
   *
   * For example, `ctx.package.description` will be parsed as Markdown
   * in `ctx.package.htmlDescription`.
   *
   * See <http://sassdoc.com/extra-tools/#markdown>.
   */
  extras.markdown(ctx);

  /**
   * Add a `display` property for each data item regarding of display
   * configuration (hide private items and aliases for example).
   *
   * You'll need to add default values in your `.sassdocrc` before
   * using this filter:
   *
   *     {
   *       "display": {
   *         "access": ["public", "private"],
   *         "alias": false
   *       }
   *     }
   *
   * See <http://sassdoc.com/extra-tools/#display-toggle>.
   */
  extras.display(ctx);

  /**
   * Allow the user to give a name to the documentation groups.
   *
   * We can then have `@group slug` in the docblock, and map `slug`
   * to `Some title string` in the theme configuration.
   *
   * **Note:** all items without a group are in the `undefined` group.
   *
   * See <http://sassdoc.com/extra-tools/#groups-aliases>.
   */
  extras.groupName(ctx);

  /**
   * Use SassDoc indexer to index the data by group and type, so we
   * have the following structure:
   *
   *     {
   *       "group-slug": {
   *         "function": [...],
   *         "mixin": [...],
   *         "variable": [...]
   *       },
   *       "another-group": {
   *         "function": [...],
   *         "mixin": [...],
   *         "variable": [...]
   *       }
   *     }
   *
   * You can then use `data.byGroupAndType` instead of `data` in your
   * templates to manipulate the indexed object.
   */
  ctx.data.byGroupAndType = extras.byGroupAndType(ctx.data);

  /**
   * Now we have prepared the data, we can proxy to the Themeleon
   * generated theme function.
   */
  return theme.apply(this, arguments);
};
<|endoftext|>


<commit_before>var core = require('./core')

var b = process.binding

process.binding = function (name) {
  var loaded = b(name)
  var cpy = {}

  Object.keys(loaded).forEach(function (prop) {
    if (typeof loaded[prop] === 'function' && loaded[prop].prototype) {
      var wrap = function () {
        var handle

        if (arguments.length === 4) handle = new loaded[prop](arguments[0], arguments[1], arguments[2], arguments[3])
        else if (arguments.length === 3) handle = new loaded[prop](arguments[0], arguments[1], arguments[2])
        else if (arguments.length === 2) handle = new loaded[prop](arguments[0], arguments[1])
        else if (arguments.length === 1) handle = new loaded[prop](arguments[0])
        else handle = new loaded[prop]()

        var e = new Error('whatevs')
        var stacks = require('stackback')(e)
        var path = require('path')

        handle.__WHY_IS_NODE_RUNNING__ = {stacks: [], wrapped: loaded[prop]}

        for (var i = 1; i < stacks.length; i++) {
          handle.__WHY_IS_NODE_RUNNING__.stacks.push(stacks[i])
        }

        return handle
      }

      Object.keys(loaded[prop]).forEach(function (name) {
        wrap[name] = loaded[prop][name]
      })

      if (/^[A-Z]/.test(prop)) {
        cpy[prop] = wrap
      } else {
        cpy[prop] = loaded[prop]
      }
    } else {
      cpy[prop] = loaded[prop]
    }
  })

  return cpy
}

core.globalTimeouts()

module.exports = function (logger) {
  logger = logger || console
  var handles = process._getActiveHandles()
  var unknown = 0
  var known = []

  handles.forEach(function (handle) {
    var stacks = findStacks(handle, 0)
    if (stacks) {
      known.push(stacks)
      return
    }

    unknown++
  })

  logger.error('There are %d known handle(s) keeping the process running and %d unknown', known.length, unknown)
  logger.error('Known handles:\n')
  known.forEach(function (obj, i) {
    var stacks = obj.stacks

    stacks = stacks.filter(function (s) {
      return s.getFileName().indexOf(require('path').sep) > -1
    })

    logger.error('# %s', obj.wrapped.name)

    if (!stacks[0]) {
      logger.error('(unknown stack trace)')
    } else {
      var padding = ''
      stacks.forEach(function (s) {
        var pad = (s.getFileName() + ':' + s.getLineNumber()).replace(/./g, ' ')
        if (pad.length > padding.length) padding = pad
      })
      stacks.forEach(function (s) {
        var prefix = s.getFileName() + ':' + s.getLineNumber()
        try {
          var src = require('fs').readFileSync(s.getFileName(), 'utf-8').split(/\n|\r\n/)
          logger.error(prefix + padding.slice(prefix.length) + ' - ' + src[s.getLineNumber() - 1].trim())
        } catch (e) {
          logger.error(prefix + padding.slice(prefix.length))
        }
      })
    }
    logger.error()
  })
}

function findStacks (obj, depth) {
  if (depth === 10) return null

  var keys = Object.keys(obj)
  for (var i = 0; i < keys.length; i++) {
    var val = obj[keys[i]]
    if (keys[i] === '__WHY_IS_NODE_RUNNING__') return val
    if (typeof val === 'object' && val) {
      val = findStacks(val, depth + 1)
      if (val) return val
    }
  }
}
<commit_msg>log out unknown stacks (#24)<commit_after>var core = require('./core')

var b = process.binding

process.binding = function (name) {
  var loaded = b(name)
  var cpy = {}

  Object.keys(loaded).forEach(function (prop) {
    if (typeof loaded[prop] === 'function' && loaded[prop].prototype) {
      var wrap = function () {
        var handle

        if (arguments.length === 4) handle = new loaded[prop](arguments[0], arguments[1], arguments[2], arguments[3])
        else if (arguments.length === 3) handle = new loaded[prop](arguments[0], arguments[1], arguments[2])
        else if (arguments.length === 2) handle = new loaded[prop](arguments[0], arguments[1])
        else if (arguments.length === 1) handle = new loaded[prop](arguments[0])
        else handle = new loaded[prop]()

        var e = new Error('whatevs')
        var stacks = require('stackback')(e)

        handle.__WHY_IS_NODE_RUNNING__ = {stacks: [], wrapped: loaded[prop]}

        for (var i = 1; i < stacks.length; i++) {
          handle.__WHY_IS_NODE_RUNNING__.stacks.push(stacks[i])
        }

        return handle
      }

      Object.keys(loaded[prop]).forEach(function (name) {
        wrap[name] = loaded[prop][name]
      })

      if (/^[A-Z]/.test(prop)) {
        cpy[prop] = wrap
      } else {
        cpy[prop] = loaded[prop]
      }
    } else {
      cpy[prop] = loaded[prop]
    }
  })

  return cpy
}

core.globalTimeouts()

module.exports = function (logger) {
  logger = logger || console
  var handles = process._getActiveHandles()
  var unknown = []
  var known = []

  handles.forEach(function (handle) {
    var stacks = findStacks(handle, 0)
    if (stacks) {
      known.push(stacks)
    } else {
      unknown.push(handle)
    }
  })

  logger.error('There are %d known handle(s) keeping the process running and %d unknown', known.length, unknown.length)
  logger.error('Known handles:\n')
  known.forEach(function (obj, i) {
    var stacks = obj.stacks

    stacks = stacks.filter(function (s) {
      return s.getFileName().indexOf(require('path').sep) > -1
    })

    logger.error('# %s', obj.wrapped.name)

    if (!stacks[0]) {
      logger.error('(unknown stack trace)')
    } else {
      var padding = ''
      stacks.forEach(function (s) {
        var pad = (s.getFileName() + ':' + s.getLineNumber()).replace(/./g, ' ')
        if (pad.length > padding.length) padding = pad
      })
      stacks.forEach(function (s) {
        var prefix = s.getFileName() + ':' + s.getLineNumber()
        try {
          var src = require('fs').readFileSync(s.getFileName(), 'utf-8').split(/\n|\r\n/)
          logger.error(prefix + padding.slice(prefix.length) + ' - ' + src[s.getLineNumber() - 1].trim())
        } catch (e) {
          logger.error(prefix + padding.slice(prefix.length))
        }
      })
    }

    logger.error('\nUnknown handles:\n')

    unknown.forEach(function (stack) {
      logger.error(stack)
      logger.error()
    })
  })
}

function findStacks (obj, depth) {
  if (depth === 10) return null

  var keys = Object.keys(obj)
  for (var i = 0; i < keys.length; i++) {
    var val = obj[keys[i]]
    if (keys[i] === '__WHY_IS_NODE_RUNNING__') return val
    if (typeof val === 'object' && val) {
      val = findStacks(val, depth + 1)
      if (val) return val
    }
  }
}
<|endoftext|>


<commit_before>var parseArgs = require('minimist');
var argv = parseArgs( process.argv , {
  number: [ 'port' ],
  string: [ 'comport' ],
  boolean: [ 'debug']
});

var port = argv.port || 'NULL';
var debug = argv.debug || false;
var comport = argv.comport;

console.log('Starting water rower.');
console.log('\tPort: ', argv.port);
console.log('\tCom port: ', argv.comport);
console.log('\tDebug: ', debug);

var server = require('http').createServer()
var ws = require('ws');
var url = require('url')
var WebSocketServer = ws.Server
var wsServer = new WebSocketServer({ server: server });

var wr = require('./water_rower.js')({ debug: debug} );
var express = require('express');
var app = express();
app.get('/', express.static(__dirname+'/public') );

var rower;

function broadcastClients(msg){
  wsServer.clients.forEach( function(client) {
    client.send( JSON.stringify(msg), function(err) {
      if (err) {
        console.log(err.toString());
      }
    });
  });
}

function setupRower() {
  rower = new wr.WaterRower({ port: comport });
  rower.on('readings', function(msg) {
    broadcastClients( {
      type: 'readings',
      data: msg
    });
  });
  rower.on('keypad', function(msg){
    broadcastClients( {
      type: 'keypad',
      data: msg
    });
  });
}

wsServer.on('connection', function connection(sock) {
  var location = url.parse(sock.upgradeReq.url, true);

  sock.on('close', function _accounceDisconnect(){
    console.log("Socket disconnect.");
  });

  sock.on('message', function _socketMessage(msg){
    console.log("Socket sent message: ", msg.toString() );
    try {
      var parsedMsg = JSON.parse(msg);
      if (parsedMsg.msg === 'reset rower') {
        setupRower();
      }
    } catch (e) {
      console.log('Error handling message: ', e.toString());
    }
  });

  console.log("Socket connect.");
});

server.on('request', app);
server.listen(port, function () {
  console.log('Listening on ' + server.address().port)
});

process.on('SIGINT', function() {
  console.log("\nSIGINT (Ctrl+C)");
  if (rower) {
    rower.shutdown();
  }
});
<commit_msg>Add quitting to SIGINT handler. Sigh. :(<commit_after>var parseArgs = require('minimist');
var argv = parseArgs( process.argv , {
  number: [ 'port' ],
  string: [ 'comport' ],
  boolean: [ 'debug']
});

var port = argv.port || 'NULL';
var debug = argv.debug || false;
var comport = argv.comport;

console.log('Starting water rower.');
console.log('\tPort: ', argv.port);
console.log('\tCom port: ', argv.comport);
console.log('\tDebug: ', debug);

var server = require('http').createServer()
var ws = require('ws');
var url = require('url')
var WebSocketServer = ws.Server
var wsServer = new WebSocketServer({ server: server });

var wr = require('./water_rower.js')({ debug: debug} );
var express = require('express');
var app = express();
app.get('/', express.static(__dirname+'/public') );

var rower;

function broadcastClients(msg){
  wsServer.clients.forEach( function(client) {
    client.send( JSON.stringify(msg), function(err) {
      if (err) {
        console.log(err.toString());
      }
    });
  });
}

function setupRower() {
  rower = new wr.WaterRower({ port: comport });
  rower.on('readings', function(msg) {
    broadcastClients( {
      type: 'readings',
      data: msg
    });
  });
  rower.on('keypad', function(msg){
    broadcastClients( {
      type: 'keypad',
      data: msg
    });
  });
}

wsServer.on('connection', function connection(sock) {
  var location = url.parse(sock.upgradeReq.url, true);

  sock.on('close', function _accounceDisconnect(){
    console.log("Socket disconnect.");
  });

  sock.on('message', function _socketMessage(msg){
    console.log("Socket sent message: ", msg.toString() );
    try {
      var parsedMsg = JSON.parse(msg);
      if (parsedMsg.msg === 'reset rower') {
        setupRower();
      }
    } catch (e) {
      console.log('Error handling message: ', e.toString());
    }
  });

  console.log("Socket connect.");
});

server.on('request', app);
server.listen(port, function () {
  console.log('Listening on ' + server.address().port)
});

process.on('SIGINT', function() {
  console.log("\nSIGINT (Ctrl+C)");
  if (rower) {
    rower.shutdown();
    process.exit(0);
  }
});
<|endoftext|>