Source: services/concept_expansion/v1-beta.js

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

'use strict';

var pick           = require('object.pick');
var extend         = require('extend');
var requestFactory = require('../../lib/requestwrapper');

var concept_decode = {
  'zZzAmpersandzZz'  : '&',
  ' zZzApostrophezZz' : '\'',
  ' zZzAtzZz'         : '@',
  'zZzBackslashzZz'   : '\\',
  ' zZzCloseParenzZz' : ')',
  ' zZzColonzZz'      : ':',
  ' zZzCommazZz'      : ',',
  'zZzCommazZz'       : ',',
  ' zZzDashzZz '      : '-',
  'zZzDollarzZz'      : '$',
  ' zZzEqualszZz '    : '=',
  ' zZzExclamationzZz': '!',
  'zZzHashzZz'        : '#',
  'zZzOpenParenzZz'   : '(',
  'zZzPercentzZz'     : '%',
  ' zZzPeriodzZz'     : '.',
  'zZzPipezZz'        : '|',
  'zZzPluszZz'        : '+',
  'zZzQuestionMarkzZz': '?',
  'zZzQuotezZz'       : '"',
  'zZzSemicolonzZz'   : ';',
  ' zZzSlashzZz'      : '/',
  'zZzSquareClosezZz' : ']',
  'zZzSquareOpenzZz'  : '[',
  'zZzStarzZz'        : '*',
  ' zZzUnderbarzZz'   : '_',
  };

// The concepts are encoded using the concept_decode map
// Create a regular expression to decode them to a human readable form
var decoderRegExp = new RegExp('/'+Object.keys(concept_decode).join('|')+'/','g');

function decodeConcept(encoded_concept) {
  return {
    prevalence: encoded_concept.prevalence,
    result: encoded_concept.result.replace(decoderRegExp,function(word) {
      return concept_decode[word];
    })
  };
}

function responseFormatter(cb) {
  return function(err, result) {
    if (err) {
      cb(err, result);
    }
    else {
      result.return_seeds = result.return_seeds.map(decodeConcept);
      cb(null, result);
    }
  };
}

/**
 *
 * @param options
 * @constructor
 */
function ConceptExpansion(options) {
  var serviceDefaults = {
    url: 'https://gateway.watsonplatform.net/concept-expansion-beta/api'
  };

  // Extend default options with user provided options
  this._options = extend(serviceDefaults, options);
}

ConceptExpansion.prototype.createJob = function(params, callback) {
  var body = extend({}, this._options, params);
  var parameters = {
    options: {
      method: 'POST',
      url: '/v1/upload',
      body: pick(body, ['dataset', 'seeds', 'label']),
      json: true
    },
    requiredParams: ['seeds'],
    defaultOptions: this._options
  };
  return requestFactory(parameters, callback);
};

ConceptExpansion.prototype.getStatus = function(params, callback) {
  var parameters = {
    options: {
      method: 'GET',
      url: '/v1/status',
      json: true,
      qs: params
    },
    requiredParams: ['jobid'],
    defaultOptions: this._options
  };
  return requestFactory(parameters, callback);
};


ConceptExpansion.prototype.getResult = function(params, callback) {
  var parameters = {
    options: {
      method: 'PUT',
      url: '/v1/result',
      body: params,
      json: true
    },
    requiredParams: ['jobid'],
    defaultOptions: this._options
  };
  return requestFactory(parameters, responseFormatter(callback));
};

ConceptExpansion.prototype.expand = function(params, callback) {
  var self = this;

  return self.createJob(params, function(err, job) {
      if (err)
        return callback(err);

    var processStatus = function(err, _status) {
      if (err)
        return callback(err);

      var status = _status.state;
      //if Awaiting Work or In Flight
      if (status === 'A' || status === 'G') {

        setTimeout(function() {
          self.getStatus(job,processStatus);
        }, params.delay || 4000);

      } else if (status === 'R' ) { // If retrieved
        callback({error: 'retrieved'});
      } else if (status === 'F' ) { // If fail
        callback({error: 'fail'});
      } else if (status === 'D') { // if done
        self.getResult(job, callback);
      } else {
        callback({error:'Unrecognized status: '+status});
      }
    };

    self.getStatus(job,processStatus);
  });
};

module.exports = ConceptExpansion;