<commit_before>/*************
 *   CRANE   *
 *************/

var spawn = require('child_process').spawn,
    fs    = require('fs'),
    path  = require('path'),
    uuid  = require('node-uuid'),
    async = require('async'),
    _     = require('lodash');

var playerDirectory = path.resolve(path.dirname(require.main.filename), './players');

module.exports.setPlayersDirectory = function(filename) {
    playerDirectory = filename;
}

var TIMEOUT_LENGTH = 1000; //milliseconds

//------- API -----

//client receives: first word is a command, second is data
//commands: filename, player
//controller receives: first word is return command, second is status, third is data

var Player = function(playerName, shell) {
  var pl = this;

  pl.name = playerName;
  pl.shell = shell;
  pl.messageTable = [];

  this.getName = function() {
    return pl.name;
  }

  this.shell.stdout.on('data', function(res) {
    if(res.toString().substr(0, 4) === 'log ') {
      console.log('Log from client ' + pl.getName() + ': ' + res.toString().substr(4));
    } else if(res.toString().substr(0, 4) === 'err ') {
      throw new Error('Error from client ' + pl.getName() + ': ' + res.toString().substr(4));
    } else {
      res = res.toString().trim();

      var lines = res.split('\n');

      for(var i = 0; i < lines.length; i++) {
          processOutput(lines[i]);
      }
    }
  });

  function processOutput(res) {
      if(res.length > 0) {

        var dataSplit = res.split(' ');

        if(dataSplit.length < 2) {
          throw new Error('client response from ' + pl.getName() + ' too short: ' + res);
        }

        var messageId = dataSplit[0];
        var status    = dataSplit[1];
        var data      = dataSplit.length >= 3 ? dataSplit.slice(2).join(' ') : null;

        if(!pl.messageTable[messageId]) {
            throw new Error('client response from ' + pl.getName() + ' with unrecognized message id ' + messageId);
        }

        pl.messageTable[messageId].done = true;

        if(parseInt(status) === 200) {
            var callback = pl.messageTable[messageId].callback;
            if(callback) { callback(data); }
        } else {
            throw new Error('client response from ' + pl.getName() + ' with status ' + status + ' and error ' + data + '.');
        }

      }
  }

  //err
  this.shell.stderr.on('data', function(data) {
    throw new Error('Error from player ' + pl.getName() + ': ' + data);
  });

  //close
  this.shell.on('close', function(code) {
    console.log('Player ' + pl.getName() + ' closing with code: ' + code);
  });

  //end
  this.shell.on('end', function() {
    process.stdout.end();
  });

  //private - takes a command and data, passes it on to the client
  function sendRaw(command, data, cb) {

      var messageId = uuid.v1();
      var messageString = [messageId, command, data].join(' ');

      pl.messageTable[messageId] = {
              callback: cb,<commit_msg>Removed erroneous stream closing thing<commit_after>/*************
 *   CRANE   *
 *************/

var spawn = require('child_process').spawn,
    fs    = require('fs'),
    path  = require('path'),
    uuid  = require('node-uuid'),
    async = require('async'),
    _     = require('lodash');

var playerDirectory = path.resolve(path.dirname(require.main.filename), './players');

module.exports.setPlayersDirectory = function(filename) {
    playerDirectory = filename;
}

var TIMEOUT_LENGTH = 1000; //milliseconds

//------- API -----

//client receives: first word is a command, second is data
//commands: filename, player
//controller receives: first word is return command, second is status, third is data

var Player = function(playerName, shell) {
  var pl = this;

  pl.name = playerName;
  pl.shell = shell;
  pl.messageTable = [];

  this.getName = function() {
    return pl.name;
  }

  this.shell.stdout.on('data', function(res) {
    if(res.toString().substr(0, 4) === 'log ') {
      console.log('Log from client ' + pl.getName() + ': ' + res.toString().substr(4));
    } else if(res.toString().substr(0, 4) === 'err ') {
      throw new Error('Error from client ' + pl.getName() + ': ' + res.toString().substr(4));
    } else {
      res = res.toString().trim();

      var lines = res.split('\n');

      for(var i = 0; i < lines.length; i++) {
          processOutput(lines[i]);
      }
    }
  });

  function processOutput(res) {
      if(res.length > 0) {

        var dataSplit = res.split(' ');

        if(dataSplit.length < 2) {
          throw new Error('client response from ' + pl.getName() + ' too short: ' + res);
        }

        var messageId = dataSplit[0];
        var status    = dataSplit[1];
        var data      = dataSplit.length >= 3 ? dataSplit.slice(2).join(' ') : null;

        if(!pl.messageTable[messageId]) {
            throw new Error('client response from ' + pl.getName() + ' with unrecognized message id ' + messageId);
        }

        pl.messageTable[messageId].done = true;

        if(parseInt(status) === 200) {
            var callback = pl.messageTable[messageId].callback;
            if(callback) { callback(data); }
        } else {
            throw new Error('client response from ' + pl.getName() + ' with status ' + status + ' and error ' + data + '.');
        }

      }
  }

  //err
  this.shell.stderr.on('data', function(data) {
    throw new Error('Error from player ' + pl.getName() + ': ' + data);
  });

  //close
  this.shell.on('close', function(code) {
    console.log('Player ' + pl.getName() + ' closing with code: ' + code);
  });

  //private - takes a command and data, passes it on to the client
  function sendRaw(command, data, cb) {

      var messageId = uuid.v1();
      var messageString = [messageId, command, data].join(' ');

      pl.messageTable[messageId] = {
              callback: cb,
{'fraction_non_alphanumeric': 0.17272727272727273, 'fraction_numerical': 0.007204116638078902, 'mean_word_length': 2.5126506024096384, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2152692', 'n_tokens_mistral': 1821, 'n_tokens_neox': 1751, 'n_words': 433}