<commit_before>var http = require('q-io/http');
var sprintf = require('sprintf-js').sprintf;

module.exports = {
  ordinal: ordinal,
  ensureArray: ensureArray,
  getJson: getJson,
};

function ordinal(num) {
  var rem = num % 10;

  if (rem === 1 && num !== 11) {
    return num + 'st';
  }

  if (rem === 2 && num !== 12) {
    return num + 'nd';
  }

  if (rem === 3 && num !== 13) {
    return num + 'rd';
  }

  return num + 'th';
}

function ensureArray(object, field) {
  if (!(object[field] instanceof Array)) {
    object[field] = [object[field]];
  }
}

function getJson(url) {

  function getBody(response) {
    if (response.status >= 400) {
      throw new Exception(response.status);
    }

    return response.body.read();
  }

  function parseJson(body) {
    return JSON.parse(body);
  }

  return http.request(url)
    .then(getBody)
    .then(parseJson);
}
<commit_msg>Automatically pull out 'data' field of JSON response<commit_after>var http = require('q-io/http');
var sprintf = require('sprintf-js').sprintf;

module.exports = {
  ordinal: ordinal,
  ensureArray: ensureArray,
  getJson: getJson,
};

function ordinal(num) {
  var rem = num % 10;

  if (rem === 1 && num !== 11) {
    return num + 'st';
  }

  if (rem === 2 && num !== 12) {
    return num + 'nd';
  }

  if (rem === 3 && num !== 13) {
    return num + 'rd';
  }

  return num + 'th';
}

function ensureArray(object, field) {
  if (!(object[field] instanceof Array)) {
    object[field] = [object[field]];
  }
}

function getJson(url) {

  function getBody(response) {
    if (response.status >= 400) {
      throw new Exception(response.status);
    }

    return response.body.read();
  }

  function parseJson(body) {
    return JSON.parse(body).data;
  }

  return http.request(url)
    .then(getBody)
    .then(parseJson);
}
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies
 */

var path = require('path');
var deepPick = require('deep-pick');
var merge = require('mixin-deep');
var hasAny = require('has-any');
var isEmpty = require('is-empty');
var omit = require('omit-keys');
var omitEmpty = require('omit-empty');
var pick = require('object-pick');
var slice = require('array-slice');
var uniqueId = require('uniqueid');
var arrayify = require('arrayify-compact');
var _ = require('lodash');
var lookupKeys = require('./lookup-keys');
var debug = require('./debug');

/**
 * Expose `utils`
 */

var utils = module.exports;

/**
 * Expose dependencies on `utils` for use in other
 * internal modules.
 *
 * @api private
 */

utils.arrayify = arrayify;
utils.deepPick = deepPick;
utils.pick = pick;
utils.omit = omit;

/**
 * Utilities for returning the native `typeof` a value.
 *
 * @api private
 */

utils.typeOf = function typeOf(val) {
  return {}.toString.call(val).toLowerCase()
    .replace(/\[object ([\S]+)\]/, '$1');
};

utils.isString = function isString(val) {
  return utils.typeOf(val) === 'string';
};

utils.isObject = function isObject(val) {
  return utils.typeOf(val) === 'object';
};

utils.isFunction = function isFunction(val) {
  return utils.typeOf(val) === 'function';
};

utils.isNumber = function isNumber(val) {
  return utils.typeOf(val) === 'number';
};

utils.isBoolean = function isBoolean(val) {
  return utils.typeOf(val) === 'boolean';
};

var hasOwn = utils.hasOwn = function(o, prop) {
  return {}.hasOwnProperty.call(o, prop);
};

/**
 * Return true if the `array` has the given native `type`.
 *
 * @param  {Array}  `arr`
 * @param  {String}  `type` Native type to look for.
 * @return {Boolean}
 */

utils.hasType = function hasType(arr, type) {
  var val = false;

  for (var i = 0; i < arr.length; i++) {
    var value = arr[i];
    if (utils.typeOf(value) === type) {
      val = true;
      break;
    }
  };

  return val;
};

/**
 * Pick `keys` from `object`
 *
 * @param  {Object} `object`
 * @return {Object}
 */

utils.basePick = function(o, keys) {
  return o == null ? {} : pick(o, keys);
};

/**
 * Pick `locals` from `object`
 *
 * @param  {Object} `object`
 * @return {Object}
 */

utils.pickDelims = function(template, locals) {
  return (template.options && template.options.delims) || locals.delims;
};

/**
 * Determine the correct layout to use for the given `value`.
 *
 * @param  {Object} `value` Template object to test search for `layout`.
 * @return {String} The name of the layout to use.
 * @api private
 */

utils.pickContent = function (template) {
  if (utils.isString(template)) return template;
  return utils.basePick(template, 'content');
};

/**
 * Look for the given `lookup` string in one the specified
 * `props` of `obj`.
 *
 * ```js
 * pickFrom(template, 'ext', ['b', 'd', 'c', 'e', 'd']);
 * ```
 *
 * @param  {Object} `object` The object to search.
 * @param  {String} `lookup` The value to find.
 * @param  {Array} `props` The nested properties to search on.
 * @return {*} Returns the first value found.
 */

utils.pickFrom = function (o, lookup, props) {
  if (!o) return null;

  var isProps = Array.isArray(props);

  if (!isProps || props.length === 0) {
    if (hasOwn(o, lookup)) {
      return o[lookup];
    }
    props = Object.keys(o);
  }

  var keys = slice(props).reverse();
  var len = keys.length - 1;
  var value;

  for (var i = len; i >= 0; i--) {
    var key = keys[i];
    var val = o[key];

    if (utils.isObject(val) && hasOwn(val, lookup)) {
      value = val[lookup];
      break;
    }
  }

  if (value) return value;
  return null;
};

/**
 * Get the correct layout to use for the given `template`.
 *
 * @param  {Object} `template` Template object to search for `layout`.
 * @param  {Object} `locals` Locals object search if not found on `template.`
 * @return {String} The name of the layout to use.
 * @api private
 */

utils.pickLayout = function (template, locals) {
  debug.utils('[utils] pickLayout:', arguments);
  var last = _.last(arguments);

  template.layout = utils.pickFrom(template, 'layout', lookupKeys);

  if (!template.layout && locals != null) {
    template.layout = utils.pickFrom(locals, 'layout', lookupKeys);
  }

  // Return the layout name if the last arg is `true`
  if (utils.isBoolean(last)) {
    return template.layout;
  }
};

utils.isPartial = function (template, locals) {
  debug.utils('[utils] isPartial:', arguments);
  var keys = Object.keys(template);
  var val = false;

  for (var i = 0; i < keys.length; i++) {
    var value = keys[i]
    if (value && hasOwn(value, 'options')) {
      if (!hasOwn(value.options, ['isLayout', 'isRenderable'])) {
        val = true;
        break;
      }
    }
  }

  return val;
};

/**
 * Determine the correct layout to use for the given `value`.
 *
 * @param  {Object} `value` Template object to test search for `layout`.
 * @return {String} The name of the layout to use.
 * @api private
 */

utils.pickCached = function (file, locals, thisArg) {
  debug.utils('[utils] pickCached:', arguments);

  var val = null;

  if (!utils.isString(arguments[0])) return val;
  var types = thisArg.templateType.renderable;
  var name = file;

  for (var i = 0; i < types.length; i++) {
    var cache = thisArg.cache[types[i]];
    if (hasOwn(cache, name)) {
      val = cache[name];
      break;
    }
  }
  return val;
};

/**
 * Determine the correct engine to use for the current template.
 *
 * @param  {Object} `cache`
 * @return {Object} `template`
 * @api private
 */

utils.pickEngine = function (cache, template) {
  debug.utils('[utils] pickCached:', arguments);

  if (!utils.isObject(cache) || !utils.isObject(template)) {
    return null;
  }

  var props = ['ext', 'engine', 'path'];
  var len = props.length;
  var ext;

  var o = pick(template, props);
  if (isEmpty(o)) return null;

  for (var i = 0; i < len; i++) {
    var ele = props[i];

    if (hasOwn(o, ele)) {
      if (ele === 'path') {
        ext = path.extname(o[ele]);
        break;
      } else {
        ext = o[ele];
        break;
      }
    }
  }

  if (ext) return cache[ext];
  return null;
};

/**
 * Determine the correct file extension to use, taking the following
 * into consideration, and in this order:
 *
 *   - `options.ext`
 *   - `value.data.ext`
 *   - `value.ext`
 *   - `value._opts.ext`
 *   - `path.extname(value.path)`
 *
 * The reasoning is that if an engine is explicitly defined, it should
 * take precendence over an engine that is automatically calculated
 * from `value.path`.
 *
 * @param  {String} `ext` The layout settings to use.
 * @param  {Object} `value` Template value object.
 * @param  {Object} `options` Object of options.
 * @return  {String} The extension to use.
 * @api private
 */

utils.pickExt = function(template, options, thisArg) {
  debug.utils('[utils] pickExt:', arguments);

  if (arguments.length === 2) {
    thisArg = options;
    options = {};
  }

  template = merge({options: {engine: ''}}, template);
  options = options || {};

  var ext = template.engine
    || template.ext
    || template.options.engine
    || options.engine
    || options.ext
    || thisArg.option('viewEngine');

  return ext ? utils.formatExt(ext) : null;
};

/**
 * Returns `null`, or `true` if the template is a layout.
 *
 * @param  {Object} `value` Template object to search for `layout`.
 * @api private
 */

utils.isLayout = function (value) {
  return utils.pickFrom(value, 'isLayout', lookupKeys);
};

/**
 * Generate a unique id to be used for caching unidentified
 * tempalates. (not used currently)
 *
 * @param  {Object} `options`
 * @return {Object}
 */

utils.generateId = function(options) {
  var opts = options || {};

  return opts.id ? opts.id : uniqueId({
    prefix: opts.prefix || '__id__',
    append: opts.append || ''
  });
};

/**
 * Ensure file extensions are formatted properly for lookups.
 *
 * @api private
 */

utils.formatExt = function(ext) {
  if (ext && ext[0] !== '.') {
    ext = '.' + ext;
  }
  return ext;
};
<commit_msg>isRenderable/isPartial<commit_after>'use strict';

/**
 * Module dependencies
 */

var path = require('path');
var deepPick = require('deep-pick');
var merge = require('mixin-deep');
var hasAny = require('has-any');
var isEmpty = require('is-empty');
var omit = require('omit-keys');
var omitEmpty = require('omit-empty');
var pick = require('object-pick');
var slice = require('array-slice');
var uniqueId = require('uniqueid');
var arrayify = require('arrayify-compact');
var _ = require('lodash');
var lookupKeys = require('./lookup-keys');
var debug = require('./debug');

/**
 * Expose `utils`
 */

var utils = module.exports;

/**
 * Expose dependencies on `utils` for use in other
 * internal modules.
 *
 * @api private
 */

utils.arrayify = arrayify;
utils.deepPick = deepPick;
utils.pick = pick;
utils.omit = omit;

/**
 * Utilities for returning the native `typeof` a value.
 *
 * @api private
 */

utils.typeOf = function typeOf(val) {
  return {}.toString.call(val).toLowerCase()
    .replace(/\[object ([\S]+)\]/, '$1');
};

utils.isString = function isString(val) {
  return utils.typeOf(val) === 'string';
};

utils.isObject = function isObject(val) {
  return utils.typeOf(val) === 'object';
};

utils.isFunction = function isFunction(val) {
  return utils.typeOf(val) === 'function';
};

utils.isNumber = function isNumber(val) {
  return utils.typeOf(val) === 'number';
};

utils.isBoolean = function isBoolean(val) {
  return utils.typeOf(val) === 'boolean';
};

var hasOwn = utils.hasOwn = function(o, prop) {
  return {}.hasOwnProperty.call(o, prop);
};

/**
 * Return true if the `array` has the given native `type`.
 *
 * @param  {Array}  `arr`
 * @param  {String}  `type` Native type to look for.
 * @return {Boolean}
 */

utils.hasType = function hasType(arr, type) {
  var val = false;

  for (var i = 0; i < arr.length; i++) {
    var value = arr[i];
    if (utils.typeOf(value) === type) {
      val = true;
      break;
    }
  };

  return val;
};

/**
 * Pick `keys` from `object`
 *
 * @param  {Object} `object`
 * @return {Object}
 */

utils.basePick = function(o, keys) {
  return o == null ? {} : pick(o, keys);
};

/**
 * Pick `locals` from `object`
 *
 * @param  {Object} `object`
 * @return {Object}
 */

utils.pickDelims = function(template, locals) {
  return (template.options && template.options.delims) || locals.delims;
};

/**
 * Determine the correct layout to use for the given `value`.
 *
 * @param  {Object} `value` Template object to test search for `layout`.
 * @return {String} The name of the layout to use.
 * @api private
 */

utils.pickContent = function (template) {
  if (utils.isString(template)) return template;
  return utils.basePick(template, 'content');
};

/**
 * Look for the given `lookup` string in one the specified
 * `props` of `obj`.
 *
 * ```js
 * pickFrom(template, 'ext', ['b', 'd', 'c', 'e', 'd']);
 * ```
 *
 * @param  {Object} `object` The object to search.
 * @param  {String} `lookup` The value to find.
 * @param  {Array} `props` The nested properties to search on.
 * @return {*} Returns the first value found.
 */

utils.pickFrom = function (o, lookup, props) {
  if (!o) return null;

  var isProps = Array.isArray(props);

  if (!isProps || props.length === 0) {
    if (hasOwn(o, lookup)) {
      return o[lookup];
    }
    props = Object.keys(o);
  }

  var keys = slice(props).reverse();
  var len = keys.length - 1;
  var value;

  for (var i = len; i >= 0; i--) {
    var key = keys[i];
    var val = o[key];

    if (utils.isObject(val) && hasOwn(val, lookup)) {
      value = val[lookup];
      break;
    }
  }

  if (value) return value;
  return null;
};

/**
 * Get the correct layout to use for the given `template`.
 *
 * @param  {Object} `template` Template object to search for `layout`.
 * @param  {Object} `locals` Locals object search if not found on `template.`
 * @return {String} The name of the layout to use.
 * @api private
 */

utils.pickLayout = function (template, locals) {
  debug.utils('[utils] pickLayout:', arguments);
  var last = _.last(arguments);

  template.layout = utils.pickFrom(template, 'layout', lookupKeys);

  if (!template.layout && locals != null) {
    template.layout = utils.pickFrom(locals, 'layout', lookupKeys);
  }

  // Return the layout name if the last arg is `true`
  if (utils.isBoolean(last)) {
    return template.layout;
  }
};

/**
 * Determine the correct layout to use for the given `value`.
 *
 * @param  {Object} `value` Template object to test search for `layout`.
 * @return {String} The name of the layout to use.
 * @api private
 */

utils.pickCached = function (file, locals, thisArg) {
  debug.utils('[utils] pickCached:', arguments);

  var val = null;

  if (!utils.isString(arguments[0])) return val;
  var types = thisArg.templateType.renderable;
  var name = file;

  for (var i = 0; i < types.length; i++) {
    var cache = thisArg.cache[types[i]];
    if (hasOwn(cache, name)) {
      val = cache[name];
      break;
    }
  }
  return val;
};

/**
 * Determine the correct engine to use for the current template.
 *
 * @param  {Object} `cache`
 * @return {Object} `template`
 * @api private
 */

utils.pickEngine = function (cache, template) {
  debug.utils('[utils] pickCached:', arguments);

  if (!utils.isObject(cache) || !utils.isObject(template)) {
    return null;
  }

  var props = ['ext', 'engine', 'path'];
  var len = props.length;
  var ext;

  var o = pick(template, props);
  if (isEmpty(o)) return null;

  for (var i = 0; i < len; i++) {
    var ele = props[i];

    if (hasOwn(o, ele)) {
      if (ele === 'path') {
        ext = path.extname(o[ele]);
        break;
      } else {
        ext = o[ele];
        break;
      }
    }
  }

  if (ext) return cache[ext];
  return null;
};

/**
 * Determine the correct file extension to use, taking the following
 * into consideration, and in this order:
 *
 *   - `options.ext`
 *   - `value.data.ext`
 *   - `value.ext`
 *   - `value._opts.ext`
 *   - `path.extname(value.path)`
 *
 * The reasoning is that if an engine is explicitly defined, it should
 * take precendence over an engine that is automatically calculated
 * from `value.path`.
 *
 * @param  {String} `ext` The layout settings to use.
 * @param  {Object} `value` Template value object.
 * @param  {Object} `options` Object of options.
 * @return  {String} The extension to use.
 * @api private
 */

utils.pickExt = function(template, options, thisArg) {
  debug.utils('[utils] pickExt:', arguments);

  if (arguments.length === 2) {
    thisArg = options;
    options = {};
  }

  template = merge({options: {engine: ''}}, template);
  options = options || {};

  var ext = template.engine
    || template.ext
    || template.options.engine
    || options.engine
    || options.ext
    || thisArg.option('viewEngine');

  return ext ? utils.formatExt(ext) : null;
};

/**
 * Returns `null`, or `true` if the template is a layout.
 *
 * @param  {Object} `value` Template object to search for `layout`.
 * @api private
 */

utils.isLayout = function (value) {
  return utils.pickFrom(value, 'isLayout', lookupKeys);
};

/**
 * Returns `null`, or `true` if the template is a layout.
 *
 * @param  {Object} `value` Template object to search for `layout`.
 * @api private
 */

utils.isRenderable = function (value) {
  return utils.pickFrom(value, 'isRenderable', lookupKeys);
};

/**
 * Returns `null`, or `true` if the template is a layout.
 *
 * @param  {Object} `value` Template object to search for `layout`.
 * @api private
 */

utils.isPartial = function (value) {

};

/**
 * Generate a unique id to be used for caching unidentified
 * tempalates. (not used currently)
 *
 * @param  {Object} `options`
 * @return {Object}
 */

utils.generateId = function(options) {
  var opts = options || {};

  return opts.id ? opts.id : uniqueId({
    prefix: opts.prefix || '__id__',
    append: opts.append || ''
  });
};

/**
 * Ensure file extensions are formatted properly for lookups.
 *
 * @api private
 */

utils.formatExt = function(ext) {
  if (ext && ext[0] !== '.') {
    ext = '.' + ext;
  }
  return ext;
};
<|endoftext|>


<commit_before>// TODO: write a cron job to go through and delete unused ones (also files)
WranglerSubmissions = new Meteor.Collection("wrangler_submissions");
WranglerSubmissions.attachSchema(new SimpleSchema({
  "user_id": { type: Meteor.ObjectID },
  "files": {
    type: [
      new SimpleSchema({
        "file_id": { type: Meteor.ObjectID },
        "file_name": { type: String },
        "status": {
          type: String,
          allowedValues: [
            "creating",
            "uploading",
            "processing",
            "done",
            "error",
          ],
        },
        // TODO: only allow if status = "error"
        "error_description": { type: String, optional: true },
      })
    ],
    optional: true
  },
  "documents": {
    type: [
      new SimpleSchema({
        "collection_name": { // not so enthused about this
          type: String,
          allowedValues: [
            "network_elements",
            "network_interactions",
          ],
        },
        "prospective_document": { type: Object, blackbox: true },
      })
    ],
    optional: true,
  }
}));

UploadedFileStore = new FS.Store.GridFS("uploaded_files", {
  beforeWrite: function (fileObject) {
    // this.userId because we're on the server (doesn't work)
    fileObject.uploaded_date = new Date();
  }
});

// UploadedFileStore.on("stored", function (storeName, fileObject) {
//   if (storeName !== UploadedFileStore.name) return; // workaround for known bug
//   var assert = Meteor.npmRequire("assert");
//   var fs = Meteor.npmRequire("fs");
//   // var byLine = Meteor.npmRequire('byLine');
//   var vcf = Meteor.npmRequire('vcf.js');
//   var blob = "";
//     var stream = fileObject.createReadStream("uploaded_files")
//      .on('data', function (chunk) {
//        blob += chunk;
//      })
//      .on('end', function () {
//       //var myData = JSON.parse(stream);
//       //console.log("##file: " + myData);
//       if (blob) {
//         data = vcf.parser()(blob);
//         //data = vcf.parser()(String(fs.readFileSync('/data/MedBook/MedBook-Wrangler/webapp/test.vcf')));
//         for (h in data.header) {
//             console.log('#vcf header:',h);
//         }
//         //console.log('#DR',  data.records);
//         var len = data.records.length;
//         console.log('len',len);
//         var mut = {};
//         for (var i = 0; i < len; i++) {
//              var dx = data.records[i];
//              var keys = Object.keys(dx);
//
//              console.log('keys',keys, dx);
//              mut.gene_id = 'none';
//              mut['gene_label'] = 'WIERD';
//              for (k in keys) {
//                var key = keys[k];
//                var mapped_key = key;
//                if (key == 'TYPE') {
//                    mapped_key = 'mutation_type';
//                }
//                mut[mapped_key] = dx[key];
//                console.log('dx [',mapped_key,']=',dx[key]);
//              }
//              Mutations.insert(mut);
//              /*
//              "gene_label": { type: String },
//              "gene_id": { type: String },
//              "protein_change": { type: String, optional: true },
//              "mutation_type": { type: String }, // variant_classification for us
//              "chromosome": { type: String },
//              "start_position": { type: Number },
//              "end_position": { type: Number },
//              "reference_allele": { type: String },
//              "variant_allele": { type: String },
//              "MA_FImpact": { type: String, optional: true },
//              "MA_FIS": { type: Number, optional: true },
//              "allele_count": { type: Number, label:"Allele count in genotypes, for each ALT allele, in the same order as listed", optional:true },
//              "allele_frequency": { type: Number, decimal:true, label:"Allele frequency, for each ALT allele, in the same order as listed", optional:true },
//              "allele_number": { type: Number, label:"Number of unique alleles across all samples", optional:true },
//              "base_quality": { type: Number, decimal:true, label:"Overall average base quality", optional:true },
//              "read_depth": { type: Number, label:"Total read depth for all samples", optional:true },
//              "fraction_alt": { type: Number, decimal:true, label:"Overall fraction of reads supporting ALT", optional:true },
//              "indel_number": { type: Number, label:"Number of indels for all samples", optional:true },
//              "modification_base_changes": { type: String, label:"Modification base changes at this position", optional:true },
//              "modification_types": { type: String, label:"Modification types at this position", optional:true },
//              "sample_number": { type: Number, label:"Number of samples with data", optional:true },
//              "origin": { type: String, label:"Where the call originated from, the tumor DNA, RNA, or both", optional:true },
//              "strand_bias": { type: Number, decimal:true, label:"Overall strand bias", optional:true },
//              "somatic": { type: Boolean, label:"Indicates if record is a somatic mutation", optional:true },
//              "variant_status": { type: Number, label:"Variant status relative to non-adjacent Normal, 0=wildtype,1=germline,2=somatic,3=LOH,4=unknown,5=rnaEditing" , optional:true},
//              "reads_at_start": { type: Number, label:"Number of reads starting at this position across all samples", optional:true },
//              "reads_at_stop": { type: Number, label:"Number of reads stopping at this position across all samples", optional:true },
//              "variant_type": { type: String, label:"Variant type, can be SNP, INS or DEL", optional:true },
//              "effects": { type: [Object], label:"Predicted effects Effect ( Effect_Impact | Functional_Class | Codon_Change | Amino_Acid_change| Amino_Acid_length | Gene_Name | Transcript_BioType | Gene_Coding | Transcript_ID | Exon  | GenotypeNum [ | ERRORS | WARNINGS ] )" , optional:true }
// */
//
//         }
//         /*for (dlist in data.records) {
//             for (d in dlist) {
//               console.log('#vcf data:',dlist.d);
//             }
//         }*/
//         //console.log('data.records[0]',data.records[0]);
//         //var dx = data.records[1];
//         //console.log('data.records[1]',typeof data.records[1],Object.keys(data.records[1]),data.records[1]);
//               console.log('done mut=',mut,'\n');
//
//       }
//
// //
//   //    vcf.parser()(chunk);
//      });
//   console.log("stored file");
// });

UploadedFiles = new FS.Collection("uploaded_files", {
  stores: [UploadedFileStore],
});

UploadedFileStore.on("stored", Meteor.bindEnvironment(
  function (storeName, fileObject) {
    if (storeName !== UploadedFileStore.name) return; // workaround for known bug

    console.log("stored file callback");

    var submission = WranglerSubmissions.findOne({
      "files": {
        $elemMatch: {
          "file_id": fileObject._id
        }
      }
    });

    WranglerSubmissions.update({
          "_id": submission._id,
          "files.file_id": fileObject._id,
        }, {
          $set: { "files.$.status": "processing" }
        });

    var fileName = fileObject.original.name;

    if (fileName.slice(-4) === ".sif") {
      console.log("we found a sif file:", fileName);

      var byLine = Meteor.npmRequire('byline');

      var processingDefinitions = true;
      var stream = byLine(fileObject.createReadStream("uploaded_files"))
        .on('data', Meteor.bindEnvironment(function (lineObject) {
          var line = lineObject.toString();

          var brokenTabs = line.split("\t");
          if (brokenTabs.length === 2 && processingDefinitions === true) {
            console.log("adding definition:", line);
            WranglerSubmissions.update({
                  "_id": submission._id,
                }, {
                  $push: {
                    "documents": {
                      "collection_name": "network_elements",
                      "prospective_document": {
                        "network_label": "superpathway_hardcoded",
                        "name": brokenTabs[1],
                        "type": brokenTabs[0],
                      }
                    }
                  }
                });
          } else if (brokenTabs.length === 3) {
            processingDefinitions = false;
            console.log("adding interaction:", line);
            WranglerSubmissions.update({
                  "_id": submission._id,
                }, {
                  $push: {
                    "documents": {
                      "collection_name": "network_interactions",
                      "prospective_document": {
                        "network_label": { type: "superpathway_hardcoded" },
                        "source": { type: brokenTabs[0] },
                        "target": { type: brokenTabs[1] },
                        "interaction": { type: brokenTabs[2] },
                        "score": { type: Number, optional: true, decimal: true },
                      }
                    }
                  }
                });
          } else {
            console.log("don't know what to do:", line);
          }
        }
      ));
    } else {
      console.log("unknown file type");
    }

    // var stream = fileObject.createReadStream("uploaded_files")
    //   .on('data', function (chunk) {
    //     console.log("file: " + chunk);
    //     var vcf = Meteor.npmRequire('vcf.js');
    //     vcf.parser()(chunk);
    //   });
  },
  function (error) {
    console.log("Error calling callback on .on('stored') for file:", error);
  }
));

// users can only modify their own documents
UploadedFiles.allow({
  insert: function (userId, doc) {
    console.log("UploadedFiles.allow insert");
    return userId === doc.user_id;
  },
  update: function(userId, doc, fields, modifier) {
    console.log("UploadedFiles.allow update:", modifier);
    return userId === doc.user_id;
  },
  remove: function (userId, doc) {
    console.log("UploadedFiles.allow remove");
    return userId === doc.user_id;
  },
  download: function (userId, doc) {
    console.log("UploadedFiles.allow download");
    return userId === doc.user_id;
  }
});
<commit_msg>added file status updates<commit_after>// TODO: write a cron job to go through and delete unused ones (also files)
WranglerSubmissions = new Meteor.Collection("wrangler_submissions");
WranglerSubmissions.attachSchema(new SimpleSchema({
  "user_id": { type: Meteor.ObjectID },
  "files": {
    type: [
      new SimpleSchema({
        "file_id": { type: Meteor.ObjectID },
        "file_name": { type: String },
        "status": {
          type: String,
          allowedValues: [
            "creating",
            "uploading",
            "processing",
            "done",
            "error",
          ],
        },
        // TODO: only allow if status = "error"
        "error_description": { type: String, optional: true },
      })
    ],
    optional: true
  },
  "documents": {
    type: [
      new SimpleSchema({
        "collection_name": { // not so enthused about this
          type: String,
          allowedValues: [
            "network_elements",
            "network_interactions",
          ],
        },
        "prospective_document": { type: Object, blackbox: true },
      })
    ],
    optional: true,
  }
}));

UploadedFileStore = new FS.Store.GridFS("uploaded_files", {
  beforeWrite: function (fileObject) {
    // this.userId because we're on the server (doesn't work)
    fileObject.uploaded_date = new Date();
  }
});

// UploadedFileStore.on("stored", function (storeName, fileObject) {
//   if (storeName !== UploadedFileStore.name) return; // workaround for known bug
//   var assert = Meteor.npmRequire("assert");
//   var fs = Meteor.npmRequire("fs");
//   // var byLine = Meteor.npmRequire('byLine');
//   var vcf = Meteor.npmRequire('vcf.js');
//   var blob = "";
//     var stream = fileObject.createReadStream("uploaded_files")
//      .on('data', function (chunk) {
//        blob += chunk;
//      })
//      .on('end', function () {
//       //var myData = JSON.parse(stream);
//       //console.log("##file: " + myData);
//       if (blob) {
//         data = vcf.parser()(blob);
//         //data = vcf.parser()(String(fs.readFileSync('/data/MedBook/MedBook-Wrangler/webapp/test.vcf')));
//         for (h in data.header) {
//             console.log('#vcf header:',h);
//         }
//         //console.log('#DR',  data.records);
//         var len = data.records.length;
//         console.log('len',len);
//         var mut = {};
//         for (var i = 0; i < len; i++) {
//              var dx = data.records[i];
//              var keys = Object.keys(dx);
//
//              console.log('keys',keys, dx);
//              mut.gene_id = 'none';
//              mut['gene_label'] = 'WIERD';
//              for (k in keys) {
//                var key = keys[k];
//                var mapped_key = key;
//                if (key == 'TYPE') {
//                    mapped_key = 'mutation_type';
//                }
//                mut[mapped_key] = dx[key];
//                console.log('dx [',mapped_key,']=',dx[key]);
//              }
//              Mutations.insert(mut);
//              /*
//              "gene_label": { type: String },
//              "gene_id": { type: String },
//              "protein_change": { type: String, optional: true },
//              "mutation_type": { type: String }, // variant_classification for us
//              "chromosome": { type: String },
//              "start_position": { type: Number },
//              "end_position": { type: Number },
//              "reference_allele": { type: String },
//              "variant_allele": { type: String },
//              "MA_FImpact": { type: String, optional: true },
//              "MA_FIS": { type: Number, optional: true },
//              "allele_count": { type: Number, label:"Allele count in genotypes, for each ALT allele, in the same order as listed", optional:true },
//              "allele_frequency": { type: Number, decimal:true, label:"Allele frequency, for each ALT allele, in the same order as listed", optional:true },
//              "allele_number": { type: Number, label:"Number of unique alleles across all samples", optional:true },
//              "base_quality": { type: Number, decimal:true, label:"Overall average base quality", optional:true },
//              "read_depth": { type: Number, label:"Total read depth for all samples", optional:true },
//              "fraction_alt": { type: Number, decimal:true, label:"Overall fraction of reads supporting ALT", optional:true },
//              "indel_number": { type: Number, label:"Number of indels for all samples", optional:true },
//              "modification_base_changes": { type: String, label:"Modification base changes at this position", optional:true },
//              "modification_types": { type: String, label:"Modification types at this position", optional:true },
//              "sample_number": { type: Number, label:"Number of samples with data", optional:true },
//              "origin": { type: String, label:"Where the call originated from, the tumor DNA, RNA, or both", optional:true },
//              "strand_bias": { type: Number, decimal:true, label:"Overall strand bias", optional:true },
//              "somatic": { type: Boolean, label:"Indicates if record is a somatic mutation", optional:true },
//              "variant_status": { type: Number, label:"Variant status relative to non-adjacent Normal, 0=wildtype,1=germline,2=somatic,3=LOH,4=unknown,5=rnaEditing" , optional:true},
//              "reads_at_start": { type: Number, label:"Number of reads starting at this position across all samples", optional:true },
//              "reads_at_stop": { type: Number, label:"Number of reads stopping at this position across all samples", optional:true },
//              "variant_type": { type: String, label:"Variant type, can be SNP, INS or DEL", optional:true },
//              "effects": { type: [Object], label:"Predicted effects Effect ( Effect_Impact | Functional_Class | Codon_Change | Amino_Acid_change| Amino_Acid_length | Gene_Name | Transcript_BioType | Gene_Coding | Transcript_ID | Exon  | GenotypeNum [ | ERRORS | WARNINGS ] )" , optional:true }
// */
//
//         }
//         /*for (dlist in data.records) {
//             for (d in dlist) {
//               console.log('#vcf data:',dlist.d);
//             }
//         }*/
//         //console.log('data.records[0]',data.records[0]);
//         //var dx = data.records[1];
//         //console.log('data.records[1]',typeof data.records[1],Object.keys(data.records[1]),data.records[1]);
//               console.log('done mut=',mut,'\n');
//
//       }
//
// //
//   //    vcf.parser()(chunk);
//      });
//   console.log("stored file");
// });

UploadedFiles = new FS.Collection("uploaded_files", {
  stores: [UploadedFileStore],
});

UploadedFileStore.on("stored", Meteor.bindEnvironment(
  function (storeName, fileObject) {
    if (storeName !== UploadedFileStore.name) return; // workaround for known bug

    console.log("stored file callback");

    var submission = WranglerSubmissions.findOne({
      "files": {
        $elemMatch: {
          "file_id": fileObject._id
        }
      }
    });

    function setFileStatus(statusString) {
      WranglerSubmissions.update({
            "_id": submission._id,
            "files.file_id": fileObject._id,
          }, {
            $set: { "files.$.status": statusString }
          });
    }
    setFileStatus("processing");

    var fileName = fileObject.original.name;
    if (fileName.slice(-4) === ".sif") {
      console.log("we found a sif file:", fileName);

      var byLine = Meteor.npmRequire('byline');

      var processingDefinitions = true;
      var stream = byLine(fileObject.createReadStream("uploaded_files"))
        .on('data', Meteor.bindEnvironment(function (lineObject) {
          var line = lineObject.toString();

          var brokenTabs = line.split("\t");
          if (brokenTabs.length === 2 && processingDefinitions === true) {
            console.log("adding definition:", line);
            WranglerSubmissions.update({
                  "_id": submission._id,
                }, {
                  $push: {
                    "documents": {
                      "collection_name": "network_elements",
                      "prospective_document": {
                        "network_label": "superpathway_hardcoded",
                        "name": brokenTabs[1],
                        "type": brokenTabs[0],
                      }
                    }
                  }
                });
          } else if (brokenTabs.length === 3) {
            processingDefinitions = false;
            console.log("adding interaction:", line);
            WranglerSubmissions.update({
                  "_id": submission._id,
                }, {
                  $push: {
                    "documents": {
                      "collection_name": "network_interactions",
                      "prospective_document": {
                        "network_label": "superpathway_hardcoded",
                        "source": brokenTabs[0],
                        "target": brokenTabs[1],
                        "interaction": brokenTabs[2],
                      }
                    }
                  }
                });
          } else {
            console.log("don't know what to do:", line);
          }
        }
      ));
    } else {
      console.log("unknown file type");
      setFileStatus("error");
      return;
    }

    setFileStatus("done");
    // var stream = fileObject.createReadStream("uploaded_files")
    //   .on('data', function (chunk) {
    //     console.log("file: " + chunk);
    //     var vcf = Meteor.npmRequire('vcf.js');
    //     vcf.parser()(chunk);
    //   });
  },
  function (error) {
    console.log("Error calling callback on .on('stored') for file:", error);
  }
));

// users can only modify their own documents
UploadedFiles.allow({
  insert: function (userId, doc) {
    console.log("UploadedFiles.allow insert");
    return userId === doc.user_id;
  },
  update: function(userId, doc, fields, modifier) {
    console.log("UploadedFiles.allow update:", modifier);
    return userId === doc.user_id;
  },
  remove: function (userId, doc) {
    console.log("UploadedFiles.allow remove");
    return userId === doc.user_id;
  },
  download: function (userId, doc) {
    console.log("UploadedFiles.allow download");
    return userId === doc.user_id;
  }
});
<|endoftext|>


<commit_before>var _ = require('lodash-node');

/**
 * Coerces a comma- or semicolon-delimited string into an array, if needed.
 * @param  {(array|string)} val The value to check.
 * @return {array} An array, can be empty.
 */
exports.ensureArray = function ensureArray(val) {
  if (val === null || val === undefined) {
    return [];
  } else if (_.isArray(val)) {
    return val;
  } else if (_.isString(val)) {
    return val.split(/[,;]/);
  } else {
    return [val];
  }
};
<commit_msg>[Utils] Add codes, colors and string extensions<commit_after>var _ = require('lodash-node');

/**
 * Coerces a comma- or semicolon-delimited string into an array, if needed.
 * @param  {(array|string)} val The value to check.
 * @return {array} An array, can be empty.
 */
function ensureArray(val) {
  if (val === null || val === undefined) {
    return [];
  } else if (_.isArray(val)) {
    return val;
  } else if (_.isString(val)) {
    return val.split(/[,;]/);
  } else {
    return [val];
  }
}
exports.ensureArray = ensureArray;

var colors = {
  white: 0,
  black: 1,
  blue: 2,
  green: 3,
  red: 4,
  brown: 5,
  purple: 6,
  magenta: 6,
  orange: 7,
  yellow: 8,
  lightGreen: 9,
  teal: 10,
  cyan: 10,
  lightTeal: 11,
  lightCyan: 11,
  lightBlue: 12,
  pink: 13,
  lightMagenta: 13,
  gray: 14,
  lightGray: 15,
  transparent: 99 // not normally supported, except by, for example, mIRC
};
exports.colors = colors;

var codes = {
  bold: '\u0002',
  color: '\u0003',
  reset: '\u000f',
  reverse: '\u0016',
  underline: '\u001f'
};
exports.codes = codes;

function wrap(str, prefix, suffix) {
  if (typeof suffix === "undefined") {
    suffix = prefix;
  }
  return prefix + str + suffix;
}

function getStringHelper(str) {
  var helpers = {};
  helpers._string = str;
  helpers.toString = function() {
    return helpers._string;
  };

  ['bold', 'reset', 'reverse', 'underline'].forEach(function(prop) {
    Object.defineProperty(helpers, prop, {
      get: function() {
        helpers._string = wrap(helpers._string, codes[prop]);
        return helpers;
      },
      configurable: true
    });
  });

  _.each(colors, function(value, key) {
    Object.defineProperty(helpers, key, {
      get: function() {
        helpers._string = wrap(helpers._string, codes.color + value, codes.color);
        return helpers;
      },
      configurable: true
    });
  });

  return helpers;
}

Object.defineProperty(String.prototype, 'irc', {
  get: function() {
    return getStringHelper(this);
  },
  configurable: true
});
<|endoftext|>


<commit_before>/* @flow */

import { Disposable, Point } from "atom";
import React from "react";
import ReactDOM from "react-dom";
import _ from "lodash";
import os from "os";
import path from "path";

import Config from "./config";
import store from "./store";

export const INSPECTOR_URI = "atom://hydrogen/inspector";
export const WATCHES_URI = "atom://hydrogen/watch-sidebar";
export const OUTPUT_AREA_URI = "atom://hydrogen/output-area";
export const KERNEL_MONITOR_URI = "atom://hydrogen/kernel-monitor";

export function reactFactory(
  reactElement: React$Element<any>,
  domElement: HTMLElement,
  additionalTeardown: ?Function,
  disposer: atom$CompositeDisposable = store.subscriptions
) {
  ReactDOM.render(reactElement, domElement);

  const disposable = new Disposable(() => {
    ReactDOM.unmountComponentAtNode(domElement);
    if (typeof additionalTeardown === "function") additionalTeardown();
  });

  disposer.add(disposable);
}

export function focus(item: ?mixed) {
  if (item) {
    const editorPane = atom.workspace.paneForItem(item);
    if (editorPane) editorPane.activate();
  }
}

export async function openOrShowDock(URI: string): Promise<?void> {
  // atom.workspace.open(URI) will activate/focus the dock by default
  // dock.toggle() or dock.show() will leave focus wherever it was

  // this function is basically workspace.open, except it
  // will not focus the newly opened pane
  let dock = atom.workspace.paneContainerForURI(URI);
  if (dock) {
    // If the target item already exist, activate it and show dock
    const pane = atom.workspace.paneForURI(URI);
    if (pane) pane.activateItemForURI(URI);
    return dock.show();
  }

  await atom.workspace.open(URI, {
    searchAllPanes: true,
    activatePane: false
  });
  dock = atom.workspace.paneContainerForURI(URI);
  return dock ? dock.show() : null;
}

export function grammarToLanguage(grammar: ?atom$Grammar) {
  if (!grammar) return null;
  const grammarLanguage = grammar.name.toLowerCase();

  const mappings = Config.getJson("languageMappings");
  const kernelLanguage = _.findKey(
    mappings,
    l => l.toLowerCase() === grammarLanguage
  );

  return kernelLanguage ? kernelLanguage.toLowerCase() : grammarLanguage;
}

/**
 * Copied from https://github.com/nteract/nteract/blob/master/src/notebook/epics/execute.js#L37
 * Create an object that adheres to the jupyter notebook specification.
 * http://jupyter-client.readthedocs.io/en/latest/messaging.html
 *
 * @param {Object} msg - Message that has content which can be converted to nbformat
 * @return {Object} formattedMsg  - Message with the associated output type
 */
export function msgSpecToNotebookFormat(message: Message) {
  return Object.assign({}, message.content, {
    output_type: message.header.msg_type
  });
}

/**
 * A very basic converter for supporting jupyter messaging protocol v4 replies
 */
export function msgSpecV4toV5(message: Message) {
  switch (message.header.msg_type) {
    case "pyout":
      message.header.msg_type = "execute_result";
      break;
    case "pyerr":
      message.header.msg_type = "error";
      break;
    case "stream":
      if (!message.content.text) message.content.text = message.content.data;
      break;
  }
  return message;
}

const markupGrammars = new Set([
  "source.gfm",
  "source.asciidoc",
  "text.restructuredtext",
  "text.tex.latex.knitr",
  "text.md",
  "source.weave.noweb",
  "source.weave.md",
  "source.weave.latex",
  "source.weave.restructuredtext",
  "source.pweave.noweb",
  "source.pweave.md",
  "source.pweave.latex",
  "source.pweave.restructuredtext",
  "source.dyndoc.md.stata",
  "source.dyndoc.latex.stata"
]);

export function isMultilanguageGrammar(grammar: atom$Grammar) {
  return markupGrammars.has(grammar.scopeName);
}

export function kernelSpecProvidesGrammar(
  kernelSpec: Kernelspec,
  grammar: ?atom$Grammar
) {
  if (!grammar || !grammar.name || !kernelSpec || !kernelSpec.language) {
    return false;
  }
  const grammarLanguage = grammar.name.toLowerCase();
  const kernelLanguage = kernelSpec.language.toLowerCase();
  if (kernelLanguage === grammarLanguage) {
    return true;
  }

  const mappedLanguage = Config.getJson("languageMappings")[kernelLanguage];
  if (!mappedLanguage) {
    return false;
  }

  return mappedLanguage.toLowerCase() === grammarLanguage;
}

export function getEmbeddedScope(
  editor: atom$TextEditor,
  position: atom$Point
): ?string {
  const scopes = editor
    .scopeDescriptorForBufferPosition(position)
    .getScopesArray();
  return _.find(scopes, s => s.indexOf("source.embedded.") === 0);
}

export function getEditorDirectory(editor: ?atom$TextEditor) {
  if (!editor) return os.homedir();
  const editorPath = editor.getPath();
  return editorPath ? path.dirname(editorPath) : os.homedir();
}

export function log(...message: Array<any>) {
  if (atom.config.get("Hydrogen.debug")) {
    console.debug("Hydrogen:", ...message);
  }
}

export function renderDevTools(enableLogging: boolean) {
  if (!atom.devMode) return;
  try {
    const devTools = require("mobx-react-devtools");
    const div = document.createElement("div");
    document.getElementsByTagName("body")[0].appendChild(div);
    devTools.setLogEnabled(enableLogging);
    ReactDOM.render(<devTools.default noPanel />, div);
  } catch (e) {
    log("Could not enable dev tools", e);
  }
}

export function hotReloadPackage() {
  const packName = "Hydrogen";
  const packPath = atom.packages.resolvePackagePath(packName);
  if (!packPath) return;
  const packPathPrefix = packPath + path.sep;
  const zeromqPathPrefix =
    path.join(packPath, "node_modules", "zeromq") + path.sep;

  console.info(`deactivating ${packName}`);
  atom.packages.deactivatePackage(packName);
  atom.packages.unloadPackage(packName);

  // Delete require cache to re-require on activation.
  // But except zeromq native module which is not re-requireable.
  const packageLibsExceptZeromq = filePath =>
    filePath.startsWith(packPathPrefix) &&
    !filePath.startsWith(zeromqPathPrefix);

  Object.keys(require.cache)
    .filter(packageLibsExceptZeromq)
    .forEach(filePath => delete require.cache[filePath]);

  atom.packages.loadPackage(packName);
  atom.packages.activatePackage(packName);
  console.info(`activated ${packName}`);
}

export function rowRangeForCodeFoldAtBufferRow(
  editor: atom$TextEditor,
  row: number
) {
  if (parseFloat(atom.getVersion()) < 1.22) {
    return editor.languageMode.rowRangeForCodeFoldAtBufferRow(row);
  } else {
    // $FlowFixMe
    const range = editor.tokenizedBuffer.getFoldableRangeContainingPoint(
      new Point(row, Infinity),
      editor.getTabLength()
    );

    return range ? [range.start.row, range.end.row] : null;
  }
}

export const EmptyMessage = () => {
  return (

No output to display

  );
};

/**
 * Given a message whose type if `execute_reply`, calculates exection time and returns its string representation.
 *
 * @param {Message} message - A Message object whose type is `execute_reply`
 * @return {String} - A string representation of the execution time
 */
export function executionTime(message: Message): string {
  if (!message.parent_header.date || !message.header.date) {
    return "Not available";
  }
  const start = Date.parse(message.parent_header.date);
  const end = Date.parse(message.header.date);
  let time = end - start; // milliseconds
  let sec = time / 1000; // seconds
  if (sec < 60) {
    return sec.toFixed(3) + " sec";
  }
  let min = (sec - (sec % 60)) / 60;
  sec = (sec % 60).toFixed(0);
  if (min < 60) {
    return min + " min " + sec + " sec";
  }
  let hour = (min - (min % 60)) / 60;
  min %= 60;
  return hour + " h " + min + " m " + sec + " s";
}
<commit_msg>add helper functions<commit_after>/* @flow */

import { Disposable, Point } from "atom";
import React from "react";
import ReactDOM from "react-dom";
import _ from "lodash";
import os from "os";
import path from "path";

import Config from "./config";
import store from "./store";

export const INSPECTOR_URI = "atom://hydrogen/inspector";
export const WATCHES_URI = "atom://hydrogen/watch-sidebar";
export const OUTPUT_AREA_URI = "atom://hydrogen/output-area";
export const KERNEL_MONITOR_URI = "atom://hydrogen/kernel-monitor";

export function reactFactory(
  reactElement: React$Element<any>,
  domElement: HTMLElement,
  additionalTeardown: ?Function,
  disposer: atom$CompositeDisposable = store.subscriptions
) {
  ReactDOM.render(reactElement, domElement);

  const disposable = new Disposable(() => {
    ReactDOM.unmountComponentAtNode(domElement);
    if (typeof additionalTeardown === "function") additionalTeardown();
  });

  disposer.add(disposable);
}

export function focus(item: ?mixed) {
  if (item) {
    const editorPane = atom.workspace.paneForItem(item);
    if (editorPane) editorPane.activate();
  }
}

export async function openOrShowDock(URI: string): Promise<?void> {
  // atom.workspace.open(URI) will activate/focus the dock by default
  // dock.toggle() or dock.show() will leave focus wherever it was

  // this function is basically workspace.open, except it
  // will not focus the newly opened pane
  let dock = atom.workspace.paneContainerForURI(URI);
  if (dock) {
    // If the target item already exist, activate it and show dock
    const pane = atom.workspace.paneForURI(URI);
    if (pane) pane.activateItemForURI(URI);
    return dock.show();
  }

  await atom.workspace.open(URI, {
    searchAllPanes: true,
    activatePane: false
  });
  dock = atom.workspace.paneContainerForURI(URI);
  return dock ? dock.show() : null;
}

export function grammarToLanguage(grammar: ?atom$Grammar) {
  if (!grammar) return null;
  const grammarLanguage = grammar.name.toLowerCase();

  const mappings = Config.getJson("languageMappings");
  const kernelLanguage = _.findKey(
    mappings,
    l => l.toLowerCase() === grammarLanguage
  );

  return kernelLanguage ? kernelLanguage.toLowerCase() : grammarLanguage;
}

/**
 * Copied from https://github.com/nteract/nteract/blob/master/src/notebook/epics/execute.js#L37
 * Create an object that adheres to the jupyter notebook specification.
 * http://jupyter-client.readthedocs.io/en/latest/messaging.html
 *
 * @param {Object} msg - Message that has content which can be converted to nbformat
 * @return {Object} formattedMsg  - Message with the associated output type
 */
export function msgSpecToNotebookFormat(message: Message) {
  return Object.assign({}, message.content, {
    output_type: message.header.msg_type
  });
}

/**
 * A very basic converter for supporting jupyter messaging protocol v4 replies
 */
export function msgSpecV4toV5(message: Message) {
  switch (message.header.msg_type) {
    case "pyout":
      message.header.msg_type = "execute_result";
      break;
    case "pyerr":
      message.header.msg_type = "error";
      break;
    case "stream":
      if (!message.content.text) message.content.text = message.content.data;
      break;
  }
  return message;
}

const markupGrammars = new Set([
  "source.gfm",
  "source.asciidoc",
  "text.restructuredtext",
  "text.tex.latex.knitr",
  "text.md",
  "source.weave.noweb",
  "source.weave.md",
  "source.weave.latex",
  "source.weave.restructuredtext",
  "source.pweave.noweb",
  "source.pweave.md",
  "source.pweave.latex",
  "source.pweave.restructuredtext",
  "source.dyndoc.md.stata",
  "source.dyndoc.latex.stata"
]);

export function isMultilanguageGrammar(grammar: atom$Grammar) {
  return markupGrammars.has(grammar.scopeName);
}

export function kernelSpecProvidesGrammar(
  kernelSpec: Kernelspec,
  grammar: ?atom$Grammar
) {
  if (!grammar || !grammar.name || !kernelSpec || !kernelSpec.language) {
    return false;
  }
  const grammarLanguage = grammar.name.toLowerCase();
  const kernelLanguage = kernelSpec.language.toLowerCase();
  if (kernelLanguage === grammarLanguage) {
    return true;
  }

  const mappedLanguage = Config.getJson("languageMappings")[kernelLanguage];
  if (!mappedLanguage) {
    return false;
  }

  return mappedLanguage.toLowerCase() === grammarLanguage;
}

export function getEmbeddedScope(
  editor: atom$TextEditor,
  position: atom$Point
): ?string {
  const scopes = editor
    .scopeDescriptorForBufferPosition(position)
    .getScopesArray();
  return _.find(scopes, s => s.indexOf("source.embedded.") === 0);
}

export function getEditorDirectory(editor: ?atom$TextEditor) {
  if (!editor) return os.homedir();
  const editorPath = editor.getPath();
  return editorPath ? path.dirname(editorPath) : os.homedir();
}

export function log(...message: Array<any>) {
  if (atom.config.get("Hydrogen.debug")) {
    console.debug("Hydrogen:", ...message);
  }
}

export function renderDevTools(enableLogging: boolean) {
  if (!atom.devMode) return;
  try {
    const devTools = require("mobx-react-devtools");
    const div = document.createElement("div");
    document.getElementsByTagName("body")[0].appendChild(div);
    devTools.setLogEnabled(enableLogging);
    ReactDOM.render(<devTools.default noPanel />, div);
  } catch (e) {
    log("Could not enable dev tools", e);
  }
}

export function hotReloadPackage() {
  const packName = "Hydrogen";
  const packPath = atom.packages.resolvePackagePath(packName);
  if (!packPath) return;
  const packPathPrefix = packPath + path.sep;
  const zeromqPathPrefix =
    path.join(packPath, "node_modules", "zeromq") + path.sep;

  console.info(`deactivating ${packName}`);
  atom.packages.deactivatePackage(packName);
  atom.packages.unloadPackage(packName);

  // Delete require cache to re-require on activation.
  // But except zeromq native module which is not re-requireable.
  const packageLibsExceptZeromq = filePath =>
    filePath.startsWith(packPathPrefix) &&
    !filePath.startsWith(zeromqPathPrefix);

  Object.keys(require.cache)
    .filter(packageLibsExceptZeromq)
    .forEach(filePath => delete require.cache[filePath]);

  atom.packages.loadPackage(packName);
  atom.packages.activatePackage(packName);
  console.info(`activated ${packName}`);
}

export function rowRangeForCodeFoldAtBufferRow(
  editor: atom$TextEditor,
  row: number
) {
  if (parseFloat(atom.getVersion()) < 1.22) {
    return editor.languageMode.rowRangeForCodeFoldAtBufferRow(row);
  } else {
    // $FlowFixMe
    const range = editor.tokenizedBuffer.getFoldableRangeContainingPoint(
      new Point(row, Infinity),
      editor.getTabLength()
    );

    return range ? [range.start.row, range.end.row] : null;
  }
}

export const EmptyMessage = () => {
  return (

No output to display

  );
};

/**
 * Given a message whose type if `execute_reply`, calculates exection time and returns its string representation.
 *
 * @param {Message} message - A Message object whose type is `execute_reply`
 * @return {String} - A string representation of the execution time
 */
export function executionTime(message: Message): string {
  if (!message.parent_header.date || !message.header.date) {
    return "Not available";
  }
  const start = Date.parse(message.parent_header.date);
  const end = Date.parse(message.header.date);
  let time = end - start; // milliseconds
  let sec = time / 1000; // seconds
  if (sec < 60) {
    return sec.toFixed(3) + " sec";
  }
  let min = (sec - (sec % 60)) / 60;
  sec = (sec % 60).toFixed(0);
  if (min < 60) {
    return min + " min " + sec + " sec";
  }
  let hour = (min - (min % 60)) / 60;
  min %= 60;
  return hour + " h " + min + " m " + sec + " s";
}

export function js_idx_to_char_idx(js_idx, text) {
  var char_idx = js_idx;
  for (var i = 0; i < text.length && i < js_idx; i++) {
    var char_code = text.charCodeAt(i);
    // check for the first half of a surrogate pair
    if (char_code >= 0xd800 && char_code < 0xdc00) {
      char_idx -= 1;
    }
  }
  return char_idx;
}

export function char_idx_to_js_idx(char_idx, text) {
  var js_idx = char_idx;
  for (var i = 0; i < text.length && i < js_idx; i++) {
    var char_code = text.charCodeAt(i);
    // check for the first half of a surrogate pair
    if (char_code >= 0xd800 && char_code < 0xdc00) {
      js_idx += 1;
    }
  }
  return js_idx;
}
<|endoftext|>


<commit_before>/**
 * Exposing useful utilities.
 */
 module.exports.getDateString = getDateString;
 module.exports.getUserHome = getUserHome;

/**
 * Formatting date into a better form.
 *
 * @return {String} date string
 * @api public
 */
function getDateString() {
  var today = new Date();
  var dd = today.getDate();
  var mm = today.getMonth()+1; //January is 0!
  var yyyy = today.getFullYear();

  if (dd < 10) {
    dd = '0' + dd;
  }
  if (mm < 10) {
    mm = '0' + mm;
  }

  today = mm + '/' + dd + '/' + yyyy;
  return today;
}

/**
 * Standard way of getting user's home directory.
 *
 * @return {String} home directory
 * @api public
 */
function getUserHome() {
  return process.env[(process.platform === 'win32') ?
    'USERPROFILE' : 'HOME'];
}
<commit_msg>Shortened to exports<commit_after>/**
 * Exposing useful utilities.
 */
 exports = module.exports;
 exports.getDateString = getDateString;
 exports.getUserHome = getUserHome;

/**
 * Formatting date into a better form.
 *
 * @return {String} date string
 * @api public
 */
function getDateString() {
  var today = new Date();
  var dd = today.getDate();
  var mm = today.getMonth()+1; //January is 0!
  var yyyy = today.getFullYear();

  if (dd < 10) {
    dd = '0' + dd;
  }
  if (mm < 10) {
    mm = '0' + mm;
  }

  today = mm + '/' + dd + '/' + yyyy;
  return today;
}

/**
 * Standard way of getting user's home directory.
 *
 * @return {String} home directory
 * @api public
 */
function getUserHome() {
  return process.env[(process.platform === 'win32') ?
    'USERPROFILE' : 'HOME'];
}
<|endoftext|>


<commit_before>'use strict'

var RelationalStore = require('./relational-util')
var _ = require('lodash')
const mySQLStore = 'mysql-store'
const postgresStore = 'postgresql-store'
var operator = {
  'or$': 'OR',
  'and$': 'AND'
}

function parseExpression (entp, sTypes, current_name, current_value, params, values) {
  var result = {
    processed: true
  }

  if (operator.current_name) {
    parseOperation(entp, sTypes, current_name, current_value, params, values, operator.current_name)
    return result
  }

  if (current_name.indexOf('$') !== -1) {
    return result
  }

  if (current_value === null) {
    // we can't use the equality on null because NULL != NULL
    params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(current_name)) + sTypes.escape + ' IS NULL')
    return result
  }

  if (current_value instanceof RegExp) {
    var op = (current_value.ignoreCase) ? '~*' : '~'
    values.push(current_value.source)
    params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(current_name)) + sTypes.escape + op + RelationalStore.preparedStatements(sTypes.name, values.length))
    return result
  }

  if (_.isObject(current_value)) {
    result.processed = false
    return result
  }
  else {
    values.push(current_value)
    params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(current_name)) + sTypes.escape + '=' + RelationalStore.preparedStatements(sTypes.name, values.length))
    return result
  }

  return result
}

function parseOperation (entp, sTypes, current_name, current_value, params, values, operator) {
  if (!_.isArray(current_value)) {
    return {err: operator + ' operator requires an array value'}
  }

  var results = []
  for (var i in current_value) {
    var w = whereargs(entp, current_value[i])
    var current_result = buildQueryFromExpression(entp, w, sTypes, values)
    values = current_result.values
    results.push(current_result)
  }

  var resultStr = ''
  for (i in results) {
    if (resultStr.length > 0) {
      resultStr += ' ' + operator + ' '
    }
    resultStr += results[i].data
  }
  params.push('(' + resultStr + ')')
}

function buildQueryFromExpressionCustom (entp, query_parameters, sTypes, values, parseExpression) {
  var params = []
  values = values || []

  if (!_.isEmpty(query_parameters) && query_parameters.params.length > 0) {
    for (var i in query_parameters.params) {
      var current_name = query_parameters.params[i]
      var current_value = query_parameters.values[i]

      var result = parseExpression(entp, sTypes, current_name, current_value, params, values)
      if (result.err) {
        return result
      }
    }

    return {err: null, data: params.join(' AND '), values: values}
  }
  else {
    return {values: values}
  }
}

function buildQueryFromExpression (entp, query_parameters, sTypes, values) {
  return buildQueryFromExpressionCustom(entp, query_parameters, sTypes, values, parseExpression)
}

function whereargs (entp, q) {
  var w = {}

  w.params = []
  w.values = []

  var qok = RelationalStore.fixquery(entp, q)

  for (var p in qok) {
    if (qok[p] !== undefined) {
      w.params.push(RelationalStore.camelToSnakeCase(p))
      w.values.push(qok[p])
    }
  }

  return w
}

function fixPrepStatement (stm, sTypes) {
  if (sTypes.name === mySQLStore) {
    return stm
  }

  var index = 1
  while (stm.indexOf('?') !== -1) {
    stm = stm.replace('?', '$' + index)
    index++
  }
  return stm
}

var jsonSupport = function (sTypes) {
  return (sTypes.name === postgresStore)
}

function savestm (ent, sTypes) {
  var stm = {}

  var table = RelationalStore.tablename(ent)
  var entp = RelationalStore.makeentp(ent, jsonSupport(sTypes))
  var fields = _.keys(entp)

  var values = []
  var params = []

  var cnt = 0

  var escapedFields = []
  fields.forEach(function (field) {
    escapedFields.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(field)) + sTypes.escape)
    values.push(entp[field])
    params.push(RelationalStore.preparedStatements(sTypes.name, ++cnt))
  })

  stm.text = 'INSERT INTO ' + RelationalStore.escapeStr(table) + ' (' + escapedFields + ') values (' + RelationalStore.escapeStr(params) + ')'
  stm.values = values

  return stm
}

function updatestm (ent, sTypes) {
  var stm = {}

  var table = RelationalStore.tablename(ent)
  var entp = RelationalStore.makeentp(ent, jsonSupport(sTypes))
  var fields = _.keys(entp)

  var values = []
  var params = []
  var cnt = 0

  fields.forEach(function (field) {
    if (field.indexOf('$') !== -1) {
      return
    }

    if (!_.isUndefined(entp[field])) {
      values.push(entp[field])
      params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(field)) + sTypes.escape + '=' + RelationalStore.preparedStatements(sTypes.name, ++cnt))
    }
  })

  stm.text = 'UPDATE ' + RelationalStore.escapeStr(table) + ' SET ' + params + " WHERE id='" + RelationalStore.escapeStr(ent.id) + "'"
  stm.values = values

  return stm
}

function deletestm (qent, q, sTypes) {
  var stm = {}

  var table = RelationalStore.tablename(qent)
  var entp = RelationalStore.makeentp(qent, jsonSupport(sTypes))

  var values = []
  var params = []

  var cnt = 0

  var w = whereargs(entp, q)

  var wherestr = ''

  if (!_.isEmpty(w) && w.params.length > 0) {
    for (var i in w.params) {
      var param = w.params[i]
      var val = w.values[i]

      if (param.indexOf('$') !== -1) {
        continue
      }

      params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(param)) + sTypes.escape + '=' + RelationalStore.preparedStatements(sTypes.name, ++cnt))
      values.push(RelationalStore.escapeStr(val))
    }

    if (params.length > 0) {
      wherestr = ' WHERE ' + params.join(' AND ')
    }
    else {
      wherestr = ' '
    }
  }

  stm.text = 'DELETE FROM ' + RelationalStore.escapeStr(table) + wherestr
  stm.values = values

  return stm
}

function filterStatement (qent, q) {
  var stm = {}

  var table = RelationalStore.tablename(qent)
  var entp = RelationalStore.makeentp(qent)

  var values = []
  var params = []

  var cnt = 0

  var w = whereargs(entp, q)

  var wherestr = ''

  if (!_.isEmpty(w) && w.params.length > 0) {
    w.params.forEach(function (param) {
      params.push('"' + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(param)) + '"=$' + (++cnt))
    })

    w.values.forEach(function (value) {
      values.push(value)
    })

    wherestr = ' WHERE ' + params.join(' AND ')
  }

  var mq = metaquery(qent, q)

  var metastr = ' ' + mq.params.join(' ')

  var filterParams = q.distinct$ || q.fields$

  var selectColumns = []
  if (filterParams && !_.isString(filterParams) && _.isArray(filterParams)) {
    selectColumns = filterParams
  }
  if (selectColumns.length === 0) {
    selectColumns.push('*')
  }

  var select = 'SELECT ' + (q.distinct$ ? 'DISTINCT ' : '')
  stm.text = select + RelationalStore.escapeStr(selectColumns.join(',')) + ' FROM ' + RelationalStore.escapeStr(table) + wherestr + RelationalStore.escapeStr(metastr)
  stm.values = values

  return stm
}

function selectstmCustom (qent, q, sTypes, queryFromExpressionBuilder, done) {
  var specialOps = ['fields$']
  var specialOpsVal = {}

  var stm = {}

  for (var i in specialOps) {
    if (q[specialOps[i]]) {
      specialOpsVal[specialOps[i]] = q[specialOps[i]]
      delete q[specialOps[i]]
    }
  }

  var table = RelationalStore.tablename(qent)
  var entp = RelationalStore.makeentp(qent, jsonSupport(sTypes))

  var w = whereargs(entp, q)

  var response = queryFromExpressionBuilder(entp, w, sTypes)
  if (response.err) {
    return done(response.err)
  }

  var wherestr = response.data

  var values = response.values

  var mq = metaquery(qent, q)

  var metastr = ' ' + mq.params.join(' ')

  var what = '*'
  if (specialOpsVal['fields$'] && _.isArray(specialOpsVal['fields$']) && specialOpsVal['fields$'].length > 0) {
    what = ' ' + specialOpsVal['fields$'].join(', ')
    what += ', id '
  }

  stm.text = 'SELECT ' + what + ' FROM ' + RelationalStore.escapeStr(table) + (wherestr ? ' WHERE ' + wherestr : '') + RelationalStore.escapeStr(metastr)
  stm.values = values

  done(null, stm)
}

function selectstm (qent, q, sTypes, done) {
  selectstmCustom(qent, q, sTypes, buildQueryFromExpression, done)
}

function selectstmOr (qent, q, sTypes) {
  var specialOps = ['fields$']
  var specialOpsVal = {}

  var stm = {}

  for (var i in specialOps) {
    if (q[specialOps[i]]) {
      specialOpsVal[specialOps[i]] = q[specialOps[i]]
      delete q[specialOps[i]]
    }
  }

  var table = RelationalStore.tablename(qent)
  var entp = RelationalStore.makeentp(qent, jsonSupport(sTypes))

  var values = []
  var params = []

  var cnt = 0

  var w = whereargs(entp, q.ids)

  var wherestr = ''

  if (!_.isEmpty(w) && w.params.length > 0) {
    w.params.forEach(function (param) {
      params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase('id')) + sTypes.escape + '=' + RelationalStore.preparedStatements(sTypes.name, ++cnt))
    })

    w.values.forEach(function (value) {
      values.push(value)
    })

    wherestr = ' WHERE ' + params.join(' OR ')
  }

  // This is required to set the limit$ to be the length of the 'ids' array, so that in situations
  // when it's not set in the query(q) it won't be applied the default limit$ of 20 records
  if (!q.limit$) {
    q.limit$ = q.ids.length
  }

  var mq = metaquery(qent, q)

  var metastr = ' ' + mq.params.join(' ')

  var what = '*'
  if (specialOpsVal['fields$'] && _.isArray(specialOpsVal['fields$']) && specialOpsVal['fields$'].length > 0) {
    what = ' ' + specialOpsVal['fields$'].join(', ')
    what += ', id '
  }

  stm.text = 'SELECT ' + what + ' FROM ' + RelationalStore.escapeStr(table) + wherestr + RelationalStore.escapeStr(metastr)
  stm.values = values

  return stm
}

function metaquery (qent, q) {
  var mq = {}

  mq.params = []
  mq.values = []

  if (q.sort$) {
    for (var sf in q.sort$) break
    var sd = q.sort$[sf] > 0 ? 'ASC' : 'DESC'
    mq.params.push('ORDER BY ' + RelationalStore.camelToSnakeCase(sf) + ' ' + sd)
  }

  if (q.limit$) {
    mq.params.push('LIMIT ' + q.limit$)
  }

  if (q.skip$) {
    mq.params.push('OFFSET ' + q.skip$)
  }

  return mq
}

module.exports.buildQueryFromExpression = buildQueryFromExpression
module.exports.updatestm = updatestm
module.exports.deletestm = deletestm
module.exports.selectstm = selectstm
module.exports.selectstmCustom = selectstmCustom
module.exports.savestm = savestm
module.exports.fixPrepStatement = fixPrepStatement
module.exports.selectstmOr = selectstmOr
module.exports.filterStatement = filterStatement
module.exports.jsonSupport = jsonSupport
module.exports.whereargs = whereargs
module.exports.metaquery = metaquery
module.exports.buildQueryFromExpressionCustom = buildQueryFromExpressionCustom
module.exports.parseExpression = parseExpression
<commit_msg>refactored recursive call<commit_after>'use strict'

var RelationalStore = require('./relational-util')
var _ = require('lodash')
const mySQLStore = 'mysql-store'
const postgresStore = 'postgresql-store'
var operator = {
  'or$': 'OR',
  'and$': 'AND'
}

function parseExpression (entp, sTypes, current_name, current_value, params, values) {
  var result = {
    processed: true
  }

  if (current_name.indexOf('$') !== -1) {
    return result
  }

  if (current_value === null) {
    // we can't use the equality on null because NULL != NULL
    params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(current_name)) + sTypes.escape + ' IS NULL')
    return result
  }

  if (current_value instanceof RegExp) {
    var op = (current_value.ignoreCase) ? '~*' : '~'
    values.push(current_value.source)
    params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(current_name)) + sTypes.escape + op + RelationalStore.preparedStatements(sTypes.name, values.length))
    return result
  }

  if (_.isObject(current_value)) {
    result.processed = false
    return result
  }
  else {
    values.push(current_value)
    params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(current_name)) + sTypes.escape + '=' + RelationalStore.preparedStatements(sTypes.name, values.length))
    return result
  }

  return result
}

function parseOperation (entp, sTypes, current_name, current_value, params, values, operator, parseExpression) {
  if (!_.isArray(current_value)) {
    return {err: operator + ' operator requires an array value'}
  }

  var results = []
  for (var i in current_value) {
    var w = whereargs(entp, current_value[i])
    for (var j in w.params) {
      var current_result = parseExpression(entp, sTypes, w.params[j], w.params[i], params, values)
      values = current_result.values
      results.push(current_result)
    }
  }

  var resultStr = ''
  for (i in results) {
    if (resultStr.length > 0) {
      resultStr += ' ' + operator + ' '
    }
    resultStr += results[i].data
  }
  params.push('(' + resultStr + ')')
}

function buildQueryFromExpressionCustom (entp, query_parameters, sTypes, values, parseExpression) {
  var params = []
  values = values || []

  if (!_.isEmpty(query_parameters) && query_parameters.params.length > 0) {
    for (var i in query_parameters.params) {
      var current_name = query_parameters.params[i]
      var current_value = query_parameters.values[i]

      if (operator[current_name]) {
        parseOperation(entp, sTypes, current_name, current_value, params, values, operator[current_name], parseExpression)
        continue
      }

      var result = parseExpression(entp, sTypes, current_name, current_value, params, values)
      if (result.err) {
        return result
      }
    }

    return {err: null, data: params.join(' AND '), values: values}
  }
  else {
    return {values: values}
  }
}

function buildQueryFromExpression (entp, query_parameters, sTypes, values) {
  return buildQueryFromExpressionCustom(entp, query_parameters, sTypes, values, parseExpression)
}

function whereargs (entp, q) {
  var w = {}

  w.params = []
  w.values = []

  var qok = RelationalStore.fixquery(entp, q)

  for (var p in qok) {
    if (qok[p] !== undefined) {
      w.params.push(RelationalStore.camelToSnakeCase(p))
      w.values.push(qok[p])
    }
  }

  return w
}

function fixPrepStatement (stm, sTypes) {
  if (sTypes.name === mySQLStore) {
    return stm
  }

  var index = 1
  while (stm.indexOf('?') !== -1) {
    stm = stm.replace('?', '$' + index)
    index++
  }
  return stm
}

var jsonSupport = function (sTypes) {
  return (sTypes.name === postgresStore)
}

function savestm (ent, sTypes) {
  var stm = {}

  var table = RelationalStore.tablename(ent)
  var entp = RelationalStore.makeentp(ent, jsonSupport(sTypes))
  var fields = _.keys(entp)

  var values = []
  var params = []

  var cnt = 0

  var escapedFields = []
  fields.forEach(function (field) {
    escapedFields.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(field)) + sTypes.escape)
    values.push(entp[field])
    params.push(RelationalStore.preparedStatements(sTypes.name, ++cnt))
  })

  stm.text = 'INSERT INTO ' + RelationalStore.escapeStr(table) + ' (' + escapedFields + ') values (' + RelationalStore.escapeStr(params) + ')'
  stm.values = values

  return stm
}

function updatestm (ent, sTypes) {
  var stm = {}

  var table = RelationalStore.tablename(ent)
  var entp = RelationalStore.makeentp(ent, jsonSupport(sTypes))
  var fields = _.keys(entp)

  var values = []
  var params = []
  var cnt = 0

  fields.forEach(function (field) {
    if (field.indexOf('$') !== -1) {
      return
    }

    if (!_.isUndefined(entp[field])) {
      values.push(entp[field])
      params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(field)) + sTypes.escape + '=' + RelationalStore.preparedStatements(sTypes.name, ++cnt))
    }
  })

  stm.text = 'UPDATE ' + RelationalStore.escapeStr(table) + ' SET ' + params + " WHERE id='" + RelationalStore.escapeStr(ent.id) + "'"
  stm.values = values

  return stm
}

function deletestm (qent, q, sTypes) {
  var stm = {}

  var table = RelationalStore.tablename(qent)
  var entp = RelationalStore.makeentp(qent, jsonSupport(sTypes))

  var values = []
  var params = []

  var cnt = 0

  var w = whereargs(entp, q)

  var wherestr = ''

  if (!_.isEmpty(w) && w.params.length > 0) {
    for (var i in w.params) {
      var param = w.params[i]
      var val = w.values[i]

      if (param.indexOf('$') !== -1) {
        continue
      }

      params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(param)) + sTypes.escape + '=' + RelationalStore.preparedStatements(sTypes.name, ++cnt))
      values.push(RelationalStore.escapeStr(val))
    }

    if (params.length > 0) {
      wherestr = ' WHERE ' + params.join(' AND ')
    }
    else {
      wherestr = ' '
    }
  }

  stm.text = 'DELETE FROM ' + RelationalStore.escapeStr(table) + wherestr
  stm.values = values

  return stm
}

function filterStatement (qent, q) {
  var stm = {}

  var table = RelationalStore.tablename(qent)
  var entp = RelationalStore.makeentp(qent)

  var values = []
  var params = []

  var cnt = 0

  var w = whereargs(entp, q)

  var wherestr = ''

  if (!_.isEmpty(w) && w.params.length > 0) {
    w.params.forEach(function (param) {
      params.push('"' + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase(param)) + '"=$' + (++cnt))
    })

    w.values.forEach(function (value) {
      values.push(value)
    })

    wherestr = ' WHERE ' + params.join(' AND ')
  }

  var mq = metaquery(qent, q)

  var metastr = ' ' + mq.params.join(' ')

  var filterParams = q.distinct$ || q.fields$

  var selectColumns = []
  if (filterParams && !_.isString(filterParams) && _.isArray(filterParams)) {
    selectColumns = filterParams
  }
  if (selectColumns.length === 0) {
    selectColumns.push('*')
  }

  var select = 'SELECT ' + (q.distinct$ ? 'DISTINCT ' : '')
  stm.text = select + RelationalStore.escapeStr(selectColumns.join(',')) + ' FROM ' + RelationalStore.escapeStr(table) + wherestr + RelationalStore.escapeStr(metastr)
  stm.values = values

  return stm
}

function selectstmCustom (qent, q, sTypes, queryFromExpressionBuilder, done) {
  var specialOps = ['fields$']
  var specialOpsVal = {}

  var stm = {}

  for (var i in specialOps) {
    if (q[specialOps[i]]) {
      specialOpsVal[specialOps[i]] = q[specialOps[i]]
      delete q[specialOps[i]]
    }
  }

  var table = RelationalStore.tablename(qent)
  var entp = RelationalStore.makeentp(qent, jsonSupport(sTypes))

  var w = whereargs(entp, q)

  var response = queryFromExpressionBuilder(entp, w, sTypes)
  if (response.err) {
    return done(response.err)
  }

  var wherestr = response.data

  var values = response.values

  var mq = metaquery(qent, q)

  var metastr = ' ' + mq.params.join(' ')

  var what = '*'
  if (specialOpsVal['fields$'] && _.isArray(specialOpsVal['fields$']) && specialOpsVal['fields$'].length > 0) {
    what = ' ' + specialOpsVal['fields$'].join(', ')
    what += ', id '
  }

  stm.text = 'SELECT ' + what + ' FROM ' + RelationalStore.escapeStr(table) + (wherestr ? ' WHERE ' + wherestr : '') + RelationalStore.escapeStr(metastr)
  stm.values = values

  done(null, stm)
}

function selectstm (qent, q, sTypes, done) {
  selectstmCustom(qent, q, sTypes, buildQueryFromExpression, done)
}

function selectstmOr (qent, q, sTypes) {
  var specialOps = ['fields$']
  var specialOpsVal = {}

  var stm = {}

  for (var i in specialOps) {
    if (q[specialOps[i]]) {
      specialOpsVal[specialOps[i]] = q[specialOps[i]]
      delete q[specialOps[i]]
    }
  }

  var table = RelationalStore.tablename(qent)
  var entp = RelationalStore.makeentp(qent, jsonSupport(sTypes))

  var values = []
  var params = []

  var cnt = 0

  var w = whereargs(entp, q.ids)

  var wherestr = ''

  if (!_.isEmpty(w) && w.params.length > 0) {
    w.params.forEach(function (param) {
      params.push(sTypes.escape + RelationalStore.escapeStr(RelationalStore.camelToSnakeCase('id')) + sTypes.escape + '=' + RelationalStore.preparedStatements(sTypes.name, ++cnt))
    })

    w.values.forEach(function (value) {
      values.push(value)
    })

    wherestr = ' WHERE ' + params.join(' OR ')
  }

  // This is required to set the limit$ to be the length of the 'ids' array, so that in situations
  // when it's not set in the query(q) it won't be applied the default limit$ of 20 records
  if (!q.limit$) {
    q.limit$ = q.ids.length
  }

  var mq = metaquery(qent, q)

  var metastr = ' ' + mq.params.join(' ')

  var what = '*'
  if (specialOpsVal['fields$'] && _.isArray(specialOpsVal['fields$']) && specialOpsVal['fields$'].length > 0) {
    what = ' ' + specialOpsVal['fields$'].join(', ')
    what += ', id '
  }

  stm.text = 'SELECT ' + what + ' FROM ' + RelationalStore.escapeStr(table) + wherestr + RelationalStore.escapeStr(metastr)
  stm.values = values

  return stm
}

function metaquery (qent, q) {
  var mq = {}

  mq.params = []
  mq.values = []

  if (q.sort$) {
    for (var sf in q.sort$) break
    var sd = q.sort$[sf] > 0 ? 'ASC' : 'DESC'
    mq.params.push('ORDER BY ' + RelationalStore.camelToSnakeCase(sf) + ' ' + sd)
  }

  if (q.limit$) {
    mq.params.push('LIMIT ' + q.limit$)
  }

  if (q.skip$) {
    mq.params.push('OFFSET ' + q.skip$)
  }

  return mq
}

module.exports.buildQueryFromExpression = buildQueryFromExpression
module.exports.updatestm = updatestm
module.exports.deletestm = deletestm
module.exports.selectstm = selectstm
module.exports.selectstmCustom = selectstmCustom
module.exports.savestm = savestm
module.exports.fixPrepStatement = fixPrepStatement
module.exports.selectstmOr = selectstmOr
module.exports.filterStatement = filterStatement
module.exports.jsonSupport = jsonSupport
module.exports.whereargs = whereargs
module.exports.metaquery = metaquery
module.exports.buildQueryFromExpressionCustom = buildQueryFromExpressionCustom
module.exports.parseExpression = parseExpression
<|endoftext|>


<commit_before>exports.Response = function(response) {
    return {
        response: function() {
            return response
        },
        handleUserError: function(error) {
            response.send(error.message, { 'Content-Type': 'text/plain' }, 400)
        },
        handleServerError: function(error) {
            response.send("Internal error", { 'Content-Type': 'text/plain' }, 500)
            console.error(error)
        }
    }
}

/**
 * Returns a function that handles callback response and throwed errors
 *
 * - Not null responses (wich value is casted to an array) are converted to a
 *   call to handledCallback(null[, ...])
 * - Nothing is done on null responses (to only handle errors)
 * - Throwed errors are converted to a call to handledCallback(error)
 */
exports.handledCallback = function(handledCallback, callback) {
    return function() {
        var response
        try {
            response = callback.apply(null, arguments)
            if (response != null) {
                if (! response instanceof Array) response = [response]
                // Add error ("no error") parameter
                response.unshift(null)
            }
        } catch (error) {
            var response = [error]
        }
        if (response != null) handledCallback.apply(null, response)
    }
}

exports.request = function(args, callback) {
    exports.handledCallback(callback, function() {
        require('request')(args, exports.handledCallback(callback, function(error, response, body) {
            if (error) throw error
            if (response.statusCode >= 400) throw new Error("Error " + response.statusCode)
            return [response, body]
        }))
    })()
}
<commit_msg>Accept non array responses in handledCallback()<commit_after>var toArray = function(value) {
    return Array.isArray(value) ? value : [value]
}

exports.Response = function(response) {
    return {
        response: function() {
            return response
        },
        handleUserError: function(error) {
            response.send(error.message, { 'Content-Type': 'text/plain' }, 400)
        },
        handleServerError: function(error) {
            response.send("Internal error", { 'Content-Type': 'text/plain' }, 500)
            console.error(error)
        }
    }
}

/**
 * Returns a function that handles callback response and throwed errors
 *
 * - Not null responses (wich value is casted to an array) are converted to a
 *   call to handledCallback(null[, ...])
 * - Nothing is done on null responses (to only handle errors)
 * - Throwed errors are converted to a call to handledCallback(error)
 */
exports.handledCallback = function(handledCallback, callback) {
    return function() {
        var response
        try {
            response = callback.apply(null, arguments)
            response = toArray(response)
            if (response != null) {
                if (! response instanceof Array) response = [response]
                // Add error ("no error") parameter
                response.unshift(null)
            }
        } catch (error) {
            var response = [error]
        }
        if (response != null) handledCallback.apply(null, response)
    }
}

exports.request = function(args, callback) {
    exports.handledCallback(callback, function() {
        require('request')(args, exports.handledCallback(callback, function(error, response, body) {
            if (error) throw error
            if (response.statusCode >= 400) throw new Error("Error " + response.statusCode)
            return [response, body]
        }))
    })()
}
<|endoftext|>


<commit_before>var Fs = require('fs');
var Path = require('path');

var internals = {};

// Find the topmost parent of the given module.
internals.findParent = function (mod) {

    return mod.parent ? internals.findParent(mod.parent) : mod;
};

// Similar to mkdir -p, recursively creates directories until `path` exists
internals.mkdir = function (path) {

    var mode = ~process.umask() & parseInt('777', 8);

    if (exports.isDir(path)) {
        return;
    }

    try {
        Fs.mkdirSync(path, mode);
    }
    catch (err) {
        if (err.code !== 'ENOENT') {
            throw err;
        }

        internals.mkdir(Path.dirname(path));
        internals.mkdir(path);
    }
};

internals.pathSep = process.platform === 'win32' ? '\\\\' : '\/';

// Expands source and target to absolute paths, then calls internals.copy
exports.copy = function (source, target, options) {

    if (typeof target === 'object') {
        options = target;
        target = undefined;
    }

    options = options || {};

    var root = Path.dirname(internals.findParent(module).filename);
    var projectRoot = exports.findProjectRoot(root);

    var sourcePath = Path.resolve(root, source);
    var targetPath = Path.resolve(projectRoot, target || source);

    if (!(new RegExp('^' + projectRoot.replace(/\//g, '\/').replace(/\\/g, '\\\\') + internals.pathSep + '.*$')).test(targetPath)) {
        throw new Error('Destination must be within project root');
    }

    return internals.copy(sourcePath, targetPath, options);
};

// Determine if source is a directory or a file and call the appropriate method
internals.copy = function (source, target, options) {

    if (exports.isDir(source)) {
        internals.copyDirectory(source, target, options);
    }
    else {
        return internals.copyFile(source, target, options);
    }
};

// Recursively copy a directory
internals.copyDirectory = function (source, target, options) {

    internals.mkdir(target);

    var sources = Fs.readdirSync(source);
    for (var i = 0, l = sources.length; i < l; ++i) {
        var sourcePath = Path.join(source, sources[i]);
        var targetPath = Path.join(target, sources[i]);

        internals.copy(sourcePath, targetPath, options);
    }
};

// Copy a single file
internals.copyFile = function (source, target, options) {

    internals.mkdir(Path.dirname(target));

    var mode = ~process.umask() & parseInt('666', 8);

    if (Fs.existsSync(target) &&
        !options.overwrite) {

        return new Error(target + ' already exists');
    }

    var sourceStream = Fs.createReadStream(source);
    var targetStream = Fs.createWriteStream(target, { flag: 'w', mode: mode });

    sourceStream.pipe(targetStream);
};

// Given a path, determine if the path is a directory
exports.isDir = function (path) {

    try {
        var stat = Fs.statSync(path);
        return stat.isDirectory();
    }
    catch (e) {
        return false;
    }
};

// Given a starting directory, find the root of a git repository.
// In this case, the root is defined as the first directory that contains
// a directory named ".git"
//
// Returns a string if found, otherwise undefined
exports.findGitRoot = function (start) {

    start = start || Path.dirname(internals.findParent(module).filename);
    var root;

    if (exports.isDir(Path.join(start, '.git'))) {
        root = start;
    }
    else if (Path.dirname(start) !== start) {
        root = exports.findGitRoot(Path.dirname(start));
    }

    return root;
};

// Given a starting directory, find the root of the current project.
// The root of the project is defined as the topmost directory that is
// *not* contained within a directory named "node_modules" that also
// contains a file named "package.json"
//
// Returns a string
exports.findProjectRoot = function (start) {

    start = start || Path.dirname(internals.findParent(module).filename);
    var position = start.indexOf('node_modules');
    var root = start.slice(0, position === -1 ? undefined : position - Path.sep.length);

    while (!Fs.existsSync(Path.join(root, 'package.json'))) {
        root = exports.findProjectRoot(Path.dirname(root));
    }

    return root;
};

// Given a root path, find a list of projects.
// A project is defined as any directory within 4 levels of the starting
// directory that contains a file named "package.json"
//
// Returns an array
exports.findProjects = function (start, depth) {

    start = start || exports.findGitRoot(internals.findParent(module).filename);
    depth = depth || 0;
    ++depth;

    if (depth > 4 ||
        !exports.isDir(start) ||
        start.indexOf('node_modules') !== -1) {

        return [];
    }

    var dirs = Fs.readdirSync(start);
    var projects = [];

    if (Fs.existsSync(Path.join(start, 'package.json'))) {
        projects.push(start);
    }

    for (var i = 0, il = dirs.length; i < il; ++i) {
        var dir = dirs[i];
        var path = Path.join(start, dir);

        if (Fs.existsSync(Path.join(path, 'package.json'))) {
            projects.push(path);
        }
        else {
            projects = projects.concat(exports.findProjects(path, depth));
        }
    }

    return projects;
};

// Install the git hooks as specified by `hooks`. Should be an array of
// strings, like ['pre-commit']. Will automatically turn a single argument into
// an array for simplicity (e.g. Validate.installHooks('pre-commit') works fine).
exports.installHooks = function (hooks) {

    if (!Array.isArray(hooks)) {
        hooks = [hooks];
    }

    var gitRoot = exports.findGitRoot();

    for (var i = 0, l = hooks.length; i < l; ++i) {
        var hook = hooks[i];
        var dest = Path.join(gitRoot, '.git', 'hooks', hook);
        var source = Path.relative(Path.dirname(dest), Path.resolve(__dirname, '..', 'bin', 'validate'));

        if (Fs.existsSync(dest)) {
            var linkDest = Fs.readlinkSync(dest);
            if (linkDest !== source) {
                Fs.renameSync(dest, dest + '.backup');
                Fs.symlinkSync(source, dest, 'file');
            }
        }
        else {
            Fs.symlinkSync(source, dest, 'file');
        }
    }
};
<commit_msg>remove call to replace() that has no effect<commit_after>var Fs = require('fs');
var Path = require('path');

var internals = {};

// Find the topmost parent of the given module.
internals.findParent = function (mod) {

    return mod.parent ? internals.findParent(mod.parent) : mod;
};

// Similar to mkdir -p, recursively creates directories until `path` exists
internals.mkdir = function (path) {

    var mode = ~process.umask() & parseInt('777', 8);

    if (exports.isDir(path)) {
        return;
    }

    try {
        Fs.mkdirSync(path, mode);
    }
    catch (err) {
        if (err.code !== 'ENOENT') {
            throw err;
        }

        internals.mkdir(Path.dirname(path));
        internals.mkdir(path);
    }
};

internals.pathSep = process.platform === 'win32' ? '\\\\' : '\/';

// Expands source and target to absolute paths, then calls internals.copy
exports.copy = function (source, target, options) {

    if (typeof target === 'object') {
        options = target;
        target = undefined;
    }

    options = options || {};

    var root = Path.dirname(internals.findParent(module).filename);
    var projectRoot = exports.findProjectRoot(root);

    var sourcePath = Path.resolve(root, source);
    var targetPath = Path.resolve(projectRoot, target || source);

    if (!(new RegExp('^' + projectRoot.replace(/\\/g, '\\\\') + internals.pathSep + '.*$')).test(targetPath)) {
        throw new Error('Destination must be within project root');
    }

    return internals.copy(sourcePath, targetPath, options);
};

// Determine if source is a directory or a file and call the appropriate method
internals.copy = function (source, target, options) {

    if (exports.isDir(source)) {
        internals.copyDirectory(source, target, options);
    }
    else {
        return internals.copyFile(source, target, options);
    }
};

// Recursively copy a directory
internals.copyDirectory = function (source, target, options) {

    internals.mkdir(target);

    var sources = Fs.readdirSync(source);
    for (var i = 0, l = sources.length; i < l; ++i) {
        var sourcePath = Path.join(source, sources[i]);
        var targetPath = Path.join(target, sources[i]);

        internals.copy(sourcePath, targetPath, options);
    }
};

// Copy a single file
internals.copyFile = function (source, target, options) {

    internals.mkdir(Path.dirname(target));

    var mode = ~process.umask() & parseInt('666', 8);

    if (Fs.existsSync(target) &&
        !options.overwrite) {

        return new Error(target + ' already exists');
    }

    var sourceStream = Fs.createReadStream(source);
    var targetStream = Fs.createWriteStream(target, { flag: 'w', mode: mode });

    sourceStream.pipe(targetStream);
};

// Given a path, determine if the path is a directory
exports.isDir = function (path) {

    try {
        var stat = Fs.statSync(path);
        return stat.isDirectory();
    }
    catch (e) {
        return false;
    }
};

// Given a starting directory, find the root of a git repository.
// In this case, the root is defined as the first directory that contains
// a directory named ".git"
//
// Returns a string if found, otherwise undefined
exports.findGitRoot = function (start) {

    start = start || Path.dirname(internals.findParent(module).filename);
    var root;

    if (exports.isDir(Path.join(start, '.git'))) {
        root = start;
    }
    else if (Path.dirname(start) !== start) {
        root = exports.findGitRoot(Path.dirname(start));
    }

    return root;
};

// Given a starting directory, find the root of the current project.
// The root of the project is defined as the topmost directory that is
// *not* contained within a directory named "node_modules" that also
// contains a file named "package.json"
//
// Returns a string
exports.findProjectRoot = function (start) {

    start = start || Path.dirname(internals.findParent(module).filename);
    var position = start.indexOf('node_modules');
    var root = start.slice(0, position === -1 ? undefined : position - Path.sep.length);

    while (!Fs.existsSync(Path.join(root, 'package.json'))) {
        root = exports.findProjectRoot(Path.dirname(root));
    }

    return root;
};

// Given a root path, find a list of projects.
// A project is defined as any directory within 4 levels of the starting
// directory that contains a file named "package.json"
//
// Returns an array
exports.findProjects = function (start, depth) {

    start = start || exports.findGitRoot(internals.findParent(module).filename);
    depth = depth || 0;
    ++depth;

    if (depth > 4 ||
        !exports.isDir(start) ||
        start.indexOf('node_modules') !== -1) {

        return [];
    }

    var dirs = Fs.readdirSync(start);
    var projects = [];

    if (Fs.existsSync(Path.join(start, 'package.json'))) {
        projects.push(start);
    }

    for (var i = 0, il = dirs.length; i < il; ++i) {
        var dir = dirs[i];
        var path = Path.join(start, dir);

        if (Fs.existsSync(Path.join(path, 'package.json'))) {
            projects.push(path);
        }
        else {
            projects = projects.concat(exports.findProjects(path, depth));
        }
    }

    return projects;
};

// Install the git hooks as specified by `hooks`. Should be an array of
// strings, like ['pre-commit']. Will automatically turn a single argument into
// an array for simplicity (e.g. Validate.installHooks('pre-commit') works fine).
exports.installHooks = function (hooks) {

    if (!Array.isArray(hooks)) {
        hooks = [hooks];
    }

    var gitRoot = exports.findGitRoot();

    for (var i = 0, l = hooks.length; i < l; ++i) {
        var hook = hooks[i];
        var dest = Path.join(gitRoot, '.git', 'hooks', hook);
        var source = Path.relative(Path.dirname(dest), Path.resolve(__dirname, '..', 'bin', 'validate'));

        if (Fs.existsSync(dest)) {
            var linkDest = Fs.readlinkSync(dest);
            if (linkDest !== source) {
                Fs.renameSync(dest, dest + '.backup');
                Fs.symlinkSync(source, dest, 'file');
            }
        }
        else {
            Fs.symlinkSync(source, dest, 'file');
        }
    }
};
<|endoftext|>