<commit_before>// Dependencies
var G = global
  , Statique    = G.Statique    = require("statique")
  , Utils       = G.Utils       = require("./utils")
  , Fs          = G.Fs          = require("fs")
  , Url         = G.Url         = require("url")
  , Http        = G.Http        = require("http")
  , Marked      = G.Marked      = require("marked")
  , Moment      = G.Moment      = require("moment")
  , Mustache    = G.Mustache    = require("mustache")
  , QueryString = G.QueryString = require("querystring")
  , Mandrill    = G.Mandrill    = require("mandrill-api/mandrill")
  , Debug       = G.Debug       = require("bug-killer")
  , Validators  = G.Validators  = require("./apis/validators")
  , Highlight   = G.Highlight   = require("highlight.js")
  , Bloggify    = G.Bloggify    = require("./lib")
  ;

// Dessions
global.sessions = {};

// Start core
Bloggify.start({
    root: __dirname
});

// Require apis after Config was inited
Bloggify.apis = require("./apis")

// Create server
Http.createServer(function(req, res) {

    var pathName = Url.parse(req.url, true).pathname;

    // Normalize path name
    if (pathName.substr(-1) !== "/") {
        pathName += "/";
    }

    var route = Statique.getRoute(pathName)
      , isBlogPost = (
            new RegExp(Config.site.blog.url + "\/[0-9]+.*")
        ).test(pathName)
      ;

    if (route && route.url || isBlogPost) {
        Bloggify.apis["handlePage:" + req.method](
            req, res, pathName, route, null, isBlogPost
        );
        return;
    }

    // Serve files
    Statique.serve(req, res);
}).listen(Config.port, Config.ipaddress);

// Print some output
Debug.log(
    "Server running at http://" + (Config.ipaddress || "localhost")
  + ":" + Config.port
  , "info"
);
<commit_msg>Handle error pages<commit_after>// Dependencies
var G = global
  , Statique    = G.Statique    = require("statique")
  , Utils       = G.Utils       = require("./utils")
  , Fs          = G.Fs          = require("fs")
  , Url         = G.Url         = require("url")
  , Http        = G.Http        = require("http")
  , Marked      = G.Marked      = require("marked")
  , Moment      = G.Moment      = require("moment")
  , Mustache    = G.Mustache    = require("mustache")
  , QueryString = G.QueryString = require("querystring")
  , Mandrill    = G.Mandrill    = require("mandrill-api/mandrill")
  , Debug       = G.Debug       = require("bug-killer")
  , Validators  = G.Validators  = require("./apis/validators")
  , Highlight   = G.Highlight   = require("highlight.js")
  , Bloggify    = G.Bloggify    = require("./lib")
  ;

// Dessions
global.sessions = {};

// Start core
Bloggify.start({
    root: __dirname
});

// Require apis after Config was inited
Bloggify.apis = require("./apis")

// Create server
Http.createServer(function(req, res) {

    var pathName = Url.parse(req.url, true).pathname;

    // Normalize path name
    if (pathName.substr(-1) !== "/") {
        pathName += "/";
    }

    // Error pages
    if (/\/[4-9][0-9][0-9]\//.test(pathName)) {
        return Statique.serve(req, res);
    }

    var route = Statique.getRoute(pathName)
      , isBlogPost = (
            new RegExp(Config.site.blog.url + "\/[0-9]+.*")
        ).test(pathName)
      ;

    if (route && route.url || isBlogPost) {
        Bloggify.apis["handlePage:" + req.method](
            req, res, pathName, route, null, isBlogPost
        );
        return;
    }

    // Serve files
    Statique.serve(req, res);
}).listen(Config.port, Config.ipaddress);

// Print some output
Debug.log(
    "Server running at http://" + (Config.ipaddress || "localhost")
  + ":" + Config.port
  , "info"
);
<|endoftext|>


<commit_before>var Botkit = require('botkit')
var request = require('request')
var mapsToken = process.env.GOOGLE_MAPS_TOKEN

// Expect a SLACK_TOKEN environment variable
var slackToken = process.env.SLACK_TOKEN
if (!slackToken) {
  console.error('SLACK_TOKEN is required!')
  process.exit(1)
}

var controller = Botkit.slackbot()
var bot = controller.spawn({
  token: slackToken
})

bot.startRTM(function (err, bot, payload) {
  if (err) {
    throw new Error('Could not connect to Slack')
  }
})

controller.hears(['where'], ['direct_message', 'direct_mention'], function (bot, message) {
	request('http://tracker.brandonevans.ca/points/latest', function(error, response, body) {
		var point = JSON.parse(body);
		var prefix = point.inside ? " in " : " near ";
		var location = point.name;

		var text = 'I\'m' + prefix + location
		var imageURL = 'https://maps.googleapis.com/maps/api/staticmap?center=' + encodeURIComponent(location) + '&zoom=6&size=600x300&maptype=roadmap&key=' + mapsToken
		var attachments = [{
			username: "slug",
			fallback: text,
			pretext: ':round_pushpin: ' + text,
			image_url: imageURL
		}]
		bot.reply(message, {attachments: attachments});
	});
});

controller.hears(['.*'], ['direct_message', 'direct_mention'], function (bot, message) {
	bot.reply(message, "Sorry, I didn't understand that. I blame my creator. :face_with_rolling_eyes:\n My source is here if you'd like to suggest changes: https://github.com/interstateone/faster-downhill-bot");
});
<commit_msg>Change image size to fit within Slack's preferred size<commit_after>var Botkit = require('botkit')
var request = require('request')
var mapsToken = process.env.GOOGLE_MAPS_TOKEN

// Expect a SLACK_TOKEN environment variable
var slackToken = process.env.SLACK_TOKEN
if (!slackToken) {
  console.error('SLACK_TOKEN is required!')
  process.exit(1)
}

var controller = Botkit.slackbot()
var bot = controller.spawn({
  token: slackToken
})

bot.startRTM(function (err, bot, payload) {
  if (err) {
    throw new Error('Could not connect to Slack')
  }
})

controller.hears(['where'], ['direct_message', 'direct_mention'], function (bot, message) {
	request('http://tracker.brandonevans.ca/points/latest', function(error, response, body) {
		var point = JSON.parse(body);
		var prefix = point.inside ? " in " : " near ";
		var location = point.name;

		var text = 'I\'m' + prefix + location
		var imageURL = 'https://maps.googleapis.com/maps/api/staticmap?center=' + encodeURIComponent(location) + '&zoom=6&size=400x250&maptype=roadmap&key=' + mapsToken
		var attachments = [{
			username: "slug",
			fallback: text,
			pretext: ':round_pushpin: ' + text,
			image_url: imageURL
		}]
		bot.reply(message, {attachments: attachments});
	});
});

controller.hears(['.*'], ['direct_message', 'direct_mention'], function (bot, message) {
	bot.reply(message, "Sorry, I didn't understand that. I blame my creator. :face_with_rolling_eyes:\n My source is here if you'd like to suggest changes: https://github.com/interstateone/faster-downhill-bot");
});
<|endoftext|>


<commit_before>var express = require('express');
var app = express();
var bodyParser=require('body-parser'); // required for AJAX POST
var mongodb = require('mongodb'); // mongodb package for node
var mc = mongodb.MongoClient;
var url='mongodb://localhost:27017/test';
var mqtt=require('mqtt');
var client=mqtt.connect('mqtt://broker.hivemq.com');

// connecting to the mongo db server
mc.connect(url,function(err,db){
	if(!err){
		console.log("Connected!");
	}
	collection=db.collection('sample');
});

app.set('port',5000);

app.use(express.static(__dirname+'/public')); // directory for all css and js
app.use('/favicon.ico', express.static('images/favicon.ico'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));

app.set('views',__dirname+'/views'); // directory for all ejs files
app.set('view engine','ejs'); // using .ejs instead of .html

app.get('/ledger/login',function(req,res){
	console.log("GET /ledger/login")
	res.render("login.ejs")
});

// GET /ledger
app.get('/ledger',function(request,response){
	console.log("GET /ledger")
	response.render("ledger_home.ejs");
});

// POST /ledger (called when the button is clicked)
app.post('/ledger',function(request,response){
	console.log("POST /ledger")
	var test=request.body;
	collection.insert({"id":1,"name":test['msg']});
	console.log("Inserted!");
	collection.find({}).toArray(function(err, docs) {
    	console.log("Found the following records");
    	// Printing all the documents in the sample in a nested JSON format
    	console.dir(docs);
    	// Sending back the third JSON document
    	response.send(docs[2]);
  	});
});

/* MPCA PART (MQTT) */
app.get('/ledger/react-check',function(req,res){
	console.log("GET /ledger/react-check");
	res.end("Checking stuff");
});

app.post('/ledger/react-check',function(req,res){
	console.log('POST /ledger/react-native');
	var data=req.body
	console.log('Attempting to connect...');
	client.on('connect',function(){
		client.subscribe('mpca');
		console.log('Publishing...');
		client.publish('mpca','the random message');
	});
	res.send(data);
});

// Listening on 127.0.0.1:5000
app.listen(app.get('port'),function(){
	console.log("Node app is running on localhost:",app.get('port'));
});
<commit_msg>mpca mqtt check<commit_after>var express = require('express');
var app = express();
var bodyParser=require('body-parser'); // required for AJAX POST
var mongodb = require('mongodb'); // mongodb package for node
var mc = mongodb.MongoClient;
var url='mongodb://localhost:27017/test';
var mqtt=require('mqtt');
var client=mqtt.connect('mqtt://broker.hivemq.com');

// connecting to the mongo db server
mc.connect(url,function(err,db){
	if(!err){
		console.log("Connected!");
	}
	collection=db.collection('sample');
});

app.set('port',5000);

app.use(express.static(__dirname+'/public')); // directory for all css and js
app.use('/favicon.ico', express.static('images/favicon.ico'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));

app.set('views',__dirname+'/views'); // directory for all ejs files
app.set('view engine','ejs'); // using .ejs instead of .html

app.get('/ledger/login',function(req,res){
	console.log("GET /ledger/login")
	res.render("login.ejs")
});

// GET /ledger
app.get('/ledger',function(request,response){
	console.log("GET /ledger")
	response.render("ledger_home.ejs");
});

// POST /ledger (called when the button is clicked)
app.post('/ledger',function(request,response){
	console.log("POST /ledger")
	var test=request.body;
	collection.insert({"id":1,"name":test['msg']});
	console.log("Inserted!");
	collection.find({}).toArray(function(err, docs) {
    	console.log("Found the following records");
    	// Printing all the documents in the sample in a nested JSON format
    	console.dir(docs);
    	// Sending back the third JSON document
    	response.send(docs[2]);
  	});
});

/* MPCA PART (MQTT) */
app.get('/ledger/react-check',function(req,res){
	console.log("GET /ledger/react-check");
	console.log('Attempting to connect...');
	res.end("Checking stuff..")
});

app.post('/ledger/react-check',function(req,res){
	console.log('POST /ledger/react-native');
	var data=req.body
	console.log('Attempting to connect...');
	var client=mqtt.connect('mqtt://broker.hivemq.com');
	client.on('connect',function(){
		client.subscribe('mpca');
		console.log('Publishing...');
		client.publish('mpca','the random message');
	});
	res.send(data);
});

// Listening on 127.0.0.1:5000
app.listen(app.get('port'),function(){
	console.log("Node app is running on localhost:",app.get('port'));
});
<|endoftext|>


<commit_before>module.exports = function (stylecow) {

	stylecow.addTask({
		//Use var() function
		"Function": {
			var: function (fn) {
				var arguments = fn.getValue();
				var value = fn.ancestor({type: 'Rule'}).getData(arguments[0]) || arguments[1];

				if (value) {
					fn.replaceWith(value);
				}

			}
		},

		//Save new --variables
		Declaration: function (declaration) {
			if (declaration.name.indexOf('--') === 0) {
				var rule = declaration.ancestor({type: 'Rule'});

				if (rule.hasChild({type: 'Selector', string: [':root', 'html']})) {
					rule.ancestor({type: 'Root'}).setData(declaration.name, declaration.value);
				} else {
					rule.setData(declaration.name, declaration.value);
				}

				declaration.remove();
			}
		}
	});
};
<commit_msg>changes for the new api in stylecow<commit_after>module.exports = function (stylecow) {

	stylecow.addTask({
		//Use var() function
		"Function": {
			var: function (fn) {
				var arguments = fn.getContent();
				var value = fn.parent({type: 'Rule'}).getData(arguments[0]) || arguments[1];

				if (value) {
					fn.replaceWith(value);
				}

			}
		},

		//Save new --variables
		Declaration: function (declaration) {
			if (declaration.name.indexOf('--') === 0) {
				var rule = declaration.parent({type: 'Rule'});

				if (rule.hasChild({type: 'Selector', string: [':root', 'html']})) {
					rule.parent({type: 'Root'}).setData(declaration.name, declaration.value);
				} else {
					rule.setData(declaration.name, declaration.value);
				}

				declaration.remove();
			}
		}
	});
};
<|endoftext|>


<commit_before>var ws = require('ws');
var https = require('https');

function debuglog(msg) {
  if (ModeDevice.debug) {
    console.log(msg);
  }
}

var defaultEventErrorCallback = function(error) {
  debuglog('Event Error: ' + error);
};

var defaultErrorCallback = function(error) {
  debuglog('Error: ' + error);
  this.scheduleReconnect(false);
};

var defaultCloseCallback = function(code, message) {
  debuglog('Connection is closed: ' + code + ' ' + message);
  if (this.pingTimer != null) {
    clearInterval(this.pingTimer);
  }
  // reconnect
  this.scheduleReconnect(false);
};

var defaultOpenCallback = function() {
  debuglog('Websocket client is connected');
  this.retryWait = 1;
  // start pinging
  var pingHandler = function() {
    debuglog('Sending a websocket ping');
    this.triggerPing();
  };

  this.pingTimer = setInterval(pingHandler.bind(this), 20 * 1000);
};

var defaultCommandCallback = function(message, flags) {
  debuglog('Received JSON message: "' + message + '"');
  debuglog('Received flag: "' + JSON.stringify(flags) + '"');
};

var defaultPongCallback = function() {
  debuglog('Received a websocket pong');
};

var commandHandler = function(message, flags) {
  debuglog('Received a command');
  debuglog('Raw message: "' + message + '"');
  var commandJson = JSON.parse(message);
  this.commandCallback(commandJson, flags);
};

var ModeDevice = function(deviceId, token) {
  this.debug = false;
  this.token = token;
  this.deviceId = deviceId;
  this.retryWait = 1;  // retry wait in msec
  this.retryWaitFib = 1;  // retry wait in msec
  this.timeout = 30 * 1000; // request timeout in msec
  this.websocket = null;
  this.eventCounter = 0;

  this.host = 'api.tinkermode.com';
  this.port = 443;  // default to wss.

  this.eventErrorCallback = defaultEventErrorCallback;
  this.errorCallback = defaultErrorCallback;
  this.closeCallback = defaultCloseCallback;
  this.openCallback = defaultOpenCallback;
  this.commandCallback = defaultCommandCallback;
  this.pongCallback = defaultPongCallback;
  this.eventFinishedCallback = defaultEventFinishedCallback;
  this.pingTimer = null;
};

ModeDevice.prototype.reconnect = function() {
  debuglog('Reconnecting websocket');
  if (this.websocket != null) {
    debuglog('Closing websocket');
    this.websocket.close();
    this.websocket = null;
  }
  var target = 'wss://' + this.host + ':' + this.port + '/devices/' + this.deviceId + '/command';
  debuglog("Connecting to " + target);
  this.websocket = new ws(target, {
    headers: {
      "Authorization": 'ModeCloud ' + this.token
    }
  });
  this.websocket.on('error', this.errorCallback.bind(this));
  this.websocket.on('close', this.closeCallback.bind(this));
  this.websocket.on('open', this.openCallback.bind(this));
  this.websocket.on('message', commandHandler.bind(this));
  this.websocket.on('pong', this.pongCallback.bind(this));
};

ModeDevice.prototype.scheduleReconnect = function(firstConnect) {
  var wait = firstConnect ? 0 : this.retryWait;
  debuglog('Reconnect websocket in ' + wait + ' seconds');
  var device = this;
  setTimeout(function() {
    device.reconnect();
  }, wait * 1000);

  // Only if less than 60 sec, we increment waiting time according to Fibonacci numbers.
  if (this.retryWait < 60) {
    var fib = this.retryWaitFib;
    this.retryWaitFib = this.retryWait;
    this.retryWait += fib;
  }
};

ModeDevice.prototype.listenCommands = function() {
  this.scheduleReconnect(true);
};

ModeDevice.prototype.triggerPing = function() {
  this.websocket.ping();
};

var defaultEventFinishedCallback = function() {
};

ModeDevice.prototype.triggerEvent = function(eventType, eventData) {
  this.eventCounter += 1;
  var eventId = this.eventCounter;
  debuglog('Triggering event #' + eventId);

  if((typeof eventType) != "string" && !(eventType instanceof String)) {
    throw "eventType must be string";
  }

  if((typeof eventData) != "object" || (eventData instanceof Array)) {
    throw "eventData must be object";
  }

  var event = {
    "eventType": eventType,
    "eventData": eventData
  };

  var jsonData = JSON.stringify(event);

  var options = {
    host: this.host,
    port: this.port,
    path: '/devices/' + this.deviceId + '/event',
    method: 'PUT',
    headers: {
      "Content-Type": 'application/json',
      "Content-Length": jsonData.length,
      "Authorization": 'ModeCloud ' + this.token
    }
  };

  var req = https.request(options, function(res) {
    var that = this;
    var body = '';
    var wasSuccess = false;
    if (res.statusCode == 204) {
      wasSuccess = true;
    }

    // need to read response data to trigger 'end' event.
    res.on('data', function(chunk) {
      body += chunk;
    });
    res.on('end', function() {
      if (wasSuccess) {
        debuglog('Event #' + eventId + ' triggered');
        that.eventFinishedCallback();
      } else {
        debuglog('Event #' + eventId + ' failed with an error');
        that.eventErrorCallback(body);
      }
    });
  }.bind(this));
  req.on('socket', function() {
    debuglog('Socket is allocated to event #' + eventId);
  });
  req.setTimeout(this.timeout, function() {
    debuglog('Event #' + eventId + ' timed out');
    req.abort();
  });
  req.write(jsonData);
  req.end();

  req.on('error', this.eventErrorCallback.bind(this));
};

module.exports = ModeDevice;
<commit_msg>Limit number of outstanding requests under unreliable network environment (deal with packet losses).<commit_after>var ws = require('ws');
var https = require('https');

function debuglog(msg) {
  if (ModeDevice.debug) {
    console.log(msg);
  }
}

var defaultEventErrorCallback = function(error) {
  debuglog('Event Error: ' + error);
};

var defaultErrorCallback = function(error) {
  debuglog('Error: ' + error);
  this.scheduleReconnect(false);
};

var defaultCloseCallback = function(code, message) {
  debuglog('Connection is closed: ' + code + ' ' + message);
  if (this.pingTimer != null) {
    clearInterval(this.pingTimer);
  }
  // reconnect
  this.scheduleReconnect(false);
};

var defaultOpenCallback = function() {
  debuglog('Websocket client is connected');
  this.retryWait = 1;
  // start pinging
  var pingHandler = function() {
    debuglog('Sending a websocket ping');
    this.triggerPing();
  };

  this.pingTimer = setInterval(pingHandler.bind(this), 20 * 1000);
};

var defaultCommandCallback = function(message, flags) {
  debuglog('Received JSON message: "' + message + '"');
  debuglog('Received flag: "' + JSON.stringify(flags) + '"');
};

var defaultPongCallback = function() {
  debuglog('Received a websocket pong');
};

var commandHandler = function(message, flags) {
  debuglog('Received a command');
  debuglog('Raw message: "' + message + '"');
  var commandJson = JSON.parse(message);
  this.commandCallback(commandJson, flags);
};

var ModeDevice = function(deviceId, token) {
  this.debug = false;
  this.token = token;
  this.deviceId = deviceId;
  this.retryWait = 1;  // retry wait in msec
  this.retryWaitFib = 1;  // retry wait in msec
  this.timeout = 10 * 1000; // request timeout in msec
  this.maxRequests = 10;  // number of simultaneous requests it will process
  this.websocket = null;
  this.eventCounter = 0;  // sequence id for events

  this.host = 'api.tinkermode.com';
  this.port = 443;  // default to wss.

  this.eventErrorCallback = defaultEventErrorCallback;
  this.errorCallback = defaultErrorCallback;
  this.closeCallback = defaultCloseCallback;
  this.openCallback = defaultOpenCallback;
  this.commandCallback = defaultCommandCallback;
  this.pongCallback = defaultPongCallback;
  this.eventFinishedCallback = defaultEventFinishedCallback;
  this.pingTimer = null;
  // Increase the number of sockets for slow networks.
  https.globalAgent.maxSockets = 20;  // originally 5.
};

ModeDevice.prototype.reconnect = function() {
  debuglog('Reconnecting websocket');
  if (this.websocket != null) {
    debuglog('Closing websocket');
    this.websocket.close();
    this.websocket = null;
  }
  var target = 'wss://' + this.host + ':' + this.port + '/devices/' + this.deviceId + '/command';
  debuglog("Connecting to " + target);
  this.websocket = new ws(target, {
    headers: {
      "Authorization": 'ModeCloud ' + this.token
    }
  });
  this.websocket.on('error', this.errorCallback.bind(this));
  this.websocket.on('close', this.closeCallback.bind(this));
  this.websocket.on('open', this.openCallback.bind(this));
  this.websocket.on('message', commandHandler.bind(this));
  this.websocket.on('pong', this.pongCallback.bind(this));
};

ModeDevice.prototype.scheduleReconnect = function(firstConnect) {
  var wait = firstConnect ? 0 : this.retryWait;
  debuglog('Reconnect websocket in ' + wait + ' seconds');
  var device = this;
  setTimeout(function() {
    device.reconnect();
  }, wait * 1000);

  // Only if less than 60 sec, we increment waiting time according to Fibonacci numbers.
  if (this.retryWait < 60) {
    var fib = this.retryWaitFib;
    this.retryWaitFib = this.retryWait;
    this.retryWait += fib;
  }
};

ModeDevice.prototype.listenCommands = function() {
  this.scheduleReconnect(true);
};

ModeDevice.prototype.triggerPing = function() {
  this.websocket.ping();
};

var defaultEventFinishedCallback = function() {
};

ModeDevice.prototype.triggerEvent = function(eventType, eventData) {
  this.eventCounter += 1;
  var eventId = this.eventCounter;
  debuglog('Triggering event #' + eventId);

  if((typeof eventType) != "string" && !(eventType instanceof String)) {
    throw "eventType must be string";
  }

  if((typeof eventData) != "object" || (eventData instanceof Array)) {
    throw "eventData must be object";
  }

  // Try not to pile up requests when the network is unstable.
  var outstandingRequests = https.globalAgent.requests;
  var hostPort = this.host + ':' + this.port;
  if (outstandingRequests[hostPort] !== undefined) {
    if (outstandingRequests[hostPort].length >= this.maxRequests) {
      // If there are enough requests queued up, it doesn't attempt to issue a request.
      var msg = 'Too many outstanding requests:' + outstandingRequests[hostPort].length;
      debuglog(msg);
      this.eventErrorCallback(msg);
      return;
    }
  }

  var event = {
    "eventType": eventType,
    "eventData": eventData
  };

  var jsonData = JSON.stringify(event);

  var options = {
    host: this.host,
    port: this.port,
    path: '/devices/' + this.deviceId + '/event',
    method: 'PUT',
    headers: {
      "Content-Type": 'application/json',
      "Content-Length": jsonData.length,
      "Authorization": 'ModeCloud ' + this.token
    }
  };

  var req = https.request(options, function(res) {
    var that = this;
    var body = '';
    var wasSuccess = false;
    if (res.statusCode == 204) {
      wasSuccess = true;
    }

    // need to read response data to trigger 'end' event.
    res.on('data', function(chunk) {
      body += chunk;
    });
    res.on('end', function() {
      if (wasSuccess) {
        debuglog('Event #' + eventId + ' triggered');
        that.eventFinishedCallback();
      } else {
        debuglog('Event #' + eventId + ' failed with an error');
        that.eventErrorCallback(body);
      }
    });
  }.bind(this));
  req.on('socket', function() {
    debuglog('Socket is allocated to event #' + eventId);
  });
  req.setTimeout(this.timeout, function() {
    debuglog('Event #' + eventId + ' timed out');
    req.abort();
  });
  req.write(jsonData);
  req.end();

  req.on('error', this.eventErrorCallback.bind(this));
};

module.exports = ModeDevice;
<|endoftext|>


<commit_before>'use strict';

var mongoose          = require('mongoose'),
      _               = require('lodash'),
      inflection      = require('inflection'),
      slugs           = require('slugs');

function slugify(model, options){
    var slugParts = _.values(_.pick(model, options.source));
    return slugs(slugParts.join(' '));
}

function getModel(document, options){
    var modelName = options.modelName || inflection.singularize(inflection.camelize(document.collection.name));
    return document.collection.conn.model(modelName);
}

function incrementAndSave(document, options, cb){
    var Model = getModel(document, options);
    var params = {};
    var slugbaseKey = options.slugBase;
    var itKey = options.slugIt;
    params[slugbaseKey] = document[slugbaseKey];

    Model.findOne(params).sort('-'+itKey).exec(function(e, doc){
        if(e) return cb(e);

        var it = (doc[itKey] || 0) + Math.ceil(Math.random()*10);

        document[itKey] = it;
        document[options.slugName] = document[slugbaseKey]+'-'+it;
        document.markModified(slugbaseKey);

        _.forEach(options.source, function(item){
            document.markModified(item);
        });

        return document.save(cb);
    });
}

function Slugin(schema, options){
    options = _.defaults(options || {}, Slugin.defaultOptions);
    if(_.isString(options.source))
        options.source = [options.source];
    options.slugIt = options.slugName + '_it';
    options.slugBase = options.slugName + '_base';
    var fields = {};
    fields[options.slugName] = {
        type : String,
        unique: true
    };

    fields[options.slugBase] = {
        type: String,
        index:true
    };

    fields[options.slugIt] = {
        type: Number
    };

    schema.add(fields);

    schema.pre('save', function(next){
        var self = this;
        var slugBase = slugify(this,options);
        console.log('Old base: %s ; New Base: %s', this[options.slugBase], slugBase);
        if(this[options.slugBase] !== slugBase){
            this[options.slugName] = slugBase;
            this[options.slugBase] = slugBase;
            delete this[options.slugIt];
        }
        next();
    });

    schema.methods.save = function(cb){
        var self = this;
        mongoose.Model.prototype.save.call(self, function(e, model, num){
            if(e && (e.code === 11000  || e.code === 11001) && !!~e.err.indexOf(self[options.slugName])){
                incrementAndSave(self, options, cb);
            }else{
                cb(e,model,num);
            }
        });
    };
}

Slugin.defaultOptions = {
    slugName : 'slug',
    source : 'title',
    modelName : null
};

module.exports = Slugin;
<commit_msg>Remove console log message<commit_after>'use strict';

var mongoose          = require('mongoose'),
      _               = require('lodash'),
      inflection      = require('inflection'),
      slugs           = require('slugs');

function slugify(model, options){
    var slugParts = _.values(_.pick(model, options.source));
    return slugs(slugParts.join(' '));
}

function getModel(document, options){
    var modelName = options.modelName || inflection.singularize(inflection.camelize(document.collection.name));
    return document.collection.conn.model(modelName);
}

function incrementAndSave(document, options, cb){
    var Model = getModel(document, options);
    var params = {};
    var slugbaseKey = options.slugBase;
    var itKey = options.slugIt;
    params[slugbaseKey] = document[slugbaseKey];

    Model.findOne(params).sort('-'+itKey).exec(function(e, doc){
        if(e) return cb(e);

        var it = (doc[itKey] || 0) + Math.ceil(Math.random()*10);

        document[itKey] = it;
        document[options.slugName] = document[slugbaseKey]+'-'+it;
        document.markModified(slugbaseKey);

        _.forEach(options.source, function(item){
            document.markModified(item);
        });

        return document.save(cb);
    });
}

function Slugin(schema, options){
    options = _.defaults(options || {}, Slugin.defaultOptions);
    if(_.isString(options.source))
        options.source = [options.source];
    options.slugIt = options.slugName + '_it';
    options.slugBase = options.slugName + '_base';
    var fields = {};
    fields[options.slugName] = {
        type : String,
        unique: true
    };

    fields[options.slugBase] = {
        type: String,
        index:true
    };

    fields[options.slugIt] = {
        type: Number
    };

    schema.add(fields);

    schema.pre('save', function(next){
        var self = this;
        var slugBase = slugify(this,options);
        if(this[options.slugBase] !== slugBase){
            this[options.slugName] = slugBase;
            this[options.slugBase] = slugBase;
            delete this[options.slugIt];
        }
        next();
    });

    schema.methods.save = function(cb){
        var self = this;
        mongoose.Model.prototype.save.call(self, function(e, model, num){
            if(e && (e.code === 11000  || e.code === 11001) && !!~e.err.indexOf(self[options.slugName])){
                incrementAndSave(self, options, cb);
            }else{
                cb(e,model,num);
            }
        });
    };
}

Slugin.defaultOptions = {
    slugName : 'slug',
    source : 'title',
    modelName : null
};

module.exports = Slugin;
<|endoftext|>


<commit_before>var parser = require('yaml-js')

module.exports = function(string){
  var body = string
    , attributes = {}
    , match = matcher(string, '= yaml =') || matcher(string, '---')

  if (match){
    attributes = parser.load(match[2].replace(/^\s+|\s+$/g, ''))
    body = string.replace(match[0], '')
  }

  return { attributes: attributes, body: body }
}

function matcher(string, seperator){
  if (process.platform === 'win32')
    var seperator = seperator || '---'
      , pattern = '^('
        + seperator
        + '$([\\s\\S]*?)'
        + seperator+'$\\r\\n)'
      , regex = new RegExp(pattern, 'm')
      , match = regex.exec(string)

  else
    var seperator = seperator || '---'
      , pattern = '^('
        + seperator
        + '$([\\s\\S]*?)'
        + seperator+'$\\n)'
      , regex = new RegExp(pattern, 'm')
      , match = regex.exec(string)

  if (match && match.length > 0) return match
}
<commit_msg>Fixes #10<commit_after>var parser = require('yaml-js')

module.exports = function(string){
  var body = string
    , attributes = {}
    , match = matcher(string, '= yaml =') || matcher(string, '---')

  if (match){
    attributes = parser.load(match[2].replace(/^\s+|\s+$/g, '')) || {}
    body = string.replace(match[0], '')
  }

  return { attributes: attributes, body: body }
}

function matcher(string, seperator){
  if (process.platform === 'win32')
    var seperator = seperator || '---'
      , pattern = '^('
        + seperator
        + '$([\\s\\S]*?)'
        + seperator+'$\\r\\n)'
      , regex = new RegExp(pattern, 'm')
      , match = regex.exec(string)

  else
    var seperator = seperator || '---'
      , pattern = '^('
        + seperator
        + '$([\\s\\S]*?)'
        + seperator+'$\\n)'
      , regex = new RegExp(pattern, 'm')
      , match = regex.exec(string)

  if (match && match.length > 0) return match
}
<|endoftext|>


<commit_before>"use strict";

/*
 * GitHub Repository: https://github.com/Unchosen/express-http2-workaround
 * NPM Package: https://www.npmjs.com/package/express-http2-workaround
 *
 * This returns an express middleware function.
 * If 'app' is passed, the middleware will be automatically applied.
 * This must be done before ANY other middleware that a http2 request will pass to.
 *
 * Example Use:
 * var expressHTTP2Workaround = require('express-http2-workaround');
 * expressApp.use(expressHTTP2Workaround({ express:express, http2:http2 }));
 *
 * Or:
 * require('express-http2-workaround')({ express:express, http2:http2, app:expressApp });
 *
 * See README.md for more information.
 */

var me = module.exports = function(obj){

	// Arguments Validation
	if(!('express' in obj)) throw new Error('Missing express argument');
	if(!('http2' in obj)) throw new Error('Missing http2 argument');
	if('app' in obj && !('use' in obj.app)) throw new Error('app argument must be an express application');
	var expressApp = ('app' in obj && 'use' in obj.app) ? obj.app : null;

	// HTTP2 Validation
	var http2 = obj.http2;
	if(!('IncomingMessage' in http2)) throw new Error('Missing IncomingMessage property on http2 module?');
	if(!('prototype' in http2.IncomingMessage)) throw new Error('Missing prototype property on http2 IncomingMessage module?');
	if(!('ServerResponse' in http2)) throw new Error('Missing ServerResponse property on http2 module?');
	if(!('prototype' in http2.ServerResponse)) throw new Error('Missing prototype property on http2 ServerResponse module?');

	// Express Validation
	var express = obj.express;
	if(!('request' in express)) throw new Error('Missing request property on express module?');
	if(!('response' in express)) throw new Error('Missing response property on express module?');

	// Find Express Request Module
	var requestCachedKey = null;
	var requestCachedModule = null;
	for(var k in require.cache){
		if(require.cache[k].exports===express.request){
			requestCachedKey = k;
			requestCachedModule = require.cache[k];
			break;
		}
	}
	if(!requestCachedKey || !requestCachedModule) throw new Error('Failed to find express request module. Express must be required before running this function.');

	// Find Express Response Module
	var responseCachedKey = null;
	var responseCachedModule = null;
	for(var k in require.cache){
		if(require.cache[k].exports===express.response){
			responseCachedKey = k;
			responseCachedModule = require.cache[k];
			break;
		}
	}
	if(!responseCachedKey || !responseCachedModule) throw new Error('Failed to find express response module. Express must be required before running this function.');

	// Require a new instance of Express Request Module
	delete require.cache[requestCachedKey]; // Temporary remove from cache
	me.requestHTTP2 = require(requestCachedModule.filename);
	require.cache[requestCachedKey] = requestCachedModule; // Restore original into cache

	// Require a new instance of Express Response Module
	delete require.cache[responseCachedKey]; // Temporary remove from cache
	me.responseHTTP2 = require(responseCachedModule.filename);
	require.cache[responseCachedKey] = responseCachedModule; // Restore original into cache

	// Set the new request and response modules to have the http2 prototypes
	me.requestHTTP2.__proto__ = http2.IncomingMessage.prototype;
	me.responseHTTP2.__proto__ = http2.ServerResponse.prototype;

	// If 'app' argument, apply middleware
	if(expressApp) expressApp.use(me.middlewareFunc);

	// Finish
	return me.middlewareFunc;
};

me.noOp = function(){};

// These post-run methods are available to use

me.middlewareFunc = function expressHTTP2WorkaroundMiddleware(req, res, next){
	if(req.httpVersionMajor===2){
		me.setRequestAsHTTP2(req);
		me.setResponseAsHTTP2(res);
	}
	next();
};

// Methods to update request and response prototypes with HTTP2 prototypes
// No argument validation, we want to keep it fast and simple

// I am using Object.defineProperty because express/lib/application.js:230 overwrites the .__proto__ property for request and response on sub express applications
// To ignore the overwrite, I am setting the property as configurable: true, but set() as noOp
// This is quite risky, but any other way is even more dangerous

me.setRequestAsHTTP2 = function(req){
	var expressApp = req.app;
	req.__proto__ = me.requestHTTP2;
	Object.defineProperty(req,'__proto__',{
		get: function(){ return me.requestHTTP2; },
		set: me.noOp,
		enumerable: true,
		configurable: true
	});
	req.app = expressApp;
};

me.setResponseAsHTTP2 = function(res){
	var expressApp = res.app;
	res.__proto__ = me.responseHTTP2;
	Object.defineProperty(res,'__proto__',{
		get: function(){ return me.responseHTTP2; },
		set: me.noOp,
		enumerable: true,
		configurable: true
	});
	res.app = expressApp;
};
<commit_msg>Optimise defineProperty calls<commit_after>"use strict";

/*
 * GitHub Repository: https://github.com/Unchosen/express-http2-workaround
 * NPM Package: https://www.npmjs.com/package/express-http2-workaround
 *
 * This returns an express middleware function.
 * If 'app' is passed, the middleware will be automatically applied.
 * This must be done before ANY other middleware that a http2 request will pass to.
 *
 * Example Use:
 * var expressHTTP2Workaround = require('express-http2-workaround');
 * expressApp.use(expressHTTP2Workaround({ express:express, http2:http2 }));
 *
 * Or:
 * require('express-http2-workaround')({ express:express, http2:http2, app:expressApp });
 *
 * See README.md for more information.
 */

var me = module.exports = function(obj){

	// Arguments Validation
	if(!('express' in obj)) throw new Error('Missing express argument');
	if(!('http2' in obj)) throw new Error('Missing http2 argument');
	if('app' in obj && !('use' in obj.app)) throw new Error('app argument must be an express application');
	var expressApp = ('app' in obj && 'use' in obj.app) ? obj.app : null;

	// HTTP2 Validation
	var http2 = obj.http2;
	if(!('IncomingMessage' in http2)) throw new Error('Missing IncomingMessage property on http2 module?');
	if(!('prototype' in http2.IncomingMessage)) throw new Error('Missing prototype property on http2 IncomingMessage module?');
	if(!('ServerResponse' in http2)) throw new Error('Missing ServerResponse property on http2 module?');
	if(!('prototype' in http2.ServerResponse)) throw new Error('Missing prototype property on http2 ServerResponse module?');

	// Express Validation
	var express = obj.express;
	if(!('request' in express)) throw new Error('Missing request property on express module?');
	if(!('response' in express)) throw new Error('Missing response property on express module?');

	// Find Express Request Module
	var requestCachedKey = null;
	var requestCachedModule = null;
	for(var k in require.cache){
		if(require.cache[k].exports===express.request){
			requestCachedKey = k;
			requestCachedModule = require.cache[k];
			break;
		}
	}
	if(!requestCachedKey || !requestCachedModule) throw new Error('Failed to find express request module. Express must be required before running this function.');

	// Find Express Response Module
	var responseCachedKey = null;
	var responseCachedModule = null;
	for(var k in require.cache){
		if(require.cache[k].exports===express.response){
			responseCachedKey = k;
			responseCachedModule = require.cache[k];
			break;
		}
	}
	if(!responseCachedKey || !responseCachedModule) throw new Error('Failed to find express response module. Express must be required before running this function.');

	// Require a new instance of Express Request Module
	delete require.cache[requestCachedKey]; // Temporary remove from cache
	me.requestHTTP2 = require(requestCachedModule.filename);
	require.cache[requestCachedKey] = requestCachedModule; // Restore original into cache

	// Require a new instance of Express Response Module
	delete require.cache[responseCachedKey]; // Temporary remove from cache
	me.responseHTTP2 = require(responseCachedModule.filename);
	require.cache[responseCachedKey] = responseCachedModule; // Restore original into cache

	// Set the new request and response modules to have the http2 prototypes
	me.requestHTTP2.__proto__ = http2.IncomingMessage.prototype;
	me.responseHTTP2.__proto__ = http2.ServerResponse.prototype;

	// If 'app' argument, apply middleware
	if(expressApp) expressApp.use(me.middlewareFunc);

	// Finish
	return me.middlewareFunc;
};

me.noOp = function(){};

// These post-run methods are available to use

me.middlewareFunc = function expressHTTP2WorkaroundMiddleware(req, res, next){
	if(req.httpVersionMajor===2){
		me.setRequestAsHTTP2(req);
		me.setResponseAsHTTP2(res);
	}
	next();
};

// Methods to update request and response prototypes with HTTP2 prototypes
// No argument validation, we want to keep it fast and simple

// I am using Object.defineProperty because express/lib/application.js:230 overwrites the .__proto__ property for request and response on sub express applications
// To ignore the overwrite, I am setting the property as configurable: true, but set() as noOp
// This is quite risky, but any other way is even more dangerous

me.setRequestAsHTTP2 = function(req){
	var expressApp = req.app;
	req.__proto__ = me.requestHTTP2;
	Object.defineProperty(req,'__proto__',me.setRequestAsHTTP2.definePropertyObj);
	req.app = expressApp;
};
me.setRequestAsHTTP2.get = function(){
	return me.requestHTTP2;
};
me.setRequestAsHTTP2.definePropertyObj = {
	get: me.setRequestAsHTTP2.get,
	set: me.noOp,
	enumerable: true,
	configurable: true
};

me.setResponseAsHTTP2 = function(res){
	var expressApp = res.app;
	res.__proto__ = me.responseHTTP2;
	Object.defineProperty(res,'__proto__',me.setResponseAsHTTP2.definePropertyObj);
	res.app = expressApp;
};
me.setResponseAsHTTP2.get = function(){
	return me.responseHTTP2;
};
me.setResponseAsHTTP2.definePropertyObj = {
	get: me.setResponseAsHTTP2.get,
	set: me.noOp,
	enumerable: true,
	configurable: true
};
<|endoftext|>


<commit_before>////////////////////////////////////////
// isgame-online-lambda
//
// Copyright (c) 2017 Jonathan Hardison
////////////////////////////////////////

var config = require('./config');
var alexa = require("alexa-app");
var Raven = require('raven');

//controllers
var gamestatusengine = require('./controllers/game-statusengine');
var gamecheckisvalid = require('./controllers/game-checkisvalid');

let configInstance = new config();
Raven.config(configInstance.ravenDSN).install();

// ALWAYS setup the alexa app and attach it to express before anything else.

var alexaApp = new alexa.app("v1alexaapi");
alexaApp.pre = function(request, response, type) {
    var session = request.getSession();

    if(configInstance.debugEnabled == "false")
    {
        //skip for debug

        if(request.applicationId != "amzn1.ask.skill.ffe13be5-1255-4bf7-a243-b89bf41f373b")
        {
            Raven.captureException(new Error("Invalid ApplicationID: " + request.applicationId + " Type: " + type + " Request: " + request + " Session ID: " + session.applicationId));
            return response.fail("Invalid applicationId");
        }
    }
    else if(configInstance.debugEnabled == "true"){
        console.log("Session APPID: " + session.applicationId);
        console.log("Request APPID: " + request.applicationId);
        console.log("Debug Flag: " + configInstance.debugEnabled);
        console.log(request);
    }
}
alexaApp.error = function(exception, request, response) {
    Raven.captureException(exception);
    response.say("Sorry, an issue occurred.").shouldEndSession(true);
};

alexaApp.launch(function(request, response) {

  response.say("Is Game Online opened. You may ask for the status of a supported online game by saying, is Secret World Legends up? Or, what is the status of The Secret World? So, what may I do for you today?").shouldEndSession(false);
  if(configInstance.debugEnabled=="true"){
        console.log("Entered launch.");
    }
  //return false;
});

// sessionEnded /////////////////////////////////////////////////////////////////
alexaApp.sessionEnded(function(request, response) {
  // cleanup the user's server-side session
  // no response required
  if(configInstance.debugEnabled=="true"){
        console.log("Entered sessionEnded.");
    }
});

// AMAZON.HelpIntent /////////////////////////////////////////////////////////////////
alexaApp.intent("AMAZON.HelpIntent",{
  "slots": {},
  "utterances": []
}, function(request, response) {
    if(configInstance.debugEnabled=="true"){
        console.log("Entered HELP.");
    }
  	var helpoutput = "Is Game Online allows you to check status of some online video games. You may ask for the status of a supported online game by saying, is Secret World Legends up? Or, what is the status of The Secret World? So, what may I do for you today?";
  	response.say(helpoutput).reprompt().shouldEndSession (false);
  	//return false;
});

// AMAZON.StopIntent /////////////////////////////////////////////////////////////////
alexaApp.intent("AMAZON.StopIntent",{
  "slots": {},
  "utterances": []
}, function(request, response) {
  	var stopoutput = "Goodbye.";
  	response.say(stopoutput).shouldEndSession(true);
  	return;
});

// AMAZON.CancelIntent /////////////////////////////////////////////////////////////////
alexaApp.intent("AMAZON.CancelIntent",{
  "slots": {},
  "utterances": []
}, function(request, response) {
  	var canceloutput = "Goodbye.";
  	response.say(canceloutput).shouldEndSession(true);
  	return;
});

// GAME STATUS ///////////////////////////////////////////////////////////////////////
alexaApp.intent("GameStatus",
    {
    //     "dialog": {
    //     type: "delegate"
    // },
    "slots":{
          "AMAZON.VideoGame": "AMAZON.VideoGame"
    },
    "utterances": ["is {AMAZON.VideoGame} up",
        "check on {AMAZON.VideoGame}",
        "what is the status of {AMAZON.VideoGame}",
        "find status of {AMAZON.VideoGame}",
        "is {AMAZON.VideoGame} down",
        "if {AMAZON.VideoGame} is up",
        "if {AMAZON.VideoGame} is down",
        "what the status of {AMAZON.VideoGame} is",
        "if {AMAZON.VideoGame} is online",
        "if {AMAZON.VideoGame} is offline",
        "status of {AMAZON.VideoGame}",
        "{AMAZON.VideoGame} state",
        "is {AMAZON.VideoGame} available",
        "is {AMAZON.VideoGame} operational"]
    },
 function(request, response) {

    try{
        var gameAsked = request.slot("AMAZON.VideoGame");
        if(typeof gameAsked === "undefined" || gameAsked === ""){
            response.say("Tell me the name of a game you want status of.").reprompt("What game would you like status for?").shouldEndSession(false).send();
            //return false;
            if(configInstance.debugEnabled=="true"){
                console.log("Undefined game, response sent: " + response);
            }
        }
        else{

            gameAsked = gameAsked.toLowerCase();
            var gameIsValid = gamecheckisvalid(gameAsked);

            if(gameIsValid !== null){

                return gamestatusengine(gameIsValid).then(function (gamestatus) {
                    if(configInstance.debugEnabled){console.log(gamestatus);}
                    if(gamestatus.status !== null){

                        if(gamestatus.status == "Online")
                        {
                            var responseTextOnline = `Yes, ${gamestatus.name} is currently ${gamestatus.status}`;
                            response.say(responseTextOnline);
                        }
                        else if(gamestatus.status == "Offline")
                        {
                            var responseTextOffline = `No, ${gamestatus.name} is currently ${gamestatus.status}`;
                            response.say(responseTextOffline);
                        }
                        else if(gamestatus.status == "Partial")
                        {
                            var responseTextPartial = `Some ${gamestatus.name} services are unavailable, but not all.`;
                        }
                        else{
                            var responseTextUnknown = `I'm not sure, but chances are ${gameAsked} is currently unavailable.`;
                            response.say(responseTextUnknown);
                        }

                        if(configInstance.debugEnabled=="true"){
                            console.log("Valid game loop, response sent: " + response);
                        }

                        response.shouldEndSession(true);
                        return response.send();

                    }
                    else
                    {

                        response.clear().say(`Sorry there was an error checking the status for ${gameAsked}`);
                        response.shouldEndSession(true);

                        if(configInstance.debugEnabled=="true"){
                            console.log("Error checking game, response sent: " + response);
                        }
                        Raven.captureException("Error checking status of game: " + gameAsked);
                        return response.send();
                    }
                });
            }
            else{
                response.clear().say(`Sorry, ${gameAsked} is not yet supported. We will try to add it in the future. Until then, try again with a supported game.`);
                response.shouldEndSession(true);
                if(configInstance.debugEnabled=="true"){
                    console.log("Unsupported game, response sent: " + response);
                }
                Raven.captureException("Unsupported game: " + gameAsked);
                return response.send();
            }
        }
    }//try
    catch(e){
        Raven.captureException(e);
        if(configInstance.debugEnabled=="true"){
                console.log("Error: " + e);
        }
        response.clear().say("Sorry, something went wrong. Please try your request again.").shouldEndSession(false);
    }//catch
  }
);

exports.handler = alexaApp.lambda();<commit_msg>Adding ability to ask about a game using -ask isgameonline about gamename-<commit_after>////////////////////////////////////////
// isgame-online-lambda
//
// Copyright (c) 2017 Jonathan Hardison
////////////////////////////////////////

var config = require('./config');
var alexa = require("alexa-app");
var Raven = require('raven');

//controllers
var gamestatusengine = require('./controllers/game-statusengine');
var gamecheckisvalid = require('./controllers/game-checkisvalid');

let configInstance = new config();
Raven.config(configInstance.ravenDSN).install();

// ALWAYS setup the alexa app and attach it to express before anything else.

var alexaApp = new alexa.app("v1alexaapi");
alexaApp.pre = function(request, response, type) {
    var session = request.getSession();

    if(configInstance.debugEnabled == "false")
    {
        //skip for debug

        if(request.applicationId != "amzn1.ask.skill.ffe13be5-1255-4bf7-a243-b89bf41f373b")
        {
            Raven.captureException(new Error("Invalid ApplicationID: " + request.applicationId + " Type: " + type + " Request: " + request + " Session ID: " + session.applicationId));
            return response.fail("Invalid applicationId");
        }
    }
    else if(configInstance.debugEnabled == "true"){
        console.log("Session APPID: " + session.applicationId);
        console.log("Request APPID: " + request.applicationId);
        console.log("Debug Flag: " + configInstance.debugEnabled);
        console.log(request);
    }
}
alexaApp.error = function(exception, request, response) {
    Raven.captureException(exception);
    response.say("Sorry, an issue occurred.").shouldEndSession(true);
};

alexaApp.launch(function(request, response) {

  response.say("Is Game Online opened. You may ask for the status of a supported online game by saying, is Secret World Legends up? Or, what is the status of The Secret World? So, what may I do for you today?").shouldEndSession(false);
  if(configInstance.debugEnabled=="true"){
        console.log("Entered launch.");
    }
  //return false;
});

// sessionEnded /////////////////////////////////////////////////////////////////
alexaApp.sessionEnded(function(request, response) {
  // cleanup the user's server-side session
  // no response required
  if(configInstance.debugEnabled=="true"){
        console.log("Entered sessionEnded.");
    }
});

// AMAZON.HelpIntent /////////////////////////////////////////////////////////////////
alexaApp.intent("AMAZON.HelpIntent",{
  "slots": {},
  "utterances": []
}, function(request, response) {
    if(configInstance.debugEnabled=="true"){
        console.log("Entered HELP.");
    }
  	var helpoutput = "Is Game Online allows you to check status of some online video games. You may ask for the status of a supported online game by saying, is Secret World Legends up? Or, what is the status of The Secret World? So, what may I do for you today?";
  	response.say(helpoutput).reprompt().shouldEndSession (false);
  	//return false;
});

// AMAZON.StopIntent /////////////////////////////////////////////////////////////////
alexaApp.intent("AMAZON.StopIntent",{
  "slots": {},
  "utterances": []
}, function(request, response) {
  	var stopoutput = "Goodbye.";
  	response.say(stopoutput).shouldEndSession(true);
  	return;
});

// AMAZON.CancelIntent /////////////////////////////////////////////////////////////////
alexaApp.intent("AMAZON.CancelIntent",{
  "slots": {},
  "utterances": []
}, function(request, response) {
  	var canceloutput = "Goodbye.";
  	response.say(canceloutput).shouldEndSession(true);
  	return;
});

// GAME STATUS ///////////////////////////////////////////////////////////////////////
alexaApp.intent("GameStatus",
    {
    //     "dialog": {
    //     type: "delegate"
    // },
    "slots":{
          "AMAZON.VideoGame": "AMAZON.VideoGame"
    },
    "utterances": ["is {AMAZON.VideoGame} up",
        "check on {AMAZON.VideoGame}",
        "what is the status of {AMAZON.VideoGame}",
        "find status of {AMAZON.VideoGame}",
        "is {AMAZON.VideoGame} down",
        "if {AMAZON.VideoGame} is up",
        "if {AMAZON.VideoGame} is down",
        "what the status of {AMAZON.VideoGame} is",
        "if {AMAZON.VideoGame} is online",
        "if {AMAZON.VideoGame} is offline",
        "status of {AMAZON.VideoGame}",
        "{AMAZON.VideoGame} state",
        "is {AMAZON.VideoGame} available",
        "is {AMAZON.VideoGame} operational",
        "about {AMAZON.VideoGame}"]
    },
 function(request, response) {

    try{
        var gameAsked = request.slot("AMAZON.VideoGame");
        if(typeof gameAsked === "undefined" || gameAsked === ""){
            response.say("Tell me the name of a game you want status of.").reprompt("What game would you like status for?").shouldEndSession(false).send();
            //return false;
            if(configInstance.debugEnabled=="true"){
                console.log("Undefined game, response sent: " + response);
            }
        }
        else{

            gameAsked = gameAsked.toLowerCase();
            var gameIsValid = gamecheckisvalid(gameAsked);

            if(gameIsValid !== null){

                return gamestatusengine(gameIsValid).then(function (gamestatus) {
                    if(configInstance.debugEnabled){console.log(gamestatus);}
                    if(gamestatus.status !== null){

                        if(gamestatus.status == "Online")
                        {
                            var responseTextOnline = `Yes, ${gamestatus.name} is currently ${gamestatus.status}`;
                            response.say(responseTextOnline);
                        }
                        else if(gamestatus.status == "Offline")
                        {
                            var responseTextOffline = `No, ${gamestatus.name} is currently ${gamestatus.status}`;
                            response.say(responseTextOffline);
                        }
                        else if(gamestatus.status == "Partial")
                        {
                            var responseTextPartial = `Some ${gamestatus.name} services are unavailable, but not all.`;
                        }
                        else{
                            var responseTextUnknown = `I'm not sure, but chances are ${gameAsked} is currently unavailable.`;
                            response.say(responseTextUnknown);
                        }

                        if(configInstance.debugEnabled=="true"){
                            console.log("Valid game loop, response sent: " + response);
                        }

                        response.shouldEndSession(true);
                        return response.send();

                    }
                    else
                    {

                        response.clear().say(`Sorry there was an error checking the status for ${gameAsked}`);
                        response.shouldEndSession(true);

                        if(configInstance.debugEnabled=="true"){
                            console.log("Error checking game, response sent: " + response);
                        }
                        Raven.captureException("Error checking status of game: " + gameAsked);
                        return response.send();
                    }
                });
            }
            else{
                response.clear().say(`Sorry, ${gameAsked} is not yet supported. We will try to add it in the future. Until then, try again with a supported game.`);
                response.shouldEndSession(true);
                if(configInstance.debugEnabled=="true"){
                    console.log("Unsupported game, response sent: " + response);
                }
                Raven.captureException("Unsupported game: " + gameAsked);
                return response.send();
            }
        }
    }//try
    catch(e){
        Raven.captureException(e);
        if(configInstance.debugEnabled=="true"){
                console.log("Error: " + e);
        }
        response.clear().say("Sorry, something went wrong. Please try your request again.").shouldEndSession(false);
    }//catch
  }
);

exports.handler = alexaApp.lambda();<|endoftext|>


<commit_before>/********************************************************
 * Copyright (c) 2013 Azavea, Inc.
 * See LICENSE in the project root for copying permission
 * Location with definition of location objects and
 * data loader object
 *********************************************************/

define(['jquery', 'Leaflet', 'Handlebars', 'favorites', 'topojson', 'common'],
    function($, L, Handlebars, favorites, topojson, common) {

    /*
     * Constructor for location
     * data -- object returned from the /location/api/<id>/ url
     */
    var Location = function(data){
        if (data.position && data.item) {
            this.data = data;
        } else {
            throw "CELLocationInvalid";
        }

        this.mapMarker = null;
    };

    /*
     * Return ID of the location
     *      shortcut if we need more functionality later
     */
    Location.prototype.getId = function() {
        return this.data.item.key;
    };

    /*
     * Checks if location is starred
     * Returns:
     *      true if starred
     *      false if not starred
     */
    Location.prototype.isStarred = function() {
        return favorites.isStarred(this.getId());
    };

    /*
     * Add location to cookie string
     */
    Location.prototype.setStarred = function(add) {
        if (add) {
            favorites.addIdToCookie(this.getId());
        } else {
            favorites.removeIdFromCookie(this.getId());
        }
    };

    /*
     * Is the location accredited?
     */
    Location.prototype.isAccredited = function() {
        var isAccredited = false;
        $.each(this.data.sfields, function(key, value) {
            if (value.fieldname === "Accreditation" && value.value !== "None") {
                isAccredited = true;
                return false;
            }
        });
        return isAccredited;
    };

    /*
     * Determines if the location is a school or not
     * Returns:
     *      true if school
     *      false if not
     */
    Location.prototype.isSchool = function() {
        var isSchool = false;
        $.each(this.data.sfields, function(key, value) {
            if (value.fieldname === "Affiliations") {
                if (value.value.indexOf("CPS Based") !== -1) {
                    isSchool = true;
                }
                return false;
            }
        });
        return isSchool;
    };

    /* Function that returns appropriate icon based on
     * a location's properties
     */
    Location.prototype.getIcon = function(options) {

        var doubleDimensions = function(option) {
            option[0] *=2;
            option[1] *=2;
        };

        var setHighlighted = function(options) {
            doubleDimensions(options.iconSize);
            doubleDimensions(options.shadowSize);
            doubleDimensions(options.iconAnchor);
            doubleDimensions(options.shadowAnchor);
            doubleDimensions(options.popupAnchor);
            options.iconUrl = options.iconUrl.replace(".png", "@2x.png");
            options.shadowUrl = options.shadowUrl.replace(".png", "@2x.png");
            return options;
        };

        var defaults = {
            key: null,
            highlighted: false,
            iconUrl: '/static/img/leaflet-icons/marker-icon.png',
            shadowUrl: '/static/img/leaflet-icons/marker-shadow.png',
            iconSize: [35, 45],
            shadowSize: [41, 41],
            iconAnchor: [17, 45],
            shadowAnchor: [10, 41],
            popupAnchor: [0, -60]
        };
        var iconOpts = $.extend({}, defaults, options),
            key = '',
            cacheKey;

        // build a key!
        if (iconOpts.key) {
            key = iconOpts.key;
        } else {
            key += this.isSchool() ? 'school' : 'center';
            key += this.isAccredited() ? '-accredited' : '';
            key += this.isStarred() ? '-starred' : '';
        }

        // cache the icon with a simple key
        cacheKey = key;
        if (iconOpts.highlighted) {
            cacheKey += '-highlighted';
        }
        if (_iconcache[cacheKey]) {
            return _iconcache[cacheKey];
        }

        switch (key) {
            case 'school':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/school.png'});
                break;
            case 'school-starred':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/school-starred.png'});
                break;
            case 'school-accredited':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/school-accredited.png'});
                break;
            case 'school-accredited-starred':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/school-accredited-starred.png'});
                break;
            case 'center':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/center.png'});
                break;
            case 'center-starred':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/center-starred.png'});
                break;
            case 'center-accredited':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/center-accredited.png'});
                break;
            case 'center-accredited-starred':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/center-accredited-starred.png'});
                break;
            case 'geolocation':
                break;
            default:
                return null;
        }

        // highlighting means we double all dimensions and replace the icon with @2x
        if (iconOpts.highlighted) {
            iconOpts = setHighlighted(iconOpts);
        }

        var icon = L.icon(iconOpts);
        _iconcache[cacheKey] = icon;
        return icon;
    };

    /*
     * Set the locations map marker icon
     */
    Location.prototype.setIcon = function(options) {
        if (this.mapMarker) {
            var icon = this.getIcon(options);
            this.mapMarker.setIcon(icon);
        }
    };

    /*
     * Get location marker object
     */
    Location.prototype.getMarker = function() {
        return this.mapMarker || null;
    };

    /*
     * Input: Leaflet Marker Icons object
     * Output: Reference to the created marker
     * If map marker already exists, updates existing marker icon
     * If map marker does not exist, creates marker with proper icon
     */
    Location.prototype.setMarker = function(options) {
        var popupTemplate = Handlebars.compile('{{item.site_name}}
{{item.address}}'),
            icon = this.getIcon(options),
            marker = this.getMarker();
        if (marker) {
            marker.setIcon(icon);
        } else {
            this.mapMarker = new L.Marker(this.getLatLng(), { icon: icon });
            this.mapMarker.bindPopup(popupTemplate(this.data), {key: this.getId()});
        }
    };

    Location.prototype.getLatLng = function() {
        return new L.LatLng(this.data.position.lat, this.data.position.lng);
    };

    /* Sets boolean value for if location should be on list
     */
    Location.prototype.isWithinMapBounds = function(map){
        var mapBounds = map.getBounds();
        return mapBounds.contains(this.getLatLng());
    };

    /**
     * Creates a new DataManager object
     * @param { Optional query collection of DOM filter objects to bind onFilterChange to } $filters
     */
    var DataManager = function($filters) {
            var that = this;
            this.events = $({});
            this.$filters = $filters || $('.filters-inner :checkbox');
            this.$filters.on('click', function() { that.onFilterChange(); });
        },
        _iconcache = {};

    DataManager.prototype = {
        /**
         * Settings for layers - data manager needs access to these to know which to load
         */
        zoomSettings: CEL.serverVars.zoomSettings,

        /**
         * DOM filters to read filter settings from
         * Set in constructor
         */
        $filters: null,

        /**
         * Updates if location is shown in map and list based on
         * applied filters and bounding box of map
         */
        locationUpdate: function(map) {
            var filters = this.getFilters(map);
                that = this;
            $.getJSON(common.getUrl('location-api'), filters, function(data) {
                $.each(data.locations, function(i, location) {
                    var key = location.item.key;
                    if (!that.locations[key]) {
                        that.locations[key] = new Location(location);
                    }
                    that.locations[key].setMarker();
                });
                that.events.trigger('DataManager.locationUpdated');
            });
        },

        /**
         * Updates school counts for neighborhoods based on
         * filters.
         *
         * Download topojson if not already downloaded.
         */
        neighborhoodUpdate: function(map) {
            var that = this,
                filters = that.getFilters(map);
            $.when(
                $.getJSON(common.getUrl('neighborhood-api'), filters, function(data) {
                    var neighborhoods = that.neighborhoods.data;
                    $.each(data.neighborhoods, function(i, neighborhood) {
                        var key = neighborhood.id;
                        neighborhoods[key] = neighborhood;
                    });
                }),
                that.geojsonUpdate()
            ).then(function() {
                that.events.trigger('DataManager.neighborhoodUpdated');
            });
        },

        /*
         * Get geojson for the neighborhoods and store in DataManager
         */
        geojsonUpdate: function() {
            var that = this;
            if (that.neighborhoods.geojson === undefined) {
                return $.getJSON(common.getUrl('neighborhoods-topo'), function(data) {
                        that.neighborhoods.geojson = topojson.feature(data, data.objects.neighborhoods);
                });
            }
        },

        // Updates data on filter changes
        onFilterChange: function() {
            this.events.trigger('DataManager.filtersUpdated');
        },

        getFilters: function(map) {
            var opts = { },
                $filters = this.$filters || $('.filters-inner :checkbox');
            $filters.filter(':checked').each(function(idx, elem) {
                opts[elem.id] = elem.checked;
            });
            if (map && map.getBounds) {
                opts.bbox = map.getBounds().pad(1.5).toBBoxString();
            }

            return opts;
        },

        /**
         * Map of locations & neighborhoods, key is the id for
         * each object
         */
        locations: {},
        neighborhoods: {
            data: {} // data for neighborhood (e.g. number of schools)
        },

        /*
         * Available events:
         * neighborhoodUpdated: 'DataManager.neighborhoodUpdated',
         *      triggered when neighborhood data is finished loading
         * locationUpdated: 'DataManager.locationUpdated'
         *      triggered when location data is finished loading
         * filtersUpdated: 'DataManager.filtersChanged'
         *      fired when DOM filters change.  This includes checkboxes and map bounding box
         */
        events: null
    };

    return {
        Location: Location,
        DataManager: DataManager
    };
});

<commit_msg>Minor location.js cleanup, no real changes<commit_after>/********************************************************
 * Copyright (c) 2013 Azavea, Inc.
 * See LICENSE in the project root for copying permission
 * Location with definition of location objects and
 * data loader object
 *********************************************************/

define(['jquery', 'Leaflet', 'Handlebars', 'favorites', 'topojson', 'common'],
    function($, L, Handlebars, favorites, topojson, common) {

    /*
     * Constructor for location
     * data -- object returned from the /location/api/<id>/ url
     */
    var Location = function(data){
        if (data.position && data.item) {
            this.data = data;
        } else {
            throw "CELLocationInvalid";
        }

        this.mapMarker = null;
    };

    /*
     * Return ID of the location
     *      shortcut if we need more functionality later
     */
    Location.prototype.getId = function() {
        return this.data.item.key;
    };

    /*
     * Checks if location is starred
     * Returns:
     *      true if starred
     *      false if not starred
     */
    Location.prototype.isStarred = function() {
        return favorites.isStarred(this.getId());
    };

    /*
     * Add location to cookie string
     */
    Location.prototype.setStarred = function(add) {
        if (add) {
            favorites.addIdToCookie(this.getId());
        } else {
            favorites.removeIdFromCookie(this.getId());
        }
    };

    /*
     * Is the location accredited?
     */
    Location.prototype.isAccredited = function() {
        var isAccredited = false;
        $.each(this.data.sfields, function(key, value) {
            if (value.fieldname === "Accreditation" && value.value !== "None") {
                isAccredited = true;
                return false;
            }
        });
        return isAccredited;
    };

    /*
     * Determines if the location is a school or not
     * Returns:
     *      true if school
     *      false if not
     */
    Location.prototype.isSchool = function() {
        var isSchool = false;
        $.each(this.data.sfields, function(key, value) {
            if (value.fieldname === "Affiliations") {
                if (value.value.indexOf("CPS Based") !== -1) {
                    isSchool = true;
                }
                return false;
            }
        });
        return isSchool;
    };

    /* Function that returns appropriate icon based on
     * a location's properties
     */
    Location.prototype.getIcon = function(options) {
        var doubleDimensions = function(option) {
            option[0] *= 2;
            option[1] *= 2;
        };

        var setHighlighted = function(options) {
            doubleDimensions(options.iconSize);
            doubleDimensions(options.shadowSize);
            doubleDimensions(options.iconAnchor);
            doubleDimensions(options.shadowAnchor);
            doubleDimensions(options.popupAnchor);
            options.iconUrl = options.iconUrl.replace(".png", "@2x.png");
            options.shadowUrl = options.shadowUrl.replace(".png", "@2x.png");
            return options;
        };

        var defaults = {
            key: null,
            highlighted: false,
            iconUrl: '/static/img/leaflet-icons/marker-icon.png',
            shadowUrl: '/static/img/leaflet-icons/marker-shadow.png',
            iconSize: [35, 45],
            shadowSize: [41, 41],
            iconAnchor: [17, 45],
            shadowAnchor: [10, 41],
            popupAnchor: [0, -60]
        };
        var iconOpts = $.extend({}, defaults, options),
            key = '',
            cacheKey;

        // build a key!
        if (iconOpts.key) {
            key = iconOpts.key;
        } else {
            key += this.isSchool() ? 'school' : 'center';
            key += this.isAccredited() ? '-accredited' : '';
            key += this.isStarred() ? '-starred' : '';
        }

        // cache the icon with a simple key
        cacheKey = key;
        if (iconOpts.highlighted) {
            cacheKey += '-highlighted';
        }
        if (_iconcache[cacheKey]) {
            return _iconcache[cacheKey];
        }

        switch (key) {
            case 'school':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/school.png'});
                break;
            case 'school-starred':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/school-starred.png'});
                break;
            case 'school-accredited':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/school-accredited.png'});
                break;
            case 'school-accredited-starred':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/school-accredited-starred.png'});
                break;
            case 'center':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/center.png'});
                break;
            case 'center-starred':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/center-starred.png'});
                break;
            case 'center-accredited':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/center-accredited.png'});
                break;
            case 'center-accredited-starred':
                $.extend(iconOpts, {iconUrl: '/static/img/leaflet-icons/center-accredited-starred.png'});
                break;
            case 'geolocation':
                break;
            default:
                return null;
        }

        // highlighting means we double all dimensions and replace the icon with @2x
        if (iconOpts.highlighted) {
            iconOpts = setHighlighted(iconOpts);
        }

        var icon = L.icon(iconOpts);
        _iconcache[cacheKey] = icon;
        return icon;
    };

    /*
     * Set the locations map marker icon
     */
    Location.prototype.setIcon = function(options) {
        if (this.mapMarker) {
            var icon = this.getIcon(options);
            this.mapMarker.setIcon(icon);
        }
    };

    /*
     * Get location marker object
     */
    Location.prototype.getMarker = function() {
        return this.mapMarker || null;
    };

    /*
     * Input: Leaflet Marker Icons object
     * Output: Reference to the created marker
     * If map marker already exists, updates existing marker icon
     * If map marker does not exist, creates marker with proper icon
     */
    Location.prototype.setMarker = function(options) {
        var popupTemplate = Handlebars.compile('{{item.site_name}}
{{item.address}}'),
            icon = this.getIcon(options),
            marker = this.getMarker();
        if (marker) {
            marker.setIcon(icon);
        } else {
            this.mapMarker = new L.Marker(this.getLatLng(), { icon: icon });
            this.mapMarker.bindPopup(popupTemplate(this.data), {key: this.getId()});
        }
    };

    Location.prototype.getLatLng = function() {
        return new L.LatLng(this.data.position.lat, this.data.position.lng);
    };

    /* Sets boolean value for if location should be on list
     */
    Location.prototype.isWithinMapBounds = function(map){
        var mapBounds = map.getBounds();
        return mapBounds.contains(this.getLatLng());
    };

    /**
     * Creates a new DataManager object
     * @param { Optional query collection of DOM filter objects to bind onFilterChange to } $filters
     */
    var DataManager = function($filters) {
            var that = this;
            this.events = $({});
            this.$filters = $filters || $('.filters-inner :checkbox');
            this.$filters.on('click', function() { that.onFilterChange(); });
        },
        _iconcache = {};

    DataManager.prototype = {
        /**
         * DOM filters to read filter settings from
         * Set in constructor
         */
        $filters: null,

        /**
         * Updates if location is shown in map and list based on
         * applied filters and bounding box of map
         */
        locationUpdate: function(map) {
            var filters = this.getFilters(map);
                that = this;
            $.getJSON(common.getUrl('location-api'), filters, function(data) {
                $.each(data.locations, function(i, location) {
                    var key = location.item.key;
                    if (!that.locations[key]) {
                        that.locations[key] = new Location(location);
                    }
                    that.locations[key].setMarker();
                });
                that.events.trigger('DataManager.locationUpdated');
            });
        },

        /**
         * Updates school counts for neighborhoods based on
         * filters.
         *
         * Download topojson if not already downloaded.
         */
        neighborhoodUpdate: function(map) {
            var that = this,
                filters = that.getFilters(map);
            $.when(
                $.getJSON(common.getUrl('neighborhood-api'), filters, function(data) {
                    var neighborhoods = that.neighborhoods.data;
                    $.each(data.neighborhoods, function(i, neighborhood) {
                        var key = neighborhood.id;
                        neighborhoods[key] = neighborhood;
                    });
                }),
                that.geojsonUpdate()
            ).then(function() {
                that.events.trigger('DataManager.neighborhoodUpdated');
            });
        },

        /*
         * Get geojson for the neighborhoods and store in DataManager
         */
        geojsonUpdate: function() {
            var that = this;
            if (that.neighborhoods.geojson === undefined) {
                return $.getJSON(common.getUrl('neighborhoods-topo'), function(data) {
                        that.neighborhoods.geojson = topojson.feature(data, data.objects.neighborhoods);
                });
            }
        },

        /**
         * Alerts listeners that filter data has changed
         */
        onFilterChange: function() {
            this.events.trigger('DataManager.filtersUpdated');
        },

        /**
         * Gets the current state of location filters for passing into a GET request
         * @param { Leaflet map object to read current bounds from } map
         * @return { query params dict }
         */
        getFilters: function(map) {
            var opts = { },
                $filters = this.$filters || $('.filters-inner :checkbox');
            $filters.filter(':checked').each(function(idx, elem) {
                opts[elem.id] = elem.checked;
            });
            if (map && map.getBounds) {
                opts.bbox = map.getBounds().pad(1.5).toBBoxString();
            }

            return opts;
        },

        /**
         * Map of locations & neighborhoods, key is the id for
         * each object
         */
        locations: {},
        neighborhoods: {
            data: {} // data for neighborhood (e.g. number of schools)
        },

        /*
         * Available events:
         * neighborhoodUpdated: 'DataManager.neighborhoodUpdated',
         *      triggered when neighborhood data is finished loading
         * locationUpdated: 'DataManager.locationUpdated'
         *      triggered when location data is finished loading
         * filtersUpdated: 'DataManager.filtersChanged'
         *      fired when DOM filters change.  This includes checkboxes and map bounding box
         */
        events: null
    };

    return {
        Location: Location,
        DataManager: DataManager
    };
});

<|endoftext|>