<commit_before>// Callback called after line chart creation and update.  Responsible for creating/updating svg icons representing whether or not
// a point has comments on it.
// TODO: This should be part of one of the models.

var pointIconPreCall = function(visualization) {
  // Remove all previous comments icons within this visualization.
  d3.select(visualization.selectElement).selectAll('.svg-comment-icon').remove()
}
var pointIconCallback = function(visualization) {

  // Iterate over each element in data, where each element represents a line
  for (var dataIndex=0; dataIndex<visualization.data.length; dataIndex++) {

    // If the data has a hidden attribute set to true, that line is hidden, so we don't want to draw it's comment icons
    if (!visualization.data[dataIndex].hidden) {

      // Find the id on the data line, which is the id of the roastprofile associated with this line.
      var roastLineID = visualization.data[dataIndex].id.toString()

      // Construct the select string, we're looking for all of the circles ( points ) on a given roast profile's line
      var selectString = 'g.nv-group.nv-series-' + visualization.seriesMap[roastLineID] + ' > circle.nv-point'

      // Associate the data with each circle
      // TODO: Instead of attaching the whole data array to each circle, attach each corresponding value ( from data[x].values ) to the circle
      d3.selectAll(selectString).datum(visualization.data);

      // Iterate over each circle, that now has the associated data
      d3.selectAll(selectString).each(function(d, i) {

        // Grab the value that should match the circle we're iterating over, since the circles are in the same order as the data[x].values array

        if (d[dataIndex].values[i].hasComments) {
          var thisCircle = d3.select(this)

          var parentG = d3.select(thisCircle.node().parentNode)

          // Append the icon as an svg image to the parent g element, and set it to be near the point
          var iconSize = 16;
          parentG
            .append("image")
              .attr("xlink:href", URL.tempPoint.commentIcon)
              .attr("x", thisCircle.attr('cx'))
              .attr("y", (parseInt(thisCircle.attr('cy')) - iconSize).toString())
              .attr("width", iconSize)
              .attr("height", iconSize)
              // Give it a unique id that matched the temppoint's ID, so we can dynamically select it later
              // Used for when a temppoint has all of it's comments deleted, and needs to tell this node
              // to remove this comment icon.
              .attr("class", "svg-comment-icon temppoint_" + d[dataIndex].values[i].id);
        }
      })
    }
  }
}

// Options to be passed into the lineChartVisualization model.
lineOptions = {
  // selectElement is the element that the svg will be attached to when it is created.
  'selectElement': selectElement,
  // data is an array of objects, and looks like this:
  // [
  //   {
  // ---> # Values is an array of objects, where each object is the x and y coordinate of the point,
  // ---> # the id of that object (temppoint), and a boolean noting whether or not is hasComments.
  //     "values":
  //       [
  //         {"y": 80.0, "x": 0, "id": 62, "hasComments": false},
  //         {"y": 92.3, "x": 1, "id": 63, "hasComments": false},
  //         ...,
  //         ...,
  //         ...,
  //       ],
  // ---> # The id of the roastprofile
  //     "id": 4,
  // ---> # The name of the roastprofile, used for the legend ( not implemented )
  //     "key": "Miiri - 4"
  //   }
  // ]
  // data also supports another key, 'hidden', which should be a boolean, and on chartUpdate this will
  // hide or show the corresponding line.
  'data': data,
  'margin': margin,
  'width': width,
  'height': height,
  // Any functions put into this list will be called on createChart and updateChart.
  'storedCallbacks': [pointIconCallback],
  'preUpdateCalls': [pointIconPreCall],
  'seriesMap': seriesMap,
}

// Initialize Chart Model.
var lineChartVis = lineChartVisualization(lineOptions);

// Callback that sets all points in the graph to, once clicked, create a matching tempPoint model
// and create an empty comment form, with all previous comments of that tempPoint listed below it.
// This does not need to be updated, it will always run on any click of any point created within this chart.
var pointClickCallback = function(visualization) {
  visualization.nvchart.lines.dispatch.on('elementClick', null)
  visualization.nvchart.lines.dispatch.on('elementClick', function(element) {
    var pointOptions = {
      roastProfileID: element.series.id,
      id: element.point.id,
      URL: URL.tempPoint,
      visualization: visualization,
    }
    var tempPoint = tempPointModel(pointOptions);
    var ajaxCallCommentCreateForm = tempPoint.commentCreateForm();
    var callback = function(response) {

      $('#comments').html(response.data);

      // Setup click handler for the submit button
      $('#submit-pointcomment').click(function() {
        var ajaxCallCommentCreate = tempPoint.commentCreate('#id_comment');
        ajaxCallCommentCreate.done(function(){
          var ajaxCallCommentCreateFormInner = tempPoint.commentCreateForm();
          tempPoint.createPointIcon();
          ajaxCallCommentCreateFormInner.done(callback);
        })
      })

      // Setup click handler for the delete button.
      $('.comment-delete').click(function() {
        commentID = $(this).closest('div.comment').prop('id');
        var ajaxCallCommentDelete = tempPoint.commentDelete(commentID);
        ajaxCallCommentDelete.done(function(response) {
          $('#' + response.deletedCommentID).remove()

          if (!response.hasComments) {
            d3.select('.svg-comment-icon.temppoint_' + tempPoint.id).remove()
          }
        })
      })

      // Scroll the screen down to the comments div.
      var target= "div.comments";
      $('html, body').animate({
        scrollTop: $(target).offset().top
      }, 1000);
    }

    ajaxCallCommentCreateForm.done(callback)
  })
}

lineChartVis.createChart([pointClickCallback]);

var setRoastProfileGraphData = function(roastProfileID, callback) {

  var roastProfile = roastProfileModel({
    'id': roastProfileID,
    'URL': URL.roastProfile,
  })

  var ajaxCall = roastProfile.getGraphData();
  ajaxCall.done(callback)

}

var updateChartGraphData = function(roastProfileID) {

    var callback = function(response) {
      var graphData = response.graphData;
      var seriesCount = Object.keys(lineChartVis.seriesMap).length

      var dataAlreadyPresent = (roastProfileID in lineChartVis.seriesMap)

      if (dataAlreadyPresent) {
        lineChartVis.data[lineChartVis.seriesMap[roastProfileID]] = graphData
      } else {
        lineChartVis.seriesMap[roastProfileID] = seriesCount.toString()
        lineChartVis.data.push(graphData)
      }

      lineChartVis.updateChart();
    }
    setRoastProfileGraphData(roastProfileID, callback)

}
// Setup handler for roastprofile select form change, and loading data into chart.
$("#id_roastprofile_select").change(function() {

  var roastProfileID = $(this).val()

  if (!roastProfileID) { return }

  updateChartGraphData(roastProfileID)

})

// Setup handler for recording a new profile & stopping the recording process.
$("#listen-newprofile").click(function() {
  if (!$(this).data("listening")) {
    $(this).data("listening", true)
    $(this).val("Recording...  Click to stop recording.")

    var roastProfile = roastProfileModel({
      'URL': URL.roastProfile,
    })

    var callback = function(response) {
      var updateChart = function() {
        updateChartGraphData(roastProfile.id)
      }

      listenUpdatesID = setInterval(updateChart, 5000);

      // REPLACE ME - URL to send to RoastTron, so it knows where to send data to
      var HARD_CODED_URL = 'http%3A//roastdoge.herokuapp.com/roastprofile/' + roastProfile.id.toString() + '/temppoint/create/'
      // REPLACE ME - RoastTron URL
      ROASTTRON_URL = 'https://agent.electricimp.com/-bmsnEgKu4Wy/' //returnURL=' + HARD_CODED_URL

      var roastTronAjax = $.post(ROASTTRON_URL+'?record=1', {})
        .done(function (response) {
          console.log(response)
      })
    }

    var ajaxCall = roastProfile.create();
    ajaxCall.done(callback)

  } else {
    clearInterval(listenUpdatesID)
    $(this).data("listening", false)
    $(this).val("Start Recording a New Profile")

    var roastTronAjax = $.post(ROASTTRON_URL+'?record=0', {})
      .done(function (response) {
        console.log(response)
    })
  }
})
<commit_msg>RoastProfile ID in getURL is dynamic<commit_after>// Callback called after line chart creation and update.  Responsible for creating/updating svg icons representing whether or not
// a point has comments on it.
// TODO: This should be part of one of the models.

var pointIconPreCall = function(visualization) {
  // Remove all previous comments icons within this visualization.
  d3.select(visualization.selectElement).selectAll('.svg-comment-icon').remove()
}
var pointIconCallback = function(visualization) {

  // Iterate over each element in data, where each element represents a line
  for (var dataIndex=0; dataIndex<visualization.data.length; dataIndex++) {

    // If the data has a hidden attribute set to true, that line is hidden, so we don't want to draw it's comment icons
    if (!visualization.data[dataIndex].hidden) {

      // Find the id on the data line, which is the id of the roastprofile associated with this line.
      var roastLineID = visualization.data[dataIndex].id.toString()

      // Construct the select string, we're looking for all of the circles ( points ) on a given roast profile's line
      var selectString = 'g.nv-group.nv-series-' + visualization.seriesMap[roastLineID] + ' > circle.nv-point'

      // Associate the data with each circle
      // TODO: Instead of attaching the whole data array to each circle, attach each corresponding value ( from data[x].values ) to the circle
      d3.selectAll(selectString).datum(visualization.data);

      // Iterate over each circle, that now has the associated data
      d3.selectAll(selectString).each(function(d, i) {

        // Grab the value that should match the circle we're iterating over, since the circles are in the same order as the data[x].values array

        if (d[dataIndex].values[i].hasComments) {
          var thisCircle = d3.select(this)

          var parentG = d3.select(thisCircle.node().parentNode)

          // Append the icon as an svg image to the parent g element, and set it to be near the point
          var iconSize = 16;
          parentG
            .append("image")
              .attr("xlink:href", URL.tempPoint.commentIcon)
              .attr("x", thisCircle.attr('cx'))
              .attr("y", (parseInt(thisCircle.attr('cy')) - iconSize).toString())
              .attr("width", iconSize)
              .attr("height", iconSize)
              // Give it a unique id that matched the temppoint's ID, so we can dynamically select it later
              // Used for when a temppoint has all of it's comments deleted, and needs to tell this node
              // to remove this comment icon.
              .attr("class", "svg-comment-icon temppoint_" + d[dataIndex].values[i].id);
        }
      })
    }
  }
}

// Options to be passed into the lineChartVisualization model.
lineOptions = {
  // selectElement is the element that the svg will be attached to when it is created.
  'selectElement': selectElement,
  // data is an array of objects, and looks like this:
  // [
  //   {
  // ---> # Values is an array of objects, where each object is the x and y coordinate of the point,
  // ---> # the id of that object (temppoint), and a boolean noting whether or not is hasComments.
  //     "values":
  //       [
  //         {"y": 80.0, "x": 0, "id": 62, "hasComments": false},
  //         {"y": 92.3, "x": 1, "id": 63, "hasComments": false},
  //         ...,
  //         ...,
  //         ...,
  //       ],
  // ---> # The id of the roastprofile
  //     "id": 4,
  // ---> # The name of the roastprofile, used for the legend ( not implemented )
  //     "key": "Miiri - 4"
  //   }
  // ]
  // data also supports another key, 'hidden', which should be a boolean, and on chartUpdate this will
  // hide or show the corresponding line.
  'data': data,
  'margin': margin,
  'width': width,
  'height': height,
  // Any functions put into this list will be called on createChart and updateChart.
  'storedCallbacks': [pointIconCallback],
  'preUpdateCalls': [pointIconPreCall],
  'seriesMap': seriesMap,
}

// Initialize Chart Model.
var lineChartVis = lineChartVisualization(lineOptions);

// Callback that sets all points in the graph to, once clicked, create a matching tempPoint model
// and create an empty comment form, with all previous comments of that tempPoint listed below it.
// This does not need to be updated, it will always run on any click of any point created within this chart.
var pointClickCallback = function(visualization) {
  visualization.nvchart.lines.dispatch.on('elementClick', null)
  visualization.nvchart.lines.dispatch.on('elementClick', function(element) {
    var pointOptions = {
      roastProfileID: element.series.id,
      id: element.point.id,
      URL: URL.tempPoint,
      visualization: visualization,
    }
    var tempPoint = tempPointModel(pointOptions);
    var ajaxCallCommentCreateForm = tempPoint.commentCreateForm();
    var callback = function(response) {

      $('#comments').html(response.data);

      // Setup click handler for the submit button
      $('#submit-pointcomment').click(function() {
        var ajaxCallCommentCreate = tempPoint.commentCreate('#id_comment');
        ajaxCallCommentCreate.done(function(){
          var ajaxCallCommentCreateFormInner = tempPoint.commentCreateForm();
          tempPoint.createPointIcon();
          ajaxCallCommentCreateFormInner.done(callback);
        })
      })

      // Setup click handler for the delete button.
      $('.comment-delete').click(function() {
        commentID = $(this).closest('div.comment').prop('id');
        var ajaxCallCommentDelete = tempPoint.commentDelete(commentID);
        ajaxCallCommentDelete.done(function(response) {
          $('#' + response.deletedCommentID).remove()

          if (!response.hasComments) {
            d3.select('.svg-comment-icon.temppoint_' + tempPoint.id).remove()
          }
        })
      })

      // Scroll the screen down to the comments div.
      var target= "div.comments";
      $('html, body').animate({
        scrollTop: $(target).offset().top
      }, 1000);
    }

    ajaxCallCommentCreateForm.done(callback)
  })
}

lineChartVis.createChart([pointClickCallback]);

var setRoastProfileGraphData = function(roastProfileID, callback) {

  var roastProfile = roastProfileModel({
    'id': roastProfileID,
    'URL': URL.roastProfile,
  })

  var ajaxCall = roastProfile.getGraphData();
  ajaxCall.done(callback)

}

var updateChartGraphData = function(roastProfileID) {

    var callback = function(response) {
      var graphData = response.graphData;
      var seriesCount = Object.keys(lineChartVis.seriesMap).length

      var dataAlreadyPresent = (roastProfileID in lineChartVis.seriesMap)

      if (dataAlreadyPresent) {
        lineChartVis.data[lineChartVis.seriesMap[roastProfileID]] = graphData
      } else {
        lineChartVis.seriesMap[roastProfileID] = seriesCount.toString()
        lineChartVis.data.push(graphData)
      }

      lineChartVis.updateChart();
    }
    setRoastProfileGraphData(roastProfileID, callback)

}
// Setup handler for roastprofile select form change, and loading data into chart.
$("#id_roastprofile_select").change(function() {

  var roastProfileID = $(this).val()

  if (!roastProfileID) { return }

  updateChartGraphData(roastProfileID)

})

// Setup handler for recording a new profile & stopping the recording process.
$("#listen-newprofile").click(function() {
  if (!$(this).data("listening")) {
    $(this).data("listening", true)
    $(this).val("Recording...  Click to stop recording.")

    var roastProfile = roastProfileModel({
      'URL': URL.roastProfile,
    })

    var callback = function(response) {
      var updateChart = function() {
        updateChartGraphData(roastProfile.id)
      }

      listenUpdatesID = setInterval(updateChart, 5000);

      // REPLACE ME - URL to send to RoastTron, so it knows where to send data to
      var HARD_CODED_URL = 'roastdoge.herokuapp.com/roastprofile/' + roastProfile.id.toString() + '/temppoint/create/'
      // REPLACE ME - RoastTron URL
      ROASTTRON_URL = 'https://agent.electricimp.com/-bmsnEgKu4Wy/' //returnURL=' + HARD_CODED_URL

      var roastTronAjax = $.post(ROASTTRON_URL+'?record=1'+'&getURL='+HARD_CODED_URL, {})
        .done(function (response) {
          console.log(response)
      })
    }

    var ajaxCall = roastProfile.create();
    ajaxCall.done(callback)

  } else {
    clearInterval(listenUpdatesID)
    $(this).data("listening", false)
    $(this).val("Start Recording a New Profile")

    var roastTronAjax = $.post(ROASTTRON_URL+'?record=0', {})
      .done(function (response) {
        console.log(response)
    })
  }
})
<|endoftext|>


<commit_before>'use strict';

var renderDocument = require('./_business-process-document')
  , _ = require('mano').i18n.bind('View: Official');

exports._parent = require('./user-base');
exports._match = 'document';

exports['sub-main'] = {
	class: { content: true, 'user-forms': true },
	content: function () {
		var rejectReasonDescription = insert(_if(eq(this.document.owner._status, 'invalid'),
			div({ class: 'info-main' },
				p(_('This document was rejected for following reason:'), ' '),
				p(this.document.owner.rejectReasonMemo))));
		renderDocument(this.document, rejectReasonDescription);
	}
};
<commit_msg>Update reject reasons<commit_after>'use strict';

var renderDocument = require('./_business-process-document')
  , _ = require('mano').i18n.bind('View: Official')
  , identity = require('es5-ext/function/identity');

exports._parent = require('./user-base');
exports._match = 'document';

exports['sub-main'] = {
	class: { content: true, 'user-forms': true },
	content: function () {
		var rejectReasonDescription = insert(_if(eq(this.document.owner._status, 'invalid'),
			div({ class: 'info-main' },
				p(_('This document was rejected for following reasons:'), ' '),
				p(this.document.owner.rejectReasonMemo))));
		renderDocument(this.document, rejectReasonDescription);
	}
};
<|endoftext|>


<commit_before>/*
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You 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 parse_memory_value = function( value )
{
  if( value !== Number( value ) )
  {
    var units = 'BKMGTPEZY';
    var match = value.match( /^(\d+([,\.]\d+)?) (\w)\w?$/ );
    var value = parseFloat( match[1] ) * Math.pow( 1024, units.indexOf( match[3].toUpperCase() ) );
  }

  return value;
};

var generate_bar = function( bar_container, bar_data, convert_label_values )
{
  bar_holder = $( '.bar-holder', bar_container );

  var bar_level = 1;
  var max_width = Math.round( $( '.bar-max', bar_holder ).width() );
  $( '.bar-max.val', bar_holder ).text( bar_data['max'] );

  bar_level++;
  var total_width = Math.round( ( bar_data['total'] * max_width ) / bar_data['max'] );
  $( '.bar-total.bar', bar_holder ).width( Math.max( total_width, 1 ) );
  $( '.bar-total.val', bar_holder ).text( bar_data['total'] );

  if( bar_data['used'] )
  {
    bar_level++;
    var used_width = Math.round( ( bar_data['used'] * max_width ) / bar_data['max'] );
    $( '.bar-used.bar', bar_holder ).width( Math.min( used_width, total_width - 1 ) );
    $( '.bar-used.val', bar_holder ).text( bar_data['used'] );
  }

  bar_holder
    .addClass( 'bar-lvl-' + bar_level );

  var percentage = ( ( ( bar_data['used'] || bar_data['total'] ) / bar_data['max'] ) * 100 ).toFixed(1);

  var hl = $( '[data-desc="' + bar_container.attr( 'id' ) + '"]' );

  $( '.bar-desc', hl )
    .remove();

  hl
    .append( ' ' + percentage + '%' );

  if( !!convert_label_values )
  {
    $( '.val', bar_holder )
      .each
      (
        function()
        {
          var self = $( this );

          var unit = null;
          var byte_value = parseInt( self.html() );

          self
            .attr( 'title', 'raw: ' + byte_value + ' B' );

          byte_value /= 1024;
          byte_value /= 1024;
          unit = 'MB';

          if( 1024 <= byte_value )
          {
            byte_value /= 1024;
            unit = 'GB';
          }

          byte_value = byte_value.toFixed( 2 ) + ' ' + unit;

          self
            .text( byte_value );
        }
      );
  }
};

var system_info = function( element, system_data )
{
  // -- usage

  var load_average = system_data['system']['uptime'].match( /load average: (.+)/ );
  if( load_average && load_average[1] )
  {
    var hl = $( '#system h2', element );

    $( '.bar-desc', hl )
      .remove();

    hl
      .append( ' ' + load_average[1].split( ', ' ).join( '  ' ).esc() + '' );
  }

  // -- physical-memory-bar

  var bar_holder = $( '#physical-memory-bar', element );
  if( !system_data['system']['totalPhysicalMemorySize'] )
  {
    bar_holder.hide();
  }
  else
  {
    bar_holder.show();

    var bar_data = {
      'max' : parse_memory_value( system_data['system']['totalPhysicalMemorySize'] ),
      'total' : parse_memory_value( system_data['system']['totalPhysicalMemorySize'] - system_data['system']['freePhysicalMemorySize'] )
    };

    generate_bar( bar_holder, bar_data, true );
  }

  // -- swap-space-bar

  var bar_holder = $( '#swap-space-bar', element );
  if( !system_data['system']['totalSwapSpaceSize'] )
  {
    bar_holder.hide();
  }
  else
  {
    bar_holder.show();

    var bar_data = {
      'max' : parse_memory_value( system_data['system']['totalSwapSpaceSize'] ),
      'total' : parse_memory_value( system_data['system']['totalSwapSpaceSize'] - system_data['system']['freeSwapSpaceSize'] )
    };

    generate_bar( bar_holder, bar_data, true );
  }

  // -- swap-space-bar

  var bar_holder = $( '#file-descriptor-bar', element );
  if( !system_data['system']['maxFileDescriptorCount'] )
  {
    bar_holder.hide();
  }
  else
  {
    bar_holder.show();

    var bar_data = {
      'max' : parse_memory_value( system_data['system']['maxFileDescriptorCount'] ),
      'total' : parse_memory_value( system_data['system']['openFileDescriptorCount'] )
    };

    generate_bar( bar_holder, bar_data );
  }

  0 === $( '#system div[id$="-bar"]:visible', element ).size()
    ? $( '#system .no-info', element ).show()
    : $( '#system .no-info', element ).hide();

  // -- memory-bar

  var jvm_memory = $.extend
  (
    {
      'free' : null,
      'total' : null,
      'max' : null,
      'used' : null,
      'raw' : {
        'free' : null,
        'total' : null,
        'max' : null,
        'used' : null,
        'used%' : null
      }
    },
    system_data['jvm']['memory']
  );

  var bar_holder = $( '#jvm-memory-bar', element );
  var bar_data = {
    'max' : parse_memory_value( jvm_memory['raw']['max'] || jvm_memory['max'] ),
    'total' : parse_memory_value( jvm_memory['raw']['total'] || jvm_memory['total'] ),
    'used' : parse_memory_value( jvm_memory['raw']['used'] || jvm_memory['used'] )
  };

  generate_bar( bar_holder, bar_data, true );
}

// #/
sammy.get
(
  /^#\/$/,
  function( context )
  {
    var content_element = $( '#content' );

    $( '#menu-wrapper #index' )
      .addClass( 'active' );

    content_element
      .html( '

' );

    $.ajax
    (
      {
        url : 'tpl/index.html',
        context : $( '#index', content_element ),
        beforeSend : function( arr, form, options )
        {
        },
        success : function( template )
        {
          var self = this;

          this
            .html( template );

          var data = {
            'start_time' : app.dashboard_values['jvm']['jmx']['startTime'],
            'host' : app.dashboard_values['core']['host'],
            'dir_instance' : app.dashboard_values['core']['directory']['instance'],
            'dir_data' : app.dashboard_values['core']['directory']['data'],
            'dir_index' : app.dashboard_values['core']['directory']['index'],
            'jvm_version' : app.dashboard_values['jvm']['name'] + ' (' + app.dashboard_values['jvm']['version'] + ')',
            'processors' : app.dashboard_values['jvm']['processors'],
            'solr_spec_version' : app.dashboard_values['lucene']['solr-spec-version'],
            'solr_impl_version' : app.dashboard_values['lucene']['solr-impl-version'],
            'lucene_spec_version' : app.dashboard_values['lucene']['lucene-spec-version'],
            'lucene_impl_version' : app.dashboard_values['lucene']['lucene-impl-version']
          };

          if( app.dashboard_values['core']['directory']['cwd'] )
          {
            data['dir_cwd'] = app.dashboard_values['core']['directory']['cwd'];
          }

          for( var key in data )
          {
            var value_element = $( '.' + key + ' dd', this );

            value_element
              .text( data[key].esc() );

            value_element.closest( 'li' )
              .show();
          }

          var commandLineArgs = app.dashboard_values['jvm']['jmx']['commandLineArgs'];
          if( 0 !== commandLineArgs.length )
          {
            var cmd_arg_element = $( '.command_line_args dt', this );
            var cmd_arg_key_element = $( '.command_line_args dt', this );
            var cmd_arg_element = $( '.command_line_args dd', this );

            for( var key in commandLineArgs )
            {
              cmd_arg_element = cmd_arg_element.clone();
              cmd_arg_element.text( commandLineArgs[key] );

              cmd_arg_key_element
                .after( cmd_arg_element );
            }

            cmd_arg_key_element.closest( 'li' )
              .show();

            $( '.command_line_args dd:last', this )
              .remove();

            $( '.command_line_args dd:odd', this )
              .addClass( 'odd' );
          }

          $( '.timeago', this )
            .timeago();

          $( '.index-left .block li:visible:odd', this )
            .addClass( 'odd' );

          // -- system_info

          system_info( this, app.dashboard_values );

          $( '#system a.reload', this )
            .die( 'click' )
            .live
            (
              'click',
              function( event )
              {
                $.ajax
                (
                  {
                    url : environment_basepath + '/admin/system?wt=json',
                    dataType : 'json',
                    context : this,
                    beforeSend : function( arr, form, options )
                    {
                      loader.show( this );
                    },
                    success : function( response )
                    {
                      system_info( self, response );
                    },
                    error : function()
                    {
                    },
                    complete : function()
                    {
                      loader.hide( this );
                    }
                  }
                );

                return false;
              }
            );
        },
        error : function( xhr, text_status, error_thrown )
        {
        },
        complete : function( xhr, text_status )
        {
        }
      }
    );
  }
);<commit_msg>SOLR-3311: fix dashboard view on windows<commit_after>/*
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You 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 parse_memory_value = function( value )
{
  if( value !== Number( value ) )
  {
    var units = 'BKMGTPEZY';
    var match = value.match( /^(\d+([,\.]\d+)?) (\w)\w?$/ );
    var value = parseFloat( match[1] ) * Math.pow( 1024, units.indexOf( match[3].toUpperCase() ) );
  }

  return value;
};

var generate_bar = function( bar_container, bar_data, convert_label_values )
{
  bar_holder = $( '.bar-holder', bar_container );

  var bar_level = 1;
  var max_width = Math.round( $( '.bar-max', bar_holder ).width() );
  $( '.bar-max.val', bar_holder ).text( bar_data['max'] );

  bar_level++;
  var total_width = Math.round( ( bar_data['total'] * max_width ) / bar_data['max'] );
  $( '.bar-total.bar', bar_holder ).width( Math.max( total_width, 1 ) );
  $( '.bar-total.val', bar_holder ).text( bar_data['total'] );

  if( bar_data['used'] )
  {
    bar_level++;
    var used_width = Math.round( ( bar_data['used'] * max_width ) / bar_data['max'] );
    $( '.bar-used.bar', bar_holder ).width( Math.min( used_width, total_width - 1 ) );
    $( '.bar-used.val', bar_holder ).text( bar_data['used'] );
  }

  bar_holder
    .addClass( 'bar-lvl-' + bar_level );

  var percentage = ( ( ( bar_data['used'] || bar_data['total'] ) / bar_data['max'] ) * 100 ).toFixed(1);

  var hl = $( '[data-desc="' + bar_container.attr( 'id' ) + '"]' );

  $( '.bar-desc', hl )
    .remove();

  hl
    .append( ' ' + percentage + '%' );

  if( !!convert_label_values )
  {
    $( '.val', bar_holder )
      .each
      (
        function()
        {
          var self = $( this );

          var unit = null;
          var byte_value = parseInt( self.html() );

          self
            .attr( 'title', 'raw: ' + byte_value + ' B' );

          byte_value /= 1024;
          byte_value /= 1024;
          unit = 'MB';

          if( 1024 <= byte_value )
          {
            byte_value /= 1024;
            unit = 'GB';
          }

          byte_value = byte_value.toFixed( 2 ) + ' ' + unit;

          self
            .text( byte_value );
        }
      );
  }
};

var system_info = function( element, system_data )
{
  // -- usage

  var load_average = ( system_data['system']['uptime'] || '' ).match( /load average: (.+)/ );
  if( load_average && load_average[1] )
  {
    var hl = $( '#system h2', element );

    $( '.bar-desc', hl )
      .remove();

    hl
      .append( ' ' + load_average[1].split( ', ' ).join( '  ' ).esc() + '' );
  }

  // -- physical-memory-bar

  var bar_holder = $( '#physical-memory-bar', element );
  if( !system_data['system']['totalPhysicalMemorySize'] )
  {
    bar_holder.hide();
  }
  else
  {
    bar_holder.show();

    var bar_data = {
      'max' : parse_memory_value( system_data['system']['totalPhysicalMemorySize'] ),
      'total' : parse_memory_value( system_data['system']['totalPhysicalMemorySize'] - system_data['system']['freePhysicalMemorySize'] )
    };

    generate_bar( bar_holder, bar_data, true );
  }

  // -- swap-space-bar

  var bar_holder = $( '#swap-space-bar', element );
  if( !system_data['system']['totalSwapSpaceSize'] )
  {
    bar_holder.hide();
  }
  else
  {
    bar_holder.show();

    var bar_data = {
      'max' : parse_memory_value( system_data['system']['totalSwapSpaceSize'] ),
      'total' : parse_memory_value( system_data['system']['totalSwapSpaceSize'] - system_data['system']['freeSwapSpaceSize'] )
    };

    generate_bar( bar_holder, bar_data, true );
  }

  // -- swap-space-bar

  var bar_holder = $( '#file-descriptor-bar', element );
  if( !system_data['system']['maxFileDescriptorCount'] )
  {
    bar_holder.hide();
  }
  else
  {
    bar_holder.show();

    var bar_data = {
      'max' : parse_memory_value( system_data['system']['maxFileDescriptorCount'] ),
      'total' : parse_memory_value( system_data['system']['openFileDescriptorCount'] )
    };

    generate_bar( bar_holder, bar_data );
  }

  0 === $( '#system div[id$="-bar"]:visible', element ).size()
    ? $( '#system .no-info', element ).show()
    : $( '#system .no-info', element ).hide();

  // -- memory-bar

  var jvm_memory = $.extend
  (
    {
      'free' : null,
      'total' : null,
      'max' : null,
      'used' : null,
      'raw' : {
        'free' : null,
        'total' : null,
        'max' : null,
        'used' : null,
        'used%' : null
      }
    },
    system_data['jvm']['memory']
  );

  var bar_holder = $( '#jvm-memory-bar', element );
  var bar_data = {
    'max' : parse_memory_value( jvm_memory['raw']['max'] || jvm_memory['max'] ),
    'total' : parse_memory_value( jvm_memory['raw']['total'] || jvm_memory['total'] ),
    'used' : parse_memory_value( jvm_memory['raw']['used'] || jvm_memory['used'] )
  };

  generate_bar( bar_holder, bar_data, true );
}

// #/
sammy.get
(
  /^#\/$/,
  function( context )
  {
    var content_element = $( '#content' );

    $( '#menu-wrapper #index' )
      .addClass( 'active' );

    content_element
      .html( '

' );

    $.ajax
    (
      {
        url : 'tpl/index.html',
        context : $( '#index', content_element ),
        beforeSend : function( arr, form, options )
        {
        },
        success : function( template )
        {
          var self = this;

          this
            .html( template );

          var data = {
            'start_time' : app.dashboard_values['jvm']['jmx']['startTime'],
            'host' : app.dashboard_values['core']['host'],
            'dir_instance' : app.dashboard_values['core']['directory']['instance'],
            'dir_data' : app.dashboard_values['core']['directory']['data'],
            'dir_index' : app.dashboard_values['core']['directory']['index'],
            'jvm_version' : app.dashboard_values['jvm']['name'] + ' (' + app.dashboard_values['jvm']['version'] + ')',
            'processors' : app.dashboard_values['jvm']['processors'],
            'solr_spec_version' : app.dashboard_values['lucene']['solr-spec-version'] || '-',
            'solr_impl_version' : app.dashboard_values['lucene']['solr-impl-version'] || '-',
            'lucene_spec_version' : app.dashboard_values['lucene']['lucene-spec-version'] || '-',
            'lucene_impl_version' : app.dashboard_values['lucene']['lucene-impl-version'] || '-'
          };

          if( app.dashboard_values['core']['directory']['cwd'] )
          {
            data['dir_cwd'] = app.dashboard_values['core']['directory']['cwd'];
          }

          for( var key in data )
          {
            var value_element = $( '.' + key + ' dd', this );

            value_element
              .text( data[key].esc() );

            value_element.closest( 'li' )
              .show();
          }

          var commandLineArgs = app.dashboard_values['jvm']['jmx']['commandLineArgs'];
          if( 0 !== commandLineArgs.length )
          {
            var cmd_arg_element = $( '.command_line_args dt', this );
            var cmd_arg_key_element = $( '.command_line_args dt', this );
            var cmd_arg_element = $( '.command_line_args dd', this );

            for( var key in commandLineArgs )
            {
              cmd_arg_element = cmd_arg_element.clone();
              cmd_arg_element.text( commandLineArgs[key] );

              cmd_arg_key_element
                .after( cmd_arg_element );
            }

            cmd_arg_key_element.closest( 'li' )
              .show();

            $( '.command_line_args dd:last', this )
              .remove();

            $( '.command_line_args dd:odd', this )
              .addClass( 'odd' );
          }

          $( '.timeago', this )
            .timeago();

          $( '.index-left .block li:visible:odd', this )
            .addClass( 'odd' );

          // -- system_info

          system_info( this, app.dashboard_values );

          $( '#system a.reload', this )
            .die( 'click' )
            .live
            (
              'click',
              function( event )
              {
                $.ajax
                (
                  {
                    url : environment_basepath + '/admin/system?wt=json',
                    dataType : 'json',
                    context : this,
                    beforeSend : function( arr, form, options )
                    {
                      loader.show( this );
                    },
                    success : function( response )
                    {
                      system_info( self, response );
                    },
                    error : function()
                    {
                    },
                    complete : function()
                    {
                      loader.hide( this );
                    }
                  }
                );

                return false;
              }
            );
        },
        error : function( xhr, text_status, error_thrown )
        {
        },
        complete : function( xhr, text_status )
        {
        }
      }
    );
  }
);<|endoftext|>


<commit_before>#! /usr/bin/env node

(function () {
    var _ = require("lodash");
    var args = _.rest(_.toArray(process.argv), 2);
    var path = require('path');
    var index_path = path.resolve(__dirname, '..', "index.js");
    var execFile = require('child_process').execFile;
    var max_mem = process.env.MAX_MEM;
    args.unshift(index_path);
    if (max_mem) {
        args.unshift("--max-old-space-size=" + max_mem);
    }
    var child = execFile('node', args);
    child.unref();
    child.stdout.on('data', function (data) {
        console.log(data.toString());
    });
    child.stderr.on('data', function (data) {
        console.log(data.toString());
    });
})();
<commit_msg>refined telegram.js<commit_after>#! /usr/bin/env node

(function () {
    var _ = require("lodash");
    var args = _.toArray(process.argv);
    var telegg_position = _.findIndex(args, function(el){
      return el.indexOf("telegrammer") != -1;
    });
    args = args.slice(telegg_position + 1);
    var path = require('path');
    var index_path = path.resolve(__dirname, '..', "index.js");
    var execFile = require('child_process').execFile;
    var max_mem = process.env.MAX_MEM;
    args.unshift(index_path);
    if (max_mem) {
        args.unshift("--max-old-space-size=" + max_mem);
    }
    var child = execFile('node', args);
    child.unref();
    child.stdout.on('data', function (data) {
        console.log(data.toString());
    });
    child.stderr.on('data', function (data) {
        console.log(data.toString());
    });
})();
<|endoftext|>


<commit_before>/**
 * Implementation of the `akismet.Server` class.
 * @module server/server
 */
const {Author, Blog, Comment, EndPoints, HTTPHeaders} = require('../core');
const bodyParser = require('body-parser');
const {Client} = require('../client');
const cors = require('cors');
const {EventEmitter} = require('events');
const express = require('express');
const http = require('http');
const https = require('https');
const url = require('url');

/**
 * An HTTP server that acts as a proxy between clients and the [Akismet](https://akismet.com) service.
 * @augments events.EventEmitter
 */
class Server extends EventEmitter {

  /**
   * Emitted when the server closes.
   * @event close
   */

  /**
   * Emitted each time the server experiences an error.
   * @event error
   * @param {Error} err The emitted error event.
   */

  /**
   * Emitted when the server has been bound after calling `listen` method.
   * @event listening
   */

  /**
   * Emitted each time there is a request.
   * @event request
   * @param {http.IncomingMessage} req The request sent by the client.
   */

  /**
   * Initializes a new instance of the class.
   * @param {object} [options] An object specifying values used to initialize this instance.
   */
  constructor(options = {}) {
    super();

    /**
     * The underlying [Express](http://expressjs.com/api.html#express) application used for routing requests.
     * @type {function}
     * @private
     */
    this._express = express();
    this._express.disable('x-powered-by');
    this._registerMiddleware();
    this._registerRoutes();

    /**
     * The underlying HTTP(S) service listening for requests.
     * @type {(http.Server|https.Server)}
     * @private
     */
    this._httpService = null;

    /**
     * The server settings.
     * @type {object}
     * @private
     */
    this._options = options;
  }

  /**
   * The default address that the server is listening on.
   * @type {string}
   */
  static get DEFAULT_ADDRESS() {
    return '0.0.0.0';
  }

  /**
   * The default port that the server is listening on.
   * @type {number}
   */
  static get DEFAULT_PORT() {
    return 3000;
  }

  /**
   * The address that the server is listening on.
   * @type {string}
   */
  get address() {
    return typeof this._options.address == 'string' ? this._options.address : Server.DEFAULT_ADDRESS;
  }

  /**
   * The port that the server is listening on.
   * @type {number}
   */
  get port() {
    return typeof this._options.port == 'number' ? this._options.port : Server.DEFAULT_PORT;
  }

  /**
   * The URL to redirect the user when a request is unhandled.
   * If this property is empty, a 404 status code is sent instead of redirecting.
   * @type {string}
   */
  get redirectURL() {
    return typeof this._options.redirectURL == 'string' && this._options.redirectURL.length ? this._options.redirectURL : null;
  }

  /**
   * Checks a comment against the service database, and prints a value indicating whether it is spam.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server.
   * @returns {Promise} Completes once the comment has been checked.
   * @throws {Error} The specified request is invalid.
   */
  checkComment(req, res) {
    if(!('akismet' in req) || !('client' in req.akismet)) throw new Error('Invalid request.');

    let client = req.akismet.client;
    return client.checkComment(req.akismet.comment).then(
      isSpam => Server._sendResponse(res, isSpam ? 'true' : 'false'),
      err => { Server._sendResponse(res, 'invalid', err); this.emit('error', err); }
    );
  }

  /**
   * Stops the server from accepting new connections.
   * @returns {Promise} Completes when the server is finally closed.
   */
  close() {
    if(!this._httpService) return Promise.resolve();

    return new Promise(resolve => this._httpService.close(() => {
      this._httpService = null;
      this.emit('close');
      resolve();
    }));
  }

  /**
   * Begin accepting connections.
   * @param {number} [port] The port that the server should run on.
   * @param {string} [address] The address that the server should run on.
   * @returns {Promise} Completes when the server has been started.
   */
  listen(port = -1, address = '') {
    if(port <= 0) port = this.port;
    if(!address.length) address = this.address;

    this._httpService =
      'ssl' in this._options ?
      https.createServer(this._options.ssl, this._express) :
      http.createServer(this._express);

    this._httpService.on('clientError', err => this.emit('error', err));
    this._httpService.on('request', req => this.emit('request', req));

    return new Promise(resolve => this._httpService.listen(port, address, () => {
      let address = this._httpService.address();
      this._options.address = address.address;
      this._options.port = address.port;

      this.emit('listening');
      resolve();
    }));
  }

  /**
   * Submits a comment that was incorrectly marked as spam but should not have been.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server.
   * @returns {Promise} Completes once the comment has been submitted.
   * @throws {Error} The specified request is invalid.
   */
  submitHam(req, res) {
    if(!('akismet' in req) || !('client' in req.akismet)) throw new Error('Invalid request.');

    let client = req.akismet.client;
    return client.submitHam(req.akismet.comment).then(
      () => Server._sendResponse(res, 'Thanks for making the web a better place.'),
      err => { Server._sendResponse(res, '', err); this.emit('error', err); }
    );
  }

  /**
   * Submits a comment that was not marked as spam but should have been.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server.
   * @returns {Promise} Completes once the comment has been submitted.
   * @throws {Error} The specified request is invalid.
   */
  submitSpam(req, res) {
    if(!('akismet' in req) || !('client' in req.akismet)) throw new Error('Invalid request.');

    let client = req.akismet.client;
    return client.submitSpam(req.akismet.comment).then(
      () => Server._sendResponse(res, 'Thanks for making the web a better place.'),
      err => { Server._sendResponse(res, '', err); this.emit('error', err); }
    );
  }

  /**
   * Checks an API key against the service database, and prints a value indicating whether it is a valid key.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server. The response sent by the server.
   * @returns {Promise} Completes once the API key has been checked.
   * @throws {Error} The specified request is invalid.
   */
  verifyKey(req, res) {
    if(!('akismet' in req) || !('client' in req.akismet)) throw new Error('Invalid request.');

    let client = req.akismet.client;
    return client.verifyKey().then(
      isValid => Server._sendResponse(res, isValid ? 'valid' : 'invalid'),
      err => { Server._sendResponse(res, 'invalid', err); this.emit('error', err); }
    );
  }

  /**
   * Processes the specified request body.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server.
   * @param {Function} next The callback used to pass the request off to the next middleware.
   * @private
   */
  static _processRequest(req, res, next) {
    // Parse client arguments.
    let apiKey = 'key' in req.body ? req.body.key : req.hostname.split('.')[0];
    let userAgent = HTTPHeaders.X_USER_AGENT in req.headers ? req.headers[HTTPHeaders.X_USER_AGENT] : req.headers['user-agent'];
    let client = new Client(apiKey, Blog.fromJSON(req.body), {userAgent});

    // Parse comment values.
    let comment = Comment.fromJSON(req.body);
    if(!comment.author) comment.author = new Author();
    if(!comment.author.ipAddress) comment.author.ipAddress = req.connection.remoteAddress;

    // Update request properties.
    req.akismet = {client, comment};
    next();
  }

  /**
   * Registers the middleware.
   * @private
   */
  _registerMiddleware() {
    this._express.use(cors({
      allowedHeaders: [HTTPHeaders.X_REQUESTED_WITH, HTTPHeaders.X_USER_AGENT],
      exposedHeaders: [HTTPHeaders.X_AKISMET_DEBUG_HELP],
      methods: ['GET', 'POST'],
      origin: '*'
    }));

    this._express.use(bodyParser.urlencoded({extended: true}));
    this._express.use(Server._processRequest);
  }

  /**
   * Registers the route table.
   * @private
   */
  _registerRoutes() {
    this._express.post(EndPoints.CHECK_COMMENT, this.checkComment.bind(this));
    this._express.post(EndPoints.SUBMIT_HAM, this.submitHam.bind(this));
    this._express.post(EndPoints.SUBMIT_SPAM, this.submitSpam.bind(this));
    this._express.post(EndPoints.VERIFY_KEY, this.verifyKey.bind(this));

    this._express.all('*', (req, res) => {
      if(req.method == 'OPTIONS')
        res.status(204).end();
      else {
        let redirect = this.redirectURL;
        if(typeof redirect == 'string') res.redirect(301, url.resolve(redirect, req.url));
        else res.status(404).send(http.STATUS_CODES[404]);
      }
    });
  }

  /**
   * Sends the specified response body.
   * @param {express.Response} res The response sent by the server.
   * @param {string} body The response body to send to the client.
   * @param {Error} [error] An error message to add to the response headers as `HTTPHeaders.X_AKISMET_DEBUG_HELP`.
   * @private
   */
  static _sendResponse(res, body, error) {
    res.type('text/plain; charset=utf-8');
    if(typeof error != 'undefined') res.set(HTTPHeaders.X_AKISMET_DEBUG_HELP, error.toString());
    res.send(body);
  }
}

// Public interface.
module.exports = Server;
<commit_msg>Avoid variable shadowing<commit_after>/**
 * Implementation of the `akismet.Server` class.
 * @module server/server
 */
const {Author, Blog, Comment, EndPoints, HTTPHeaders} = require('../core');
const bodyParser = require('body-parser');
const {Client} = require('../client');
const cors = require('cors');
const {EventEmitter} = require('events');
const express = require('express');
const http = require('http');
const https = require('https');
const url = require('url');

/**
 * An HTTP server that acts as a proxy between clients and the [Akismet](https://akismet.com) service.
 * @augments events.EventEmitter
 */
class Server extends EventEmitter {

  /**
   * Emitted when the server closes.
   * @event close
   */

  /**
   * Emitted each time the server experiences an error.
   * @event error
   * @param {Error} err The emitted error event.
   */

  /**
   * Emitted when the server has been bound after calling `listen` method.
   * @event listening
   */

  /**
   * Emitted each time there is a request.
   * @event request
   * @param {http.IncomingMessage} req The request sent by the client.
   */

  /**
   * Initializes a new instance of the class.
   * @param {object} [options] An object specifying values used to initialize this instance.
   */
  constructor(options = {}) {
    super();

    /**
     * The underlying [Express](http://expressjs.com/api.html#express) application used for routing requests.
     * @type {function}
     * @private
     */
    this._express = express();
    this._express.disable('x-powered-by');
    this._registerMiddleware();
    this._registerRoutes();

    /**
     * The underlying HTTP(S) service listening for requests.
     * @type {(http.Server|https.Server)}
     * @private
     */
    this._httpService = null;

    /**
     * The server settings.
     * @type {object}
     * @private
     */
    this._options = options;
  }

  /**
   * The default address that the server is listening on.
   * @type {string}
   */
  static get DEFAULT_ADDRESS() {
    return '0.0.0.0';
  }

  /**
   * The default port that the server is listening on.
   * @type {number}
   */
  static get DEFAULT_PORT() {
    return 3000;
  }

  /**
   * The address that the server is listening on.
   * @type {string}
   */
  get address() {
    return typeof this._options.address == 'string' ? this._options.address : Server.DEFAULT_ADDRESS;
  }

  /**
   * The port that the server is listening on.
   * @type {number}
   */
  get port() {
    return typeof this._options.port == 'number' ? this._options.port : Server.DEFAULT_PORT;
  }

  /**
   * The URL to redirect the user when a request is unhandled.
   * If this property is empty, a 404 status code is sent instead of redirecting.
   * @type {string}
   */
  get redirectURL() {
    return typeof this._options.redirectURL == 'string' && this._options.redirectURL.length ? this._options.redirectURL : null;
  }

  /**
   * Checks a comment against the service database, and prints a value indicating whether it is spam.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server.
   * @returns {Promise} Completes once the comment has been checked.
   * @throws {Error} The specified request is invalid.
   */
  checkComment(req, res) {
    if(!('akismet' in req) || !('client' in req.akismet)) throw new Error('Invalid request.');

    let client = req.akismet.client;
    return client.checkComment(req.akismet.comment).then(
      isSpam => Server._sendResponse(res, isSpam ? 'true' : 'false'),
      err => { Server._sendResponse(res, 'invalid', err); this.emit('error', err); }
    );
  }

  /**
   * Stops the server from accepting new connections.
   * @returns {Promise} Completes when the server is finally closed.
   */
  close() {
    if(!this._httpService) return Promise.resolve();

    return new Promise(resolve => this._httpService.close(() => {
      this._httpService = null;
      this.emit('close');
      resolve();
    }));
  }

  /**
   * Begin accepting connections.
   * @param {number} [port] The port that the server should run on.
   * @param {string} [address] The address that the server should run on.
   * @returns {Promise} Completes when the server has been started.
   */
  listen(port = -1, address = '') {
    if(port <= 0) port = this.port;
    if(!address.length) address = this.address;

    this._httpService =
      'ssl' in this._options ?
      https.createServer(this._options.ssl, this._express) :
      http.createServer(this._express);

    this._httpService.on('clientError', err => this.emit('error', err));
    this._httpService.on('request', req => this.emit('request', req));

    return new Promise(resolve => this._httpService.listen(port, address, () => {
      let socket = this._httpService.address();
      this._options.address = socket.address;
      this._options.port = socket.port;

      this.emit('listening');
      resolve();
    }));
  }

  /**
   * Submits a comment that was incorrectly marked as spam but should not have been.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server.
   * @returns {Promise} Completes once the comment has been submitted.
   * @throws {Error} The specified request is invalid.
   */
  submitHam(req, res) {
    if(!('akismet' in req) || !('client' in req.akismet)) throw new Error('Invalid request.');

    let client = req.akismet.client;
    return client.submitHam(req.akismet.comment).then(
      () => Server._sendResponse(res, 'Thanks for making the web a better place.'),
      err => { Server._sendResponse(res, '', err); this.emit('error', err); }
    );
  }

  /**
   * Submits a comment that was not marked as spam but should have been.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server.
   * @returns {Promise} Completes once the comment has been submitted.
   * @throws {Error} The specified request is invalid.
   */
  submitSpam(req, res) {
    if(!('akismet' in req) || !('client' in req.akismet)) throw new Error('Invalid request.');

    let client = req.akismet.client;
    return client.submitSpam(req.akismet.comment).then(
      () => Server._sendResponse(res, 'Thanks for making the web a better place.'),
      err => { Server._sendResponse(res, '', err); this.emit('error', err); }
    );
  }

  /**
   * Checks an API key against the service database, and prints a value indicating whether it is a valid key.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server. The response sent by the server.
   * @returns {Promise} Completes once the API key has been checked.
   * @throws {Error} The specified request is invalid.
   */
  verifyKey(req, res) {
    if(!('akismet' in req) || !('client' in req.akismet)) throw new Error('Invalid request.');

    let client = req.akismet.client;
    return client.verifyKey().then(
      isValid => Server._sendResponse(res, isValid ? 'valid' : 'invalid'),
      err => { Server._sendResponse(res, 'invalid', err); this.emit('error', err); }
    );
  }

  /**
   * Processes the specified request body.
   * @param {express.Request} req The request sent by a client.
   * @param {express.Response} res The response sent by the server.
   * @param {Function} next The callback used to pass the request off to the next middleware.
   * @private
   */
  static _processRequest(req, res, next) {
    // Parse client arguments.
    let apiKey = 'key' in req.body ? req.body.key : req.hostname.split('.')[0];
    let userAgent = HTTPHeaders.X_USER_AGENT in req.headers ? req.headers[HTTPHeaders.X_USER_AGENT] : req.headers['user-agent'];
    let client = new Client(apiKey, Blog.fromJSON(req.body), {userAgent});

    // Parse comment values.
    let comment = Comment.fromJSON(req.body);
    if(!comment.author) comment.author = new Author();
    if(!comment.author.ipAddress) comment.author.ipAddress = req.connection.remoteAddress;

    // Update request properties.
    req.akismet = {client, comment};
    next();
  }

  /**
   * Registers the middleware.
   * @private
   */
  _registerMiddleware() {
    this._express.use(cors({
      allowedHeaders: [HTTPHeaders.X_REQUESTED_WITH, HTTPHeaders.X_USER_AGENT],
      exposedHeaders: [HTTPHeaders.X_AKISMET_DEBUG_HELP],
      methods: ['GET', 'POST'],
      origin: '*'
    }));

    this._express.use(bodyParser.urlencoded({extended: true}));
    this._express.use(Server._processRequest);
  }

  /**
   * Registers the route table.
   * @private
   */
  _registerRoutes() {
    this._express.post(EndPoints.CHECK_COMMENT, this.checkComment.bind(this));
    this._express.post(EndPoints.SUBMIT_HAM, this.submitHam.bind(this));
    this._express.post(EndPoints.SUBMIT_SPAM, this.submitSpam.bind(this));
    this._express.post(EndPoints.VERIFY_KEY, this.verifyKey.bind(this));

    this._express.all('*', (req, res) => {
      if(req.method == 'OPTIONS')
        res.status(204).end();
      else {
        let redirect = this.redirectURL;
        if(typeof redirect == 'string') res.redirect(301, url.resolve(redirect, req.url));
        else res.status(404).send(http.STATUS_CODES[404]);
      }
    });
  }

  /**
   * Sends the specified response body.
   * @param {express.Response} res The response sent by the server.
   * @param {string} body The response body to send to the client.
   * @param {Error} [error] An error message to add to the response headers as `HTTPHeaders.X_AKISMET_DEBUG_HELP`.
   * @private
   */
  static _sendResponse(res, body, error) {
    res.type('text/plain; charset=utf-8');
    if(typeof error != 'undefined') res.set(HTTPHeaders.X_AKISMET_DEBUG_HELP, error.toString());
    res.send(body);
  }
}

// Public interface.
module.exports = Server;
<|endoftext|>


<commit_before>/**
 * Tester Plugin : Includes test files within the project's modules.
 *
 * Config:
 *    root:
 *      test:
 *        Array of test files to include. Alternatively may be an object with special values below.
 *
 *        Special Values:
 *          auto-include: Directory prefix that will be scaned for matching paths.
 *
 * Mixins:
 *  File mappings will be mixed in but are executed within the scope of the mixin only. I.e. foo.js
 *  will auto include mixin/test/foo.js etc.
 *
 */
var _ = require('underscore'),
    async = require('async'),
    lumbar = require('lumbar'),
    fu = lumbar.fileUtil,
    path = require('path');

function generator(string) {
  var ret = function(context, callback) { callback(undefined, {data: string, noSeparator: true}); };
  ret.stringValue = string;
  ret.sourceFile = undefined;
  return ret;
}

module.exports = function(options) {
  options = options || {};

  return {
    priority: 80,

    moduleResources: function(context, next, complete) {
      if (!options.includeTests && context.module['test-module']) {
        // Prevent output from any test modules if we aren't including tests
        return complete(undefined, []);
      }
      if (context.mode !== 'scripts' || context.module['test-module']) {
        // Don't touch anything outside of script mode or explicit test modules
        return next(complete);
      }

      var attr = context.config.attributes.test || {};

      next(function(err, ret) {
        if (err || !ret) {
          return complete(err);
        }

        // Only include the test output if the user explicitly opted in
        var tests = options.includeTests ? context.module.tests : [];

        // Auto-include if enabled
        if (!tests) {
          tests = ret.map(function(resource) {
              var filterResource = (lumbar.build || context.config).filterResource,
                  mixin = resource.mixin && (resource.mixin.parent || resource.mixin),
                  config = (mixin ? mixin.test : attr) || {},
                  includeDir = config['auto-include'];
              if (includeDir && filterResource(resource, context)
                  && (resource.src || _.isString(resource))) {
                if (resource.mixin) {
                  var root = resource.mixin.root,
                      src = resource.originalSrc || resource.src.substring(root.length);

                  return root + includeDir + src;
                } else {
                  return includeDir + (resource.src || resource);
                }
              }
            });
          async.map(tests, function(resource, callback) {
              if (!resource) { return callback(undefined, resource); }
              fu.stat(fu.resolvePath(resource), function(err) {
                if (!err) {
                  callback(undefined, resource);
                } else {
                  // File not found, watch the parent dir for adds
                  var dir = fu.resolvePath(path.dirname(resource));
                  fu.stat(dir, function(err) {
                    callback(undefined, !err && {watch: dir});
                  });
                }
              });
            },
            function(err, tests) {
              finish(_.filter(tests, function(test) { return test; }));
            });
        } else {
          finish(tests);
        }

        function finish(tests) {
          // Create a submodule scope for all of the output
          if (tests && tests.length) {
            ret.push(generator('exports.' + (attr.export || 'tests') + ' = function() {\n'));
            ret.push.apply(ret, tests);
            ret.push(generator('};\n'));
          }

          complete(undefined, ret);
        }
      });
    }
  };
};
<commit_msg>Short circuit if flagged in module-map mode<commit_after>/**
 * Tester Plugin : Includes test files within the project's modules.
 *
 * Config:
 *    root:
 *      test:
 *        Array of test files to include. Alternatively may be an object with special values below.
 *
 *        Special Values:
 *          auto-include: Directory prefix that will be scaned for matching paths.
 *
 * Mixins:
 *  File mappings will be mixed in but are executed within the scope of the mixin only. I.e. foo.js
 *  will auto include mixin/test/foo.js etc.
 *
 */
var _ = require('underscore'),
    async = require('async'),
    lumbar = require('lumbar'),
    fu = lumbar.fileUtil,
    path = require('path');

function generator(string) {
  var ret = function(context, callback) { callback(undefined, {data: string, noSeparator: true}); };
  ret.stringValue = string;
  ret.sourceFile = undefined;
  return ret;
}

module.exports = function(options) {
  options = options || {};

  return {
    priority: 80,

    moduleResources: function(context, next, complete) {
      if (!options.includeTests && context.module['test-module']) {
        // Prevent output from any test modules if we aren't including tests
        return complete(undefined, []);
      }
      if (context.isModuleMap || context.mode !== 'scripts' || context.module['test-module']) {
        // Don't touch anything outside of script mode or explicit test modules
        return next(complete);
      }

      var attr = context.config.attributes.test || {};

      next(function(err, ret) {
        if (err || !ret) {
          return complete(err);
        }

        // Only include the test output if the user explicitly opted in
        var tests = options.includeTests ? context.module.tests : [];

        // Auto-include if enabled
        if (!tests) {
          tests = ret.map(function(resource) {
              var filterResource = (lumbar.build || context.config).filterResource,
                  mixin = resource.mixin && (resource.mixin.parent || resource.mixin),
                  config = (mixin ? mixin.test : attr) || {},
                  includeDir = config['auto-include'];
              if (includeDir && filterResource(resource, context)
                  && (resource.src || _.isString(resource))) {
                if (resource.mixin) {
                  var root = resource.mixin.root,
                      src = resource.originalSrc || resource.src.substring(root.length);

                  return root + includeDir + src;
                } else {
                  return includeDir + (resource.src || resource);
                }
              }
            });
          async.map(tests, function(resource, callback) {
              if (!resource) { return callback(undefined, resource); }
              fu.stat(fu.resolvePath(resource), function(err) {
                if (!err) {
                  callback(undefined, resource);
                } else {
                  // File not found, watch the parent dir for adds
                  var dir = fu.resolvePath(path.dirname(resource));
                  fu.stat(dir, function(err) {
                    callback(undefined, !err && {watch: dir});
                  });
                }
              });
            },
            function(err, tests) {
              finish(_.filter(tests, function(test) { return test; }));
            });
        } else {
          finish(tests);
        }

        function finish(tests) {
          // Create a submodule scope for all of the output
          if (tests && tests.length) {
            ret.push(generator('exports.' + (attr.export || 'tests') + ' = function() {\n'));
            ret.push.apply(ret, tests);
            ret.push(generator('};\n'));
          }

          complete(undefined, ret);
        }
      });
    }
  };
};
<|endoftext|>


<commit_before>var zlib = require('zlib'),
    utils = require('./utils'),
    parseUrl = require('url').parse,
    uuid = require('node-uuid');

var Client = function Client(options) {
    this.servers = options.servers;
    this.key = options.key;
    this.name = options.name || require('os').hostname();
    this.site = options.site;
    this.root = options.root || process.cwd();
}, _ = Client.prototype;

module.exports.Client = Client;

_.get_ident = function get_ident(result) {
    return result.id+'$'+result.checksum;
};

_.process = function process(kwargs) {
    var message_id = uuid().replace(/-/g, ''),
        checksum;

    kwargs['event_id'] = message_id;

    if(!kwargs['checksum']){
        checksum = kwargs['checksum'] = utils.construct_checksum(kwargs);
    } else {
        checksum = kwargs['checksum'];
    }

    kwargs['server_name'] = kwargs['server_name'] || this.name;
    kwargs['site'] = kwargs['site'] || this.site;
    kwargs['extra'] = kwargs['extra'] || {};

    this.send(kwargs);

    return {'id': message_id, 'checksum': checksum};
};

_.send_remote = function send_remote(url, message, headers, callback) {
    url = parseUrl(url);
    var options = {
        host: url.hostname,
        path: url.pathname,
        port: ~~url.port,
        headers: headers,
        method: 'POST',
    }, req = require(url.protocol.slice(0, url.protocol.length-1)).request(options, function(res){
        res.on('data', function(data) {
            console.log(data.toString());
        });
    });

    req.end(message);
};

_.send = function send(kwargs) {
    var self = this;
    zlib.deflate(JSON.stringify(kwargs), function(err, buff) {
        var message = buff.toString('base64');
        //TODO: refactor this to not blast out to all servers at once.
        self.servers.forEach(function(url) {
            var timestamp = new Date().getTime()/1000,
                signature = utils.get_signature(self.key, message, timestamp),
                headers = {
                    'X-Sentry-Auth': utils.get_auth_header(signature, timestamp),
                    'Content-Type': 'application/octet-stream',
                    'Content-Length': message.length,
                };

            self.send_remote(url, message, headers);
        });
    });
};

_.create_from_text = function create_from_text(message, kwargs, callback) {
    kwargs = kwargs || {};
    kwargs['sentry.interfaces.Message'] = {
        message: message,
        params: kwargs
    };
    callback(this.process(kwargs));
};

_.create_from_exception =
_.create_from_error = function create_from_exception(err, kwargs, callback) {
    var self = this;
    kwargs = kwargs || {};
    utils.parseStack(err.stack, function(e, frames) {
        kwargs['message'] = err.name+': '+err.message;
        kwargs['sentry.interfaces.Exception'] = {type:err.name, value:err.message};
        kwargs['sentry.interfaces.Stacktrace'] = {frames:frames};
        kwargs['culprit'] = err.name + ' in ' + err.stack.split('\n')[1].match(/^.*?\((.*?):\d+:\d+\)$/)[1].replace(process.cwd()+'/', '');
        callback(self.process(kwargs));
    });
};

module.exports.patch_global = function patch_global(options) {
    var client = new Client(options);
    process.on('uncaughtException', function(err) {
        client.create_from_exception(err, {}, function(result) {
            var util = require('util');
            util.log('uncaughtException: '+client.get_ident(result));
        });
    });
};<commit_msg>Make the kwargs argument optional.<commit_after>var zlib = require('zlib'),
    utils = require('./utils'),
    parseUrl = require('url').parse,
    uuid = require('node-uuid');

var Client = function Client(options) {
    this.servers = options.servers;
    this.key = options.key;
    this.name = options.name || require('os').hostname();
    this.site = options.site;
    this.root = options.root || process.cwd();
}, _ = Client.prototype;

module.exports.Client = Client;

_.get_ident = function get_ident(result) {
    return result.id+'$'+result.checksum;
};

_.process = function process(kwargs) {
    var message_id = uuid().replace(/-/g, ''),
        checksum;

    kwargs['event_id'] = message_id;

    if(!kwargs['checksum']){
        checksum = kwargs['checksum'] = utils.construct_checksum(kwargs);
    } else {
        checksum = kwargs['checksum'];
    }

    kwargs['server_name'] = kwargs['server_name'] || this.name;
    kwargs['site'] = kwargs['site'] || this.site;
    kwargs['extra'] = kwargs['extra'] || {};

    this.send(kwargs);

    return {'id': message_id, 'checksum': checksum};
};

_.send_remote = function send_remote(url, message, headers, callback) {
    url = parseUrl(url);
    var options = {
        host: url.hostname,
        path: url.pathname,
        port: ~~url.port,
        headers: headers,
        method: 'POST',
    }, req = require(url.protocol.slice(0, url.protocol.length-1)).request(options, function(res){
        res.on('data', function(data) {
            console.log(data.toString());
        });
    });

    req.end(message);
};

_.send = function send(kwargs) {
    var self = this;
    zlib.deflate(JSON.stringify(kwargs), function(err, buff) {
        var message = buff.toString('base64');
        //TODO: refactor this to not blast out to all servers at once.
        self.servers.forEach(function(url) {
            var timestamp = new Date().getTime()/1000,
                signature = utils.get_signature(self.key, message, timestamp),
                headers = {
                    'X-Sentry-Auth': utils.get_auth_header(signature, timestamp),
                    'Content-Type': 'application/octet-stream',
                    'Content-Length': message.length,
                };

            self.send_remote(url, message, headers);
        });
    });
};

_.create_from_text = function create_from_text(message, kwargs, callback) {
    if(!callback && typeof kwargs === 'function') {
        callback = kwargs;
        kwargs = {};
    } else {
        kwargs = kwargs || {};
    }
    kwargs['sentry.interfaces.Message'] = {
        message: message,
        params: kwargs
    };
    callback(this.process(kwargs));
};

_.create_from_exception =
_.create_from_error = function create_from_exception(err, kwargs, callback) {
    var self = this;
    if(!callback && typeof kwargs === 'function') {
        callback = kwargs;
        kwargs = {};
    } else {
        kwargs = kwargs || {};
    }
    utils.parseStack(err.stack, function(e, frames) {
        kwargs['message'] = err.name+': '+err.message;
        kwargs['sentry.interfaces.Exception'] = {type:err.name, value:err.message};
        kwargs['sentry.interfaces.Stacktrace'] = {frames:frames};
        kwargs['culprit'] = err.name + ' in ' + err.stack.split('\n')[1].match(/^.*?\((.*?):\d+:\d+\)$/)[1].replace(process.cwd()+'/', '');
        callback(self.process(kwargs));
    });
};

module.exports.patch_global = function patch_global(options) {
    var client = new Client(options);
    process.on('uncaughtException', function(err) {
        client.create_from_exception(err, function(result) {
            var util = require('util');
            util.log('uncaughtException: '+client.get_ident(result));
        });
    });
};<|endoftext|>


<commit_before>var roundUp = 1.5;
var rounded = Math.round(roundUp);
console.log(rounded);<commit_msg>changes var to const in rounding-numbers (#249)<commit_after>const roundUp = 1.5;
const rounded = Math.round(roundUp);
console.log(rounded);<|endoftext|>


<commit_before>var util = require('util'),
    http = require('http'),
    bemutil = require('../util'),
    q = require('q'),
    path = require('../path'),
    url = require('url'),
    vm = require('vm'),
    bk = require('borschik').api;

var root;

exports.start = function(opts) {

    root = opts.project;

    bemutil.isExists(root)
        .then(function(exists) {
            if(exists) {
                root = path.resolve(root);

                console.log(util.format('project root is %s', root));
                console.log(util.format("server is starting on port %s", opts.port));

                var server = http.Server(
                    function(req, res) {
                        handleRequest(req, res);
                    }).on('error',
                    function(e) {
                        console.log(util.format('Ошибка инициализации сервера: %s', e.message));
                    }).listen(opts.port);

            } else {
                console.log(util.format('%s не существует', root));
            }
        });
}

function handleRequest(req, res) {

    var query = url.parse(req.url, true),
        relUri = query.pathname,
        filePath = path.join(root, relUri);

    console.log(util.format('attempting to access file %s', filePath));

    if(filePath.match(/.*\.html$/i) && bemFilesExist(filePath)) {
        console.log('requested file will be generated from bemjson and bemhtml');
        processBEMHTML(filePath, res);
    } else if(filePath.match(/_.*\.(js|css)$/i)) {
        console.log('requested file will be processed with borschik');
        processBorschik(filePath, res);
    } else {
        bemutil.isExists(filePath)
            .then(function(exists) {
                if(!exists) {
                    res.writeHead(404);
                    res.end();
                    return;
                }

                bemutil.readFile(filePath)
                    .then(function(content) {
                        res.writeHead(200);
                        res.end(content);
                    })
                    .fail(function(error) {
                        console.log(error.stack);
                        res.writeHead(500);
                        res.end(error.message);
                    });
            });
    }
}

function bemFilesExist(file) {
    var bemhtmlFile = file.replace(/html$/i, 'bemhtml.js'),
        bemjsonFile = file.replace(/html$/i, 'bemjson.js');

    return bemutil.isFile(bemhtmlFile) && bemutil.isFile(bemjsonFile);
}

function processBEMHTML(htmlFile, res) {

    var bemhtmlFile = htmlFile.replace(/html$/i, 'bemhtml.js'),
        bemjsonFile = htmlFile.replace(/html$/i, 'bemjson.js');

    console.log(util.format('reading bemhtml %s and bemjson %s', bemhtmlFile, bemjsonFile));

    bemutil.readFile(bemhtmlFile)
        .then(function(bemhtml) {
            return bemutil.readFile(bemjsonFile)
                .then(function(bemjson) {
                    try {
                        vm.runInThisContext(bemhtml);
                        var html = BEMHTML.apply(vm.runInThisContext(bemjson));
                        res.writeHead(200);
                        res.end(html);
                    } catch(e) {
                        console.log(util.format('error occured during bemjson processing: %s', e));
                        res.writeHead(500);
                        res.end(util.format('error occured during bemjson processing: %s', e));
                    }
                })
        })
        .fail(function(error) {
            res.writeHead(500);
            res.end(error.message);
        });
}

function processBorschik(file, res) {

    var options = {
        input : file,
        output : res
    };

    if(file.match(/\.css$/i)) options.tech = 'css';

    q.when(bk(null,
        options),
        function() {
            res.end();
        },
        function(error) {
            console.log(error.stack);
            res.writeHead(500);
            res.end(error.message);
        });
}<commit_msg>- directory listing is added<commit_after>var util = require('util'),
    http = require('http'),
    bemutil = require('../util'),
    q = require('q'),
    qw = require('q-wrap'),
    path = require('../path'),
    fs = require('fs'),
    url = require('url'),
    vm = require('vm'),
    bk = require('borschik').api;

var root;

exports.start = function(opts) {

    root = opts.project;

    bemutil.isExists(root)
        .then(function(exists) {
            if(exists) {
                root = path.resolve(root);

                console.log(util.format('project root is %s', root));
                console.log(util.format("server is starting on port %s", opts.port));

                var server = http.Server(
                    function(req, res) {
                        handleRequest(req, res);
                    }).on('error',
                    function(e) {
                        console.log(util.format('Ошибка инициализации сервера: %s', e.message));
                    }).listen(opts.port);

            } else {
                console.log(util.format('%s не существует', root));
            }
        });
}

function handleRequest(req, res) {

    var query = url.parse(req.url, true),
        relUri = query.pathname,
        filePath = path.join(root, relUri);

    console.log(util.format('attempting to access %s', filePath));

    if(filePath.match(/.*\.html$/i) && bemFilesExist(filePath)) {
        console.log('requested file will be generated from bemjson and bemhtml');
        processBEMHTML(filePath, res);
    } else if(filePath.match(/_.*\.(js|css)$/i)) {
        console.log('requested file will be processed with borschik');
        processBorschik(filePath, res);
    } else {
        q.when(qw.execute(fs.stat, filePath),
            function(stat) {
                if(stat.isDirectory()) {
                    processDirectory(filePath, res);
                } else {
                    bemutil.readFile(filePath)
                        .then(function(content) {
                            res.writeHead(200);
                            res.end(content);
                        })
                        .fail(function(error) {
                            console.log(error.stack);
                            res.writeHead(500);
                            res.end(error.message);
                        });
                }
            },
            function(err) {
                res.writeHead(404);
                res.end();
            });
    }
}

function processDirectory(dirpath, res) {
    var items = [];

    res.write(util.format('<!DOCTYPE html><meta charset="utf-8"/><title>%s</title>', dirpath));
    res.write(util.format('Index of %s
', dirpath));

    q.when(qw.execute(fs.readdir, dirpath),
        function(f) {
            var files = [],
                dirs = ['..'];

            console.dir(f);

            f && f.forEach(function(item) {
                if(bemutil.isDirectory(path.join(dirpath, item))) {
                    dirs.push(item);
                    console.log('dir ' + item);
                }
                else {
                    files.push(item);
                    console.log('file ' + item);
                }
            });

            dirs.sort();
            files.sort();

            dirs.forEach(function(dir){
                res.write(util.format('
/%s
', dir, dir));
            });

            files.forEach(function(file){
                res.write(util.format('
%s
', file, file));
            });

            res.end('
');
        },
        function(error) {
            res.end(error.message);
        });

}

function bemFilesExist(file) {
    var bemhtmlFile = file.replace(/html$/i, 'bemhtml.js'),
        bemjsonFile = file.replace(/html$/i, 'bemjson.js');

    return bemutil.isFile(bemhtmlFile) && bemutil.isFile(bemjsonFile);
}

function processBEMHTML(htmlFile, res) {

    var bemhtmlFile = htmlFile.replace(/html$/i, 'bemhtml.js'),
        bemjsonFile = htmlFile.replace(/html$/i, 'bemjson.js');

    console.log(util.format('reading bemhtml %s and bemjson %s', bemhtmlFile, bemjsonFile));

    bemutil.readFile(bemhtmlFile)
        .then(function(bemhtml) {
            return bemutil.readFile(bemjsonFile)
                .then(function(bemjson) {
                    try {
                        vm.runInThisContext(bemhtml);
                        var html = BEMHTML.apply(vm.runInThisContext(bemjson));
                        res.writeHead(200);
                        res.end(html);
                    } catch(e) {
                        console.log(util.format('error occured during bemjson processing: %s', e));
                        res.writeHead(500);
                        res.end(util.format('error occured during bemjson processing: %s', e));
                    }
                })
        })
        .fail(function(error) {
            res.writeHead(500);
            res.end(error.message);
        });
}

function processBorschik(file, res) {

    var options = {
        input : file,
        output : res
    };

    if(file.match(/\.css$/i)) options.tech = 'css';

    q.when(bk(null,
        options),
        function() {
            res.end();
        },
        function(error) {
            console.log(error.stack);
            res.writeHead(500);
            res.end(error.message);
        });
}<|endoftext|>