<commit_before>(function() {
  // "use strict";
  chart.$inject = [ "$http", "$q" ];
  function chart($http, $q) {
    var obj = {
      "foo": 1,
      "bar": 2
    },
    executeNames = ["Symbicort", "Aggrenox"],
    uniqueNames = {},
    jeezy = [],
    jeezy2 = [];
    var uniqueFilter = function(ref) {
      var o = ref, i, l = ref.length, r = [];
      for(i=0; i<l;i++) o[this[i]] = this[i];
      for(i in o) r.push(o[i]);
      return r;
    };
    // for (var key in obj) {
    //   console.log(obj[key]);
    // }
    var populateData = function(ref){
      var o = ref, i, l=ref.length, r = [];
      for(i=0; i<l; i++)
      {
        drugName = ref[i].toString();
        xIteration = "x"+i.toString();
        var url = "https://api.fda.gov/drug/event.json?search=patient.drug.openfda.brand_name:" + drugName + "&count=patient.reaction.reactionmeddrapt.exact";
        $http.get(url)
        .success(function(data) {
          console.log(data);
          jeezy.push(drugName);
          jeezy2.push(xIteration);
          var gw = data.results;
          for (var key in gw) {
            jeezy.push(gw[key].term);
            jeezy2.push(gw[key].count);
            uniqueNames[gw[key].term];
            uniqueNames[gw[key].term] = gw[key].term;
          }
          console.log(jeezy);
          console.log(jeezy2);
          console.log(uniqueFilter(uniqueNames));
        })
      }
    }
    populateData(executeNames);
  }
  angular.module("myApp")
  .controller("chart", chart)
}());

//
//   function chart ($http) {
//     var
//     u ={},
//     a = [],
//     effectsName = [],
//     effectsCount = [],
//     rxcui = [ "1191", "3521" ];
//
//
//
//
//
//
//
//     var getdata = function(rxcui) {
//       for (var i = 0; i < rxcui.length; i++) {
//         var url = "https://api.fda.gov/drug/event.json?search=patient.drug.openfda.rxcui." + rxcui[i] + "&count=patient.reaction.reactionmeddrapt.exact";
//         $http.get(url)
//         .success(function(data) {
//           console.log(data);
//           for (var j = 0; j <= data.results.length; j++) {
//             processEffects(data.results[j], j, data.results.length, i, rxcui.length);
//             if (!u.hasOwnProperty(effectsName[j])) {
//               a.push(effectsName[j]);
//               u[effectsName[j]] = 1;
//             }
//           }
//           return a;
//         })
//         .error(function(err) {
//           console.log(err);
//         });
//       }
//     }
//     // var unique = function(arr) {
//     //   var u = {}, a = [];
//     //   for(var i = 0, l = arr.length; i < l; ++i){
//     //     if(!u.hasOwnProperty(arr[i])) {
//     //       a.push(arr[i]);
//     //       u[arr[i]] = 1;
//     //     }
//     //   }
//     //   return a;
//     //   }
//     // }
//     var dataName = function(effectsName) {
//       for (var i = 0; i < effectsName.length; i++) {
//
//       }
//     }
//     var processEffects = function(effect, iterate, limit, ver, vertotal) {
//
//         } else if (iterate === limit && ver === vertotal) {
//           for (var l = 0; l < effectsCountHolder.length; l++) {
//             effectsCount.push(effectsCountHolder[l]);
//             console.log("effects count holder");
//             console.log(effectsCountHolder);
//             console.log(effectsCount);
//           }
//
//         } else {
//           effectsName.push(effect.term);
//           effectsCountHolder[rxcui[i]].push(effect.count);
//         }
//       }
//     }
//     var chart = c3.generate({
//       data: {
//         json: {
//           ASPIRIN: [450, 0, 50, 40, 60, 50],
//           data2: [200, 130, 90, 240, 130, 220],
//           data3: [300, 200, 160, 400, 250, 250]
//         }
//       },
//       zoom: true,
//       axis: {
//         x: {
//           type: "category",
//           categories: a,
//           tick: {
//             rotate: 75,
//             multiline: false
//           },
//           height: 130
//         }
//       }
//     });
//     getdata(rxcui);
//   }
//   angular.module("myApp")
//   .controller  ("chart", chart)
// }());
<commit_msg>refactor<commit_after>(function() {
  // "use strict";
  chart.$inject = [ "$http", "$q" ];
  function chart($http, $q) {
    var obj = {
      "foo": 1,
      "bar": 2
    },
    executeNames = ["Symbicort", "Aggrenox"],
    uniqueNames = {},
    tempData = {},
    jeezy = [],
    jeezy2 = [];
    var uniqueFilter = function(ref) {
      var o = ref, i, l = ref.length, r = [];
      for(i=0; i<l;i++) o[this[i]] = this[i];
      for(i in o) r.push(o[i]);
      return r;
    };
    var populateData = function(ref){
      var o = ref, i, l=ref.length, r = [];
      for(i=0; i<l; i++)
      {
        drugName = ref[i].toString();
        xIteration = "x"+i.toString();
        jeezy.push(drugName);
        jeezy2.push(xIteration);
        var url = "https://api.fda.gov/drug/event.json?search=patient.drug.openfda.brand_name:" + drugName + "&count=patient.reaction.reactionmeddrapt.exact";
        $http.get(url)
        .success(function(data) {
          console.log(data);
          var gw = data.results;
          for (var key in gw) {
            jeezy.push(gw[key].term);
            jeezy2.push(gw[key].count);
            uniqueNames[gw[key].term] = gw[key].term;
          }
          console.log(jeezy);
          console.log(jeezy2);
          console.log(uniqueFilter(uniqueNames));
        })
      }
    }
    populateData(executeNames);
  }
  angular.module("myApp")
  .controller("chart", chart)
}());

//
//   function chart ($http) {
//     var
//     u ={},
//     a = [],
//     effectsName = [],
//     effectsCount = [],
//     rxcui = [ "1191", "3521" ];
//
//
//
//
//
//
//
//     var getdata = function(rxcui) {
//       for (var i = 0; i < rxcui.length; i++) {
//         var url = "https://api.fda.gov/drug/event.json?search=patient.drug.openfda.rxcui." + rxcui[i] + "&count=patient.reaction.reactionmeddrapt.exact";
//         $http.get(url)
//         .success(function(data) {
//           console.log(data);
//           for (var j = 0; j <= data.results.length; j++) {
//             processEffects(data.results[j], j, data.results.length, i, rxcui.length);
//             if (!u.hasOwnProperty(effectsName[j])) {
//               a.push(effectsName[j]);
//               u[effectsName[j]] = 1;
//             }
//           }
//           return a;
//         })
//         .error(function(err) {
//           console.log(err);
//         });
//       }
//     }
//     // var unique = function(arr) {
//     //   var u = {}, a = [];
//     //   for(var i = 0, l = arr.length; i < l; ++i){
//     //     if(!u.hasOwnProperty(arr[i])) {
//     //       a.push(arr[i]);
//     //       u[arr[i]] = 1;
//     //     }
//     //   }
//     //   return a;
//     //   }
//     // }
//     var dataName = function(effectsName) {
//       for (var i = 0; i < effectsName.length; i++) {
//
//       }
//     }
//     var processEffects = function(effect, iterate, limit, ver, vertotal) {
//
//         } else if (iterate === limit && ver === vertotal) {
//           for (var l = 0; l < effectsCountHolder.length; l++) {
//             effectsCount.push(effectsCountHolder[l]);
//             console.log("effects count holder");
//             console.log(effectsCountHolder);
//             console.log(effectsCount);
//           }
//
//         } else {
//           effectsName.push(effect.term);
//           effectsCountHolder[rxcui[i]].push(effect.count);
//         }
//       }
//     }
//     var chart = c3.generate({
//       data: {
//         json: {
//           ASPIRIN: [450, 0, 50, 40, 60, 50],
//           data2: [200, 130, 90, 240, 130, 220],
//           data3: [300, 200, 160, 400, 250, 250]
//         }
//       },
//       zoom: true,
//       axis: {
//         x: {
//           type: "category",
//           categories: a,
//           tick: {
//             rotate: 75,
//             multiline: false
//           },
//           height: 130
//         }
//       }
//     });
//     getdata(rxcui);
//   }
//   angular.module("myApp")
//   .controller  ("chart", chart)
// }());
<|endoftext|>


<commit_before>/**
 * 负责请求知乎日报 API，并返回结果。
 */

var _ = require("lodash");
var config = require("config");
var cheerio = require("cheerio");
var querystring = require("querystring");
var imageRequest = require("request");
var dailyRequest = require("request").defaults({
    baseUrl : config.zhihu_daily_api
});

var utils = require("./utils");
const PREFIX = "/api/4/imgs/";

/**
 * 获取最新知乎日报 ID 列表。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchLatestStoryIDs = function (p_callback)
{
    if (!_.isFunction(p_callback)) return;

    dailyRequest.get({ url: "/news/latest", json: true }, function (err, res, body)
    {
        if (!err && res.statusCode == 200)
        {
            // 因知乎日报的 API 返回的图片太小，这里直接丢弃，后面再通过其他途径获取图片。
            p_callback(null, {
                date: body.date,
                ids: body.stories.map(function (value)
                {
                    return value.id;
                })
            });
        }
        else
        {
            p_callback(new Error("request Zhihu-Daily API ('/news/latest') error."));
        }
    });
};

/**
 * 获取最新热门知乎日报 ID 列表。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchTopStoryIDs = function (p_callback)
{
    dailyRequest.get({ url: "/news/latest", json: true }, function (err, res, body)
    {
        if (!err && res.statusCode == 200)
        {
            var ids = body.top_stories.map(function (value)
            {
                return {
                    id: value.id,
                    title: value.title,
                    image: PREFIX + querystring.escape(value.image)
                };
            });
            p_callback(null, {
                date: body.date,
                ids: ids
            });
        }
        else
        {
            p_callback(new Error("request Zhihu-Daily API ('/news/latest') error."));
        }
    });
};

/**
 * 获取指定日期的知乎日报 ID 列表。
 * @param {String} p_date 日期。如果小于"20130519"，返回值 res 为 {}。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchStoryIDs = function (p_date, p_callback)
{
    if (!_.isFunction(p_callback)) return;

    // 因知乎日报 API 返回的是指定日期的前一天的日报，
    // 所以要加一天才能获取指定日期的日报。
    var date = utils.nextZhihuDay(p_date);
    if (date)
    {
        if (utils.convertZhihuDateToMoment(date).isBefore(utils.MIN_DATE))
        {
            // "20130519"之前是没有知乎日报的。
            p_callback(null, {});
        }
        else
        {
            dailyRequest.get({ url: "/news/before/" + date, json: true }, function (err, res, body)
            {
                if (!err && res.statusCode == 200)
                {
                    p_callback(null, {
                        date: body.date,
                        ids: body.stories.map(function (value)
                        {
                            return value.id;
                        })
                    });
                }
                else
                {
                    p_callback(new Error("request Zhihu-Daily API ('/news/before/:date') error."));
                }
            });
        }
    }
    else
    {
        p_callback(new Error("p_date has a wrong format."));
    }
};

/**
 * 获取指定 ID 的知乎日报。
 * @param {String} p_id ID。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchStory = function (p_id, p_callback)
{
    if (!_.isFunction(p_callback)) return;

    // 检查 ID 是否为纯数字。
    if (/^\d+$/.test(p_id))
    {
        dailyRequest.get({ url: "/news/" + p_id, json: true }, function (err, res, body)
        {
            if (!err && res.statusCode == 200)
            {
                var images = [];
                var story = {};
                story.id = body.id;
                story.title = body.title;

                images.push(body.image);
                story.image = PREFIX + querystring.escape(body.image);

                story.imageSource = body.image_source;
                story.shareURL = body.share_url;

                if (body.body)
                {
                    var $ = cheerio.load(body.body, { decodeEntities: false });
                    story.backgrounds = $(".headline>.headline-background .headline-background-link").map(function (i, e)
                    {
                        return {
                            href: $(e).attr("href"),
                            title : $(e).children(".heading").text(),
                            text : $(e).children(".heading-content").text()
                        };
                    }).get();

                    story.contents = $(".content-inner>.question").map(function (i, e)
                    {
                        var question = {};
                        question.title = $(e).children(".question-title").text();
                        question.answers = $(e).children(".answer").map(function (i, e)
                        {
                            $(e).find(".content img").each(function (i, e)
                            {
                                var src = $(e).attr("src");
                                if (!_.isEmpty(src))
                                {
                                    images.push(src);
                                    $(e).attr("src", PREFIX + querystring.escape(src));
                                }
                            });

                            // TODO: 图片暂时不入库，后面再说。
                            var avatar = $(e).find(".meta>.avatar").attr("src");
                            if (_.isEmpty(avatar))
                            {
                                avatar = "";
                            }
                            else
                            {
                                images.push(avatar);
                                avatar = PREFIX + querystring.escape(avatar);
                            }

                            return {
                                avatar : avatar,
                                name: $(e).find(".meta>.author").text(),
                                bio : $(e).find(".meta>.bio").text(),
                                content : $(e).children(".content").html()
                            };
                        }).get();

                        var a = $(e).find(".view-more>a");
                        if (a.length > 0)
                        {
                            question.link = {
                                href : a.attr("href"),
                                text : a.text(),
                            };
                        }

                        return question;
                    }).get();
                }

                p_callback(null, {
                    story: story,
                    images: images
                });
            }
            else
            {
                p_callback(new Error("request Zhihu-Daily API ('/news/:id') error."));
            }
        });
    }
    else
    {
        p_callback(new Error("p_id has a wrong format."));
    }
};

/**
 * 获取指定地址的图片。
 * @param {String} p_url 地址。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchImage = function (p_url, p_callback)
{
    if (!_.isFunction(p_callback)) return;

    imageRequest({ url: p_url, encoding: null }, function (err, res, body)
    {
        if (!err && res.statusCode == 200)
        {
            p_callback(null, {
                id: p_url,
                contentType: res.headers["content-type"],
                data: body
            });
        }
        else
        {
            p_callback(new Error("failed to request image."));
        }
    });
};
<commit_msg>update fetchImage function<commit_after>/**
 * 负责请求知乎日报 API，并返回结果。
 */

var _ = require("lodash");
var config = require("config");
var cheerio = require("cheerio");
var querystring = require("querystring");
var imageRequest = require("request");
var dailyRequest = require("request").defaults({
    baseUrl : config.zhihu_daily_api
});

var utils = require("./utils");
const PREFIX = "/api/4/imgs/";

/**
 * 获取最新知乎日报 ID 列表。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchLatestStoryIDs = function (p_callback)
{
    if (!_.isFunction(p_callback)) return;

    dailyRequest.get({ url: "/news/latest", json: true }, function (err, res, body)
    {
        if (!err && res.statusCode == 200)
        {
            // 因知乎日报的 API 返回的图片太小，这里直接丢弃，后面再通过其他途径获取图片。
            p_callback(null, {
                date: body.date,
                ids: body.stories.map(function (value)
                {
                    return value.id;
                })
            });
        }
        else
        {
            p_callback(new Error("request Zhihu-Daily API ('/news/latest') error."));
        }
    });
};

/**
 * 获取最新热门知乎日报 ID 列表。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchTopStoryIDs = function (p_callback)
{
    dailyRequest.get({ url: "/news/latest", json: true }, function (err, res, body)
    {
        if (!err && res.statusCode == 200)
        {
            var ids = body.top_stories.map(function (value)
            {
                return {
                    id: value.id,
                    title: value.title,
                    image: PREFIX + querystring.escape(value.image)
                };
            });
            p_callback(null, {
                date: body.date,
                ids: ids
            });
        }
        else
        {
            p_callback(new Error("request Zhihu-Daily API ('/news/latest') error."));
        }
    });
};

/**
 * 获取指定日期的知乎日报 ID 列表。
 * @param {String} p_date 日期。如果小于"20130519"，返回值 res 为 {}。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchStoryIDs = function (p_date, p_callback)
{
    if (!_.isFunction(p_callback)) return;

    // 因知乎日报 API 返回的是指定日期的前一天的日报，
    // 所以要加一天才能获取指定日期的日报。
    var date = utils.nextZhihuDay(p_date);
    if (date)
    {
        if (utils.convertZhihuDateToMoment(date).isBefore(utils.MIN_DATE))
        {
            // "20130519"之前是没有知乎日报的。
            p_callback(null, {});
        }
        else
        {
            dailyRequest.get({ url: "/news/before/" + date, json: true }, function (err, res, body)
            {
                if (!err && res.statusCode == 200)
                {
                    p_callback(null, {
                        date: body.date,
                        ids: body.stories.map(function (value)
                        {
                            return value.id;
                        })
                    });
                }
                else
                {
                    p_callback(new Error("request Zhihu-Daily API ('/news/before/:date') error."));
                }
            });
        }
    }
    else
    {
        p_callback(new Error("p_date has a wrong format."));
    }
};

/**
 * 获取指定 ID 的知乎日报。
 * @param {String} p_id ID。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchStory = function (p_id, p_callback)
{
    if (!_.isFunction(p_callback)) return;

    // 检查 ID 是否为纯数字。
    if (/^\d+$/.test(p_id))
    {
        dailyRequest.get({ url: "/news/" + p_id, json: true }, function (err, res, body)
        {
            if (!err && res.statusCode == 200)
            {
                var images = [];
                var story = {};
                story.id = body.id;
                story.title = body.title;

                images.push(body.image);
                story.image = PREFIX + querystring.escape(body.image);

                story.imageSource = body.image_source;
                story.shareURL = body.share_url;

                if (body.body)
                {
                    var $ = cheerio.load(body.body, { decodeEntities: false });
                    story.backgrounds = $(".headline>.headline-background .headline-background-link").map(function (i, e)
                    {
                        return {
                            href: $(e).attr("href"),
                            title : $(e).children(".heading").text(),
                            text : $(e).children(".heading-content").text()
                        };
                    }).get();

                    story.contents = $(".content-inner>.question").map(function (i, e)
                    {
                        var question = {};
                        question.title = $(e).children(".question-title").text();
                        question.answers = $(e).children(".answer").map(function (i, e)
                        {
                            $(e).find(".content img").each(function (i, e)
                            {
                                var src = $(e).attr("src");
                                if (!_.isEmpty(src))
                                {
                                    images.push(src);
                                    $(e).attr("src", PREFIX + querystring.escape(src));
                                }
                            });

                            // TODO: 图片暂时不入库，后面再说。
                            var avatar = $(e).find(".meta>.avatar").attr("src");
                            if (_.isEmpty(avatar))
                            {
                                avatar = "";
                            }
                            else
                            {
                                images.push(avatar);
                                avatar = PREFIX + querystring.escape(avatar);
                            }

                            return {
                                avatar : avatar,
                                name: $(e).find(".meta>.author").text(),
                                bio : $(e).find(".meta>.bio").text(),
                                content : $(e).children(".content").html()
                            };
                        }).get();

                        var a = $(e).find(".view-more>a");
                        if (a.length > 0)
                        {
                            question.link = {
                                href : a.attr("href"),
                                text : a.text(),
                            };
                        }

                        return question;
                    }).get();
                }

                p_callback(null, {
                    story: story,
                    images: images
                });
            }
            else
            {
                p_callback(new Error("request Zhihu-Daily API ('/news/:id') error."));
            }
        });
    }
    else
    {
        p_callback(new Error("p_id has a wrong format."));
    }
};

/**
 * 获取指定地址的图片。
 * @param {String} p_url 地址。
 * @param {Function(err, res)} [p_callback]
 */
exports.fetchImage = function (p_url, p_callback)
{
    if (!_.isFunction(p_callback)) return;

    if (_.isEmpty(p_url))
    {
        p_callback(new Error("p_url must not be null."));
    }
    else
    {
        imageRequest({ url: p_url, encoding: null }, function (err, res, body)
        {
            if (!err && res.statusCode == 200)
            {
                p_callback(null, {
                    id: p_url,
                    contentType: res.headers["content-type"],
                    data: body
                });
            }
            else
            {
                p_callback(new Error("failed to request image."));
            }
        });
    }
};
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var dateDujour = require('../models/dateDujour');
var NbDeFruits = require('../models/NbDeFruits');

var Sequelize = require('sequelize');

var connection = new Sequelize('testsequelize', 'root', 'password');

/*
var fs = require('fs');
var obj;
fs.readFile('fruits.json', 'utf8', function (err, data) {
  if (err) throw err;
  obj = JSON.parse(data);
  kiwis = obj.fruits[0].kiwis;
  //console.log(kiwis);
});
*/

/* GET home page.*/
router.get('/', function (req, res, next) {
  res.render('index', dateDujour());
});

router.get('/test', function (req, res, next) {
  res.render('test', { title: 'youpidouo' });
});

router.get('/fruits', function (req, res, next) {
    connection.query("SELECT * FROM testsequelize.sensorvalues;")
    .then(function (projects) {
      res.render('fruits', {
        title: projects[0][0].Sensors_SID,
        sensId: projects[0][0].Sensors_SID,
        sensVal: projects[0][0].Value,
        sensors: projects[0]
      })
      // console.log("start-toto")
      // console.log(projects)
      // console.log("end-toto")
    });
});

module.exports = router;
<commit_msg>array of sensor's values<commit_after>var express = require('express');
var router = express.Router();
var dateDujour = require('../models/dateDujour');
var NbDeFruits = require('../models/NbDeFruits');

var Sequelize = require('sequelize');

var connection = new Sequelize('testsequelize', 'root', 'password');

/*
var fs = require('fs');
var obj;
fs.readFile('fruits.json', 'utf8', function (err, data) {
  if (err) throw err;
  obj = JSON.parse(data);
  kiwis = obj.fruits[0].kiwis;
  //console.log(kiwis);
});
*/

/* GET home page.*/
router.get('/', function (req, res, next) {
  res.render('index', dateDujour());
});

router.get('/test', function (req, res, next) {
  res.render('test', { title: 'youpidouo' });
});

router.get('/fruits', function (req, res, next) {
    connection.query("SELECT * FROM testsequelize.sensorvalues order by Sensors_SID;")
    .then(function (projects) {
      var array = []
      var init = projects[0][0].Sensors_SID
      for (var i = 0; i < projects[0].length; i++){
          if (init == projects[0][i].Sensors_SID ){
          array.push(projects[0][i].Sensors_SID + "  " +projects[0][i].Value);
          }
          else{
            init = projects[0][i].Sensors_SID;
          }
      }
      res.render('fruits', {
        title: projects[0][0].Sensors_SID,
        sensId: projects[0][0].Sensors_SID,
        sensVal: projects[0][0].Value,
        sensors: projects[0]
      })
      // console.log("start-toto")
       console.log(projects)
      // console.log("end-toto")
    });
});

module.exports = router;
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash'),
  filename = __filename.split('/').pop().split('.').shift(),
  lib = require('./' + filename),
  files = require('./files'),
  expect = require('chai').expect,
  sinon = require('sinon');

describe(_.startCase(filename), function () {
  var sandbox;

  beforeEach(function () {
    sandbox = sinon.sandbox.create();
  });

  afterEach(function () {
    sandbox.restore();
  });

  describe('addComponent', function () {
    var fn = lib[this.title];

    it('missing parameters throws error', function () {
      expect(function () {
        fn('', {});
      }).to.throw();
    });

    it('returns data if no import function available', function () {
      sandbox.mock(files).expects('getComponentModule').returns(null);

      expect(fn('something', {})).to.contain.keys('key', 'type', 'value');
    });
  });

  describe('addPage', function () {
    var fn = lib[this.title];

    it('missing parameters throws error', function () {
      expect(function () {
        fn('', '', {}, {});
      }).to.throw();
    });
  });
});<commit_msg>add test for add component<commit_after>'use strict';

var _ = require('lodash'),
  filename = __filename.split('/').pop().split('.').shift(),
  lib = require('./' + filename),
  files = require('./files'),
  expect = require('chai').expect,
  sinon = require('sinon'),
  bluebird = require('bluebird'),
  log = require('./log');

describe(_.startCase(filename), function () {
  var sandbox;

  beforeEach(function () {
    sandbox = sinon.sandbox.create();
  });

  afterEach(function () {
    sandbox.restore();
  });

  describe('addComponent', function () {
    var fn = lib[this.title];

    it('missing parameters throws error', function () {
      expect(function () {
        fn('', {});
      }).to.throw();
    });

    it('returns data if no import function available', function () {
      sandbox.mock(files).expects('getComponentModule').returns(null);

      expect(fn('something', {})).to.contain.keys('key', 'type', 'value');
    });

    it('returns promise if import function available', function (done) {
      sandbox.stub(log);
      sandbox.mock(files).expects('getComponentModule').returns({
        import: function (ref, data) { return bluebird.resolve(data); }
      });

      fn('something', {}).then(function (result) {
        expect(result[0]).to.contain.keys('key', 'type', 'value');
        done();
      });
    });
  });

  describe('addPage', function () {
    var fn = lib[this.title];

    it('missing parameters throws error', function () {
      expect(function () {
        fn('', '', {}, {});
      }).to.throw();
    });
  });
});<|endoftext|>


<commit_before>
// Load the Shift model
var Shift = require('../models/shiftModel');
var Template = require('../models/templateModel');
var Cancelled = require('../models/cancelledModel');
var email = require('./email');
var moment = require('moment');
var mongoose = require('mongoose');
var ObjectID = require('mongodb').ObjectID;

// Get options from config file
var config = require('../config');

// Check if shifts have been created for the current week
exports.checkShifts = function (req, res, next) {
  var ret;
  if (typeof next == 'function') {
    ret = next;
  } else {
    ret = 0;
  }
  var query = getFriday(moment());
  Cancelled.findOne(query, function (err0, results0) {
    if (err0) {return console.log(err0);}
    // If the week isn't cancelled, create the shifts
    if (!results0) {
      Shift.find(query, function (err1, results1) {
        if (err1) {return console.log(err1);}
        // If there are no shifts for this week, create them
        if (!results1.length) {
          Template.findOne({}, null, {sort: {version: -1}}, function (err2, results2) {
            if (err2) {return console.log(err2);}
            if (!results2) {return console.log("No templates were found. Please create a template first");}
            Template.find({version: results2.version}, function (err3, results3) {
              var i, j, k, l, m;
              for (i = 0; i < results3.length; i++) {
                j = results3[i].nSpots; k = results3[i].nExec;
                Shift.create({date: query.date, index: results3[i].index, time: results3[i].time, nVol: (j-k), nExec: k, newUsers: results3[i].newUsers}, function (err4, results4) {
                  if (err4) {return console.log(err4);}
                });
              }
              console.log("Creating new shifts for this Friday");
            });
          });
        }
      });
      return ret;
    } else {
      // If the week is cancelled, just continue
      return ret;
    }
  });
};

exports.getShifts = function (req, res, next) {
  // http://mongoosejs.com/docs/populate.html
  var query = getFriday(moment());
  Cancelled.findOne(query, function (err0, results0) {
    if (err0) {return console.log(err0);}
    if (!results0) {
      Shift.find(query).populate({path: 'Vol', select: '_id firstName lastNameInitial profilePicture'}).populate({path: 'Exec', select: '_id firstName lastNameInitial profilePicture'}).exec(function (err, results) {
        if (err) {return console.log(err)}
        res.json(results);
      });
    } else {
      var cancelled = {"cancelled": true};
      res.json(cancelled);
    }
  });
};

exports.getDetails = function (req, res, next) {
  // http://mongoosejs.com/docs/populate.html
  var query = getFriday(moment());
  var shifts = Shift.find(query).populate({path: 'Vol', select: '_id firstName lastName email'}).populate({path: 'Exec', select: '_id firstName lastName email'}).exec(function (err, results) {
    if (err) {return console.log(err)}
    res.json(results);
  });
};

exports.volunteer = function (req, res, next) {
  var shiftID = req.body.shiftID;
  // Just quit if the ObjectID isn't valid
  if (!mongoose.Types.ObjectId.isValid(shiftID)) {
    console.log("shiftID was invalid");
    return next;
  }
  // Quit if shifts aren't open
  if (!shouldWrite()) {
    console.log("shouldWrite was false (exiting)");
    return next;
  }
  var rightNow = moment();
  var query = getFriday(rightNow);
  query.Vol = [];
  query.Vol[0] = req.user._id;
  // Check if the volunteer already has a shift this week (if yes, cancel it)
  Shift.findOneAndUpdate(query, {$pull:{"Vol":req.user._id}}, function (err, result) {
    if (err) {return console.log(err);}
    var switching = false; if (result != null) {switching = true;}
    // Check that there actually is a spot available
    Shift.findOne({"_id": ObjectID(shiftID)}, function (err0, result0) {
      var nVolNow = result0.Vol.length;
      if (nVolNow < result0.nVol) {
        var uQuery = getFriday(rightNow); // Ensure shift is for this week
        uQuery["_id"] = ObjectID(shiftID);
        Shift.update(uQuery, {$push:{"Vol":req.user._id}}, function (err1, results1) {
          if (err1) {return console.log(err1)};
          if (results1 != null) {
            if (switching === true) {
              email.switching(req.user._id, result, uQuery, config.opt.email);
            } else {
              email.newShift(req.user._id, uQuery, config.opt.email);
            }
          }
        });
      } else {
        console.log("No more volunteering spots left");
      }
    });
  });
  return next();
};

exports.volunteerExec = function (req, res, next) {
  var shiftID = req.body.shiftID;
  // Just quit if the ObjectID isn't valid
  if (!mongoose.Types.ObjectId.isValid(shiftID)) {
    console.log("shiftID was invalid");
    return next;
  }
  // Quit if shifts aren't open
  if (!shouldWrite()) {
    console.log("shouldWrite was false (exiting)");
    return next;
  }
  var rightNow = moment();
    // Check that there actually is a spot available
    Shift.findOne({"_id": ObjectID(shiftID)}, function (err0, result0) {
      var nExecNow = result0.Exec.length;
      if (nExecNow < result0.nExec) {
        var uQuery = getFriday(rightNow); // Ensure shift is for this week
        uQuery["_id"] = ObjectID(shiftID);
        Shift.update(uQuery, {$push:{"Exec":req.user._id}}, function (err1, results1) {
          if (err1) {return console.log(err1)};
          if (results1 != null) {
              email.newExecShift(req.user._id, uQuery, config.opt.email);
          }
        });
      } else {
        console.log("No spot available left");
      }
    });
  return next();
};

exports.deleteMyShift= function (req, res, next) {
  // Quit if shifts aren't open
  if (!shouldWrite()) {
    console.log("shouldWrite was false (exiting)");
    return next;
  }
  var rightNow = moment();
  var query = getFriday(rightNow);
  query.Vol = [];
  query.Vol[0] = req.user._id;
  // Check if the volunteer already has a shift this week (if yes, cancel it)
  Shift.findOneAndUpdate(query, {$pull:{"Vol":req.user._id}}, function (err, result) {
      if (err) {return console.log(err);}
      if (result != null) {
        email.cancelled(req.user._id, result, config.opt.email);
      }
    });
  return next();
};

exports.deleteAnyShift= function (req, res, next) {
  var shiftID = req.body.shiftID;
  var volID = req.body.volID;
  // Quit if shifts aren't open
  if (!shouldWrite()) {
    console.log("shouldWrite was false (exiting)");
    return next;
  }
  // Just quit if the ObjectIDs aren't valid
  if (!mongoose.Types.ObjectId.isValid(shiftID)) {
    console.log("shiftID was invalid");
    return next;
  }
  if (!mongoose.Types.ObjectId.isValid(volID)) {
    console.log("volID was invalid");
    return next;
  }
  var rightNow = moment();
  var query = getFriday(rightNow);
  query["_id"] = shiftID;
  query.Vol = [];
  query.Vol[0] = volID;
  // Check if the volunteer already has a shift this week (if yes, cancel it)
  Shift.findOneAndUpdate(query, {$pull:{"Vol":volID}}, function (err, result) {
      if (err) {return console.log(err);}
      if (result != null) {
        email.cancelled(volID, result, config.opt.email);
      }
      if (result === null) {
		delete query.Vol;
		query.Exec = [];
		query.Exec[0] = volID;
        Shift.findOneAndUpdate(query, {$pull:{"Exec":volID}}, function (err, result) {
            if (err) {return console.log(err);}
            if (result != null) {
              email.cancelled(volID, result, config.opt.email);
            }
          });
      }
    });
  return next();
};

exports.getCancelled = function (req,res,next) {
  var today = moment().startOf('day').toDate();
  Cancelled.find({date: {$gte: today}}, function (err, data) {
    if (err) {return console.log(err);}
    res.json(data);
  });
};

exports.cancelWeek = function (req, res, next) {
  console.log(req.body);
  var date = moment(req.body.week, 'YYYY-MM-DD', true);
  if (date.isValid() !== true || date.day() != 5) {return console.log("Date was invalid");}
  // If the week is already cancelled, don't create a duplicate entry
  Cancelled.findOneAndUpdate({date: date.startOf('day').toDate()}, {date: date.startOf('day').toDate()}, {upsert:true}, function (err, result) {
    if (err) {return console.log(err);}
    console.log(result);
    res.json(result);
  });
};

exports.unCancelWeek = function (req, res, next) {
  var weekID = req.body.weekID;
  console.log(weekID);
  // Just quit if the ObjectID isn't valid
  if (!mongoose.Types.ObjectId.isValid(weekID)) {
    console.log("weekID was invalid");
    return next;
  }
  Cancelled.remove({_id: weekID}, function (err, result) {
    if (err) {return console.log(err);}
    res.json(result);
  });
};

var getFriday = function (now) {
  if (now.day() < 5 && now.day() > 0) {
    query = {"date" : now.day(5).startOf('day').toDate()};
  } else if (now.day() === 5) {
    query = {"date" : now.startOf('day').toDate()};
  } else if (now.day() === 6) {
    query = {"date" : now.day(5).startOf('day').toDate()};
  } else if (now.day() === 0) {
    query = {"date" : now.day(-2).startOf('day').toDate()};
  } else {
    console.log("Could not interpret day of week in checkShifts. Had now.day() = ", now.day());
    return;
  }
	return query;
};
module.exports.getFriday = getFriday;

function shouldWrite() {
  var now = moment();
  if (now.day() < 5 && now.day() > 0) {
    return true;
  } else if (now.day() === 5 && now.hour() < 17) {
    return true;
  } else if (now.day() === 5 && now.hour() >= 17) {
    return false;
  } else if (now.day() === 6 || now.day() === 0) {
    return false;
  } else {
    console.log("Could not interpret time in shouldWrite. Had now.day() = ", now.day(), "and now.hour() = ", now.hour());
    return false;
  }
};
<commit_msg>Fix non-automatic checkShifts<commit_after>
// Load the Shift model
var Shift = require('../models/shiftModel');
var Template = require('../models/templateModel');
var Cancelled = require('../models/cancelledModel');
var email = require('./email');
var moment = require('moment');
var mongoose = require('mongoose');
var ObjectID = require('mongodb').ObjectID;

// Get options from config file
var config = require('../config');

// Check if shifts have been created for the current week
exports.checkShifts = function (req, res, next) {
  if (typeof next != 'function') {
    next = function(){console.log("(Running checkShifts automatically)")};
  }
  var query = getFriday(moment());
  Cancelled.findOne(query, function (err0, results0) {
    if (err0) {return console.log(err0);}
    // If the week isn't cancelled, create the shifts
    if (!results0) {
      Shift.find(query, function (err1, results1) {
        if (err1) {return console.log(err1);}
        // If there are no shifts for this week, create them
        if (!results1.length) {
          Template.findOne({}, null, {sort: {version: -1}}, function (err2, results2) {
            if (err2) {return console.log(err2);}
            if (!results2) {return console.log("No templates were found. Please create a template first");}
            Template.find({version: results2.version}, function (err3, results3) {
              var i, j, k, l, m;
              for (i = 0; i < results3.length; i++) {
                j = results3[i].nSpots; k = results3[i].nExec;
                Shift.create({date: query.date, index: results3[i].index, time: results3[i].time, nVol: (j-k), nExec: k, newUsers: results3[i].newUsers}, function (err4, results4) {
                  if (err4) {return console.log(err4);}
                });
              }
              console.log("Creating new shifts for this Friday");
            });
          });
        }
      });
      next();
      return;
    } else {
      // If the week is cancelled, just continue
      next();
      return;
    }
  });
};

exports.getShifts = function (req, res, next) {
  // http://mongoosejs.com/docs/populate.html
  var query = getFriday(moment());
  Cancelled.findOne(query, function (err0, results0) {
    if (err0) {return console.log(err0);}
    if (!results0) {
      Shift.find(query).populate({path: 'Vol', select: '_id firstName lastNameInitial profilePicture'}).populate({path: 'Exec', select: '_id firstName lastNameInitial profilePicture'}).exec(function (err, results) {
        if (err) {return console.log(err)}
        res.json(results);
      });
    } else {
      var cancelled = {"cancelled": true};
      res.json(cancelled);
    }
  });
};

exports.getDetails = function (req, res, next) {
  // http://mongoosejs.com/docs/populate.html
  var query = getFriday(moment());
  var shifts = Shift.find(query).populate({path: 'Vol', select: '_id firstName lastName email'}).populate({path: 'Exec', select: '_id firstName lastName email'}).exec(function (err, results) {
    if (err) {return console.log(err)}
    res.json(results);
  });
};

exports.volunteer = function (req, res, next) {
  var shiftID = req.body.shiftID;
  // Just quit if the ObjectID isn't valid
  if (!mongoose.Types.ObjectId.isValid(shiftID)) {
    console.log("shiftID was invalid");
    return next;
  }
  // Quit if shifts aren't open
  if (!shouldWrite()) {
    console.log("shouldWrite was false (exiting)");
    return next;
  }
  var rightNow = moment();
  var query = getFriday(rightNow);
  query.Vol = [];
  query.Vol[0] = req.user._id;
  // Check if the volunteer already has a shift this week (if yes, cancel it)
  Shift.findOneAndUpdate(query, {$pull:{"Vol":req.user._id}}, function (err, result) {
    if (err) {return console.log(err);}
    var switching = false; if (result != null) {switching = true;}
    // Check that there actually is a spot available
    Shift.findOne({"_id": ObjectID(shiftID)}, function (err0, result0) {
      var nVolNow = result0.Vol.length;
      if (nVolNow < result0.nVol) {
        var uQuery = getFriday(rightNow); // Ensure shift is for this week
        uQuery["_id"] = ObjectID(shiftID);
        Shift.update(uQuery, {$push:{"Vol":req.user._id}}, function (err1, results1) {
          if (err1) {return console.log(err1)};
          if (results1 != null) {
            if (switching === true) {
              email.switching(req.user._id, result, uQuery, config.opt.email);
            } else {
              email.newShift(req.user._id, uQuery, config.opt.email);
            }
          }
        });
      } else {
        console.log("No more volunteering spots left");
      }
    });
  });
  return next();
};

exports.volunteerExec = function (req, res, next) {
  var shiftID = req.body.shiftID;
  // Just quit if the ObjectID isn't valid
  if (!mongoose.Types.ObjectId.isValid(shiftID)) {
    console.log("shiftID was invalid");
    return next;
  }
  // Quit if shifts aren't open
  if (!shouldWrite()) {
    console.log("shouldWrite was false (exiting)");
    return next;
  }
  var rightNow = moment();
    // Check that there actually is a spot available
    Shift.findOne({"_id": ObjectID(shiftID)}, function (err0, result0) {
      var nExecNow = result0.Exec.length;
      if (nExecNow < result0.nExec) {
        var uQuery = getFriday(rightNow); // Ensure shift is for this week
        uQuery["_id"] = ObjectID(shiftID);
        Shift.update(uQuery, {$push:{"Exec":req.user._id}}, function (err1, results1) {
          if (err1) {return console.log(err1)};
          if (results1 != null) {
              email.newExecShift(req.user._id, uQuery, config.opt.email);
          }
        });
      } else {
        console.log("No spot available left");
      }
    });
  return next();
};

exports.deleteMyShift= function (req, res, next) {
  // Quit if shifts aren't open
  if (!shouldWrite()) {
    console.log("shouldWrite was false (exiting)");
    return next;
  }
  var rightNow = moment();
  var query = getFriday(rightNow);
  query.Vol = [];
  query.Vol[0] = req.user._id;
  // Check if the volunteer already has a shift this week (if yes, cancel it)
  Shift.findOneAndUpdate(query, {$pull:{"Vol":req.user._id}}, function (err, result) {
      if (err) {return console.log(err);}
      if (result != null) {
        email.cancelled(req.user._id, result, config.opt.email);
      }
    });
  return next();
};

exports.deleteAnyShift= function (req, res, next) {
  var shiftID = req.body.shiftID;
  var volID = req.body.volID;
  // Quit if shifts aren't open
  if (!shouldWrite()) {
    console.log("shouldWrite was false (exiting)");
    return next;
  }
  // Just quit if the ObjectIDs aren't valid
  if (!mongoose.Types.ObjectId.isValid(shiftID)) {
    console.log("shiftID was invalid");
    return next;
  }
  if (!mongoose.Types.ObjectId.isValid(volID)) {
    console.log("volID was invalid");
    return next;
  }
  var rightNow = moment();
  var query = getFriday(rightNow);
  query["_id"] = shiftID;
  query.Vol = [];
  query.Vol[0] = volID;
  // Check if the volunteer already has a shift this week (if yes, cancel it)
  Shift.findOneAndUpdate(query, {$pull:{"Vol":volID}}, function (err, result) {
      if (err) {return console.log(err);}
      if (result != null) {
        email.cancelled(volID, result, config.opt.email);
      }
      if (result === null) {
		delete query.Vol;
		query.Exec = [];
		query.Exec[0] = volID;
        Shift.findOneAndUpdate(query, {$pull:{"Exec":volID}}, function (err, result) {
            if (err) {return console.log(err);}
            if (result != null) {
              email.cancelled(volID, result, config.opt.email);
            }
          });
      }
    });
  return next();
};

exports.getCancelled = function (req,res,next) {
  var today = moment().startOf('day').toDate();
  Cancelled.find({date: {$gte: today}}, function (err, data) {
    if (err) {return console.log(err);}
    res.json(data);
  });
};

exports.cancelWeek = function (req, res, next) {
  console.log(req.body);
  var date = moment(req.body.week, 'YYYY-MM-DD', true);
  if (date.isValid() !== true || date.day() != 5) {return console.log("Date was invalid");}
  // If the week is already cancelled, don't create a duplicate entry
  Cancelled.findOneAndUpdate({date: date.startOf('day').toDate()}, {date: date.startOf('day').toDate()}, {upsert:true}, function (err, result) {
    if (err) {return console.log(err);}
    console.log(result);
    res.json(result);
  });
};

exports.unCancelWeek = function (req, res, next) {
  var weekID = req.body.weekID;
  console.log(weekID);
  // Just quit if the ObjectID isn't valid
  if (!mongoose.Types.ObjectId.isValid(weekID)) {
    console.log("weekID was invalid");
    return next;
  }
  Cancelled.remove({_id: weekID}, function (err, result) {
    if (err) {return console.log(err);}
    res.json(result);
  });
};

var getFriday = function (now) {
  if (now.day() < 5 && now.day() > 0) {
    query = {"date" : now.day(5).startOf('day').toDate()};
  } else if (now.day() === 5) {
    query = {"date" : now.startOf('day').toDate()};
  } else if (now.day() === 6) {
    query = {"date" : now.day(5).startOf('day').toDate()};
  } else if (now.day() === 0) {
    query = {"date" : now.day(-2).startOf('day').toDate()};
  } else {
    console.log("Could not interpret day of week in checkShifts. Had now.day() = ", now.day());
    return;
  }
	return query;
};
module.exports.getFriday = getFriday;

function shouldWrite() {
  var now = moment();
  if (now.day() < 5 && now.day() > 0) {
    return true;
  } else if (now.day() === 5 && now.hour() < 17) {
    return true;
  } else if (now.day() === 5 && now.hour() >= 17) {
    return false;
  } else if (now.day() === 6 || now.day() === 0) {
    return false;
  } else {
    console.log("Could not interpret time in shouldWrite. Had now.day() = ", now.day(), "and now.hour() = ", now.hour());
    return false;
  }
};
<|endoftext|>


<commit_before>/**  @author Gilles Coomans <gilles.coomans@gmail.com> */
var Filter = require('./filter'),
	replacementRegExp = /true|false|null|\$\.(?:[a-zA-Z]\w*(?:\.\w*)*)|\$(?:[a-zA-Z]\w*(?:\.\w*)*)\(?|"[^"]*"|'[^']*'|[a-zA-Z_]\w*(?:\.\w*)*\(?/g,
	splitRegEx = /\{\{\s*(.+?)((?:(?:\s\|\s)(.+?))?)\s*\}\}/,
	cacheFull = {},
	cacheXpr = {};

function tryExpr(func, context) {
	try {
		return func.call(context.data, context, context.env.data.expressionsGlobal);
	} catch (e) {
		console.error(e);
		if (context.env.data.debug)
			console.error(e.stack);
		return '';
	}
}

// analyse and produce xpr func
function compileExpression(expr, filter, dependencies) {
	// console.log('xpr parse : ', expr);
	var total = expr + filter;
	if (cacheXpr[total]) {
		dependencies.push.apply(dependencies, cacheXpr[total].dependencies);
		return cacheXpr[total].func;
	}
	var dep = [];
	expr = expr.replace(replacementRegExp, function(whole) {
		if (whole == 'true' || whole == 'false' ||  whole == 'null')
			return whole;
		switch (whole[0]) {
			case '"':
			case "'":
				return whole;
			case '$':
				if (whole[1] === '.')
					return '__global' + whole.substring(1);
				// else do default case
			default:
				if (whole[whole.length - 1] === '(') {
					var wholePath = whole.substring(0, whole.length - 1);
					dep.push(wholePath);
					var splitted = wholePath.split('.'),
						last;
					if (splitted.length > 1)
						last = splitted.pop();
					return '__context.get(["' + splitted.join('","') + '"])' + (last ? ('.' + last) : '') + '(';
				} else {
					dep.push(whole);
					return '__context.get(["' + whole.split('.').join('","') + '"])';
				}
		}
	});
	// console.log('xpr parsing res : ', expr);
	dependencies.push.apply(dependencies, dep);

	var func = new Function("__context", "__global", "return " + expr + ";");
	if (!filter) {
		cacheXpr[total] = {
			func: func,
			dependencies: dep
		};
		return func;
	}
	// produce filter
	var fltr = new Function('Filter', 'return new Filter().' + filter)(Filter);
	// wrap expr func with filter
	var f = cacheXpr[total] = function(context, global) {
		return fltr.call(this, func.call(this, context, global));
	};
	cacheXpr[total] = {
		func: f,
		dependencies: dep
	};
	return f;
}

// produce context's subscibtion event handler
function handler(instance, context, func, index, callback) {
	return function(type, path, newValue) {
		var old = instance.results[index];
		instance.results[index] = tryExpr(func, context);
		if (old === instance.results[index])
			return;
		if (instance.dependenciesCount === 1)
			callback(type, path, instance.output(context));
		else if (!instance.willFire)
			instance.willFire = context.delay(function() { // allow small time to manage other dependencies update without multiple rerender
				if (instance.willFire) {
					instance.willFire = null;
					callback(type, path, instance.output(context));
				}
			}, 0);
	};
}

// special case when interpolable is composed of only one expression with no text decoration
// return expr result directly
function directOutput(context) {
	var o = tryExpr(this.parts[1].func, context);
	return (typeof o === 'undefined' && !this._strict) ? '' : o;
}

//___________________________________ INSTANCE of interpolable (linked to specific context)
/*
We need instances of "interpolables" when we bind interpolable object on a specific context.
We hold original interpolable parts array reference in instance and use it to produce output with local values from binded context.
 */
var Instance = function(interpolable) {
	this.outputed = false;
	this.results = [];
	this.willFire = null;
	this.parts = interpolable.parts;
	this.dependenciesCount = interpolable.dependenciesCount;
	this.directOutput = interpolable.directOutput;
	this._strict = interpolable._strict;
	this.binds = [];
};

// produce interpolable output
Instance.prototype = {
	output: function(context) {
		if (this.directOutput) {
			if (this.outputed)
				return this.results[0];
			this.outputed = true;
			return this.results[0] = this.directOutput(context);
		}
		var out = '',
			odd = true,
			count = 0;
		for (var i = 0, len = this.parts.length; i < len; i++) {
			if (odd)
				out += this.parts[i];
			else {
				out += this.outputed ? this.results[count] : (this.results[count] = tryExpr(this.parts[i].func, context));
				count++;
			}
			odd = !odd;
		}
		this.outputed = true;
		return out;
	},
	destroy: function() {
		for (var i = 0, len = this.binds.length; i < len; ++i)
			this.binds[i]();
	}
};

//_______________________________________________________ INTERPOLABLE

// Constructor
var Interpolable = function(splitted, strict) {
	// console.log('Interpolabe : splitted : ', splitted);
	this.__interpolable__ = true;
	this._strict = strict || false;
	var dp;
	if (splitted.length === 5 && splitted[0] === "" && splitted[4] === "")
		this.directOutput = directOutput;
	// interpolable string
	this.parts = [];
	this.dependenciesCount = 0;
	var odd = false;
	for (var i = 0, len = splitted.length; i < len; i++) {
		odd = !odd;
		if (odd) {
			this.parts.push(splitted[i]);
			continue;
		}
		var dp = [];
		this.parts.push({
			func: compileExpression(splitted[i], splitted[i + 2], dp),
			dep: dp
		});
		i += 2;
		this.dependenciesCount += dp.length;
	}
};

function unsub(context, instance) {
	return function() {
		if (!context.destroyed)
			instance.destroy();
	};
}

Interpolable.prototype = {
	// produce instance and bind to context
	subscribeTo: function(context, callback, binds) {
		var instance = new Instance(this);
		var count = 0;
		for (var i = 1, len = this.parts.length; i < len; i = i + 2) {
			var h = handler(instance, context, this.parts[i].func, count, callback),
				dep = this.parts[i].dep;
			count++;
			for (var j = 0, lenJ = dep.length; j < lenJ; j++)
				context.subscribe(dep[j], h, false, instance.binds)
		}
		if (binds)
			binds.push(unsub(instance));
		return instance;
	},
	// output interpolable with given context
	output: function(context) {
		if (this.directOutput)
			return this.directOutput(context);
		var out = "",
			odd = true,
			parts = this.parts;
		for (var j = 0, len = parts.length; j < len; ++j) {
			if (odd)
				out += parts[j];
			else {
				var r = tryExpr(parts[j].func, context);
				if (typeof r === 'undefined') {
					if (this._strict)
						return;
					out += '';
				}
				out += r;
			}
			odd = !odd;
		}
		return out;
	}
};

module.exports = {
	// check if a string is interpolable. if so : return new Interpolable. else return original string.
	interpolable: function(string, strict) {
		if (typeof string !== 'string')
			return string;
		if (cacheFull[string])
			return cacheFull[string];
		var splitted = string.split(splitRegEx);
		if (splitted.length == 1)
			return string; // string is not interpolable
		return cacheFull[string] = new Interpolable(splitted, strict);
	},
	Interpolable: Interpolable
};
<commit_msg>remove double error output in tryExpr<commit_after>/**  @author Gilles Coomans <gilles.coomans@gmail.com> */
var Filter = require('./filter'),
	replacementRegExp = /true|false|null|\$\.(?:[a-zA-Z]\w*(?:\.\w*)*)|\$(?:[a-zA-Z]\w*(?:\.\w*)*)\(?|"[^"]*"|'[^']*'|[a-zA-Z_]\w*(?:\.\w*)*\(?/g,
	splitRegEx = /\{\{\s*(.+?)((?:(?:\s\|\s)(.+?))?)\s*\}\}/,
	cacheFull = {},
	cacheXpr = {};

function tryExpr(func, context) {
	try {
		return func.call(context.data, context, context.env.data.expressionsGlobal);
	} catch (e) {
		console.error(e);
		return '';
	}
}

// analyse and produce xpr func
function compileExpression(expr, filter, dependencies) {
	// console.log('xpr parse : ', expr);
	var total = expr + filter;
	if (cacheXpr[total]) {
		dependencies.push.apply(dependencies, cacheXpr[total].dependencies);
		return cacheXpr[total].func;
	}
	var dep = [];
	expr = expr.replace(replacementRegExp, function(whole) {
		if (whole == 'true' || whole == 'false' ||  whole == 'null')
			return whole;
		switch (whole[0]) {
			case '"':
			case "'":
				return whole;
			case '$':
				if (whole[1] === '.')
					return '__global' + whole.substring(1);
				// else do default case
			default:
				if (whole[whole.length - 1] === '(') {
					var wholePath = whole.substring(0, whole.length - 1);
					dep.push(wholePath);
					var splitted = wholePath.split('.'),
						last;
					if (splitted.length > 1)
						last = splitted.pop();
					return '__context.get(["' + splitted.join('","') + '"])' + (last ? ('.' + last) : '') + '(';
				} else {
					dep.push(whole);
					return '__context.get(["' + whole.split('.').join('","') + '"])';
				}
		}
	});
	// console.log('xpr parsing res : ', expr);
	dependencies.push.apply(dependencies, dep);

	var func = new Function("__context", "__global", "return " + expr + ";");
	if (!filter) {
		cacheXpr[total] = {
			func: func,
			dependencies: dep
		};
		return func;
	}
	// produce filter
	var fltr = new Function('Filter', 'return new Filter().' + filter)(Filter);
	// wrap expr func with filter
	var f = cacheXpr[total] = function(context, global) {
		return fltr.call(this, func.call(this, context, global));
	};
	cacheXpr[total] = {
		func: f,
		dependencies: dep
	};
	return f;
}

// produce context's subscibtion event handler
function handler(instance, context, func, index, callback) {
	return function(type, path, newValue) {
		var old = instance.results[index];
		instance.results[index] = tryExpr(func, context);
		if (old === instance.results[index])
			return;
		if (instance.dependenciesCount === 1)
			callback(type, path, instance.output(context));
		else if (!instance.willFire)
			instance.willFire = context.delay(function() { // allow small time to manage other dependencies update without multiple rerender
				if (instance.willFire) {
					instance.willFire = null;
					callback(type, path, instance.output(context));
				}
			}, 0);
	};
}

// special case when interpolable is composed of only one expression with no text decoration
// return expr result directly
function directOutput(context) {
	var o = tryExpr(this.parts[1].func, context);
	return (typeof o === 'undefined' && !this._strict) ? '' : o;
}

//___________________________________ INSTANCE of interpolable (linked to specific context)
/*
We need instances of "interpolables" when we bind interpolable object on a specific context.
We hold original interpolable parts array reference in instance and use it to produce output with local values from binded context.
 */
var Instance = function(interpolable) {
	this.outputed = false;
	this.results = [];
	this.willFire = null;
	this.parts = interpolable.parts;
	this.dependenciesCount = interpolable.dependenciesCount;
	this.directOutput = interpolable.directOutput;
	this._strict = interpolable._strict;
	this.binds = [];
};

// produce interpolable output
Instance.prototype = {
	output: function(context) {
		if (this.directOutput) {
			if (this.outputed)
				return this.results[0];
			this.outputed = true;
			return this.results[0] = this.directOutput(context);
		}
		var out = '',
			odd = true,
			count = 0;
		for (var i = 0, len = this.parts.length; i < len; i++) {
			if (odd)
				out += this.parts[i];
			else {
				out += this.outputed ? this.results[count] : (this.results[count] = tryExpr(this.parts[i].func, context));
				count++;
			}
			odd = !odd;
		}
		this.outputed = true;
		return out;
	},
	destroy: function() {
		for (var i = 0, len = this.binds.length; i < len; ++i)
			this.binds[i]();
	}
};

//_______________________________________________________ INTERPOLABLE

// Constructor
var Interpolable = function(splitted, strict) {
	// console.log('Interpolabe : splitted : ', splitted);
	this.__interpolable__ = true;
	this._strict = strict || false;
	var dp;
	if (splitted.length === 5 && splitted[0] === "" && splitted[4] === "")
		this.directOutput = directOutput;
	// interpolable string
	this.parts = [];
	this.dependenciesCount = 0;
	var odd = false;
	for (var i = 0, len = splitted.length; i < len; i++) {
		odd = !odd;
		if (odd) {
			this.parts.push(splitted[i]);
			continue;
		}
		var dp = [];
		this.parts.push({
			func: compileExpression(splitted[i], splitted[i + 2], dp),
			dep: dp
		});
		i += 2;
		this.dependenciesCount += dp.length;
	}
};

function unsub(context, instance) {
	return function() {
		if (!context.destroyed)
			instance.destroy();
	};
}

Interpolable.prototype = {
	// produce instance and bind to context
	subscribeTo: function(context, callback, binds) {
		var instance = new Instance(this);
		var count = 0;
		for (var i = 1, len = this.parts.length; i < len; i = i + 2) {
			var h = handler(instance, context, this.parts[i].func, count, callback),
				dep = this.parts[i].dep;
			count++;
			for (var j = 0, lenJ = dep.length; j < lenJ; j++)
				context.subscribe(dep[j], h, false, instance.binds)
		}
		if (binds)
			binds.push(unsub(instance));
		return instance;
	},
	// output interpolable with given context
	output: function(context) {
		if (this.directOutput)
			return this.directOutput(context);
		var out = "",
			odd = true,
			parts = this.parts;
		for (var j = 0, len = parts.length; j < len; ++j) {
			if (odd)
				out += parts[j];
			else {
				var r = tryExpr(parts[j].func, context);
				if (typeof r === 'undefined') {
					if (this._strict)
						return;
					out += '';
				}
				out += r;
			}
			odd = !odd;
		}
		return out;
	}
};

module.exports = {
	// check if a string is interpolable. if so : return new Interpolable. else return original string.
	interpolable: function(string, strict) {
		if (typeof string !== 'string')
			return string;
		if (cacheFull[string])
			return cacheFull[string];
		var splitted = string.split(splitRegEx);
		if (splitted.length == 1)
			return string; // string is not interpolable
		return cacheFull[string] = new Interpolable(splitted, strict);
	},
	Interpolable: Interpolable
};
<|endoftext|>


<commit_before>'use strict';

// Defines the main endpoint for receiving and parsing incoming
// text messages

var twilio = require('twilio');

var User = require('../models/users');
var secrets = require('../config/secrets');
var fs = require('fs');
var spawn = require('child_process').spawn;

var client = new twilio.RestClient(
  secrets.twilio.twilio_account_id,
  secrets.twilio.twilio_auth_token
);

// Called by twilio upon receiving text messages to user's
// API number
exports.receiveText = function(request, response) {
  // TODO: Add check to make sure this is actually from a text
  var textResp = new twilio.TwimlResponse();
  var sendingNumber = request.body.From;
  var query = {'local.phone': sendingNumber};

  User.findOne(query, function(err, user) {
    if(err) {
      textResp.message('Error occurred. Please try again.');
      response.send(textResp.toString());
    } else {
      if(!user) {
        console.log("Unknown user detected");
        textResp.message("Unknown number: " + sendingNumber);
        response.send(textResp.toString());
      } else {
        var parsedText = parseTextMessage(request.body.Body);
        var command = parsedText[0];
        if (isHelpRequest(command)) {
          var commandsList = listUserCommands(user);
          textResp.message('You have configured the following commands:\n' + commandsList);
          response.send(textResp.toString());
        } else {

          // Otherwise must be a user command
          var userScript = findScript(user, command);

          if (!userScript) {
            console.log('Invalid command name');
            textResp.message('Invalid command');
            response.send(textResp.toString());
          } else {

            var args = parsedText;
            args.shift() // Shift array to get only arguments

            console.log('Executing user command: ' + userScript.name);
            fs.writeFile('../tmp/' + userScript.name + '.py', userScript.code, function(err) {
              if (err){
                textResp.message('Error occurred running the command.');
                response.send(textResp.toString());
              } else {
                args.unshift('../tmp/' + userScript.name + '.py');
                var process = spawn('python', args);
                process.stdout.setEncoding('utf8');

                // Set up callback to catch all script output
                var output = '';
                process.stdout.on('data', function (data) {
                  output += data.toString();
                });

                // Send text response once script is done
                process.on('close', function (code) {
                  if (output) {
                    textResp.message('Result: ' + output);
                    response.send(textResp.toString());
                  } else {
                    textResp.message('Script done, exited with code ' + code);
                    response.send(textResp.toString());
                  }
                });
              }

            });
          }
        }
      }
    }
  });
}

// Parses the given text message, extracting the command name
// and any arguments for the command
// TODO: Configure this to take in arguments w/ spaces
// Maybe use quotes as delimiters?
function parseTextMessage(textContent) {
  console.log("Parsing text message");
  if (textContent === undefined) {
    console.log("Textcontent is undefined!");
  }
  var contents = textContent.split(' ');
  console.log(contents);
  return contents;
}

function findScript(user, command) {
  for(var i = 0; i < user.programs.length; i++){
    var script = user.programs[i];
    if (script.name === command) {
      return script;
    }
  }
  return null;
}

function isHelpRequest(command) {
  console.log('Checking if command ' + command + ' is a help request');
  return command === '.help';
}

function sendHelpMessage(textResp, response, user) {
  var commandsList = listUserCommands(user);
  textResp.message('You have configured the following commands: ' + commandsList);
  response.send(textResp.toString());
}

function listUserCommands(user) {
  var result = [];
  for (var i = 0; i < user.programs.length; i++) {
    var script = user.programs[i];
    var entry = script.name + ': ' + script.description;
    result.push(entry);
  }
  return result.join('\n');
}

/*
function executeUserScript(script, args) {
  console.log('Executing user command: ' + script.name);
  var spawn = require('child_process').spawn;
  var process = spawn(script.filepath, args);
  process.stdout.setEncoding('utf8');

  // Set up callback to catch all script output
  var output = '';
  process.stdout.on('data', function (data) {
    var output += data.toString();
  });

  process.on('close', function (code) {

  });
  return;
}*/

function sendUnknownNumberMsg(sendingNumber, textResp, response) {
  textResp.message("Unknown number: " + sendingNumber);
  response.send(textResp.toString());
}
<commit_msg>debugging<commit_after>'use strict';

// Defines the main endpoint for receiving and parsing incoming
// text messages

var twilio = require('twilio');

var User = require('../models/users');
var secrets = require('../config/secrets');
var fs = require('fs');
var spawn = require('child_process').spawn;

var client = new twilio.RestClient(
  secrets.twilio.twilio_account_id,
  secrets.twilio.twilio_auth_token
);

// Called by twilio upon receiving text messages to user's
// API number
exports.receiveText = function(request, response) {
  // TODO: Add check to make sure this is actually from a text
  var textResp = new twilio.TwimlResponse();
  var sendingNumber = request.body.From;
  var query = {'local.phone': sendingNumber};

  User.findOne(query, function(err, user) {
    if(err) {
      textResp.message('Error occurred. Please try again.');
      response.send(textResp.toString());
    } else {
      if(!user) {
        console.log("Unknown user detected");
        textResp.message("Unknown number: " + sendingNumber);
        response.send(textResp.toString());
      } else {
        var parsedText = parseTextMessage(request.body.Body);
        var command = parsedText[0];
        if (isHelpRequest(command)) {
          var commandsList = listUserCommands(user);
          textResp.message('You have configured the following commands:\n' + commandsList);
          response.send(textResp.toString());
        } else {

          // Otherwise must be a user command
          var userScript = findScript(user, command);

          if (!userScript) {
            console.log('Invalid command name');
            textResp.message('Invalid command');
            response.send(textResp.toString());
          } else {

            var args = parsedText;
            args.shift() // Shift array to get only arguments

            console.log('Executing user command: ' + userScript.name);
            fs.writeFile('../tmp/' + userScript.name + '.py', userScript.code, function(err) {
              console.log(userScript.code);
              if (err){
                textResp.message('Error occurred running the command.');
                response.send(textResp.toString());
              } else {
                args.unshift('../tmp/' + userScript.name + '.py');
                console.log('Passing in the following args: ' + args.join(' '));
                var process = spawn('python', args);
                process.stdout.setEncoding('utf8');

                // Set up callback to catch all script output
                var output = '';
                process.stdout.on('data', function (data) {
                  output += data.toString();
                });

                // Send text response once script is done
                process.on('close', function (code) {
                  if (output) {
                    textResp.message('Result: ' + output);
                    response.send(textResp.toString());
                  } else {
                    textResp.message('Script done, exited with code ' + code);
                    response.send(textResp.toString());
                  }
                });
              }

            });
          }
        }
      }
    }
  });
}

// Parses the given text message, extracting the command name
// and any arguments for the command
// TODO: Configure this to take in arguments w/ spaces
// Maybe use quotes as delimiters?
function parseTextMessage(textContent) {
  console.log("Parsing text message");
  if (textContent === undefined) {
    console.log("Textcontent is undefined!");
  }
  var contents = textContent.split(' ');
  console.log(contents);
  return contents;
}

function findScript(user, command) {
  for(var i = 0; i < user.programs.length; i++){
    var script = user.programs[i];
    if (script.name === command) {
      return script;
    }
  }
  return null;
}

function isHelpRequest(command) {
  console.log('Checking if command ' + command + ' is a help request');
  return command === '.help';
}

function sendHelpMessage(textResp, response, user) {
  var commandsList = listUserCommands(user);
  textResp.message('You have configured the following commands: ' + commandsList);
  response.send(textResp.toString());
}

function listUserCommands(user) {
  var result = [];
  for (var i = 0; i < user.programs.length; i++) {
    var script = user.programs[i];
    var entry = script.name + ': ' + script.description;
    result.push(entry);
  }
  return result.join('\n');
}

/*
function executeUserScript(script, args) {
  console.log('Executing user command: ' + script.name);
  var spawn = require('child_process').spawn;
  var process = spawn(script.filepath, args);
  process.stdout.setEncoding('utf8');

  // Set up callback to catch all script output
  var output = '';
  process.stdout.on('data', function (data) {
    var output += data.toString();
  });

  process.on('close', function (code) {

  });
  return;
}*/

function sendUnknownNumberMsg(sendingNumber, textResp, response) {
  textResp.message("Unknown number: " + sendingNumber);
  response.send(textResp.toString());
}
<|endoftext|>


<commit_before>import { Action } from './../lib/Action';
import { Monogatari } from '../monogatari';

export class Stop extends Action {

	static matchString ([ action ]) {
		return action === 'stop';
	}

	/**
	 * Prepare the needed values to run the fade function on the given player
	 *
	 * @param {string} fadeTime - The time it will take the audio to reach 0
	 * @param {Audio} player - The Audio object to modify
	 *
	 * @return {Promise} - This promise will resolve once the fadeOut has ended
	 */
	static fadeOut (fadeTime, player) {
		const time = parseFloat (fadeTime.match (/\d*(\.\d*)?/));
		const increments = time / 0.1;
		const maxVolume = parseFloat (player.dataset.maxVolume);

		const volume = (maxVolume / increments) / maxVolume;

		const interval = (1000 * time) / increments;

		const expected = Date.now () + interval;

		player.dataset.fade = 'out';

		return new Promise ((resolve, reject) => {
			setTimeout (() => {
				Stop.fade (player, volume, interval, expected, resolve);
			}, interval);
		});
	}

	/**
	 * Fade the player's audio on small iterations until it reaches 0
	 *
	 * @param {Audio} player The Audio player to which the audio will fadeOut
	 * @param {number} volume The amount to decrease the volume on each iteration
	 * @param {number} interval The time in milliseconds between each iteration
	 * @param {Date} expected The expected time the next iteration will happen
	 * @param {function} resolve The resolve function of the promise returned by the fadeOut function
	 *
	 * @return {void}
	 */
	static fade (player, volume, interval, expected, resolve) {
		const now = Date.now () - expected; // the drift (positive for overshooting)

		if (now > interval) {
			// something really bad happened. Maybe the browser (tab) was inactive?
			// possibly special handling to avoid futile "catch up" run
		}

		if (player.volume !== 0 && player.dataset.fade === 'out') {
			if (player.volume - volume < 0) {
				resolve ();
			} else {
				player.volume -= volume;
				expected += interval;
				setTimeout (() => {
					Stop.fade (player, volume, interval, expected, resolve);
				}, Math.max (0, interval - now)); // take into account drift
			}
		}
	}

	constructor ([ action, type, media, ...props ]) {
		super ();

		this.type = type;
		this.media = media;
		this.props = props;

		if (typeof media === 'undefined' && media !== 'with') {
			this.player = Monogatari.mediaPlayers (type, true);
		} else {
			this.player = Monogatari.mediaPlayer (type, media);
		}
	}

	willApply () {
		if (this.player) {
			if (typeof this.player === 'object' && !(this.player instanceof Audio)) {
				for (const player of Object.values (this.player)) {
					player.loop = false;
				}
			} else {
				this.player.loop = false;
			}
		}
		return Promise.resolve ();
	}

	apply () {
		if (this.player) {
			// Check if the audio should have a fade time
			const fadePosition = this.props.indexOf ('fade');

			if (typeof this.player === 'object' && !(this.player instanceof Audio)) {
				if (fadePosition > -1) {
					for (const player of this.player) {
						Stop.fadeOut (this.props[fadePosition + 1], this.player).then (() => {
							Monogatari.removeMediaPlayer (this.type, player.dataset.key);
						});
					}
				} else {
					Monogatari.removeMediaPlayer (this.type);
				}
			} else {

				if (fadePosition > -1) {
					Stop.fadeOut (this.props[fadePosition + 1], this.player).then (() => {
						Monogatari.removeMediaPlayer (this.type, this.media);
					});
				} else {
					Monogatari.removeMediaPlayer (this.type, this.mediaKey);
				}
			}
		}

		return Promise.resolve ();
	}

	didApply () {
		const state = {};

		if (typeof this.media !== 'undefined') {
			state[this.type] = Monogatari.state (this.type).filter ((m) => m.indexOf (`play ${this.type} ${this.media}`) <= -1);
		} else {
			Monogatari.history (this.type).push (Monogatari.state (this.type));
			state[this.type] = [];
		}

		Monogatari.state (state);

		return Promise.resolve ({ advance: true });
	}

	revert () {
		if (typeof this.media !== 'undefined') {
			const last = Monogatari.history (this.type).reverse ().find ((m) => m.indexOf (`play ${this.type} ${this.media}`) > -1);

			const promise = Monogatari.run (last, false).then (() => {
				Monogatari.history (this.type).pop ();
			});

			return promise;

		} else {
			const statements = Monogatari.history (this.type).pop ();

			const promises = [];
			for (const statement of statements) {
				promises.push (Monogatari.run (statement, false).then (() => {
					Monogatari.history (this.type).pop ();
					return Promise.resolve ();
				}));
			}
			return Promise.all (promises);
		}
	}

	didRevert () {
		return Promise.resolve ({ advance: true, step: true });
	}
}

Stop.id = 'Stop';

Monogatari.registerAction (Stop);<commit_msg>Prevent using undefined value on revert action<commit_after>import { Action } from './../lib/Action';
import { Monogatari } from '../monogatari';

export class Stop extends Action {

	static matchString ([ action ]) {
		return action === 'stop';
	}

	/**
	 * Prepare the needed values to run the fade function on the given player
	 *
	 * @param {string} fadeTime - The time it will take the audio to reach 0
	 * @param {Audio} player - The Audio object to modify
	 *
	 * @return {Promise} - This promise will resolve once the fadeOut has ended
	 */
	static fadeOut (fadeTime, player) {
		const time = parseFloat (fadeTime.match (/\d*(\.\d*)?/));
		const increments = time / 0.1;
		const maxVolume = parseFloat (player.dataset.maxVolume);

		const volume = (maxVolume / increments) / maxVolume;

		const interval = (1000 * time) / increments;

		const expected = Date.now () + interval;

		player.dataset.fade = 'out';

		return new Promise ((resolve, reject) => {
			setTimeout (() => {
				Stop.fade (player, volume, interval, expected, resolve);
			}, interval);
		});
	}

	/**
	 * Fade the player's audio on small iterations until it reaches 0
	 *
	 * @param {Audio} player The Audio player to which the audio will fadeOut
	 * @param {number} volume The amount to decrease the volume on each iteration
	 * @param {number} interval The time in milliseconds between each iteration
	 * @param {Date} expected The expected time the next iteration will happen
	 * @param {function} resolve The resolve function of the promise returned by the fadeOut function
	 *
	 * @return {void}
	 */
	static fade (player, volume, interval, expected, resolve) {
		const now = Date.now () - expected; // the drift (positive for overshooting)

		if (now > interval) {
			// something really bad happened. Maybe the browser (tab) was inactive?
			// possibly special handling to avoid futile "catch up" run
		}

		if (player.volume !== 0 && player.dataset.fade === 'out') {
			if (player.volume - volume < 0) {
				resolve ();
			} else {
				player.volume -= volume;
				expected += interval;
				setTimeout (() => {
					Stop.fade (player, volume, interval, expected, resolve);
				}, Math.max (0, interval - now)); // take into account drift
			}
		}
	}

	constructor ([ action, type, media, ...props ]) {
		super ();

		this.type = type;
		this.media = media;
		this.props = props;

		if (typeof media === 'undefined' && media !== 'with') {
			this.player = Monogatari.mediaPlayers (type, true);
		} else {
			this.player = Monogatari.mediaPlayer (type, media);
		}
	}

	willApply () {
		if (this.player) {
			if (typeof this.player === 'object' && !(this.player instanceof Audio)) {
				for (const player of Object.values (this.player)) {
					player.loop = false;
				}
			} else {
				this.player.loop = false;
			}
		}
		return Promise.resolve ();
	}

	apply () {
		if (this.player) {
			// Check if the audio should have a fade time
			const fadePosition = this.props.indexOf ('fade');

			if (typeof this.player === 'object' && !(this.player instanceof Audio)) {
				if (fadePosition > -1) {
					for (const player of this.player) {
						Stop.fadeOut (this.props[fadePosition + 1], this.player).then (() => {
							Monogatari.removeMediaPlayer (this.type, player.dataset.key);
						});
					}
				} else {
					Monogatari.removeMediaPlayer (this.type);
				}
			} else {

				if (fadePosition > -1) {
					Stop.fadeOut (this.props[fadePosition + 1], this.player).then (() => {
						Monogatari.removeMediaPlayer (this.type, this.media);
					});
				} else {
					Monogatari.removeMediaPlayer (this.type, this.mediaKey);
				}
			}
		}

		return Promise.resolve ();
	}

	didApply () {
		const state = {};

		if (typeof this.media !== 'undefined') {
			state[this.type] = Monogatari.state (this.type).filter ((m) => m.indexOf (`play ${this.type} ${this.media}`) <= -1);
		} else {
			Monogatari.history (this.type).push (Monogatari.state (this.type));
			state[this.type] = [];
		}

		Monogatari.state (state);

		return Promise.resolve ({ advance: true });
	}

	revert () {
		if (typeof this.media !== 'undefined') {
			const last = [...Monogatari.history (this.type)].reverse ().find ((m) => m.indexOf (`play ${this.type} ${this.media}`) > -1);

			if (typeof last !== 'undefined') {
				const promise = Monogatari.run (last, false).then (() => {
					Monogatari.history (this.type).pop ();
					return Promise.resolve ();
				});

				return promise;
			}

		} else {
			const statements = Monogatari.history (this.type).pop ();

			const promises = [];
			for (const statement of statements) {
				promises.push (Monogatari.run (statement, false).then (() => {
					Monogatari.history (this.type).pop ();
					return Promise.resolve ();
				}));
			}
			return Promise.all (promises);
		}

		return Promise.resolve ();
	}

	didRevert () {
		return Promise.resolve ({ advance: true, step: true });
	}
}

Stop.id = 'Stop';

Monogatari.registerAction (Stop);<|endoftext|>


<commit_before>/*
 * config.js: Configuration for the jitsu CLI.
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var path = require('path'),
    fs = require('fs'),
    jitsu = require('../jitsu');

//
// Store the original `jitsu.config.load()` function
// for later use.
//
var _load = jitsu.config.load;

//
// Update env if using Windows
//
if (process.platform == "win32") {
  process.env.HOME = process.env.USERPROFILE;
}

//
// Setup target file for `.jitsuconf`.
//
//
// TODO: Refactor broadway to emit `bootstrap:after` and put this
//       code in a handler for that event
//
try {
  jitsu.config.file({
    file: jitsu.argv.jitsuconf || jitsu.argv.j || '.jitsuconf',
    dir: process.env.HOME,
    search: true
  });
}
catch (err) {
  console.log('Error parsing ' + jitsu.config.stores.file.file.magenta);
  console.log(err.message);
  console.log('');
  console.log('This is most likely not an error in jitsu');
  console.log('Please check the .jitsuconf file and try again');
  console.log('');
  process.exit(1);
}

var defaults = {
  analyze: true,
  release: 'build',
  colors: true,
  gzipbin: 'gzip',
  loglevel: 'info',
  loglength: 110,
  protocol: 'https',
  remoteHost: 'api.nodejitsu.com',
  requiresAuth: ['apps', 'databases', 'env', 'logs', 'snapshots'],
  root: process.env.HOME,
  tar: 'tar',
  tmproot: path.join(process.env.HOME, '.jitsu/tmp'),
  userconfig: '.jitsuconf'
};

Object.defineProperty(defaults, 'remoteUri', {
  get: function () {
    var port = jitsu.config.get('port') || '';
    if (port) {
      port = ':' + port;
    }

    return [jitsu.config.get('protocol'), '://', jitsu.config.get('remoteHost'), port].join('');
  }
});

//
// Set defaults for `jitsu.config`.
//
jitsu.config.defaults(defaults);

//
// Use the `flatiron-cli-config` plugin for `jitsu config *` commands
//
jitsu.use(require('flatiron-cli-config'), {
  store: 'file',
  restricted: [
    'auth',
    'gzipbin',
    'root',
    'remoteUri',
    'tmproot',
    'tar',
    'userconfig'
  ],
  before: {
    list: function () {
      var username = jitsu.config.get('username'),
          configFile = jitsu.config.stores.file.file;

      var display = [
        ' here is the ' + configFile.grey + ' file:',
        'To change a property type:',
        'jitsu config set <key> <value>',
      ];

      if (!username) {
        jitsu.log.warn('No user has been setup on this machine');
        display[0] = 'Hello' + display[0];
      }
      else {
        display[0] = 'Hello ' + username.green + display[0];
      }

      display.forEach(function (line) {
        jitsu.log.help(line);
      });

      return true;
    }
  }
});

//
// Override `jitsu.config.load` so that we can map
// some existing properties to their correct location.
//
jitsu.config.load = function (callback) {
  _load.call(jitsu.config, function (err, store) {
    if (err) {
      return callback(err, true, true, true);
    }

    jitsu.config.set('userconfig', jitsu.config.stores.file.file);

    if (store.auth) {
      var auth = store.auth.split(':');
      jitsu.config.clear('auth');
      jitsu.config.set('username', auth[0]);
      jitsu.config.set('password', auth[1]);
      return jitsu.config.save(callback);
    }

    callback(null, store);
  });
};
<commit_msg>[api] added default timeout property<commit_after>/*
 * config.js: Configuration for the jitsu CLI.
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var path = require('path'),
    fs = require('fs'),
    jitsu = require('../jitsu');

//
// Store the original `jitsu.config.load()` function
// for later use.
//
var _load = jitsu.config.load;

//
// Update env if using Windows
//
if (process.platform == "win32") {
  process.env.HOME = process.env.USERPROFILE;
}

//
// Setup target file for `.jitsuconf`.
//
//
// TODO: Refactor broadway to emit `bootstrap:after` and put this
//       code in a handler for that event
//
try {
  jitsu.config.file({
    file: jitsu.argv.jitsuconf || jitsu.argv.j || '.jitsuconf',
    dir: process.env.HOME,
    search: true
  });
}
catch (err) {
  console.log('Error parsing ' + jitsu.config.stores.file.file.magenta);
  console.log(err.message);
  console.log('');
  console.log('This is most likely not an error in jitsu');
  console.log('Please check the .jitsuconf file and try again');
  console.log('');
  process.exit(1);
}

var defaults = {
  analyze: true,
  release: 'build',
  colors: true,
  gzipbin: 'gzip',
  loglevel: 'info',
  loglength: 110,
  protocol: 'https',
  remoteHost: 'api.nodejitsu.com',
  requiresAuth: ['apps', 'databases', 'env', 'logs', 'snapshots'],
  root: process.env.HOME,
  tar: 'tar',
  timeout: 4 * 60 * 1000,
  tmproot: path.join(process.env.HOME, '.jitsu/tmp'),
  userconfig: '.jitsuconf'
};

Object.defineProperty(defaults, 'remoteUri', {
  get: function () {
    var port = jitsu.config.get('port') || '';
    if (port) {
      port = ':' + port;
    }

    return [jitsu.config.get('protocol'), '://', jitsu.config.get('remoteHost'), port].join('');
  }
});

//
// Set defaults for `jitsu.config`.
//
jitsu.config.defaults(defaults);

//
// Use the `flatiron-cli-config` plugin for `jitsu config *` commands
//
jitsu.use(require('flatiron-cli-config'), {
  store: 'file',
  restricted: [
    'auth',
    'gzipbin',
    'root',
    'remoteUri',
    'tmproot',
    'tar',
    'userconfig'
  ],
  before: {
    list: function () {
      var username = jitsu.config.get('username'),
          configFile = jitsu.config.stores.file.file;

      var display = [
        ' here is the ' + configFile.grey + ' file:',
        'To change a property type:',
        'jitsu config set <key> <value>',
      ];

      if (!username) {
        jitsu.log.warn('No user has been setup on this machine');
        display[0] = 'Hello' + display[0];
      }
      else {
        display[0] = 'Hello ' + username.green + display[0];
      }

      display.forEach(function (line) {
        jitsu.log.help(line);
      });

      return true;
    }
  }
});

//
// Override `jitsu.config.load` so that we can map
// some existing properties to their correct location.
//
jitsu.config.load = function (callback) {
  _load.call(jitsu.config, function (err, store) {
    if (err) {
      return callback(err, true, true, true);
    }

    jitsu.config.set('userconfig', jitsu.config.stores.file.file);

    if (store.auth) {
      var auth = store.auth.split(':');
      jitsu.config.clear('auth');
      jitsu.config.set('username', auth[0]);
      jitsu.config.set('password', auth[1]);
      return jitsu.config.save(callback);
    }

    callback(null, store);
  });
};
<|endoftext|>