<commit_before>'use strict';

const apiai = require('apiai');
const express = require('express');
const bodyParser = require('body-parser');
const uuid = require('node-uuid');
const request = require('request');

const REST_PORT = (process.env.PORT || 5000);
const APIAI_ACCESS_TOKEN = process.env.APIAI_ACCESS_TOKEN;
const APIAI_LANG = process.env.APIAI_LANG || 'en';
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;
const FB_PAGE_ACCESS_TOKEN = process.env.FB_PAGE_ACCESS_TOKEN;

const apiAiService = apiai(APIAI_ACCESS_TOKEN, "deprecated", {
    hostname: "dev.api.ai",
    endpoint: "/api/",
    language: APIAI_LANG
});
const sessionIds = new Map();

function processEvent(event) {
    var sender = event.sender.id;

    if (event.message && event.message.text) {
        var text = event.message.text;
        // Handle a text message from this sender

        if (!sessionIds.has(sender)) {
            sessionIds.set(sender, uuid.v1());
        }

        console.log("Text", text);

        let apiaiRequest = apiAiService.textRequest(text,
            {
                sessionId: sessionIds.get(sender)
            });

        apiaiRequest.on('response', (response) => {
            if (isDefined(response.result)) {
                let responseText = response.result.fulfillment.speech;
                let responseData = response.result.data;
                let action = response.result.action;

                if (isDefined(responseData)) {
                    try {
                        let responseObject = JSON.parse(responseData);
                        sendFBMessage(sender, responseObject.facebook);
                    } catch (err) {
                        sendFBMessage(sender, err.message);
                    }
                } else if (isDefined(responseText)) {
                    sendFBMessage(sender, {text: responseText});
                }

            }
        });

        apiaiRequest.on('error', (error) => console.error(error));
        apiaiRequest.end();
    }
}

function sendFBMessage(sender, messageData) {
    request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {access_token: FB_PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: sender},
            message: messageData
        }
    }, function (error, response, body) {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }
    });
}

function makeSubscribeRequest() {
    // making subscribe post request
    request({
            method: 'POST',
            uri: "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=" + FB_PAGE_ACCESS_TOKEN
        },
        function (error, response, body) {
            if (error) {
                console.error('Error while subscription: ', error);
            } else {
                console.log('Subscription result: ', response.body);
            }
        });
}

function isDefined(obj) {
    if (typeof obj == 'undefined') {
        return false;
    }

    if (!obj) {
        return false;
    }

    return obj != null;
}

const app = express();
app.use(bodyParser.json());
app.all('*', function (req, res, next) {
    // res.header("Access-Control-Allow-Origin", '*');
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, content-type, accept");
    next();
});

app.get('/webhook/', function (req, res) {
    if (req.query['hub.verify_token'] == FB_VERIFY_TOKEN) {
        res.send(req.query['hub.challenge']);

        setTimeout(function () {
            makeSubscribeRequest();
        }, 3000);
    } else {
        res.send('Error, wrong validation token');
    }
});

app.post('/webhook/', function (req, res) {
    try {
        var messaging_events = req.body.entry[0].messaging;
        for (var i = 0; i < messaging_events.length; i++) {
            var event = req.body.entry[0].messaging[i];
            processEvent(event);
        }
        return res.status(200).json({
            status: "ok"
        });
    } catch (err) {
        return res.status(400).json({
            status: "error",
            error: err
        });
    }

});

app.listen(REST_PORT, function () {
    console.log('Rest service ready on port ' + REST_PORT);
});
<commit_msg>Additional subscribe request<commit_after>'use strict';

const apiai = require('apiai');
const express = require('express');
const bodyParser = require('body-parser');
const uuid = require('node-uuid');
const request = require('request');

const REST_PORT = (process.env.PORT || 5000);
const APIAI_ACCESS_TOKEN = process.env.APIAI_ACCESS_TOKEN;
const APIAI_LANG = process.env.APIAI_LANG || 'en';
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;
const FB_PAGE_ACCESS_TOKEN = process.env.FB_PAGE_ACCESS_TOKEN;

const apiAiService = apiai(APIAI_ACCESS_TOKEN, "deprecated", {
    hostname: "dev.api.ai",
    endpoint: "/api/",
    language: APIAI_LANG
});
const sessionIds = new Map();

function processEvent(event) {
    var sender = event.sender.id;

    if (event.message && event.message.text) {
        var text = event.message.text;
        // Handle a text message from this sender

        if (!sessionIds.has(sender)) {
            sessionIds.set(sender, uuid.v1());
        }

        console.log("Text", text);

        let apiaiRequest = apiAiService.textRequest(text,
            {
                sessionId: sessionIds.get(sender)
            });

        apiaiRequest.on('response', (response) => {
            if (isDefined(response.result)) {
                let responseText = response.result.fulfillment.speech;
                let responseData = response.result.data;
                let action = response.result.action;

                if (isDefined(responseData)) {
                    try {
                        let responseObject = JSON.parse(responseData);
                        sendFBMessage(sender, responseObject.facebook);
                    } catch (err) {
                        sendFBMessage(sender, err.message);
                    }
                } else if (isDefined(responseText)) {
                    sendFBMessage(sender, {text: responseText});
                }

            }
        });

        apiaiRequest.on('error', (error) => console.error(error));
        apiaiRequest.end();
    }
}

function sendFBMessage(sender, messageData) {
    request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {access_token: FB_PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: sender},
            message: messageData
        }
    }, function (error, response, body) {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }
    });
}

function doSubscribeRequest() {
    // making subscribe post request
    request({
            method: 'POST',
            uri: "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=" + FB_PAGE_ACCESS_TOKEN
        },
        function (error, response, body) {
            if (error) {
                console.error('Error while subscription: ', error);
            } else {
                console.log('Subscription result: ', response.body);
            }
        });
}

function isDefined(obj) {
    if (typeof obj == 'undefined') {
        return false;
    }

    if (!obj) {
        return false;
    }

    return obj != null;
}

const app = express();
app.use(bodyParser.json());
app.all('*', function (req, res, next) {
    // res.header("Access-Control-Allow-Origin", '*');
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, content-type, accept");
    next();
});

app.get('/webhook/', function (req, res) {
    if (req.query['hub.verify_token'] == FB_VERIFY_TOKEN) {
        res.send(req.query['hub.challenge']);

        setTimeout(function () {
            doSubscribeRequest();
        }, 3000);
    } else {
        res.send('Error, wrong validation token');
    }
});

app.post('/webhook/', function (req, res) {
    try {
        var messaging_events = req.body.entry[0].messaging;
        for (var i = 0; i < messaging_events.length; i++) {
            var event = req.body.entry[0].messaging[i];
            processEvent(event);
        }
        return res.status(200).json({
            status: "ok"
        });
    } catch (err) {
        return res.status(400).json({
            status: "error",
            error: err
        });
    }

});

app.listen(REST_PORT, function () {
    console.log('Rest service ready on port ' + REST_PORT);
});

doSubscribeRequest();<|endoftext|>


<commit_before>/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */

function readExifValue(format, stream) {
	switch(format) {
		case 1: return stream.nextUInt8();
		case 3: return stream.nextUInt16();
		case 4: return stream.nextUInt32();
		case 5: return [stream.nextUInt32(), stream.nextUInt32()];
		case 6: return stream.nextInt8();
		case 8: return stream.nextUInt16();
		case 9: return stream.nextUInt32();
		case 10: return [stream.nextInt32(), stream.nextInt32()];
		case 11: return stream.nextFloat();
		case 12: return stream.nextDouble();
		default: throw new Error('Invalid format while decoding: ' + format);
	}
}

function getBytesPerComponent(format) {
	switch(format) {
		case 1:
		case 2:
		case 6:
		case 7:
			return 1;
		case 3:
		case 8:
			return 2;
		case 4:
		case 9:
		case 11:
			return 4;
		case 5:
		case 10:
		case 12:
			return 8;
		default:
			return 0;
	}
}

function readExifTag(tiffMarker, stream) {
	var tagType = stream.nextUInt16(),
		format = stream.nextUInt16(),
		bytesPerComponent = getBytesPerComponent(format),
		components = stream.nextUInt32(),
		valueBytes = bytesPerComponent * components,
		values,
		value,
		c;

	/* if the value is bigger then 4 bytes, the value is in the data section of the IFD
	and the value present in the tag is the offset starting from the tiff header. So we replace the stream
	with a stream that is located at the given offset in the data section. s*/
	if(valueBytes > 4) {
		stream = tiffMarker.openWithOffset(stream.nextUInt32());
	}
	//we don't want to read strings as arrays
	if(format === 2) {
		values = stream.nextString(components);
		//cut off \0 characters
		var lastNull = values.indexOf('\0');
		if(lastNull !== -1) {
			values = values.substr(0, lastNull);
		}
	}
	else if(format === 7) {
		values = stream.nextBuffer(components);
	}
	else if(format !== 0) {
		values = [];
		for(c = 0; c < components; ++c) {
			values.push(readExifValue(format, stream));
		}
	}
	//since our stream is a stateful object, we need to skip remaining bytes
	//so our offset stays correct
	if(valueBytes < 4) {
		stream.skip(4 - valueBytes);
	}

	return [tagType, values, format];
}

function readIFDSection(tiffMarker, stream, iterator) {
	var numberOfEntries = stream.nextUInt16(), tag, i;
	for(i = 0; i < numberOfEntries; ++i) {
		tag = readExifTag(tiffMarker, stream);
		iterator(tag[0], tag[1], tag[2]);
	}
}

function readHeader(stream) {
	var exifHeader = stream.nextString(6);
	if(exifHeader !== 'Exif\0\0') {
		throw new Error('Invalid EXIF header');
	}

	var tiffMarker = stream.mark();
	var tiffHeader = stream.nextUInt16();
	if(tiffHeader === 0x4949) {
		stream.setBigEndian(false);
	} else if(tiffHeader === 0x4D4D) {
		stream.setBigEndian(true);
	} else {
		throw new Error('Invalid TIFF header');
	}
	if(stream.nextUInt16() !== 0x002A) {
		throw new Error('Invalid TIFF data');
	}
	return tiffMarker;
}

module.exports = {
	IFD0: 1,
	IFD1: 2,
	GPSIFD: 3,
	SubIFD: 4,
	InteropIFD: 5,
	parseTags: function(stream, iterator) {
		var tiffMarker;
		try {
			tiffMarker = readHeader(stream);
		} catch(e) {
			return false;	//ignore APP1 sections with invalid headers
		}
		var subIfdOffset, gpsOffset, interopOffset;
		var ifd0Stream = tiffMarker.openWithOffset(stream.nextUInt32()),
			IFD0 = this.IFD0;
		readIFDSection(tiffMarker, ifd0Stream, function(tagType, value, format) {
			switch(tagType) {
				case 0x8825: gpsOffset = value[0]; break;
				case 0x8769: subIfdOffset = value[0]; break;
				default: iterator(IFD0, tagType, value, format); break;
			}
		});
		var ifd1Offset = ifd0Stream.nextUInt32();
		if(ifd1Offset !== 0) {
			var ifd1Stream = tiffMarker.openWithOffset(ifd1Offset);
			readIFDSection(tiffMarker, ifd1Stream, iterator.bind(null, this.IFD1));
		}

		if(gpsOffset) {
			var gpsStream = tiffMarker.openWithOffset(gpsOffset);
			readIFDSection(tiffMarker, gpsStream, iterator.bind(null, this.GPSIFD));
		}

		if(subIfdOffset) {
			var subIfdStream = tiffMarker.openWithOffset(subIfdOffset), InteropIFD = this.InteropIFD;
			readIFDSection(tiffMarker, subIfdStream, function(tagType, value, format) {
				if(tagType === 0xA005) {
					interopOffset = value[0];
				} else {
					iterator(InteropIFD, tagType, value, format);
				}
			});
		}

		if(interopOffset) {
			var interopStream = tiffMarker.openWithOffset(interopOffset);
			readIFDSection(tiffMarker, interopStream, iterator.bind(null, this.InteropIFD));
		}
		return true;
	}
};<commit_msg>Fixes 'Offset is outside the bounds of the DataView' error<commit_after>/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */

function readExifValue(format, stream) {
	switch(format) {
		case 1: return stream.nextUInt8();
		case 3: return stream.nextUInt16();
		case 4: return stream.nextUInt32();
		case 5: return [stream.nextUInt32(), stream.nextUInt32()];
		case 6: return stream.nextInt8();
		case 8: return stream.nextUInt16();
		case 9: return stream.nextUInt32();
		case 10: return [stream.nextInt32(), stream.nextInt32()];
		case 11: return stream.nextFloat();
		case 12: return stream.nextDouble();
		default: throw new Error('Invalid format while decoding: ' + format);
	}
}

function getBytesPerComponent(format) {
	switch(format) {
		case 1:
		case 2:
		case 6:
		case 7:
			return 1;
		case 3:
		case 8:
			return 2;
		case 4:
		case 9:
		case 11:
			return 4;
		case 5:
		case 10:
		case 12:
			return 8;
		default:
			return 0;
	}
}

function readExifTag(tiffMarker, stream) {
	var tagType = stream.nextUInt16(),
		format = stream.nextUInt16(),
		bytesPerComponent = getBytesPerComponent(format),
		components = stream.nextUInt32(),
		valueBytes = bytesPerComponent * components,
		values,
		value,
		c;

	/* if the value is bigger then 4 bytes, the value is in the data section of the IFD
	and the value present in the tag is the offset starting from the tiff header. So we replace the stream
	with a stream that is located at the given offset in the data section. s*/
	if(valueBytes > 4) {
		stream = tiffMarker.openWithOffset(stream.nextUInt32());
	}
	//we don't want to read strings as arrays
	if(format === 2) {
		values = stream.nextString(components);
		//cut off \0 characters
		var lastNull = values.indexOf('\0');
		if(lastNull !== -1) {
			values = values.substr(0, lastNull);
		}
	}
	else if(format === 7) {
		values = stream.nextBuffer(components);
	}
	else if(format !== 0) {
		values = [];
		for(c = 0; c < components; ++c) {
			values.push(readExifValue(format, stream));
		}
	}
	//since our stream is a stateful object, we need to skip remaining bytes
	//so our offset stays correct
	if(valueBytes < 4) {
		stream.skip(4 - valueBytes);
	}

	return [tagType, values, format];
}

function readIFDSection(tiffMarker, stream, iterator) {
	// make sure we can read nextUint16 byte
	if (stream.remainingLength() < 2){
		return;
	}
	var numberOfEntries = stream.nextUInt16(), tag, i;
	for(i = 0; i < numberOfEntries; ++i) {
		tag = readExifTag(tiffMarker, stream);
		iterator(tag[0], tag[1], tag[2]);
	}
}

function readHeader(stream) {
	var exifHeader = stream.nextString(6);
	if(exifHeader !== 'Exif\0\0') {
		throw new Error('Invalid EXIF header');
	}

	var tiffMarker = stream.mark();
	var tiffHeader = stream.nextUInt16();
	if(tiffHeader === 0x4949) {
		stream.setBigEndian(false);
	} else if(tiffHeader === 0x4D4D) {
		stream.setBigEndian(true);
	} else {
		throw new Error('Invalid TIFF header');
	}
	if(stream.nextUInt16() !== 0x002A) {
		throw new Error('Invalid TIFF data');
	}
	return tiffMarker;
}

module.exports = {
	IFD0: 1,
	IFD1: 2,
	GPSIFD: 3,
	SubIFD: 4,
	InteropIFD: 5,
	parseTags: function(stream, iterator) {
		var tiffMarker;
		try {
			tiffMarker = readHeader(stream);
		} catch(e) {
			return false;	//ignore APP1 sections with invalid headers
		}
		var subIfdOffset, gpsOffset, interopOffset;
		var ifd0Stream = tiffMarker.openWithOffset(stream.nextUInt32()),
			IFD0 = this.IFD0;
		readIFDSection(tiffMarker, ifd0Stream, function(tagType, value, format) {
			switch(tagType) {
				case 0x8825: gpsOffset = value[0]; break;
				case 0x8769: subIfdOffset = value[0]; break;
				default: iterator(IFD0, tagType, value, format); break;
			}
		});
		var ifd1Offset = ifd0Stream.nextUInt32();
		if(ifd1Offset !== 0) {
			var ifd1Stream = tiffMarker.openWithOffset(ifd1Offset);
			readIFDSection(tiffMarker, ifd1Stream, iterator.bind(null, this.IFD1));
		}

		if(gpsOffset) {
			var gpsStream = tiffMarker.openWithOffset(gpsOffset);
			readIFDSection(tiffMarker, gpsStream, iterator.bind(null, this.GPSIFD));
		}

		if(subIfdOffset) {
			var subIfdStream = tiffMarker.openWithOffset(subIfdOffset), InteropIFD = this.InteropIFD;
			readIFDSection(tiffMarker, subIfdStream, function(tagType, value, format) {
				if(tagType === 0xA005) {
					interopOffset = value[0];
				} else {
					iterator(InteropIFD, tagType, value, format);
				}
			});
		}

		if(interopOffset) {
			var interopStream = tiffMarker.openWithOffset(interopOffset);
			readIFDSection(tiffMarker, interopStream, iterator.bind(null, this.InteropIFD));
		}
		return true;
	}
};
<|endoftext|>


<commit_before>//
// Eyes.js - a customizable value inspector for Node.js
//
//   usage:
//
//       var inspect = require('eyes').inspector({styles: {all: 'magenta'}});
//       inspect(something); // inspect with the settings passed to `inspector`
//
//     or
//
//       var eyes = require('eyes');
//       eyes.inspect(something); // inspect with the default settings
//
var eyes = exports,
    stack = [];

eyes.defaults = {
    styles: {                 // Styles applied to stdout
        all:     'cyan',      // Overall style applied to everything
        label:   'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]`
        other:   'inverted',  // Objects which don't have a literal representation, such as functions
        key:     'bold',      // The keys in object literals, like 'a' in `{a: 1}`
        special: 'grey',      // null, undefined...
        string:  'green',
        number:  'magenta',
        bool:    'blue',      // true false
        regexp:  'green',     // /\d+/
    },
    pretty: true,             // Indent object literals
    hideFunctions: false,
    stream: process.stdout,
    maxLength: 2048           // Truncate output if longer
};

// Return a curried inspect() function, with the `options` argument filled in.
eyes.inspector = function (options) {
    var that = this;
    return function (obj, label, opts) {
        return that.inspect.call(that, obj, label,
            merge(options || {}, opts || {}));
    };
};

// If we have a `stream` defined, use it to print a styled string,
// if not, we just return the stringified object.
eyes.inspect = function (obj, label, options) {
    options = merge(this.defaults, options || {});

    if (options.stream) {
        return this.print(stringify(obj, options), label, options);
    } else {
        return stringify(obj, options) + (options.styles ? '\033[39m' : '');
    }
};

// Output using the 'stream', and an optional label
// Loop through `str`, and truncate it after `options.maxLength` has been reached.
// Because escape sequences are, at this point embeded within
// the output string, we can't measure the length of the string
// in a useful way, without separating what is an escape sequence,
// versus a printable character (`c`). So we resort to counting the
// length manually.
eyes.print = function (str, label, options) {
    for (var c = 0, i = 0; i < str.length; i++) {
        if (str.charAt(i) === '\033') { i += 4 } // `4` because '\033[25m'.length + 1 == 5
        else if (c === options.maxLength) {
           str = str.slice(0, i - 1) + '…';
           break;
        } else { c++ }
    }
    return options.stream.write.call(options.stream, (label ?
        this.stylize(label, options.styles.label, options.styles) + ': ' : '') +
        this.stylize(str,   options.styles.all, options.styles) + '\033[0m' + "\n");
};

// Apply a style to a string, eventually,
// I'd like this to support passing multiple
// styles.
eyes.stylize = function (str, style, styles) {
    var codes = {
        'bold'      : [1,  22],
        'underline' : [4,  24],
        'inverse'   : [7,  27],
        'cyan'      : [36, 39],
        'magenta'   : [35, 39],
        'blue'      : [34, 39],
        'yellow'    : [33, 39],
        'green'     : [32, 39],
        'red'       : [31, 39],
        'grey'      : [90, 39]
    }, endCode;

    if (style && codes[style]) {
        endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0]
                                                         : codes[style][1];
        return '\033[' + codes[style][0] + 'm' + str +
               '\033[' + endCode + 'm';
    } else { return str }
};

// Convert any object to a string, ready for output.
// When an 'array' or an 'object' are encountered, they are
// passed to specialized functions, which can then recursively call
// stringify().
function stringify(obj, options) {
    var that = this, stylize = function (str, style) {
        return eyes.stylize(str, options.styles[style], options.styles)
    }, index, result;

    if ((index = stack.indexOf(obj)) !== -1) {
        return stylize(new(Array)(stack.length - index + 1).join('.'), 'special');
    }
    stack.push(obj);

    result = (function (obj) {
        switch (typeOf(obj)) {
            case "string"   : obj = stringifyString(obj.indexOf("'") === -1 ? "'" + obj + "'"
                                                                            : '"' + obj + '"');
                              return stylize(obj, 'string');
            case "regexp"   : return stylize('/' + obj.source + '/', 'regexp');
            case "number"   : return stylize(obj + '',    'number');
            case "function" : return options.stream ? stylize("Function", 'other') : '[Function]';
            case "null"     : return stylize("null",      'special');
            case "undefined": return stylize("undefined", 'special');
            case "boolean"  : return stylize(obj + '',    'bool');
            case "date"     : return stylize(obj.toUTCString());
            case "array"    : return stringifyArray(obj,  options, stack.length);
            case "object"   : return stringifyObject(obj, options, stack.length);
        }
    })(obj);

    stack.pop();
    return result;
};

// Escape invisible characters in a string
function stringifyString (str, options) {
    return str.replace(/\\/g, '\\\\')
              .replace(/\n/g, '\\n')
              .replace(/[\u0001-\u001F]/g, function (match) {
                  return '\\0' + match[0].charCodeAt(0).toString(8);
              });
}

// Convert an array to a string, such as [1, 2, 3].
// This function calls stringify() for each of the elements
// in the array.
function stringifyArray(ary, options, level) {
    var out = [];
    var pretty = options.pretty && (ary.length > 4 || ary.some(function (o) {
        return (o !== null && typeof(o) === 'object' && Object.keys(o).length > 0) ||
               (Array.isArray(o) && o.length > 0);
    }));
    var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' ';

    for (var i = 0; i < ary.length; i++) {
        out.push(stringify(ary[i], options));
    }

    if (out.length === 0) {
        return '[]';
    } else {
        return '[' + ws
                   + out.join(',' + (pretty ? ws : ' '))
                   + (pretty ? ws.slice(0, -4) : ws) +
               ']';
    }
};

// Convert an object to a string, such as {a: 1}.
// This function calls stringify() for each of its values,
// and does not output functions or prototype values.
function stringifyObject(obj, options, level) {
    var out = [];
    var pretty = options.pretty && (Object.keys(obj).length > 2 ||
                                    Object.keys(obj).some(function (k) { return typeof(obj[k]) === 'object' }));
    var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' ';

    Object.keys(obj).forEach(function (k) {
        if (Object.prototype.hasOwnProperty.call(obj, k) &&
          !(obj[k] instanceof Function && options.hideFunctions)) {
            out.push(eyes.stylize(k, options.styles.key, options.styles) + ': ' +
                     stringify(obj[k], options));
        }
    });

    if (out.length === 0) {
        return '{}';
    } else {
        return "{" + ws
                   + out.join(',' + (pretty ? ws : ' '))
                   + (pretty ? ws.slice(0, -4) : ws) +
               "}";
   }
};

// A better `typeof`
function typeOf(value) {
    var s = typeof(value),
        types = [Object, Array, String, RegExp, Number, Function, Boolean, Date];

    if (s === 'object' || s === 'function') {
        if (value) {
            types.forEach(function (t) {
                if (value instanceof t) { s = t.name.toLowerCase() }
            });
        } else { s = 'null' }
    }
    return s;
}

function merge(/* variable args */) {
    var objs = Array.prototype.slice.call(arguments);
    var target = {};

    objs.forEach(function (o) {
        Object.keys(o).forEach(function (k) {
            if (k === 'styles') {
                if (! o.styles) {
                    target.styles = false;
                } else {
                    target.styles = {}
                    for (var s in o.styles) {
                        target.styles[s] = o.styles[s];
                    }
                }
            } else {
                target[k] = o[k];
            }
        });
    });
    return target;
}

<commit_msg>[v0.6 feature] Add `showHidden` option<commit_after>//
// Eyes.js - a customizable value inspector for Node.js
//
//   usage:
//
//       var inspect = require('eyes').inspector({styles: {all: 'magenta'}});
//       inspect(something); // inspect with the settings passed to `inspector`
//
//     or
//
//       var eyes = require('eyes');
//       eyes.inspect(something); // inspect with the default settings
//
var eyes = exports,
    stack = [];

eyes.defaults = {
    styles: {                 // Styles applied to stdout
        all:     'cyan',      // Overall style applied to everything
        label:   'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]`
        other:   'inverted',  // Objects which don't have a literal representation, such as functions
        key:     'bold',      // The keys in object literals, like 'a' in `{a: 1}`
        special: 'grey',      // null, undefined...
        string:  'green',
        number:  'magenta',
        bool:    'blue',      // true false
        regexp:  'green',     // /\d+/
    },
    pretty: true,             // Indent object literals
    hideFunctions: false,
    showHidden: false,
    stream: process.stdout,
    maxLength: 2048           // Truncate output if longer
};

// Return a curried inspect() function, with the `options` argument filled in.
eyes.inspector = function (options) {
    var that = this;
    return function (obj, label, opts) {
        return that.inspect.call(that, obj, label,
            merge(options || {}, opts || {}));
    };
};

// If we have a `stream` defined, use it to print a styled string,
// if not, we just return the stringified object.
eyes.inspect = function (obj, label, options) {
    options = merge(this.defaults, options || {});

    if (options.stream) {
        return this.print(stringify(obj, options), label, options);
    } else {
        return stringify(obj, options) + (options.styles ? '\033[39m' : '');
    }
};

// Output using the 'stream', and an optional label
// Loop through `str`, and truncate it after `options.maxLength` has been reached.
// Because escape sequences are, at this point embeded within
// the output string, we can't measure the length of the string
// in a useful way, without separating what is an escape sequence,
// versus a printable character (`c`). So we resort to counting the
// length manually.
eyes.print = function (str, label, options) {
    for (var c = 0, i = 0; i < str.length; i++) {
        if (str.charAt(i) === '\033') { i += 4 } // `4` because '\033[25m'.length + 1 == 5
        else if (c === options.maxLength) {
           str = str.slice(0, i - 1) + '…';
           break;
        } else { c++ }
    }
    return options.stream.write.call(options.stream, (label ?
        this.stylize(label, options.styles.label, options.styles) + ': ' : '') +
        this.stylize(str,   options.styles.all, options.styles) + '\033[0m' + "\n");
};

// Apply a style to a string, eventually,
// I'd like this to support passing multiple
// styles.
eyes.stylize = function (str, style, styles) {
    var codes = {
        'bold'      : [1,  22],
        'underline' : [4,  24],
        'inverse'   : [7,  27],
        'cyan'      : [36, 39],
        'magenta'   : [35, 39],
        'blue'      : [34, 39],
        'yellow'    : [33, 39],
        'green'     : [32, 39],
        'red'       : [31, 39],
        'grey'      : [90, 39]
    }, endCode;

    if (style && codes[style]) {
        endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0]
                                                         : codes[style][1];
        return '\033[' + codes[style][0] + 'm' + str +
               '\033[' + endCode + 'm';
    } else { return str }
};

// Convert any object to a string, ready for output.
// When an 'array' or an 'object' are encountered, they are
// passed to specialized functions, which can then recursively call
// stringify().
function stringify(obj, options) {
    var that = this, stylize = function (str, style) {
        return eyes.stylize(str, options.styles[style], options.styles)
    }, index, result;

    if ((index = stack.indexOf(obj)) !== -1) {
        return stylize(new(Array)(stack.length - index + 1).join('.'), 'special');
    }
    stack.push(obj);

    result = (function (obj) {
        switch (typeOf(obj)) {
            case "string"   : obj = stringifyString(obj.indexOf("'") === -1 ? "'" + obj + "'"
                                                                            : '"' + obj + '"');
                              return stylize(obj, 'string');
            case "regexp"   : return stylize('/' + obj.source + '/', 'regexp');
            case "number"   : return stylize(obj + '',    'number');
            case "function" : return options.stream ? stylize("Function", 'other') : '[Function]';
            case "null"     : return stylize("null",      'special');
            case "undefined": return stylize("undefined", 'special');
            case "boolean"  : return stylize(obj + '',    'bool');
            case "date"     : return stylize(obj.toUTCString());
            case "array"    : return stringifyArray(obj,  options, stack.length);
            case "object"   : return stringifyObject(obj, options, stack.length);
        }
    })(obj);

    stack.pop();
    return result;
};

// Escape invisible characters in a string
function stringifyString (str, options) {
    return str.replace(/\\/g, '\\\\')
              .replace(/\n/g, '\\n')
              .replace(/[\u0001-\u001F]/g, function (match) {
                  return '\\0' + match[0].charCodeAt(0).toString(8);
              });
}

// Convert an array to a string, such as [1, 2, 3].
// This function calls stringify() for each of the elements
// in the array.
function stringifyArray(ary, options, level) {
    var out = [];
    var pretty = options.pretty && (ary.length > 4 || ary.some(function (o) {
        return (o !== null && typeof(o) === 'object' && Object.keys(o).length > 0) ||
               (Array.isArray(o) && o.length > 0);
    }));
    var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' ';

    for (var i = 0; i < ary.length; i++) {
        out.push(stringify(ary[i], options));
    }

    if (out.length === 0) {
        return '[]';
    } else {
        return '[' + ws
                   + out.join(',' + (pretty ? ws : ' '))
                   + (pretty ? ws.slice(0, -4) : ws) +
               ']';
    }
};

// Convert an object to a string, such as {a: 1}.
// This function calls stringify() for each of its values,
// and does not output functions or prototype values.
function stringifyObject(obj, options, level) {
    var out = [];
    var pretty = options.pretty && (Object.keys(obj).length > 2 ||
                                    Object.keys(obj).some(function (k) { return typeof(obj[k]) === 'object' }));
    var ws = pretty ? '\n' + new(Array)(level * 4 + 1).join(' ') : ' ';

    var keys = options.showHidden ? Object.keys(obj) : Object.getOwnPropertyNames(obj);
    keys.forEach(function (k) {
        if (Object.prototype.hasOwnProperty.call(obj, k)
          && !(obj[k] instanceof Function && options.hideFunctions)) {
            out.push(eyes.stylize(k, options.styles.key, options.styles) + ': ' +
                     stringify(obj[k], options));
        }
    });

    if (out.length === 0) {
        return '{}';
    } else {
        return "{" + ws
                   + out.join(',' + (pretty ? ws : ' '))
                   + (pretty ? ws.slice(0, -4) : ws) +
               "}";
   }
};

// A better `typeof`
function typeOf(value) {
    var s = typeof(value),
        types = [Object, Array, String, RegExp, Number, Function, Boolean, Date];

    if (s === 'object' || s === 'function') {
        if (value) {
            types.forEach(function (t) {
                if (value instanceof t) { s = t.name.toLowerCase() }
            });
        } else { s = 'null' }
    }
    return s;
}

function merge(/* variable args */) {
    var objs = Array.prototype.slice.call(arguments);
    var target = {};

    objs.forEach(function (o) {
        Object.keys(o).forEach(function (k) {
            if (k === 'styles') {
                if (! o.styles) {
                    target.styles = false;
                } else {
                    target.styles = {}
                    for (var s in o.styles) {
                        target.styles[s] = o.styles[s];
                    }
                }
            } else {
                target[k] = o[k];
            }
        });
    });
    return target;
}

<|endoftext|>


<commit_before>/**
 * Copyright (C) 2016 yanni4night.com
 * file.js
 *
 * changelog
 * 2016-06-20[14:38:37]:revised
 *
 * @author yanni4night@gmail.com
 * @version 1.0.0
 * @since 1.0.0
 */
'use strict';

const {
    NAMESPACE
} = require('./config');

class File {
    constructor(filename, content, destname, resource) {
        Object.defineProperties(this, {
            filename: {
                value: filename,
                writable: false,
                configurable: false,
                enumerable: true
            },
            destname: {
                value: destname || filename,
                writable: true,
                configurable: false,
                enumerable: true
            },
            content: {
                value: content,
                writable: true,
                configurable: false,
                enumerable: true
            },
            moduleId: {
                value: `${NAMESPACE}:${filename}`,
                writable: false,
                configurable: false,
                enumerable: true
            },
            resource: {
                value: resource,
                writable: true,
                configurable: false,
                enumerable: true
            }
        });
    }
    clone(content) {
        return new File(this.filename, content || this.content, this.destname, this.resource);
    }
    update(content) {
        this.content = content;
        return this;
    }
    truncate() {
        this.content = null;
        return this;
    }
    setResource(key, value) {
        if (!this.resource) {
            this.resource = {};
        }
        this.resource[key] = value;
        return this;
    }
}

module.exports = File;<commit_msg>optimize moduleId in file<commit_after>/**
 * Copyright (C) 2016 yanni4night.com
 * file.js
 *
 * changelog
 * 2016-06-20[14:38:37]:revised
 *
 * @author yanni4night@gmail.com
 * @version 1.0.0
 * @since 1.0.0
 */
'use strict';

const {
    NAMESPACE
} = require('./config');

class File {
    constructor(filename, content, destname, resource) {
        Object.defineProperties(this, {
            filename: {
                value: filename,
                writable: false,
                configurable: false,
                enumerable: true
            },
            destname: {
                value: destname || filename,
                writable: true,
                configurable: false,
                enumerable: true
            },
            content: {
                value: content,
                writable: true,
                configurable: false,
                enumerable: true
            },
            moduleId: {
                get() {
                    return `${NAMESPACE}:${filename}`;
                },
                configurable: false,
                enumerable: true
            },
            resource: {
                value: resource,
                writable: true,
                configurable: false,
                enumerable: true
            }
        });
    }
    clone() {
        return new File(this.filename, this.content, this.destname, this.resource);
    }
    update(content) {
        this.content = content;
        return this;
    }
    truncate() {
        this.content = null;
        return this;
    }
    setResource(key, value) {
        // Prevent from useless memory allocate
        if (!this.resource) {
            this.resource = {};
        }
        this.resource[key] = value;
        return this;
    }
}

module.exports = File;<|endoftext|>


<commit_before>/**
 * Main application module.
 * Project started: 16.03.2014 - 00:21
 * @module app
 * @author Sören Gade
 *
 * @requires config
 * @requires web/index
 * @requires io/rfidreader
 * */

require('./log-replace')();
var package = require('../package');
var config = require('./config');
var web = require('./web/');
var RFIDReader = require('./io/rfidreader');
var Relais = require('./io/relais');
var db = require('./db/');

/* ==========
 * Globals
 * ==========
 * */
var rfidReader = null;
var relais = null;

/* ==========
 * Init
 * ==========
 * */
/**
 * Starts the webserver.
 * */
function startWeb() {
  var port = config.web.port;

  if(typeof PhusionPassenger !== 'undefined') {
    PhusionPassenger.configure({ autoInstall: false });
    port = 'passenger';
  }

  web.init(port, web_RFIDRequest, web_OpenDoor, function() {
    web.start(function() {
      console.log("Web interface running on port " + web.getPort() + ".");
    });
  });
}
// callbacks for web requests
function web_RFIDRequest(callback) {
  rfidReader.on('data', function(data) {
    callback(data);
  });
}
function web_OpenDoor(callback) {
  console.log("Opening door...");

  openDoor(callback);
}

/**
 * Initializes the connection with the RFID reader.
 * */
function initRFIDReader() {
  var port = config.port.rfid;
  if ( !port ) {
    console.log("Please set the rfidreader port in the config.");
    return;
  }

  // create new instance
  rfidReader = new RFIDReader(port);

  // add event listeners
  rfidReader.on('data', function(data) {
    data = data.toString();
    console.log("Data by RFID reader:", data);

    db.Card.find({
      where: {
        uid: data
      }
    }).success(function(card) {
      if ( !card ) {
        console.log("no card found.");
      } else {
        console.log("Card found.");
        card.getUser().success(function(user) {
          if ( !user ) {
            console.log("no user found");
          } else {
            console.log("user is", user.username);
          }
        });
      }
    });
  });

  // open connection
  rfidReader.open(function(err) {
    if ( !!err ) {
      console.log("Error opening connection to rfid reader:", err);
    } else {
      console.log("Connection to RFID reader opened (" + port + ").");
    }
  });
}
/**
 * Initializes the connection with the relais card.
 * */
function initRelais() {
  var port = config.port.relais;
  if ( !port ) {
    console.log("Please set the relais card port in the config.");
    return;
  }

  relais = new Relais(port);

  relais.open(function(err) {
    if ( !!err ) {
      console.log("Error opening connection to relais card:", err);
    } else {
      relais.setup(function(err, ok) {
        if ( !!err ) {
          console.log("Error setting up relais card:", err);
        } else {
          if ( !ok ) {
            console.log("Could not open connection to relais card.");
          } else {
            console.log("Connection to relais card opened (" + port + ").");

            relais.deactivateAll();
          }
        }
      });
    }
  });
}

function openDoor(callback) {
  // TODO: Try out if it really works in real environments
  relais.setSingle(config.relaisport.door, function(err) {
    if ( !!err ) {
      console.log("Error opening the door:", err);
      return callback(err);
    }

    setTimeout(function() {
      relais.delSingle(config.relaisport.door, function(err) {
        if ( !!err ) {
          console.log("Door could not be closed!");
          return callback(err);
        }

        console.log("door closed.");
        return callback(null);
      });
    }, config.web.doorOpenTime);

  });
}

if ( !module.parent || typeof PhusionPassenger !== 'undefined') {
  /**
   * The main application entry point.
   * */
  (function main() {
    console.log(package.name, "v" + package.version, "started.");

    initRFIDReader();
    initRelais();
    startWeb();
  }());
}

function exit(err) {
  if ( err ) {
    console.log("Unhandled Error:", err.stack);
  } else {
    console.log("Exiting...");
  }
  if ( rfidReader.isOpen ) {
    rfidReader.close();
  }
  if ( relais.isOpen ) {
    relais.close();
  }

  web.stop();

  // Done
  console.log("Bye!");
  // won't exit otherwise
  process.kill();
}
process.on('SIGINT', exit);
if ( process.env.NODE_ENV !== 'development' ) {
  process.on('exit', exit);
  process.on('uncaughtException', exit);
}
<commit_msg>Opening door after RFID request.<commit_after>/**
 * Main application module.
 * Project started: 16.03.2014 - 00:21
 * @module app
 * @author Sören Gade
 *
 * @requires config
 * @requires web/index
 * @requires io/rfidreader
 * */

require('./log-replace')();
var package = require('../package');
var config = require('./config');
var web = require('./web/');
var RFIDReader = require('./io/rfidreader');
var Relais = require('./io/relais');
var db = require('./db/');

/* ==========
 * Globals
 * ==========
 * */
var rfidReader = null;
var relais = null;

/* ==========
 * Init
 * ==========
 * */
/**
 * Starts the webserver.
 * */
function startWeb() {
  var port = config.web.port;

  if(typeof PhusionPassenger !== 'undefined') {
    PhusionPassenger.configure({ autoInstall: false });
    port = 'passenger';
  }

  web.init(port, web_RFIDRequest, web_OpenDoor, function() {
    web.start(function() {
      console.log("Web interface running on port " + web.getPort() + ".");
    });
  });
}
// callbacks for web requests
function web_RFIDRequest(callback) {
  rfidReader.on('data', function(data) {
    callback(data);
  });
}
function web_OpenDoor(callback) {
  console.log("Opening door...");

  openDoor(callback);
}

/**
 * Initializes the connection with the RFID reader.
 * */
function initRFIDReader() {
  var port = config.port.rfid;
  if ( !port ) {
    console.log("Please set the rfidreader port in the config.");
    return;
  }

  // create new instance
  rfidReader = new RFIDReader(port);

  // add event listeners
  rfidReader.on('data', function(data) {
    data = data.toString();
    console.log("Data by RFID reader:", data);

    db.Card.find({
      where: {
        uid: data
      }
    }).success(function(card) {
      if ( !card ) {
        console.log("no card found.");
      } else {
        console.log("Card found.");
        card.getUser().success(function(user) {
          if ( !user ) {
            console.log("no user found");
          } else {
            console.log("user is", user.username);

            openDoor(function(err) {
              if ( !!err ) {
                console.log("Error opening door:", err);
                return;
              }

              console.log("Door had been opened.");
            });
          }
        });
      }
    });
  });

  // open connection
  rfidReader.open(function(err) {
    if ( !!err ) {
      console.log("Error opening connection to rfid reader:", err);
    } else {
      console.log("Connection to RFID reader opened (" + port + ").");
    }
  });
}
/**
 * Initializes the connection with the relais card.
 * */
function initRelais() {
  var port = config.port.relais;
  if ( !port ) {
    console.log("Please set the relais card port in the config.");
    return;
  }

  relais = new Relais(port);

  relais.open(function(err) {
    if ( !!err ) {
      console.log("Error opening connection to relais card:", err);
    } else {
      relais.setup(function(err, ok) {
        if ( !!err ) {
          console.log("Error setting up relais card:", err);
        } else {
          if ( !ok ) {
            console.log("Could not open connection to relais card.");
          } else {
            console.log("Connection to relais card opened (" + port + ").");

            relais.deactivateAll();
          }
        }
      });
    }
  });
}

function openDoor(callback) {
  // TODO: Try out if it really works in real environments
  relais.setSingle(config.relaisport.door, function(err) {
    if ( !!err ) {
      console.log("Error opening the door:", err);
      return callback(err);
    }

    setTimeout(function() {
      relais.delSingle(config.relaisport.door, function(err) {
        if ( !!err ) {
          console.log("Door could not be closed!");
          return callback(err);
        }

        console.log("door closed.");
        return callback(null);
      });
    }, config.web.doorOpenTime);

  });
}

if ( !module.parent || typeof PhusionPassenger !== 'undefined') {
  /**
   * The main application entry point.
   * */
  (function main() {
    console.log(package.name, "v" + package.version, "started.");

    initRFIDReader();
    initRelais();
    startWeb();
  }());
}

function exit(err) {
  if ( err ) {
    console.log("Unhandled Error:", err.stack);
  } else {
    console.log("Exiting...");
  }
  if ( rfidReader.isOpen ) {
    rfidReader.close();
  }
  if ( relais.isOpen ) {
    relais.close();
  }

  web.stop();

  // Done
  console.log("Bye!");
  // won't exit otherwise
  process.kill();
}
process.on('SIGINT', exit);
if ( process.env.NODE_ENV !== 'development' ) {
  process.on('exit', exit);
  process.on('uncaughtException', exit);
}
<|endoftext|>


<commit_before>require.main.paths.splice(0, 0, process.env.NODE_PATH);
var remote = require('remote');
var ContainerStore = require('./stores/ContainerStore');
var Menu = remote.require('menu');
var React = require('react');
var SetupStore = require('./stores/SetupStore');
var bugsnag = require('bugsnag-js');
var ipc = require('ipc');
var machine = require('./utils/DockerMachineUtil');
var metrics = require('./utils/MetricsUtil');
var router = require('./router');
var template = require('./menutemplate');
var webUtil = require('./utils/WebUtil');
var urlUtil = require ('./utils/URLUtil');
var app = remote.require('app');
var request = require('request');

webUtil.addWindowSizeSaving();
webUtil.addLiveReload();
webUtil.addBugReporting();
webUtil.disableGlobalBackspace();

Menu.setApplicationMenu(Menu.buildFromTemplate(template()));

metrics.track('Started App');
metrics.track('app heartbeat');
setInterval(function () {
  metrics.track('app heartbeat');
}, 14400000);

router.run(Handler => React.render(<Handler/>, document.body));

SetupStore.setup().then(() => {
  if (ContainerStore.pending()) {
    router.transitionTo('pull');
  } else {
    router.transitionTo('new');
  }
  Menu.setApplicationMenu(Menu.buildFromTemplate(template()));
  ContainerStore.on(ContainerStore.SERVER_ERROR_EVENT, (err) => {
    bugsnag.notify(err);
  });
  ContainerStore.init(function () {});
}).catch(err => {
  metrics.track('Setup Failed', {
    step: 'catch',
    message: err.message
  });
  console.log(err);
  bugsnag.notify(err);
});

ipc.on('application:quitting', () => {
  if (localStorage.getItem('settings.closeVMOnQuit') === 'true') {
    machine.stop();
  }
});

// Event fires when the app receives a docker:// URL such as
// docker://repository/run/redis
ipc.on('application:open-url', opts => {
  request.get('https://kitematic.com/flags.json', (flags, err) => {
    if (err || !flags) {
      return;
    }
    urlUtil.openUrl(opts.url, flags, app.getVersion());
  });
});

urlUtil.openUrl('docker://repository/run/redis', {dockerURLEnabledVersion: '0.5.19'}, app.getVersion());
<commit_msg>removing test url<commit_after>require.main.paths.splice(0, 0, process.env.NODE_PATH);
var remote = require('remote');
var ContainerStore = require('./stores/ContainerStore');
var Menu = remote.require('menu');
var React = require('react');
var SetupStore = require('./stores/SetupStore');
var bugsnag = require('bugsnag-js');
var ipc = require('ipc');
var machine = require('./utils/DockerMachineUtil');
var metrics = require('./utils/MetricsUtil');
var router = require('./router');
var template = require('./menutemplate');
var webUtil = require('./utils/WebUtil');
var urlUtil = require ('./utils/URLUtil');
var app = remote.require('app');
var request = require('request');

webUtil.addWindowSizeSaving();
webUtil.addLiveReload();
webUtil.addBugReporting();
webUtil.disableGlobalBackspace();

Menu.setApplicationMenu(Menu.buildFromTemplate(template()));

metrics.track('Started App');
metrics.track('app heartbeat');
setInterval(function () {
  metrics.track('app heartbeat');
}, 14400000);

router.run(Handler => React.render(<Handler/>, document.body));

SetupStore.setup().then(() => {
  if (ContainerStore.pending()) {
    router.transitionTo('pull');
  } else {
    router.transitionTo('new');
  }
  Menu.setApplicationMenu(Menu.buildFromTemplate(template()));
  ContainerStore.on(ContainerStore.SERVER_ERROR_EVENT, (err) => {
    bugsnag.notify(err);
  });
  ContainerStore.init(function () {});
}).catch(err => {
  metrics.track('Setup Failed', {
    step: 'catch',
    message: err.message
  });
  console.log(err);
  bugsnag.notify(err);
});

ipc.on('application:quitting', () => {
  if (localStorage.getItem('settings.closeVMOnQuit') === 'true') {
    machine.stop();
  }
});

// Event fires when the app receives a docker:// URL such as
// docker://repository/run/redis
ipc.on('application:open-url', opts => {
  request.get('https://kitematic.com/flags.json', (flags, err) => {
    if (err || !flags) {
      return;
    }
    urlUtil.openUrl(opts.url, flags, app.getVersion());
  });
});
<|endoftext|>


<commit_before>/**
 *  flic
 *  Written by: Nick Comer <nick@comer.io> (http://nick.comer.io)
 *  Licensed under MIT
 */

var net = require("net"),
	util = require("util"),
	events = require("events"),
	debug = require("debug")("flic"),
	_ = require("lodash"),
	Message = require("./flic-message.js");

// slave1 --[SLAVE_TELL(slave_name, slave_event, params...)]-> master --[SLAVE_EVENT(from, callback_id, event_name, params)]-> slave2
// 	||																													||	  <-[EVENT_CALLBACK(to, callback_id, params)]-------------   ||
//	||	 <-[MSG_ACK(callback_id, params...)]-----------------   ||

const SLAVE_TELL = "slave_tell";
// when going to master
// [0] slave name
// [1] slave event
// [2] array of params

const SLAVE_EVENT = "slave_event";
// [0] sent from which slave
// [1] callback id
// [2] event name
// [3] array of params

const EVENT_CALLBACK = "event_callback";
// [0] to
// [1] callback_id
// [2] params

const SLAVE_IDENT = "slave_ident";
// NOTE: slaveName can be attached to the message instead of having to be placed
// in the data array.

const MSG_ACK = "message_ack";
// [0] the id of the message that is being acknowledged
// [1] array of args
//
// NOTE: MSG_ACK should never EVER be sent to Master, this might results in a
// callback loop.

function Master(port) {
	var self = this;
	if (!_.isNumber(port)) port = 8221;

	self.sockets = {};
	self.server = net.createServer(function(socket) {
		debug("Master - new slave");

		socket.on("data", function(message) {

			if (process.env.DEBUG_FLIC) {
				debug("Slave --> Master: %s", message);
			}

			// message is a stringified JSON, let's parse it
			message = JSON.parse(message);

			// make sure that the message has a type
			if (message.hasOwnProperty("type") && _.isString(message.type)) {
				switch (message.type) {
					case SLAVE_IDENT:
						debug("Master - Received SLAVE_IDENT from %s", message.slaveName);

						// Check if slave name is already taken
						if ( !! self.sockets[message.slaveName]) {
							debug("Duplicate slave name: %s", message.slaveName);

							// Unfortunately Error containers don't translate across TCP, so
							// we have to fall back to just putting error messages in strings.
							//
							// Documentation should strongly advise using the "error-first"
							// style callbacks, as flic will send any non-fatal error messages
							// using this paradigm.
							var err = new Error("Duplicate slave name!");
							err = err.toString();

							var ack_w_err = new Message(MSG_ACK, [message.id, [err]]);
							socket.write(ack_w_err.toString());
							return;
						}

						// Save socket to list of sockets!
						self.sockets[message.slaveName] = socket;

						// Create MSG_ACK message
						var ack = new Message(MSG_ACK, [message.id, [null]]);

						// Send that bitch
						debug("Master - Sending MSG_ACK (id: %s)", message.id);
						self.sockets[message.slaveName].write(ack.toString());

						break;
					case SLAVE_TELL:
						debug("Master - Received SLAVE_TELL from %s", message.slaveName);
						var to_tell = message.data[0];
						if (!self.sockets[to_tell]) {
							debug("Attempting to tell a non-existent slave: %s", to_tell);

							var err = new Error("Attempting to tell non-existent slave");
							err = err.toString();

							var ack_w_err = new Message(MSG_ACK, [message.id, [err]]);
							self.sockets[message.slaveName].write(ack_w_err.toString());
							return;
						}

						// Okay so the slave exists, lets prepare a message

						var msg = new Message(SLAVE_EVENT, [message.slaveName, message.id, message.data[1], message.data[2]]);

						self.sockets[message.data[0]].write(msg.toString());
						break;
					case EVENT_CALLBACK:
						debug("Master - Received EVENT_CALLBACK from %s", message.slaveName);
						var to = message.data[0],
							callback_id = message.data[1],
							params = message.data[2],
							msg;

						var msg = new Message(MSG_ACK, [callback_id, params]);

						self.sockets[to].write(msg.toString());
						break;
					default:
						debug("Master received unrecognized command");
				}
			}
		});
	}).listen(port, function() {
		debug("Master - listening on port %d", port);
	});
}

function Slave(name, port, callback) {
	/*
	TODO:
	- if disconnected from Master attempt to reconnect
	 */

	var self = this;

	// Set slave name
	if (!_.isString(name) && !name.match(/^[a-zA-Z|_|$][a-zA-Z0-9|_|$]*$/))
		throw new Error("Slave must have a valid name");
	else
		self.slaveName = name;

	// Make sure we have a valid port number
	if (!_.isNumber(port)) port = 8221;

	// Set up an array to store waiting callbacks
	self.waiters = {};

	// Lets connect to the Master
	self.master = net.connect(port, function() {

		// Identify the slave to the master
		debug("Slave  - sending SLAVE_IDENT");

		// Create a new Message
		var ident = new Message(SLAVE_IDENT);

		// Attach the slave name
		ident.setSlaveName(self.slaveName);

		// Get the ID of the message so we can store the callback as a waiter
		var message_id = ident.getId();

		// store the callback in the waiters list
		self.waiters[message_id] = callback;

		// tell the master
		self.master.write(ident.toString());
	});

	self.master.on("data", function(message) {

		if (process.env.DEBUG_FLIC) {
			debug("Slave <-- Master: %s", message);
		}

		// message is a stringified JSON, let's parse it
		message = JSON.parse(message);

		if (message.hasOwnProperty("type")) {
			switch (message.type) {
				case MSG_ACK:
					debug("Slave  - Received MSG_ACK from Master for message: %s", message.data[0]);
					// Save the message ack id - we'll be plucking it from the array later.
					var mid = message.data[0];
					if (self.waiters.hasOwnProperty(mid)) {
						var callback = self.waiters[mid];

						if (_.isFunction(callback)) {
							var args = message.data[1];

							callback.apply(self, args);

							debug("Slave  - removing callback %s from waiters", mid);
							delete self.waiters[mid];
						}
					}
					break;
				case SLAVE_EVENT:
					var from = message.data[0],
						callback_id = message.data[1],
						event_name = message.data[2],
						params = message.data[3];

					// Define a callback function that can be called by a receiving function
					var cb = function() {
						// Grab all the args
						var args = Array.prototype.slice.call(arguments);

						// construct the message
						var msg = new Message(EVENT_CALLBACK, [from, callback_id, args]);

						// set a slave name just for kicks i guess
						msg.setSlaveName(self.slaveName);

						// send that mo-fucka
						self.master.write(msg.toString());
					};

					// push the callback to the end of the params array
					params.push(cb);

					// push the event name to the beginning
					params.unshift(event_name);

					// emit that sunuva-bitch
					self.emit.apply(self, params);
			}
		}

	});

	self.master.on("error", function(e) {
		callback(err);
	});
}
util.inherits(Slave, events.EventEmitter);

/**
 * Slave.tell - Send an event to a remote slave w/ data
 * @param {string} who_what "slave_name:event_name" a string
 * @param (who_what) - {string}
 * @param {args} args - any amount of arguments that need to be sent to the event
 * @param {function} callback - a callback function if the slave decideds to reply
 * @return {null}
 */
Slave.prototype.tell = function() {
	var self, args, who_what, callback, tell_message, mid;

	self = this;
	args = Array.prototype.slice.call(arguments);
	who_what = args.shift();
	if (_.isFunction(args[args.length - 1])) {
		callback = args.pop();
	}

	if (!(_.isString(who_what) && who_what.match(/^[a-zA-Z0-9|_|$]*:[a-zA-Z0-9|_|$]*$/)))
		throw new Error("Invalid tell statment");

	var i = who_what.indexOf(":");
	var slaveName = who_what.substring(0, i);
	var eventName = who_what.substring(i + 1);

	var destination = [slaveName, eventName, args];

	tell_message = new Message(SLAVE_TELL, destination);
	tell_message.setSlaveName(self.slaveName);

	if ( !! callback) {
		mid = tell_message.getId();
		self.waiters[mid] = callback;
	}

	self.master.write(tell_message.toString());

	return self;
}

Slave.prototype.shout = function() {

};

module.exports = {
	master: Master,
	slave: Slave
};<commit_msg>better argument handling. Anonymous Slaves. more improvements.<commit_after>/**
 *  flic
 *  Written by: Nick Comer <nick@comer.io> (http://nick.comer.io)
 *  Licensed under MIT
 */

var net = require("net"),
	util = require("util"),
	events = require("events"),
	debug = require("debug")("flic"),
	_ = require("lodash"),
	Message = require("./flic-message.js");

// slave1 --[SLAVE_TELL(slave_name, slave_event, params...)]-> master --[SLAVE_EVENT(from, callback_id, event_name, params)]-> slave2
// 	||																													||	  <-[EVENT_CALLBACK(to, callback_id, params)]-------------   ||
//	||	 <-[MSG_ACK(callback_id, params...)]-----------------   ||

const SLAVE_TELL = "slv-tell";
// Send a message to the master to tell a slave about an event.
// [0] slave name
// [1] slave event
// [2] array of params

const SLAVE_EVENT = "slv-evnt";
// Master sends a message to a slave about an event sent from another slave
// [0] sent from which slave
// [1] callback id
// [2] event name
// [3] array of params

const EVENT_CALLBACK = "evnt-cb";
// Slave sends a callback from an event back to the master, master then sends
// MSG_ACK
// [0] to
// [1] callback_id
// [2] params

const SLAVE_IDENT = "slv-ident";
// NOTE: slaveName can be attached to the message instead of having to be placed
// in the data array.

const MSG_ACK = "msg-ack";
// [0] the id of the message that is being acknowledged
// [1] array of args
//
// NOTE: MSG_ACK should never EVER be sent to Master, this might results in a
// callback loop.

function Master(port) {
	var self = this;

	if(port){
		if(_.isNumber(port)){
			if(!(port > 1023 && port <= 65535)){
				throw new Error("Invalid port number supplied");
			}
		}else{
			throw new Error("Invalid port number supplied");
		}
	}else{
		port = 8221;
	}

	// We store all of the sockets here
	self.sockets = {};

	//
	self.tcpServer = net.createServer(function(socket) {
		debug("Master - new slave");

		socket.on("data", function(message) {

			if (process.env.DEBUG_FLIC) {
				debug("Slave --> Master: %s", message);
			}

			// message is a stringified JSON, let's parse it
			message = JSON.parse(message);

			// make sure that the message has a type
			if (message.hasOwnProperty("type") && _.isString(message.type)) {
				switch (message.type) {
					case SLAVE_IDENT:
						debug("Master - Received SLAVE_IDENT from %s", message.slaveName);

						// Check if slave name is already taken
						if ( !! self.sockets[message.slaveName]) {
							debug("Duplicate slave name: %s", message.slaveName);

							// Unfortunately Error containers don't translate across TCP, so
							// we have to fall back to just putting error messages in strings.
							//
							// Documentation should strongly advise using the "error-first"
							// style callbacks, as flic will send any non-fatal error messages
							// using this paradigm.
							var err = new Error("Duplicate slave name!");
							err = err.toString();

							var ack_w_err = new Message(MSG_ACK, [message.id, [err]]);
							socket.write(ack_w_err.toString());
							return;
						}

						// Save socket to list of sockets!
						self.sockets[message.slaveName] = socket;

						// Create MSG_ACK message
						var ack = new Message(MSG_ACK, [message.id, [null]]);

						// Send that bitch
						debug("Master - Sending MSG_ACK (id: %s)", message.id);
						self.sockets[message.slaveName].write(ack.toString());

						break;
					case SLAVE_TELL:
						debug("Master - Received SLAVE_TELL from %s", message.slaveName);
						var to_tell = message.data[0];
						if (!self.sockets[to_tell]) {
							debug("Attempting to tell a non-existent slave: %s", to_tell);

							var err = new Error("Attempting to tell non-existent slave");
							err = err.toString();

							var ack_w_err = new Message(MSG_ACK, [message.id, [err]]);
							self.sockets[message.slaveName].write(ack_w_err.toString());
							return;
						}

						// Okay so the slave exists, lets prepare a message

						var msg = new Message(SLAVE_EVENT, [message.slaveName, message.id, message.data[1], message.data[2]]);

						self.sockets[message.data[0]].write(msg.toString());
						break;
					case EVENT_CALLBACK:
						debug("Master - Received EVENT_CALLBACK from %s", message.slaveName);
						var to = message.data[0],
							callback_id = message.data[1],
							params = message.data[2],
							msg;

						var msg = new Message(MSG_ACK, [callback_id, params]);

						self.sockets[to].write(msg.toString());
						break;
					default:
						debug("Master received unrecognized command");
				}
			}
		});
	}).listen(port, function() {
		debug("Master - listening on port %d", port);
	});
}

function Slave() {
	var name, port, callback, self, args;
	/*
	TODO:
	- if disconnected from Master attempt to reconnect
	 */

	args = Array.prototype.slice.call(arguments);

	for(var i = 0; i < args.length; i++){
		if(_.isString(args[i]))
	 		name = args[i];

	 	if(_.isNumber(args[i]))
	 		port = args[i];

	 	if(_.isFunction(args[i]))
	 		callback = args[i];
	}

	self = this;

	// Set slave name
	if (!name) {
		// No name? Anonymous slave.
		// Anonymous slaves:
		// - Can receive shouts
		// - Can't be told remotely (Slave.tell)
		// - Can tell other slaves and receive callbacks from tell
		self.slaveName = randString();
	} else {
		if (!name.match(/^[a-zA-Z|_|$][a-zA-Z0-9|_|$]*$/))
			throw new Error("Slave must have a valid name");
		else
			self.slaveName = name;
	}

	// Make sure we have a valid port number
	if (!port || port <= 1023 || port > 65535) port = 8221;

	// Make sure there is a function to call, even if its empty
	if (!callback) callback = function(){};

	// Set up an array to store waiting callbacks
	self.waiters = {};

	// Lets connect to the Master
	self.master = net.connect(port, function() {
		var ident, message_id;

		// Identify the slave to the master
		debug("Slave  - sending SLAVE_IDENT");

		// Create a new Message
		ident = new Message(SLAVE_IDENT);

		// Attach the slave name
		ident.setSlaveName(self.slaveName);

		// Get the ID of the message so we can store the callback as a waiter
		message_id = ident.getId();

		// store the callback in the waiters list
		self.waiters[message_id] = callback;

		// tell the master
		self.master.write(ident.toString());
	});

	self.master.on("data", function(message) {

		if (process.env.DEBUG_FLIC) {
			debug("Slave <-- Master: %s", message);
		}

		// message is a stringified JSON, let's parse it
		message = JSON.parse(message);

		if (message.hasOwnProperty("type")) {
			switch (message.type) {
				case MSG_ACK:
					debug("Slave  - Received MSG_ACK from Master for message: %s", message.data[0]);
					// Save the message ack id - we'll be plucking it from the array later.
					var mid = message.data[0];
					if (self.waiters.hasOwnProperty(mid)) {
						var callback = self.waiters[mid];

						if (_.isFunction(callback)) {
							var args = message.data[1];

							callback.apply(self, args);

							debug("Slave  - removing callback %s from waiters", mid);
							delete self.waiters[mid];
						}
					}
					break;
				case SLAVE_EVENT:
					var from = message.data[0],
						callback_id = message.data[1],
						event_name = message.data[2],
						params = message.data[3];

					debug("Slave  - Received SLAVE_EVENT(%s) from %s", event_name, from);

					// Define a callback function that can be called by a receiving function
					var cb = function() {
						var args, msg;
						// Grab all the args
						args = Array.prototype.slice.call(arguments);

						// construct the message
						msg = new Message(EVENT_CALLBACK, [from, callback_id, args]);

						// set a slave name just for kicks i guess
						msg.setSlaveName(self.slaveName);

						// send that mo-fucka
						self.master.write(msg.toString());
					};

					// push the callback to the end of the params array
					params.push(cb);

					// push the event name to the beginning
					params.unshift(event_name);

					// emit that sunuva-bitch
					self.emit.apply(self, params);
			}
		}

	});

	self.master.on("error", function(e) {
		callback(e);
	});
}
util.inherits(Slave, events.EventEmitter);

Slave.prototype.connect = function() {
	// body...
};

/**
 * Slave.tell - Send an event to a remote slave w/ data
 * @param {string} who_what "slave_name:event_name" a string
 * @param (who_what) - {string}
 * @param {args} args - any amount of arguments that need to be sent to the event
 * @param {function} callback - a callback function if the slave decideds to reply
 * @return {null}
 */
Slave.prototype.tell = function() {
	var self, args, who_what, callback, tell_message, mid;

	self = this;
	args = Array.prototype.slice.call(arguments);
	who_what = args.shift();
	if (_.isFunction(args[args.length - 1])) {
		callback = args.pop();
	}

	if (!(_.isString(who_what) && who_what.match(/^[a-zA-Z0-9|_|$]*:[a-zA-Z0-9|_|$]*$/)))
		throw new Error("Invalid tell statment");

	var i = who_what.indexOf(":");
	var slaveName = who_what.substring(0, i);
	var eventName = who_what.substring(i + 1);

	var destination = [slaveName, eventName, args];

	tell_message = new Message(SLAVE_TELL, destination);
	tell_message.setSlaveName(self.slaveName);

	if ( !! callback) {
		mid = tell_message.getId();
		self.waiters[mid] = callback;
	}

	self.master.write(tell_message.toString());

	return self;
}

Slave.prototype.shout = function() {

};

function randString() {
	var text = "";
	var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

	for (var i = 0; i < 5; i++)
		text += possible.charAt(Math.floor(Math.random() * possible.length));

	return text;
}

module.exports = {
	master: Master,
	slave: Slave
};<|endoftext|>


<commit_before>'use strict';

const apiai = require('apiai');
const express = require('express');
const bodyParser = require('body-parser');
const uuid = require('node-uuid');
const request = require('request');

const REST_PORT = (process.env.PORT || 5000);
const APIAI_ACCESS_TOKEN = process.env.APIAI_ACCESS_TOKEN;
const APIAI_LANG = process.env.APIAI_LANG || 'en';
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;
const FB_PAGE_ACCESS_TOKEN = process.env.FB_PAGE_ACCESS_TOKEN;

const apiAiService = apiai(APIAI_ACCESS_TOKEN, {language: APIAI_LANG, requestSource: "fb"});
const sessionIds = new Map();

function processEvent(event) {
    var sender = event.sender.id;

    if (event.message && event.message.text) {
        var text = event.message.text;
        // Handle a text message from this sender

        if (!sessionIds.has(sender)) {
            sessionIds.set(sender, uuid.v1());
        }

        console.log("Text", text);
        var userName = "User_Name";

        let apiaiRequest = apiAiService.textRequest(text,
            {
                sessionId: sessionIds.get(sender)
            });

        apiaiRequest.on('response', (response) => {
            if (isDefined(response.result)) {
                let responseText = response.result.fulfillment.speech;
                let responseData = response.result.fulfillment.data;
                let action = response.result.action;

                if (isDefined(responseData) && isDefined(responseData.facebook)) {
                    try {
                        console.log('Response as formatted message');
                        sendFBMessage(sender, responseData.facebook);
                    } catch (err) {
                        sendFBMessage(sender, {text: err.message });
                    }
                } else if (isDefined(responseText)) {
                    console.log('Response as text message');
                    sendFBMessage(sender, {text: responseText});
                }

            }
        });

        apiaiRequest.on('error', (error) => console.error(error));
        apiaiRequest.end();
    }
}

function sendFBMessage(sender, messageData) {

    var APISpeech = require('./powerlevel')(9050);
    if(APISpeech == "structured"){
        messageData = {
            "attachment": {
              "type": "template",
              "payload": {
                "template_type": "generic",
                "elements": [{
                  "title": "First card",
                  "subtitle": "Element #1 of an hscroll",
                  "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
                  "buttons": [{
                    "type": "web_url",
                    "url": "https://www.messenger.com/",
                    "title": "Web url"
                  }, {
                    "type": "postback",
                    "title": "Postback",
                    "payload": "Payload for first element in a generic bubble",
                  }],
                },{
                  "title": "Second card",
                  "subtitle": "Element #2 of an hscroll",
                  "image_url": "http://messengerdemo.parseapp.com/img/gearvr.png",
                  "buttons": [{
                    "type": "postback",
                    "title": "Postback",
                    "payload": "Payload for second element in a generic bubble",
                  }],
                }]
              }
            }
          };
    }

    request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {access_token: FB_PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: sender},
            message: messageData
        }
    }, function (error, response, body) {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }
    });
}

function doSubscribeRequest() {
    request({
            method: 'POST',
            uri: "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=" + FB_PAGE_ACCESS_TOKEN
        },
        function (error, response, body) {
            if (error) {
                console.error('Error while subscription: ', error);
            } else {
                console.log('Subscription result: ', response.body);
            }
        });
}

function isDefined(obj) {
    if (typeof obj == 'undefined') {
        return false;
    }

    if (!obj) {
        return false;
    }

    return obj != null;
}

const app = express();
app.use(bodyParser.json());
app.all('*', function (req, res, next) {
    // res.header("Access-Control-Allow-Origin", '*');
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, content-type, accept");
    next();
});

app.get('/webhook/', function (req, res) {
    if (req.query['hub.verify_token'] == FB_VERIFY_TOKEN) {
        res.send(req.query['hub.challenge']);

        setTimeout(function () {
            doSubscribeRequest();
        }, 3000);
    } else {
        res.send('Error, wrong validation token');
    }
});

app.post('/webhook/', function (req, res) {
    try {
        var messaging_events = req.body.entry[0].messaging;
        for (var i = 0; i < messaging_events.length; i++) {
            var event = req.body.entry[0].messaging[i];

             if (event.message) {
                  processEvent(event);
             }else{
                 if (event.postback) {
                    sendFBMessage(event.sender.id, {"text" : JSON.stringify(event)});
                  }
             }

        }
        return res.status(200).json({
            status: "ok"
        });
    } catch (err) {
        return res.status(400).json({
            status: "error",
            error: err
        });
    }

});

app.listen(REST_PORT, function () {
    console.log('Rest service ready on port ' + REST_PORT);
});

doSubscribeRequest();
<commit_msg>Update app.js<commit_after>'use strict';

const apiai = require('apiai');
const express = require('express');
const bodyParser = require('body-parser');
const uuid = require('node-uuid');
const request = require('request');

const REST_PORT = (process.env.PORT || 5000);
const APIAI_ACCESS_TOKEN = process.env.APIAI_ACCESS_TOKEN;
const APIAI_LANG = process.env.APIAI_LANG || 'en';
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;
const FB_PAGE_ACCESS_TOKEN = process.env.FB_PAGE_ACCESS_TOKEN;

const apiAiService = apiai(APIAI_ACCESS_TOKEN, {language: APIAI_LANG, requestSource: "fb"});
const sessionIds = new Map();

function processEvent(event) {
    var sender = event.sender.id;

    if (event.message && event.message.text) {
        var text = event.message.text;
        // Handle a text message from this sender

        if (!sessionIds.has(sender)) {
            sessionIds.set(sender, uuid.v1());
        }

        console.log("Text", text);
        var userName = "User_Name";

        let apiaiRequest = apiAiService.textRequest(text,
            {
                sessionId: sessionIds.get(sender)
            });

        apiaiRequest.on('response', (response) => {
            if (isDefined(response.result)) {
                let responseText = response.result.fulfillment.speech;
                let responseData = response.result.fulfillment.data;
                let action = response.result.action;

                if (isDefined(responseData) && isDefined(responseData.facebook)) {
                    try {
                        console.log('Response as formatted message');
                        sendFBMessage(sender, responseData.facebook);
                    } catch (err) {
                        sendFBMessage(sender, {text: err.message });
                    }
                } else if (isDefined(responseText)) {
                    console.log('Response as text message');
                    sendFBMessage(sender, {text: responseText});
                }

            }
        });

        apiaiRequest.on('error', (error) => console.error(error));
        apiaiRequest.end();
    }
}

function sendFBMessage(sender, messageData) {

    var APISpeech = require('powerlevel')(9050);
    if(APISpeech == "structured"){
        messageData = {
            "attachment": {
              "type": "template",
              "payload": {
                "template_type": "generic",
                "elements": [{
                  "title": "First card",
                  "subtitle": "Element #1 of an hscroll",
                  "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
                  "buttons": [{
                    "type": "web_url",
                    "url": "https://www.messenger.com/",
                    "title": "Web url"
                  }, {
                    "type": "postback",
                    "title": "Postback",
                    "payload": "Payload for first element in a generic bubble",
                  }],
                },{
                  "title": "Second card",
                  "subtitle": "Element #2 of an hscroll",
                  "image_url": "http://messengerdemo.parseapp.com/img/gearvr.png",
                  "buttons": [{
                    "type": "postback",
                    "title": "Postback",
                    "payload": "Payload for second element in a generic bubble",
                  }],
                }]
              }
            }
          };
    }

    request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {access_token: FB_PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: sender},
            message: messageData
        }
    }, function (error, response, body) {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }
    });
}

function doSubscribeRequest() {
    request({
            method: 'POST',
            uri: "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=" + FB_PAGE_ACCESS_TOKEN
        },
        function (error, response, body) {
            if (error) {
                console.error('Error while subscription: ', error);
            } else {
                console.log('Subscription result: ', response.body);
            }
        });
}

function isDefined(obj) {
    if (typeof obj == 'undefined') {
        return false;
    }

    if (!obj) {
        return false;
    }

    return obj != null;
}

const app = express();
app.use(bodyParser.json());
app.all('*', function (req, res, next) {
    // res.header("Access-Control-Allow-Origin", '*');
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, content-type, accept");
    next();
});

app.get('/webhook/', function (req, res) {
    if (req.query['hub.verify_token'] == FB_VERIFY_TOKEN) {
        res.send(req.query['hub.challenge']);

        setTimeout(function () {
            doSubscribeRequest();
        }, 3000);
    } else {
        res.send('Error, wrong validation token');
    }
});

app.post('/webhook/', function (req, res) {
    try {
        var messaging_events = req.body.entry[0].messaging;
        for (var i = 0; i < messaging_events.length; i++) {
            var event = req.body.entry[0].messaging[i];

             if (event.message) {
                  processEvent(event);
             }else{
                 if (event.postback) {
                    sendFBMessage(event.sender.id, {"text" : JSON.stringify(event)});
                  }
             }

        }
        return res.status(200).json({
            status: "ok"
        });
    } catch (err) {
        return res.status(400).json({
            status: "error",
            error: err
        });
    }

});

app.listen(REST_PORT, function () {
    console.log('Rest service ready on port ' + REST_PORT);
});

doSubscribeRequest();
<|endoftext|>


<commit_before>'use strict';

// loading config etc.
const newrelic = require('newrelic');
const config = require('../config');
const version = require('../package.json').version;

// loading libraries
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io');
const socket = io(server);
const path = require('path');
const logger = require('./logger');

// Loading components
import SearchServer from './components/Search/Search.server.js';

// settings up our provider
const serviceProvider = require('dbc-node-serviceprovider');
serviceProvider.init(config.services, socket);

// Port config
app.set('port', process.env.PORT || 8080); // eslint-disable-line no-process-env

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

// setting paths
app.use(express.static(path.join(__dirname, '../public')));
app.use(express.static(path.join(__dirname, '../static')));

// setting local vars that should be availbe to our template engine
app.locals.newrelic = newrelic;
app.locals.version = version;
app.locals.production = (process.env.NODE_ENV === 'production'); // eslint-disable-line no-process-env

// setting basic routes -- should be moved elsewhere in the future
app.get('/', function(req, res) {
  res.render('logo');
});

app.get('/autocomplete', function(req, res) {
  res.render('autocomplete');
});

app.get(['/search', '/search/*'], function(req, res) {
  const query = req.query || [];
  res.render('search', SearchServer({query}));
});

app.get(['/work', '/work/*'], function(req, res) {
  let pid = req.query.pid;
  pid = '"' + pid + '"';
  res.render('work', {pid});
});

// starting server
server.listen(app.get('port'), function() {
  logger.info('Server listening on ' + app.get('port'));
  logger.info({message: 'Versions: ', data: process.versions});
  logger.info(version + ' is up and running');
});
<commit_msg>Search page on /<commit_after>'use strict';

// loading config etc.
const newrelic = require('newrelic');
const config = require('../config');
const version = require('../package.json').version;

// loading libraries
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io');
const socket = io(server);
const path = require('path');
const logger = require('./logger');

// Loading components
import SearchServer from './components/Search/Search.server.js';

// settings up our provider
const serviceProvider = require('dbc-node-serviceprovider');
serviceProvider.init(config.services, socket);

// Port config
app.set('port', process.env.PORT || 8080); // eslint-disable-line no-process-env

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

// setting paths
app.use(express.static(path.join(__dirname, '../public')));
app.use(express.static(path.join(__dirname, '../static')));

// setting local vars that should be availbe to our template engine
app.locals.newrelic = newrelic;
app.locals.version = version;
app.locals.production = (process.env.NODE_ENV === 'production'); // eslint-disable-line no-process-env

app.get(['/', '/search', '/search/*'], function(req, res) {
  const query = req.query || [];
  res.render('search', SearchServer({query}));
});

app.get('/autocomplete', function(req, res) {
  res.render('autocomplete');
});

app.get(['/work', '/work/*'], function(req, res) {
  let pid = req.query.pid;
  pid = '"' + pid + '"';
  res.render('work', {pid});
});

// starting server
server.listen(app.get('port'), function() {
  logger.info('Server listening on ' + app.get('port'));
  logger.info({message: 'Versions: ', data: process.versions});
  logger.info(version + ' is up and running');
});
<|endoftext|>


<commit_before>var fs = require('fs');
var repeat = require('repeat');
var config = require('./config.json');
var canvas = require('./services/canvas');
var repo = require('./services/repo');

var getJulian = function(date) {
    var onejan = new Date(date.getFullYear(),0,1);
    return Math.ceil((date - onejan) / 86400000);
}

var getRequiredCommits = function(){
    var data = canvas.getCanvas(config.input);
    var julian =  getJulian(new Date());

    if(data.length > julian)
        return data[julian];
    else
        return 0;
}

var appendFile = function() {
    fs.appendFile(config.file, new Date(), [], function (error) {
        if(error) throw error;
    });
}

var updateCanvas = function() {
    console.log('updating canvas at ' + new Date())
    try
    {
        var requiredCommits = getRequiredCommits();
        for(var i = 0; i < requiredCommits; i++) {
            appendFile();
            repo.addCommit(config.repo_url, "Updated " + config.file);
        }
        repo.pushCommits(config.repo_url);
    }
    catch(error){
        console.log("Error: " + error)
    }
}

//running method
//repeat(updateCanvas).every(24, 'h').start.now()

//test methods
//var data = canvas.getCanvas(config.input); //still need to get the ghostscript font issue sorted
appendFile(); repo.addCommit(config.repo_url, "Updated " + config.file);<commit_msg>Cleaned up formatting.<commit_after>var fs = require('fs');
var repeat = require('repeat');
var config = require('./config.json');
var canvas = require('./services/canvas');
var repo = require('./services/repo');

var getJulian = function(date) {
    var onejan = new Date(date.getFullYear(),0,1);
    return Math.ceil((date - onejan) / 86400000);
};

var getRequiredCommits = function(){
    var data = canvas.getCanvas(config.input);
    var julian =  getJulian(new Date());

    if(data.length > julian)
        return data[julian];
    else
        return 0;
};

var appendFile = function() {
    fs.appendFile(config.file, new Date(), [], function (error) {
        if(error) throw error;
    });
};

var updateCanvas = function() {
    try
    {
        console.log('Updating canvas at ' + new Date());
        var requiredCommits = getRequiredCommits();

        for(var i = 0; i < requiredCommits; i++) {
            appendFile();
            repo.addCommit(config.repo_url, "Updated " + config.file);
        }

        repo.pushCommits(config.repo_url);
    }
    catch(error){
        console.log("Error: " + error);
    }
};

//running method
//repeat(updateCanvas).every(24, 'h').start.now()

//test methods
//var data = canvas.getCanvas(config.input); //still need to get the ghostscript font issue sorted
appendFile(); repo.addCommit(config.repo_url, "Updated " + config.file);<|endoftext|>


<commit_before>'use strict'

const load = require('./src/core/load.js')

let cy = {}

// loads a file on start
load(cy) // comment for debugging

/*
The default behavior of the app (asking to load graphs) can be annoying
when developing new features. To prevent that, uncomment the code below and
comment everyting above it. It loads a hard coded graph everytime you reload
the app.
*/

// uncomment the code below for debugging

// const testGraph = '../../graphs/implementation/smartHome.js'
// const initialize = require('./src/initialize.js')
// const cyOptions = require('./src/core/cyOptions.js')
//
// let cy = {}
// cyOptions(cy, testGraph) // uncomment for debugging
// initialize(cy.out) // uncomment for debugging
<commit_msg>typos<commit_after>'use strict'

const load = require('./src/core/load.js')

let cy = {}

// loads a file on start
load(cy) // comment for debugging

/*
The default behavior of the app (asking to load graphs) can be annoying
when developing new features. To prevent that, uncomment the code below and
comment everything above it. It loads a hard coded graph every time you reload
the app.
*/

// uncomment the code below for debugging

// const testGraph = '../../graphs/implementation/smartHome.js'
// const initialize = require('./src/initialize.js')
// const cyOptions = require('./src/core/cyOptions.js')
//
// let cy = {}
// cyOptions(cy, testGraph) // uncomment for debugging
// initialize(cy.out) // uncomment for debugging
<|endoftext|>