<commit_before>/**
 * Created by bo on 4/17/16.
 */
/**
 * Upload the file sending it via Ajax at the Spring Boot server.
 */
var sessions = [];

var _deleteCurrentSubmission = function() {
    $.ajax({
        url: baseApp + "/submission/delete",
        type: "post",
        data: {},
        success: function () {
            console.log('submission deleted');
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
        }
    });
};

function uploadFile() {

    var isSessionNameDefined = ($('#upload-session-input').val() !== "");
    var isDataSelected = ($('#upload-file-input').val() !== "");
    var isMappingSelected = ($('#upload-mapping-input').val() !== "");

    SESSIONNAME = $('#upload-session-input').val();
    var sessionnames = [];
    for (var i = 0; i < sessions.length; i++) {
        sessionnames.push(sessions[i].name);
    }

    if (sessionnames.indexOf(SESSIONNAME) !== -1) isSessionNameDefined = false;

    $("#message-board").empty();

    var mappingFileUpload = function () {
        if (isMappingSelected) {
            //upload the mapping file and direct to mapping view, also enable the mapping button by MAPPING_FILE_ENABLED = true;
            // MAPPING_FILE_ENABLED = true;
            // var upload_mapping_data = new FormData($("#upload-mapping-form")[0]);
            // $.ajax({
            //     headers: {
            //         'Accept': 'application/json',
            //         'Content-Type': 'application/json'
            //     },
            //     url: baseApp+"/upload/mapping",
            //     type: "POST",
            //     data: upload_mapping_data,
            //     processData: false, // Don't process the files
            //     // contentType: false,
            //     cache: false,
            //     dataType: 'json',
            //     success: function (feedback) {
            //         // Handle upload success
            //         var info = 'Mapping succesfully uploaded';
            //         $("#message-board").append(info);
            //         isMappingUploaded = true;
            //         if (!isDirected && isDataUploaded) {
            //             // window.location.href = "/mapping");
            //             console.log(feedback);
            //         }
            //     },
            //     error: function (jqXHR, textStatus, errorThrown) {
            //         console.log("Mapping upload to the server failed. HTTP status code:" + jqXHR.status + " " + errorThrown);
            //         // Handle upload error
            //         var info = 'Mapping not uploaded';
            //         $("#message-board").append(info);
            //         isMappingUploaded = false;
            //     }
            // });
            // window.setTimeout(function () {
            //     $("#mapping-alert").fadeTo(500, 0).slideUp(500, function () {
            //         $(this).empty();
            //     });
            // }, 3000);
        }
        else {
            //direct to mapping view
            window.location.href = baseApp + "/views/mapping";
        }
    }

    var dataFileUpload = function () {
        $.ajax({
            url: baseApp + "/upload/data",
            type: "POST",
            data: new FormData($("#upload-file-form")[0]),
            enctype: 'multipart/form-data',
            processData: false,
            contentType: false,
            success: function (fileFormatErrors) {
                if (fileFormatErrors.length === 0) {
                    // Handle upload success
                    mappingFileUpload();

                } else {
                    var info = '

';
                    fileFormatErrors.forEach(function (error) {
                        var errDiv = '
' + error.message + '
';
                        info += errDiv;
                    });
                    info += '

';
                    $("#message-board").append(info);

                    //since this is format error, we delete the just created submission
                    _deleteCurrentSubmission();
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                // Handle upload error
                var message = 'Data upload failed. Please check the data format, which should be a plain, tab-delimited file. The size of the file should be less than 10MB. ';
                var info = '
' + message + '
';
                $("#message-board").append(info);
                console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
               _deleteCurrentSubmission();
            }
        });
    };

    if (isSessionNameDefined && isDataSelected) {
        $.ajax({
            url: baseApp + "/submission/create",
            type: "post",
            data: {name: SESSIONNAME},
            success: dataFileUpload,
            error: function (jqXHR, textStatus, errorThrown) {
                console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
            }
        });
    }

    if (!isSessionNameDefined || !isDataSelected) {
        $("#message-board").empty();
        if (!isSessionNameDefined) {
            var info = 'Pleaes give your new submission a unique name. ';
            $("#message-board").append(info);
        }
        if (!isDataSelected) {
            var info = 'Please select a data file to upload. ';
            $("#message-board").append(info);
        }
    }

} //function uploadFile

function retrieveSessions() {
    $.ajax({
        url: baseApp + "/submission/all",
        type: "get",
        success: handle_session_retrieval_all,
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
            // if(jqXHR.status == 401) {
            //     window.location.href = baseApp+"/views/data";
            // }
        }
    });

}

function handle_session_retrieval_all(_sessions) {
    sessions = _sessions;
    $("#data-proceed-btn").attr("disabled", false);
    var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    $('#old_upload_section').append('

');
    for (var i = 0; i < _sessions.length; i++) {
        var s = _sessions[i];
        var btnid = "s" + (i + 1);
        var d = new Date(s.savedDate);
        var sessionHTML = '
' +
            '<button type="button" class="btn btn-primary" id="' + btnid + '" session_index=' + i + '>' + s.name + '</button>' +
            '
saved on: ' + monthNames[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear() + '
' +
            '<button type="button" class="btn btn-danger" id="removal_' + btnid + '" session_index=' + i + '>Remove this submission</button>
';
        $(sessionHTML).insertAfter("#anchor_old_sessions");
        // $('#session_container').append(sessionHTML);
        $('#' + btnid).click(handle_session_retrieval);
        $('#removal_' + btnid).click(handle_session_removal);
    }//for
}//function handle_session_retrieval_all

function handle_session_retrieval() {
    var ind = $(this).attr('session_index');
    var session = sessions[ind];
    var sid = session.id;
    //set the current session
    $.ajax({
        url: baseApp + "/submission/select",
        type: "get",
        data: {sessionId: sid},
        success: function (data) {
            var page;
            //direct user to the selected session
            switch (session.step) {
                case "MAPPING":
                    page = "mapping";
                    break;
                case "FEEDBACK_DATA":
                    page = "feedback-data";
                    break;
                case "SUBJECTS":
                    page = "subjects";
                    break;
                case "FEEDBACK_SUBJECTS":
                    page = "feedback-subjects";
                    break;
                case "EVENTS":
                    page = "events";
                    break;
                case "FEEDBACK_EVENTS":
                    page = "feedback-events";
                    break;
                case "OVERVIEW":
                    page = "final";
                    break;
                default:
                    page = "mapping";
            }
            window.location.href = baseApp + "/views/" + page;
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
        }
    });
}//function handle_session_retrieval

function handle_session_removal() {
    var ind = $(this).attr('session_index');
    var session = sessions[ind];
    var sid = session.id;
    $.ajax({
        url: baseApp + "/submission/deleteSession",
        type: "post",
        data: {id: sid},
        success: function (data) {
            console.log('deleted session ' + sid);
            $('#session_well_' + ind).remove();
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
        }
    });
}

function backBtnHandler() {
    window.history.back();
}

$(document).ready(function () {
    $("#data-proceed-btn").attr("disabled", "disabled");

    //retrieve user name
    $.ajax({
        url: baseApp + "/submission/username",
        type: "get",
        success: function (data) {
            USERNAME = data;
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
        }
    });

    retrieveSessions();
});
<commit_msg>Add offenders to the messages in the data upload<commit_after>/**
 * Created by bo on 4/17/16.
 */
/**
 * Upload the file sending it via Ajax at the Spring Boot server.
 */
var sessions = [];

var _deleteCurrentSubmission = function() {
    $.ajax({
        url: baseApp + "/submission/delete",
        type: "post",
        data: {},
        success: function () {
            console.log('submission deleted');
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
        }
    });
};

function uploadFile() {

    var isSessionNameDefined = ($('#upload-session-input').val() !== "");
    var isDataSelected = ($('#upload-file-input').val() !== "");
    var isMappingSelected = ($('#upload-mapping-input').val() !== "");

    SESSIONNAME = $('#upload-session-input').val();
    var sessionnames = [];
    for (var i = 0; i < sessions.length; i++) {
        sessionnames.push(sessions[i].name);
    }

    if (sessionnames.indexOf(SESSIONNAME) !== -1) isSessionNameDefined = false;

    $("#message-board").empty();

    var mappingFileUpload = function () {
        if (isMappingSelected) {
            //upload the mapping file and direct to mapping view, also enable the mapping button by MAPPING_FILE_ENABLED = true;
            // MAPPING_FILE_ENABLED = true;
            // var upload_mapping_data = new FormData($("#upload-mapping-form")[0]);
            // $.ajax({
            //     headers: {
            //         'Accept': 'application/json',
            //         'Content-Type': 'application/json'
            //     },
            //     url: baseApp+"/upload/mapping",
            //     type: "POST",
            //     data: upload_mapping_data,
            //     processData: false, // Don't process the files
            //     // contentType: false,
            //     cache: false,
            //     dataType: 'json',
            //     success: function (feedback) {
            //         // Handle upload success
            //         var info = 'Mapping succesfully uploaded';
            //         $("#message-board").append(info);
            //         isMappingUploaded = true;
            //         if (!isDirected && isDataUploaded) {
            //             // window.location.href = "/mapping");
            //             console.log(feedback);
            //         }
            //     },
            //     error: function (jqXHR, textStatus, errorThrown) {
            //         console.log("Mapping upload to the server failed. HTTP status code:" + jqXHR.status + " " + errorThrown);
            //         // Handle upload error
            //         var info = 'Mapping not uploaded';
            //         $("#message-board").append(info);
            //         isMappingUploaded = false;
            //     }
            // });
            // window.setTimeout(function () {
            //     $("#mapping-alert").fadeTo(500, 0).slideUp(500, function () {
            //         $(this).empty();
            //     });
            // }, 3000);
        }
        else {
            //direct to mapping view
            window.location.href = baseApp + "/views/mapping";
        }
    }

    var dataFileUpload = function () {
        $.ajax({
            url: baseApp + "/upload/data",
            type: "POST",
            data: new FormData($("#upload-file-form")[0]),
            enctype: 'multipart/form-data',
            processData: false,
            contentType: false,
            success: function (fileFormatErrors) {
                if (fileFormatErrors.length === 0) {
                    // Handle upload success
                    mappingFileUpload();

                } else {
                    var info = '

';
                    fileFormatErrors.forEach(function (error) {
                        var errDiv = '
' + error.message +': '+ error.offendingValues+'
';
                        info += errDiv;
                    });
                    info += '

';
                    $("#message-board").append(info);

                    //since this is format error, we delete the just created submission
                    _deleteCurrentSubmission();
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                // Handle upload error
                var message = 'Data upload failed. Please check the data format, which should be a plain, tab-delimited file. The size of the file should be less than 10MB. ';
                var info = '
' + message + '
';
                $("#message-board").append(info);
                console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
               _deleteCurrentSubmission();
            }
        });
    };

    if (isSessionNameDefined && isDataSelected) {
        $.ajax({
            url: baseApp + "/submission/create",
            type: "post",
            data: {name: SESSIONNAME},
            success: dataFileUpload,
            error: function (jqXHR, textStatus, errorThrown) {
                console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
            }
        });
    }

    if (!isSessionNameDefined || !isDataSelected) {
        $("#message-board").empty();
        if (!isSessionNameDefined) {
            var info = 'Pleaes give your new submission a unique name. ';
            $("#message-board").append(info);
        }
        if (!isDataSelected) {
            var info = 'Please select a data file to upload. ';
            $("#message-board").append(info);
        }
    }

} //function uploadFile

function retrieveSessions() {
    $.ajax({
        url: baseApp + "/submission/all",
        type: "get",
        success: handle_session_retrieval_all,
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
            // if(jqXHR.status == 401) {
            //     window.location.href = baseApp+"/views/data";
            // }
        }
    });

}

function handle_session_retrieval_all(_sessions) {
    sessions = _sessions;
    $("#data-proceed-btn").attr("disabled", false);
    var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    $('#old_upload_section').append('

');
    for (var i = 0; i < _sessions.length; i++) {
        var s = _sessions[i];
        var btnid = "s" + (i + 1);
        var d = new Date(s.savedDate);
        var sessionHTML = '
' +
            '<button type="button" class="btn btn-primary" id="' + btnid + '" session_index=' + i + '>' + s.name + '</button>' +
            '
saved on: ' + monthNames[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear() + '
' +
            '<button type="button" class="btn btn-danger" id="removal_' + btnid + '" session_index=' + i + '>Remove this submission</button>
';
        $(sessionHTML).insertAfter("#anchor_old_sessions");
        // $('#session_container').append(sessionHTML);
        $('#' + btnid).click(handle_session_retrieval);
        $('#removal_' + btnid).click(handle_session_removal);
    }//for
}//function handle_session_retrieval_all

function handle_session_retrieval() {
    var ind = $(this).attr('session_index');
    var session = sessions[ind];
    var sid = session.id;
    //set the current session
    $.ajax({
        url: baseApp + "/submission/select",
        type: "get",
        data: {sessionId: sid},
        success: function (data) {
            var page;
            //direct user to the selected session
            switch (session.step) {
                case "MAPPING":
                    page = "mapping";
                    break;
                case "FEEDBACK_DATA":
                    page = "feedback-data";
                    break;
                case "SUBJECTS":
                    page = "subjects";
                    break;
                case "FEEDBACK_SUBJECTS":
                    page = "feedback-subjects";
                    break;
                case "EVENTS":
                    page = "events";
                    break;
                case "FEEDBACK_EVENTS":
                    page = "feedback-events";
                    break;
                case "OVERVIEW":
                    page = "final";
                    break;
                default:
                    page = "mapping";
            }
            window.location.href = baseApp + "/views/" + page;
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
        }
    });
}//function handle_session_retrieval

function handle_session_removal() {
    var ind = $(this).attr('session_index');
    var session = sessions[ind];
    var sid = session.id;
    $.ajax({
        url: baseApp + "/submission/deleteSession",
        type: "post",
        data: {id: sid},
        success: function (data) {
            console.log('deleted session ' + sid);
            $('#session_well_' + ind).remove();
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
        }
    });
}

function backBtnHandler() {
    window.history.back();
}

$(document).ready(function () {
    $("#data-proceed-btn").attr("disabled", "disabled");

    //retrieve user name
    $.ajax({
        url: baseApp + "/submission/username",
        type: "get",
        success: function (data) {
            USERNAME = data;
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(jqXHR.status + " " + textStatus + " " + errorThrown);
        }
    });

    retrieveSessions();
});
<|endoftext|>


<commit_before>var _ = require('lodash')
  , raf = require('raf/polyfill')
  , Ribcage
  , extendView;

Ribcage = {
  initialize: function (opts) {

    opts = opts || {};

    // if we need to load data before rendering, do it
    if (typeof this.loadData == 'function') {
      this._dataLoaded = false
    }
    // otherwise, assume we have the data already
    else {
      this._dataLoaded = true
    }

    // backbone 1.1+ doesn't auto-set this.options
    this.options = opts

    if(this.beforeInit) {
      this.beforeInit(opts);
    }

    this.template = this.template || opts.template;

    if (!this.template) {
      this.template = function () { return ''; };
    }

    if (this.afterInit) {
      this.afterInit(opts);
    }

    this.render();

  }

, context: function () {
    return _.extend({}, this.options, this.model);
  }

, close: function() {

    if (this.beforeClose) {
      this.beforeClose();
    }

    this.closeSubviews();
    this.off();
    this.remove();

  }

, render: function () {
    var self = this
      , model = this.model;

    if(typeof this.bindEvents === 'function') {
      //Make sure we don't double up on event listeners
      //You no longer have to manually stop listening on re-render -cstumph
      _.each(this._listeners, function (emitter){
        this.stopListening(emitter)
      }, this)

      this.bindEvents()
    }

    if (!this._dataLoaded && typeof this.loadData == 'function') {
      return this.loadData(function () {
        self._dataLoaded = true
        self.render()
      })
    }

    if (this.beforeRender) {
      this.beforeRender();
    }

    this.closeSubviews();
    this.$el.empty();

    if (this.beforeTemplating) {
      model = this.beforeTemplating();
    }

    if (this.context) {
      model = this.context();
    }

    this.$el.html(this.template(model));

    // As soon as the view is bound to DOM, we need to re-delegate and re-render all
    // subviews to keep events intact. -cstumph
    this.delegateEvents()
    this.eachSubview(function eachSubviewInRender (view){
      view.render()
    })

    // I'm not happy deferring here, but backbone's
    // event system is based on the DOM, so my hands
    // are tied. - Daniel
    _.defer(function () {
      self.trigger('afterRender')
    });

    if (this.afterRender) {
      this.afterRender();
    }

    return this;

  }

, proxy: function (name, view) {
    this.listenTo(view, name, function proxiedEventCallback(){
      var args = Array.prototype.slice.call(arguments, 0);
      args.splice(0, 0, name);
      this.trigger.apply(this, args);
    })
  }

, eachSubview: function(iterator) {
    _.each(this.subviews, iterator);
  }

, _attachSubView: function(view){
    this.subviews = this.subviews || {};
    this.subviewByModelId = this.subviewByModelId || {};

    this.subviews[view.cid] = view;
    if (view.model) {
      if (!this.subviewByModelId[view.model.id]) this.subviewByModelId[view.model.id] = [];
      this.subviewByModelId[view.model.id].push(view);
    }

    return view;
  }

, appendSubview: function(view, el) {
    el || (el = this.$el);

    this._attachSubView(view);

    if (view.options.render) view.render()
    el.append(view.el);

    _.defer(function () {
      view.trigger('afterAppend', view);
    });

    if (view.afterAppend) {
      view.afterAppend();
    }

  }

, prependSubview: function(view, el) {
    el || (el = this.$el);

    this._attachSubView(view);

    if (view.options.renderOnAppend) view.render()
    el.prepend(view.el);

    _.defer(function () {
      view.trigger('afterPrepend', view);
    });

    if (view.afterPrepend) {
      view.afterPrepend();
    }

  }

, appendSubviews: function(views, el, callback){
    el || (el = this.$el);

    var fragment = document.createDocumentFragment();

    _.each(views, function(view){
      this._attachSubView(view);

      if (view.options.renderOnAppend) view.render()
      fragment.appendChild(view.el);

      _.defer(function () {
        view.trigger('afterAppend', view);
      });

      if (view.afterAppend) {
        view.afterAppend();
      }
    }, this);

    raf.call(window, function(){
      el[0].appendChild(fragment);
      if (_.isFunction(callback)) callback(views);
    });
}

, batchAppendSubviews: function(views, el, batchCount, callback){
  _.chain(views)
    .groupBy(function(view, index){
      return Math.floor(index / batchCount);
    })
    .toArray()
    .each(function(viewBatch){
      this.appendSubviews(viewBatch, el, function(){
        if (_.isFunction(callback)) callback(viewBatch);
      });
    }, this)
  ;
}

, closeSubviews: function() {

    this.eachSubview(function(subview) {
      subview.close();
    });

    this.subviews = {};

  }

, detachSubview: function(view) {
    var msg

    if (this.subviews) {

      if (view && !this.subviews[view.cid]) {
        msg = 'View not found in ' + this.className + '\'s subviews: ' + view.className

        if(view.model)
          msg += '\n\n'+ view.model.toJSON()

        throw new Error(msg)
      }

      delete this.subviews[view.cid];
    }

    view.$el.detach();

  }

, detachSubviewByModel: function(model){
    var id = model.id
    if (this.subviewByModelId){
      if (!id || !this.subviewByModelId[id]){
        throw new Error('No views with ' + id + ' model id found in ' + this.className + ' subviews');
      }

      _.each(this.subviewByModelId[id], function(view){
        this.detachSubview(view);
      }, this);

      delete this.subviewByModelId[id];
    }
  }
};

extendView = function (view) {
  return view.extend(Ribcage);
};

module.exports = extendView;
<commit_msg>housekeeping<commit_after>var _ = require('lodash')
  , raf = require('raf/polyfill')
  , Ribcage
  , extendView;

Ribcage = {
  initialize: function (opts){

    opts = opts || {};

    // if we need to load data before rendering, do it
    if (typeof this.loadData == 'function') {
      this._dataLoaded = false
    }
    // otherwise, assume we have the data already
    else {
      this._dataLoaded = true
    }

    // backbone 1.1+ doesn't auto-set this.options
    this.options = opts

    if(this.beforeInit) {
      this.beforeInit(opts);
    }

    this.template = this.template || opts.template;

    if (!this.template) {
      this.template = function () { return ''; };
    }

    if (this.afterInit) {
      this.afterInit(opts);
    }

    this.render();
  }

, context: function () {
    return _.extend({}, this.options, this.model);
  }

, close: function() {

    if (this.beforeClose) {
      this.beforeClose();
    }

    this.closeSubviews();
    this.off();
    this.remove();
  }

, render: function () {
    var self = this
      , model = this.model;

    if(typeof this.bindEvents === 'function') {
      //Make sure we don't double up on event listeners
      //You no longer have to manually stop listening on re-render -cstumph
      _.each(this._listeners, function (emitter){
        this.stopListening(emitter)
      }, this)

      this.bindEvents()
    }

    if (!this._dataLoaded && typeof this.loadData == 'function') {
      return this.loadData(function () {
        self._dataLoaded = true
        self.render()
      })
    }

    if (this.beforeRender) {
      this.beforeRender();
    }

    this.closeSubviews();
    this.$el.empty();

    if (this.beforeTemplating) {
      model = this.beforeTemplating();
    }

    if (this.context) {
      model = this.context();
    }

    this.$el.html(this.template(model));

    // As soon as the view is bound to DOM, we need to re-delegate and re-render all
    // subviews to keep events intact. -cstumph
    this.delegateEvents()
    this.eachSubview( function eachSubviewInRender (view){
      view.render()
    })

    // I'm not happy deferring here, but backbone's
    // event system is based on the DOM, so my hands
    // are tied. - Daniel
    _.defer(function () {
      self.trigger('afterRender')
    });

    if (this.afterRender) {
      this.afterRender();
    }

    return this;
  }

, proxy: function (name, view){
    this.listenTo(view, name, function proxiedEventCallback(){
      var args = Array.prototype.slice.call(arguments, 0);
      args.splice(0, 0, name);
      this.trigger.apply(this, args);
    })
  }

, eachSubview: function (iterator){
    _.each(this.subviews, iterator);
  }

, _attachSubView: function (view){
    this.subviews = this.subviews || {};
    this.subviewByModelId = this.subviewByModelId || {};

    this.subviews[view.cid] = view;
    if (view.model) {
      if (!this.subviewByModelId[view.model.id]) this.subviewByModelId[view.model.id] = [];
      this.subviewByModelId[view.model.id].push(view);
    }

    return view;
  }

, appendSubview: function (view, el){
    el || (el = this.$el);

    this._attachSubView(view);

    if (view.options.render) view.render()
    el.append(view.el);

    _.defer(function (){
      view.trigger('afterAppend', view);
    });

    if (view.afterAppend) {
      view.afterAppend();
    }
  }

, prependSubview: function (view, el){
    el || (el = this.$el);

    this._attachSubView(view);

    if (view.options.renderOnAppend) view.render()
    el.prepend(view.el);

    _.defer(function () {
      view.trigger('afterPrepend', view);
    });

    if (view.afterPrepend) {
      view.afterPrepend();
    }
  }

, appendSubviews: function (views, el, callback){
    el || (el = this.$el);

    var fragment = document.createDocumentFragment();

    _.each(views, function(view){
      this._attachSubView(view);

      if (view.options.renderOnAppend) view.render()
      fragment.appendChild(view.el);

      _.defer(function () {
        view.trigger('afterAppend', view);
      });

      if (view.afterAppend) {
        view.afterAppend();
      }
    }, this);

    raf.call(window, function(){
      el[0].appendChild(fragment);
      if (_.isFunction(callback)) callback(views);
    });
  }

, batchAppendSubviews: function (views, el, batchCount, callback){
    _.chain(views)
    .groupBy( function (view, index){
      return Math.floor(index / batchCount);
    })
    .toArray()
    .each( function (viewBatch){
      this.appendSubviews(viewBatch, el, function (){
        if (_.isFunction(callback)) callback(viewBatch);
      });
    }, this);
  }

, closeSubviews: function (){
    this.eachSubview( function (subview){
      subview.close();
    });

    this.subviews = {};
  }

, detachSubview: function (view){
    var msg

    if (this.subviews) {

      if (view && !this.subviews[view.cid]) {
        msg = 'View not found in ' + this.className + '\'s subviews: ' + view.className

        if(view.model)
          msg += '\n\n'+ view.model.toJSON()

        throw new Error(msg)
      }

      delete this.subviews[view.cid];
    }

    view.$el.detach();
  }

, detachSubviewByModel: function (model){
    var id = model.id
    if (this.subviewByModelId){
      if (!id || !this.subviewByModelId[id]){
        throw new Error('No views with ' + id + ' model id found in ' + this.className + ' subviews');
      }

      _.each(this.subviewByModelId[id], function(view){
        this.detachSubview(view);
      }, this);

      delete this.subviewByModelId[id];
    }
  }

};//end Ribcage{}

extendView = function (view){
  return view.extend(Ribcage);
};

module.exports = extendView;
<|endoftext|>


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

var appId = 'developerTestApp';

// ID of pod - comes back from 'hello'
var podId;
var userId;
var uiService;
var navService;
var modulesService;
var userService;
var jwt;

// Once tokens have been validated and trust between javascript apps is extablished, client extentsion app can call
// Extended User Info service to get a signed JWT that includes PII for the logged in user.  Pass this JWT to the
// backend server to establish user's identity at the server.
function login()
{
    userService = SYMPHONY.services.subscribe('extended-user-info');

    if (userService) {
        return userService.getJwt()
            .then(function(response)
            {
                jwt = response;
                var request =
                {
                    jwt : jwt,
                    podId : podId   // Must pass pod ID so that signature can be verified using certificate from pod
                };

                return ajax.call('/login-with-jwt', request, 'POST', 'application/json')
                    .then(function(data)
                    {
                        console.log("Response: ", data);
                        return data;
                    }.bind(this));

            });
    }

    return Q.reject(new Error("Could not login"));

}

// We only get here if login was successful.  In this case successful login means the JWT was valid.
// It is possible that the Symphony user is not recognized by the application.  This is handled by
// displaying login form for the application which allows a mapping from Symphony user ID to application
// user ID to be recorded.  This only need to be done one time.

// Response looks like:
// {
//     jwtValid : true | false,
//     userFound : true | false,
//     message : "Some message",
//     userDisplayName : "application's user display name" | null
// }

// At this point, if userFound == false, we need to show the form to collect username then submit
// username, JWT and podId (as a JSON structure) to /login-with-username
//
// If userFound == true, use userDisplayName to display a welcome message (or just show the message from
// the response which is a welcome message.

function setState(response) {
    if (!response.userFound) {
        $(document.body).addClass('login');
        $('#username').change(clearError);
        $('#submit').click(saveUser);
    } else {
        $('#welcome-message').text(response.message);
    }
}

function setError(message) {
    $('#error').html(message);
}

function clearError() {
    $('#error').html('');
}

function saveUser() {
    var username = $('#username').val();

    if (!username) {
        setError('You must enter a user name');
        return;
    }

    var request = {
        username: username,
        jwt: jwt,
        podId: podId

    }
    return ajax.call('/create-user', request, 'POST', 'application/json')
        .then(function(response) {
            return response;
        })
        .fail(function(e) {
            setError('Cannot save username', username);
            return false;
        })
}

function theme(helloResponse) {
    setTheme(helloResponse.themeV2);
    return Q(helloResponse);
}

function focus()
{
    this.modulesService.focus('app-auth');
    this.navService.focus('app-auth-nav');
}

function setTheme(theme)
{
    $(document.body).removeClass(theme.classes.join(' '));
    $(document.body).addClass(theme.name);
    $(document.body).addClass(theme.size);
}

function connect(helloResponse) {
    podId = '' + helloResponse.pod;
    return SYMPHONY.application.connect(appId, ['ui', 'modules', 'applications-nav', 'extended-user-info'], [])
        .then(login)
        .then(function(loginResponse) {
            return setState(loginResponse);

            uiService = SYMPHONY.services.subscribe('ui');
            navService = SYMPHONY.services.subscribe('applications-nav');
            modulesService = SYMPHONY.services.subscribe('modules');

            uiService.listen('themeChangeV2', onThemeChange);

            focus();

            $(window).on('focus', function() {
                focus();
            }.bind(this));

        })
}

// All Symphony services are namespaced with SYMPHONY
SYMPHONY.remote.hello()
    .then(theme)
    .then(connect)
    .fail(function(e) {
        console.log(e.stack);
    });
<commit_msg>- whoops<commit_after>/*
 * Copyright 2016-2017 Symphony Application Authentication - Symphony LLC
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var appId = 'developerTestApp';

// ID of pod - comes back from 'hello'
var podId;
var userId;
var uiService;
var navService;
var modulesService;
var userService;
var jwt;

// Once tokens have been validated and trust between javascript apps is extablished, client extentsion app can call
// Extended User Info service to get a signed JWT that includes PII for the logged in user.  Pass this JWT to the
// backend server to establish user's identity at the server.
function login()
{
    userService = SYMPHONY.services.subscribe('extended-user-info');

    if (userService) {
        return userService.getJwt()
            .then(function(response)
            {
                jwt = response;
                var request =
                {
                    jwt : jwt,
                    podId : podId   // Must pass pod ID so that signature can be verified using certificate from pod
                };

                return ajax.call('/login-with-jwt', request, 'POST', 'application/json')
                    .then(function(data)
                    {
                        console.log("Response: ", data);
                        return data;
                    }.bind(this));

            });
    }

    return Q.reject(new Error("Could not login"));

}

// We only get here if login was successful.  In this case successful login means the JWT was valid.
// It is possible that the Symphony user is not recognized by the application.  This is handled by
// displaying login form for the application which allows a mapping from Symphony user ID to application
// user ID to be recorded.  This only need to be done one time.

// Response looks like:
// {
//     jwtValid : true | false,
//     userFound : true | false,
//     message : "Some message",
//     userDisplayName : "application's user display name" | null
// }

// At this point, if userFound == false, we need to show the form to collect username then submit
// username, JWT and podId (as a JSON structure) to /login-with-username
//
// If userFound == true, use userDisplayName to display a welcome message (or just show the message from
// the response which is a welcome message.

function setState(response) {
    if (!response.userFound) {
        $(document.body).addClass('login');
        $('#username').change(clearError);
        $('#submit').click(saveUser);
    } else {
        $('#welcome-message').text(response.message);
    }
}

function setError(message) {
    $('#error').html(message);
}

function clearError() {
    $('#error').html('');
}

function saveUser() {
    var username = $('#username').val();

    if (!username) {
        setError('You must enter a user name');
        return;
    }

    var request = {
        username: username,
        jwt: jwt,
        podId: podId

    }
    return ajax.call('/create-user', request, 'POST', 'application/json')
        .then(function(response) {
            return response;
        })
        .fail(function(e) {
            setError('Cannot save username', username);
            return false;
        })
}

function theme(helloResponse) {
    setTheme(helloResponse.themeV2);
    return Q(helloResponse);
}

function focus()
{
    this.modulesService.focus('app-auth');
    this.navService.focus('app-auth-nav');
}

function setTheme(theme)
{
    $(document.body).removeClass(theme.classes.join(' '));
    $(document.body).addClass(theme.name);
    $(document.body).addClass(theme.size);
}

function connect(helloResponse) {
    podId = '' + helloResponse.pod;
    return SYMPHONY.application.connect(appId, ['ui', 'modules', 'applications-nav', 'extended-user-info'], [])
        .then(login)
        .then(function(loginResponse) {
            setState(loginResponse);

            uiService = SYMPHONY.services.subscribe('ui');
            navService = SYMPHONY.services.subscribe('applications-nav');
            modulesService = SYMPHONY.services.subscribe('modules');

            uiService.listen('themeChangeV2', onThemeChange);

            focus();

            $(window).on('focus', function() {
                focus();
            }.bind(this));

        })
}

// All Symphony services are namespaced with SYMPHONY
SYMPHONY.remote.hello()
    .then(theme)
    .then(connect)
    .fail(function(e) {
        console.log(e.stack);
    });
<|endoftext|>


<commit_before>'use strict';

var zmq         = require('zmq');
var dbc         = require('dbc');
var binaryutils = require('./binaryutils.js');

var __hasProp = Object.prototype.hasOwnProperty;

var pre_process_filters  = [];
var post_process_filters = [];

var status = {
   OK_200                     : 200,
   NO_CONTENT_204             : 204,
   BAD_REQUEST_400            : 400,
   UNAUTHORIZED_401           : 401,
   FORBIDDEN_402              : 402,
   NOT_FOUND_404              : 404,
   INTERNAL_SERVER_ERROR_500  : 500
};

var standard_headers = {
   plain : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/plain; charset=utf-8'
   },
   json  : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'application/json; charset=utf-8'
   },
   html  : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/html; charset=utf-8'
   },
   stream: {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/event-stream; charset=utf-8',
      'Cache-Control' : 'no-cache',
      'Connection'    : 'keep-alive'
   }
};

var header_cors = {
   "access-control-allow-origin" : "*",
   "access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS, PATCH",
   "access-control-allow-headers": "content-type, accept, authorization",
   "access-control-max-age"      : 10, // Seconds.
   "content-length"              : 0
};

var statusMessages = {
   '100': 'Continue',
   '101': 'Switching Protocols',
   '200': 'OK',
   '201': 'Created',
   '202': 'Accepted',
   '203': 'Non-Authoritative Information',
   '204': 'No Content',
   '205': 'Reset Content',
   '206': 'Partial Content',
   '300': 'Multiple Choices',
   '301': 'Moved Permanently',
   '302': 'Found',
   '303': 'See Other',
   '304': 'Not Modified',
   '305': 'Use Proxy',
   '307': 'Temporary Redirect',
   '400': 'Bad Request',
   '401': 'Unauthorized',
   '402': 'Payment Required',
   '403': 'Forbidden',
   '404': 'Not Found',
   '405': 'Method Not Allowed',
   '406': 'Not Acceptable',
   '407': 'Proxy Authentication Required',
   '408': 'Request Timeout',
   '409': 'Conflict',
   '410': 'Gone',
   '411': 'Length Required',
   '412': 'Precondition Failed',
   '413': 'Request Entity Too Large',
   '414': 'Request-URI Too Large',
   '415': 'Unsupported Media Type',
   '416': 'Request Range Not Satisfiable',
   '417': 'Expectation Failed',
   '500': 'Internal Server Error',
   '501': 'Not Implemented',
   '502': 'Bad Gateway',
   '503': 'Service Unavailable',
   '504': 'Gateway Timeout',
   '505': 'HTTP Version Not Supported'
};

var setCors = function(headers){
   header_cors = headers;
};

var addPreProcessFilter = function(fun){
   pre_process_filters.push(fun);
};

var addPostProcessFilter = function(fun){
   post_process_filters.push(fun);
};

var split = function(str, chr, limit) {
   var parts = str.split  (chr);
   var ret   = parts.slice(0, limit - 1);

   ret.push(parts.slice(limit - 1).join(chr));
   return ret;
};

var parseNetstring = function(ns) {

   var nsSplit = split(ns, ':', 2);
   var length  = parseInt  (nsSplit[0], 10);
   var payload = nsSplit[1];

   if (payload.length -1 < length){
      length = payload.length -1;
   }

   if (payload[length] !== ',') {
      throw 'Netstring did not end in ","';
   }

   return [ payload.slice(0, length), payload.slice(length + 1) ];
};

var getJSON = function(str){
   try {
      return JSON.parse(str);
   } catch(e) {
      return null;
   }
};

var isValidJSON = function(str){
   if (0 === str.length){
      return true;
   }
   try {
      JSON.parse(str);
      return true;
   } catch(e) {
      return false;
   }
};

var parse = function(mongrelString) {

   var mongrelStringSplit = split(mongrelString, ' ', 4);

   var uuid       = mongrelStringSplit[0];
   var connId     = parseInt(mongrelStringSplit[1]);
   var path       = mongrelStringSplit[2];
   var payload    = mongrelStringSplit[3];

   var paySplit   = parseNetstring(payload);
   var headers    = getJSON       (paySplit[0]);
   var body       = parseNetstring(paySplit[1])[0];

   var valid_json = isValidJSON(body);
   var json       = getJSON(body);

   return {
      headers    : headers,
      uuid       : uuid,
      connId     : connId,
      path       : path,
      json       : json,
      valid_json : valid_json
   };
};

var dataToBuffer = function(data){

   if (Buffer.isBuffer(data)){
      return data;
   }

   var body = (Object.prototype.toString.call(data) === '[object String]') ? data : JSON.stringify(data);

   if (undefined === body){
      body = '';
   }

   return new Buffer(body, 'utf8' );
};

var buildZmqResponse = function(uuid, connId, status, headers, data) {

   var header_arr = [];
   var dataBuffer = dataToBuffer(data);

   header_arr.push('Content-Length: ' + dataBuffer.length);

   for (var header in headers) {
      if (__hasProp.call(headers, header)) {
         header_arr.push('' + header + ': ' + headers[header]);
      }
   }

   var str = ''
      + uuid
      + ' '
      + String(connId).length
      + ':'
      + connId
      + ', '
      + 'HTTP/1.1 '
      + status
      + ' '
      + statusMessages[status]
      + '\r\n'
      + header_arr.join('\r\n')
      + '\r\n\r\n';

   var strBuffer = new Buffer(str, 'utf8' );

   return Buffer.concat([strBuffer, dataBuffer]);
};

var sender = function(config) {

   dbc.hasMember(config, 'spec');
   dbc.hasMemberIn(config, 'type', ['pub', 'push']);

   var send      = zmq.socket(config.type);
   send.identity = config.id;

   process.on('exit', function(){
      if (send){
         send.close();
         process.exit();
      }
   });

   if (config.bind) {
      send.bindSync(config.spec);
   } else {
      send.connect(config.spec);
   }

   if (config.isMongrel2 || config.isGeneric) {
      return {
         'send' : function (uuid, connId, status, headers, body) {

            var msg = {
               'uuid'    : uuid,
               'connId'  : connId,
               'status'  : status,
               'headers' : headers,
               'body'    : body
            };

            for (var i in post_process_filters) {
               if(post_process_filters.hasOwnProperty(i)) {
                  post_process_filters[i](msg);
               }
            }

            var message;
            if(!config.isGeneric)
               message = buildZmqResponse(msg.uuid, msg.connId, msg.status, msg.headers, msg.body);
            else
               message = JSON.stringify(msg);

            return send.send(message);
         }
      };
   } else {
      return {
         'send' : function (message) {
            console.log(message);
            send.send(JSON.stringify(message));
         }
      };
   }
};

var readFirstLine = function(data) {

   for (var i = 0; i < data.length; i++) {
      if (10 === data.readInt8(i) && 13 === data.readInt8(i-1)) {
         return data.toString('utf8', 0, i);
      }
   }
   return data.toString('utf8');
};

var getHeadersAndMongrel2 = function(data) {

   var mongrelString      = readFirstLine(data);
   var mongrelStringSplit = split(mongrelString, ' ', 4);
   var payload            = mongrelStringSplit[3];
   var paySplit           = parseNetstring(payload);

   return [mongrelStringSplit[0], mongrelStringSplit[1], mongrelStringSplit[2], getJSON(paySplit[0])];

};

var receiver = function(config, error_config, callback) {

   dbc.hasMember           (config, 'spec');
   dbc.hasMemberIn         (config, 'type', ['sub', 'pull']);
   dbc.conditionalHasMember(config, 'subscribe', config.type === 'sub');

   var receive      = zmq.socket(config.type);
   receive.identity = config.id;

   var client = null;

   if (config.isMongrel2) {
      dbc.hasMember  (error_config, 'spec');
      dbc.assert     (error_config.isMongrel2 === true);
      client = zmq.socket('pub');
      client.connect(error_config.spec);
   }

   process.on('exit', function() {
      if (receive) {
         receive.close();
      }
      if (config.isMongrel2 && client) {
         client.close();
      }
      process.exit();
   });

   if (config.isMongrel2) {
      receive.on('message', function (envelope) {

         var headersAndMongrel2 = getHeadersAndMongrel2(envelope);
         var headers            = headersAndMongrel2[3];

         var proceed = true;

         var filterResponse = function (uuid, connId, status, headers, body) {
            proceed = false;
            var message = buildZmqResponse(uuid, connId, status, headers, body);
            return client.send(message);
         };

         var callbackWithFilter = function(zmqMsg) {

            for (var i in pre_process_filters) {
               if(pre_process_filters.hasOwnProperty(i)) {
                  pre_process_filters[i](zmqMsg, filterResponse);
                  if (false === proceed) {
                     return;
                  }
               }
            }
            callback(zmqMsg);
         };

         if( binaryutils.isBinaryUpload(headers)) {
            binaryutils.processBinaryUpload(headersAndMongrel2, client, envelope, callbackWithFilter);
         } else {
            console.log('!!!');
            console.log(envelope.toString('utf8'));
            var zmqMsg = parse(envelope.toString('utf8'));

            if(zmqMsg.headers.METHOD === 'JSON' && 'disconnect' === zmqMsg.json.type) {
               //do nothing
            } else if (zmqMsg.headers.METHOD === 'OPTIONS') {
               client.send(buildZmqResponse(zmqMsg.uuid, zmqMsg.connId, status.NO_CONTENT_204, header_cors, ''));
            } else if (!zmqMsg.valid_json) {
               client.send(buildZmqResponse(zmqMsg.uuid, zmqMsg.connId, status.BAD_REQUEST_400, standard_headers.json, {'message':'Invalid JSON'}));
            } else {
               delete zmqMsg['valid_json'];
               return callbackWithFilter(zmqMsg);
            }
         }
      });
   } else {
      receive.on('message', function (envelope) {
         var zmqMsg = envelope.toString('utf8');
         var j;
         console.log(envelope.toString('utf8'));
         try
         {
            j = JSON.parse(zmqMsg);
         }
         catch(_)
         {
            try
            {
               j = JSON.parse(parse(zmqMsg));
            }
            catch(_)
            {
               j = zmqMsg;
            }
         }

         return callback(j);
      });
   }

   if (config.bind) {
      receive.bindSync(config.spec);
   } else {
      receive.connect(config.spec);
   }

   if ('sub' === config.type){
      receive.subscribe(config.subscribe);
   }
};

var setMongrel2UploadDir = function(dir) {
   binaryutils.setMongrel2UploadDir(dir);
};

module.exports.status               = status;
module.exports.getJSON              = getJSON;
module.exports.parse                = parse;
module.exports.parseNetstring       = parseNetstring;
module.exports.receiver             = receiver;
module.exports.sender               = sender;
module.exports.buildZmqResponse     = buildZmqResponse;
module.exports.setCors              = setCors;
module.exports.addPreProcessFilter  = addPreProcessFilter;
module.exports.addPostProcessFilter = addPostProcessFilter;
module.exports.setMongrel2UploadDir = setMongrel2UploadDir;
module.exports.standard_headers     = standard_headers;
<commit_msg>renamed isGeneric to a more functional asJson<commit_after>'use strict';

var zmq         = require('zmq');
var dbc         = require('dbc');
var binaryutils = require('./binaryutils.js');

var __hasProp = Object.prototype.hasOwnProperty;

var pre_process_filters  = [];
var post_process_filters = [];

var status = {
   OK_200                     : 200,
   NO_CONTENT_204             : 204,
   BAD_REQUEST_400            : 400,
   UNAUTHORIZED_401           : 401,
   FORBIDDEN_402              : 402,
   NOT_FOUND_404              : 404,
   INTERNAL_SERVER_ERROR_500  : 500
};

var standard_headers = {
   plain : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/plain; charset=utf-8'
   },
   json  : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'application/json; charset=utf-8'
   },
   html  : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/html; charset=utf-8'
   },
   stream: {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/event-stream; charset=utf-8',
      'Cache-Control' : 'no-cache',
      'Connection'    : 'keep-alive'
   }
};

var header_cors = {
   "access-control-allow-origin" : "*",
   "access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS, PATCH",
   "access-control-allow-headers": "content-type, accept, authorization",
   "access-control-max-age"      : 10, // Seconds.
   "content-length"              : 0
};

var statusMessages = {
   '100': 'Continue',
   '101': 'Switching Protocols',
   '200': 'OK',
   '201': 'Created',
   '202': 'Accepted',
   '203': 'Non-Authoritative Information',
   '204': 'No Content',
   '205': 'Reset Content',
   '206': 'Partial Content',
   '300': 'Multiple Choices',
   '301': 'Moved Permanently',
   '302': 'Found',
   '303': 'See Other',
   '304': 'Not Modified',
   '305': 'Use Proxy',
   '307': 'Temporary Redirect',
   '400': 'Bad Request',
   '401': 'Unauthorized',
   '402': 'Payment Required',
   '403': 'Forbidden',
   '404': 'Not Found',
   '405': 'Method Not Allowed',
   '406': 'Not Acceptable',
   '407': 'Proxy Authentication Required',
   '408': 'Request Timeout',
   '409': 'Conflict',
   '410': 'Gone',
   '411': 'Length Required',
   '412': 'Precondition Failed',
   '413': 'Request Entity Too Large',
   '414': 'Request-URI Too Large',
   '415': 'Unsupported Media Type',
   '416': 'Request Range Not Satisfiable',
   '417': 'Expectation Failed',
   '500': 'Internal Server Error',
   '501': 'Not Implemented',
   '502': 'Bad Gateway',
   '503': 'Service Unavailable',
   '504': 'Gateway Timeout',
   '505': 'HTTP Version Not Supported'
};

var setCors = function(headers){
   header_cors = headers;
};

var addPreProcessFilter = function(fun){
   pre_process_filters.push(fun);
};

var addPostProcessFilter = function(fun){
   post_process_filters.push(fun);
};

var split = function(str, chr, limit) {
   var parts = str.split  (chr);
   var ret   = parts.slice(0, limit - 1);

   ret.push(parts.slice(limit - 1).join(chr));
   return ret;
};

var parseNetstring = function(ns) {

   var nsSplit = split(ns, ':', 2);
   var length  = parseInt  (nsSplit[0], 10);
   var payload = nsSplit[1];

   if (payload.length -1 < length){
      length = payload.length -1;
   }

   if (payload[length] !== ',') {
      throw 'Netstring did not end in ","';
   }

   return [ payload.slice(0, length), payload.slice(length + 1) ];
};

var getJSON = function(str){
   try {
      return JSON.parse(str);
   } catch(e) {
      return null;
   }
};

var isValidJSON = function(str){
   if (0 === str.length){
      return true;
   }
   try {
      JSON.parse(str);
      return true;
   } catch(e) {
      return false;
   }
};

var parse = function(mongrelString) {

   var mongrelStringSplit = split(mongrelString, ' ', 4);

   var uuid       = mongrelStringSplit[0];
   var connId     = parseInt(mongrelStringSplit[1]);
   var path       = mongrelStringSplit[2];
   var payload    = mongrelStringSplit[3];

   var paySplit   = parseNetstring(payload);
   var headers    = getJSON       (paySplit[0]);
   var body       = parseNetstring(paySplit[1])[0];

   var valid_json = isValidJSON(body);
   var json       = getJSON(body);

   return {
      headers    : headers,
      uuid       : uuid,
      connId     : connId,
      path       : path,
      json       : json,
      valid_json : valid_json
   };
};

var dataToBuffer = function(data){

   if (Buffer.isBuffer(data)){
      return data;
   }

   var body = (Object.prototype.toString.call(data) === '[object String]') ? data : JSON.stringify(data);

   if (undefined === body){
      body = '';
   }

   return new Buffer(body, 'utf8' );
};

var buildZmqResponse = function(uuid, connId, status, headers, data) {

   var header_arr = [];
   var dataBuffer = dataToBuffer(data);

   header_arr.push('Content-Length: ' + dataBuffer.length);

   for (var header in headers) {
      if (__hasProp.call(headers, header)) {
         header_arr.push('' + header + ': ' + headers[header]);
      }
   }

   var str = ''
      + uuid
      + ' '
      + String(connId).length
      + ':'
      + connId
      + ', '
      + 'HTTP/1.1 '
      + status
      + ' '
      + statusMessages[status]
      + '\r\n'
      + header_arr.join('\r\n')
      + '\r\n\r\n';

   var strBuffer = new Buffer(str, 'utf8' );

   return Buffer.concat([strBuffer, dataBuffer]);
};

var sender = function(config) {

   dbc.hasMember(config, 'spec');
   dbc.hasMemberIn(config, 'type', ['pub', 'push']);

   var send      = zmq.socket(config.type);
   send.identity = config.id;

   process.on('exit', function(){
      if (send){
         send.close();
         process.exit();
      }
   });

   if (config.bind) {
      send.bindSync(config.spec);
   } else {
      send.connect(config.spec);
   }

   if (config.isMongrel2 || config.asJson) {
      return {
         'send' : function (uuid, connId, status, headers, body) {

            var msg = {
               'uuid'    : uuid,
               'connId'  : connId,
               'status'  : status,
               'headers' : headers,
               'body'    : body
            };

            for (var i in post_process_filters) {
               if(post_process_filters.hasOwnProperty(i)) {
                  post_process_filters[i](msg);
               }
            }

            var message;
            if(!config.asJson)
               message = buildZmqResponse(msg.uuid, msg.connId, msg.status, msg.headers, msg.body);
            else
               message = JSON.stringify(msg);

            return send.send(message);
         }
      };
   } else {
      return {
         'send' : function (message) {
            send.send(JSON.stringify(message));
         }
      };
   }
};

var readFirstLine = function(data) {

   for (var i = 0; i < data.length; i++) {
      if (10 === data.readInt8(i) && 13 === data.readInt8(i-1)) {
         return data.toString('utf8', 0, i);
      }
   }
   return data.toString('utf8');
};

var getHeadersAndMongrel2 = function(data) {

   var mongrelString      = readFirstLine(data);
   var mongrelStringSplit = split(mongrelString, ' ', 4);
   var payload            = mongrelStringSplit[3];
   var paySplit           = parseNetstring(payload);

   return [mongrelStringSplit[0], mongrelStringSplit[1], mongrelStringSplit[2], getJSON(paySplit[0])];

};

var receiver = function(config, error_config, callback) {

   dbc.hasMember           (config, 'spec');
   dbc.hasMemberIn         (config, 'type', ['sub', 'pull']);
   dbc.conditionalHasMember(config, 'subscribe', config.type === 'sub');

   var receive      = zmq.socket(config.type);
   receive.identity = config.id;

   var client = null;

   if (config.isMongrel2) {
      dbc.hasMember  (error_config, 'spec');
      dbc.assert     (error_config.isMongrel2 === true);
      client = zmq.socket('pub');
      client.connect(error_config.spec);
   }

   process.on('exit', function() {
      if (receive) {
         receive.close();
      }
      if (config.isMongrel2 && client) {
         client.close();
      }
      process.exit();
   });

   if (config.isMongrel2) {
      receive.on('message', function (envelope) {

         var headersAndMongrel2 = getHeadersAndMongrel2(envelope);
         var headers            = headersAndMongrel2[3];

         var proceed = true;

         var filterResponse = function (uuid, connId, status, headers, body) {
            proceed = false;
            var message = buildZmqResponse(uuid, connId, status, headers, body);
            return client.send(message);
         };

         var callbackWithFilter = function(zmqMsg) {

            for (var i in pre_process_filters) {
               if(pre_process_filters.hasOwnProperty(i)) {
                  pre_process_filters[i](zmqMsg, filterResponse);
                  if (false === proceed) {
                     return;
                  }
               }
            }
            callback(zmqMsg);
         };

         if( binaryutils.isBinaryUpload(headers)) {
            binaryutils.processBinaryUpload(headersAndMongrel2, client, envelope, callbackWithFilter);
         } else {
            var zmqMsg = parse(envelope.toString('utf8'));

            if(zmqMsg.headers.METHOD === 'JSON' && 'disconnect' === zmqMsg.json.type) {
               //do nothing
            } else if (zmqMsg.headers.METHOD === 'OPTIONS') {
               client.send(buildZmqResponse(zmqMsg.uuid, zmqMsg.connId, status.NO_CONTENT_204, header_cors, ''));
            } else if (!zmqMsg.valid_json) {
               client.send(buildZmqResponse(zmqMsg.uuid, zmqMsg.connId, status.BAD_REQUEST_400, standard_headers.json, {'message':'Invalid JSON'}));
            } else {
               delete zmqMsg['valid_json'];
               return callbackWithFilter(zmqMsg);
            }
         }
      });
   } else {
      receive.on('message', function (envelope) {
         var zmqMsg = envelope.toString('utf8');
         var j;
         try
         {
            j = JSON.parse(zmqMsg);
         }
         catch(_)
         {
            try
            {
               j = JSON.parse(parse(zmqMsg));
            }
            catch(_)
            {
               j = zmqMsg;
            }
         }

         return callback(j);
      });
   }

   if (config.bind) {
      receive.bindSync(config.spec);
   } else {
      receive.connect(config.spec);
   }

   if ('sub' === config.type){
      receive.subscribe(config.subscribe);
   }
};

var setMongrel2UploadDir = function(dir) {
   binaryutils.setMongrel2UploadDir(dir);
};

module.exports.status               = status;
module.exports.getJSON              = getJSON;
module.exports.parse                = parse;
module.exports.parseNetstring       = parseNetstring;
module.exports.receiver             = receiver;
module.exports.sender               = sender;
module.exports.buildZmqResponse     = buildZmqResponse;
module.exports.setCors              = setCors;
module.exports.addPreProcessFilter  = addPreProcessFilter;
module.exports.addPostProcessFilter = addPostProcessFilter;
module.exports.setMongrel2UploadDir = setMongrel2UploadDir;
module.exports.standard_headers     = standard_headers;
<|endoftext|>


<commit_before>//import * as actionTypes from '../constants/actionTypes';
import { getPolygonfromBBox } from '../utils/gisHelper';
import * as mappingActions from './mappingActions';
import * as actionTypes from '../constants/actionTypes';

import {
  SERVICE
} from '../constants/cids';

import 'whatwg-fetch';

export function searchForPlans(gazObject) {
  return function (dispatch, getState) {
    dispatch(mappingActions.setSearchProgressIndicator(true));
    const state = getState();
    let query={
      "list": [{
        "key": "wktString",
        "value": getPolygonfromBBox(state.mapping.boundingBox)
      }
      ,{
        "key": "status",
        "value": ''
      },{
        "key": "srs",
        "value": 25832
      },{
        "key": "urlprefix",
        "value": "https://wunda-geoportal-docs.cismet.de"
      }
      ]
    };
    //console.log(JSON.stringify(query));
    fetch(SERVICE + '/searches/WUNDA_BLAU.BPlanAPISearch/results?role=all&limit=100&offset=0', {
      method: 'post',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(query)

    }).then(function (response) {
      if (response.status >= 200 && response.status < 300) {
        response.json().then(function (result) {

            let featureArray=[];
            let counter=0;
            let lastFeature=null;
            let selectionIndexWish=0;
            for (let objArr of result.$collection) {
                let feature=convertPropArrayToFeature(objArr,counter);

                if (lastFeature!=null && JSON.stringify(feature.geometry)==JSON.stringify(lastFeature.geometry)) {
                  lastFeature.twin=counter;
                  feature.twin=counter-1;
                }

                if (gazObject!=null && gazObject.length == 1 && gazObject[0] !=null && gazObject.string==feature.properties.nummer) {
//                  if (gazObject!=null && gazObject[0].string==feature.properties.nummer) {
                  selectionIndexWish=counter;
                }
                featureArray.push(feature);
                lastFeature=feature;
                counter++;
            }

           dispatch(mappingActions.setSearchProgressIndicator(false));
           dispatch(mappingActions.setFeatureCollection(featureArray));
           if (featureArray.length>0) {
            dispatch(mappingActions.setSelectedFeatureIndex(selectionIndexWish));
           }
          // dispatch(mappingActions.fitFeatureBounds(featureArray[0],stateConstants.AUTO_FIT_MODE_STRICT));
        });
      } else if (response.status === 401) {
           dispatch(mappingActions.setSearchProgressIndicator(false));
      }
    });
  };
}
export function setDocumentLoadingIndicator(isLoading) {
  return {
    type: actionTypes.SET_DOCUMENT_LOADING_INDICATOR,
    isLoading
  };
}

function convertPropArrayToFeature(propArray,counter,){
    let plaene_rk;
    let geom=JSON.parse(propArray[6]);

    if (propArray[3]!=null) {
      plaene_rk=JSON.parse(propArray[3]);
    } else {
      plaene_rk=[];
    }
    let plaene_nrk;
    if (propArray[4]!=null) {
      plaene_nrk=JSON.parse(propArray[4]);
    } else {
      plaene_nrk=[];
    }
    let docs;
    if (propArray[5]!=null) {
      docs=JSON.parse(propArray[5]);
    } else {
      docs=[];
    }
    return  {
    "id": propArray[0]+"."+counter,
    "type": "Feature",
    "selected": false,
    "geometry": geom,
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:EPSG::25832"
        }
    },
    "properties": {
    "nummer":propArray[0],
    "name":propArray[1],
    "status":propArray[2],
    "plaene_rk":plaene_rk,
    "plaene_nrk":plaene_nrk,
    "docs":docs,
    "twin":null
    }
  };
}<commit_msg>working on #3: if the gazetteer hit lies in the next bplan then auto fit this bplan<commit_after>//import * as actionTypes from '../constants/actionTypes';
import { getPolygonfromBBox } from '../utils/gisHelper';
import * as mappingActions from './mappingActions';
import * as actionTypes from '../constants/actionTypes';
import * as turf from '@turf/turf';
import * as stateConstants from '../constants/stateConstants';

import {
  SERVICE
} from '../constants/cids';

import 'whatwg-fetch';

export function searchForPlans(gazObject) {
  return function (dispatch, getState) {
    dispatch(mappingActions.setSearchProgressIndicator(true));
    const state = getState();
    let query={
      "list": [{
        "key": "wktString",
        "value": getPolygonfromBBox(state.mapping.boundingBox)
      }
      ,{
        "key": "status",
        "value": ''
      },{
        "key": "srs",
        "value": 25832
      },{
        "key": "urlprefix",
        "value": "https://wunda-geoportal-docs.cismet.de"
      }
      ]
    };
    //console.log(JSON.stringify(query));
    fetch(SERVICE + '/searches/WUNDA_BLAU.BPlanAPISearch/results?role=all&limit=100&offset=0', {
      method: 'post',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(query)

    }).then(function (response) {
      if (response.status >= 200 && response.status < 300) {
        response.json().then(function (result) {

            let featureArray=[];
            let counter=0;
            let lastFeature=null;
            let selectionIndexWish=0;
            for (let objArr of result.$collection) {
                let feature=convertPropArrayToFeature(objArr,counter);

                if (lastFeature!=null && JSON.stringify(feature.geometry)==JSON.stringify(lastFeature.geometry)) {
                  lastFeature.twin=counter;
                  feature.twin=counter-1;
                }

                if (gazObject!=null && gazObject.length == 1 && gazObject[0] !=null && gazObject.string==feature.properties.nummer) {
//                  if (gazObject!=null && gazObject[0].string==feature.properties.nummer) {
                  selectionIndexWish=counter;
                }
                featureArray.push(feature);
                lastFeature=feature;
                counter++;
            }

           dispatch(mappingActions.setSearchProgressIndicator(false));
           dispatch(mappingActions.setFeatureCollection(featureArray));
           if (featureArray.length>0) {
            dispatch(mappingActions.setSelectedFeatureIndex(selectionIndexWish));
           }
           if (gazObject!=null && gazObject.length == 1 && gazObject[0] !=null) {
              let p=turf.point([gazObject[0].x,gazObject[0].y]);
              if (turf.inside(p,featureArray[selectionIndexWish])) {
                dispatch(mappingActions.fitFeatureBounds(featureArray[selectionIndexWish],stateConstants.AUTO_FIT_MODE_STRICT));
              }
           }

        });
      } else if (response.status === 401) {
           dispatch(mappingActions.setSearchProgressIndicator(false));
      }
    });
  };
}
export function setDocumentLoadingIndicator(isLoading) {
  return {
    type: actionTypes.SET_DOCUMENT_LOADING_INDICATOR,
    isLoading
  };
}

function convertPropArrayToFeature(propArray,counter,){
    let plaene_rk;
    let geom=JSON.parse(propArray[6]);

    if (propArray[3]!=null) {
      plaene_rk=JSON.parse(propArray[3]);
    } else {
      plaene_rk=[];
    }
    let plaene_nrk;
    if (propArray[4]!=null) {
      plaene_nrk=JSON.parse(propArray[4]);
    } else {
      plaene_nrk=[];
    }
    let docs;
    if (propArray[5]!=null) {
      docs=JSON.parse(propArray[5]);
    } else {
      docs=[];
    }
    return  {
    "id": propArray[0]+"."+counter,
    "type": "Feature",
    "selected": false,
    "geometry": geom,
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:EPSG::25832"
        }
    },
    "properties": {
    "nummer":propArray[0],
    "name":propArray[1],
    "status":propArray[2],
    "plaene_rk":plaene_rk,
    "plaene_nrk":plaene_nrk,
    "docs":docs,
    "twin":null
    }
  };
}<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Joshua Hollenbeck
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 */
const Promise = require('bluebird');
const mixinSubscribable = require('mixinSubscribable');
const RefraxMutableResource = require('RefraxMutableResource');
const RefraxOptions = require('RefraxOptions');
const RefraxResource = require('RefraxResource');
const RefraxTools = require('RefraxTools');
const prototypeAction = {};

const MixinStatus = {
  isPending: function() {
    return this._promises.length > 0;
  }
};

function mixinStatus(target) {
  Object.defineProperty(target, '_promises', {value: []});

  return RefraxTools.extend(target, MixinStatus);
}

const MixinMutable = {
  get: function(attribute) {
    return this.mutable[attribute] ||
      (this.getDefault && this.getDefault()[attribute]);
  },
  set: function(attribute, value) {
    this.mutable[attribute] = value;
  },
  setter: function(attribute) {
    var self = this;

    return function(value) {
      self.mutable[attribute] = value;
    };
  },
  setterHandler: function(attribute) {
    var self = this;

    return function(event) {
      self.mutable[attribute] = event.target.value;
      self.emit('change');
    };
  },
  unset: function() {
    this.mutable = {};
    this.emit('change');
  },
  getErrors: function(attribute) {
    return attribute ? this.errors[attribute] : this.errors;
  }
};

function mixinMutable(target) {
  Object.defineProperty(target, 'mutable', {
    value: {},
    writable: true
  });
  Object.defineProperty(target, 'errors', {
    value: {},
    writable: true
  });

  Object.defineProperty(target, 'data', {
    get: function() {
      var base = this.getDefault && this.getDefault() || {};
      return RefraxTools.setPrototypeOf(this.mutable, base);
    }
  });

  return RefraxTools.extend(target, MixinMutable);
}

class ActionInvoker {
  constructor(action, options) {
    Object.defineProperty(this, '_action', {value: action});
    Object.defineProperty(this, '_options', {value: options});
  }

  mutableFrom(accessor, ...args) {
    return RefraxMutableResource.from(accessor, new RefraxOptions(this._options.resource), ...args);
  }
}

function invokeAction(emitters, method, params, options, args) {
  var action = emitters[0]
    , invoker = new ActionInvoker(action, options)
    , promise, result, i;

  // reset errors on invocation
  action.errors = {};
  params = RefraxTools.extend({}, action.getDefault(), action.mutable, params);

  for (i=0; i<emitters.length; i++) {
    emitters[i].emit('start');
  }

  promise = result = method.apply(invoker, [params].concat(args));

  if (!RefraxTools.isPromise(result)) {
    promise = new Promise(function(resolve, reject) {
      resolve(result);
    });
  }

  action._promises.push(promise);
  function finalize() {
    var i = action._promises.indexOf(promise);
    if (i > -1) {
      action._promises.splice(i, 1);
    }

    for (i=0; i<emitters.length; i++) {
      emitters[i].emit('finish');
    }
  }
  promise.then(finalize, finalize);

  promise.catch(function(response) {
    if (RefraxTools.isPlainObject(response.mutable)) {
      action.errors = RefraxTools.extend({}, response.mutable);
    }
    action.emit('change');
  });

  return promise;
}

function createActionInstance(template, method, options) {
  function ActionInstance(params, ...args) {
    return invokeAction([ActionInstance, template], method, params, options, args);
  }

  ActionInstance.getDefault = function() {
    var result = options.default || {};

    if (RefraxTools.isFunction(result)) {
      result = result();
    }

    if (result instanceof RefraxResource) {
      result = result.data || {};
    }
    else if (!RefraxTools.isPlainObject(result)) {
      throw new TypeError('ActionInstance ' + template + ' failed to resolve default value');
    }

    return result;
  };

  mixinSubscribable(ActionInstance);
  mixinStatus(ActionInstance);
  mixinMutable(ActionInstance);

  return ActionInstance;
}

function createAction(method) {
  if (this instanceof createAction) {
    throw new TypeError('Cannot call createAction as a class');
  }

  /**
   * An Action can either be globally invoked or instantiated and invoked on that
   * particular instance.
   */
  function Action(params, ...args) {
    if (this instanceof Action) {
      return createActionInstance(Action, method, params);
    }
    else {
      return invokeAction([Action], method, params, {}, args);
    }
  }
  // templates all share the same prototype so they can be identified above with instanceof
  RefraxTools.setPrototypeOf(Action, prototypeAction);

  mixinSubscribable(Action);
  mixinStatus(Action);
  mixinMutable(Action);

  return Action;
}

createAction.prototype = prototypeAction;

export default createAction;
<commit_msg>Mutable always propagates unless configured now<commit_after>/**
 * Copyright (c) 2015-present, Joshua Hollenbeck
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 */
const Promise = require('bluebird');
const mixinSubscribable = require('mixinSubscribable');
const RefraxMutableResource = require('RefraxMutableResource');
const RefraxOptions = require('RefraxOptions');
const RefraxResource = require('RefraxResource');
const RefraxTools = require('RefraxTools');
const prototypeAction = {};

const MixinStatus = {
  isPending: function() {
    return this._promises.length > 0;
  }
};

function mixinStatus(target) {
  Object.defineProperty(target, '_promises', {value: []});

  return RefraxTools.extend(target, MixinStatus);
}

const MixinMutable = {
  get: function(attribute) {
    return this.mutable[attribute] ||
      (this.getDefault && this.getDefault()[attribute]);
  },
  set: function(attribute, value, options = {}) {
    this.mutable[attribute] = value;

    if (options.noPropagate !== true) {
      this.emit('change');
    }
  },
  setter: function(attribute, options = {}) {
    var self = this;

    return function(value) {
      self.mutable[attribute] = value;

      if (options.noPropagate !== true) {
        self.emit('change');
      }
    };
  },
  setterHandler: function(attribute, options = {}) {
    var self = this;

    return function(event) {
      self.mutable[attribute] = event.target.value;

      if (options.noPropagate !== true) {
        self.emit('change');
      }
    };
  },
  unset: function(options = {}) {
    this.mutable = {};

    if (options.noPropagate !== true) {
      this.emit('change');
    }
  },
  getErrors: function(attribute) {
    return attribute ? this.errors[attribute] : this.errors;
  }
};

function mixinMutable(target) {
  Object.defineProperty(target, 'mutable', {
    value: {},
    writable: true
  });
  Object.defineProperty(target, 'errors', {
    value: {},
    writable: true
  });

  Object.defineProperty(target, 'data', {
    get: function() {
      var base = this.getDefault && this.getDefault() || {};
      return RefraxTools.setPrototypeOf(this.mutable, base);
    }
  });

  return RefraxTools.extend(target, MixinMutable);
}

class ActionInvoker {
  constructor(action, options) {
    Object.defineProperty(this, '_action', {value: action});
    Object.defineProperty(this, '_options', {value: options});
  }

  mutableFrom(accessor, ...args) {
    return RefraxMutableResource.from(accessor, new RefraxOptions(this._options.resource), ...args);
  }
}

function invokeAction(emitters, method, params, options, args) {
  var action = emitters[0]
    , invoker = new ActionInvoker(action, options)
    , promise, result, i;

  // reset errors on invocation
  action.errors = {};
  params = RefraxTools.extend({}, action.getDefault(), action.mutable, params);

  for (i=0; i<emitters.length; i++) {
    emitters[i].emit('start');
  }

  promise = result = method.apply(invoker, [params].concat(args));

  if (!RefraxTools.isPromise(result)) {
    promise = new Promise(function(resolve, reject) {
      resolve(result);
    });
  }

  action._promises.push(promise);
  function finalize() {
    var i = action._promises.indexOf(promise);
    if (i > -1) {
      action._promises.splice(i, 1);
    }

    for (i=0; i<emitters.length; i++) {
      emitters[i].emit('finish');
    }
  }
  promise.then(finalize, finalize);

  promise.catch(function(response) {
    if (RefraxTools.isPlainObject(response.mutable)) {
      action.errors = RefraxTools.extend({}, response.mutable);
    }
    action.emit('change');
  });

  return promise;
}

function createActionInstance(template, method, options) {
  function ActionInstance(params, ...args) {
    return invokeAction([ActionInstance, template], method, params, options, args);
  }

  ActionInstance.getDefault = function() {
    var result = options.default || {};

    if (RefraxTools.isFunction(result)) {
      result = result();
    }

    if (result instanceof RefraxResource) {
      result = result.data || {};
    }
    else if (!RefraxTools.isPlainObject(result)) {
      throw new TypeError('ActionInstance ' + template + ' failed to resolve default value');
    }

    return result;
  };

  mixinSubscribable(ActionInstance);
  mixinStatus(ActionInstance);
  mixinMutable(ActionInstance);

  return ActionInstance;
}

function createAction(method) {
  if (this instanceof createAction) {
    throw new TypeError('Cannot call createAction as a class');
  }

  /**
   * An Action can either be globally invoked or instantiated and invoked on that
   * particular instance.
   */
  function Action(params, ...args) {
    if (this instanceof Action) {
      return createActionInstance(Action, method, params);
    }
    else {
      return invokeAction([Action], method, params, {}, args);
    }
  }
  // templates all share the same prototype so they can be identified above with instanceof
  RefraxTools.setPrototypeOf(Action, prototypeAction);

  mixinSubscribable(Action);
  mixinStatus(Action);
  mixinMutable(Action);

  return Action;
}

createAction.prototype = prototypeAction;

export default createAction;
<|endoftext|>


<commit_before>'use strict';

import request from 'request';
import {checkURL} from '../core/utils';

export default class RequestJSON {
  constructor() {
    this.appUrl = null;
    this.done = null;
    this.fail = null;
  }

  /**
   * Constructor
   * @param  {String} url The API URL
   */
  init(url) {
    this.apiUrl = checkURL(url);
    this.done = null;
    this.fail = null;
  }

  ajax(method, url) {
    const options = {
      method: method.toUpperCase(),
      url: this.apiUrl + url,
      headers: {
          'User-Agent': 'ironwing'
        }
    };
    console.log('fetching from ' + options.url);
    request(options, (err, res, body) => {
      if (err || !body) {
        this.fail.call();
      }
      else {
        this.done.call(null, JSON.parse(body));
      }
    });
  }

  /**
   * URL getter
   * @return {String} URL string
   */
  getAPIURL() {
    return this.apiUrl;
  }

  /**
   * Callback which is if the request is done
   * @param  {Function} callback Callback function
   * @return {Object}            Mjs
   */
  onDone(callback) {
    this.done = callback;

    return this;
  }

  /**
   * Callback which is if the request failed
   * @param  {Function} callback Callback function
   * @return {Object}            Mjs
   */
  onFail(callback) {
    this.fail = callback;

    return this;
  }
}
<commit_msg>Removed console log<commit_after>'use strict';

import request from 'request';
import {checkURL} from '../core/utils';

export default class RequestJSON {
  constructor() {
    this.appUrl = null;
    this.done = null;
    this.fail = null;
  }

  /**
   * Constructor
   * @param  {String} url The API URL
   */
  init(url) {
    this.apiUrl = checkURL(url);
    this.done = null;
    this.fail = null;
  }

  ajax(method, url) {
    const options = {
      method: method.toUpperCase(),
      url: this.apiUrl + url,
      headers: {
          'User-Agent': 'ironwing'
        }
    };
    request(options, (err, res, body) => {
      if (err || !body) {
        this.fail.call();
      }
      else {
        this.done.call(null, JSON.parse(body));
      }
    });
  }

  /**
   * URL getter
   * @return {String} URL string
   */
  getAPIURL() {
    return this.apiUrl;
  }

  /**
   * Callback which is if the request is done
   * @param  {Function} callback Callback function
   * @return {Object}            Mjs
   */
  onDone(callback) {
    this.done = callback;

    return this;
  }

  /**
   * Callback which is if the request failed
   * @param  {Function} callback Callback function
   * @return {Object}            Mjs
   */
  onFail(callback) {
    this.fail = callback;

    return this;
  }
}
<|endoftext|>


<commit_before>var Promise = require('es6-promise').Promise;
var generic = require('./generic');
var ddp     = require('./ddp');

module.exports = function makeDDPClient (ddpSetupProvider, myPrototype) {

  // TODO: check if arguments are ok

  var dataUpdatedPromise = Promise.resolve();

  var methods = [];

  myPrototype = myPrototype || {};

  myPrototype.login = function (data) {
    return this.call('login', [ data ]);
  };

  myPrototype.logout = function () {
    return this.call('logout', []);
  };

  myPrototype.waitForUpdates = function (name) {
    var myPromise = dataUpdatedPromise;
    return this.__custom__(function (operand, cb) {
      myPromise
        .then(function () {
          cb(null, operand.collections[name]);
        })
        .catch(cb);
    });
  };

  myPrototype.subscribe = function (name, args) {
    args = args || [];
    return this.__custom__(function (operand, cb) {
      operand.subscribe(name, args, cb);
    });
  };

  myPrototype.collection = function (name) {
    return this.__custom__(function (operand, cb) {
      cb(null, operand.collections[name]);
    });
  };

  myPrototype.call = function (name, args) {
    var myPromise = null;
    var myResolve;

    args = args || [];

    dataUpdatedPromise = dataUpdatedPromise.then(function () {
      return myPromise = myPromise || new Promise(function (resolve) {
        myResolve = resolve;
      });
    });

    return this.__custom__(function (operand, cb) {
      operand.call(name, args, cb, function () {
        if (myPromise) {
          myResolve();
        } else {
          myPromise = Promise.resolve();
        }
      });
    });
  };

  var DDPGeneric = generic(methods, myPrototype);

  var DDPClient = function () {
    DDPGeneric.call(this, ddp(ddpSetupProvider));
  };

  DDPClient.prototype = Object.create(new DDPGeneric(), {
    methods: { value: Object.keys(myPrototype).concat(DDPGeneric.prototype.methods) }
  });

  return new DDPClient();

}
<commit_msg>Handle helpers in a more consistent way<commit_after>var Promise = require('es6-promise').Promise;
var generic = require('./generic');
var ddp     = require('./ddp');

module.exports = function makeDDPClient (ddpSetupProvider, helpers) {

  // TODO: check if arguments are ok

  var dataUpdatedPromise = Promise.resolve();

  var methods = [];

  helpers = helpers || {};

  myPrototype = Object.create(helpers);

  myPrototype.login = function (data) {
    return this.call('login', [ data ]);
  };

  myPrototype.logout = function () {
    return this.call('logout', []);
  };

  myPrototype.waitForUpdates = function (name) {
    var myPromise = dataUpdatedPromise;
    return this.__custom__(function (operand, cb) {
      myPromise
        .then(function () {
          cb(null, operand.collections[name]);
        })
        .catch(cb);
    });
  };

  myPrototype.subscribe = function (name, args) {
    args = args || [];
    return this.__custom__(function (operand, cb) {
      operand.subscribe(name, args, cb);
    });
  };

  myPrototype.collection = function (name) {
    return this.__custom__(function (operand, cb) {
      cb(null, operand.collections[name]);
    });
  };

  myPrototype.call = function (name, args) {
    var myPromise = null;
    var myResolve;

    args = args || [];

    dataUpdatedPromise = dataUpdatedPromise.then(function () {
      return myPromise = myPromise || new Promise(function (resolve) {
        myResolve = resolve;
      });
    });

    return this.__custom__(function (operand, cb) {
      operand.call(name, args, cb, function () {
        if (myPromise) {
          myResolve();
        } else {
          myPromise = Promise.resolve();
        }
      });
    });
  };

  var DDPGeneric = generic(methods, myPrototype);

  var DDPClient = function () {
    DDPGeneric.call(this, ddp(ddpSetupProvider));
  };

  DDPClient.prototype = Object.create(new DDPGeneric(), {
    methods: { value: [].concat(Object.keys(myPrototype), Object.keys(helpers), DDPGeneric.prototype.methods) }
  });

  return new DDPClient();

}
<|endoftext|>


<commit_before>/*******************************************************************************
 * @license
 * Copyright (c) 2012 VMware, Inc. All Rights Reserved.
 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
 * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
 * CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
 * You can obtain a current copy of the Eclipse Public License from
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * Contributors:
 *     Kris De Volder - initial API and implementation
 ******************************************************************************/

/*global console require*/

//
// A servlet that provides access to the jsdepend api via
// http.
//

var url = require('url');
var servlets = require('../servlets');
var configuration = require('../jsdepend/filesystem');
var apiMaker = require('../jsdepend/api');
var makeRequestHandler = require('./servlet-utils').makeRequestHandler;

var conf = configuration.withBaseDir(null);
conf.sloppy = false;
var api = apiMaker.configure(conf);

var basePath = "/jsdepend";
   //where to serve all this api's functions. Each function will be served at
   // basePath + '/' + functionName

for (var functionName in api) {
	if (api.hasOwnProperty(functionName)) {
	    console.log('Creating servlet handler for function: '+functionName);
		var fun = api[functionName];
		if (typeof(fun)==='function') {
			servlets.register(basePath+"/"+functionName, makeRequestHandler(fun));
		} else {
		    console.log('SKIPPED: Not a function: '+functionName);
		}
	}
}
<commit_msg>Add comment about important but implicit dependency between dirwatch and sloppy resolution mode support.<commit_after>/*******************************************************************************
 * @license
 * Copyright (c) 2012 VMware, Inc. All Rights Reserved.
 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
 * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
 * CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
 * You can obtain a current copy of the Eclipse Public License from
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * Contributors:
 *     Kris De Volder - initial API and implementation
 ******************************************************************************/

/*global console require*/

//
// A servlet that provides access to the jsdepend api via
// http.
//

var url = require('url');
var servlets = require('../servlets');
var configuration = require('../jsdepend/filesystem');
var apiMaker = require('../jsdepend/api');
var makeRequestHandler = require('./servlet-utils').makeRequestHandler;

var conf = configuration.withBaseDir(null);
conf.sloppy = false; //IMPORTANT: if this gets switched back on... must also make sure
					 // to switch dirwatch back on (i.e. disable the FAKE mode)
var api = apiMaker.configure(conf);

var basePath = "/jsdepend";
   //where to serve all this api's functions. Each function will be served at
   // basePath + '/' + functionName

for (var functionName in api) {
	if (api.hasOwnProperty(functionName)) {
	    console.log('Creating servlet handler for function: '+functionName);
		var fun = api[functionName];
		if (typeof(fun)==='function') {
			servlets.register(basePath+"/"+functionName, makeRequestHandler(fun));
		} else {
		    console.log('SKIPPED: Not a function: '+functionName);
		}
	}
}
<|endoftext|>