<commit_before>// Polyfill localStorage
// https://developer.mozilla.org/nl/docs/DOM/Storage
if (!window.localStorage) { window.localStorage = { getItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return null; } return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); }, key: function (nKeyId) { return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); }, setItem: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; this.length = document.cookie.match(/\=/g).length; }, length: 0, removeItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return; } document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; this.length--; }, hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); } }; window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; }

// Encapsulates handling of preferred language (CoffeeScript or
// JavaScript)
CD = (function () {
  var language = localStorage.getItem('language') || 'coffeescript';
  return {
    // Get/set preferred language
    language: function (value) {
      if (value) {
        language = value;
        localStorage.setItem('language', language);
      }
      return language;
    },
    // Show code examples for given language
    show: function (language) {
      var language = language.toLowerCase();
      var other = language === "coffeescript" ? "javascript" : "coffeescript";
      // Update UI
      $('form.language li').removeClass('active').find(':radio[value=' + language + ']')
        .prop('checked', true)
        .closest('li').addClass('active');
      // Add class for inline code
      $('body').removeClass('show-' + other).addClass('show-' + language);
      // Toggle code blocks
      $('.highlight')
        .hide()
        .filter(':has(.' + language + ')').show();
    }
  };
})();

$(document).ready(function () {
  // Set up handling of language toggling
  $(':radio[name=language]')
    .click(function () {
      var language = $('form.language input:checked').val();
      CD.show(CD.language(language));
    });
  // Show code examples according to user prefs
  CD.show(CD.language());
});
<commit_msg>Add doc language switch restriction to JS/Coffee<commit_after>// Polyfill localStorage
// https://developer.mozilla.org/nl/docs/DOM/Storage
if (!window.localStorage) { window.localStorage = { getItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return null; } return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); }, key: function (nKeyId) { return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); }, setItem: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; this.length = document.cookie.match(/\=/g).length; }, length: 0, removeItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return; } document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; this.length--; }, hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); } }; window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; }

// Encapsulates handling of preferred language (CoffeeScript or
// JavaScript)
CD = (function () {
  var language = localStorage.getItem('language') || 'coffeescript';
  return {
    // Get/set preferred language
    language: function (value) {
      if (value) {
        language = value;
        localStorage.setItem('language', language);
      }
      return language;
    },
    // Show code examples for given language
    show: function (language) {
      var language = language.toLowerCase();
      var other = language === "coffeescript" ? "javascript" : "coffeescript";
      // Update UI
      $('form.language li').removeClass('active').find(':radio[value=' + language + ']')
        .prop('checked', true)
        .closest('li').addClass('active');
      // Add class for inline code
      $('body').removeClass('show-' + other).addClass('show-' + language);
      // Toggle code blocks
      $('.highlight:has(.coffeescript), .highlight:has(.javascript)')
        .hide()
        .filter(':has(.' + language + ')').show();
    }
  };
})();

$(document).ready(function () {
  // Set up handling of language toggling
  $(':radio[name=language]')
    .click(function () {
      var language = $('form.language input:checked').val();
      CD.show(CD.language(language));
    });
  // Show code examples according to user prefs
  CD.show(CD.language());
});
<|endoftext|>


<commit_before>import hold from '@most/hold'
import snabbdom from 'snabbdom'
import h from 'snabbdom/h'
import classNameFromVNode from 'snabbdom-selector/lib/classNameFromVNode'
import selectorParser from 'snabbdom-selector/lib/selectorParser'

import {domSelectorParser} from './utils'
import vTreeParser from './vTreeParser'
import {isolateSink, isolateSource} from './isolate'
import {makeSelectorParser} from './select'

function vNodeWrapper(vNode, rootElement) {
  const {tagName: selectorTagName, id: selectorId} = selectorParser(vNode.sel)
  const vNodeClassName = classNameFromVNode(vNode)
  const {data: vNodeData = {}} = vNode
  const {props: vNodeDataProps = {}} = vNodeData
  const {id: vNodeId = selectorId} = vNodeDataProps

  const isVNodeAndRootElementIdentical =
    vNodeId === rootElement.id &&
    selectorTagName === rootElement.tagName &&
    vNodeClassName === rootElement.className

  if (isVNodeAndRootElementIdentical) {
    return vNode
  }

  const {tagName, id, className} = rootElement
  const elementId = id ? `#${id}` : ``
  const elementClassName = className ?
    `.${className.split(` `).join(`.`)}` :
    ``
  return h(`${tagName}${elementId}${elementClassName}`, {}, [vNode])
}

const domDriverInputGuard =
  view$ => {
    if (!view$ || typeof view$.observe !== `function`) {
      throw new Error(`The DOM driver function expects as input an ` +
        `Observable of virtual DOM elements`)
    }
  }

const makeDOMDriver =
  (containerElementSelectors, modules = [
    require(`snabbdom/modules/class`),
    require(`snabbdom/modules/props`),
    require(`snabbdom/modules/attributes`),
    require(`snabbdom/modules/style`),
  ]) => {
    const patch = snabbdom.init(modules)
    const rootElement = domSelectorParser(containerElementSelectors)

    const DomDriver =
      view$ => {
        domDriverInputGuard(view$)

        const rootVNode$ =
          view$
            .map(vTreeParser)
            .switch()
            .scan(
              (prevVNode, vNode) =>
                patch(prevVNode, vNodeWrapper(vNode, rootElement)),
              rootElement
            )
            .skip(1)

        return {
          namespace: [],
          select: makeSelectorParser(hold(rootVNode$)),
          isolateSink,
          isolateSource,
        }
      }

    return DomDriver
  }

export default makeDOMDriver
<commit_msg>feat(makeDOMDriver): pass a stream of the rootElem to makeElementSelector<commit_after>import {create} from 'most'
import hold from '@most/hold'
import snabbdom from 'snabbdom'
import h from 'snabbdom/h'
import classNameFromVNode from 'snabbdom-selector/lib/classNameFromVNode'
import selectorParser from 'snabbdom-selector/lib/selectorParser'

import {domSelectorParser} from './utils'
import vTreeParser from './vTreeParser'
import {isolateSink, isolateSource} from './isolate'
import makeElementSelector from './select'

function makeVNodeWrapper(rootElement) {
  return function vNodeWrapper(vNode) {
    const {tagName: selectorTagName, id: selectorId} = selectorParser(vNode.sel)
    const vNodeClassName = classNameFromVNode(vNode)
    const {data: vNodeData = {}} = vNode
    const {props: vNodeDataProps = {}} = vNodeData
    const {id: vNodeId = selectorId} = vNodeDataProps

    const isVNodeAndRootElementIdentical =
      vNodeId === rootElement.id &&
      selectorTagName === rootElement.tagName &&
      vNodeClassName === rootElement.className

    if (isVNodeAndRootElementIdentical) {
      return vNode
    }

    const {tagName, id, className} = rootElement
    const elementId = id ? `#${id}` : ``
    const elementClassName = className ?
      `.${className.split(` `).join(`.`)}` :
      ``
    return h(`${tagName}${elementId}${elementClassName}`, {}, [vNode])
  }
}

const domDriverInputGuard =
  view$ => {
    if (!view$ || typeof view$.observe !== `function`) {
      throw new Error(`The DOM driver function expects as input an ` +
        `Observable of virtual DOM elements`)
    }
  }

const makeDOMDriver =
  (containerElementSelectors, modules = [
    require(`snabbdom/modules/class`),
    require(`snabbdom/modules/props`),
    require(`snabbdom/modules/attributes`),
    require(`snabbdom/modules/style`),
  ]) => {
    const patch = snabbdom.init(modules)
    const rootElement = domSelectorParser(containerElementSelectors)

    const DomDriver =
      view$ => {
        domDriverInputGuard(view$)

        const rootElement$ = hold(create(add => {
          view$
            .map(vTreeParser)
            .switch()
            .map(makeVNodeWrapper(rootElement))
            .reduce((prev, curr) => {
              const vNode = patch(prev, curr)
              add(vNode.elm)
              return vNode
            }, rootElement)
        }))

        rootElement$.drain()

        return {
          namespace: [],
          select: makeElementSelector(rootElement$),
          isolateSink,
          isolateSource,
        }
      }

    return DomDriver
  }

export default makeDOMDriver
<|endoftext|>


<commit_before>"use strict";

var Cylon = require('cylon')
var tilted = false;
var talking = false;
var leds = {red:2,blue:3,green:4};
var color = "";
var whiteArray = {red:0,blue:0,green:0};
var blackArray = {red:0,blue:0,green:0};
var colorArray = {red:0,blue:0,green:0};

require('shelljs/global');

Cylon.robot({
  connections: {
    edison: { adaptor: 'intel-iot' }
  },
  devices: {
    //outputs:
    laser: { driver: 'led', pin: 7 },
    redLed: { driver: 'led', pin: 4 }
    greenLed: { driver: 'led', pin: 5 }
    blueLed: { driver: 'led', pin: 6 }

    //inputs:
    tilt: { driver: 'button', pin: 3 },
    button: { driver: 'button', pin: 2 },
    ambient: { driver: 'analog-sensor', pin: 3, lowerLimit: 100, upperLimit: 900 },
    color_detector: { driver: 'analog-sensor', pin: 0, lowerLimit: 0, upperLimit: 1024 },

  },
  work: function(my) {
    my.button.on('push', function() {
      my.laser.toggle();
    console.log("laser toggled");

    });

    every((1).seconds(), function() {
      console.log("Hello, human!");
    });

    var output_sound= function(color) {
    console.log(color + " detected");
    if (!talking){
        if (color === "red"){
            exec('sh red.sh');
        }
        if (color === "green"){
            exec('sh green.sh');
        }
        if (color === "blue"){
            exec('sh blue.sh');
        }
    }
    };

      my.tilt.on('push', function() {
          console.log("Tilt Activated");
          tilted = true;
      });
      my.tilt.on('release', function() {
          console.log("Tilt Deactivated");
          tilted = false;
      });

      var setRed = function(){
          my.redLed.turnOn()
          my.greenLed.turnOff()
          my.blueLed.turnOff()
      };
      var setBlue = function(){
          my.redLed.turnOff()
          my.greenLed.turnOff()
          my.blueLed.turnOn()
      }
      var setGreen = function(){
          my.redLed.turnOff()
          my.greenLed.turnOn()
          my.blueLed.turnOff()
      }
      var setOff = function(){
          my.redLed.turnOff()
          my.greenLed.turnOff()
          my.blueLed.turnOff()
      }

    var calibrate = function(cb){
            setRed();
            after((0.01).seconds(), function() {
                getReading(5, function(avgRead){
                    whiteArray.red = avgRead;
                    console.log("Set white red to "+avgRead);
                    setBlue();
                    after((0.01).seconds(), function() {
                        getReading(5, function(avgRead){
                            whiteArray.blue = avgRead;
                            console.log("Set white blue to "+avgRead);
                            setGreen();
                            after((0.01).seconds(), function() {
                                getReading(5, function(avgRead){
                                    whiteArray.green = avgRead;
                                    console.log("Set white green to "+avgRead);
                                    setOff();
                                    after((5).seconds(), function() {
                                        setRed();
                                        after((0.01).seconds(), function() {
                                            getReading(5, function(avgRead){
                                                blackArray.red = avgRead;
                                                console.log("Set black red to "+avgRead);
                                                setBlue();
                                                after((0.01).seconds(), function() {
                                                    getReading(5, function(avgRead){
                                                        blackArray.blue = avgRead;
                                                        console.log("Set black blue to "+avgRead);
                                                        setGreen();
                                                        after((0.01).seconds(), function() {
                                                            getReading(5, function(avgRead){
                                                                blackArray.green = avgRead;
                                                                console.log("Set black green to "+avgRead);
                                                                after((0.01).seconds(), function() {
                                                                    cb();
                                                                });
                                                            });
                                                        });
                                                    });
                                                });
                                            });
                                        });
                                    });
                                });
                            });
                        });
                    });
                });
            });
        };

    var getReading = function(times, cb, tally){
        if (times ===0){
            var avgRead = (tally) / times;
            cb(avgRead);
        }
        if (!tally){
            tally=0;
        }

        var reading = my.ambient.analogRead();
        tally = reading + tally;
        after((0.01).seconds(), function() {
            getReading(times-1, cb, tally);
        });
    };

    after((5).seconds(), function() {
        calibrate(function(){
            every((1).seconds(), function() {
              console.log("Check color");
                    setRed();
                    after((0.01).seconds(), function() {
                        getReading(5, function(avgRead){
                            colorArray.red = avgRead;
                            console.log("Set colorArray red to "+avgRead);
                            var greydiff = whiteArray.red - blackArray.red;
                            colorArray.red = (colorArray.red - blackArray.red) / (greyDiff) * 255;//the reading returned minus the lowest value divided by the possible range multiplied by 255 is a value roughly between 0-255 representing the value
                            //for the current reflectivity(for the color it is exposed to) of what is being scanned
                            avgArray.red = (avgArray.red + colorArray.red) / 2;

                            setBlue();
                            after((0.01).seconds(), function() {
                                getReading(5, function(avgRead){
                                    colorArray.blue = avgRead;
                                    console.log("Set colorArray blue to "+avgRead);
                                    var greydiff = whiteArray.blue - blackArray.blue;
                                    colorArray.blue = (colorArray.blue - blackArray.blue) / (greyDiff) * 255;//the reading returned minus the lowest value divided by the possible range multiplied by 255 is a value roughly between 0-255 representing the value
                                    //for the current reflectivity(for the color it is exposed to) of what is being scanned
                                    avgArray.blue = (avgArray.blue + colorArray.blue) / 2;
                                    setGreen();
                                    after((0.01).seconds(), function() {
                                        getReading(5, function(avgRead){
                                            colorArray.green = avgRead;
                                            console.log("Set colorArray green to "+avgRead);
                                            var greydiff = whiteArray.green - blackArray.green;
                                            colorArray.green = (colorArray.green - blackArray.green) / (greyDiff) * 255;//the reading returned minus the lowest value divided by the possible range multiplied by 255 is a value roughly between 0-255 representing the value
                                            //for the current reflectivity(for the color it is exposed to) of what is being scanned
                                            avgArray.green = (avgArray.green + colorArray.green) / 2;
                                            after((0.01).seconds(), function() {
                                                setOff();
                                                if(avgArray.red > avgArray.green && avgArray.red > avgArray.blue) {
                                                    console.log("Detected Red");
                                                    output_sound("red");
                                                }
                                                else if(avgArray.green > avgArray.red && avgArray.green > avgArray.blue) {
                                                    console.log("Detected Green");
                                                    output_sound("green");

                                                }
                                                else {
                                                    console.log("Detected Blue");
                                                    output_sound("blue");
                                                }

                                            });
                                        });
                                    });
                                });
                            });
                        });
                    });
              });
            });
        });

    } //end setup

}).start();
<commit_msg>change rgb pins<commit_after>"use strict";

var Cylon = require('cylon')
var tilted = false;
var talking = false;
var leds = {red:2,blue:3,green:4};
var color = "";
var whiteArray = {red:0,blue:0,green:0};
var blackArray = {red:0,blue:0,green:0};
var colorArray = {red:0,blue:0,green:0};

require('shelljs/global');

Cylon.robot({
  connections: {
    edison: { adaptor: 'intel-iot' }
  },
  devices: {
    //outputs:
    laser: { driver: 'led', pin: 7 },
    redLed: { driver: 'led', pin: 4 },
    greenLed: { driver: 'led', pin: 5 },
    blueLed: { driver: 'led', pin: 6 },

    //inputs:
    tilt: { driver: 'button', pin: 3 },
    button: { driver: 'button', pin: 2 },
    ambient: { driver: 'analog-sensor', pin: 3, lowerLimit: 100, upperLimit: 900 },
    color_detector: { driver: 'analog-sensor', pin: 0, lowerLimit: 0, upperLimit: 1024 },

  },
  work: function(my) {
    my.button.on('push', function() {
      my.laser.toggle();
    console.log("laser toggled");

    });

    every((1).seconds(), function() {
      console.log("Hello, human!");
    });

    var output_sound= function(color) {
    console.log(color + " detected");
    if (!talking){
        if (color === "red"){
            exec('sh red.sh');
        }
        if (color === "green"){
            exec('sh green.sh');
        }
        if (color === "blue"){
            exec('sh blue.sh');
        }
    }
    };

      my.tilt.on('push', function() {
          console.log("Tilt Activated");
          tilted = true;
      });
      my.tilt.on('release', function() {
          console.log("Tilt Deactivated");
          tilted = false;
      });

      var setRed = function(){
          my.redLed.turnOn()
          my.greenLed.turnOff()
          my.blueLed.turnOff()
      };
      var setBlue = function(){
          my.redLed.turnOff()
          my.greenLed.turnOff()
          my.blueLed.turnOn()
      }
      var setGreen = function(){
          my.redLed.turnOff()
          my.greenLed.turnOn()
          my.blueLed.turnOff()
      }
      var setOff = function(){
          my.redLed.turnOff()
          my.greenLed.turnOff()
          my.blueLed.turnOff()
      }

    var calibrate = function(cb){
            setRed();
            after((0.01).seconds(), function() {
                getReading(5, function(avgRead){
                    whiteArray.red = avgRead;
                    console.log("Set white red to "+avgRead);
                    setBlue();
                    after((0.01).seconds(), function() {
                        getReading(5, function(avgRead){
                            whiteArray.blue = avgRead;
                            console.log("Set white blue to "+avgRead);
                            setGreen();
                            after((0.01).seconds(), function() {
                                getReading(5, function(avgRead){
                                    whiteArray.green = avgRead;
                                    console.log("Set white green to "+avgRead);
                                    setOff();
                                    after((5).seconds(), function() {
                                        setRed();
                                        after((0.01).seconds(), function() {
                                            getReading(5, function(avgRead){
                                                blackArray.red = avgRead;
                                                console.log("Set black red to "+avgRead);
                                                setBlue();
                                                after((0.01).seconds(), function() {
                                                    getReading(5, function(avgRead){
                                                        blackArray.blue = avgRead;
                                                        console.log("Set black blue to "+avgRead);
                                                        setGreen();
                                                        after((0.01).seconds(), function() {
                                                            getReading(5, function(avgRead){
                                                                blackArray.green = avgRead;
                                                                console.log("Set black green to "+avgRead);
                                                                after((0.01).seconds(), function() {
                                                                    cb();
                                                                });
                                                            });
                                                        });
                                                    });
                                                });
                                            });
                                        });
                                    });
                                });
                            });
                        });
                    });
                });
            });
        };

    var getReading = function(times, cb, tally){
        if (times ===0){
            var avgRead = (tally) / times;
            cb(avgRead);
        }
        if (!tally){
            tally=0;
        }

        var reading = my.ambient.analogRead();
        tally = reading + tally;
        after((0.01).seconds(), function() {
            getReading(times-1, cb, tally);
        });
    };

    after((5).seconds(), function() {
        calibrate(function(){
            every((1).seconds(), function() {
              console.log("Check color");
                    setRed();
                    after((0.01).seconds(), function() {
                        getReading(5, function(avgRead){
                            colorArray.red = avgRead;
                            console.log("Set colorArray red to "+avgRead);
                            var greydiff = whiteArray.red - blackArray.red;
                            colorArray.red = (colorArray.red - blackArray.red) / (greyDiff) * 255;//the reading returned minus the lowest value divided by the possible range multiplied by 255 is a value roughly between 0-255 representing the value
                            //for the current reflectivity(for the color it is exposed to) of what is being scanned
                            avgArray.red = (avgArray.red + colorArray.red) / 2;

                            setBlue();
                            after((0.01).seconds(), function() {
                                getReading(5, function(avgRead){
                                    colorArray.blue = avgRead;
                                    console.log("Set colorArray blue to "+avgRead);
                                    var greydiff = whiteArray.blue - blackArray.blue;
                                    colorArray.blue = (colorArray.blue - blackArray.blue) / (greyDiff) * 255;//the reading returned minus the lowest value divided by the possible range multiplied by 255 is a value roughly between 0-255 representing the value
                                    //for the current reflectivity(for the color it is exposed to) of what is being scanned
                                    avgArray.blue = (avgArray.blue + colorArray.blue) / 2;
                                    setGreen();
                                    after((0.01).seconds(), function() {
                                        getReading(5, function(avgRead){
                                            colorArray.green = avgRead;
                                            console.log("Set colorArray green to "+avgRead);
                                            var greydiff = whiteArray.green - blackArray.green;
                                            colorArray.green = (colorArray.green - blackArray.green) / (greyDiff) * 255;//the reading returned minus the lowest value divided by the possible range multiplied by 255 is a value roughly between 0-255 representing the value
                                            //for the current reflectivity(for the color it is exposed to) of what is being scanned
                                            avgArray.green = (avgArray.green + colorArray.green) / 2;
                                            after((0.01).seconds(), function() {
                                                setOff();
                                                if(avgArray.red > avgArray.green && avgArray.red > avgArray.blue) {
                                                    console.log("Detected Red");
                                                    output_sound("red");
                                                }
                                                else if(avgArray.green > avgArray.red && avgArray.green > avgArray.blue) {
                                                    console.log("Detected Green");
                                                    output_sound("green");

                                                }
                                                else {
                                                    console.log("Detected Blue");
                                                    output_sound("blue");
                                                }

                                            });
                                        });
                                    });
                                });
                            });
                        });
                    });
              });
            });
        });

    } //end setup

}).start();
<|endoftext|>


<commit_before>"use strict";

var Cylon = require('cylon')
var tilted = false;
var Player = require('player');
var talking = false;
var red = new Player('./mp3/red.mp3');
var green = new Player('./mp3/green.mp3');
var blue = new Player('./mp3/blue.mp3');
var leds = {red:2,blue:3,green:4};
var color = "";
var whiteArray = {red:0,blue:0,green:0};
var blackArray = {red:0,blue:0,green:0};
var colorArray = {red:0,blue:0,green:0};

Cylon.robot({
  connections: {
    edison: { adaptor: 'intel-iot' }
  },
  devices: {
    //outputs:
    laser: { driver: 'led', pin: 13 },
    rgb_led: { driver: 'rgb-led', redPin: 2, greenPin: 3, bluePin: 4 },

    //inputs:
    tilt: { driver: 'button', pin: 4 },
    ambient: { driver: 'analog-sensor', pin: 0, lowerLimit: 100, upperLimit: 900 },
    color_detector: { driver: 'analog-sensor', pin: 1, lowerLimit: 0, upperLimit: 1024 },

  },
  work: function(my) {
    my.button.on('push', function() {
      my.laser.toggle();
    });
  },

  detect_color: function() {

  },

  output_sound: function(color) {
    console.log(color + " detected");
    if (!talking){
        if (color === "red"){

            red.play(function(err, player){
                if (err){
                    console.log("Error playing red",err);
                }
                console.log('red playend!');
                talking = false;
            });

        }
        if (color === "green"){
            green.play(function(err, player){
                if (err){
                    console.log("Error playing green",err);
                }
                console.log('green playend!');
                talking = false;
            });
        }
        if (color === "blue"){
            blue.play(function(err, player){
                if (err){
                    console.log("Error playing blue",err);
                }
                console.log('blue playend!');
                talking = false;
            });
        }
    }
  },

  warn_tilt: function() {
    my.tilt.on('push', function() {
      console.log("Tilt Activated");
      tilted = true;
    });
    my.tilt.on('release', function() {
      console.log("Tilt Deactivated");
      tilted = false;
    });

},
  setup: function(my) {
    var setRed = function(){
        my.rgb_led.setRGB("FF0000")
    };
    var setBlue = function(){
        my.rgb_led.setRGB("0000FF")
    }
    var setGreen = function(){
        my.rgb_led.setRGB("00FF00")
    }

    var calibrate(){
            setRed();
            after((0.001).seconds(), function() {
                getReading(5, function(avgRead){
                    whiteArray.red = avgRead;
                });
            }

            digitalWrite(ledArray[i], LOW);
            delay(100);
        }

        }
    var getReading = function(num, cb){
        if (num ===0){
            cb();
        }

    }
    every((1).seconds(), function() {
      console.log("Hello, human!");
    });
    after((0.5).seconds(), function() {
        setRed();
        after((0.001).seconds(), function() {
         getReading(5);
         whiteArray[i] = avgRead;
         digitalWrite(ledArray[i], LOW);
         delay(100);
      }

    });

    });
  }
});

}).start();
<commit_msg>Color sensing?<commit_after>"use strict";

var Cylon = require('cylon')
var tilted = false;
var Player = require('player');
var talking = false;
var red = new Player('./mp3/red.mp3');
var green = new Player('./mp3/green.mp3');
var blue = new Player('./mp3/blue.mp3');
var leds = {red:2,blue:3,green:4};
var color = "";
var whiteArray = {red:0,blue:0,green:0};
var blackArray = {red:0,blue:0,green:0};
var colorArray = {red:0,blue:0,green:0};

Cylon.robot({
  connections: {
    edison: { adaptor: 'intel-iot' }
  },
  devices: {
    //outputs:
    laser: { driver: 'led', pin: 13 },
    rgb_led: { driver: 'rgb-led', redPin: 2, greenPin: 3, bluePin: 4 },

    //inputs:
    tilt: { driver: 'button', pin: 4 },
    ambient: { driver: 'analog-sensor', pin: 0, lowerLimit: 100, upperLimit: 900 },
    color_detector: { driver: 'analog-sensor', pin: 1, lowerLimit: 0, upperLimit: 1024 },

  },
  work: function(my) {
    my.button.on('push', function() {
      my.laser.toggle();
    });
  },

  detect_color: function() {

  },

  output_sound: function(color) {
    console.log(color + " detected");
    if (!talking){
        if (color === "red"){

            red.play(function(err, player){
                if (err){
                    console.log("Error playing red",err);
                }
                console.log('red playend!');
                talking = false;
            });

        }
        if (color === "green"){
            green.play(function(err, player){
                if (err){
                    console.log("Error playing green",err);
                }
                console.log('green playend!');
                talking = false;
            });
        }
        if (color === "blue"){
            blue.play(function(err, player){
                if (err){
                    console.log("Error playing blue",err);
                }
                console.log('blue playend!');
                talking = false;
            });
        }
    }
  },

  warn_tilt: function() {
    my.tilt.on('push', function() {
      console.log("Tilt Activated");
      tilted = true;
    });
    my.tilt.on('release', function() {
      console.log("Tilt Deactivated");
      tilted = false;
    });

},
  setup: function(my) {
    var setRed = function(){
        my.rgb_led.setRGB("FF0000")
    };
    var setBlue = function(){
        my.rgb_led.setRGB("0000FF")
    }
    var setGreen = function(){
        my.rgb_led.setRGB("00FF00")
    }
    var setOff = function(){
        my.rgb_led.setRGB("000000")
    }

    var calibrate = function(cb){
            setRed();
            after((0.01).seconds(), function() {
                getReading(5, function(avgRead){
                    whiteArray.red = avgRead;
                    console.log("Set white red to "+avgRead);
                    setBlue();
                    after((0.01).seconds(), function() {
                        getReading(5, function(avgRead){
                            whiteArray.blue = avgRead;
                            console.log("Set white blue to "+avgRead);
                            setGreen();
                            after((0.01).seconds(), function() {
                                getReading(5, function(avgRead){
                                    whiteArray.green = avgRead;
                                    console.log("Set white green to "+avgRead);
                                    setOff();
                                    after((5).seconds(), function() {
                                        setRed();
                                        after((0.01).seconds(), function() {
                                            getReading(5, function(avgRead){
                                                blackArray.red = avgRead;
                                                console.log("Set black red to "+avgRead);
                                                setBlue();
                                                after((0.01).seconds(), function() {
                                                    getReading(5, function(avgRead){
                                                        blackArray.blue = avgRead;
                                                        console.log("Set black blue to "+avgRead);
                                                        setGreen();
                                                        after((0.01).seconds(), function() {
                                                            getReading(5, function(avgRead){
                                                                blackArray.green = avgRead;
                                                                console.log("Set black green to "+avgRead);
                                                                after((0.01).seconds(), function() {
                                                                    cb();
                                                                });
                                                            });
                                                        });
                                                    });
                                                });
                                            });
                                        });
                                    });
                                });
                            });
                        });
                    });
                });
            });
        };

    var getReading = function(times, cb, tally){
        if (times ===0){
            var avgRead = (tally) / times;
            cb(avgRead);
        }
        if (!tally){
            tally=0;
        }

        var reading = my.ambient.analogRead();
        tally = reading + tally;
        after((0.01).seconds(), function() {
            getReading(times-1, cb, tally);
        });
    };

    every((1).seconds(), function() {
      console.log("Hello, human!");
    });

    after((5).seconds(), function() {
        calibrate(function(){
            every((1).seconds(), function() {
              console.log("Check color");
                    setRed();
                    after((0.01).seconds(), function() {
                        getReading(5, function(avgRead){
                            colorArray.red = avgRead;
                            console.log("Set colorArray red to "+avgRead);
                            var greydiff = whiteArray.red - blackArray.red;
                            colorArray.red = (colorArray.red - blackArray.red) / (greyDiff) * 255;//the reading returned minus the lowest value divided by the possible range multiplied by 255 is a value roughly between 0-255 representing the value
                            //for the current reflectivity(for the color it is exposed to) of what is being scanned
                            avgArray.red = (avgArray.red + colorArray.red) / 2;

                            setBlue();
                            after((0.01).seconds(), function() {
                                getReading(5, function(avgRead){
                                    colorArray.blue = avgRead;
                                    console.log("Set colorArray blue to "+avgRead);
                                    var greydiff = whiteArray.blue - blackArray.blue;
                                    colorArray.blue = (colorArray.blue - blackArray.blue) / (greyDiff) * 255;//the reading returned minus the lowest value divided by the possible range multiplied by 255 is a value roughly between 0-255 representing the value
                                    //for the current reflectivity(for the color it is exposed to) of what is being scanned
                                    avgArray.blue = (avgArray.blue + colorArray.blue) / 2;
                                    setGreen();
                                    after((0.01).seconds(), function() {
                                        getReading(5, function(avgRead){
                                            colorArray.green = avgRead;
                                            console.log("Set colorArray green to "+avgRead);
                                            var greydiff = whiteArray.green - blackArray.green;
                                            colorArray.green = (colorArray.green - blackArray.green) / (greyDiff) * 255;//the reading returned minus the lowest value divided by the possible range multiplied by 255 is a value roughly between 0-255 representing the value
                                            //for the current reflectivity(for the color it is exposed to) of what is being scanned
                                            avgArray.green = (avgArray.green + colorArray.green) / 2;
                                            after((0.01).seconds(), function() {
                                                setOff();
                                            });
                                        });
                                    });
                                });
                            });
                        });
                    });
              });
            });
        });

    } //end setup

}).start();
<|endoftext|>


<commit_before>/***************************************************************************
 * This is the pubsub driver that should tell caspa about the melted status
 *
 * this code is more than slightly coupled with caspa's section that deals
 * with the messages. It should probably be refactored a little, things like
 * creating constants in and handling db collections in mbc-common
 ***************************************************************************/
var events = require('events');
var util = require('util');
var _ = require('underscore');
var mbc = require('mbc-common');

defaults = { // copied from caspa/models.App.Status
    _id: 2,
    piece: {
        previous: {name: ''},
        current:  {name: '', progress: '0%'},
        next:     {name: ''},
    },
    show: {
        previous: {_id: -1},
        current:  {_id: -1},
        next:     {_id: -1},
    },
    source: null,
    on_air: false,
};

function MostoMessage(value, description, message) {
    this.value = value;
    this.description = description;
    this.message = message;
}

function CaspaDriver() {
    events.EventEmitter.call(this);
    var self = this;
    this.status = _.clone(defaults);
    this.db = mbc.db();
    this.publisher = mbc.pubsub();

    CaspaDriver.prototype.setupAll = function() {
        var setups = [
            this.setupStatus,
            this.setupMessages,
        ];
        var sendReady = _.after(setups.length, function() {
            self.emit('ready');
        });
        setups.forEach(function(setup){
            setup(sendReady);
        });
    };

    CaspaDriver.prototype.setupStatus = function(callback) {
        var col = this.db.collection('status');
        col.findOne({_id: 2}, function(err, res) {
            if( err )
                // err.. do something?
                return;
            if( !res ) {
                // the status doesn't exist, create it
                col.save(self.status, function(err, itm) {
                    callback();
                });
            } else {
                // res existed, just signal as ready
                callback();
            }
        });
    };

    CaspaDriver.prototype.setupMessages = function(callback) {
        // I think we should assume at init there's no sticky errors?
        this.db.collection('mostomessages').remove(callback);
    };

    CaspaDriver.prototype.setStatus = function(meltedStatus) {
        // this overrides this.status with the values passed by status
        function makePiece(clip) {
            if (clip===undefined) return { name: '', _id: '' };
            return {
                name: clip.name,
                _id: clip.id
            }
        }

        var clips = meltedStatus.clips;
        var status = {
            piece: {
                previous: makePiece(clips[meltedStatus.clip.previous]),
                current:  makePiece(clips[meltedStatus.clip.current]),
                next:     makePiece(clips[meltedStatus.clip.next]),
            },
            show: {
                previous: { _id: meltedStatus.show.previous },
                current: { _id: meltedStatus.show.current },
                next: { _id: meltedStatus.show.next },
            },
            on_air: true,
        };
        status.piece.current.progress = meltedStatus.position * 100 + "%";

        this.status = _.extend(this.status, status);
        // except next. If that's undefined, I just don't know!
        this.status.show.next = status.show.next;
        this.publishStatus(status);
    };
    CaspaDriver.prototype.publishStatus = function(status) {
        this.publisher.publish({backend: "mostoStatus", model: status})
    };

    CaspaDriver.prototype.publishMessage = function(code, description, message, sticky) {
        message = new MostoMessage(code, description, message);
        var method = 'emit';
        if( sticky ) {
            // I create an id with the timestamp to be able to cancel the error afterwards
            message.stickId = (new moment()).valueOf();
            method = 'create';
        }
        this.publisher.publish({backend: "mostoMessage", method: method,
                                model: message});
        return message;
    };
    CaspaDriver.prototype.dropMessage = function(message) {
        this.publisher.publish({backend: "mostoMessage", method: 'delete',
                                model: message});
    };
}

util.inherits(CaspaDriver, events.EventEmitter);

exports = module.exports = function() {
    var driver = new CaspaDriver();
    driver.setupAll();

    return driver;
};
<commit_msg>status message comes with StatusClip objects<commit_after>/***************************************************************************
 * This is the pubsub driver that should tell caspa about the melted status
 *
 * this code is more than slightly coupled with caspa's section that deals
 * with the messages. It should probably be refactored a little, things like
 * creating constants in and handling db collections in mbc-common
 ***************************************************************************/
var events = require('events');
var util = require('util');
var _ = require('underscore');
var mbc = require('mbc-common');

defaults = { // copied from caspa/models.App.Status
    _id: 2,
    piece: {
        previous: {name: ''},
        current:  {name: '', progress: '0%'},
        next:     {name: ''},
    },
    show: {
        previous: {_id: -1},
        current:  {_id: -1},
        next:     {_id: -1},
    },
    source: null,
    on_air: false,
};

function MostoMessage(value, description, message) {
    this.value = value;
    this.description = description;
    this.message = message;
}

function CaspaDriver() {
    events.EventEmitter.call(this);
    var self = this;
    this.status = _.clone(defaults);
    this.db = mbc.db();
    this.publisher = mbc.pubsub();

    CaspaDriver.prototype.setupAll = function() {
        var setups = [
            this.setupStatus,
            this.setupMessages,
        ];
        var sendReady = _.after(setups.length, function() {
            self.emit('ready');
        });
        setups.forEach(function(setup){
            setup(sendReady);
        });
    };

    CaspaDriver.prototype.setupStatus = function(callback) {
        var col = this.db.collection('status');
        col.findOne({_id: 2}, function(err, res) {
            if( err )
                // err.. do something?
                return;
            if( !res ) {
                // the status doesn't exist, create it
                col.save(self.status, function(err, itm) {
                    callback();
                });
            } else {
                // res existed, just signal as ready
                callback();
            }
        });
    };

    CaspaDriver.prototype.setupMessages = function(callback) {
        // I think we should assume at init there's no sticky errors?
        this.db.collection('mostomessages').remove(callback);
    };

    CaspaDriver.prototype.setStatus = function(meltedStatus) {
        // this overrides this.status with the values passed by status
        function makePiece(clip) {
            if (clip===undefined) return { name: '', _id: '' };
            return {
                name: clip.name,
                _id: clip.id
            }
        }

        var clips = meltedStatus.clips;
        var status = {
            piece: {
                previous: makePiece(meltedStatus.clip.previous),
                current:  makePiece(meltedStatus.clip.current),
                next:     makePiece(meltedStatus.clip.next),
            },
            show: {
                previous: { _id: meltedStatus.show.previous },
                current: { _id: meltedStatus.show.current },
                next: { _id: meltedStatus.show.next },
            },
            on_air: true,
        };
        status.piece.current.progress = meltedStatus.position * 100 + "%";

        this.status = _.extend(this.status, status);
        // except next. If that's undefined, I just don't know!
        this.status.show.next = status.show.next;
        this.publishStatus(status);
    };
    CaspaDriver.prototype.publishStatus = function(status) {
        this.publisher.publish({backend: "mostoStatus", model: status})
    };

    CaspaDriver.prototype.publishMessage = function(code, description, message, sticky) {
        message = new MostoMessage(code, description, message);
        var method = 'emit';
        if( sticky ) {
            // I create an id with the timestamp to be able to cancel the error afterwards
            message.stickId = (new moment()).valueOf();
            method = 'create';
        }
        this.publisher.publish({backend: "mostoMessage", method: method,
                                model: message});
        return message;
    };
    CaspaDriver.prototype.dropMessage = function(message) {
        this.publisher.publish({backend: "mostoMessage", method: 'delete',
                                model: message});
    };
}

util.inherits(CaspaDriver, events.EventEmitter);

exports = module.exports = function() {
    var driver = new CaspaDriver();
    driver.setupAll();

    return driver;
};
<|endoftext|>


<commit_before>/**
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const { BigQuery } = require('@google-cloud/bigquery');
const { Storage } = require('@google-cloud/storage');
const bigqueryClient = new BigQuery();
const storageClient = new Storage();
const schemaFileName = "schema.json";
const transformFileName = "transform.sql";
const defaultLocation = 'US';
const defaultTransformQuery = "*";
const acceptable = ['csv', 'gz', 'txt', 'avro', 'json'];
const stagingTableExpiryDays = 2;
const processPrefix = "bqds";
const batchIdColumnName = `${processPrefix}_batch_id`;

/**
 * @param  {} event
 * @param  {} context
 */
exports.processEvent = async (event, context) => {
    console.log(`Object notification arrived for gs://${event.bucket}/${event.name}`);
    if (canProcess(event.name)) {
        const config = await getConfiguration(event, context);
        const haveDataset = await datasetExists(config.dataset);
        if (!haveDataset) {
            console.log(`Dataset ${config.dataset} not found, creating...`);
            await createDataset(config.dataset);
            console.log(`Created dataset ${config.dataset}`);
        } else {
            console.log(`found dataset ${config.dataset}`);
        }
        try {
            await stageFile(config);
            await transform(config);
            await deleteTable(config.dataset, config.stagingTable);
        } catch (exception) {
            console.error(`Exception processing ${event.name}: ${getExceptionString(exception)}`);
            return;
        }
    } else {
        console.log("ignoring file " + event.name + ", exiting");
    }
    return;
};

/**
 * @param  {} event
 * @param  {} context
 */
async function getConfiguration(event, context) {
    const dest = getDestination(event.name).split('.');
    const dataset = dest[0];
    const destinationTable = dest[1];

    const schemaConfig = await fromStorage(event.bucket, `${processPrefix}/${destinationTable}.${schemaFileName}`);

    // This will pull in the dictionary from the configuration file. IE: includes destination, metadata, truncate, etc.
    const config = JSON.parse(schemaConfig);

    // Updates the configured metadata to create necessary default values.
    config.metadata = setMetadataDefaults(config);

    // Runtime created properties
    config.dataset = dataset;
    config.destinationTable = destinationTable;
    config.stagingTable = `TMP_${config.destinationTable}_${context.eventId}`;
    config.sourceFile = event.name;
    config.bucket = event.bucket;
    config.eventId = context.eventId;

    console.log("configuration: " + JSON.stringify(config));
    return config;
}

/**
 * Determine whether a file suffix is recognized for ingestion.
 * @param  {} fileName
 */
function canProcess(fileName) {
    const parts = fileName.split('.');
    if (parts[0] &&
        (parts[0].startsWith(processPrefix)
            || parts[0].startsWith(`/${processPrefix}`))) {
        return false;
    } else {
        const ext = parts[parts.length - 1];
        console.log(`file has extension ${ext}`);
        return acceptable.includes(ext.toLowerCase());
    }
}

/**
 * Generates the batch Id.
 * @param  {} config
 */
function generateBatchId(config) {
    return [
        new Date().getTime(),
        config.eventId,
        config.bucket,
        config.sourceFile
    ].join(':');
}

/**
 * Exceutes the sql transformation.
 * @param  {} config
 */
async function transform(config) {
    const batchId = generateBatchId(config);
    const transformQuery = await fromStorage(config.bucket,
        `${processPrefix}/${config.destinationTable}.${transformFileName}`) || defaultTransformQuery;
    const dataset = bigqueryClient.dataset(config.dataset);
    // const exists = await tableExists(config.dataset, config.destinationTable);
    // if (!exists) {
    //     console.log(`creating table ${config.destinationTable} with ${config.metadata.fields}`);
    //     await dataset.createTable(config.destinationTable, { schema: config.metadata.fields });
    // }
    const transform = `SELECT ${transformQuery}, '${batchId}' AS ${batchIdColumnName} FROM \`${config.dataset}.${config.stagingTable}\``;
    console.log(`executing transform query: ${transform}`);
    const job = await runTransform(config, transform);
    console.log(`${job[0].metadata.id} ${job[0].metadata.statistics.query.statementType} ${job[0].metadata.configuration.jobType} ${job[0].metadata.status.state}`);
    console.log("processing done");
    return;
}

/**
 * Deletes a BQ table.
 * @param  {} dataset
 * @param  {} tableName
 */
async function deleteTable(dataset, tableName) {
    const ds = bigqueryClient.dataset(dataset);
    console.log('Deleting temp table ' + tableName);
    const toDelete = ds.table(tableName);
    const response = await toDelete.delete();
    console.log("delete table: " + JSON.stringify(response));
}

/**
 * Loads data into BQ staging table.
 * @param  {} config
 */
async function stageFile(config) {
    console.log(`using config ` + JSON.stringify(config));
    const dataset = bigqueryClient.dataset(config.dataset);
    let today = new Date();
    today.setDate(today.getDate() + stagingTableExpiryDays);
    const expiryTime = today.getTime();
    console.log(`setting expirationTime for staging table to ${expiryTime}`);

    const fields = (config.metadata && config.metadata.fields) || undefined;

    const cfg = fields
        ? { schema: fields, expirationTime: expiryTime }
        : { autodetect: true, expirationTime: expiryTime };

    await dataset.createTable(config.stagingTable, cfg);

    const table = dataset.table(config.stagingTable);
    console.log(`created table ${config.stagingTable}`);
    console.log(`executing load for ${config.sourceFile} with ` + JSON.stringify(config.metadata));

    try {
        let [job] = await table.load(storageClient.bucket(config.bucket).file(config.sourceFile), config.metadata || { autodetect: true });
        console.log(`${job.id} ${job.configuration.jobType} ${job.status.state} ${job.statistics.load.outputRows} rows`);
        return;
    } catch (ex) {
        console.error(`Errors encountered loading ${config.sourceFile} to ${config.stagingTable}`);
        logException(ex);
        throw (ex);
    }
}

/**
 * @param  {} bucket
 * @param  {} file
 */
async function fromStorage(bucket, file) {
    try {
        let content = await storageClient
            .bucket(bucket)
            .file(file)
            .download();
        console.log(`Found gs://${bucket}/${file}: ${content}`);
        return content;
    } catch (error) {
        console.info(`File ${file} not found in bucket ${bucket}: ${getExceptionString(error)}`);
        return undefined;
    }
}

/**
 * Returns value indicating if a BQ table exists.
 * @param  {} datasetId
 * @param  {} tableName
 */
async function tableExists(datasetId, tableName) {
    const dataset = bigqueryClient.dataset(datasetId);
    const table = dataset.table(tableName);
    const response = await table.exists();
    const exists = response[0];
    console.log(`Check if table exists: ${tableName}: ${exists}`);
    return exists;
}

/**
 * Returns value indicating if a BQ dataset exists.
 * @param  {} datasetId
 */
async function datasetExists(datasetId) {
    const dataset = bigqueryClient.dataset(datasetId);
    const results = await dataset.exists();
    console.log('dataset exists?: ' + JSON.stringify(results));
    return results.length > 0 ? results[0] : false;
}

/**
 * Creates a dataset.
 * @param  {} datasetId
 */
async function createDataset(datasetId) {
    const dataset = bigqueryClient.dataset(datasetId);
    return await dataset.create();
}

/**
 * Creates query job for the transformation query.
 * @param  {} config
 * @param  {} query
 */
async function runTransform(config, query) {
    console.log("configuration for runTransform: " + JSON.stringify(config));
    const options = {
        location: defaultLocation,
        destinationTable: {
            projectId: process.env.GCP_PROJECT,
            datasetId: config.dataset,
            tableId: config.destinationTable
        },
        createDisposition: "CREATE_IF_NEEDED",
        writeDisposition: (config.truncate)
            ? "WRITE_TRUNCATE"
            : "WRITE_APPEND",
        query: query,
        jobPrefix: `${processPrefix}_`,
        timePartitioning: {
            type: 'DAY'
        }
    };
    console.log("BigQuery options: " + JSON.stringify(options));
    try {
        return await bigqueryClient.createQueryJob(options);
    } catch (exception) {
        console.error(`Exception encountered running transform: ${getExceptionString(exception)}`);
        logException(exception);
        throw (exception);
    }
}

function logException(exception) {
    const errors = exception.errors;
    if (errors && errors.length > 0) {
        for (let i = 0; i < errors.length; i++) {
            console.error('ERROR ' + (i + 1) + ": " + JSON.stringify(errors[i].message));
        }
    } else {
        console.error(`Exception thrown, but no error array was given: ${getExceptionString(exception)}`);
    }
}

/**
 * @param  {} bucket
 * @param  {} schemaFileName
 */
function setMetadataDefaults(dict) {
    if (!dict.metadata) {
        console.log("No metadata found");
        return dict;
    } else {
        const meta = dict.metadata;

        if (!meta.sourceFormat) {
            meta.sourceFormat = 'CSV';
        }

        if (!meta.skipLeadingRows) {
            meta.skipLeadingRows = 1;
        }

        if (!meta.maxBadRecords) {
            meta.maxBadRecords = 0;
        }

        if (!meta.location) {
            meta.location = defaultLocation;
        }

        console.log("using metadata: " + JSON.stringify(meta));
        return meta;
    }
}

/**
 * @param  {} fileName
 */
function getDestination(fileName) {
    let name = fileName.indexOf('/') >= 0 ?
        fileName.substring(fileName.lastIndexOf('/') + 1) :
        fileName;
    const parts = name.split('.');
    if (parts && parts.length > 0) {
        name = parts[1];
        name.replace('.', '_');
        name = name.replace('-', '_');
        name = name.replace(' ', '_');
        return `${parts[0]}.${parts[1]}`;
    }
    return name;
}

/**
 * @param  {} exception
 * Returns exception message in string format. Attempts to stringify JSON, if that's undefined, returns the exception as a string.
 */
function getExceptionString(exception) {
    let str = JSON.stringify(exception);
    if (!str) {
        str = exception;
    }
    return str;
}

/**
 * @param  {} message
 */
function log(message) {
    console.log(JSON.stringify(message, undefined, 1));
}
<commit_msg>Update index.js (#69)<commit_after>/**
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const { BigQuery } = require('@google-cloud/bigquery');
const { Storage } = require('@google-cloud/storage');
const bigqueryClient = new BigQuery();
const storageClient = new Storage();
const schemaFileName = "schema.json";
const transformFileName = "transform.sql";
const defaultLocation = 'US';
const defaultTransformQuery = "*";
const acceptable = ['csv', 'gz', 'txt', 'avro', 'json'];
const stagingTableExpiryDays = 2;
const processPrefix = "bqds";
const batchIdColumnName = `${processPrefix}_batch_id`;

/**
 * @param  {} event
 * @param  {} context
 */
exports.processEvent = async (event, context) => {
    console.log(`Object notification arrived for gs://${event.bucket}/${event.name}`);
    if (canProcess(event.name)) {
        const config = await getConfiguration(event, context);
        const haveDataset = await datasetExists(config.dataset);
        if (!haveDataset) {
            console.log(`Dataset ${config.dataset} not found, creating...`);
            await createDataset(config.dataset);
            console.log(`Created dataset ${config.dataset}`);
        } else {
            console.log(`found dataset ${config.dataset}`);
        }
        try {
            await stageFile(config);
            await transform(config);
            await deleteTable(config.dataset, config.stagingTable);
        } catch (exception) {
            console.error(`Exception processing ${event.name}: ${getExceptionString(exception)}`);
            return;
        }
    } else {
        console.log("ignoring file " + event.name + ", exiting");
    }
    return;
};

/**
 * @param  {} event
 * @param  {} context
 */
async function getConfiguration(event, context) {
    const dest = getDestination(event.name).split('.');
    const dataset = dest[0];
    const destinationTable = dest[1];

    const schemaConfig = await fromStorage(event.bucket, `${processPrefix}/${destinationTable}.${schemaFileName}`);
    let config = {};
    if (schemaConfig) {
        // This will pull in the dictionary from the configuration file. IE: includes destination, metadata, truncate, etc.
        config = JSON.parse(schemaConfig);

        // Updates the configured metadata to create necessary default values.
        config.metadata = setMetadataDefaults(config);
    }

    // Runtime created properties
    config.dataset = dataset;
    config.destinationTable = destinationTable;
    config.stagingTable = `TMP_${destinationTable}_${context.eventId}`;
    config.sourceFile = event.name;
    config.bucket = event.bucket;
    config.eventId = context.eventId;

    console.log("configuration: " + JSON.stringify(config));
    return config;
}

/**
 * Determine whether a file suffix is recognized for ingestion.
 * @param  {} fileName
 */
function canProcess(fileName) {
    const parts = fileName.split('.');
    if (parts[0] &&
        (parts[0].startsWith(processPrefix)
            || parts[0].startsWith(`/${processPrefix}`))) {
        return false;
    } else {
        const ext = parts[parts.length - 1];
        console.log(`file has extension ${ext}`);
        return acceptable.includes(ext.toLowerCase());
    }
}

/**
 * Generates the batch Id.
 * @param  {} config
 */
function generateBatchId(config) {
    return [
        new Date().getTime(),
        config.eventId,
        config.bucket,
        config.sourceFile
    ].join(':');
}

/**
 * Exceutes the sql transformation.
 * @param  {} config
 */
async function transform(config) {
    const batchId = generateBatchId(config);
    const transformQuery = await fromStorage(config.bucket,
        `${processPrefix}/${config.destinationTable}.${transformFileName}`) || defaultTransformQuery;
    const dataset = bigqueryClient.dataset(config.dataset);
    // const exists = await tableExists(config.dataset, config.destinationTable);
    // if (!exists) {
    //     console.log(`creating table ${config.destinationTable} with ${config.metadata.fields}`);
    //     await dataset.createTable(config.destinationTable, { schema: config.metadata.fields });
    // }
    const transform = `SELECT ${transformQuery}, '${batchId}' AS ${batchIdColumnName} FROM \`${config.dataset}.${config.stagingTable}\``;
    console.log(`executing transform query: ${transform}`);
    const job = await runTransform(config, transform);
    console.log(`${job[0].metadata.id} ${job[0].metadata.statistics.query.statementType} ${job[0].metadata.configuration.jobType} ${job[0].metadata.status.state}`);
    console.log("processing done");
    return;
}

/**
 * Deletes a BQ table.
 * @param  {} dataset
 * @param  {} tableName
 */
async function deleteTable(dataset, tableName) {
    const ds = bigqueryClient.dataset(dataset);
    console.log('Deleting temp table ' + tableName);
    const toDelete = ds.table(tableName);
    const response = await toDelete.delete();
    console.log("delete table: " + JSON.stringify(response));
}

/**
 * Loads data into BQ staging table.
 * @param  {} config
 */
async function stageFile(config) {
    console.log(`using config ` + JSON.stringify(config));
    const dataset = bigqueryClient.dataset(config.dataset);
    let today = new Date();
    today.setDate(today.getDate() + stagingTableExpiryDays);
    const expiryTime = today.getTime();
    console.log(`setting expirationTime for staging table to ${expiryTime}`);

    const fields = (config.metadata && config.metadata.fields) || undefined;

    const cfg = fields
        ? { schema: fields, expirationTime: expiryTime }
        : { autodetect: true, expirationTime: expiryTime };

    await dataset.createTable(config.stagingTable, cfg);

    const table = dataset.table(config.stagingTable);
    console.log(`created table ${config.stagingTable}`);
    console.log(`executing load for ${config.sourceFile} with ` + JSON.stringify(config.metadata));

    try {
        let [job] = await table.load(storageClient.bucket(config.bucket).file(config.sourceFile), config.metadata || { autodetect: true });
        console.log(`${job.id} ${job.configuration.jobType} ${job.status.state} ${job.statistics.load.outputRows} rows`);
        return;
    } catch (ex) {
        console.error(`Errors encountered loading ${config.sourceFile} to ${config.stagingTable}`);
        logException(ex);
        throw (ex);
    }
}

/**
 * @param  {} bucket
 * @param  {} file
 */
async function fromStorage(bucket, file) {
    try {
        let content = await storageClient
            .bucket(bucket)
            .file(file)
            .download();
        console.log(`Found gs://${bucket}/${file}: ${content}`);
        return content;
    } catch (error) {
        console.info(`File ${file} not found in bucket ${bucket}: ${getExceptionString(error)}`);
        return undefined;
    }
}

/**
 * Returns value indicating if a BQ table exists.
 * @param  {} datasetId
 * @param  {} tableName
 */
async function tableExists(datasetId, tableName) {
    const dataset = bigqueryClient.dataset(datasetId);
    const table = dataset.table(tableName);
    const response = await table.exists();
    const exists = response[0];
    console.log(`Check if table exists: ${tableName}: ${exists}`);
    return exists;
}

/**
 * Returns value indicating if a BQ dataset exists.
 * @param  {} datasetId
 */
async function datasetExists(datasetId) {
    const dataset = bigqueryClient.dataset(datasetId);
    const results = await dataset.exists();
    console.log('dataset exists?: ' + JSON.stringify(results));
    return results.length > 0 ? results[0] : false;
}

/**
 * Creates a dataset.
 * @param  {} datasetId
 */
async function createDataset(datasetId) {
    const dataset = bigqueryClient.dataset(datasetId);
    return await dataset.create();
}

/**
 * Creates query job for the transformation query.
 * @param  {} config
 * @param  {} query
 */
async function runTransform(config, query) {
    console.log("configuration for runTransform: " + JSON.stringify(config));
    const options = {
        location: defaultLocation,
        destinationTable: {
            projectId: process.env.GCP_PROJECT,
            datasetId: config.dataset,
            tableId: config.destinationTable
        },
        createDisposition: "CREATE_IF_NEEDED",
        writeDisposition: (config.truncate)
            ? "WRITE_TRUNCATE"
            : "WRITE_APPEND",
        query: query,
        jobPrefix: `${processPrefix}_`,
        timePartitioning: {
            type: 'DAY'
        }
    };
    console.log("BigQuery options: " + JSON.stringify(options));
    try {
        return await bigqueryClient.createQueryJob(options);
    } catch (exception) {
        console.error(`Exception encountered running transform: ${getExceptionString(exception)}`);
        logException(exception);
        throw (exception);
    }
}

function logException(exception) {
    const errors = exception.errors;
    if (errors && errors.length > 0) {
        for (let i = 0; i < errors.length; i++) {
            console.error('ERROR ' + (i + 1) + ": " + JSON.stringify(errors[i].message));
        }
    } else {
        console.error(`Exception thrown, but no error array was given: ${getExceptionString(exception)}`);
    }
}

/**
 * @param  {} bucket
 * @param  {} schemaFileName
 */
function setMetadataDefaults(dict) {
    if (!dict.metadata) {
        console.log("No metadata found");
        return dict;
    } else {
        const meta = dict.metadata;

        if (!meta.sourceFormat) {
            meta.sourceFormat = 'CSV';
        }

        if (!meta.skipLeadingRows) {
            meta.skipLeadingRows = 1;
        }

        if (!meta.maxBadRecords) {
            meta.maxBadRecords = 0;
        }

        if (!meta.location) {
            meta.location = defaultLocation;
        }

        console.log("using metadata: " + JSON.stringify(meta));
        return meta;
    }
}

/**
 * @param  {} fileName
 */
function getDestination(fileName) {
    let name = fileName.indexOf('/') >= 0 ?
        fileName.substring(fileName.lastIndexOf('/') + 1) :
        fileName;
    const parts = name.split('.');
    if (parts && parts.length > 0) {
        name = parts[1];
        name.replace('.', '_');
        name = name.replace('-', '_');
        name = name.replace(' ', '_');
        return `${parts[0]}.${parts[1]}`;
    }
    return name;
}

/**
 * @param  {} exception
 * Returns exception message in string format. Attempts to stringify JSON, if that's undefined, returns the exception as a string.
 */
function getExceptionString(exception) {
    let str = JSON.stringify(exception);
    if (!str) {
        str = exception;
    }
    return str;
}

/**
 * @param  {} message
 */
function log(message) {
    console.log(JSON.stringify(message, undefined, 1));
}
<|endoftext|>


<commit_before>var cp = require("child_process");
var path = require("path");

Promise.all([
  "eg/project-simple",
  "eg/project-filtering",
  "eg/project-has-browser",
].reduce((accum, egpath) => {
  accum.push(
    new Promise((resolve, reject) => {
      cp.exec(`cd ${path.join(process.cwd(), egpath)}; npm install;`, (error) => {
        if (error) {
          return reject(error);
        }
        resolve();
      })
    })
  );
  return accum;
}, [])).then(() => {
  process.exit(0);
}).catch(error => {
  console.log(error);
  process.exit(1);
});
<commit_msg>appveyor: log process.cwd to debug path issue<commit_after>var cp = require("child_process");
var path = require("path");

console.log("process.cwd()", process.cwd());

Promise.all([
  "eg/project-simple",
  "eg/project-filtering",
  "eg/project-has-browser",
].reduce((accum, egpath) => {
  accum.push(
    new Promise((resolve, reject) => {
      cp.exec(`cd ${path.join(process.cwd(), egpath)}; npm install;`, (error) => {
        if (error) {
          return reject(error);
        }
        resolve();
      })
    })
  );
  return accum;
}, [])).then(() => {
  process.exit(0);
}).catch(error => {
  console.log(error);
  process.exit(1);
});
<|endoftext|>


<commit_before>var tap = require('tap');
var urlOf = require('./lib/url');
var pass = require('./lib/pass');
var P = require('bluebird');

require('./lib/sharedNemo').then(function(nemo) {
  tap.test('sign up for on-site trial', {
    bail: true
  }, function(t) {
    return P.resolve(nemo.driver.get(urlOf('/onsite'))).then(function() {
      return P.all([
        nemo.view.onsite.firstnameWaitVisible().then(pass(t, "form field visible")),
        nemo.view.onsite.firstname().sendKeys("Boops"),
        nemo.view.onsite.lastname().sendKeys("boops"),
        nemo.view.onsite.email().sendKeys("test+" + Date.now() + "@npmjs.com"),
        nemo.view.onsite.phone().sendKeys("415-857-5309"),
        nemo.view.onsite.company().sendKeys("yesallmen.com"),
        nemo.view.onsite.numemployees().sendKeys("2")
      ]);
    }).then(function() {
      return nemo.view.onsite.submit().click();
    }).then(function() {
      return P.all([
        nemo.view.onsite.agreementWaitVisible().then(pass(t, "navigated to second page")),
        nemo.view.onsite.agreement().sendKeys(" "),
        nemo.view.onsite.submitAgreement().click()
      ]);
    }).then(function() {
      return P.all([
        nemo.view.onsite.h2WaitVisible(),
        nemo.view.onsite.h2TextEquals('time to check your email').then(pass(t, 'confirmation found'))
      ]);
    }).then(function() {
      if (!module.parent) {
        return nemo.driver.quit();
      }
    }).catch(t.error).then(t.end);
  });
});
<commit_msg>psssst es6 sneaky sneaky<commit_after>var tap = require('tap');
var urlOf = require('./lib/url');
var P = require('bluebird');

require('./lib/sharedNemo').then(function(nemo) {
  tap.test('sign up for on-site trial', {
    bail: true
  }, function(t) {
    return P.resolve(nemo.driver.get(urlOf('/onsite'))).then(function() {
      return P.all([
        nemo.view.onsite.firstnameWaitVisible().then(() => t.pass("form field visible")),
        nemo.view.onsite.firstname().sendKeys("Boops"),
        nemo.view.onsite.lastname().sendKeys("boops"),
        nemo.view.onsite.email().sendKeys("test+" + Date.now() + "@npmjs.com"),
        nemo.view.onsite.phone().sendKeys("415-857-5309"),
        nemo.view.onsite.company().sendKeys("yesallmen.com"),
        nemo.view.onsite.numemployees().sendKeys("2")
      ]);
    }).then(function() {
      return nemo.view.onsite.submit().click();
    }).then(function() {
      return P.all([
        nemo.view.onsite.agreementWaitVisible().then(() => t.pass("navigated to second page")),
        nemo.view.onsite.agreement().sendKeys(" "),
        nemo.view.onsite.submitAgreement().click()
      ]);
    }).then(function() {
      return P.all([
        nemo.view.onsite.h2WaitVisible(),
        nemo.view.onsite.h2TextEquals('time to check your email').then(() => t.pass('confirmation found'))
      ]);
    }).then(function() {
      if (!module.parent) {
        return nemo.driver.quit();
      }
    });
  });
});
<|endoftext|>


<commit_before>(function($) {

    // ----------------------------------------------------------------------
    // This sample adds an overview connected to the main viewer.
    // ----------------------------------------------------------------------

    var document;
    var viewer;
    var overview;
    var initViewers = function() {
        document = giclee.document.Document.create([
            {type:"foo", pos:{x:100, y:100, o:0.1, s:1.2}},
            {type:"foo", pos:{x:300, y:200, o:0.3, s:0.9}}
        ]);

        viewer = giclee.viewer.Viewer.create($("#canvas"), document);
        overview = giclee.viewer.Overview.create(
            $("#overview"), viewer, {viewBoxColor:"#cc0000"}
        );
    };

    /**
     * We want the main viewer to resize with the window.
     */
    var initResizeManager = function() {
        var resize = giclee.managers.ResizeManager.create(
            $("#canvas"),
            $(window)
        );
        resize.events.register(
            "resize", function() { if (viewer !== undefined) viewer.draw(); }
        );
    };

    /**
     * Top level initialization.
     */
    var init = function() {
        initResizeManager();
        initViewers();
    };

    $(init);
})(jQuery);<commit_msg>Made overview in sample 2 redraw on resize. Needs to be a better way to handle resizing, so elements stay centered.<commit_after>(function($) {

    // ----------------------------------------------------------------------
    // This sample adds an overview connected to the main viewer.
    // ----------------------------------------------------------------------

    var document;
    var viewer;
    var overview;
    var initViewers = function() {
        document = giclee.document.Document.create([
            {type:"foo", pos:{x:100, y:100, o:0.1, s:1.2}},
            {type:"foo", pos:{x:300, y:200, o:0.3, s:0.9}}
        ]);

        viewer = giclee.viewer.Viewer.create($("#canvas"), document);
        overview = giclee.viewer.Overview.create(
            $("#overview"), viewer, {viewBoxColor:"#cc0000"}
        );
    };

    /**
     * We want the main viewer to resize with the window.
     */
    var initResizeManager = function() {
        var resize = giclee.managers.ResizeManager.create(
            $("#canvas"),
            $(window)
        );
        resize.events.register(
            "resize", function() {
                if (viewer !== undefined) viewer.draw();
                if (overview !== undefined) overview.draw();
            }
        );
    };

    /**
     * Top level initialization.
     */
    var init = function() {
        initResizeManager();
        initViewers();
    };

    $(init);
})(jQuery);<|endoftext|>