<commit_before>
import React from "react";
import moment from "moment";
import Immutable from "immutable";
import LightComponent from "ui-lib/light_component";
import AppHeader from "ui-components/app_header";
import { IconStyler, CodeFarmIcon } from "ui-components/app_icons";
import { Header, Row, Column, Loading } from "ui-components/layout";
import TypeList from "ui-observables/type_list";
import { States as ObservableDataStates } from "ui-lib/observable_data";
import { CardList, RevisionCard, ArtifactCard } from "ui-components/data_card";

const ICON_SIZE = {
    width: 312,
    height: 312
};

class IndexPage extends LightComponent {
    constructor(props) {
        super(props);

        this.revisions = new TypeList({
            type: "coderepo.revision",
            query: { status: { $ne: "abandoned" } },
            sortOn: "statusSetAt",
            limit: 10
        });

        this.artifacts = new TypeList({
            type: "coderepo.revision",
            query: { state: "commited" },
            sortOn: "created",
            limit: 10
        });

        this.state = {
            revisions: this.revisions.value.getValue(),
            revisionsState: this.revisions.state.getValue(),
            artifacts: this.artifacts.value.getValue(),
            artifactsState: this.artifacts.state.getValue()
        };
    }

    componentDidMount() {
        this.addDisposable(this.revisions.start());

        this.addDisposable(this.revisions.value.subscribe((revisions) => this.setState({ revisions })));
        this.addDisposable(this.revisions.value.subscribe((revisionsState) => this.setState({ revisionsState })));

        this.addDisposable(this.artifacts.start());

        this.addDisposable(this.artifacts.value.subscribe((artifacts) => this.setState({ artifacts })));
        this.addDisposable(this.artifacts.value.subscribe((artifactsState) => this.setState({ artifactsState })));
    }

    render() {
        const iconStyle = {
            verticalAlign: "bottom"
        };
        const icon = (
            <IconStyler white>
                <CodeFarmIcon
                    style={iconStyle}
                    width={ICON_SIZE.width}
                    height={ICON_SIZE.height}
                />
            </IconStyler>
        );

        const revisions = this.state.revisions.map((revision) => Immutable.fromJS({
            id: revision.get("_id"),
            time: moment(revision.get("statusSetAt")).unix(),
            item: revision.toJS(),
            Card: RevisionCard,
            props: {}
        }));

        const artifacts = this.state.artifacts.map((artifact) => Immutable.fromJS({
            id: artifact.get("_id"),
            time: moment(artifact.get("created")).unix(),
            item: artifact.toJS(),
            Card: ArtifactCard,
            props: {}
        }));

        return (

                <AppHeader
                    primaryText="Welcome to the Code Farm"
                    secondaryText="Grow your software, herd your revisions..."
                    icon={icon}
                />
            <Row style={{ margin: 16, marginTop: 32 }}>
                    <Column xs={12} md={4}>

                            This is the code farm, where your code and artifacts are tested, integrated and delivered.

                    </Column>
                    <Column xs={12} md={4}>

                        <Loading show={this.state.revisionsState === ObservableDataStates.LOADING}/>
                        <CardList list={Immutable.fromJS(revisions)} />
                    </Column>
                    <Column xs={12} md={4}>

                        <Loading show={this.state.artifactsState === ObservableDataStates.LOADING}/>
                        <CardList list={Immutable.fromJS(artifacts)} />
                    </Column>
                </Row>

        );
    }
}

export default IndexPage;
<commit_msg>UI: Fix artifact list on index page (#196)<commit_after>
import React from "react";
import moment from "moment";
import Immutable from "immutable";
import LightComponent from "ui-lib/light_component";
import AppHeader from "ui-components/app_header";
import { IconStyler, CodeFarmIcon } from "ui-components/app_icons";
import { Header, Row, Column, Loading } from "ui-components/layout";
import TypeList from "ui-observables/type_list";
import { States as ObservableDataStates } from "ui-lib/observable_data";
import { CardList, RevisionCard, ArtifactCard } from "ui-components/data_card";

const ICON_SIZE = {
    width: 312,
    height: 312
};

class IndexPage extends LightComponent {
    constructor(props) {
        super(props);

        this.revisions = new TypeList({
            type: "coderepo.revision",
            query: { status: { $ne: "abandoned" } },
            sortOn: "statusSetAt",
            limit: 10
        });

        this.artifacts = new TypeList({
            type: "artifactrepo.artifact",
            query: { state: "commited" },
            sortOn: "created",
            limit: 10
        });

        this.state = {
            revisions: this.revisions.value.getValue(),
            revisionsState: this.revisions.state.getValue(),
            artifacts: this.artifacts.value.getValue(),
            artifactsState: this.artifacts.state.getValue()
        };
    }

    componentDidMount() {
        this.addDisposable(this.revisions.start());

        this.addDisposable(this.revisions.value.subscribe((revisions) => this.setState({ revisions })));
        this.addDisposable(this.revisions.value.subscribe((revisionsState) => this.setState({ revisionsState })));

        this.addDisposable(this.artifacts.start());

        this.addDisposable(this.artifacts.value.subscribe((artifacts) => this.setState({ artifacts })));
        this.addDisposable(this.artifacts.value.subscribe((artifactsState) => this.setState({ artifactsState })));
    }

    render() {
        const iconStyle = {
            verticalAlign: "bottom"
        };
        const icon = (
            <IconStyler white>
                <CodeFarmIcon
                    style={iconStyle}
                    width={ICON_SIZE.width}
                    height={ICON_SIZE.height}
                />
            </IconStyler>
        );

        const revisions = this.state.revisions.map((revision) => Immutable.fromJS({
            id: revision.get("_id"),
            time: moment(revision.get("statusSetAt")).unix(),
            item: revision.toJS(),
            Card: RevisionCard,
            props: {}
        }));

        const artifacts = this.state.artifacts.map((artifact) => Immutable.fromJS({
            id: artifact.get("_id"),
            time: moment(artifact.get("created")).unix(),
            item: artifact.toJS(),
            Card: ArtifactCard,
            props: {}
        }));

        return (

                <AppHeader
                    primaryText="Welcome to the Code Farm"
                    secondaryText="Grow your software, herd your revisions..."
                    icon={icon}
                />
            <Row style={{ margin: 16, marginTop: 32 }}>
                    <Column xs={12} md={4}>

                            This is the code farm, where your code and artifacts are tested, integrated and delivered.

                    </Column>
                    <Column xs={12} md={4}>

                        <Loading show={this.state.revisionsState === ObservableDataStates.LOADING}/>
                        <CardList list={Immutable.fromJS(revisions)} />
                    </Column>
                    <Column xs={12} md={4}>

                        <Loading show={this.state.artifactsState === ObservableDataStates.LOADING}/>
                        <CardList list={Immutable.fromJS(artifacts)} />
                    </Column>
                </Row>

        );
    }
}

export default IndexPage;
<|endoftext|>


<commit_before>VISH.Quiz.Renderer = (function(V,$,undefined){
  var isQuizInPreview= false;

  var init = function(){
  };

  ////////////////////
  //renderer methods called from VISH.Renderer
  ///////////////////

  /**
   * Function to render a quiz inside an article (a slide)
   */
  var renderQuiz = function(quizType, quiz_element, zone_class, slide_id, zone){
    switch(quizType){
      case "multiplechoice":
        return _renderMcQuestion(quiz_element, zone_class, slide_id, zone);

        break;

      case "openQuestion":
        return _renderOpenquestion(element, template);
        break;
      case "truefalse":
        return _renderTrueFalseQuestion(quiz_element, zone_class, slide_id, zone);

        break;
      default:
        break;
    }
  };

  var _renderMcQuestion = function(quiz_element, zone_class, slide_id, zone){
      V.Debugging.log("_renderMcQuestion, and quiz choices received is:  " + JSON.stringify(quiz_element['options']['choices']));
      var ret = "
";
      ret += "
";
      ret += "
";
      ret += "
"+ quiz_element['question']+"
";
      ret += "<form class='mcquestion_form' action='"+quiz_element['posturl']+"' method='post'>";
      ret += "
";
      for(var i = 0; i<quiz_element['options']['choices'].length; i++){
        var next_index = String.fromCharCode("a".charCodeAt(0) + (i));
        if(VISH.Quiz.getQuizMode()=="answer"){
          ret += "
";
          ret += "<input class='mc_radio' type='radio' name='mc_radio' value='"+next_index+"'/>"+next_index+")
"+quiz_element.options['choices'][i]['container']+"
";
          ret += "
"
        }
        else {
          ret += "
";
          ret += ""+next_index+")
"+quiz_element.options['choices'][i]['container']+"
";
          ret += "
"
         }
        ret += "

";
        ret += "";
      }
      ret += "
";
      ret += "<input type='hidden' value='"+ zone +"' name='zone' />";
      ret += "<input type='hidden' value='"+quiz_element['quiz_id']+"' name='quiz_id' class='quizId' />";
      ret += "
";
      ret += "<input type='button' class='quiz_session_start_button' value='Start Quiz'/>";
      ret += "<input type='button' class='quiz_send_vote_button' value='Send'/>";
      ret += "<input type='button' class='quiz_session_options_button' value='Options'/>";
      ret += "
"; //close mch_input_wrapper
      ret += "</form>";
      ret += "
";//close mcquestion_body
      ret += "
";//close mcquestion_container
       ret += "
"; //close zoneclass quiz
      return ret;
  };

  var _renderOpenquestion = function(element, template){
    var ret = "<form action='"+element['posturl']+"' method='post' style='text-align:center;'>";
    ret += "Name:  ";
    ret += "<textarea id='pupil_name' rows='1' cols='50' class='question_name_input' placeholder='Write your name here'></textarea>";
    ret += "
 Question: "+element['question']+"?
";

    ret += "Answer: ";
    ret += "<textarea id='question_answer' rows='5' cols='50' class='question_answer' placeholder='Write your answer here'></textarea>";

    ret += "<button type='button' class='question_button'>Send</button>";

    return ret;
  };

  /**
   * Function to render a True False Question choice question form inside an article (a slide)
   * TODO Include in the VISH.Quiz?? ... think and ask Kike about it
   */

  var _renderTrueFalseQuestion = function(quiz_element, zone_class, slide_id, zone){

    var ret = "
";
    ret += "
";

    //ret += "<form class='truefalse_question_form' action='"+element['posturl']+"' method='post'>";
    ret+= "
";
    ret += quiz_element['question'];
    ret += "
";
    ret += "
 ";
    ret += "<form class='truefalse_form' action='"+quiz_element['posturl']+"' method='post'>";
    ret += "
";
       ret += "
";
          ret += "
True
";
          ret += "
False
";
        ret += "
";

 if(VISH.Quiz.getQuizMode()=="answer"){  //Just radio inputs to respond
    ret+= "
";
    ret += "<input class='truefalse_answer_radio_true' type='radio' name='truefalse' value='true'/>";
    ret += "<input class='truefalse_answer_radio_false' type='radio' name='truefalse' value='false'/>";
    ret += "
";

    }
  else { //Teacher view.  button to enable answers view or not (default view not show)
     ret+= "
";
     if( quiz_element['options']['answer']=="true") {
       ret += "<input class='truefalse_answer_radio_true' type='radio' name='truefalse' value='true' disabled='disabled' checked/>";
       ret += "<input class='truefalse_answer_radio_false' type='radio' name='truefalse' value='false' disabled='disabled'/>";
    }
    else if ( quiz_element['options']['answer']==="false") {
      ret += "<input class='truefalse_answer_radio_true' type='radio' name='truefalse' value='true' disabled='disabled'/>";
      ret += "<input class='truefalse_answer_radio_false' type='radio' name='truefalse' value='false' disabled='disabled' checked/>";

    }
  ret += "
";
    ret += "
";
    ret += "<input type='button' class='show_answers_button' value='Show Answer'/>";
    ret += "<input type='button' class='hide_answers_button' value='Hide Answer'/>";
    ret += "
";

  }

      ret += "
";
      //ret += "<input type='hidden' value='"+ zone +"' name='zone' />";
      ret += "<input type='hidden' value='"+quiz_element['quiz_id']+"' name='quiz_id' class='quizId' />";
      ret += "
";
      ret += "<input type='button' class='quiz_session_start_button' value='Start Quiz'/>";
      ret += "<input type='button' class='quiz_send_vote_button' value='Send'/>";
      ret += "<input type='button' class='quiz_session_options_button' value='Options'/>";
       ret += "
"; //close mch_input_wrapper
      ret += "</form>";
      ret += "
";//close mcquestion_body
      ret += "
";//close mcquestion_container
       ret += "
"; //close zoneclass quiz

    return ret;
  };

  return {
    init                              : init,
    renderQuiz                        : renderQuiz

  };

}) (VISH, jQuery);<commit_msg>Quiz: added quiztype in zone<commit_after>VISH.Quiz.Renderer = (function(V,$,undefined){
  var isQuizInPreview= false;

  var init = function(){
  };

  ////////////////////
  //renderer methods called from VISH.Renderer
  ///////////////////

  /**
   * Function to render a quiz inside an article (a slide)
   */
  var renderQuiz = function(quizType, quiz_element, zone_class, slide_id, zone){
    switch(quizType){
      case "multiplechoice":
        return _renderMcQuestion(quiz_element, zone_class, slide_id, zone);

        break;

      case "openQuestion":
        return _renderOpenquestion(element, template);
        break;
      case "truefalse":
        return _renderTrueFalseQuestion(quiz_element, zone_class, slide_id, zone);

        break;
      default:
        break;
    }
  };

  var _renderMcQuestion = function(quiz_element, zone_class, slide_id, zone){
      V.Debugging.log("_renderMcQuestion, and quiz choices received is:  " + JSON.stringify(quiz_element['options']['choices']));
      var ret = "
";
      ret += "
";
      ret += "
";
      ret += "
"+ quiz_element['question']+"
";
      ret += "<form class='mcquestion_form' action='"+quiz_element['posturl']+"' method='post'>";
      ret += "
";
      for(var i = 0; i<quiz_element['options']['choices'].length; i++){
        var next_index = String.fromCharCode("a".charCodeAt(0) + (i));
        if(VISH.Quiz.getQuizMode()=="answer"){
          ret += "
";
          ret += "<input class='mc_radio' type='radio' name='mc_radio' value='"+next_index+"'/>"+next_index+")
"+quiz_element.options['choices'][i]['container']+"
";
          ret += "
"
        }
        else {
          ret += "
";
          ret += ""+next_index+")
"+quiz_element.options['choices'][i]['container']+"
";
          ret += "
"
         }
        ret += "

";
        ret += "";
      }
      ret += "
";
      ret += "<input type='hidden' value='"+ zone +"' name='zone' />";
      ret += "<input type='hidden' value='"+quiz_element['quiz_id']+"' name='quiz_id' class='quizId' />";
      ret += "
";
      ret += "<input type='button' class='quiz_session_start_button' value='Start Quiz'/>";
      ret += "<input type='button' class='quiz_send_vote_button' value='Send'/>";
      ret += "<input type='button' class='quiz_session_options_button' value='Options'/>";
      ret += "
"; //close mch_input_wrapper
      ret += "</form>";
      ret += "
";//close mcquestion_body
      ret += "
";//close mcquestion_container
       ret += "
"; //close zoneclass quiz
      return ret;
  };

  var _renderOpenquestion = function(element, template){
    var ret = "<form action='"+element['posturl']+"' method='post' style='text-align:center;'>";
    ret += "Name:  ";
    ret += "<textarea id='pupil_name' rows='1' cols='50' class='question_name_input' placeholder='Write your name here'></textarea>";
    ret += "
 Question: "+element['question']+"?
";

    ret += "Answer: ";
    ret += "<textarea id='question_answer' rows='5' cols='50' class='question_answer' placeholder='Write your answer here'></textarea>";

    ret += "<button type='button' class='question_button'>Send</button>";

    return ret;
  };

  /**
   * Function to render a True False Question choice question form inside an article (a slide)
   * TODO Include in the VISH.Quiz?? ... think and ask Kike about it
   */

  var _renderTrueFalseQuestion = function(quiz_element, zone_class, slide_id, zone){

    var ret = "
";
    ret += "
";

    //ret += "<form class='truefalse_question_form' action='"+element['posturl']+"' method='post'>";
    ret+= "
";
    ret += quiz_element['question'];
    ret += "
";
    ret += "
 ";
    ret += "<form class='truefalse_form' action='"+quiz_element['posturl']+"' method='post'>";
    ret += "
";
       ret += "
";
          ret += "
True
";
          ret += "
False
";
        ret += "
";

 if(VISH.Quiz.getQuizMode()=="answer"){  //Just radio inputs to respond
    ret+= "
";
    ret += "<input class='truefalse_answer_radio_true' type='radio' name='truefalse' value='true'/>";
    ret += "<input class='truefalse_answer_radio_false' type='radio' name='truefalse' value='false'/>";
    ret += "
";

    }
  else { //Teacher view.  button to enable answers view or not (default view not show)
     ret+= "
";
     if( quiz_element['options']['answer']=="true") {
       ret += "<input class='truefalse_answer_radio_true' type='radio' name='truefalse' value='true' disabled='disabled' checked/>";
       ret += "<input class='truefalse_answer_radio_false' type='radio' name='truefalse' value='false' disabled='disabled'/>";
    }
    else if ( quiz_element['options']['answer']==="false") {
      ret += "<input class='truefalse_answer_radio_true' type='radio' name='truefalse' value='true' disabled='disabled'/>";
      ret += "<input class='truefalse_answer_radio_false' type='radio' name='truefalse' value='false' disabled='disabled' checked/>";

    }
  ret += "
";
    ret += "
";
    ret += "<input type='button' class='show_answers_button' value='Show Answer'/>";
    ret += "<input type='button' class='hide_answers_button' value='Hide Answer'/>";
    ret += "
";

  }

      ret += "
";
      //ret += "<input type='hidden' value='"+ zone +"' name='zone' />";
      ret += "<input type='hidden' value='"+quiz_element['quiz_id']+"' name='quiz_id' class='quizId' />";
      ret += "
";
      ret += "<input type='button' class='quiz_session_start_button' value='Start Quiz'/>";
      ret += "<input type='button' class='quiz_send_vote_button' value='Send'/>";
      ret += "<input type='button' class='quiz_session_options_button' value='Options'/>";
       ret += "
"; //close mch_input_wrapper
      ret += "</form>";
      ret += "
";//close mcquestion_body
      ret += "
";//close mcquestion_container
       ret += "
"; //close zoneclass quiz

    return ret;
  };

  return {
    init                              : init,
    renderQuiz                        : renderQuiz

  };

}) (VISH, jQuery);<|endoftext|>


<commit_before>
if (!('Request' in this))
    Request = function() {};

function CacheList() {
    this.caches = {};
}

CacheList.prototype._getCache = function(cache_name) {
    if (!(cache_name in this.caches))
        this.caches[cache_name] = new Cache(cache_name);
    return this.caches[cache_name];
};

CacheList.prototype.forEach = function(callback) {
    for (var name in this.caches) {
        callback(name, this.caches[name], this);
    }
};

CacheList.prototype.delete = function(name) {
    if (name in this.caches)
        delete this.caches.name;
};

CacheList.prototype.match = function(cache_name, url) {
    return this._getCache(cache_name).match(url);
};

CacheList.prototype.get = function(cache_name) {
    return this._getCache(cache_name);
};

CacheList.prototype.set = function(cache_name, cache) {
    if (cache.name != cache_name)
        throw "Cache names must match [polyfill restriction]";
    if (cache_name in this.caches &&
        this.caches[cache_name] !== cache)
        throw "Already have a cache named '" + cache_name + "'";

    this.caches[cache_name] = cache;
    return cache;
};

// translates a string or a request object into an object with a .url
// property
function _getRequest(urlOrRequest) {
    if (urlOrRequest.url) {
        urlOrRequest.url = absolutizeURI(location.toString(), urlOrRequest.url);
        return urlOrRequest;
    }
    var request = new SameOriginResponse();
    request.url = absolutizeURI(location.toString(), urlOrRequest);
    request.method = 'GET';
    return request;
}

// This differs slightly from the the explainer, in that the 'name' is
// passed as the first parameter - vastly simplified the implementation.
function Cache(name /*, url, url, ...*/) {
    var cache = this;
    var requestsOrUrls = Array.prototype.slice.call(arguments, 1);
    this.name = name;

    // These are promises we want to resolve before any future cache action.
    var pending = [];
    this.readyPromise = this._open().then(function(cache) {
        return cache._add(requestsOrUrls).then(function(addresults) {
            return addresults;
        });
    }).then(function(results) {
        // throw away the pending promises
        return cache;
    }).catch(function(e) {
        lasterr = e;
    });
}

// TODO - a basic cache consistency thing needs to be exposed here,
// since our promises may include network requests that may result in our gets/puts
// being executed slightly out of order from IDB itself.
//
// Consider:
// p1 = cache.add("http://google.com/");
// p2 = cache.match("http://google.com/");
//
// The add step may actually mean:
// networkFetch("http://google.com/").then(saveToIDB)
//
// But I think the effect we want is that p2 resolves after p1, which
// is how IDB works. Not sure.
//
// If this is how it should be implemented, then all outstanding
// requests need to be (functionally, if not actually) resolved before
// resolution of the next promise.
//
// Here is what needs to happen to make that work:
//
// 1) every time this api creats a new promise to write, it needs to
//    add it to a 'pending' list on Cache.
//
// 2) The first thing that such a promise needs to do when resolved is clear
//    itself from the pending promises list.
//
// 3) Every time ready() is called, we snapshot the outstanding
//    promises, and call Q.all() on them, probably returning that
//    here.
//
// [1] because promises are resolved with a separate resolver function, resolution doesn't technically even need to run until the first person calls then(), so
Cache.prototype.ready = function() {
    return this.readyPromise;
};

Cache.prototype._open = function () {
    var cache = this;
    if (!cache.db) {
        cache.db = new Promise(function(resolver) {
            var openReq = indexedDB.open("cache-" + cache.name, 1);
            openReq.onupgradeneeded = function(e) {
                var db = e.target.result;
                db.createObjectStore(cache.name);
            };
            openReq.onsuccess = function(e) {
                var db = cache.db = e.target.result;
                resolver.resolve(cache);
            };
            openReq.onerror = function(e) {
                resolver.reject("Error opening " + cache.name + ": " + e.name);
            };
        });
    }
    return cache.db;
};

// _get and _set are generic wrappers around idb, that assume the db is open and ready.
Cache.prototype._get = function(url) {
    var cache = this;
    url = _getRequest(url).url;
    return new Promise(function(resolver) {
        try {
            var req = cache.db.transaction(cache.name)
                    .objectStore(cache.name).get(url);
        } catch(ex) {
            resolver.reject("Couldn't load url '" + url + "': " + ex);
        }
        req.onsuccess = function(e) {
            if (!e.target.result) {
                resolver.reject("URL not found: " + url);
                return;
            }
            var result = {
                request: e.target.result.request,
                response: cache._makeResponse(e.target.result.response)
            };
            resolver.resolve(result);
        };
        req.onerror = function(e) {
            resolver.reject("Error in _get for " + url + ": " + e.name);
        };
    });
};

Cache.prototype._set = function(key, value) {
    var cache = this;
    return new Promise(function(resolver) {
        var req = cache.db.transaction(cache.name, 'readwrite')
                .objectStore(cache.name).put(value, key);
        req.onsuccess = function(e) {
            resolver.resolve(e.target.result);
        };
        req.onerror = function(e) {
            resolver.reject("Error in _get for " + key + ": " + e.name);
        };
    });
};

Cache.prototype._getKeys = function() {
    var cache = this;
    return new Promise(function(resolver) {
        var req = cache.db.transaction(cache.name)
                .objectStore(cache.name).openCursor();
        var resultkeys = [];
        req.onsuccess = function(e) {
            var cursor = e.target.result;
            if (cursor == null) {
                resolver.resolve(resultkeys);
                return;
            }
            resultkeys.push(cursor.key);
            cursor.continue();
        };
        req.onerror = function(e) {
            resolve.reject(e);
        };
    });
};

// Not sure what iteration looks like, so for now we just iterate here
Cache.prototype.getKeys = function() {
    return this.ready().then(function(cache) {
        return cache._getKeys();
    });
};

Cache.prototype._makeResponse = function (responseObj) {
    var response = new SameOriginResponse();
    for (var k in responseObj)
        response[k] = responseObj[k];
    var content_type;
    if ('setHeader' in response) {
        responseObj.headers.forEach(function(header) {
            if (header[0].toLowerCase() == 'content-type')
                content_type = header[1];
            response.setHeader(header[0], header[1]);
        });
    }
    if ('setBody' in response) {
        response.setBody(createBlob(response.body, content_type));
    }
    return response;
};

// Gives a response object suitable for passing to respondWith()
Cache.prototype.match = function(url) {
    var cache = this;
    return this.ready()
        .then(function(cache) {
            return cache._get(url);
        }).then(function(entry) {
            return entry.response;
        })
        .catch(function(ex) {
            var response = new SameOriginResponse();
            response.statusCode = 404;
            response.statusText = "Not Found: " + ex;
            lastex = ex;
            response.method = '';
            response.setBody("Not found in cache: " + ex, "text/plain");
            return response;
        });
};

// Gets the full entry, including a request and response object
Cache.prototype.get = function(url) {
    var cache = this;
    return this.ready()
        .then(function(cache) {
            return cache._get(url);
        });
};

// This returns a callback which binds the request to the response
Cache.prototype._setResponse = function(request) {
    var cache = this;
    var requestObj = {};
    for (var k in request) {
        if (typeof request[k] != 'function')
            requestObj[k] = request[k];
    }
    return function(response) {
        // the main object isn't clonable, but its subparts are
        var responseObj = {};
        for (var k in response) {
            if (typeof response[k] != 'function')
                responseObj[k] = response[k];
        }
        return cache._set(request.url,
                          { request: requestObj, response: responseObj });
    };
};

// Given a set of requests, fetch them and store them in the cache.
Cache.prototype._add = function(requests) {
    var pending = [];
    var cache = this;
    for (var i = 0; i < requests.length; ++i) {
        var request = _getRequest(requests[i]);
        pending.push(networkFetch(request.url)
                     .then(cache._setResponse(request)));
    }
    return Promise.every.apply(Promise, pending);
};

// Add one or more urls to the cache.
Cache.prototype.add = function(/* request, request, request, ...*/) {
    var requests = arguments;
    return this.ready().then(function(cache) {
        var result = cache._add(requests);
        if (requests.length == 1)
            return result[0];
        return result;
    });
};

Cache.prototype.addResponse = function(urlOrRequest, response) {
    var request = _getRequest(urlOrRequest);
    return this.ready().then(function(cache) {
        request = JSON.parse(JSON.stringify(request));
        response = JSON.parse(JSON.stringify(response));
        cache._set(request.url, { request: request, response: response });
    });
};
<commit_msg>fix blob creation of error message<commit_after>
if (!('Request' in this))
    Request = function() {};

function CacheList() {
    this.caches = {};
}

CacheList.prototype._getCache = function(cache_name) {
    if (!(cache_name in this.caches))
        this.caches[cache_name] = new Cache(cache_name);
    return this.caches[cache_name];
};

CacheList.prototype.forEach = function(callback) {
    for (var name in this.caches) {
        callback(name, this.caches[name], this);
    }
};

CacheList.prototype.delete = function(name) {
    if (name in this.caches)
        delete this.caches.name;
};

CacheList.prototype.match = function(cache_name, url) {
    return this._getCache(cache_name).match(url);
};

CacheList.prototype.get = function(cache_name) {
    return this._getCache(cache_name);
};

CacheList.prototype.set = function(cache_name, cache) {
    if (cache.name != cache_name)
        throw "Cache names must match [polyfill restriction]";
    if (cache_name in this.caches &&
        this.caches[cache_name] !== cache)
        throw "Already have a cache named '" + cache_name + "'";

    this.caches[cache_name] = cache;
    return cache;
};

// translates a string or a request object into an object with a .url
// property
function _getRequest(urlOrRequest) {
    if (urlOrRequest.url) {
        urlOrRequest.url = absolutizeURI(location.toString(), urlOrRequest.url);
        return urlOrRequest;
    }
    var request = new SameOriginResponse();
    request.url = absolutizeURI(location.toString(), urlOrRequest);
    request.method = 'GET';
    return request;
}

// This differs slightly from the the explainer, in that the 'name' is
// passed as the first parameter - vastly simplified the implementation.
function Cache(name /*, url, url, ...*/) {
    var cache = this;
    var requestsOrUrls = Array.prototype.slice.call(arguments, 1);
    this.name = name;

    // These are promises we want to resolve before any future cache action.
    var pending = [];
    this.readyPromise = this._open().then(function(cache) {
        return cache._add(requestsOrUrls).then(function(addresults) {
            return addresults;
        });
    }).then(function(results) {
        // throw away the pending promises
        return cache;
    }).catch(function(e) {
        lasterr = e;
    });
}

// TODO - a basic cache consistency thing needs to be exposed here,
// since our promises may include network requests that may result in our gets/puts
// being executed slightly out of order from IDB itself.
//
// Consider:
// p1 = cache.add("http://google.com/");
// p2 = cache.match("http://google.com/");
//
// The add step may actually mean:
// networkFetch("http://google.com/").then(saveToIDB)
//
// But I think the effect we want is that p2 resolves after p1, which
// is how IDB works. Not sure.
//
// If this is how it should be implemented, then all outstanding
// requests need to be (functionally, if not actually) resolved before
// resolution of the next promise.
//
// Here is what needs to happen to make that work:
//
// 1) every time this api creats a new promise to write, it needs to
//    add it to a 'pending' list on Cache.
//
// 2) The first thing that such a promise needs to do when resolved is clear
//    itself from the pending promises list.
//
// 3) Every time ready() is called, we snapshot the outstanding
//    promises, and call Q.all() on them, probably returning that
//    here.
//
// [1] because promises are resolved with a separate resolver function, resolution doesn't technically even need to run until the first person calls then(), so
Cache.prototype.ready = function() {
    return this.readyPromise;
};

Cache.prototype._open = function () {
    var cache = this;
    if (!cache.db) {
        cache.db = new Promise(function(resolver) {
            var openReq = indexedDB.open("cache-" + cache.name, 1);
            openReq.onupgradeneeded = function(e) {
                var db = e.target.result;
                db.createObjectStore(cache.name);
            };
            openReq.onsuccess = function(e) {
                var db = cache.db = e.target.result;
                resolver.resolve(cache);
            };
            openReq.onerror = function(e) {
                resolver.reject("Error opening " + cache.name + ": " + e.name);
            };
        });
    }
    return cache.db;
};

// _get and _set are generic wrappers around idb, that assume the db is open and ready.
Cache.prototype._get = function(url) {
    var cache = this;
    url = _getRequest(url).url;
    return new Promise(function(resolver) {
        try {
            var req = cache.db.transaction(cache.name)
                    .objectStore(cache.name).get(url);
        } catch(ex) {
            resolver.reject("Couldn't load url '" + url + "': " + ex);
        }
        req.onsuccess = function(e) {
            if (!e.target.result) {
                resolver.reject("URL not found: " + url);
                return;
            }
            var result = {
                request: e.target.result.request,
                response: cache._makeResponse(e.target.result.response)
            };
            resolver.resolve(result);
        };
        req.onerror = function(e) {
            resolver.reject("Error in _get for " + url + ": " + e.name);
        };
    });
};

Cache.prototype._set = function(key, value) {
    var cache = this;
    return new Promise(function(resolver) {
        var req = cache.db.transaction(cache.name, 'readwrite')
                .objectStore(cache.name).put(value, key);
        req.onsuccess = function(e) {
            resolver.resolve(e.target.result);
        };
        req.onerror = function(e) {
            resolver.reject("Error in _get for " + key + ": " + e.name);
        };
    });
};

Cache.prototype._getKeys = function() {
    var cache = this;
    return new Promise(function(resolver) {
        var req = cache.db.transaction(cache.name)
                .objectStore(cache.name).openCursor();
        var resultkeys = [];
        req.onsuccess = function(e) {
            var cursor = e.target.result;
            if (cursor == null) {
                resolver.resolve(resultkeys);
                return;
            }
            resultkeys.push(cursor.key);
            cursor.continue();
        };
        req.onerror = function(e) {
            resolve.reject(e);
        };
    });
};

// Not sure what iteration looks like, so for now we just iterate here
Cache.prototype.getKeys = function() {
    return this.ready().then(function(cache) {
        return cache._getKeys();
    });
};

// Creates a SameOriginRequest from an object that came out of IDB
Cache.prototype._makeResponse = function (responseObj) {
    var response = new SameOriginResponse();
    for (var k in responseObj)
        response[k] = responseObj[k];
    var content_type;
    if ('setHeader' in response) {
        responseObj.headers.forEach(function(header) {
            if (header[0].toLowerCase() == 'content-type')
                content_type = header[1];
            response.setHeader(header[0], header[1]);
        });
    }
    if ('setBody' in response) {
        response.setBody(createBlob(response.body, content_type));
    }
    return response;
};

// Gives a response object suitable for passing to respondWith()
Cache.prototype.match = function(url) {
    var cache = this;
    return this.ready()
        .then(function(cache) {
            return cache._get(url);
        }).then(function(entry) {
            return entry.response;
        })
        // not sure we want a 'catch' at all here, but the
        // current implementation of respondWith() doesn't really
        // deal with failure.
        .catch(function(ex) {
            var response = new SameOriginResponse();
            response.statusCode = 404;
            response.statusText = "Not Found: " + ex;
            lastex = ex;
            response.method = '';
            response.setBody(createBlob("Not found in cache: " + ex, "text/plain"));
            return response;
        });
};

// Gets the full entry, including a request and response object
Cache.prototype.get = function(url) {
    var cache = this;
    return this.ready()
        .then(function(cache) {
            return cache._get(url);
        });
};

// This returns a callback which binds the request to the response
Cache.prototype._setResponse = function(request) {
    var cache = this;
    var requestObj = {};
    for (var k in request) {
        if (typeof request[k] != 'function')
            requestObj[k] = request[k];
    }
    return function(response) {
        // the main object isn't clonable, but its subparts are
        var responseObj = {};
        for (var k in response) {
            if (typeof response[k] != 'function')
                responseObj[k] = response[k];
        }
        return cache._set(request.url,
                          { request: requestObj, response: responseObj });
    };
};

// Given a set of requests, fetch them and store them in the cache.
Cache.prototype._add = function(requests) {
    var pending = [];
    var cache = this;
    for (var i = 0; i < requests.length; ++i) {
        var request = _getRequest(requests[i]);
        pending.push(networkFetch(request.url)
                     .then(cache._setResponse(request)));
    }
    return Promise.every.apply(Promise, pending);
};

// Add one or more urls to the cache.
Cache.prototype.add = function(/* request, request, request, ...*/) {
    var requests = arguments;
    return this.ready().then(function(cache) {
        var result = cache._add(requests);
        if (requests.length == 1)
            return result[0];
        return result;
    });
};

Cache.prototype.addResponse = function(urlOrRequest, response) {
    var request = _getRequest(urlOrRequest);
    return this.ready().then(function(cache) {
        request = JSON.parse(JSON.stringify(request));
        response = JSON.parse(JSON.stringify(response));
        cache._set(request.url, { request: request, response: response });
    });
};
<|endoftext|>


<commit_before>const crypto = require('crypto')
const os = require('os')
const path = require('path')
const cp = require('child_process')
const fs = require('fs')

const _ = require('lodash/fp')

const logger = require('console-log-level')({level: 'info'})

module.exports = {
  es,
  writeSupervisorConfig,
  firewall,
  randomPass,
  fetchAndInstall,
  logger,
  isInstalledSoftware,
  writeFile
}

const BINARIES = {
  BTC: {
    url: 'https://bitcoin.org/bin/bitcoin-core-0.16.2/bitcoin-0.16.2-x86_64-linux-gnu.tar.gz',
    dir: 'bitcoin-0.16.2/bin'
  },
  ETH: {
    url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.8.13-225171a4.tar.gz',
    dir: 'geth-linux-amd64-1.8.13-225171a4'
  },
  ZEC: {
    url: 'https://z.cash/downloads/zcash-2.0.0-linux64.tar.gz',
    dir: 'zcash-2.0.0/bin'
  },
  DASH: {
    url: 'https://github.com/dashpay/dash/releases/download/v0.12.3.2/dashcore-0.12.3.2-x86_64-linux-gnu.tar.gz',
    dir: 'dashcore-0.12.3/bin'
  },
  LTC: {
    url: 'https://download.litecoin.org/litecoin-0.16.0/linux/litecoin-0.16.0-x86_64-linux-gnu.tar.gz',
    dir: 'litecoin-0.16.0/bin'
  },
  BCH: {
    url: 'https://download.bitcoinabc.org/0.18.0/linux/bitcoin-abc-0.18.0-x86_64-linux-gnu.tar.gz',
    dir: 'bitcoin-abc-0.18.0/bin',
    files: [['bitcoind', 'bitcoincashd'], ['bitcoin-cli', 'bitcoincash-cli']]
  }
}

function firewall (ports) {
  if (!ports || ports.length === 0) throw new Error('No ports supplied')
  const portsString = ports.join(',')
  es(`sudo ufw allow ${portsString}`)
}

function randomPass () {
  return crypto.randomBytes(32).toString('hex')
}

function es (cmd) {
  const env = {HOME: os.userInfo().homedir}
  const options = {encoding: 'utf8', env}
  const res = cp.execSync(cmd, options)
  logger.debug(res)
  return res.toString()
}

function writeSupervisorConfig (coinRec, cmd) {
  if (isInstalledSoftware(coinRec)) return

  const blockchain = coinRec.code

  const supervisorConfig = `[program:${blockchain}]
command=nice ${cmd}
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/${blockchain}.err.log
stdout_logfile=/var/log/supervisor/${blockchain}.out.log
environment=HOME="/root"
`

  writeFile(`/etc/supervisor/conf.d/${coinRec.code}.conf`, supervisorConfig)
}

function isInstalledSoftware (coinRec) {
  return fs.existsSync(`/etc/supervisor/conf.d/${coinRec.code}.conf`)
}

function fetchAndInstall (coinRec) {
  if (isInstalledSoftware(coinRec)) return

  const binaries = BINARIES[coinRec.cryptoCode]
  if (!binaries) throw new Error(`No such coin: ${coinRec.code}`)

  const url = binaries.url
  const downloadFile = path.basename(url)
  const binDir = binaries.dir

  es(`wget -q ${url}`)
  es(`tar -xzf ${downloadFile}`)

  if (_.isEmpty(binaries.files)) {
    es(`sudo cp ${binDir}/* /usr/local/bin`)
    return
  }

  _.forEach(([source, target]) => {
    es(`sudo cp ${binDir}/${source} /usr/local/bin/${target}`)
  }, binaries.files)
}

function writeFile (path, content) {
  try {
    fs.writeFileSync(path, content)
  } catch (err) {
    if (err.code === 'EEXIST') {
      logger.info(`${path} exists, skipping.`)
      return
    }

    throw err
  }
}
<commit_msg>Patch bitcoind-inhereted network vulnerability (#168)<commit_after>const crypto = require('crypto')
const os = require('os')
const path = require('path')
const cp = require('child_process')
const fs = require('fs')

const _ = require('lodash/fp')

const logger = require('console-log-level')({level: 'info'})

module.exports = {
  es,
  writeSupervisorConfig,
  firewall,
  randomPass,
  fetchAndInstall,
  logger,
  isInstalledSoftware,
  writeFile
}

const BINARIES = {
  BTC: {
    url: 'https://bitcoin.org/bin/bitcoin-core-0.16.3/bitcoin-0.16.3-x86_64-linux-gnu.tar.gz',
    dir: 'bitcoin-0.16.3/bin'
  },
  ETH: {
    url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.8.15-89451f7c.tar.gz',
    dir: 'geth-linux-amd64-1.8.15-89451f7c'
  },
  ZEC: {
    url: 'https://z.cash/downloads/zcash-2.0.0-linux64.tar.gz',
    dir: 'zcash-2.0.0/bin'
  },
  DASH: {
    url: 'https://github.com/dashpay/dash/releases/download/v0.12.3.3/dashcore-0.12.3.3-x86_64-linux-gnu.tar.gz',
    dir: 'dashcore-0.12.3/bin'
  },
  LTC: {
    url: 'https://download.litecoin.org/litecoin-0.16.3/linux/litecoin-0.16.3-x86_64-linux-gnu.tar.gz',
    dir: 'litecoin-0.16.3/bin'
  },
  BCH: {
    url: 'https://download.bitcoinabc.org/0.18.2/linux/bitcoin-abc-0.18.2-x86_64-linux-gnu.tar.gz',
    dir: 'bitcoin-abc-0.18.2/bin',
    files: [['bitcoind', 'bitcoincashd'], ['bitcoin-cli', 'bitcoincash-cli']]
  }
}

function firewall (ports) {
  if (!ports || ports.length === 0) throw new Error('No ports supplied')
  const portsString = ports.join(',')
  es(`sudo ufw allow ${portsString}`)
}

function randomPass () {
  return crypto.randomBytes(32).toString('hex')
}

function es (cmd) {
  const env = {HOME: os.userInfo().homedir}
  const options = {encoding: 'utf8', env}
  const res = cp.execSync(cmd, options)
  logger.debug(res)
  return res.toString()
}

function writeSupervisorConfig (coinRec, cmd) {
  if (isInstalledSoftware(coinRec)) return

  const blockchain = coinRec.code

  const supervisorConfig = `[program:${blockchain}]
command=nice ${cmd}
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/${blockchain}.err.log
stdout_logfile=/var/log/supervisor/${blockchain}.out.log
environment=HOME="/root"
`

  writeFile(`/etc/supervisor/conf.d/${coinRec.code}.conf`, supervisorConfig)
}

function isInstalledSoftware (coinRec) {
  return fs.existsSync(`/etc/supervisor/conf.d/${coinRec.code}.conf`)
}

function fetchAndInstall (coinRec) {
  if (isInstalledSoftware(coinRec)) return

  const binaries = BINARIES[coinRec.cryptoCode]
  if (!binaries) throw new Error(`No such coin: ${coinRec.code}`)

  const url = binaries.url
  const downloadFile = path.basename(url)
  const binDir = binaries.dir

  es(`wget -q ${url}`)
  es(`tar -xzf ${downloadFile}`)

  if (_.isEmpty(binaries.files)) {
    es(`sudo cp ${binDir}/* /usr/local/bin`)
    return
  }

  _.forEach(([source, target]) => {
    es(`sudo cp ${binDir}/${source} /usr/local/bin/${target}`)
  }, binaries.files)
}

function writeFile (path, content) {
  try {
    fs.writeFileSync(path, content)
  } catch (err) {
    if (err.code === 'EEXIST') {
      logger.info(`${path} exists, skipping.`)
      return
    }

    throw err
  }
}
<|endoftext|>


<commit_before>
/*!
 * Module dependencies.
 */

var _ = require('lodash');
var multiparty = require('multiparty');
var knox = require('knox');
var randomstring = require('randomstring');
var path = require('path');
var easyimage = require('easyimage');
var async = require('async');
var models = require('../models');
var Q = require('q');
var commandExists = require('command-exists');
var config = require('../../config/config');
var fs = require('fs-extra');

exports.index = function (req, res, next) {

    models.Session.findAll({
        order: '"createdAt" DESC'
    }).then(function(sessions) {
        res.render('session/index', {
            sessions: sessions
        });
    }).error(next);
};

exports.feed = function (req, res, next) {

    var sessionId = req.params.sid;
    var Session = models.Session;
    var VisualizationType = models.VisualizationType;
    var Visualization = models.Visualization;

    Q.all([
        Session
            .find({
                where: {
                    id: sessionId
                }
            }),
        Visualization
            .findAll({
                where: {
                    SessionId: sessionId
                }
            }),
        VisualizationType.findAll({
            order: '"name" ASC'
        })
    ]).spread(function(session, visualizations, vizTypes) {

        if(!session) {
            return res.status(404).send('Session not found');
        }

        _.each(visualizations, function(viz) {
            console.log(viz.images);
        });

        res.render('session/feed', {
            session: session,
            visualizations: visualizations,
            vizTypes: _.object(_.map(vizTypes, function(item) {
                return [item.name, item];
            }))
        });
    }).fail(next);
};

exports.update = function (req, res, next) {

    var sessionId = req.params.sid;
    var Session = models.Session;

    Session
        .update(req.body, {
            id: sessionId
        }).success(function(sessions) {
            return res.json(sessions);
        }).error(next);

};

exports.create = function(req, res, next) {

    models.Session
        .create(_.pick(req.body, 'name'))
        .then(function(session) {
            return res.json(session);
        }).error(next);
};

exports.getCreate = function(req, res, next) {
    models.Session
        .create()
        .then(function(session) {
            return res.redirect('/sessions/' + session.id + '/feed/');
        }).error(next);
};

exports.delete = function(req, res, next) {
    var sessionId = req.params.sid;

    models.Session
        .find(sessionId)
        .then(function(session) {
            session.destroy().success(function() {
                return res.json(session);
            }).error(next);
        }).error(next);
};

exports.getDelete = function(req, res, next) {

    var sessionId = req.params.sid;

    models.Session
        .find(sessionId)
        .then(function(session) {
            session.destroy().success(function() {
                return res.redirect('/sessions/');
            }).error(next);
        }).error(next);
};

exports.addData = function (req, res, next) {
    var sessionId = req.params.sid;

    var Visualization = models.Visualization;

    if(req.is('json')) {
        Visualization
            .create({
                data: req.body.data,
                type: req.body.type,
                SessionId: sessionId
            }).then(function(viz) {
                req.io.of('/sessions/' + sessionId)
                    .emit('viz', viz);
                return res.json(viz);
            }).error(next);
    } else {
        var form = new multiparty.Form();

        form.parse(req, function(err, fields, files) {

            _.each(files, function(f) {
                thumbnailAndUpload(f, sessionId, function(err, data) {

                    if(err) {
                        console.log('error in thumbnailAndUpload');
                        return res.status(500).send('error creating image thumbnail');
                    }

                    var imgData = data.imgData;

                    console.log(imgData);

                    var type = 'image';
                    if(fields.type) {
                        if(_.isArray(fields.type) || _.isObject(fields.type)) {
                            type = fields.type[0];
                        } else {
                            type = fields.type;
                        }
                    }

                    Visualization
                        .create({
                            type:  type,
                            images: [imgData],
                            SessionId: sessionId
                        }).then(function(viz) {
                            req.io.of('/sessions/' + sessionId)
                                .emit('viz', viz);

                            return res.json(viz);
                        }).error(next);
                });
            });
        });
    }
};

exports.appendData = function (req, res, next) {

    var sessionId = req.params.sid;
    var vizId = req.params.vid;
    var fieldName = req.params.field;

    models.Visualization
        .find(vizId)
        .then(function(viz) {
            if(req.is('json')) {

                if(fieldName) {

                    if(_.isArray(viz.data[fieldName])) {
                        viz.data[fieldName].push(req.body.data);
                    } else if(_.isUndefined(viz.data[fieldName])) {
                        console.log(fieldName);
                        viz.data[fieldName] = req.body.data;
                    } else {
                        console.log('unknown field');
                    }
                } else {
                    if(_.isArray(viz.data)) {
                        if(_.isArray(req.body.data)) {
                            viz.data = viz.data.concat(req.body.data);
                        } else {
                            viz.data.push(req.body.data);
                        }
                    } else if(_.isUndefined(viz.data)) {
                        viz.data = req.body.data;
                    } else {
                        console.log('unknown field');
                    }
                }

                viz
                    .save()
                    .then(function() {
                        return res.json(viz);
                    }).error(next);

                req.io.of('/sessions/' + sessionId)
                    .emit('append', {
                        vizId: viz.id,
                        data: req.body.data
                    });

            } else if(fieldName === 'images') {

                var form = new multiparty.Form();

                form.parse(req, function(err, fields, files) {
                    _.each(files, function(f) {
                        thumbnailAndUpload(f, sessionId, function(err, data) {

                            if(err) {
                                console.log('error in thumbnailAndUpload');
                                return res.status(500).send('error creating image thumbnail');
                            }
                            var imgData = data.imgData;
                            var s3Response = data.response;

                            if(viz.images) {
                                viz.images.push(imgData);
                            } else {
                                viz.images = [imgData];
                            }
                            viz
                                .save()
                                .then(function() {

                                    if(typeof s3Response === 'object') {
                                        res.statusCode = s3Response.statusCode;
                                        s3Response.pipe(res);
                                    } else {
                                        return res.status(data.response).send('');
                                    }
                                });

                            req.io.of('/sessions/' + sessionId)
                                .emit('append', {
                                    vizId: viz.id,
                                    data: imgData
                                });

                        });
                    });
                });
            } else {
                return next(500);
            }

        }).error(next);

};

exports.updateData = function (req, res, next) {

    var sessionId = req.params.sid;
    var vizId = req.params.vid;
    var fieldName = req.params.field;

    models.Visualization
        .find(vizId)
        .then(function(viz) {
            if(req.is('json')) {

                if(fieldName) {
                    viz.data[fieldName] = req.body.data;
                } else {
                    viz.data = req.body.data;
                }

                viz
                    .save()
                    .then(function() {
                        return res.json(viz);
                    }).error(next);

                req.io.of('/sessions/' + sessionId)
                    .emit('update', {
                        vizId: viz.id,
                        data: req.body.data
                    });

            } else if(fieldName === 'images') {

                var form = new multiparty.Form();

                form.parse(req, function(err, fields, files) {
                    _.each(files, function(f) {
                        thumbnailAndUpload(f, sessionId, function(err, data) {

                            if(err) {
                                console.log('error in thumbnailAndUpload');
                                return res.status(500).send('error creating image thumbnail');
                            }
                            var imgData = data.imgData;
                            var s3Response = data.response;

                            viz.images = [imgData];

                            viz
                                .save()
                                .then(function() {

                                    if(typeof s3Response === 'object') {
                                        res.statusCode = s3Response.statusCode;
                                        s3Response.pipe(res);
                                    } else {
                                        return res.status(data.response).send('');
                                    }
                                });

                            req.io.of('/sessions/' + sessionId)
                                .emit('update', {
                                    vizId: viz.id,
                                    data: imgData
                                });

                        });
                    });
                });
            } else {
                return next(500);
            }

        }).error(next);

};

var thumbnailAndUpload = function(f, sessionId, callback) {

    var staticUrl = '/';
    if(config.url) {
        staticUrl = 'http://' + config.url + '/';
    }

    // check if thumbnailing exists,
    // and if s3 creds exist
    var s3Exists = !!config.s3.key;
    var s3Client = null;

    if(s3Exists) {

        s3Client = knox.createClient({
            secure: false,
            key: process.env.S3_KEY,
            secret: process.env.S3_SECRET,
            bucket: process.env.S3_BUCKET,
        });
     }

    var maxWidth = 500;
    var maxHeight = 500;

    // Image file info
    var imgPath = f[0].path;
    var extension = path.extname(imgPath).toLowerCase();
    var filenameWithoutExtension = path.basename(imgPath, extension);

    var thumbnailPath;

    if(process.env.NODE_ENV === 'production') {
        thumbnailPath = path.resolve(__dirname + '/../../' + './tmp/' + filenameWithoutExtension + '_thumbnail' + extension);
    } else {
        thumbnailPath = path.dirname(imgPath) + filenameWithoutExtension + '_thumbnail' + extension;
    }

    // Upload paths for s3
    var uploadName = randomstring.generate();
    var destPath = '/sessions/' + sessionId + '/';
    var originalS3Path = destPath + uploadName;
    var thumbnailS3Path = destPath + uploadName + '_small';

    // s3 headers
    var headers = {
      'x-amz-acl': 'public-read',
    };
    if( extension === '.jpg' || extension === '.jpeg' ) {
        headers['Content-Type'] = 'image/jpeg';
    } else if (extension === '.png') {
        headers['Content-Type'] = 'image/png';
    }

    commandExists('identify', function(err, imageMagickExists) {

        if(imageMagickExists) {

            easyimage
                .info(imgPath)
                .then(function(file) {
                    var thumbWidth;
                    var thumbHeight;

                    console.log('outputing to: ' + thumbnailPath);

                    if(file.width > file.height) {
                        thumbWidth = Math.min(maxWidth, file.width);
                        thumbHeight = file.height * (thumbWidth / file.width);
                    } else {
                        thumbHeight = Math.min(maxHeight, file.height);
                        thumbWidth = file.width * (thumbHeight / file.height);
                    }

                    return easyimage.resize({
                        src: imgPath,
                        dst: thumbnailPath,
                        width: thumbWidth,
                        height: thumbHeight
                    });
                }).then(function() {

                    if(s3Exists) {
                        async.parallel([
                            function(callback) {
                                console.log('s3 exists');
                                console.log('uploading image');
                                console.log(imgPath + ':' + originalS3Path);
                                s3Client.putFile(imgPath, originalS3Path, headers, callback);
                            },
                            function(callback) {
                                console.log('uploading thumbnail');
                                console.log(thumbnailPath + ':' + thumbnailS3Path);
                                s3Client.putFile(thumbnailPath, thumbnailS3Path, headers, callback);
                            }
                        ], function(err, results) {

                            console.log('in herrrr')

                            var s3Response = results[0];

                            var imgURL = 'https://s3.amazonaws.com/' + process.env.S3_BUCKET + originalS3Path;
                            // var thumbURL = 'https://s3.amazonaws.com/' + process.env.S3_BUCKET + thumbnailS3Path;

                            var imgData = imgURL;

                            callback(null, {
                                response: s3Response,
                                imgData: imgData
                            });

                        });
                    } else {

                        console.log('S3 Credentials not found. Using local images');

                        async.parallel([
                            function(callback) {
                                var outpath = path.resolve(__dirname + '../../../public/images/uploads' + originalS3Path);
                                fs.copy(imgPath, outpath, callback);
                            },
                            function(callback) {
                                var outpath = path.resolve(__dirname + '../../../public/images/uploads' + thumbnailS3Path);
                                fs.copy(thumbnailPath, outpath, callback);
                            }
                        ], function(err) {
                            if(err) {
                                return callback(err);
                            }

                            return callback(null, {
                                response: 200,
                                imgData: staticUrl + 'images/uploads' + originalS3Path
                            });
                        });
                    }

                }, function(err) {
                    console.log(err);
                    callback(err);
                });
        } else {

            if(s3Exists) {
                async.parallel([
                    function(callback) {
                        console.log(imgPath + ':' + originalS3Path);
                        s3Client.putFile(imgPath, originalS3Path, headers, callback);
                    },
                    function(callback) {
                        console.log(thumbnailPath + ':' + thumbnailS3Path);
                        s3Client.putFile(thumbnailPath, thumbnailS3Path, headers, callback);
                    }
                ], function(err, results) {
                    var s3Response = results[0];

                    var imgURL = 'https://s3.amazonaws.com/' + process.env.S3_BUCKET + originalS3Path;
                    // var thumbURL = 'https://s3.amazonaws.com/' + process.env.S3_BUCKET + thumbnailS3Path;

                    var imgData = imgURL;

                    callback(null, {
                        response: s3Response,
                        imgData: imgData
                    });

                });
            } else {

                console.log('S3 Credentials not found. Using local images');

                async.parallel([
                    function(callback) {
                        var outpath = path.resolve(__dirname + '../../../public/images/uploads' + originalS3Path);
                        console.log(outpath);
                        fs.copy(imgPath, outpath, callback);
                    },
                    function(callback) {
                        var outpath = path.resolve(__dirname + '../../../public/images/uploads' + thumbnailS3Path);
                        console.log(outpath);
                        fs.copy(imgPath, outpath, callback);
                    }
                ], function(err) {
                    if(err) {
                        return callback(err);
                    }

                    return callback(null, {
                        response: 200,
                        imgData: staticUrl + 'images/uploads' + originalS3Path
                    });
                });
            }
        }
    })

};<commit_msg>special case streaming / non-streaming data concatenation<commit_after>
/*!
 * Module dependencies.
 */

var _ = require('lodash');
var multiparty = require('multiparty');
var knox = require('knox');
var randomstring = require('randomstring');
var path = require('path');
var easyimage = require('easyimage');
var async = require('async');
var models = require('../models');
var Q = require('q');
var commandExists = require('command-exists');
var config = require('../../config/config');
var fs = require('fs-extra');

exports.index = function (req, res, next) {

    models.Session.findAll({
        order: '"createdAt" DESC'
    }).then(function(sessions) {
        res.render('session/index', {
            sessions: sessions
        });
    }).error(next);
};

exports.feed = function (req, res, next) {

    var sessionId = req.params.sid;
    var Session = models.Session;
    var VisualizationType = models.VisualizationType;
    var Visualization = models.Visualization;

    Q.all([
        Session
            .find({
                where: {
                    id: sessionId
                }
            }),
        Visualization
            .findAll({
                where: {
                    SessionId: sessionId
                }
            }),
        VisualizationType.findAll({
            order: '"name" ASC'
        })
    ]).spread(function(session, visualizations, vizTypes) {

        if(!session) {
            return res.status(404).send('Session not found');
        }

        _.each(visualizations, function(viz) {
            console.log(viz.images);
        });

        res.render('session/feed', {
            session: session,
            visualizations: visualizations,
            vizTypes: _.object(_.map(vizTypes, function(item) {
                return [item.name, item];
            }))
        });
    }).fail(next);
};

exports.update = function (req, res, next) {

    var sessionId = req.params.sid;
    var Session = models.Session;

    Session
        .update(req.body, {
            id: sessionId
        }).success(function(sessions) {
            return res.json(sessions);
        }).error(next);

};

exports.create = function(req, res, next) {

    models.Session
        .create(_.pick(req.body, 'name'))
        .then(function(session) {
            return res.json(session);
        }).error(next);
};

exports.getCreate = function(req, res, next) {
    models.Session
        .create()
        .then(function(session) {
            return res.redirect('/sessions/' + session.id + '/feed/');
        }).error(next);
};

exports.delete = function(req, res, next) {
    var sessionId = req.params.sid;

    models.Session
        .find(sessionId)
        .then(function(session) {
            session.destroy().success(function() {
                return res.json(session);
            }).error(next);
        }).error(next);
};

exports.getDelete = function(req, res, next) {

    var sessionId = req.params.sid;

    models.Session
        .find(sessionId)
        .then(function(session) {
            session.destroy().success(function() {
                return res.redirect('/sessions/');
            }).error(next);
        }).error(next);
};

exports.addData = function (req, res, next) {
    var sessionId = req.params.sid;

    var Visualization = models.Visualization;

    if(req.is('json')) {
        Visualization
            .create({
                data: req.body.data,
                type: req.body.type,
                SessionId: sessionId
            }).then(function(viz) {
                req.io.of('/sessions/' + sessionId)
                    .emit('viz', viz);
                return res.json(viz);
            }).error(next);
    } else {
        var form = new multiparty.Form();

        form.parse(req, function(err, fields, files) {

            _.each(files, function(f) {
                thumbnailAndUpload(f, sessionId, function(err, data) {

                    if(err) {
                        console.log('error in thumbnailAndUpload');
                        return res.status(500).send('error creating image thumbnail');
                    }

                    var imgData = data.imgData;

                    console.log(imgData);

                    var type = 'image';
                    if(fields.type) {
                        if(_.isArray(fields.type) || _.isObject(fields.type)) {
                            type = fields.type[0];
                        } else {
                            type = fields.type;
                        }
                    }

                    Visualization
                        .create({
                            type:  type,
                            images: [imgData],
                            SessionId: sessionId
                        }).then(function(viz) {
                            req.io.of('/sessions/' + sessionId)
                                .emit('viz', viz);

                            return res.json(viz);
                        }).error(next);
                });
            });
        });
    }
};

exports.appendData = function (req, res, next) {

    var sessionId = req.params.sid;
    var vizId = req.params.vid;
    var fieldName = req.params.field;

    models.Visualization
        .find(vizId)
        .then(function(viz) {
            if(req.is('json')) {

                if(fieldName) {

                    if(_.isArray(viz.data[fieldName])) {

                        if(viz.type.indexOf('streaming') > -1) {
                            _.each(req.body.data, function(d, i) {
                                if(i < viz.data[fieldName].length) {
                                    viz.data[fieldName][i] = viz.data[fieldName][i].concat(d);
                                }
                            });
                        } else {
                            viz.data[fieldName].push(req.body.data);
                        }

                    } else if(_.isUndefined(viz.data[fieldName])) {
                        console.log(fieldName);
                        viz.data[fieldName] = req.body.data;
                    } else {
                        console.log('unknown field');
                    }
                } else {
                    if(_.isArray(viz.data)) {
                        if(_.isArray(req.body.data)) {

                            if(viz.type.indexOf('streaming') > -1) {
                                _.each(req.body.data, function(d, i) {

                                });
                            } else {
                                viz.data = viz.data.concat(req.body.data);
                            }

                        } else {
                            viz.data.push(req.body.data);
                        }
                    } else if(_.isUndefined(viz.data)) {
                        viz.data = req.body.data;
                    } else {
                        console.log('unknown field');
                    }
                }

                viz
                    .save()
                    .then(function() {
                        return res.json(viz);
                    }).error(next);

                req.io.of('/sessions/' + sessionId)
                    .emit('append', {
                        vizId: viz.id,
                        data: req.body.data
                    });

            } else if(fieldName === 'images') {

                var form = new multiparty.Form();

                form.parse(req, function(err, fields, files) {
                    _.each(files, function(f) {
                        thumbnailAndUpload(f, sessionId, function(err, data) {

                            if(err) {
                                console.log('error in thumbnailAndUpload');
                                return res.status(500).send('error creating image thumbnail');
                            }
                            var imgData = data.imgData;
                            var s3Response = data.response;

                            if(viz.images) {
                                viz.images.push(imgData);
                            } else {
                                viz.images = [imgData];
                            }
                            viz
                                .save()
                                .then(function() {

                                    if(typeof s3Response === 'object') {
                                        res.statusCode = s3Response.statusCode;
                                        s3Response.pipe(res);
                                    } else {
                                        return res.status(data.response).send('');
                                    }
                                });

                            req.io.of('/sessions/' + sessionId)
                                .emit('append', {
                                    vizId: viz.id,
                                    data: imgData
                                });

                        });
                    });
                });
            } else {
                return next(500);
            }

        }).error(next);

};

exports.updateData = function (req, res, next) {

    var sessionId = req.params.sid;
    var vizId = req.params.vid;
    var fieldName = req.params.field;

    models.Visualization
        .find(vizId)
        .then(function(viz) {
            if(req.is('json')) {

                if(fieldName) {
                    viz.data[fieldName] = req.body.data;
                } else {
                    viz.data = req.body.data;
                }

                viz
                    .save()
                    .then(function() {
                        return res.json(viz);
                    }).error(next);

                req.io.of('/sessions/' + sessionId)
                    .emit('update', {
                        vizId: viz.id,
                        data: req.body.data
                    });

            } else if(fieldName === 'images') {

                var form = new multiparty.Form();

                form.parse(req, function(err, fields, files) {
                    _.each(files, function(f) {
                        thumbnailAndUpload(f, sessionId, function(err, data) {

                            if(err) {
                                console.log('error in thumbnailAndUpload');
                                return res.status(500).send('error creating image thumbnail');
                            }
                            var imgData = data.imgData;
                            var s3Response = data.response;

                            viz.images = [imgData];

                            viz
                                .save()
                                .then(function() {

                                    if(typeof s3Response === 'object') {
                                        res.statusCode = s3Response.statusCode;
                                        s3Response.pipe(res);
                                    } else {
                                        return res.status(data.response).send('');
                                    }
                                });

                            req.io.of('/sessions/' + sessionId)
                                .emit('update', {
                                    vizId: viz.id,
                                    data: imgData
                                });

                        });
                    });
                });
            } else {
                return next(500);
            }

        }).error(next);

};

var thumbnailAndUpload = function(f, sessionId, callback) {

    var staticUrl = '/';
    if(config.url) {
        staticUrl = 'http://' + config.url + '/';
    }

    // check if thumbnailing exists,
    // and if s3 creds exist
    var s3Exists = !!config.s3.key;
    var s3Client = null;

    if(s3Exists) {

        s3Client = knox.createClient({
            secure: false,
            key: process.env.S3_KEY,
            secret: process.env.S3_SECRET,
            bucket: process.env.S3_BUCKET,
        });
     }

    var maxWidth = 500;
    var maxHeight = 500;

    // Image file info
    var imgPath = f[0].path;
    var extension = path.extname(imgPath).toLowerCase();
    var filenameWithoutExtension = path.basename(imgPath, extension);

    var thumbnailPath;

    if(process.env.NODE_ENV === 'production') {
        thumbnailPath = path.resolve(__dirname + '/../../' + './tmp/' + filenameWithoutExtension + '_thumbnail' + extension);
    } else {
        thumbnailPath = path.dirname(imgPath) + filenameWithoutExtension + '_thumbnail' + extension;
    }

    // Upload paths for s3
    var uploadName = randomstring.generate();
    var destPath = '/sessions/' + sessionId + '/';
    var originalS3Path = destPath + uploadName;
    var thumbnailS3Path = destPath + uploadName + '_small';

    // s3 headers
    var headers = {
      'x-amz-acl': 'public-read',
    };
    if( extension === '.jpg' || extension === '.jpeg' ) {
        headers['Content-Type'] = 'image/jpeg';
    } else if (extension === '.png') {
        headers['Content-Type'] = 'image/png';
    }

    commandExists('identify', function(err, imageMagickExists) {

        if(imageMagickExists) {

            easyimage
                .info(imgPath)
                .then(function(file) {
                    var thumbWidth;
                    var thumbHeight;

                    console.log('outputing to: ' + thumbnailPath);

                    if(file.width > file.height) {
                        thumbWidth = Math.min(maxWidth, file.width);
                        thumbHeight = file.height * (thumbWidth / file.width);
                    } else {
                        thumbHeight = Math.min(maxHeight, file.height);
                        thumbWidth = file.width * (thumbHeight / file.height);
                    }

                    return easyimage.resize({
                        src: imgPath,
                        dst: thumbnailPath,
                        width: thumbWidth,
                        height: thumbHeight
                    });
                }).then(function() {

                    if(s3Exists) {
                        async.parallel([
                            function(callback) {
                                console.log('s3 exists');
                                console.log('uploading image');
                                console.log(imgPath + ':' + originalS3Path);
                                s3Client.putFile(imgPath, originalS3Path, headers, callback);
                            },
                            function(callback) {
                                console.log('uploading thumbnail');
                                console.log(thumbnailPath + ':' + thumbnailS3Path);
                                s3Client.putFile(thumbnailPath, thumbnailS3Path, headers, callback);
                            }
                        ], function(err, results) {
                            var s3Response = results[0];

                            var imgURL = 'https://s3.amazonaws.com/' + process.env.S3_BUCKET + originalS3Path;
                            // var thumbURL = 'https://s3.amazonaws.com/' + process.env.S3_BUCKET + thumbnailS3Path;

                            var imgData = imgURL;

                            callback(null, {
                                response: s3Response,
                                imgData: imgData
                            });

                        });
                    } else {

                        console.log('S3 Credentials not found. Using local images');

                        async.parallel([
                            function(callback) {
                                var outpath = path.resolve(__dirname + '../../../public/images/uploads' + originalS3Path);
                                fs.copy(imgPath, outpath, callback);
                            },
                            function(callback) {
                                var outpath = path.resolve(__dirname + '../../../public/images/uploads' + thumbnailS3Path);
                                fs.copy(thumbnailPath, outpath, callback);
                            }
                        ], function(err) {
                            if(err) {
                                return callback(err);
                            }

                            return callback(null, {
                                response: 200,
                                imgData: staticUrl + 'images/uploads' + originalS3Path
                            });
                        });
                    }

                }, function(err) {
                    console.log(err);
                    callback(err);
                });
        } else {

            if(s3Exists) {
                async.parallel([
                    function(callback) {
                        console.log(imgPath + ':' + originalS3Path);
                        s3Client.putFile(imgPath, originalS3Path, headers, callback);
                    },
                    function(callback) {
                        console.log(thumbnailPath + ':' + thumbnailS3Path);
                        s3Client.putFile(thumbnailPath, thumbnailS3Path, headers, callback);
                    }
                ], function(err, results) {
                    var s3Response = results[0];

                    var imgURL = 'https://s3.amazonaws.com/' + process.env.S3_BUCKET + originalS3Path;
                    // var thumbURL = 'https://s3.amazonaws.com/' + process.env.S3_BUCKET + thumbnailS3Path;

                    var imgData = imgURL;

                    callback(null, {
                        response: s3Response,
                        imgData: imgData
                    });

                });
            } else {

                console.log('S3 Credentials not found. Using local images');

                async.parallel([
                    function(callback) {
                        var outpath = path.resolve(__dirname + '../../../public/images/uploads' + originalS3Path);
                        console.log(outpath);
                        fs.copy(imgPath, outpath, callback);
                    },
                    function(callback) {
                        var outpath = path.resolve(__dirname + '../../../public/images/uploads' + thumbnailS3Path);
                        console.log(outpath);
                        fs.copy(imgPath, outpath, callback);
                    }
                ], function(err) {
                    if(err) {
                        return callback(err);
                    }

                    return callback(null, {
                        response: 200,
                        imgData: staticUrl + 'images/uploads' + originalS3Path
                    });
                });
            }
        }
    })

};<|endoftext|>


<commit_before><commit_msg>[FIX] point_of_sale: get tip product if needed<commit_after><|endoftext|>


<commit_before>var PERFUSE = (function() {
    // Initialize some private variables.
    var spawn = require('child_process').spawn,
        cmd = spawn('npm', ['link']);
    var os = require('os');
    var express = require('express');
    var route = function (app, regex, prefix) {
        app.get(regex, function (req, res) {
          var type = req.params[0];
          var path = req.params[1];
          var file = prefix + type + '/' + path
          res.sendfile(file);
        });
    }

    // Return object encapsulating public variables.
    return {
        // Initialize some public constants.
        MASTER: 'perfuse-master', // Master's hostname
        WS_PORT: '8080',          // Port num to use for websockets
        REQ_PORT: '3000',         // Port num to use for pub requests
        RES_PORT: '3001',         // Port num to use for pull responses

        // Initialize some public variables.
        app: express(),
        zmq: require('zmq'),
        hostname: os.hostname(),
        web_sock_server: require('ws').Server,
        web_sock: null,
        cmd: cmd
    }
}());

PERFUSE.cmd.on('close', function (code) {
  console.log('child process exited with code ' + code);
  if (code === 0) {
    if (PERFUSE.hostname == PERFUSE.MASTER) {
        console.log('Master running');

        // Serve main page.
        PERFUSE.app.get('/', function(req, res){
            res.sendfile('index.html');
        });

        // Serve js, css, and image files.
        PERFUSE.app.get(/^\/(styles|images|scripts|fonts)\/(.*)/, function (req, res) {
            var type = req.params[0];
            var path = req.params[1];
            var file = '/src/' + type + '/' + path
            res.sendfile(file);
        });

        // Start web server listening on port 80.
        PERFUSE.app.listen(80);
        console.log('Listening on port 80');

        // Init ZeroMQ pub socket for fanning out requests, and
        // pull socket for receiving point-to-point responses.
        var sock_send = PERFUSE.zmq.socket('pub');
        sock_send.bindSync('tcp://*:' + PERFUSE.REQ_PORT);
        var sock_recv = PERFUSE.zmq.socket('pull');
        sock_recv.bindSync('tcp://*:' + PERFUSE.RES_PORT);

        // Define behavior for handling test responses.
        sock_recv.on('message', function(msg){
            try {
                var ev = JSON.parse(msg);
                if (ev.type == 'perf') {
                    console.log('event received from slave: ' + msg);
                    // We received a perf test response from a slave. If we
                    // have a websockets connection, forward the result to
                    // the client so that it can be presented to the user.
                    if (PERFUSE.web_sock) {
                        try {
                            PERFUSE.web_sock.send(msg.toString());
                        } catch(e) {
                            console.log("error " + e);
                        }
                    }
                } else {
                    console.log('unknown event received from slave: ' + msg);
                }
            } catch(e) {
                console.log("error " + e);
            }
        });

        // Open a server side websocket connection.
        wss = new PERFUSE.web_sock_server({port: PERFUSE.WS_PORT});

        // Define behavior for handling websocket connection requests.
        wss.on('connection', function(ws) {
            console.log('new websocket connected');
            PERFUSE.web_sock = ws;
            // Define behavior for receiving websocket messages.
            ws.on('message', function(msg) {
                try {
                    console.log('received from ws client: ' + msg);
                    m = JSON.parse(msg);
                    msg = JSON.stringify(m);
                    try {
                        // Perf test request received. Distribute too all slaves
                        // via the ZeroMQ pub socket.
                        sock_send.send(msg);
                    } catch(e) {
                        console.log("error " + e);
                    }
                } catch(e) {
                    console.log("error " + e);
                }
            });

            // Define behavior for handling closed websocket connection.
            ws.on('close', function(ws) {
                console.log('websocket disconnected');
                PERFUSE.web_sock = null;
            });
        });
    }
});
<commit_msg>syntax error fix to server.js for step 4<commit_after>var PERFUSE = (function() {
    // Initialize some private variables.
    var spawn = require('child_process').spawn,
        cmd = spawn('npm', ['link']);
    var os = require('os');
    var express = require('express');
    var route = function (app, regex, prefix) {
        app.get(regex, function (req, res) {
          var type = req.params[0];
          var path = req.params[1];
          var file = prefix + type + '/' + path
          res.sendfile(file);
        });
    }

    // Return object encapsulating public variables.
    return {
        // Initialize some public constants.
        MASTER: 'perfuse-master', // Master's hostname
        WS_PORT: '8080',          // Port num to use for websockets
        REQ_PORT: '3000',         // Port num to use for pub requests
        RES_PORT: '3001',         // Port num to use for pull responses

        // Initialize some public variables.
        app: express(),
        zmq: require('zmq'),
        hostname: os.hostname(),
        web_sock_server: require('ws').Server,
        web_sock: null,
        cmd: cmd
    }
}());

PERFUSE.cmd.on('close', function (code) {
    console.log('child process exited with code ' + code);
    if (code !== 0) {
        console.log('error running prep command');
        return;
    }
    if (PERFUSE.hostname == PERFUSE.MASTER) {
        console.log('Master running');

        // Serve main page.
        PERFUSE.app.get('/', function(req, res){
            res.sendfile('index.html');
        });

        // Serve js, css, and image files.
        PERFUSE.app.get(/^\/(styles|images|scripts|fonts)\/(.*)/, function (req, res) {
            var type = req.params[0];
            var path = req.params[1];
            var file = '/src/' + type + '/' + path
            res.sendfile(file);
        });

        // Start web server listening on port 80.
        PERFUSE.app.listen(80);
        console.log('Listening on port 80');

        // Init ZeroMQ pub socket for fanning out requests, and
        // pull socket for receiving point-to-point responses.
        var sock_send = PERFUSE.zmq.socket('pub');
        sock_send.bindSync('tcp://*:' + PERFUSE.REQ_PORT);
        var sock_recv = PERFUSE.zmq.socket('pull');
        sock_recv.bindSync('tcp://*:' + PERFUSE.RES_PORT);

        // Define behavior for handling test responses.
        sock_recv.on('message', function(msg){
            try {
                var ev = JSON.parse(msg);
                if (ev.type == 'perf') {
                    console.log('event received from slave: ' + msg);
                    // We received a perf test response from a slave. If we
                    // have a websockets connection, forward the result to
                    // the client so that it can be presented to the user.
                    if (PERFUSE.web_sock) {
                        try {
                            PERFUSE.web_sock.send(msg.toString());
                        } catch(e) {
                            console.log("error " + e);
                        }
                    }
                } else {
                    console.log('unknown event received from slave: ' + msg);
                }
            } catch(e) {
                console.log("error " + e);
            }
        });

        // Open a server side websocket connection.
        wss = new PERFUSE.web_sock_server({port: PERFUSE.WS_PORT});

        // Define behavior for handling websocket connection requests.
        wss.on('connection', function(ws) {
            console.log('new websocket connected');
            PERFUSE.web_sock = ws;
            // Define behavior for receiving websocket messages.
            ws.on('message', function(msg) {
                try {
                    console.log('received from ws client: ' + msg);
                    m = JSON.parse(msg);
                    msg = JSON.stringify(m);
                    try {
                        // Perf test request received. Distribute too all slaves
                        // via the ZeroMQ pub socket.
                        sock_send.send(msg);
                    } catch(e) {
                        console.log("error " + e);
                    }
                } catch(e) {
                    console.log("error " + e);
                }
            });

            // Define behavior for handling closed websocket connection.
            ws.on('close', function(ws) {
                console.log('websocket disconnected');
                PERFUSE.web_sock = null;
            });
        });
    }
});
<|endoftext|>


<commit_before>import VueCharts from 'vue-chartjs';

// ====

let props = {
  data: {
    type: Object,
    require: true
  },

  options: {
    type: Object,
    require: true
  }
};

const bar = VueCharts.Bar.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, {
      responsive: true,
      maintainAspectRatio: false
    });
  }
});

const line = VueCharts.Line.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, {
      responsive: true,
      maintainAspectRatio: false
    });
  }
});

const doughnut = VueCharts.Doughnut.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, {
      responsive: true,
      maintainAspectRatio: false
    });
  }
});

const pie = VueCharts.Pie.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, {
      responsive: true,
      maintainAspectRatio: false
    });
  }
});

const bubble = VueCharts.Bubble.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, {
      responsive: true,
      maintainAspectRatio: false
    });
  }
});

// ====

export default {
  bar,
  line,
  doughnut,
  pie,
  bubble
};<commit_msg>Realiza o bind das props através do componente.<commit_after>import VueCharts from 'vue-chartjs';

// ====

let props = {
  data: {
    type: Object,
    require: true
  },

  options: {
    type: Object,
    require: true
  }
};

const bar = VueCharts.Bar.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, this.props);
  }
});

const line = VueCharts.Line.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, this.props);
  }
});

const doughnut = VueCharts.Doughnut.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, this.props);
  }
});

const pie = VueCharts.Pie.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, this.props);
  }
});

const bubble = VueCharts.Bubble.extend({
  props: props,

  mounted () {
    this.renderChart(this.data, this.props);
  }
});

// ====

export default {
  bar,
  line,
  doughnut,
  pie,
  bubble
};<|endoftext|>