aio_gif/index.js
2015-03-17 16:16:54 -04:00

142 lines
2.8 KiB
JavaScript

/**** Module dependencies ****/
var stream = require('stream'),
util = require('util'),
http = require('http'),
fs = require('fs'),
AIO = require('adafruit-io'),
Handlebars = require('handlebars'),
path = require('path'),
spawn = require('child_process').spawn;
/**** Make AIO_GIF a writable stream ****/
util.inherits(AIO_GIF, stream.Writable);
/**** AIO_GIF prototype ****/
var proto = AIO_GIF.prototype;
/**** Expose AIO_GIF ****/
exports = module.exports = AIO_GIF;
/**** AIO_GIF constructor ****/
function AIO_GIF(key, feed, options) {
if (! (this instanceof AIO_GIF)) {
return new AIO_GIF(key, feed, options);
}
stream.Writable.call(this);
// pass key and feed as args or just
// pass options as first arg
if(key && feed) {
this.key = key;
this.feed = feed;
} else {
options = key;
}
// apply options
util._extend(this, options || {});
// compile handlebars template
var tmp = fs.readFileSync(this.template, {encoding: 'utf8'});
this.compiled_template = Handlebars.compile(tmp);
if(! this.compiled_template) {
this.emit('error', 'Template failed to compile');
return this.end();
}
// start http server
this.listen();
// connect to AIO if we have a key and feed
if(this.key && this.feed) {
this.connectToAIO();
}
}
proto.aio = false;
proto.key = false;
proto.feed = false;
proto.current = '';
proto.port = 8080;
proto.hostname = false;
proto.template = path.join(__dirname, 'template.handlebars');
proto.compiled_template = false;
proto._write = function(data, encoding, cb) {
data = data.toString().trim();
if(! this.validate(data)) {
return cb();
}
this.current = data;
this.emit('image', data);
cb();
};
// checks if data sent has an image extension
proto.validate = function(data) {
if(/(jpg|png|gif)$/.test(data)) {
return true;
}
return false;
};
// start http server
proto.listen = function() {
// respond to requests using the configured port and hostname
var server = http.createServer(function(req, res) {
// return template with current url
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(this.compiled_template({ url: this.current }));
}.bind(this));
// only listen on specific hostname if it's set
if(this.hostname) {
return server.listen(this.port, this.hostname);
}
server.listen(this.port);
};
proto.connectToAIO = function(key, feed) {
// already connected
if(this.aio) {
return;
}
// save key and feed values if passed
if(key && feed) {
this.key = key;
this.feed = feed;
}
// aio init
this.aio = AIO(this.key);
var feed = this.aio.feeds(this.feed);
// grab last value
feed.last(function(err, data) {
if(err) return;
this.write(data.value);
}.bind(this));
// pipe new values
feed.pipe(this);
};