<commit_before>(function(factory){
  if (typeof define !== "undefined" && define.cmd) {
    define(function(require, exports, module){
      var $ = require('zepto');
      factory($);
    });
  } else {
    var $ = Zepto;
    factory($);
  }
}(function($){

  var mapObj = null,
      citylocation = null,
      aqiTips = null;

  loadScript();

  window.initMap = function(){
    mapObj = new AMap.Map("container", {
      view: new AMap.View2D({
        zoom: 4
      })
    });
    mapObj.plugin(["AMap.MapType"],function(){
      var mapType= new AMap.MapType({
        defaultType:1,
        showRoad:true
      });
      mapObj.addControl(mapType);
    });
    mapObj.plugin(["AMap.ToolBar"],function(){
      var toolBar = new AMap.ToolBar();
      mapObj.addControl(toolBar);
    });
  };

  $.getJSON("data/citylocation.amap.json", function(data){
    citylocation = data;

    $.getJSON("data/tips.baidu.json", function(data){
      aqiTips = data;
      $.getJSON("data/citylist.baidu.json", getAQI);
    });
  });

  function getAQI(citylist){
    $.each(citylist, function(index, item) {
      (function(city){
        $.ajax({
          url: "aqi.php",
          data: {cname: city.name, c: city.code},
          dataType: "json",
          success: function(data) {
            showCityAQI(city.name, data.current_city);
          },
          error: function(xhr, errorType, error){
            console.warn("GetAQI Error:", errorType, error, city.name);
          }
        });
      })(item);

    });
  }

  function showCityAQI(cityShortName, aqiData) {
    if (!citylocation[cityShortName]) return ;
    var cityLoc = citylocation[cityShortName]["point"];

    var markerContent = document.createElement("div");
    markerContent.className = "markerContentStyle";
    markerContent.style.backgroundColor = aqiTips[aqiData.level]["bgColor"];
    markerContent.innerHTML = cityShortName + aqiData.aqi;
    var marker = new AMap.Marker({
      content: markerContent,
      position: new AMap.LngLat(cityLoc.x/100000, cityLoc.y/100000)
    });
    marker.setMap(mapObj);
  }

  function loadScript(){
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "http://webapi.amap.com/maps?v=1.3&key=b1fc6abe324303d61dbccbe745be09de&callback=initMap";
    document.body.appendChild(script);
  }

}));

<commit_msg>Add the showAQIData() function<commit_after>(function(factory){
  if (typeof define !== "undefined" && define.cmd) {
    define(function(require, exports, module){
      var $ = require('zepto');
      factory($);
    });
  } else {
    var $ = Zepto;
    factory($);
  }
}(function($){

  var mapObj = null,
      citylocation = null,
      aqiTips = null;

  loadScript();

  window.initMap = function(){
    mapObj = new AMap.Map("container", {
      view: new AMap.View2D({
        zoom: 4
      })
    });
    mapObj.plugin(["AMap.MapType"],function(){
      var mapType= new AMap.MapType({
        defaultType:1,
        showRoad:true
      });
      mapObj.addControl(mapType);
    });
    mapObj.plugin(["AMap.ToolBar"],function(){
      var toolBar = new AMap.ToolBar();
      mapObj.addControl(toolBar);
    });

    showAQIData();
  };

  function showAQIData() {
    $.getJSON("data/citylocation.amap.json", function(data){
      citylocation = data;

      $.getJSON("data/tips.baidu.json", function(data){
        aqiTips = data;
        $.getJSON("data/citylist.baidu.json", getAQI);
      });
    });
  }

  function getAQI(citylist){
    $.each(citylist, function(index, item) {
      (function(city){
        $.ajax({
          url: "aqi.php",
          data: {cname: city.name, c: city.code},
          dataType: "json",
          success: function(data) {
            showCityAQI(city.name, data.current_city);
          },
          error: function(xhr, errorType, error){
            console.warn("GetAQI Error:", errorType, error, city.name);
          }
        });
      })(item);

    });
  }

  function showCityAQI(cityShortName, aqiData) {
    if (!citylocation[cityShortName]) return ;
    var cityLoc = citylocation[cityShortName]["point"];

    var markerContent = document.createElement("div");
    markerContent.className = "markerContentStyle";
    markerContent.style.backgroundColor = aqiTips[aqiData.level]["bgColor"];
    markerContent.innerHTML = cityShortName + aqiData.aqi;
    var marker = new AMap.Marker({
      content: markerContent,
      position: new AMap.LngLat(cityLoc.x/100000, cityLoc.y/100000)
    });
    marker.setMap(mapObj);
  }

  function loadScript(){
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "http://webapi.amap.com/maps?v=1.3&key=b1fc6abe324303d61dbccbe745be09de&callback=initMap";
    document.body.appendChild(script);
  }

}));

<|endoftext|>


<commit_before>//
// Sprinkler
//

var express = require('express');
var sockjs = require('sockjs');
var http = require('http');
var fs = require('fs');

var redis = require('redis');
var db = redis.createClient();

var Socket = require('./lib/Socket');
var utils = require('./utils');

// 1. Check for config file
var config;
if (!fs.existsSync('./config.js')) {
    // TODO start config setup
    throw new Error('Config file not found');
} else {
    config  = require('./config'); // config file
}

// 1. Get sockjs servers
//var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.3.min.js"};

var endpoints = [];

var ping = sockjs.createServer({});
ping.on('connection', function(conn) {
    conn.on('data', function(message) {
        conn.write('pong');
    });
});

// 2. Express server
var app = express();

app.use(express.urlencoded());

// New message
app.post('/message/:channel', function (req, res) {
    var key = req.get('key');
    var channel = req.params.channel;
    var endpoint = '/' + channel;

    if (!key) {
        res.json({ 'message': 'No key' }, 401);
    } else {
        // Check key
        utils.authenticate(endpoint, key).then(function() {
            // post message
            db.publish(endpoint, req.body.message);
            res.json({
                'message': req.body.message
            }, 200);
        }, function(error) {
            res.json({ 'message': 'Wrong key' }, 401);
        });
    }
    /*
  var keys = db.keys;
  if(keys.get(req.body.key)) { // check key against database
    if(db.channels.get(req.body.channel)) { // channel exists
      var event = req.body.event;
      if(!req.body.event) { // if no socket.io event specified
        event = 'message';
      }
      sockets.channel[req.body.channel].emit(event, req.body.message); // send message
      res.json('Success');
    } else {
      res.json("Channel doesn't exist, sorry!", 409);
    }
  } else {
    res.json('Wrong key', 401);
  }
  */
});

var server = http.createServer(app);

console.log(' [*] Listening on 0.0.0.0:' + config.port);
server.listen(config.port, '0.0.0.0');

// 3. Create endpoints

// special case for ping
ping.installHandlers(server, { prefix: '/ping' });

// Get all endpoints that have been setup
db.lrange('endpoints', 0, -1, function(err, list) {
    list.forEach(function(endpoint) {
        // Get auth key for endpoint
        db.hget('keys', endpoint, function(err, key) {
            var sock = new Socket(endpoint, key);
            sock.socket.installHandlers(server, { prefix: sock.prefix });
        });
    });
});

/*

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(function(err, req, res, next){
    if(err) {
      res.json({ response: 'error', message: err.toString() }, 500);
    }
  });
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

// Routes

app.get('/', routes.index);
app.post('/newchannel', routes.newchannel);
app.post('/newmessage', routes.newmessage);

sockets.run(app);

app.listen(config.port);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
*/
<commit_msg>Removed redundant code<commit_after>//
// Sprinkler
//

var express = require('express');
var sockjs = require('sockjs');
var http = require('http');
var fs = require('fs');

var redis = require('redis');
var db = redis.createClient();

var Socket = require('./lib/Socket');
var utils = require('./utils');

// 1. Check for config file
var config;
if (!fs.existsSync('./config.js')) {
    // TODO start config setup
    throw new Error('Config file not found');
} else {
    config  = require('./config'); // config file
}

// 1. Get sockjs servers
//var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.3.min.js"};

var endpoints = [];

var ping = sockjs.createServer({});
ping.on('connection', function(conn) {
    conn.on('data', function(message) {
        conn.write('pong');
    });
});

// 2. Express server
var app = express();

app.use(express.urlencoded());

// New message
app.post('/message/:channel', function (req, res) {
    var key = req.get('key');
    var channel = req.params.channel;
    var endpoint = '/' + channel;

    if (!key) {
        res.json({ 'message': 'No key' }, 401);
    } else {
        // Check key
        utils.authenticate(endpoint, key).then(function() {
            // post message
            db.publish(endpoint, req.body.message);
            res.json({
                'message': req.body.message
            }, 200);
        }, function(error) {
            res.json({ 'message': 'Wrong key' }, 401);
        });
    }
});

var server = http.createServer(app);

console.log(' [*] Listening on 0.0.0.0:' + config.port);
server.listen(config.port, '0.0.0.0');

// 3. Create endpoints

// special case for ping
ping.installHandlers(server, { prefix: '/ping' });

// Get all endpoints that have been setup
db.lrange('endpoints', 0, -1, function(err, list) {
    list.forEach(function(endpoint) {
        // Get auth key for endpoint
        db.hget('keys', endpoint, function(err, key) {
            var sock = new Socket(endpoint, key);
            sock.socket.installHandlers(server, { prefix: sock.prefix });
        });
    });
});

/*

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(function(err, req, res, next){
    if(err) {
      res.json({ response: 'error', message: err.toString() }, 500);
    }
  });
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

// Routes

app.get('/', routes.index);
app.post('/newchannel', routes.newchannel);
app.post('/newmessage', routes.newmessage);

sockets.run(app);

app.listen(config.port);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
*/
<|endoftext|>


<commit_before>var Botkit = require('botkit');
var builder = require('botbuilder');

var controller = Botkit.slackbot();
var bot = controller.spawn({
    token: process.env.token
});

var slackBot = new builder.SlackBot(controller, bot);
slackBot.add('/', function(session) {
    session.send('Hello team, another fine day in the making!');
});

slackBot.listenForMentions();

bot.startRTM(function(err, bot, payload) {
    if(err) {
        throw new Error('Could not connect to Slack!');
    }
});<commit_msg>Added command dialog to test.<commit_after>var Botkit = require('botkit');
var builder = require('botbuilder');

var controller = Botkit.slackbot();
var bot = controller.spawn({
    token: process.env.token
});

var slackBot = new builder.SlackBot(controller, bot);
var dialog = new builder.CommandDialog();

slackBot.add('/', dialog);

dialog.onDefault( function(session) {
    session.send('Hello, another fine day in the making! How may I help you?');
});

dialog.matches('status', builder.DialogAction.send('You are asking for current production status.'));

dialog.matches('performance', builder.DialogAction.send('You are asking for station performance.'));

dialog.matches('schedule', builder.DialogAction.send('You are asking for on-time schedule.'));

slackBot.listenForMentions();

bot.startRTM( function(err, bot, payload) {
    if(err) {
        throw new Error('Could not connect to Slack!');
    }
});<|endoftext|>


<commit_before>'use strict';

var hoursOfOperation = ['6:00 AM', '7:00 AM', '8:00 AM', '9:00 AM', '10:00 AM', '11:00 AM', '12:00 PM', '1:00 PM', '2:00 PM', '3:00 PM', '4:00 PM', '5:00 PM', '6:00 PM', '7:00 PM'];

function CookieShop(shopLoc, minCust, maxCust, avgCookiePerCust){
  this.shopLoc = shopLoc;
  this.minCust = minCust;
  this.maxCust = maxCust;
  this.avgCookiePerCust = avgCookiePerCust;
  this.totalCustEachHour = [];
  this.totalCookiesPerHour = [];
  this.totalStaffPerHour = [];
}

CookieShop.prototype.randomCust = function() {
  for( var i = 14; i > 0; i--) {
    this.totalCustEachHour.push ((Math.floor (Math.random() * (this.maxCust - this.minCust + 1))) + this.minCust);
  }
};

CookieShop.prototype.cookiesPerHour = function() {
  for( var i = 0; i < this.totalCustEachHour.length; i++) {
    this.totalCookiesPerHour.push (Math.floor (this.totalCustEachHour[i] * this.avgCookiePerCust));
    this.totalStaffPerHour.push (Math.ceil (this.totalCookiesPerHour[i]/20));
  }
};

CookieShop.prototype.salesReportTableRows = function() {
  var newEl = document.createElement('tr');
  newEl.id = this.shopLoc + ' row';
  var position = document.getElementById('salesReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  var newText = document.createTextNode(this.shopLoc);
  newEl.appendChild(newText);
  position = document.getElementById(this.shopLoc + ' row');
  position.appendChild(newEl);

  var total = 0;
  for( var i in this.totalCookiesPerHour) {
    total += this.totalCookiesPerHour[i];
  }

  this.totalCookiesPerHour.push(total);

  for (i = 0; i <= hoursOfOperation.length; i++){
    newEl = document.createElement('td');
    // newEl.id = 'countMe '+ i;
    newText = document.createTextNode(this.totalCookiesPerHour[i]);
    newEl.appendChild(newText);
    position = document.getElementById(this.shopLoc + ' row');
    position.appendChild(newEl);
  }

  CookieShop.prototype.staffReportTableRows = function() {
    var newEl = document.createElement('tr');
    newEl.id = this.shopLoc + ' row Staff';
    var position = document.getElementById('staffReportTable');
    position.appendChild(newEl);

    newEl = document.createElement('th');
    var newText = document.createTextNode(this.shopLoc);
    newEl.appendChild(newText);
    position = document.getElementById(this.shopLoc + ' row Staff');
    position.appendChild(newEl);

    var total = 0;
    for( var i in this.totalStaffPerHour) {
      total += this.totalStaffPerHour[i];
    }

    this.totalStaffPerHour.push(total);

    for (i = 0; i <= hoursOfOperation.length; i++){
      newEl = document.createElement('td');
      // newEl.id = 'countMe '+ i;
      newText = document.createTextNode(this.totalStaffPerHour[i]);
      newEl.appendChild(newText);
      position = document.getElementById(this.shopLoc + ' row Staff');
      position.appendChild(newEl);
    }
  };
};

var cookieShopFirstPike = new CookieShop('First and Pike', 23, 65, 6.3);
var cookieShopSeatacAirport = new CookieShop('Seatac Airport', 3, 24, 1.2);
var cookieShopSeattleCenter = new CookieShop('Seattle Center', 11, 38, 3.7);
var cookieShopCapitolHill = new CookieShop('Capitol Hill', 20, 38, 3.2);
var cookieShopAlki = new CookieShop('Alki', 2, 16, 4.6);

var cookieShops = [cookieShopFirstPike, cookieShopSeatacAirport, cookieShopSeattleCenter, cookieShopCapitolHill, cookieShopAlki];

for(var i = 0; i < cookieShops.length; i++) {
  cookieShops[i].randomCust();
  cookieShops[i].cookiesPerHour();
}
console.log(cookieShops);

function salesReportTableHead (){
  var newEl = document.createElement('table');
  newEl.id = 'salesReportTable';
  var position = document.getElementById('bodySales');
  position.appendChild(newEl);

  newEl = document.createElement('thead');
  newEl.id = 'colHeaders';
  position = document.getElementById('salesReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('tr');
  newEl.id = 'colHeadersRow';
  position = document.getElementById('colHeaders');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  position = document.getElementById('colHeadersRow');
  position.appendChild(newEl);

  for (var i = 0; i < hoursOfOperation.length; i++){
    newEl = document.createElement('th');
    var newText = document.createTextNode(hoursOfOperation[i]);
    newEl.appendChild(newText);
    position = document.getElementById('colHeadersRow');
    position.appendChild(newEl);
  }

  newEl = document.createElement('th');
  newText = document.createTextNode('Daily Location Total');
  newEl.appendChild(newText);
  position = document.getElementById('colHeadersRow');
  position.appendChild(newEl);
}

var cookieTotalsPerHourAllShops = [0,0,0,0,0,0,0,0,0,0,0,0,0,0];

for(i = 0; i < hoursOfOperation.length; i++){
  cookieTotalsPerHourAllShops[i] = cookieTotalsPerHourAllShops[i] + cookieShops[0].totalCookiesPerHour[i]+ cookieShops[1].totalCookiesPerHour[i] + cookieShops[2].totalCookiesPerHour[i] + cookieShops[3].totalCookiesPerHour[i] + cookieShops[4].totalCookiesPerHour[i];
}

var total = 0;
for( i in cookieTotalsPerHourAllShops) {
  total += cookieTotalsPerHourAllShops[i];
}

cookieTotalsPerHourAllShops.push(total);

console.log(cookieTotalsPerHourAllShops);

function salesReportTableFoot (){
  var newEl = document.createElement('tfoot');
  newEl.id = 'colTotals';
  var position = document.getElementById('salesReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('tr');
  newEl.id = 'colTotalsRow';
  position = document.getElementById('colTotals');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  var newText = document.createTextNode('Totals:');
  newEl.appendChild(newText);
  position = document.getElementById('colTotalsRow');
  position.appendChild(newEl);

  for (var i = 0; i <= hoursOfOperation.length; i++){
    newEl = document.createElement('td');
    newText = document.createTextNode(cookieTotalsPerHourAllShops[i]);
    newEl.appendChild(newText);
    position = document.getElementById('colTotalsRow');
    position.appendChild(newEl);
  }
}

//Stretch Goal: Second Table for staff needs.

function staffReportTableHead (){
  var newEl = document.createElement('table');
  newEl.id = 'staffReportTable';
  var position = document.getElementById('bodySales');
  position.appendChild(newEl);

  newEl = document.createElement('thead');
  newEl.id = 'colHeadersStaff';
  position = document.getElementById('staffReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('tr');
  newEl.id = 'colHeadersRowStaff';
  position = document.getElementById('colHeadersStaff');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  position = document.getElementById('colHeadersRowStaff');
  position.appendChild(newEl);

  for (var i = 0; i < hoursOfOperation.length; i++){
    newEl = document.createElement('th');
    var newText = document.createTextNode(hoursOfOperation[i]);
    newEl.appendChild(newText);
    position = document.getElementById('colHeadersRowStaff');
    position.appendChild(newEl);
  }

  newEl = document.createElement('th');
  newText = document.createTextNode('Total Staff Hours');
  newEl.appendChild(newText);
  position = document.getElementById('colHeadersRowStaff');
  position.appendChild(newEl);
}

function staffReportTableFoot (){
  var newEl = document.createElement('tfoot');
  newEl.id = 'colTotalsStaff';
  var position = document.getElementById('staffReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('tr');
  newEl.id = 'colTotalsRowStaff';
  position = document.getElementById('colTotalsStaff');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  var newText = document.createTextNode('Totals:');
  newEl.appendChild(newText);
  position = document.getElementById('colTotalsRowStaff');
  position.appendChild(newEl);

  for (var i = 0; i <= hoursOfOperation.length; i++){
    newEl = document.createElement('td');
    newText = document.createTextNode(cookieTotalsPerHourAllShops[i]);
    newEl.appendChild(newText);
    position = document.getElementById('colTotalsRowStaff');
    position.appendChild(newEl);
  }
}
salesReportTableHead(cookieShops);

for(i = 0; i < cookieShops.length; i++){
  cookieShops[i].salesReportTableRows();
}

salesReportTableFoot();

staffReportTableHead();

for(i = 0; i < cookieShops.length; i++){
  cookieShops[i].staffReportTableRows();
}

staffReportTableFoot();
<commit_msg>stretch goal staff hour table functioning for all rows and totals<commit_after>'use strict';

var hoursOfOperation = ['6:00 AM', '7:00 AM', '8:00 AM', '9:00 AM', '10:00 AM', '11:00 AM', '12:00 PM', '1:00 PM', '2:00 PM', '3:00 PM', '4:00 PM', '5:00 PM', '6:00 PM', '7:00 PM'];

function CookieShop(shopLoc, minCust, maxCust, avgCookiePerCust){
  this.shopLoc = shopLoc;
  this.minCust = minCust;
  this.maxCust = maxCust;
  this.avgCookiePerCust = avgCookiePerCust;
  this.totalCustEachHour = [];
  this.totalCookiesPerHour = [];
  this.totalStaffPerHour = [];
}

CookieShop.prototype.randomCust = function() {
  for( var i = 14; i > 0; i--) {
    this.totalCustEachHour.push ((Math.floor (Math.random() * (this.maxCust - this.minCust + 1))) + this.minCust);
  }
};

CookieShop.prototype.cookiesPerHour = function() {
  for( var i = 0; i < this.totalCustEachHour.length; i++) {
    this.totalCookiesPerHour.push (Math.floor (this.totalCustEachHour[i] * this.avgCookiePerCust));
    this.totalStaffPerHour.push (Math.ceil (this.totalCookiesPerHour[i]/20));
  }
};

CookieShop.prototype.salesReportTableRows = function() {
  var newEl = document.createElement('tr');
  newEl.id = this.shopLoc + ' row';
  var position = document.getElementById('salesReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  var newText = document.createTextNode(this.shopLoc);
  newEl.appendChild(newText);
  position = document.getElementById(this.shopLoc + ' row');
  position.appendChild(newEl);

  var total = 0;
  for( var i in this.totalCookiesPerHour) {
    total += this.totalCookiesPerHour[i];
  }

  this.totalCookiesPerHour.push(total);

  for (i = 0; i <= hoursOfOperation.length; i++){
    newEl = document.createElement('td');
    // newEl.id = 'countMe '+ i;
    newText = document.createTextNode(this.totalCookiesPerHour[i]);
    newEl.appendChild(newText);
    position = document.getElementById(this.shopLoc + ' row');
    position.appendChild(newEl);
  }

  CookieShop.prototype.staffReportTableRows = function() {
    var newEl = document.createElement('tr');
    newEl.id = this.shopLoc + ' row Staff';
    var position = document.getElementById('staffReportTable');
    position.appendChild(newEl);

    newEl = document.createElement('th');
    var newText = document.createTextNode(this.shopLoc);
    newEl.appendChild(newText);
    position = document.getElementById(this.shopLoc + ' row Staff');
    position.appendChild(newEl);

    var total = 0;
    for( var i in this.totalStaffPerHour) {
      total += this.totalStaffPerHour[i];
    }

    this.totalStaffPerHour.push(total);

    for (i = 0; i <= hoursOfOperation.length; i++){
      newEl = document.createElement('td');
      // newEl.id = 'countMe '+ i;
      newText = document.createTextNode(this.totalStaffPerHour[i]);
      newEl.appendChild(newText);
      position = document.getElementById(this.shopLoc + ' row Staff');
      position.appendChild(newEl);
    }
  };
};

var cookieShopFirstPike = new CookieShop('First and Pike', 23, 65, 6.3);
var cookieShopSeatacAirport = new CookieShop('Seatac Airport', 3, 24, 1.2);
var cookieShopSeattleCenter = new CookieShop('Seattle Center', 11, 38, 3.7);
var cookieShopCapitolHill = new CookieShop('Capitol Hill', 20, 38, 3.2);
var cookieShopAlki = new CookieShop('Alki', 2, 16, 4.6);

var cookieShops = [cookieShopFirstPike, cookieShopSeatacAirport, cookieShopSeattleCenter, cookieShopCapitolHill, cookieShopAlki];

for(var i = 0; i < cookieShops.length; i++) {
  cookieShops[i].randomCust();
  cookieShops[i].cookiesPerHour();
}
console.log(cookieShops);

function salesReportTableHead (){
  var newEl = document.createElement('table');
  newEl.id = 'salesReportTable';
  var position = document.getElementById('bodySales');
  position.appendChild(newEl);

  newEl = document.createElement('thead');
  newEl.id = 'colHeaders';
  position = document.getElementById('salesReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('tr');
  newEl.id = 'colHeadersRow';
  position = document.getElementById('colHeaders');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  var newText = document.createTextNode('Daily Sales Report');
  newEl.appendChild(newText);
  position = document.getElementById('colHeadersRow');
  position.appendChild(newEl);

  for (var i = 0; i < hoursOfOperation.length; i++){
    newEl = document.createElement('th');
    newText = document.createTextNode(hoursOfOperation[i]);
    newEl.appendChild(newText);
    position = document.getElementById('colHeadersRow');
    position.appendChild(newEl);
  }

  newEl = document.createElement('th');
  newText = document.createTextNode('Daily Location Total');
  newEl.appendChild(newText);
  position = document.getElementById('colHeadersRow');
  position.appendChild(newEl);
}

var cookieTotalsPerHourAllShops = [0,0,0,0,0,0,0,0,0,0,0,0,0,0];

for(i = 0; i < hoursOfOperation.length; i++){
  cookieTotalsPerHourAllShops[i] = cookieTotalsPerHourAllShops[i] + cookieShops[0].totalCookiesPerHour[i]+ cookieShops[1].totalCookiesPerHour[i] + cookieShops[2].totalCookiesPerHour[i] + cookieShops[3].totalCookiesPerHour[i] + cookieShops[4].totalCookiesPerHour[i];
}

var total = 0;
for( i in cookieTotalsPerHourAllShops) {
  total += cookieTotalsPerHourAllShops[i];
}

cookieTotalsPerHourAllShops.push(total);

console.log(cookieTotalsPerHourAllShops);

function salesReportTableFoot (){
  var newEl = document.createElement('tfoot');
  newEl.id = 'colTotals';
  var position = document.getElementById('salesReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('tr');
  newEl.id = 'colTotalsRow';
  position = document.getElementById('colTotals');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  var newText = document.createTextNode('Totals:');
  newEl.appendChild(newText);
  position = document.getElementById('colTotalsRow');
  position.appendChild(newEl);

  for (var i = 0; i <= hoursOfOperation.length; i++){
    newEl = document.createElement('td');
    newText = document.createTextNode(cookieTotalsPerHourAllShops[i]);
    newEl.appendChild(newText);
    position = document.getElementById('colTotalsRow');
    position.appendChild(newEl);
  }
}

//Stretch Goal: Second Table for staff needs.

function staffReportTableHead (){
  var newEl = document.createElement('table');
  newEl.id = 'staffReportTable';
  var position = document.getElementById('bodySales');
  position.appendChild(newEl);

  newEl = document.createElement('thead');
  newEl.id = 'colHeadersStaff';
  position = document.getElementById('staffReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('tr');
  newEl.id = 'colHeadersRowStaff';
  position = document.getElementById('colHeadersStaff');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  var newText = document.createTextNode('Daily Staff Report');
  newEl.appendChild(newText);
  position = document.getElementById('colHeadersRowStaff');
  position.appendChild(newEl);

  for (var i = 0; i < hoursOfOperation.length; i++){
    newEl = document.createElement('th');
    newText = document.createTextNode(hoursOfOperation[i]);
    newEl.appendChild(newText);
    position = document.getElementById('colHeadersRowStaff');
    position.appendChild(newEl);
  }

  newEl = document.createElement('th');
  newText = document.createTextNode('Total Staff Hours');
  newEl.appendChild(newText);
  position = document.getElementById('colHeadersRowStaff');
  position.appendChild(newEl);
}

var staffTotalsPerHourAllShops = [0,0,0,0,0,0,0,0,0,0,0,0,0,0];

for(i = 0; i < hoursOfOperation.length; i++){
  staffTotalsPerHourAllShops[i] = staffTotalsPerHourAllShops[i] + cookieShops[0].totalStaffPerHour[i]+ cookieShops[1].totalStaffPerHour[i] + cookieShops[2].totalStaffPerHour[i] + cookieShops[3].totalStaffPerHour[i] + cookieShops[4].totalStaffPerHour[i];
}

total = 0;
for( i in staffTotalsPerHourAllShops) {
  total += staffTotalsPerHourAllShops[i];
}

staffTotalsPerHourAllShops.push(total);

console.log(staffTotalsPerHourAllShops);

function staffReportTableFoot (){
  var newEl = document.createElement('tfoot');
  newEl.id = 'colTotalsStaff';
  var position = document.getElementById('staffReportTable');
  position.appendChild(newEl);

  newEl = document.createElement('tr');
  newEl.id = 'colTotalsRowStaff';
  position = document.getElementById('colTotalsStaff');
  position.appendChild(newEl);

  newEl = document.createElement('th');
  var newText = document.createTextNode('Totals:');
  newEl.appendChild(newText);
  position = document.getElementById('colTotalsRowStaff');
  position.appendChild(newEl);

  for (var i = 0; i <= hoursOfOperation.length; i++){
    newEl = document.createElement('td');
    newText = document.createTextNode(staffTotalsPerHourAllShops[i]);
    newEl.appendChild(newText);
    position = document.getElementById('colTotalsRowStaff');
    position.appendChild(newEl);
  }
}
salesReportTableHead(cookieShops);

for(i = 0; i < cookieShops.length; i++){
  cookieShops[i].salesReportTableRows();
}

salesReportTableFoot();

staffReportTableHead();

for(i = 0; i < cookieShops.length; i++){
  cookieShops[i].staffReportTableRows();
}

staffReportTableFoot();
<|endoftext|>


<commit_before>var _         = require('underscore');
var async     = require('async');
var AWS       = require('aws-sdk');
var config    = require('config');
var express   = require('express');
var Firebase  = require('firebase');
var fs        = require('fs');
var http      = require('http');
var httpget   = require('http-get')
var kue       = require('kue');
var mkdirp    = require('mkdirp');
var moment    = require('moment');
var path      = require('path');
var PebbleSdk = require('./pebble-sdk');
var redis     = require('redis');
var request   = require('request');
var rimraf    = require('rimraf');
var stathat   = require('stathat');
var url       = require('url');
var uuid      = require('node-uuid');

var APP_NAME_REGEX = new RegExp("[A-Za-z0-9\ ]");

var FirebaseDb = new Firebase(config.firebase.url);
FirebaseDb.auth(config.firebase.authToken);

AWS.config.loadFromPath(config.aws.configFile);
var s3 = new AWS.S3();

var PebbleSdkVersions = [ '1.12' ];
var PebbleSdks = {};
_.each(PebbleSdkVersions, function (version) {
  var sdk = new PebbleSdk(version);
  if (sdk.ok) {
    PebbleSdks[version] =sdk;
  }
  else {
    console.log('SDK v' + version + ' is not OK');
  }
});

// Kue Code

var workerQueue = kue.createQueue();
kue.app.listen(8001);

workerQueue.process('download', function (job, done) {
  var id = job.data.id;

  updateBuildState(id, 'working');
  addBuildTimingEntry(id, 'download started');
  downloadBuildFiles(id, function (err) {
    if (err) {
      console.log('Download failed [' + id + ']');
      recordStatCount('download failures');
      updateBuildState(id, 'error');
      setBuildError(id, err);
      done(err);
      workerQueue.create('cleanup', job.data).save();
      return;
    }
    updateBuildState(id, 'done');
    addBuildTimingEntry(id, 'download finished');
    done();

    workerQueue.create('compile', job.data).save();
    updateBuildStep(id, 'compile');
    updateBuildState(id, 'queued');
  });
});

workerQueue.process('compile', function (job, done) {
  var id = job.data.id;

  updateBuildState(id, 'working');
  addBuildTimingEntry(id, 'compile started');

  compileBuild(id, function (err) {
    if (err) {
      console.log('Compile failed [' + id + ']');
      recordStatCount('compile failures');
      updateBuildState(id, 'error');
      setBuildError(id, err);
      done(err);
      workerQueue.create('cleanup', job.data).save();
      return;
    }
    updateBuildState(id, 'done');
    addBuildTimingEntry(id, 'compile finished');
    done();

    workerQueue.create('upload', job.data).save();
    updateBuildStep(id, 'upload');
    updateBuildState(id, 'queued');
  });
});

workerQueue.process('upload', function (job, done) {
  var id = job.data.id;

  updateBuildState(id, 'working');
  addBuildTimingEntry(id, 'upload started');

  uploadBuild(id, function (err) {
    if (err) {
      console.log('Upload failed [' + id + ']');
      recordStatCount('upload failures');
      updateBuildState(id, 'error');
      setBuildError(id, err);
      done(err);
      workerQueue.create('cleanup', job.data).save();
      return;
    }
    done();
    updateBuildState(id, 'done');
    addBuildTimingEntry(id, 'upload finished');

    workerQueue.create('tidy', job.data).save();
    updateBuildStep(id, 'tidy');
    updateBuildState(id, 'queued');
  });
});

workerQueue.process('tidy', function (job, done) {
  var id = job.data.id;

  updateBuildState(id, 'working');
  addBuildTimingEntry(id, 'tidy started');

  tidyBuild(id, function (err) {
    if (err) {
      console.log('Tidy failed [' + id + ']');
      // Disabled due to limited number of StatHat stats. //
      //recordStatCount('tidy failures');
      updateBuildState(id, 'error');
      setBuildError(id, err);
      return done(err);
    }
    done();
    updateBuildState(id, 'done');
    addBuildTimingEntry(id, 'tidy finished');
    addBuildTimingEntry(id, 'done');

    recordTimingStats(id);
  });
});

workerQueue.process('cleanup', function (job, done) {
  var id = job.data.id;
  cleanFailedBuild(id, function (err) {
    if (err) {
      console.log('Clean failed [' + id + ']');
      // Disabled due to limited number of StatHat stats. //
      //recordStatCount('cleanup failures');
      return done(err);
    }
    done();
  })
});

// End Kue Code

// Express Code

var app = express();

app.set('port', config.express.port);
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);

app.get('/', function (req, res) {
  res.redirect('http://builder.pblweb.com/');
});

app.post('/build/', function (req, res) {
  createNewBuild(req.body, function (err, id) {
    if (err) {
      return res.json(400, { error: err });
    }
    return res.json(200, { id: id });
  });
});

app.get('/status/', function (req, res) {
  getBuildInfo(req.query.id, function (err, info) {
    return res.json({ step: info.step, state: info.state });
  });
});

http.createServer(app).listen(app.get('port'), function () {});

// End Express Code

function createNewBuild(info, callback) {
  var infoProblem = isValidBuildInfo(info);
  if (infoProblem !== null) {
    return callback(infoProblem);
  }
  var id = generateBuildId();
  fs.mkdir(path.join(config.misc.buildFolder, id), function (err) {
    if (err) {
      return callback('Unknown error occurred.');
    }
    info.step = 'download';
    info.state = 'queued';
    saveBuildInfo(id, info);
    addBuildTimingEntry(id, 'created');
    workerQueue.create('download', {
      id: id,
      title: id
    }).save();
    recordStatCount('builds');
    return callback(null, id);
  });
}

function isValidBuildInfo(info) {
  // Validate SDK version.
  if (! info.sdkVersion) {
    return 'Missing "sdkVersion".';
  }
  if (! _.has(PebbleSdks, info.sdkVersion)) {
    return 'Unknown sdkVersion "' + info.sdkVersion + '".';
  }
  // Validate list of files.
  if (! info.files) {
    return 'Missing "files".';
  }
  if (info.files.length < 2) {
    return 'Not enough files.';
  }
  // TODO: Make sure files are not malicious!
  if (! _.every(info.files, function (file) {
    try {
      // Validate the URL part of the file.
      var urlObj = url.parse(file.url);
      if (! urlObj) {
        return false;
      }
      if (urlObj.protocol !== 'http:' && urlObj.protocol !== 'https:') {
        return false;
      }
      // Validate the file part of the file.
      var filePath = path.normalize(file.path);
      if (! filePath.length) {
        return false;
      }
      if (filePath.substr(0, 1) === '.') {
        return false;
      }
    }
    catch (e) {
      return false;
    }
    return true;
  })) {
    return 'Bad list of files.';
  }
  // Validate user token.
  if (! info.userToken) {
    return 'Missing "userToken".';
  }
  if (info.userToken !== 'P7S1bAKN24Tnq3pE') {
    return 'Invalid userToken "' + userToken + '".';
  }
  // Validate app name.
  if (! info.appName || ! info.appName.length) {
    return 'Missing "appName".';
  }
  if (! APP_NAME_REGEX.test(info.appName)) {
    return 'Invalid appName "' + info.appName + '"';
  }
  return null;
}

function generateBuildId() {
  return uuid.v4();
}

function downloadBuildFiles(id, callback) {
  getBuildInfo(id, function (err, build) {
    async.each(build.files, function (filePair, callback) {
      var filePath = filePair.path;
      if (filePath.substr(0, 1) === '/') {
        filePath = filePath.substr(1);
      }
      var fileUrl = filePair.url;
      var folder = path.dirname(filePath);
      mkdirp(path.join(config.misc.buildFolder, id, folder), function (err) {
        if (err) {
          return callback(err);
        }
        var file = path.join(config.misc.buildFolder, id, filePath);
        httpget.head(fileUrl, function (err, res) {
          if (err) {
            return callback(err);
          }
          var overrideSizeCheck = false;
          if (fileUrl.substr(0, 24) === 'https://gist.github.com/' || fileUrl.substr(0, 23) === 'http://gist.github.com/') {
            overrideSizeCheck = true;
          }
          if (! overrideSizeCheck && ! res.headers['content-length']) {
            return callback(new Error('Unknown file size for "' + fileUrl + '".'));
          }
          if (parseInt(res.headers['content-length']) > config.misc.maxDownloadSize) {
            return callback(new Error('File too large for "' + fileUrl + '".'));
          }
          httpget.get(fileUrl, file, function (err, res) {
            return callback(err);
          })
        })
      });
    }, callback);
  })
}

function compileBuild(id, callback) {
  getBuildInfo(id, function (err, build) {
    var folder = path.join(config.misc.buildFolder, id);
    var sdk = PebbleSdks[build.sdkVersion];
    if (! sdk) {
      return callback(new Error('Unknown SDK "' + build.sdkVersion + '"'));
    }

    sdk.initApp(folder, function (res) {
      if (res.code !== 0) {
        return callback(res.stderr);
      }
      sdk.configureApp(folder, function (res) {
        if (res.code !== 0) {
          return callback(res.stderr);
        }
        sdk.buildApp(folder, function (res) {
          if (res.code !== 0) {
            return callback(res.stderr);
          }
          return callback();
        })
      })
    })
  })
}

function uploadBuild(id, callback) {
  getBuildInfo(id, function (err, build) {
    var folder = path.join(config.misc.buildFolder, id);

    var buildPath = path.join(folder, 'build', id + '.pbw');
    fs.exists(buildPath, function (exists) {
      if (! exists) {
        err = new Error('Build file does not exist.');
        return callback(err);
      }

      fs.readFile(buildPath, function (err, buildData) {
        if (err) {
          return callback(err);
        }
        var s3File = {
          Bucket: 'builder.pblweb.com',
          Key: [ id, 'build.pbw' ].join('/'),
          ACL:'public-read',
          Body: buildData
        };
        s3.client.putObject(s3File, callback);
      });
    });
  });
}

function tidyBuild(id, callback) {
  var folder = path.join(config.misc.buildFolder, id);
  rimraf(folder, function (err) {
    callback(err);
  });
}

function cleanFailedBuild(id, callback) {
  var folder = path.join(config.misc.buildFolder, id);
  rimraf(folder, function (err) {
    callback(err);
  });
}

function recordStatCount(stat, count) {
  if (typeof count === 'undefined') {
    count = 1;
  }
  var statName = [ config.stathat.prefix, stat ].join(' ');
  if (! config.stathat.enabled) {
    console.log('Fake StatHat Count:', statName, count);
    return;
  }
  stathat.trackEZCount(config.stathat.email, statName, count, function (status, json) {
    if (status !== 200) {
      console.log('StatHat failed (' + status + ')');
    }
  });
}

function recordStatValue(stat, value) {
  if (typeof value === 'undefined') {
    value = 1;
  }
  var statName = [ config.stathat.prefix, stat ].join(' ');
  if (! config.stathat.enabled) {
    console.log('Fake StatHat Count:', statName, value);
    return;
  }
  stathat.trackEZValue(config.stathat.email, statName, value, function (status, json) {
    if (status !== 200) {
      console.log('StatHat failed (' + status + ')');
    }
  });
}

function recordTimingStats(id) {
  getBuildInfo(id, function (err, build) {
    var downloadTime = build.timings['download finished'] - build.timings['download started'];
    var compileTime = build.timings['compile finished'] - build.timings['compile started'];
    var uploadTime = build.timings['upload finished'] - build.timings['upload started'];
    var tidyTime = build.timings['tidy finished'] - build.timings['tidy started'];

    var queueDownload = build.timings['download started'] - build.timings['created'];
    var queueCompile = build.timings['compile started'] - build.timings['download finished'];
    var queueUpload = build.timings['upload started'] - build.timings['compile finished'];
    var queueTidy = build.timings['tidy started'] - build.timings['upload finished'];

    var queueTotal = queueDownload + queueCompile + queueUpload + queueTidy;
    var totalTime = build.timings['done'] - build.timings['created'];

    recordStatValue('download time', downloadTime / 1000);
    recordStatValue('compile time', compileTime / 1000);
    recordStatValue('upload time', uploadTime / 1000);
    recordStatValue('queue time', queueTotal / 1000);
    recordStatValue('total time', totalTime / 1000);
  });
}

function saveBuildInfo(id, info) {
  var buildRef = FirebaseDb.child(id);
  buildRef.set(info);
}

function getBuildInfo(id, callback) {
  var buildRef = FirebaseDb.child(id);
  buildRef.once('value', function (snapshot) {
    return callback(null, snapshot.val());
  });
}

function updateBuildStep(id, step) {
  var buildRef = FirebaseDb.child(id);
  buildRef.child('step').set(step);
}

function updateBuildState(id, state) {
  var buildRef = FirebaseDb.child(id);
  buildRef.child('state').set(state);
}

function setBuildError(id, error) {
  var buildRef = FirebaseDb.child(id);
  buildRef.child('error').set(error);
}

function addBuildTimingEntry(id, name) {
  var buildRef = FirebaseDb.child(id);
  buildRef.child('timings').child(name).set(moment().valueOf());
}<commit_msg>Use config for Kue port.<commit_after>var _         = require('underscore');
var async     = require('async');
var AWS       = require('aws-sdk');
var config    = require('config');
var express   = require('express');
var Firebase  = require('firebase');
var fs        = require('fs');
var http      = require('http');
var httpget   = require('http-get')
var kue       = require('kue');
var mkdirp    = require('mkdirp');
var moment    = require('moment');
var path      = require('path');
var PebbleSdk = require('./pebble-sdk');
var redis     = require('redis');
var request   = require('request');
var rimraf    = require('rimraf');
var stathat   = require('stathat');
var url       = require('url');
var uuid      = require('node-uuid');

var APP_NAME_REGEX = new RegExp("[A-Za-z0-9\ ]");

var FirebaseDb = new Firebase(config.firebase.url);
FirebaseDb.auth(config.firebase.authToken);

AWS.config.loadFromPath(config.aws.configFile);
var s3 = new AWS.S3();

var PebbleSdkVersions = [ '1.12' ];
var PebbleSdks = {};
_.each(PebbleSdkVersions, function (version) {
  var sdk = new PebbleSdk(version);
  if (sdk.ok) {
    PebbleSdks[version] =sdk;
  }
  else {
    console.log('SDK v' + version + ' is not OK');
  }
});

// Kue Code

var workerQueue = kue.createQueue();
kue.app.listen(config.kue.port);

workerQueue.process('download', function (job, done) {
  var id = job.data.id;

  updateBuildState(id, 'working');
  addBuildTimingEntry(id, 'download started');
  downloadBuildFiles(id, function (err) {
    if (err) {
      console.log('Download failed [' + id + ']');
      recordStatCount('download failures');
      updateBuildState(id, 'error');
      setBuildError(id, err);
      done(err);
      workerQueue.create('cleanup', job.data).save();
      return;
    }
    updateBuildState(id, 'done');
    addBuildTimingEntry(id, 'download finished');
    done();

    workerQueue.create('compile', job.data).save();
    updateBuildStep(id, 'compile');
    updateBuildState(id, 'queued');
  });
});

workerQueue.process('compile', function (job, done) {
  var id = job.data.id;

  updateBuildState(id, 'working');
  addBuildTimingEntry(id, 'compile started');

  compileBuild(id, function (err) {
    if (err) {
      console.log('Compile failed [' + id + ']');
      recordStatCount('compile failures');
      updateBuildState(id, 'error');
      setBuildError(id, err);
      done(err);
      workerQueue.create('cleanup', job.data).save();
      return;
    }
    updateBuildState(id, 'done');
    addBuildTimingEntry(id, 'compile finished');
    done();

    workerQueue.create('upload', job.data).save();
    updateBuildStep(id, 'upload');
    updateBuildState(id, 'queued');
  });
});

workerQueue.process('upload', function (job, done) {
  var id = job.data.id;

  updateBuildState(id, 'working');
  addBuildTimingEntry(id, 'upload started');

  uploadBuild(id, function (err) {
    if (err) {
      console.log('Upload failed [' + id + ']');
      recordStatCount('upload failures');
      updateBuildState(id, 'error');
      setBuildError(id, err);
      done(err);
      workerQueue.create('cleanup', job.data).save();
      return;
    }
    done();
    updateBuildState(id, 'done');
    addBuildTimingEntry(id, 'upload finished');

    workerQueue.create('tidy', job.data).save();
    updateBuildStep(id, 'tidy');
    updateBuildState(id, 'queued');
  });
});

workerQueue.process('tidy', function (job, done) {
  var id = job.data.id;

  updateBuildState(id, 'working');
  addBuildTimingEntry(id, 'tidy started');

  tidyBuild(id, function (err) {
    if (err) {
      console.log('Tidy failed [' + id + ']');
      // Disabled due to limited number of StatHat stats. //
      //recordStatCount('tidy failures');
      updateBuildState(id, 'error');
      setBuildError(id, err);
      return done(err);
    }
    done();
    updateBuildState(id, 'done');
    addBuildTimingEntry(id, 'tidy finished');
    addBuildTimingEntry(id, 'done');

    recordTimingStats(id);
  });
});

workerQueue.process('cleanup', function (job, done) {
  var id = job.data.id;
  cleanFailedBuild(id, function (err) {
    if (err) {
      console.log('Clean failed [' + id + ']');
      // Disabled due to limited number of StatHat stats. //
      //recordStatCount('cleanup failures');
      return done(err);
    }
    done();
  })
});

// End Kue Code

// Express Code

var app = express();

app.set('port', config.express.port);
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);

app.get('/', function (req, res) {
  res.redirect('http://builder.pblweb.com/');
});

app.post('/build/', function (req, res) {
  createNewBuild(req.body, function (err, id) {
    if (err) {
      return res.json(400, { error: err });
    }
    return res.json(200, { id: id });
  });
});

app.get('/status/', function (req, res) {
  getBuildInfo(req.query.id, function (err, info) {
    return res.json({ step: info.step, state: info.state });
  });
});

http.createServer(app).listen(app.get('port'), function () {});

// End Express Code

function createNewBuild(info, callback) {
  var infoProblem = isValidBuildInfo(info);
  if (infoProblem !== null) {
    return callback(infoProblem);
  }
  var id = generateBuildId();
  fs.mkdir(path.join(config.misc.buildFolder, id), function (err) {
    if (err) {
      return callback('Unknown error occurred.');
    }
    info.step = 'download';
    info.state = 'queued';
    saveBuildInfo(id, info);
    addBuildTimingEntry(id, 'created');
    workerQueue.create('download', {
      id: id,
      title: id
    }).save();
    recordStatCount('builds');
    return callback(null, id);
  });
}

function isValidBuildInfo(info) {
  // Validate SDK version.
  if (! info.sdkVersion) {
    return 'Missing "sdkVersion".';
  }
  if (! _.has(PebbleSdks, info.sdkVersion)) {
    return 'Unknown sdkVersion "' + info.sdkVersion + '".';
  }
  // Validate list of files.
  if (! info.files) {
    return 'Missing "files".';
  }
  if (info.files.length < 2) {
    return 'Not enough files.';
  }
  // TODO: Make sure files are not malicious!
  if (! _.every(info.files, function (file) {
    try {
      // Validate the URL part of the file.
      var urlObj = url.parse(file.url);
      if (! urlObj) {
        return false;
      }
      if (urlObj.protocol !== 'http:' && urlObj.protocol !== 'https:') {
        return false;
      }
      // Validate the file part of the file.
      var filePath = path.normalize(file.path);
      if (! filePath.length) {
        return false;
      }
      if (filePath.substr(0, 1) === '.') {
        return false;
      }
    }
    catch (e) {
      return false;
    }
    return true;
  })) {
    return 'Bad list of files.';
  }
  // Validate user token.
  if (! info.userToken) {
    return 'Missing "userToken".';
  }
  if (info.userToken !== 'P7S1bAKN24Tnq3pE') {
    return 'Invalid userToken "' + userToken + '".';
  }
  // Validate app name.
  if (! info.appName || ! info.appName.length) {
    return 'Missing "appName".';
  }
  if (! APP_NAME_REGEX.test(info.appName)) {
    return 'Invalid appName "' + info.appName + '"';
  }
  return null;
}

function generateBuildId() {
  return uuid.v4();
}

function downloadBuildFiles(id, callback) {
  getBuildInfo(id, function (err, build) {
    async.each(build.files, function (filePair, callback) {
      var filePath = filePair.path;
      if (filePath.substr(0, 1) === '/') {
        filePath = filePath.substr(1);
      }
      var fileUrl = filePair.url;
      var folder = path.dirname(filePath);
      mkdirp(path.join(config.misc.buildFolder, id, folder), function (err) {
        if (err) {
          return callback(err);
        }
        var file = path.join(config.misc.buildFolder, id, filePath);
        httpget.head(fileUrl, function (err, res) {
          if (err) {
            return callback(err);
          }
          var overrideSizeCheck = false;
          if (fileUrl.substr(0, 24) === 'https://gist.github.com/' || fileUrl.substr(0, 23) === 'http://gist.github.com/') {
            overrideSizeCheck = true;
          }
          if (! overrideSizeCheck && ! res.headers['content-length']) {
            return callback(new Error('Unknown file size for "' + fileUrl + '".'));
          }
          if (parseInt(res.headers['content-length']) > config.misc.maxDownloadSize) {
            return callback(new Error('File too large for "' + fileUrl + '".'));
          }
          httpget.get(fileUrl, file, function (err, res) {
            return callback(err);
          })
        })
      });
    }, callback);
  })
}

function compileBuild(id, callback) {
  getBuildInfo(id, function (err, build) {
    var folder = path.join(config.misc.buildFolder, id);
    var sdk = PebbleSdks[build.sdkVersion];
    if (! sdk) {
      return callback(new Error('Unknown SDK "' + build.sdkVersion + '"'));
    }

    sdk.initApp(folder, function (res) {
      if (res.code !== 0) {
        return callback(res.stderr);
      }
      sdk.configureApp(folder, function (res) {
        if (res.code !== 0) {
          return callback(res.stderr);
        }
        sdk.buildApp(folder, function (res) {
          if (res.code !== 0) {
            return callback(res.stderr);
          }
          return callback();
        })
      })
    })
  })
}

function uploadBuild(id, callback) {
  getBuildInfo(id, function (err, build) {
    var folder = path.join(config.misc.buildFolder, id);

    var buildPath = path.join(folder, 'build', id + '.pbw');
    fs.exists(buildPath, function (exists) {
      if (! exists) {
        err = new Error('Build file does not exist.');
        return callback(err);
      }

      fs.readFile(buildPath, function (err, buildData) {
        if (err) {
          return callback(err);
        }
        var s3File = {
          Bucket: 'builder.pblweb.com',
          Key: [ id, 'build.pbw' ].join('/'),
          ACL:'public-read',
          Body: buildData
        };
        s3.client.putObject(s3File, callback);
      });
    });
  });
}

function tidyBuild(id, callback) {
  var folder = path.join(config.misc.buildFolder, id);
  rimraf(folder, function (err) {
    callback(err);
  });
}

function cleanFailedBuild(id, callback) {
  var folder = path.join(config.misc.buildFolder, id);
  rimraf(folder, function (err) {
    callback(err);
  });
}

function recordStatCount(stat, count) {
  if (typeof count === 'undefined') {
    count = 1;
  }
  var statName = [ config.stathat.prefix, stat ].join(' ');
  if (! config.stathat.enabled) {
    console.log('Fake StatHat Count:', statName, count);
    return;
  }
  stathat.trackEZCount(config.stathat.email, statName, count, function (status, json) {
    if (status !== 200) {
      console.log('StatHat failed (' + status + ')');
    }
  });
}

function recordStatValue(stat, value) {
  if (typeof value === 'undefined') {
    value = 1;
  }
  var statName = [ config.stathat.prefix, stat ].join(' ');
  if (! config.stathat.enabled) {
    console.log('Fake StatHat Count:', statName, value);
    return;
  }
  stathat.trackEZValue(config.stathat.email, statName, value, function (status, json) {
    if (status !== 200) {
      console.log('StatHat failed (' + status + ')');
    }
  });
}

function recordTimingStats(id) {
  getBuildInfo(id, function (err, build) {
    var downloadTime = build.timings['download finished'] - build.timings['download started'];
    var compileTime = build.timings['compile finished'] - build.timings['compile started'];
    var uploadTime = build.timings['upload finished'] - build.timings['upload started'];
    var tidyTime = build.timings['tidy finished'] - build.timings['tidy started'];

    var queueDownload = build.timings['download started'] - build.timings['created'];
    var queueCompile = build.timings['compile started'] - build.timings['download finished'];
    var queueUpload = build.timings['upload started'] - build.timings['compile finished'];
    var queueTidy = build.timings['tidy started'] - build.timings['upload finished'];

    var queueTotal = queueDownload + queueCompile + queueUpload + queueTidy;
    var totalTime = build.timings['done'] - build.timings['created'];

    recordStatValue('download time', downloadTime / 1000);
    recordStatValue('compile time', compileTime / 1000);
    recordStatValue('upload time', uploadTime / 1000);
    recordStatValue('queue time', queueTotal / 1000);
    recordStatValue('total time', totalTime / 1000);
  });
}

function saveBuildInfo(id, info) {
  var buildRef = FirebaseDb.child(id);
  buildRef.set(info);
}

function getBuildInfo(id, callback) {
  var buildRef = FirebaseDb.child(id);
  buildRef.once('value', function (snapshot) {
    return callback(null, snapshot.val());
  });
}

function updateBuildStep(id, step) {
  var buildRef = FirebaseDb.child(id);
  buildRef.child('step').set(step);
}

function updateBuildState(id, state) {
  var buildRef = FirebaseDb.child(id);
  buildRef.child('state').set(state);
}

function setBuildError(id, error) {
  var buildRef = FirebaseDb.child(id);
  buildRef.child('error').set(error);
}

function addBuildTimingEntry(id, name) {
  var buildRef = FirebaseDb.child(id);
  buildRef.child('timings').child(name).set(moment().valueOf());
}<|endoftext|>


<commit_before>// Source: https://gist.github.com/nicothin/1ba505f7cdfbe969600afcad6d9f1d33

'use strict';

const fs = require('fs');
const mkdirp = require('mkdirp');

let blockName = process.argv[2];
let extensions = [];

extensions = uniqueArray(extensions.concat(process.argv.slice(3)));

// Путь к папке с модулями
let basePath = 'source/modules/';

// Шаблоны
let templates = [
		{
			type: 'necessary',
			ext: 'pug',
			tpl: 'mixin {blockName}(data)\n\t.{blockName}&attributes(attributes)\n\t\t\n'
		},
		{
			type: 'necessary',
			ext: 'styl',
			tpl: '.{blockName}\n\t//\n'
		},
		{
			type: 'optional',
			ext: 'js',
			tpl: '// // {blockName}\n// (function($, window, document, undefined) {\n// \t\'use strict\';\n\n// \t// Your code here\n\n// })(jQuery, window, document);\n'
		},
		{
			type: 'optional',
			ext: 'yml',
			path: 'data',
			tpl: '---\n  {blockName}:\n    default:\n      \n'
		}
	];

// Если есть имя блока
if (blockName) {

	let dirPath = basePath + blockName + '/'; // полный путь к создаваемой папке блока

	// создаем
	mkdirp(dirPath, function(err) {

		// Если какая-то ошибка — покажем
		if (err) {
			console.error('Отмена операции: ' + err);
		}

		// Нет ошибки, поехали!
		else {
			console.log('Создание папки ' + dirPath + ' (создана, если ещё не существует)');

			// Обходим массив расширений и создаем файлы, если они еще не созданы
			templates.forEach(function(template) {
				let filePath = dirPath + blockName + '.' + template.ext;
				let fileContent = template.tpl.replace(/{blockName}/g, blockName);
				let fileCreateMsg = '';

				if (typeof template.path !== 'undefined') {
					if (extensions.indexOf(template.ext) >= 0) {
						mkdirp(dirPath + template.path);
						filePath = dirPath + template.path + '/' + blockName + '.' + template.ext;
					}
				}

				if (template.type !== 'optional') {
					writeFile(filePath, fileContent, fileCreateMsg);
				}
				else {
					if (extensions.indexOf(template.ext) >= 0) {
						writeFile(filePath, fileContent, fileCreateMsg);
					}
				}

			});
		}
	});
} else {
	console.log('Отмена операции: не указан блок');
}

// Оставить в массиве только уникальные значения (убрать повторы)
function uniqueArray(arr) {
	var objectTemp = {};
	for (var i = 0; i < arr.length; i++) {
		var str = arr[i];
		objectTemp[str] = true; // запомнить строку в виде свойства объекта
	}
	return Object.keys(objectTemp);
}

// Проверка существования файла
function fileExist(path) {
	const fs = require('fs');
	try {
		fs.statSync(path);
	} catch (err) {
		return !(err && err.code === 'ENOENT');
	}
};

function writeFile(filePath, fileContent, fileCreateMsg) {
	if (fileExist(filePath) === false) {
		fs.writeFile(filePath, fileContent, function(err) {
			if (err) {
				return console.log('Файл НЕ создан: ' + err);
			}
			console.log('Файл создан: ' + filePath);
			if (fileCreateMsg) {
				console.warn(fileCreateMsg);
			}
		});
	} else {
		console.log('Файл НЕ создан: ' + filePath + ' (уже существует)');
	}
};
<commit_msg>Update add module script<commit_after>// Source: https://gist.github.com/nicothin/1ba505f7cdfbe969600afcad6d9f1d33

'use strict';

const fs = require('fs');
const mkdirp = require('mkdirp');

let blockName = process.argv[2];
let extensions = [];

extensions = uniqueArray(extensions.concat(process.argv.slice(3)));

// Путь к папке с модулями
let basePath = 'source/modules/';

// Шаблоны
let templates = [
		{
			type: 'necessary',
			ext: 'pug',
			tpl: 'mixin {blockName}(data)\n\t.{blockName}&attributes(attributes)\n\t\t\n'
		},
		{
			type: 'necessary',
			ext: 'styl',
			tpl: '.{blockName}\n\t//\n'
		},
		{
			type: 'optional',
			ext: 'js',
			tpl: '// // {blockName}\n// (function() {\n\n// \t// Your code here\n\n// })();\n'
		},
		{
			type: 'optional',
			ext: 'yml',
			path: 'data',
			tpl: '---\n  {blockName}:\n    default:\n      \n'
		}
	];

// Если есть имя блока
if (blockName) {

	let dirPath = basePath + blockName + '/'; // полный путь к создаваемой папке блока

	// создаем
	mkdirp(dirPath, function(err) {

		// Если какая-то ошибка — покажем
		if (err) {
			console.error('Отмена операции: ' + err);
		}

		// Нет ошибки, поехали!
		else {
			console.log('Создание папки ' + dirPath + ' (создана, если ещё не существует)');

			// Обходим массив расширений и создаем файлы, если они еще не созданы
			templates.forEach(function(template) {
				let filePath = dirPath + blockName + '.' + template.ext;
				let fileContent = template.tpl.replace(/{blockName}/g, blockName);
				let fileCreateMsg = '';

				if (typeof template.path !== 'undefined') {
					if (extensions.indexOf(template.ext) >= 0) {
						mkdirp(dirPath + template.path);
						filePath = dirPath + template.path + '/' + blockName + '.' + template.ext;
					}
				}

				if (template.type !== 'optional') {
					writeFile(filePath, fileContent, fileCreateMsg);
				}
				else {
					if (extensions.indexOf(template.ext) >= 0) {
						writeFile(filePath, fileContent, fileCreateMsg);
					}
				}

			});
		}
	});
} else {
	console.log('Отмена операции: не указан блок');
}

// Оставить в массиве только уникальные значения (убрать повторы)
function uniqueArray(arr) {
	var objectTemp = {};
	for (var i = 0; i < arr.length; i++) {
		var str = arr[i];
		objectTemp[str] = true; // запомнить строку в виде свойства объекта
	}
	return Object.keys(objectTemp);
}

// Проверка существования файла
function fileExist(path) {
	const fs = require('fs');
	try {
		fs.statSync(path);
	} catch (err) {
		return !(err && err.code === 'ENOENT');
	}
};

function writeFile(filePath, fileContent, fileCreateMsg) {
	if (fileExist(filePath) === false) {
		fs.writeFile(filePath, fileContent, function(err) {
			if (err) {
				return console.log('Файл НЕ создан: ' + err);
			}
			console.log('Файл создан: ' + filePath);
			if (fileCreateMsg) {
				console.warn(fileCreateMsg);
			}
		});
	} else {
		console.log('Файл НЕ создан: ' + filePath + ' (уже существует)');
	}
};
<|endoftext|>


<commit_before>/* globals require console */
"use strict";

const config = require("./config");

let data = require("./data")(config.connectionString["development"]);

const app = require("./config/application")({ data });

require("./routers")({ app, data });

app.listen(config.port, () => console.log(`Cooking Web App running at :${config.port}`));<commit_msg>Testing Heroku<commit_after>/* globals require console */
"use strict";

const config = require("./config");

let data = require("./data")(config.connectionString["production"]);

const app = require("./config/application")({ data });

require("./routers")({ app, data });

app.listen(config.port, () => console.log(`Cooking Web App running at :${config.port}`));<|endoftext|>


<commit_before>var _ = require('underscore');
var ninjaBlocks = require('ninja-blocks');
var vars = require('./vars.js');
var moment = require('moment');
var exec = require('child_process').exec;
var nodemailer = require('nodemailer');

var USER_ACCESS_TOKEN = vars.userAccessToken;
var PYNEST_COMMAND = vars.pynest_command;
var EMAIL_TRANSPORT = vars.email_transport;
var EMAIL_SERVICE = vars.email_service;
var EMAIL_USER = vars.email_user;
var EMAIL_PASS = vars.email_pass;

var transport = nodemailer.createTransport(EMAIL_TRANSPORT, {
  service: EMAIL_SERVICE,
  auth: {
    user: EMAIL_USER,
    pass: EMAIL_PASS
  }
});

var ninja = ninjaBlocks.app({user_access_token:USER_ACCESS_TOKEN});

// temps get converted to Fahrenheit to compare

var MAX_TIME_DELTA = 180;
var GUID_1 = '0101';
var START_TIME = 22; // 2200 11PM or later
var END_TIME = 6; // 5AM or earlier
var LOW_LIMIT_HEAT = 68; // 68
var HIGH_LIMIT_HEAT = 72; // 72
var HIGH_LIMIT_AC = 73; // 76

// Get the most recent temperature reading from all temperature sensors
// then analyze and get a single one
ninja.devices({ device_type: 'temperature' }, function(err, devices) {
  _.each(devices, function(device,guid){
    ninja.device(guid).last_heartbeat(function(err, data) {
      if ( data.G === GUID_1) {
        var timestamp = new Date().getTime();
        var timeDelta = (timestamp - data.timestamp) / 1000;
        if (timeDelta < MAX_TIME_DELTA) {
          console.log(device.shortName+' is '+data.DA+'C');
          var temp_f = (data.DA * (9/5)) + 32;
          console.log('');
          console.log('temp in F is: '+temp_f+'F');

          //
          // 68F min 72F max
          //
          // 11PM start 6AM end
          //
          var now = moment();
          var hour = now.hours();
          console.log(hour);
          if (hour > START_TIME || hour < END_TIME) {
            if (temp_f < LOW_LIMIT_HEAT) {
              // switch to heat
              // check temp and raise by 1 degree
              var child = exec(PYNEST_COMMAND+'mode heat', function(error, stdout, stderr){
                if (error !== null) {
                  console.log('exec error: '+error);
                }
                console.log('set mode to heat');
                // curtarget is the temperature the nest is currently set to
                var child = exec(PYNEST_COMMAND+'curtarget', function(error, stdout, stderr){
                  if (error !== null) {
                    console.log('exec error: '+error);
                  }
                  var current_temp_nest = Math.round(stdout);
                  var new_temp_nest = current_temp_nest + 1;
                  console.log('current temp nest: '+current_temp_nest);
                  console.log('new temp nest: '+new_temp_nest);
                  var child = exec(PYNEST_COMMAND+'temp '+new_temp_nest, function(error, stdout, stderr){
                    if (error !== null) {
                      console.log('exec error: '+error);
                    }
                    var mailOptions = {
                      from: EMAIL_USER,
                      to: EMAIL_USER,
                      subject: "Node ninjablocks temp update",
                      text: 'Ninjablocks temp: '+temp_f+'\nSet Mode to Heat\ncurrent temp nest: '+current_temp_nest+'\nnew temp nest: '+new_temp_nest
                    };
                    transport.sendMail(mailOptions, function(error, response){
                      if(error) {
                        console.log(error);
                      } else {
                        console.log('email sent');
                      }
                    }); //end of transport mail

                  });
                });
              });
            // this block of code never gets called, need to investigate
            } else if(temp_f > HIGH_LIMIT_HEAT && temp_f <= HIGH_LIMIT_AC) {
              // check mode, if heat lower by 1 degree
              var child = exec(PYNEST_COMMAND+'curmode', function(error, stdout, stderr){
                if (error !== null) {
                  console.log('exec error: '+error);
                }
                if (stdout == 'heat'){
                  console.log('current mode is heat');
                  var child = exec(PYNEST_COMMAND+'curtarget', function(error, stdout, stderr){
                    if (error !== null) {
                      console.log('exec error: '+error);
                    }
                    var current_temp_nest = Math.round(stdout);
                    var new_temp_nest = current_temp_nest - 1;
                    console.log('current temp nest: '+current_temp_nest);
                    console.log('new temp nest: '+new_temp_nest);
                    var child = exec(PYNEST_COMMAND+'temp '+new_temp_nest, function(error, stdout, stderr){
                      if (error !== null) {
                        console.log('exec error: '+error);
                      }
                      var mailOptions = {
                        from: EMAIL_USER,
                        to: EMAIL_USER,
                        subject: "Node ninjablocks temp update",
                        text: 'Ninjablocks temp: '+temp_f+'\nCurrent mode is heat\ncurrent temp nest: '+current_temp_nest+'\nnew temp nest: '+new_temp_nest
                      };
                      transport.sendMail(mailOptions, function(error, response){
                        if(error) {
                          console.log(error);
                        } else {
                          console.log('email sent');
                        }
                      }); //end of transport mail
                    });
                  });
                }
              });

            } else if (temp_f > HIGH_LIMIT_AC) {
              // switch to air conditioning
              //var child = exec(PYNEST_COMMAND+'mode cool', function(error, stdout, stderr){
              //  if (error !== null) {
              //    console.log('exec error: '+error);
              //  }
                console.log('switched to air conditioning');
                console.log('disabled');
                var child = exec(PYNEST_COMMAND+'curtarget', function(error, stdout, stderr){
                  if (error !== null) {
                    console.log('exec error: '+error);
                  }
                  var current_temp_nest = Math.round(stdout);
                  var new_temp_nest = current_temp_nest - 1;
                  console.log('current temp nest: '+current_temp_nest);
                  console.log('new temp nest: '+new_temp_nest);
                  var child = exec(PYNEST_COMMAND+'temp '+new_temp_nest, function(error, stdout, stderr){
                    if (error !== null) {
                      console.log('exec error: '+error);
                    }
                    var child = exec(PYNEST_COMMAND+'fan on', function(error, stdout, stderr){
                      if (error !== null) {
                        console.log('exec error: '+error);
                      }
                      var mailOptions = {
                        from: EMAIL_USER,
                        to: EMAIL_USER,
                        subject: "Node ninjablocks temp update",
                        text: 'Ninjablocks temp: '+temp_f+'\nSet Mode to AC\ndisabled\ncurrent temp nest: '+current_temp_nest+'\nnew temp nest: '+new_temp_nest+'\nset fan to on'
                      };
                      transport.sendMail(mailOptions, function(error, response){
                        if(error) {
                          console.log(error);
                        } else {
                          console.log('email sent');
                        }
                      }); //end of transport mail
                    });
                  });
                });
              //});

            } else {
              var child = exec(PYNEST_COMMAND+'fan auto', function(error, stdout, stderr){
                if (error !== null) {
                  console.log('exec error: '+error);
                }
              });

            }
            // here
          } else {
            var child = exec(PYNEST_COMMAND+'fan auto', function(error, stdout, stderr){
              if (error !== null) {
                console.log('exec error: '+error);
              }
            });

          }
        } else {
          console.log("hasn't checked in in over "+MAX_TIME_DELTA+" seconds");
        }
      }
    })
  })
});
<commit_msg>removed fan on<commit_after>var _ = require('underscore');
var ninjaBlocks = require('ninja-blocks');
var vars = require('./vars.js');
var moment = require('moment');
var exec = require('child_process').exec;
var nodemailer = require('nodemailer');

var USER_ACCESS_TOKEN = vars.userAccessToken;
var PYNEST_COMMAND = vars.pynest_command;
var EMAIL_TRANSPORT = vars.email_transport;
var EMAIL_SERVICE = vars.email_service;
var EMAIL_USER = vars.email_user;
var EMAIL_PASS = vars.email_pass;

var transport = nodemailer.createTransport(EMAIL_TRANSPORT, {
  service: EMAIL_SERVICE,
  auth: {
    user: EMAIL_USER,
    pass: EMAIL_PASS
  }
});

var ninja = ninjaBlocks.app({user_access_token:USER_ACCESS_TOKEN});

// temps get converted to Fahrenheit to compare

var MAX_TIME_DELTA = 180;
var GUID_1 = '0101';
var START_TIME = 22; // 2200 (greater than 10PM), 11PM or later
var END_TIME = 6; // less than 6AM, 5AM or earlier
var LOW_LIMIT_HEAT = 68; // 68
var HIGH_LIMIT_HEAT = 72; // 72
var HIGH_LIMIT_AC = 73; // 76

// Get the most recent temperature reading from all temperature sensors
// then analyze and get a single one
ninja.devices({ device_type: 'temperature' }, function(err, devices) {
  _.each(devices, function(device,guid){
    ninja.device(guid).last_heartbeat(function(err, data) {
      if ( data.G === GUID_1) {
        var timestamp = new Date().getTime();
        var timeDelta = (timestamp - data.timestamp) / 1000;
        if (timeDelta < MAX_TIME_DELTA) {
          console.log(device.shortName+' is '+data.DA+'C');
          var temp_f = (data.DA * (9/5)) + 32;
          console.log('');
          console.log('temp in F is: '+temp_f+'F');

          //
          // 68F min 72F max
          //
          // 11PM start 6AM end
          //
          var now = moment();
          var hour = now.hours();
          console.log(hour);
          if (hour > START_TIME || hour < END_TIME) {
            if (temp_f < LOW_LIMIT_HEAT) {
              // switch to heat
              // check temp and raise by 1 degree
              var child = exec(PYNEST_COMMAND+'mode heat', function(error, stdout, stderr){
                if (error !== null) {
                  console.log('exec error: '+error);
                }
                console.log('set mode to heat');
                // curtarget is the temperature the nest is currently set to
                var child = exec(PYNEST_COMMAND+'curtarget', function(error, stdout, stderr){
                  if (error !== null) {
                    console.log('exec error: '+error);
                  }
                  var current_temp_nest = Math.round(stdout);
                  var new_temp_nest = current_temp_nest + 1;
                  console.log('current temp nest: '+current_temp_nest);
                  console.log('new temp nest: '+new_temp_nest);
                  var child = exec(PYNEST_COMMAND+'temp '+new_temp_nest, function(error, stdout, stderr){
                    if (error !== null) {
                      console.log('exec error: '+error);
                    }
                    var mailOptions = {
                      from: EMAIL_USER,
                      to: EMAIL_USER,
                      subject: "Node ninjablocks temp update",
                      text: 'Ninjablocks temp: '+temp_f+'\nSet Mode to Heat\ncurrent temp nest: '+current_temp_nest+'\nnew temp nest: '+new_temp_nest
                    };
                    transport.sendMail(mailOptions, function(error, response){
                      if(error) {
                        console.log(error);
                      } else {
                        console.log('email sent');
                      }
                    }); //end of transport mail

                  });
                });
              });
            // this block of code never gets called, need to investigate
            } else if(temp_f > HIGH_LIMIT_HEAT && temp_f <= HIGH_LIMIT_AC) {
              // check mode, if heat lower by 1 degree
              var child = exec(PYNEST_COMMAND+'curmode', function(error, stdout, stderr){
                if (error !== null) {
                  console.log('exec error: '+error);
                }
                if (stdout == 'heat'){
                  console.log('current mode is heat');
                  var child = exec(PYNEST_COMMAND+'curtarget', function(error, stdout, stderr){
                    if (error !== null) {
                      console.log('exec error: '+error);
                    }
                    var current_temp_nest = Math.round(stdout);
                    var new_temp_nest = current_temp_nest - 1;
                    console.log('current temp nest: '+current_temp_nest);
                    console.log('new temp nest: '+new_temp_nest);
                    var child = exec(PYNEST_COMMAND+'temp '+new_temp_nest, function(error, stdout, stderr){
                      if (error !== null) {
                        console.log('exec error: '+error);
                      }
                      var mailOptions = {
                        from: EMAIL_USER,
                        to: EMAIL_USER,
                        subject: "Node ninjablocks temp update",
                        text: 'Ninjablocks temp: '+temp_f+'\nCurrent mode is heat\ncurrent temp nest: '+current_temp_nest+'\nnew temp nest: '+new_temp_nest
                      };
                      transport.sendMail(mailOptions, function(error, response){
                        if(error) {
                          console.log(error);
                        } else {
                          console.log('email sent');
                        }
                      }); //end of transport mail
                    });
                  });
                }
              });

            } else if (temp_f > HIGH_LIMIT_AC) {
              // switch to air conditioning
              //var child = exec(PYNEST_COMMAND+'mode cool', function(error, stdout, stderr){
              //  if (error !== null) {
              //    console.log('exec error: '+error);
              //  }
                console.log('switched to air conditioning');
                console.log('disabled');
                var child = exec(PYNEST_COMMAND+'curtarget', function(error, stdout, stderr){
                  if (error !== null) {
                    console.log('exec error: '+error);
                  }
                  var current_temp_nest = Math.round(stdout);
                  var new_temp_nest = current_temp_nest - 1;
                  console.log('current temp nest: '+current_temp_nest);
                  console.log('new temp nest: '+new_temp_nest);
                  var child = exec(PYNEST_COMMAND+'temp '+new_temp_nest, function(error, stdout, stderr){
                    if (error !== null) {
                      console.log('exec error: '+error);
                    }
                    var mailOptions = {
                      from: EMAIL_USER,
                      to: EMAIL_USER,
                      subject: "Node ninjablocks temp update",
                      text: 'Ninjablocks temp: '+temp_f+'\nSet Mode to AC\ndisabled\ncurrent temp nest: '+current_temp_nest+'\nnew temp nest: '+new_temp_nest+'\nset fan to on'
                    };
                    transport.sendMail(mailOptions, function(error, response){
                      if(error) {
                        console.log(error);
                      } else {
                        console.log('email sent');
                      }
                    }); //end of transport mail
                  });
                });
              //});

            }
            // here
          }
        } else {
          console.log("hasn't checked in in over "+MAX_TIME_DELTA+" seconds");
        }
      }
    })
  })
});
<|endoftext|>