<commit_before>module.exports = (function Nfield () {

  var Promise = require('bluebird');

  var nfieldInstance;

  /**
   * Creates Nfield instance
   * @constructor NfieldInstance
   * @param {Object} nfieldParams - Parameters to configure Nfield user to use with API, must contain server url and user credentials
   * @param {Object=} requestParams - Parameters to configure request module, that is used to connect to API
   */
  function NfieldInstance (nfieldParams, requestParams) {

    var _this = this;
    var request;
    var token = { 'AuthenticationToken' : '', 'Timestamp' : 0 };
    var connectInterval;
    var nfieldOptions = nfieldParams || {};
    var requestOptions = requestParams || {};

    /**
     * Reconfigures Nfield instance
     * @memberof NfieldInstance
     * @method configure
     * @param {Object=} nP - Parameters to configure Nfield user to use with API, must contain server url and user credentials
     * @param {Object=} rP - Parameters to configure request module, that is used to connect to API
     */
    _this.configure = function configure (nP, rP) {
      nfieldOptions = nP || nfieldOptions;
      requestOptions = rP || requestOptions;
      requestOptions.baseUrl = nfieldOptions.server || 'https://api.nfieldmr.com/';
      request = Promise.promisify(require('request').defaults(requestOptions));
    };

    /**
     * Response callback
     * @callback responseCallback
     * @param {Array} err
     * @param {Array} resp
     */

    // SignIn

    /**
     *
Sign in to the Nfield API

     *
 Nfield API reference:
     *

[POST v1/SignIn]{@link https://api.nfieldmr.com/help/api/post-v1-signin}

     *

     * @memberof NfieldInstance
     * @method signIn
     * @param {Object} credentials - Sign in credentials
     * @param {String} credentials.Domain
     * @param {String} credentials.Username
     * @param {String} credentials.Password
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.signIn = function signIn (credentials, callback) {
      return request({
        method : 'POST',
        uri : 'v1/SignIn',
        json : credentials
      }).nodeify(callback);
    };

    // SurveyFieldwork

    /**
     *
Request survey fieldwork status

     *
 Nfield API reference:
     *

[GET v1/Surveys/{surveyId}/Fieldwork/Status]{@link https://api.nfieldmr.com/help/api/get-v1-surveys-surveyid-fieldwork-status}

     *

     * @memberof NfieldInstance
     * @method getSurveyStatus
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.getSurveyStatus = function getSurveyStatus (surveyId, callback) {
      return request({
        method : 'GET',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Status').replace('{surveyId}', surveyId),
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    };

    /**
     *
Start survey

     *
 Nfield API reference:
     *

[PUT v1/Surveys/{surveyId}/Fieldwork/Start]{@link https://api.nfieldmr.com/help/api/put-v1-surveys-surveyid-fieldwork-start}

     *

     * @memberof NfieldInstance
     * @method startSurvey
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.startSurvey = function startSurvey (surveyId, callback) {
      return request({
        method : 'PUT',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Start').replace('{surveyId}', surveyId),
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    };

    /**
     *
Stop (pause) survey

     *
 Nfield API reference:
     *

[PUT v1/Surveys/{surveyId}/Fieldwork/Stop]{@link https://api.nfieldmr.com/help/api/put-v1-surveys-surveyid-fieldwork-stop}

     *

     * @memberof NfieldInstance
     * @method stopSurvey
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.stopSurvey = function stopSurvey (surveyId, callback) {
      return request({
        method : 'PUT',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Stop').replace('{surveyId}', surveyId),
        json : {
          // TODO: Wainig for the answer from the NIPO support to clarify meaning of the variable, value is fixed for now
          'TerminateRunningInterviews' : true
        },
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    };

    // DefaultTexts

    /**
     *
Get specific/all default text(s) for the domain

     *
Nfield API reference:
     *

[GET v1/DefaultTexts]{@link https://api.nfieldmr.com/help/api/get-v1-defaulttexts}

     *
[GET v1/DefaultTexts/{translationKey}]{@link https://api.nfieldmr.com/help/api/get-v1-defaulttexts-translationkey}

     *

     * @memberof NfieldInstance
     * @method getDefaultText
     * @param {String=} translationKey - Translation key
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.getDefaultText = function getDefaultText (translationKey, callback) {
      var reqURI = '';

      if (translationKey) {
        reqURI = ('v1/DefaultTexts/{translationKey}').replace('{translationKey}', translationKey);
      } else {
        reqURI = 'v1/DefaultTexts';
      }

      return request({
        method : 'GET',
        uri : reqURI,
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    };

    /**
     * Token update error callback
     * @callback persistantErrorCallback
     * @param {Array} error - Request response array
     */

    /**
     *
Connects Nfield instance to Nfield API with parameters provided during initialization

     *
Nfield API uses tokens that lasts for 15 minutes for authorisation, so as an options this method allows you to initiate an autoupdate for the token in Nfield instance, that fires every 12 minutes

     * @memberof NfieldInstance
     * @method connect
     * @param {Boolean=} persistant - Initiate an autoupdate for token (true/false)
     * @param {persistantErrorCallback=} persistantErrorCallback - Callback, that fires if something goes wrong during token update
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.connect = function connect (persistant, persistantErrorCallback, callback) {
      if (persistant === true && !connectInterval) {
        connectInterval = setInterval(function () {
          _this.signIn(nfieldOptions.credentials).then(function(data) {
            if (data[0].statusCode == 200) {
              token.AuthenticationToken = data[0].body.AuthenticationToken;
              token.Timestamp = Date.now();
            } else {
              if (typeof persistantErrorCallback == 'function') persistantErrorCallback(data);
            }
          });
        }, 1000 * 60 * 12);
      } else if (persistant === true && connectInterval) {
        console.log('Persistant connection already running');
      }

      return new Promise(function (resolve, reject) {
        if (token.AuthenticationToken !== '' && (Date.now() - token.Timestamp) < 1000 * 60 * 12) {
          resolve(token);
        } else {
          _this.signIn(nfieldOptions.credentials).then(function (data) {
            if (data[0].statusCode == 200) {
              token.AuthenticationToken = data[0].body.AuthenticationToken;
              token.Timestamp = Date.now();
              resolve(token);
            } else {
              reject(data);
            }
          }).catch(function (error) {
            reject(error);
          });
        }
      }).nodeify(callback);
    };

    /**
     * Clears persistant token update interval
     * @memberof NfieldInstance
     * @method stopPersistant
     */
    _this.stopPersistant = function stopPersistant () {
      clearInterval(connectInterval);
      connectInterval = null;
    };

    _this.configure(nfieldOptions, requestOptions);
  }

  /**
   * Creates new [Nfield instance]{@link NfieldInstance} or returns existing one
   * @memberof Nfield
   * @method init
   * @param {Object} nfieldParams - Parameters to configure Nfield user to use with API, must contain server url and user credentials
   * @param {String} nfieldParams.credentials.Domain
   * @param {String} nfieldParams.credentials.Username
   * @param {String} nfieldParams.credentials.Password
   * @param {String} nfieldParams.server
   * @param {Object=} requestParams - Parameters to configure request module, that is used to connect to API
   * @returns {NfieldInstance} Returns Nfield instance
   */
  function init (nfieldParams, requestParams) {
    if (!nfieldInstance) {
      nfieldInstance = new NfieldInstance(nfieldParams, requestParams);
    } else {
      nfieldInstance.configure(nfieldParams, nfieldParams);
    }
    return nfieldInstance;
  }

  return {
    init : init
  };

})();<commit_msg>Add TerminateRunningInterviews param to stopSurvey()<commit_after>module.exports = (function Nfield () {

  var Promise = require('bluebird');

  var nfieldInstance;

  /**
   * Creates Nfield instance
   * @constructor NfieldInstance
   * @param {Object} nfieldParams - Parameters to configure Nfield user to use with API, must contain server url and user credentials
   * @param {Object=} requestParams - Parameters to configure request module, that is used to connect to API
   */
  function NfieldInstance (nfieldParams, requestParams) {

    var _this = this;
    var request;
    var token = { 'AuthenticationToken' : '', 'Timestamp' : 0 };
    var connectInterval;
    var nfieldOptions = nfieldParams || {};
    var requestOptions = requestParams || {};

    /**
     * Reconfigures Nfield instance
     * @memberof NfieldInstance
     * @method configure
     * @param {Object=} nP - Parameters to configure Nfield user to use with API, must contain server url and user credentials
     * @param {Object=} rP - Parameters to configure request module, that is used to connect to API
     */
    _this.configure = function configure (nP, rP) {
      nfieldOptions = nP || nfieldOptions;
      requestOptions = rP || requestOptions;
      requestOptions.baseUrl = nfieldOptions.server || 'https://api.nfieldmr.com/';
      request = Promise.promisify(require('request').defaults(requestOptions));
    };

    /**
     * Response callback
     * @callback responseCallback
     * @param {Array} err
     * @param {Array} resp
     */

    // SignIn

    /**
     *
Sign in to the Nfield API

     *
 Nfield API reference:
     *

[POST v1/SignIn]{@link https://api.nfieldmr.com/help/api/post-v1-signin}

     *

     * @memberof NfieldInstance
     * @method signIn
     * @param {Object} credentials - Sign in credentials
     * @param {String} credentials.Domain
     * @param {String} credentials.Username
     * @param {String} credentials.Password
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.signIn = function signIn (credentials, callback) {
      return request({
        method : 'POST',
        uri : 'v1/SignIn',
        json : credentials
      }).nodeify(callback);
    };

    // SurveyFieldwork

    /**
     *
Request survey fieldwork status

     *
 Nfield API reference:
     *

[GET v1/Surveys/{surveyId}/Fieldwork/Status]{@link https://api.nfieldmr.com/help/api/get-v1-surveys-surveyid-fieldwork-status}

     *

     * @memberof NfieldInstance
     * @method getSurveyStatus
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.getSurveyStatus = function getSurveyStatus (surveyId, callback) {
      return request({
        method : 'GET',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Status').replace('{surveyId}', surveyId),
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    };

    /**
     *
Start survey

     *
 Nfield API reference:
     *

[PUT v1/Surveys/{surveyId}/Fieldwork/Start]{@link https://api.nfieldmr.com/help/api/put-v1-surveys-surveyid-fieldwork-start}

     *

     * @memberof NfieldInstance
     * @method startSurvey
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.startSurvey = function startSurvey (surveyId, callback) {
      return request({
        method : 'PUT',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Start').replace('{surveyId}', surveyId),
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    };

    /**
     *
Stop (pause) survey

     *
 Nfield API reference:
     *

[PUT v1/Surveys/{surveyId}/Fieldwork/Stop]{@link https://api.nfieldmr.com/help/api/put-v1-surveys-surveyid-fieldwork-stop}

     *

     * @memberof NfieldInstance
     * @method stopSurvey
     * @param {String} surveyId - Survey ID
     * @param {Boolean=} [terminate=false] - Terminate running interviews
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.stopSurvey = function stopSurvey (surveyId, terminate, callback) {
      return request({
        method : 'PUT',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Stop').replace('{surveyId}', surveyId),
        json : {
          'TerminateRunningInterviews' : terminate || false
        },
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    };

    // DefaultTexts

    /**
     *
Get specific/all default text(s) for the domain

     *
Nfield API reference:
     *

[GET v1/DefaultTexts]{@link https://api.nfieldmr.com/help/api/get-v1-defaulttexts}

     *
[GET v1/DefaultTexts/{translationKey}]{@link https://api.nfieldmr.com/help/api/get-v1-defaulttexts-translationkey}

     *

     * @memberof NfieldInstance
     * @method getDefaultText
     * @param {String=} translationKey - Translation key
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.getDefaultText = function getDefaultText (translationKey, callback) {
      var reqURI = '';

      if (translationKey) {
        reqURI = ('v1/DefaultTexts/{translationKey}').replace('{translationKey}', translationKey);
      } else {
        reqURI = 'v1/DefaultTexts';
      }

      return request({
        method : 'GET',
        uri : reqURI,
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    };

    /**
     * Token update error callback
     * @callback persistantErrorCallback
     * @param {Array} error - Request response array
     */

    /**
     *
Connects Nfield instance to Nfield API with parameters provided during initialization

     *
Nfield API uses tokens that lasts for 15 minutes for authorisation, so as an options this method allows you to initiate an autoupdate for the token in Nfield instance, that fires every 12 minutes

     * @memberof NfieldInstance
     * @method connect
     * @param {Boolean=} persistant - Initiate an autoupdate for token (true/false)
     * @param {persistantErrorCallback=} persistantErrorCallback - Callback, that fires if something goes wrong during token update
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    _this.connect = function connect (persistant, persistantErrorCallback, callback) {
      if (persistant === true && !connectInterval) {
        connectInterval = setInterval(function () {
          _this.signIn(nfieldOptions.credentials).then(function(data) {
            if (data[0].statusCode == 200) {
              token.AuthenticationToken = data[0].body.AuthenticationToken;
              token.Timestamp = Date.now();
            } else {
              if (typeof persistantErrorCallback == 'function') persistantErrorCallback(data);
            }
          });
        }, 1000 * 60 * 12);
      } else if (persistant === true && connectInterval) {
        console.log('Persistant connection already running');
      }

      return new Promise(function (resolve, reject) {
        if (token.AuthenticationToken !== '' && (Date.now() - token.Timestamp) < 1000 * 60 * 12) {
          resolve(token);
        } else {
          _this.signIn(nfieldOptions.credentials).then(function (data) {
            if (data[0].statusCode == 200) {
              token.AuthenticationToken = data[0].body.AuthenticationToken;
              token.Timestamp = Date.now();
              resolve(token);
            } else {
              reject(data);
            }
          }).catch(function (error) {
            reject(error);
          });
        }
      }).nodeify(callback);
    };

    /**
     * Clears persistant token update interval
     * @memberof NfieldInstance
     * @method stopPersistant
     */
    _this.stopPersistant = function stopPersistant () {
      clearInterval(connectInterval);
      connectInterval = null;
    };

    _this.configure(nfieldOptions, requestOptions);
  }

  /**
   * Creates new [Nfield instance]{@link NfieldInstance} or returns existing one
   * @memberof Nfield
   * @method init
   * @param {Object} nfieldParams - Parameters to configure Nfield user to use with API, must contain server url and user credentials
   * @param {String} nfieldParams.credentials.Domain
   * @param {String} nfieldParams.credentials.Username
   * @param {String} nfieldParams.credentials.Password
   * @param {String} nfieldParams.server
   * @param {Object=} requestParams - Parameters to configure request module, that is used to connect to API
   * @returns {NfieldInstance} Returns Nfield instance
   */
  function init (nfieldParams, requestParams) {
    if (!nfieldInstance) {
      nfieldInstance = new NfieldInstance(nfieldParams, requestParams);
    } else {
      nfieldInstance.configure(nfieldParams, nfieldParams);
    }
    return nfieldInstance;
  }

  return {
    init : init
  };

})();<|endoftext|>


<commit_before>var idents = require('javascript-idents');
var infer = require('tern/lib/infer');
var tern = require('tern');
var symbol_id = require('./symbol_id');

exports.refs = function(origins, options) {
  if (typeof origins == 'string') origins = [origins];
  var state = new State(origins, options || {});

  state.cx.parent.files.forEach(function(file) {
    if (!state.isTarget(file.name)) return;
    idents.inspect(file.ast, function(ident) {
      resolve(file, ident, state);
    });
  });

  return state.output;
};

function State(origins, options) {
  this.origins = origins;
  this.cx = infer.cx();
  this.output = [];
}

State.prototype.isTarget = function(origin) {
  return this.origins.indexOf(origin) > -1;
};

function resolve(file, ident, state) {
  var out = {file: file.name, span: ident.start + '-' + ident.end};

  out.target = getRefTarget(file, ident);
  if (out.target) {
    if (state.isTarget(out.target.origin)) delete out.target.origin;
  }

  if (out.target) state.output.push(out);
}

function getRefTarget(file, ident) {
  if (ident._path) return getConcretePathTypeID(ident._path);

  var expr;
  try {
    expr = tern.findQueryExpr(file, ident);
  } catch (e) {
    console.error('No expression at ' + file.name + ':' + ident.start + '-' + ident.end);
    return null;
  }

  var av = infer.expressionType(expr);
  if (av.originNode && av.originNode._path) return getConcretePathTypeID(av.originNode._path);

  var type = av.getType(false);
  if (!type) return null;
  if (type.originNode && type.originNode._path) return getConcretePathTypeID(type.originNode._path);

  if (type instanceof infer.Prim || type instanceof infer.Arr) return;

  return getTypeID(type);
}

function getConcretePathTypeID(path) {
  var target = symbol_id.parse(path);
  target.abstract = false;
  return target;
}

function getTypeID(type) {
  // Hack for CommonJS "module"
  if (type.name == 'Module' && type.proto.origin == 'node' && type.proto.name == 'Module.prototype') {
    type.origin = 'node';
    type._isCommonJSModule = true;
  }

  var target = {origin: type.origin};
  switch (type.origin) {
  case 'ecma5':
  case 'browser':
    target.abstract = true;
    target.path = type.path;
    target.namespace = 'global';
    break;
  case 'node':
    target.abstract = true;

    // Hack for CommonJS "require"
    if (!type.path && type.name == 'require') {
      target.path = 'module.require';
      target.namespace = 'global';
      break;
    }

    // Hack for CommonJS "module"
    if (type._isCommonJSModule) {
      target.path = 'module';
      target.namespace = 'global';
      break;
    }

    if (!type.path) type.path = type.name;
    var parts = type.path.split('.');
    target.namespace = 'commonjs';
    target.module = parts[0];
    target.path = parts.slice(1).join('.');
    break;
  case 'requirejs':
    target.abstract = true;
    target.path = type.path;
    target.namespace = 'global';
    target.module = '';
    break;
  default:
    target.abstract = false;

    // Hack for CommonJS module obtained via "require"
    if (type.metaData && type.metaData.nodejs && type.metaData.nodejs.moduleExports) {
      type.path = '!commonjs.' + type.origin.replace(/\./g, '`');
    }

    // Hack for RequireJS module definition
    if (type.metaData && type.metaData.amd && type.metaData.amd.module) {
      type.path = '!requirejs.' + type.origin.replace(/\./g, '`');
    }

    if (!type.path) {
      // throw new Error('no type.path: ' + require('util').inspect(type));
      return;
    }
    return getConcretePathTypeID(type.path);
  }

  return target;
}
<commit_msg>Comment about types with no path<commit_after>var idents = require('javascript-idents');
var infer = require('tern/lib/infer');
var tern = require('tern');
var symbol_id = require('./symbol_id');

exports.refs = function(origins, options) {
  if (typeof origins == 'string') origins = [origins];
  var state = new State(origins, options || {});

  state.cx.parent.files.forEach(function(file) {
    if (!state.isTarget(file.name)) return;
    idents.inspect(file.ast, function(ident) {
      resolve(file, ident, state);
    });
  });

  return state.output;
};

function State(origins, options) {
  this.origins = origins;
  this.cx = infer.cx();
  this.output = [];
}

State.prototype.isTarget = function(origin) {
  return this.origins.indexOf(origin) > -1;
};

function resolve(file, ident, state) {
  var out = {file: file.name, span: ident.start + '-' + ident.end};

  out.target = getRefTarget(file, ident);
  if (out.target) {
    if (state.isTarget(out.target.origin)) delete out.target.origin;
  }

  if (out.target) state.output.push(out);
}

function getRefTarget(file, ident) {
  if (ident._path) return getConcretePathTypeID(ident._path);

  var expr;
  try {
    expr = tern.findQueryExpr(file, ident);
  } catch (e) {
    console.error('No expression at ' + file.name + ':' + ident.start + '-' + ident.end);
    return null;
  }

  var av = infer.expressionType(expr);
  if (av.originNode && av.originNode._path) return getConcretePathTypeID(av.originNode._path);

  var type = av.getType(false);
  if (!type) return null;
  if (type.originNode && type.originNode._path) return getConcretePathTypeID(type.originNode._path);

  if (type instanceof infer.Prim || type instanceof infer.Arr) return;

  return getTypeID(type);
}

function getConcretePathTypeID(path) {
  var target = symbol_id.parse(path);
  target.abstract = false;
  return target;
}

function getTypeID(type) {
  // Hack for CommonJS "module"
  if (type.name == 'Module' && type.proto.origin == 'node' && type.proto.name == 'Module.prototype') {
    type.origin = 'node';
    type._isCommonJSModule = true;
  }

  var target = {origin: type.origin};
  switch (type.origin) {
  case 'ecma5':
  case 'browser':
    target.abstract = true;
    target.path = type.path;
    target.namespace = 'global';
    break;
  case 'node':
    target.abstract = true;

    // Hack for CommonJS "require"
    if (!type.path && type.name == 'require') {
      target.path = 'module.require';
      target.namespace = 'global';
      break;
    }

    // Hack for CommonJS "module"
    if (type._isCommonJSModule) {
      target.path = 'module';
      target.namespace = 'global';
      break;
    }

    if (!type.path) type.path = type.name;
    var parts = type.path.split('.');
    target.namespace = 'commonjs';
    target.module = parts[0];
    target.path = parts.slice(1).join('.');
    break;
  case 'requirejs':
    target.abstract = true;
    target.path = type.path;
    target.namespace = 'global';
    target.module = '';
    break;
  default:
    target.abstract = false;

    // Hack for CommonJS module obtained via "require"
    if (type.metaData && type.metaData.nodejs && type.metaData.nodejs.moduleExports) {
      type.path = '!commonjs.' + type.origin.replace(/\./g, '`');
    }

    // Hack for RequireJS module definition
    if (type.metaData && type.metaData.amd && type.metaData.amd.module) {
      type.path = '!requirejs.' + type.origin.replace(/\./g, '`');
    }

    if (!type.path) {
      // Type is probably a local variable or some other type that's unreachable
      // from the topScope or roots.
      // throw new Error('no type.path: ' + require('util').inspect(type));
      return;
    }
    return getConcretePathTypeID(type.path);
  }

  return target;
}
<|endoftext|>


<commit_before>const fs = require('fs');
const stream = require('stream');
const chalk = require('chalk');
const moment = require('moment');
const got = require('got');
const unzipper = require('unzipper');

const db = require('./db.js');
const debug = require('./utils/debug.js');

const fsp = fs.promises;

// Download data into temporary folder.
async function download() {
	debug.time('data-download', 'Downloading data');

	// Download and extract MNT data into temporary folder.
	await new Promise((resolve) => {
		got.stream('http://peatus.ee/gtfs/gtfs.zip')
			.pipe(unzipper.Parse())
			.pipe(stream.Transform({
				objectMode: true,
				transform(entry, e, cb) {
					entry.pipe(fs.createWriteStream(`tmp/${entry.path.split('.')[0]}.csv`)).on('finish', cb);
				}
			})).on('finish', resolve);
	});

	// Download and write Elron stop data into temporary folder.
	let data = 'name,lat,lng\n';
	for (const stop of JSON.parse((await got('https://elron.ee/api/v1/stops')).body).data) data += `${stop.peatus},${stop.latitude},${stop.longitude}\n`;
	await fsp.writeFile('tmp/elron.csv', data);

	debug.timeEnd('data-download', 'Downloaded data');
}

// Execute scripts in folder.
async function execute(path, msgIncomplete, msgComplete) {
	for (const file of await fsp.readdir(path)) {
		const name = file.split('.')[0];

		debug.time('data-prepare-' + name, msgIncomplete + ' ' + chalk.white(name.replace(/.*-/, '')));

		switch (file.split('.')[1]) {
			case 'sql':
				await db.query((await fsp.readFile(`${path}/${file}`)).toString());
				break;
			case 'js':
				await (require(`./${path}/${file}`))();
				break;
		}

		debug.timeEnd('data-prepare-' + name, msgComplete + ' ' + chalk.white(name.replace(/.*-/, '')));
	}
}

// Update data.
async function update() {
	try {
		let nextUpdate;

		try {
			await fsp.stat('tmp/update');
			nextUpdate = (await fsp.readFile('tmp/update')).toString();
		} catch {}

		// Update stale data.
		if (!nextUpdate || new Date(nextUpdate) <= new Date()) {
			debug.info('Starting data update');
			debug.time('data-update');

			await download();
			await execute('data/importers', 'Importing', 'Imported');
			await execute('data/processors', 'Processing', 'Generated');

			await fsp.writeFile('tmp/update', moment().add(1, 'day').hour(6).minute(0).second(0).toDate());
			debug.timeEnd('data-update', 'Data update completed');
		}
	} catch (ex) {
		debug.error('Failed to update data', ex);
	}
}

module.exports = {
	update
};
<commit_msg>Fix processor debug message (api)<commit_after>const fs = require('fs');
const stream = require('stream');
const chalk = require('chalk');
const moment = require('moment');
const got = require('got');
const unzipper = require('unzipper');

const db = require('./db.js');
const debug = require('./utils/debug.js');

const fsp = fs.promises;

// Download data into temporary folder.
async function download() {
	debug.time('data-download', 'Downloading data');

	// Download and extract MNT data into temporary folder.
	await new Promise((resolve) => {
		got.stream('http://peatus.ee/gtfs/gtfs.zip')
			.pipe(unzipper.Parse())
			.pipe(stream.Transform({
				objectMode: true,
				transform(entry, e, cb) {
					entry.pipe(fs.createWriteStream(`tmp/${entry.path.split('.')[0]}.csv`)).on('finish', cb);
				}
			})).on('finish', resolve);
	});

	// Download and write Elron stop data into temporary folder.
	let data = 'name,lat,lng\n';
	for (const stop of JSON.parse((await got('https://elron.ee/api/v1/stops')).body).data) data += `${stop.peatus},${stop.latitude},${stop.longitude}\n`;
	await fsp.writeFile('tmp/elron.csv', data);

	debug.timeEnd('data-download', 'Downloaded data');
}

// Execute scripts in folder.
async function execute(path, msgIncomplete, msgComplete) {
	for (const file of await fsp.readdir(path)) {
		const name = file.split('.')[0];

		debug.time('data-prepare-' + name, msgIncomplete + ' ' + chalk.white(name.replace(/.*-/, '')));

		switch (file.split('.')[1]) {
			case 'sql':
				await db.query((await fsp.readFile(`${path}/${file}`)).toString());
				break;
			case 'js':
				await (require(`./${path}/${file}`))();
				break;
		}

		debug.timeEnd('data-prepare-' + name, msgComplete + ' ' + chalk.white(name.replace(/.*-/, '')));
	}
}

// Update data.
async function update() {
	try {
		let nextUpdate;

		try {
			await fsp.stat('tmp/update');
			nextUpdate = (await fsp.readFile('tmp/update')).toString();
		} catch {}

		// Update stale data.
		if (!nextUpdate || new Date(nextUpdate) <= new Date()) {
			debug.info('Starting data update');
			debug.time('data-update');

			await download();
			await execute('data/importers', 'Importing', 'Imported');
			await execute('data/processors', 'Processing', 'Processed');

			await fsp.writeFile('tmp/update', moment().add(1, 'day').hour(6).minute(0).second(0).toDate());
			debug.timeEnd('data-update', 'Data update completed');
		}
	} catch (ex) {
		debug.error('Failed to update data', ex);
	}
}

module.exports = {
	update
};
<|endoftext|>


<commit_before>/*
 * This script tells us which Stripe subscriptions are inactive
 */

const app = require('../server/index');
import models from '../server/models';
import { retrieveSubscription } from '../server/gateways/stripe';
//const stripeGateway = require('../server/gateways').stripe;

const done = (err) => {
  if (err) console.log('err', err);
  console.log('done!');
  process.exit();
}

function run() {
  let inactiveSubscriptionCount = 0;
  let sumAmount = 0;
  return models.Order.findAll({
    where: {
      SubscriptionId: {
        $ne: null
      },
      PaymentMethodId: {
        $ne: null
      }
    },
    include: [
      { model: models.Subscription,
        where: {
          isActive: true,
          stripeSubscriptionId: {
            $ne: null
          }
        }
      },
      { model: models.Collective, as: 'collective'},
      { model: models.PaymentMethod }
    ]
  })
  .tap(orders => console.log("Total Subscriptions found: ", orders.length))
  .each(order => {
    console.log(`Processing SubscriptionId: ${order.SubscriptionId}`);
    return order.Collective.getStripeAccount()
      .then(stripeAccount => retrieveSubscription(stripeAccount, order.PaymentMethod.customerId, order.Subscription.stripeSubscriptionId))
      .then(stripeSubscription => {
        if (!stripeSubscription) {
          console.log('Stripe Subscription not found');
        } else {
          console.log('Subscription found!');
        }
      })
      .catch(err => {
        if (err.type === 'StripeInvalidRequestError') {
          console.log('Stripe Subscription not found');
          inactiveSubscriptionCount +=1;
          if (order.currency === 'USD' || order.currency === 'EUR') {
            sumAmount += order.amount;
          }
          const subscription = order.Subscription;
          subscription.isActive = false;
          subscription.deactivatedAt = new Date();
          return subscription.save();
        } else {
          console.log(err);
          Promise.resolve();
        }
      })
  })
  .then(() => console.log("Subscriptions marked inactive: ", inactiveSubscriptionCount))
  .then(() => console.log("Total amount reduced per month (in ~USD): ", sumAmount))
  .then(() => done())
  .catch(done)
}

run();<commit_msg>update check_subscriptions_script (#999)<commit_after>/*
 * This script tells us which Stripe subscriptions are inactive
 */

import models from '../server/models';
import { retrieveSubscription } from '../server/gateways/stripe';
//const stripeGateway = require('../server/gateways').stripe;

const done = (err) => {
  if (err) console.log('err', err);
  console.log('done!');
  process.exit();
}

function run() {
  let inactiveSubscriptionCount = 0;
  let sumAmount = 0;
  return models.Order.findAll({
    where: {
      SubscriptionId: {
        $ne: null
      },
      PaymentMethodId: {
        $ne: null
      }
    },
    include: [
      { model: models.Subscription,
        where: {
          isActive: true,
          stripeSubscriptionId: {
            $ne: null
          }
        }
      },
      { model: models.Collective, as: 'collective'},
      { model: models.PaymentMethod, as: 'paymentMethod' }
    ]
  })
  .tap(orders => console.log("Total Subscriptions found: ", orders.length))
  .each(order => {
    console.log(`Processing SubscriptionId: ${order.SubscriptionId}`);
    return order.collective.getHostStripeAccount()
      .then(stripeAccount => retrieveSubscription(stripeAccount, order.paymentMethod.customerId, order.Subscription.stripeSubscriptionId))
      .then(stripeSubscription => {
        if (!stripeSubscription) {
          console.log('Stripe Subscription not found');
        } else {
          console.log('Subscription found!');
        }
      })
      .catch(err => {
        if (err.type === 'StripeInvalidRequestError') {
          console.log('Stripe Subscription not found');
          inactiveSubscriptionCount +=1;
          if (order.currency === 'USD' || order.currency === 'EUR') {
            sumAmount += order.amount;
          }
          const subscription = order.Subscription;
          subscription.isActive = false;
          subscription.deactivatedAt = new Date();
          return subscription.save();
        } else {
          console.log(err);
          Promise.resolve();
        }
      })
  })
  .then(() => console.log("Subscriptions marked inactive: ", inactiveSubscriptionCount))
  .then(() => console.log("Total amount reduced per month (in ~USD): ", sumAmount))
  .then(() => done())
  .catch(done)
}

run();<|endoftext|>


<commit_before>var Idea, mongoose, newIdea;
var moment = require('moment');
//var _ = require('lodash');
mongoose = require("mongoose");

//var geetest = require('geetest')('6421f2c80c3a32f701f87ac7403b8b72');

var Idea = mongoose.model("Idea",{
  user_id:String,

  time:{ type: Date, default: Date.now },

  description: String,

  ideaboardName: String,

  title: String,
  email: String,
  //tags: [String],
  ip: String,
  //ip_2: String,
  comments: [
  {
    user_id: {type: String, ref: 'User'},
    content: String,
    date: { type: Date, default: Date.now }
  }]

});

var newIdea = function(req, res, next){
  //getClientIp(req);
	console.log("hi newIdea~");
  //console.log((req.headers['x-forwarded-for'] || '').split(',')[0]);
  //console.log(req.connection.remoteAddress);
  //console.log(req.headers);

  var newIdea = new Idea({
    user_id: req.param('user_id'),
    email: req.param("email"),
    title: req.param('title'),
		description: req.param('description'),
    ideaboardName: req.param('ideaboardName'),
		tags: req.param('tags'),
    ip: (req.headers['x-forwarded-for'] || '').split(',')[0] || req._remoteAddress
    //ip_2: req.headers['x-real-ip']
	});
  //console.log(req);
  //console.log(newIdea.ip);
  Idea.find({ip: newIdea.ip})
  .sort('-time')
  .exec(function(err, ideas){
    if(err){
      res.json(500,err);
    }else if(ideas && ideas.length!=0){
      var timeLastIdea = moment(ideas[0].time);
      var timeNow = moment();
      var timeDiff = timeNow.diff(timeLastIdea,'minutes');
      console.log(timeDiff);
      if(timeDiff > 1){
        newIdea.save(function(err){
          if (err){
            console.log(err);
            res.json(500,err);
          }else{
            res.json(200,{success:newIdea.description});
          }
        });
      }else{
        console.log("You publish idea too quickly");
        res.json(401,{fail:"You publish idea too quickly"});
      }  //console.log(ideas);
    }else{
      newIdea.save(function(err){
          if (err){
            console.log(err);
            res.json(500,err);
          }else{
            res.json(200,{success:newIdea.description});
          }
      });
    }
  });

  //console.log(req._startTime);
  //Idea.find

};

var listIdea = function(req, res, next){
    Idea.find({ ideaboardName: req.param('ideaboardName') })
      .sort('-time')
      .exec(function(err, ideas){
        //console.log(ideas);
        if(!err){
            return res.send(ideas);
        }
        else{
            return console.log(err);
        }
    });
};

var listHackathonIdea = function (req, res, next){
      Idea.find({ })
      .sort('-time')
      .exec(function(err, ideas){
        //console.log(ideas);
        if(!err){
            return res.send(ideas);
        }
        else{
            return console.log(err);
        }
    });

}

var getClientAddress = function (req) {
    console.log((req.headers['x-forwarded-for'] || '').split(',')[0]
        || req.connection.remoteAddress);
    return (req.headers['x-forwarded-for'] || '').split(',')[0];
        //|| req.connection.remoteAddress;
};

exports.getIp = getClientAddress;
exports.newIdea = newIdea;
exports.listIdea = listIdea;
<commit_msg>bug fix<commit_after>var Idea, mongoose, newIdea;
var moment = require('moment');
//var _ = require('lodash');
mongoose = require("mongoose");

//var geetest = require('geetest')('6421f2c80c3a32f701f87ac7403b8b72');

var Idea = mongoose.model("Idea",{
  user_id:String,

  time:{ type: Date, default: Date.now },

  description: String,

  ideaboardName: String,

  title: String,
  email: String,
  //tags: [String],
  ip: String,
  //ip_2: String,
  comments: [
  {
    user_id: {type: String, ref: 'User'},
    content: String,
    date: { type: Date, default: Date.now }
  }]

});

var newIdea = function(req, res, next){
  //getClientIp(req);
	console.log("hi newIdea~");
  //console.log((req.headers['x-forwarded-for'] || '').split(',')[0]);
  //console.log(req.connection.remoteAddress);
  //console.log(req.headers);

  var newIdea = new Idea({
    user_id: req.param('user_id'),
    email: req.param("email"),
    title: req.param('title'),
		description: req.param('description'),
    ideaboardName: req.param('ideaboardName'),
		tags: req.param('tags'),
    ip: (req.headers['x-forwarded-for'] || '').split(',')[0] || req._remoteAddress
    //ip_2: req.headers['x-real-ip']
	});
  //console.log(req);
  //console.log(newIdea.ip);
  Idea.find({ip: newIdea.ip})
  .sort('-time')
  .exec(function(err, ideas){
    if(err){
      res.json(500,err);
    }else if(ideas && ideas.length!=0){
      var timeLastIdea = moment(ideas[0].time);
      var timeNow = moment();
      var timeDiff = timeNow.diff(timeLastIdea,'minutes');
      console.log(timeDiff);
      if(timeDiff > 1){
        newIdea.save(function(err){
          if (err){
            console.log(err);
            res.json(500,err);
          }else{
            res.json(200,{success:newIdea.description});
          }
        });
      }else{
        console.log("You publish idea too quickly");
        res.json(401,{fail:"You publish idea too quickly"});
      }  //console.log(ideas);
    }else{
      newIdea.save(function(err){
          if (err){
            console.log(err);
            res.json(500,err);
          }else{
            res.json(200,{success:newIdea.description});
          }
      });
    }
  });

  //console.log(req._startTime);
  //Idea.find

};

var listIdea = function(req, res, next){
    Idea.find({ ideaboardName: req.param('ideaboardName') })
      .sort('-time')
      .exec(function(err, ideas){
        //console.log(ideas);
        if(!err){
            return res.send(ideas);
        }
        else{
            return console.log(err);
        }
    });
};

var listHackathonIdea = function (req, res, next){
      Idea.find({ })
      .sort('-time')
      .exec(function(err, ideas){
        //console.log(ideas);
        if(!err){
            return res.send(ideas);
        }
        else{
            return console.log(err);
        }
    });

}

var getClientAddress = function (req) {
    console.log((req.headers['x-forwarded-for'] || '').split(',')[0]
        || req.connection.remoteAddress);
    return (req.headers['x-forwarded-for'] || '').split(',')[0];
        //|| req.connection.remoteAddress;
};

exports.getIp = getClientAddress;
exports.newIdea = newIdea;
exports.listIdea = listIdea;
exports.listHackathonIdea = listHackathonIdea;<|endoftext|>


<commit_before>// these are the event handlers for the ChildNav accordion
// What does it do?
// 1) responds to media query changes, page resizes to compact the accordion
// 2) adds a click handler to the menu button that appears in XS viewports.

var childNavElement  = document.getElementById( 'guides-childnav-accordion' );
var childNavClicked = false;
var childNavButton = document.getElementById('childnav__button');
var childNavOpen = false;

if ( childNavElement ) {
	var anchorLinkToggler = childNavElement.getElementsByClassName('au-accordion__title');
}

// decide whether to open or close the accordion depending on screen size
function CheckChildNav() {
	if ( childNavElement ) {

		// check if the button is hidden (display:none) to decide whether to be
		// open or closed
		var guidesButtonDisplay = window.getComputedStyle( childnav__button, '' ).getPropertyValue( 'display' );
		if( guidesButtonDisplay === 'none' ){
			AU.accordion.Open (anchorLinkToggler);
		// check if the accordion has been opened by the user, if so, don't auto resize
		} else if (!childNavClicked) {
			AU.accordion.Close( anchorLinkToggler );
		}
	}
}

// toggle the accordion as a user action
function UserToggleChildNav() {
	if ( childNavElement ) {
		AU.accordion.Toggle( anchorLinkToggler );
		childNavClicked = true;

		if (!childNavOpen) {
			childNavOpen = true;
			childNavButton.classList.remove("au-accordion--closed");
		} else {
			childNavOpen = false
			childNavButton.classList.add("au-accordion--closed");
		}
	}
}

// user click handler
var childnavbutton = document.getElementById('childnav__button');
if (childnavbutton) {
	childnavbutton.addEventListener("click",UserToggleChildNav);
}
<commit_msg>remove unused code on ChildNav<commit_after>// these are the event handlers for the ChildNav accordion
// What does it do?
// 1) responds to media query changes, page resizes to compact the accordion
// 2) adds a click handler to the menu button that appears in XS viewports.

var childNavElement  = document.getElementById( 'guides-childnav-accordion' );
var childNavClicked = false;
var childNavButton = document.getElementById('childnav__button');
var childNavOpen = false;

if ( childNavElement ) {
	var anchorLinkToggler = childNavElement.getElementsByClassName('au-accordion__title');
}

// toggle the accordion as a user action
function UserToggleChildNav() {
	if ( childNavElement ) {
		AU.accordion.Toggle( anchorLinkToggler );
		childNavClicked = true;

		if (!childNavOpen) {
			childNavOpen = true;
			childNavButton.classList.remove("au-accordion--closed");
		} else {
			childNavOpen = false
			childNavButton.classList.add("au-accordion--closed");
		}
	}
}

// user click handler
var childnavbutton = document.getElementById('childnav__button');
if (childnavbutton) {
	childnavbutton.addEventListener("click",UserToggleChildNav);
}
<|endoftext|>


<commit_before>const promise = require("bluebird");
const options = {
  // Initialization Options
  promiseLib: promise, // use bluebird as promise library
  capSQL: true, // when building SQL queries dynamically, capitalize SQL keywords
};
const pgp = require("pg-promise")(options);
const connectionString = process.env.DATABASE_URL;
const parse = require("pg-connection-string").parse;
const oldS3Url = 'uploads.participedia.xyz';
const newS3Url = 'participedia.stage';

let config;
try {
  config = parse(connectionString);
  if (process.env.NODE_ENV === "test" || config.host === "localhost") {
    config.ssl = false;
  } else {
    config.ssl = true;
  }
} catch (e) {
  console.error("# Error parsing DATABASE_URL environment variable");
}

let db = pgp(config);
getPhotos('cases');
getPhotos('methods');
getPhotos('organizations');

function getPhotos(table) {
  db.any(`SELECT id, photos FROM ${table}`)
  .then(function(data) {
    data.forEach(data => {
      var photo = data.photos;
      if (photo.search(oldS3Url) >= 0) {
        var newPhoto = photo.replace(oldS3Url, newS3Url);
        updatePhoto(data.id, newPhoto, table);
      } else {
        console.log(`Row ${data.id} doesn't have the URL we are looking for.`);
      }
    });
  })
  .catch(function(error) {
    console.log(error);
  });
}

function updatePhoto(id, value, table) {
  const dataSingle = {photos: value};
  const condition = pgp.as.format(` WHERE id = ${id}`, dataSingle);
  const update = pgp.helpers.update(dataSingle, null, table) + condition;

  db.none(update)
  .then(function(data) {
    console.log(`Table: ${table}; ID: ${id} updated`);
  })
  .catch(function(error) {
    console.log(error);
  });
}<commit_msg>Use bucket in the env var<commit_after>const promise = require("bluebird");
const options = {
  // Initialization Options
  promiseLib: promise, // use bluebird as promise library
  capSQL: true, // when building SQL queries dynamically, capitalize SQL keywords
};
const pgp = require("pg-promise")(options);
const connectionString = process.env.DATABASE_URL;
const parse = require("pg-connection-string").parse;
const oldS3Url = 'uploads.participedia.xyz';
const newS3Url = process.env.AWS_S3_BUCKET;

let config;
try {
  config = parse(connectionString);
  if (process.env.NODE_ENV === "test" || config.host === "localhost") {
    config.ssl = false;
  } else {
    config.ssl = true;
  }
} catch (e) {
  console.error("# Error parsing DATABASE_URL environment variable");
}

let db = pgp(config);
getPhotos('cases');
getPhotos('methods');
getPhotos('organizations');

function getPhotos(table) {
  db.any(`SELECT id, photos FROM ${table}`)
  .then(function(data) {
    data.forEach(data => {
      var photo = data.photos;
      if (photo.search(oldS3Url) >= 0) {
        var newPhoto = photo.replace(oldS3Url, newS3Url);
        updatePhoto(data.id, newPhoto, table);
      } else {
        console.log(`Row ${data.id} doesn't have the URL we are looking for.`);
      }
    });
  })
  .catch(function(error) {
    console.log(error);
  });
}

function updatePhoto(id, value, table) {
  const dataSingle = {photos: value};
  const condition = pgp.as.format(` WHERE id = ${id}`, dataSingle);
  const update = pgp.helpers.update(dataSingle, null, table) + condition;

  db.none(update)
  .then(function(data) {
    console.log(`Table: ${table}; ID: ${id} updated`);
  })
  .catch(function(error) {
    console.log(error);
  });
}<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var State = require('./app/models/state');

mongoose.connect('mongodb://localhost/hackathon-war-dev');

var states = [
  ['Acre', 'AC', '-9.1285244', '-70.3077931'],
  ['Alagoas', 'AL', '-9.658443', '-36.6897704'],
  ['Amapá', 'AP', '1.603494', '-52.3764644'],
  ['Amazonas', 'AM', '-3.7857105', '-64.9495526'],
  ['Bahia', 'BA', '-13.4343696', '-41.982751'],
  ['Ceará', 'CE', '-5.3214533', '-39.3382675'],
  ['Espírito Santo', 'ES', '-19.5968657', '-40.7717683'],
  ['Goiás', 'GO', '-15.9471833', '-49.5790826'],
  ['Maranhão', 'MA', '-5.6558833', '-45.2755116'],
  ['Mato Grosso do Sul', 'MS', '-20.611376', '-54.5449798'],
  ['Mato Grosso', 'MT', '-12.6955444', '-55.9289973'],
  ['Minas Gerais', 'MG', '-18.5779703', '-45.4514505'],
  ['Paraná', 'PR', '-24.6169813', '-51.3214141'],
  ['Paraíba', 'PB', '-7.1644358', '-36.7793751'],
  ['Pará', 'PA', '-3.6250659', '-52.4812983'],
  ['Pernambuco', 'PE', '-8.3779283', '-38.0825865'],
  ['Piauí', 'PI', '-6.8380377', '-43.1823977'],
  ['Rio Grande do Norte', 'RN', '-5.9072667', '-36.7754294'],
  ['Rio Grande do Sul', 'RS', '-30.4163413', '-53.6677564'],
  ['Rio de Janeiro', 'RJ', '-22.066452', '-42.9232368'],
  ['Rondônia', 'RO', '-10.8315007', '-63.2922964'],
  ['Roraima', 'RR', '1.8456015', '-61.8560613'],
  ['Santa Catarina', 'SC', '-27.6536999', '-51.1508311'],
  ['Sergipe', 'SE', '-10.5417791', '-37.3227577'],
  ['São Paulo', 'SP', '-22.5455869', '-48.6355226'],
  ['Tocantins', 'TO', '-9.3180492', '-48.219068']
];

var counter = 0;
states.forEach(function (state) {
  new State({
    name: state[0],
    acronym: state[1],
    lat: state[2],
    lng: state[3]
  }).save(function (err) {
    if (err) {
      console.error(err);
    }
    counter ++;
    if (counter === states.length) {
      mongoose.connection.close();
    }
  });
});
<commit_msg>Fix seed connection<commit_after>var mongoose = require('mongoose');
var State = require('./app/models/state');

mongoose.connect(process.env.MONGOLAB_URI ||
  'mongodb://localhost/hackathon-war-dev');

var states = [
  ['Acre', 'AC', '-9.1285244', '-70.3077931'],
  ['Alagoas', 'AL', '-9.658443', '-36.6897704'],
  ['Amapá', 'AP', '1.603494', '-52.3764644'],
  ['Amazonas', 'AM', '-3.7857105', '-64.9495526'],
  ['Bahia', 'BA', '-13.4343696', '-41.982751'],
  ['Ceará', 'CE', '-5.3214533', '-39.3382675'],
  ['Espírito Santo', 'ES', '-19.5968657', '-40.7717683'],
  ['Goiás', 'GO', '-15.9471833', '-49.5790826'],
  ['Maranhão', 'MA', '-5.6558833', '-45.2755116'],
  ['Mato Grosso do Sul', 'MS', '-20.611376', '-54.5449798'],
  ['Mato Grosso', 'MT', '-12.6955444', '-55.9289973'],
  ['Minas Gerais', 'MG', '-18.5779703', '-45.4514505'],
  ['Paraná', 'PR', '-24.6169813', '-51.3214141'],
  ['Paraíba', 'PB', '-7.1644358', '-36.7793751'],
  ['Pará', 'PA', '-3.6250659', '-52.4812983'],
  ['Pernambuco', 'PE', '-8.3779283', '-38.0825865'],
  ['Piauí', 'PI', '-6.8380377', '-43.1823977'],
  ['Rio Grande do Norte', 'RN', '-5.9072667', '-36.7754294'],
  ['Rio Grande do Sul', 'RS', '-30.4163413', '-53.6677564'],
  ['Rio de Janeiro', 'RJ', '-22.066452', '-42.9232368'],
  ['Rondônia', 'RO', '-10.8315007', '-63.2922964'],
  ['Roraima', 'RR', '1.8456015', '-61.8560613'],
  ['Santa Catarina', 'SC', '-27.6536999', '-51.1508311'],
  ['Sergipe', 'SE', '-10.5417791', '-37.3227577'],
  ['São Paulo', 'SP', '-22.5455869', '-48.6355226'],
  ['Tocantins', 'TO', '-9.3180492', '-48.219068']
];

var counter = 0;
states.forEach(function (state) {
  new State({
    name: state[0],
    acronym: state[1],
    lat: state[2],
    lng: state[3]
  }).save(function (err) {
    if (err) {
      console.error(err);
    }
    counter ++;
    if (counter === states.length) {
      mongoose.connection.close();
    }
  });
});
<|endoftext|>


<commit_before>var api = require('express').Router()
  , config = require('../lib/config')
  , db = require('ezseed-database').db.user
  , p = require('path')
  , fs = require('fs')
  , jwt = require('express-jwt')
  , prettyBytes = require('pretty-bytes')
  , debug = require('debug')('ezseed:api')
  , logger = require('ezseed-logger')('api')

jwt.sign = require('jsonwebtoken').sign

api

.use(
  jwt({ secret: config.secret }).unless({ path: ['/api/login', '/api/config'] })
)

.use(function(err, req, res, next) {
  if(err.name === 'UnauthorizedError') {
    logger.error(err)
    return res.status(401).end()
  }

  next()
})

.get('/config', function(req, res) {
  res.json(config)
})

.post('/login', function(req, res) {

  db.login(req.body, function(err, user) {
    if(err) {
      return res.send({error: err}).status(401).end()
    } else {
      user.prettySize = prettyBytes(user.spaceLeft)
      user.token = jwt.sign(user, config.secret)

      return res.json(user)
    }
  })

}

/** Protected methods **/

.get('/-', function(req, res, next) {

  //get user paths
  db.paths(req.user.id, function(err, user) {

    if(!user)
      return next(new Error('No user'))
    else if (err)
      return next(err)

    user.prettySize = prettyBytes(user.spaceLeft)
    return res.json(user)
  })

})

.get('/-/files', function(req, res, next) {
  var types = ['others', 'movies', 'albums']

  if(req.query.type && types.indexOf(req.query.type) === -1)
    return res.status(500).send({error: req.params.type+' is not a valid type'}).end()

  if(req.query.match)
    req.query.match = JSON.parse(req.query.match)

  debug("Files", req.query)

  //need params, limit, dateUpdate, paths, type !
  db.files(req.user.id, req.query, function(err, paths) {

    if(!paths)
      return next(new Error('No paths'))
    else if (err)
      return next(err)

    if(req.query.type) {
      var files = {}
      files[req.query.type] = []
    } else {
      var files = {movies: [], albums: [], others: []}
    }

    paths.paths.forEach(function(path) {
      for(var i in files) {
        for(var j in path[i]) {
          files[i].push(path[i][j])
        }
      }
    })

    return res.json(files)
  })
})

.get('/-/refresh', function(req, res) {
  db.paths(req.user.id, function(err, user) {
    process.watcher.client.call('refresh', user.paths, function(err, update) {
      if(err) {
        res.status(500).send({error: err})
      } else {
        res.json(update)
      }
    })
  })
})

// Mainly used for debugging
.get('/-/reset', function(req,res) {
  db.reset(req.user.id, function(err, paths) {
    if(err) {
      logger.error(err)
    }
    process.watcher.client.call('refresh', paths.paths, function(err, update) {
      if(err) {
        res.status(500).send({error: err})
      } else {
        res.json(update)
      }
    })
  })
})

.get('/-/size', function(req, res, next) {

  var size = {
    movies: 0,
    albums: 0,
    others: 0
  },
  //stores the number of elements for paging
  num = {
    movies: 0,
    albums: 0,
    others: 0
  },
  total = 0

  var opts = req.params && req.params.default ? {default: req.user.default_path} : {}

  db.files(req.user.id, opts, function(err, files) {

    if(!files)
      return next(new Error('No files'))
    else if (err)
      return next(err)

    files.paths.forEach(function(p) {

      if(!req.params.path || req.params.paths.indexOf(p._id) !== -1 || req.params.paths.indexOf(p._id) !== -1) {
        for(var i in size) {
          num[i] += p[i].length
          p[i].forEach(function(files) {
            files[require('ezseed-database').helpers.filename(i)].forEach(function(file) {
              size[i] += file.size
            })
          })

          total += size[i]

        }
      }
    })

    size.total = total

    var pretty = {}

    //converting bytes to pretty version
    for(var i in size) {
      pretty[i] = {
        percent: size[i] / req.user.spaceLeft * 100,
        bytes: size[i],
        pretty: prettyBytes(size[i]),
        num: num[i]
      }
    }

    return res.json(pretty)
  })
})

.use(function(err, req, res, next) {
  if(err) {
    logger.error(err)
    return res.status(500).send(err)
  } else {
    next()
  }
})

module.exports = api
<commit_msg>fix(api): Typo<commit_after>var api = require('express').Router()
  , config = require('../lib/config')
  , db = require('ezseed-database').db.user
  , p = require('path')
  , fs = require('fs')
  , jwt = require('express-jwt')
  , prettyBytes = require('pretty-bytes')
  , debug = require('debug')('ezseed:api')
  , logger = require('ezseed-logger')('api')

jwt.sign = require('jsonwebtoken').sign

api

.use(
  jwt({ secret: config.secret }).unless({ path: ['/api/login', '/api/config'] })
)

.use(function(err, req, res, next) {
  if(err.name === 'UnauthorizedError') {
    logger.error(err)
    return res.status(401).end()
  }

  next()
})

.get('/config', function(req, res) {
  res.json(config)
})

.post('/login', function(req, res) {

  db.login(req.body, function(err, user) {
    if(err) {
      return res.send({error: err}).status(401).end()
    } else {
      user.prettySize = prettyBytes(user.spaceLeft)
      user.token = jwt.sign(user, config.secret)

      return res.json(user)
    }
  })

})

/** Protected methods **/

.get('/-', function(req, res, next) {

  //get user paths
  db.paths(req.user.id, function(err, user) {

    if(!user)
      return next(new Error('No user'))
    else if (err)
      return next(err)

    user.prettySize = prettyBytes(user.spaceLeft)
    return res.json(user)
  })

})

.get('/-/files', function(req, res, next) {
  var types = ['others', 'movies', 'albums']

  if(req.query.type && types.indexOf(req.query.type) === -1)
    return res.status(500).send({error: req.params.type+' is not a valid type'}).end()

  if(req.query.match)
    req.query.match = JSON.parse(req.query.match)

  debug("Files", req.query)

  //need params, limit, dateUpdate, paths, type !
  db.files(req.user.id, req.query, function(err, paths) {

    if(!paths)
      return next(new Error('No paths'))
    else if (err)
      return next(err)

    if(req.query.type) {
      var files = {}
      files[req.query.type] = []
    } else {
      var files = {movies: [], albums: [], others: []}
    }

    paths.paths.forEach(function(path) {
      for(var i in files) {
        for(var j in path[i]) {
          files[i].push(path[i][j])
        }
      }
    })

    return res.json(files)
  })
})

.get('/-/refresh', function(req, res) {
  db.paths(req.user.id, function(err, user) {
    process.watcher.client.call('refresh', user.paths, function(err, update) {
      if(err) {
        res.status(500).send({error: err})
      } else {
        res.json(update)
      }
    })
  })
})

// Mainly used for debugging
.get('/-/reset', function(req,res) {
  db.reset(req.user.id, function(err, paths) {
    if(err) {
      logger.error(err)
    }
    process.watcher.client.call('refresh', paths.paths, function(err, update) {
      if(err) {
        res.status(500).send({error: err})
      } else {
        res.json(update)
      }
    })
  })
})

.get('/-/size', function(req, res, next) {

  var size = {
    movies: 0,
    albums: 0,
    others: 0
  },
  //stores the number of elements for paging
  num = {
    movies: 0,
    albums: 0,
    others: 0
  },
  total = 0

  var opts = req.params && req.params.default ? {default: req.user.default_path} : {}

  db.files(req.user.id, opts, function(err, files) {

    if(!files)
      return next(new Error('No files'))
    else if (err)
      return next(err)

    files.paths.forEach(function(p) {

      if(!req.params.path || req.params.paths.indexOf(p._id) !== -1 || req.params.paths.indexOf(p._id) !== -1) {
        for(var i in size) {
          num[i] += p[i].length
          p[i].forEach(function(files) {
            files[require('ezseed-database').helpers.filename(i)].forEach(function(file) {
              size[i] += file.size
            })
          })

          total += size[i]

        }
      }
    })

    size.total = total

    var pretty = {}

    //converting bytes to pretty version
    for(var i in size) {
      pretty[i] = {
        percent: size[i] / req.user.spaceLeft * 100,
        bytes: size[i],
        pretty: prettyBytes(size[i]),
        num: num[i]
      }
    }

    return res.json(pretty)
  })
})

.use(function(err, req, res, next) {
  if(err) {
    logger.error(err)
    return res.status(500).send(err)
  } else {
    next()
  }
})

module.exports = api
<|endoftext|>


<commit_before>import { postgresConnection as cn } from '../../config/helpers.js';
const pgp = require('pg-promise')();
const db = pgp(cn);

module.exports = {
  getOneRecipe: (request, response, next) => {
    const newQueryObj = {
      name: 'get-one-recipe',
      text: `SELECT
               *
             FROM
               recipes
             WHERE
               id = $1`,
      values: [request.params.recipe_id],
    };

    db.one(newQueryObj)
      .then((data) => {
        response.json(data);
        next();
      }).catch((error) => {
        response.json(error);
        next();
      });
  },
  getMultipleRecipes: (request, response, next) => {
    const newQueryObj = {
      name: 'get-multiple-recipes',
      text: `SELECT *
                 FROM
                   recipes
                 WHERE
                   id = ANY($1)`,
      values: [request.query.recipes],
    };

    db.query(newQueryObj).then((data) => {
      response.json(data);
      next();
    }).catch((error) => {
      response.json(error);
      next();
    });
  },
  addRecipeImage: (request, response, next) => {
    const newQueryObj = {
      name: 'add-recipe-image',
      text: `UPDATE recipes
              SET
                images = array_append(images, $1)
              WHERE
                id = $2`,
      values: [request.body.newURL, request.body.id],
    };

    const newQueryObj2 = {
      name: 'find-new-recipe-image',
      text: `SELECT images
              FROM recipes
                WHERE $1 = ANY(images)
                AND id = $2`,
      values: [request.body.newURL, request.body.id],
    };
    db.query(newQueryObj);
    db.query(newQueryObj2)
      .then((data) => {
        response.status(201);
        response.json(data);
        next();
      }).catch((error) => {
        response.json(error);
        next();
      });
  },

  removeRecipeImage: (request, response, next) => {
    const newQueryObj = {
      name: 'remove-recipe-image',
      text: `UPDATE recipes
              SET
                images = array_remove(images, $1)
              WHERE
                id = $2`,
      values: [request.body.newURL, request.body.id],
    };

    const newQueryObj2 = {
      name: 'find-new-recipe-image',
      text: `SELECT images
              FROM recipes
                WHERE $1 = ANY(images)
                AND id = $2`,
      values: [request.body.newURL, request.body.id],
    };

    db.query(newQueryObj);
    db.query(newQueryObj2).then((data) => {
      response.json(data);
      next();
    }).catch((error) => {
      response.json(error);
      next();
    });
  },

  createRecipe: (request, response, next) => {
    let queryObj;

    if (request.body.fork_history) {
      queryObj = {
      name: 'create-recipe',
      text: `insert into recipes(
        title,
        images,
        followers,
        yield,
        yield_unit,
        ingredients,
        prep_time,
        prep_steps,
        cook_time,
        cook_steps,
        finish_steps,
        tags,
        parent,
        author,
        fork_history
      ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) returning *`,
      values: [
        request.body.title,
        request.body.images,
        request.body.followers,
        request.body.yield,
        request.body.yield_unit,
        request.body.ingredients,
        request.body.prep_time,
        request.body.prep_steps,
        request.body.cook_time,
        request.body.cook_steps,
        request.body.finish_steps,
        request.body.tags,
        request.body.parent,
        request.body.author,
        request.body.fork_history,
      ],
      };
    } else {
      queryObj = {
        name: 'create-recipe',
        text: `insert into recipes(
          title,
          images,
          followers,
          yield,
          yield_unit,
          ingredients,
          prep_time,
          prep_steps,
          cook_time,
          cook_steps,
          finish_steps,
          tags,
          parent,
          author,
        ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) returning *`,
        values: [
          request.body.title,
          request.body.images,
          request.body.followers,
          request.body.yield,
          request.body.yield_unit,
          request.body.ingredients,
          request.body.prep_time,
          request.body.prep_steps,
          request.body.cook_time,
          request.body.cook_steps,
          request.body.finish_steps,
          request.body.tags,
          request.body.parent,
          request.body.author,
        ],
      };
    }

    db.one(queryObj)
      .then((data) => {
        response.status(201);
        response.json(data);
        next();
      })
      .catch((error) => {
        response.status(500);
        response.json({
          error: `Error code: ${error.code}, Error message: ${error.detail}`,
        });
        next();
      });
  },
<commit_msg>add trending recipe retreival from db<commit_after>import { postgresConnection as cn } from '../../config/helpers.js';
const pgp = require('pg-promise')();
const db = pgp(cn);

module.exports = {
  getOneRecipe: (request, response, next) => {
    const newQueryObj = {
      name: 'get-one-recipe',
      text: `SELECT
               *
             FROM
               recipes
             WHERE
               id = $1`,
      values: [request.params.recipe_id],
    };

    db.one(newQueryObj)
      .then((data) => {
        response.json(data);
        next();
      }).catch((error) => {
        response.json(error);
        next();
      });
  },
  getMultipleRecipes: (request, response, next) => {
    const newQueryObj = {
      name: 'get-multiple-recipes',
      text: `SELECT *
                 FROM
                   recipes
                 WHERE
                   id = ANY($1)`,
      values: [request.query.recipes],
    };

    db.query(newQueryObj).then((data) => {
      response.json(data);
      next();
    }).catch((error) => {
      response.json(error);
      next();
    });
  },
  addRecipeImage: (request, response, next) => {
    const newQueryObj = {
      name: 'add-recipe-image',
      text: `UPDATE recipes
              SET
                images = array_append(images, $1)
              WHERE
                id = $2`,
      values: [request.body.newURL, request.body.id],
    };

    const newQueryObj2 = {
      name: 'find-new-recipe-image',
      text: `SELECT images
              FROM recipes
                WHERE $1 = ANY(images)
                AND id = $2`,
      values: [request.body.newURL, request.body.id],
    };
    db.query(newQueryObj);
    db.query(newQueryObj2)
      .then((data) => {
        response.status(201);
        response.json(data);
        next();
      }).catch((error) => {
        response.json(error);
        next();
      });
  },

  removeRecipeImage: (request, response, next) => {
    const newQueryObj = {
      name: 'remove-recipe-image',
      text: `UPDATE recipes
              SET
                images = array_remove(images, $1)
              WHERE
                id = $2`,
      values: [request.body.newURL, request.body.id],
    };

    const newQueryObj2 = {
      name: 'find-new-recipe-image',
      text: `SELECT images
              FROM recipes
                WHERE $1 = ANY(images)
                AND id = $2`,
      values: [request.body.newURL, request.body.id],
    };

    db.query(newQueryObj);
    db.query(newQueryObj2).then((data) => {
      response.json(data);
      next();
    }).catch((error) => {
      response.json(error);
      next();
    });
  },

  createRecipe: (request, response, next) => {
    let queryObj;

    if (request.body.fork_history) {
      queryObj = {
      name: 'create-recipe',
      text: `insert into recipes(
        title,
        images,
        followers,
        yield,
        yield_unit,
        ingredients,
        prep_time,
        prep_steps,
        cook_time,
        cook_steps,
        finish_steps,
        tags,
        parent,
        author,
        fork_history
      ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) returning *`,
      values: [
        request.body.title,
        request.body.images,
        request.body.followers,
        request.body.yield,
        request.body.yield_unit,
        request.body.ingredients,
        request.body.prep_time,
        request.body.prep_steps,
        request.body.cook_time,
        request.body.cook_steps,
        request.body.finish_steps,
        request.body.tags,
        request.body.parent,
        request.body.author,
        request.body.fork_history,
      ],
      };
    } else {
      queryObj = {
        name: 'create-recipe',
        text: `insert into recipes(
          title,
          images,
          followers,
          yield,
          yield_unit,
          ingredients,
          prep_time,
          prep_steps,
          cook_time,
          cook_steps,
          finish_steps,
          tags,
          parent,
          author,
        ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) returning *`,
        values: [
          request.body.title,
          request.body.images,
          request.body.followers,
          request.body.yield,
          request.body.yield_unit,
          request.body.ingredients,
          request.body.prep_time,
          request.body.prep_steps,
          request.body.cook_time,
          request.body.cook_steps,
          request.body.finish_steps,
          request.body.tags,
          request.body.parent,
          request.body.author,
        ],
      };
    }

    db.one(queryObj)
      .then((data) => {
        response.status(201);
        response.json(data);
        next();
      })
      .catch((error) => {
        response.status(500);
        response.json({
          error: `Error code: ${error.code}, Error message: ${error.detail}`,
        });
        next();
      });
  },

  trendingRecipes: (request, response, next) => {
    const interval = request.body.interval || '1 day';
    const limit = request.body.limit || 10;

    // console.log("MADE IT!", ("'"+interval+"'"), limit);
    const newQueryObj = {
      name: 'get-trending-recipes',
      text: `SELECT
              *
              FROM (
                SELECT
                  parent,
                  COUNT (parent)
                FROM
                  recipes
                WHERE
                  created_at > CURRENT_TIMESTAMP - INTERVAL '1 day'
                AND
                  parent is not null
                GROUP BY
                  parent
                ORDER BY
                  COUNT (parent) DESC
                LIMIT $1
              ) trends`,
      values: [limit],
    };

    db.query(newQueryObj).then((data) => {
      let trendingIds = data.map((element) => {
        return element.parent;
      });
      return trendingIds;
    }).then((trendingIds) => {
      const newQueryObj2 = {
        name: 'get-multiple-recipes',
        text: `SELECT title
                   FROM
                     recipes
                   WHERE
                     id = ANY($1)`,
        values: [trendingIds],
      };
      return db.query(newQueryObj2)})
    .then((data) => {
      response.json(data);
      next();
    }).catch((error) => {
      response.json(error);
      next();
    });
  },
};
<|endoftext|>


<commit_before>var Roadmap = require('./roadmapModel.js'),
    User = require('../users/userModel.js'),
    ObjectId = require('mongoose').Types.ObjectId,
    handleError = require('../../util.js').handleError,
    handleQuery = require('../queryHandler.js');

var findId = function (req, res, next) {
  User.findOne(req.body.author)
    .then(function (user) {
      req.body.author = user._id;
      resolveCreation(req, res, next);
    })
    .catch(handleError(next));
};

var resolveCreation = function (req, res, next) {
  var newRoadmap = req.body;
  Roadmap(newRoadmap).save()
    .then(function(dbResults){
      res.status(201).json({data: dbResults});
    })
    .catch(handleError(next));
};

module.exports = {

  createRoadmap : function (req, res, next) {
    var author = req.body.author.toString();

    if (author.length !== 24 || new ObjectId(author) !== author)
      findId(req, res, next);
    else
      resolveCreation(req, res, next);
  },

  getRoadmaps : function (req, res, next) {
    var dbArgs = handleQuery(req.query);

    Roadmap.find(dbArgs.filters, dbArgs.fields, dbArgs.params)
      .populate('author nodes')
      .then(function(dbResults){
        res.json({data: dbResults});
      })
      .catch(handleError(next));
  },

  getRoadmapByID : function (req, res, next) {
    var _id = req.params.roadmapID;
    Roadmap.findById(_id)
      .populate('author nodes')
      .then(function(dbResults){
        res.json({data: dbResults});
      })
      .catch(handleError(next));
  },

  updateRoadmap : function (req, res, next) {
    var _id = req.params.roadmapID;
    var updateCommand = req.body;
    Roadmap.findByIdAndUpdate(_id, updateCommand, {new: true})
      .populate('author nodes')
      .then(function(dbResults){
        res.json({data: dbResults});
      })
      .catch(handleError(next));
  },

  deleteRoadmap : function (req, res, next) {
    var _id = req.params.roadmapID;
    Roadmap.findOne({_id:_id})
      .populate('author nodes')
      .then(function(roadmap){
        if (roadmap) roadmap.remove();
        res.json({data: roadmap});
      })
      .catch(handleError(next));
  }

};<commit_msg>(feat) Refactor POST /api/roadmaps route handler to get author from Authorization header instead of request payload<commit_after>var Roadmap = require('./roadmapModel.js'),
    User = require('../users/userModel.js'),
    ObjectId = require('mongoose').Types.ObjectId,
    handleError = require('../../util.js').handleError,
    handleQuery = require('../queryHandler.js'),
    getAuthHeader = require('basic-auth');

module.exports = {

  createRoadmap : function (req, res, next) {
    var author = getAuthHeader(req).name;
    var newRoadmap = req.body;

    User.findOne({username: author})
      .then(function (user) {
        newRoadmap.author = user._id;
        return Roadmap(newRoadmap).save();
      })
      .then(function(dbResults){
        res.status(201).json({data: dbResults});
      })
      .catch(handleError(next));
  },

  getRoadmaps : function (req, res, next) {
    var dbArgs = handleQuery(req.query);

    Roadmap.find(dbArgs.filters, dbArgs.fields, dbArgs.params)
      .populate('author nodes')
      .then(function(dbResults){
        res.json({data: dbResults});
      })
      .catch(handleError(next));
  },

  getRoadmapByID : function (req, res, next) {
    var _id = req.params.roadmapID;
    Roadmap.findById(_id)
      .populate('author nodes')
      .then(function(dbResults){
        res.json({data: dbResults});
      })
      .catch(handleError(next));
  },

  updateRoadmap : function (req, res, next) {
    var _id = req.params.roadmapID;
    var updateCommand = req.body;
    Roadmap.findByIdAndUpdate(_id, updateCommand, {new: true})
      .populate('author nodes')
      .then(function(dbResults){
        res.json({data: dbResults});
      })
      .catch(handleError(next));
  },

  deleteRoadmap : function (req, res, next) {
    var _id = req.params.roadmapID;
    Roadmap.findOne({_id:_id})
      .populate('author nodes')
      .then(function(roadmap){
        if (roadmap) roadmap.remove();
        res.json({data: roadmap});
      })
      .catch(handleError(next));
  }

};<|endoftext|>


<commit_before>"use strict";

//Load dependencies
var async = require("async");
var moment = require('moment-timezone');
var applicationStorage = process.require("core/applicationStorage.js");
var updateModel = process.require("updates/updateModel.js");
var updateService = process.require("updates/updateService.js");
var guildModel = process.require("guilds/guildModel.js");
var guildService = process.require("guilds/guildService.js");
var bnetAPI = process.require("core/api/bnet.js");
var wowProgressAPI = process.require("core/api/wowProgress.js");
var progressAPI = process.require("core/api/progress.js");

/**
 * GuildUpdateProcess constructor
 * @constructor
 */
function GuildUpdateProcess() {
}

/**
 * Update a guild
 */
GuildUpdateProcess.prototype.updateGuild = function () {
    var self = this;
    var logger = applicationStorage.logger;
    var config = applicationStorage.config;

    async.waterfall([
        function (callback) {
            //Get next guild to update
            updateService.getNextUpdate('gu', function (error, guildUpdate) {
                if (guildUpdate == null) {
                    //Guild update is empty
                    logger.info("No guild to update ... waiting 3 sec");
                    setTimeout(function () {
                        callback(true);
                    }, 3000);
                } else {
                    logger.info("Update guild %s-%s-%s", guildUpdate.region, guildUpdate.realm, guildUpdate.name);
                    callback(error, guildUpdate);
                }
            });
        },
        function (guildUpdate, callback) {
            //Sanitize name
            bnetAPI.getGuild(guildUpdate.region, guildUpdate.realm, guildUpdate.name, ["members"], function (error, guild) {
                if (guild && guild.realm && guild.name) {
                    callback(error, guildUpdate.region, guild);
                } else {
                    logger.warn("Bnet return empty guild skip it");
                    callback(true);
                }

            })
        },
        function(region,guild,callback){
            //Set guild to update for progress (change with url call update)
            updateModel.insert('wp_gu', region, guild.realm, guild.name, 5, function (error) {
                callback(error,region,guild);
            });
        },
        function (region, guild, callback) {
            async.parallel({
                ad: function (callback) {
                    async.waterfall([
                        function (callback) {
                            guildModel.findOne({
                                region: region,
                                realm: guild.realm,
                                name: guild.name
                            }, {ad: 1}, function (error, guild) {
                                callback(error, guild);
                            });
                        },
                        function (guild, callback) {
                            if (guild && guild.ad && guild.ad.timezone && guild.ad.lfg == true) {
                                var offset = Math.round(moment.tz.zone(guild.ad.timezone).parse(Date.UTC()) / 60);
                                async.each(guild.ad.play_time, function (day, callback) {
                                    day.start.hourUTC = day.start.hour + offset;
                                    day.end.hourUTC = day.end.hour + offset;
                                    callback();
                                }, function () {
                                    callback(null, guild.ad);
                                });
                            } else {
                                callback();
                            }
                        }
                    ], function (error, ad) {
                        if (error) {
                            logger.error(error.message);
                        }
                        callback(null, ad)
                    });
                },
                rank: function (callback) {
                    progressAPI.getRank(config.currentProgress, region, guild.realm, guild.name, function (error, rank) {
                        if (error) {
                            logger.error(error.message);
                        } else if (rank) {
                            rank.updated = new Date().getTime();
                        }
                        callback(null, rank);
                    });
                },
                progress: function (callback) {
                    progressAPI.getProgress(18,region,guild.realm,guild.name,function(error,progress){
                        if (error) {
                            logger.error(error.message);
                        } else if(progress){
                            progress.updated = new Date().getTime();
                        }
                        callback(null, progress);
                    });
                }
            }, function (error, results) {
                results.bnet = guild;
                results.bnet.updated = new Date().getTime();
                guildModel.upsert(region, guild.realm, guild.name, results, function (error) {
                    if (error) {
                        logger.error(error.message);
                    }
                    callback();
                });
            })
        }
    ], function (error) {
        if (error && error !== true) {
            logger.error(error.message);
        }
        self.updateGuild();
    });
};

/**
 * Start GuildUpdateProcess
 * @param callback
 */
GuildUpdateProcess.prototype.start = function (callback) {
    applicationStorage.logger.info("Starting GuildUpdateProcess");
    this.updateGuild();
    callback();
};

module.exports = GuildUpdateProcess;<commit_msg>Fix a bug on guildUpdateProcess<commit_after>"use strict";

//Load dependencies
var async = require("async");
var moment = require('moment-timezone');
var applicationStorage = process.require("core/applicationStorage.js");
var updateModel = process.require("updates/updateModel.js");
var updateService = process.require("updates/updateService.js");
var guildModel = process.require("guilds/guildModel.js");
var guildService = process.require("guilds/guildService.js");
var bnetAPI = process.require("core/api/bnet.js");
var wowProgressAPI = process.require("core/api/wowProgress.js");
var progressAPI = process.require("core/api/progress.js");

/**
 * GuildUpdateProcess constructor
 * @constructor
 */
function GuildUpdateProcess() {
}

/**
 * Update a guild
 */
GuildUpdateProcess.prototype.updateGuild = function () {
    var self = this;
    var logger = applicationStorage.logger;
    var config = applicationStorage.config;

    async.waterfall([
        function (callback) {
            //Get next guild to update
            updateService.getNextUpdate('gu', function (error, guildUpdate) {
                if (guildUpdate == null) {
                    //Guild update is empty
                    logger.info("No guild to update ... waiting 3 sec");
                    setTimeout(function () {
                        callback(true);
                    }, 3000);
                } else {
                    logger.info("Update guild %s-%s-%s", guildUpdate.region, guildUpdate.realm, guildUpdate.name);
                    callback(error, guildUpdate);
                }
            });
        },
        function (guildUpdate, callback) {
            //Sanitize name
            bnetAPI.getGuild(guildUpdate.region, guildUpdate.realm, guildUpdate.name, ["members"], function (error, guild) {
                if (guild && guild.realm && guild.name) {
                    callback(error, guildUpdate.region, guild);
                } else {
                    logger.warn("Bnet return empty guild skip it");
                    callback(true);
                }

            })
        },
        function(region,guild,callback){
            //Set guild to update for progress (change with url call update)
            updateModel.insert('wp_gu', region, guild.realm, guild.name, 5, function (error) {
                callback(error,region,guild);
            });
        },
        function (region, guild, callback) {
            async.parallel({
                ad: function (callback) {
                    async.waterfall([
                        function (callback) {
                            guildModel.findOne({
                                region: region,
                                realm: guild.realm,
                                name: guild.name
                            }, {ad: 1}, function (error, guild) {
                                callback(error, guild);
                            });
                        },
                        function (guild, callback) {
                            if (guild && guild.ad && guild.ad.timezone && guild.ad.lfg == true) {
                                var offset = Math.round(moment.tz.zone(guild.ad.timezone).parse(Date.UTC()) / 60);
                                async.each(guild.ad.play_time, function (day, callback) {
                                    day.start.hourUTC = day.start.hour + offset;
                                    day.end.hourUTC = day.end.hour + offset;
                                    callback();
                                }, function () {
                                    callback(null, guild.ad);
                                });
                            } else {
                                callback();
                            }
                        }
                    ], function (error, ad) {
                        if (error) {
                            logger.error(error.message);
                        }
                        callback(null, ad)
                    });
                },
                rank: function (callback) {
                    progressAPI.getRank(config.currentProgress, region, guild.realm, guild.name, function (error, rank) {
                        if (error) {
                            logger.error(error.message);
                            callback();
                        } else if (rank) {
                            rank.updated = new Date().getTime();
                            callback(null, rank);
                        }
                    });
                },
                progress: function (callback) {
                    progressAPI.getProgress(18,region,guild.realm,guild.name,function(error,progress){
                        if (error) {
                            logger.error(error.message);
                            callback();
                        } else if(progress){
                            progress.updated = new Date().getTime();
                            callback(null, progress);
                        }
                    });
                }
            }, function (error, results) {
                results.bnet = guild;
                results.bnet.updated = new Date().getTime();
                guildModel.upsert(region, guild.realm, guild.name, results, function (error) {
                    if (error) {
                        logger.error(error.message);
                    }
                    callback();
                });
            })
        }
    ], function (error) {
        if (error && error !== true) {
            logger.error(error.message);
        }
        self.updateGuild();
    });
};

/**
 * Start GuildUpdateProcess
 * @param callback
 */
GuildUpdateProcess.prototype.start = function (callback) {
    applicationStorage.logger.info("Starting GuildUpdateProcess");
    this.updateGuild();
    callback();
};

module.exports = GuildUpdateProcess;<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var path = require('path');
var async = require('async');
var fs = require('fs');
var mongoose = require('mongoose');
var grid = require('gridfs-stream');
var config = require('../../config/environment');

var auth = require('../../auth/auth.service');
var Mdph = require('../../api/mdph/mdph.model');
var DocumentCategoryCtrl = require('../../api/document/document-category.controller');

module.exports = function(request, user, requestTempPdfPath, documentList, callback) {
  if (auth.hasRole(user, 'adminMdph')) {
    buildGroupStructure(request, requestTempPdfPath, documentList, callback);
  } else {
    buildFlatStructure(requestTempPdfPath, documentList, callback);
  }
};

function buildGroupStructure(request, requestTempPdfPath, documentList, callback) {
  Mdph
    .findOne({zipcode: request.mdph})
    .exec(function(err, mdph) {
      if (err) {
        return callback(err);
      }

      async.parallel([
        function(callback) {
          DocumentCategoryCtrl.getPdfCategory(mdph, callback);
        },

        function(callback) {
          DocumentCategoryCtrl.getUnclassifiedCategory(mdph, callback);
        },

        function(callback) {
          DocumentCategoryCtrl.findAndSortCategoriesForMdph(mdph, callback);
        }
      ], function(err, results) {
        if (err) {
          return callback(err);
        }

        // console.log(results);
        const pdfCategory = results[0];
        const unclassifiedCategory = results[1];
        const documentCategories = results[2];
        const pdfStructure = [];
        const gfs = grid(mongoose.connection.db);

        // Main request document
        if (pdfCategory.barcode) {
          pdfStructure.push(gfs.createReadStream({_id: pdfCategory.barcode._id}));
        }

        pdfStructure.push(requestTempPdfPath);

        // Documents sorted by categories
        _.forEach(documentCategories, function(category) {
          let documentFoundForThisCategory = false;

          _.forEach(category.documentTypes, function(documentType) {
            _.forEach(documentList, function(currentDocument) {
              if (currentDocument.type === documentType.id) {
                if (!documentFoundForThisCategory) {
                  pdfStructure.push(gfs.createReadStream({_id: category.barcode._id}));
                  documentFoundForThisCategory = true;
                }

                pdfStructure.push(currentDocument.path);
                currentDocument.___classified = true;
              }
            });
          });
        });

        // Other documents
        var unclassifiedDocuments = _.filter(documentList, function(document) {
          return !document.___classified;
        });

        if (unclassifiedCategory.barcode && unclassifiedDocuments.length > 0) {
          pdfStructure.push(gfs.createReadStream({_id: unclassifiedCategory.barcode._id}));
        }

        _.forEach(unclassifiedDocuments, function(currentDocument) {
          pdfStructure.push(currentDocument.path);
        });

        callback(null, pdfStructure);
      });
    });
}

function buildFlatStructure(requestTempPdfPath, documentList, callback) {
  var pdfStructure = [
    requestTempPdfPath
  ];

  if (documentList.length > 0) {
    documentList.forEach(function(currentDocument) {
      pdfStructure.push(currentDocument.path);
    });
  }

  callback(null, pdfStructure);
}
<commit_msg>Add check if barcode is present<commit_after>'use strict';

var _ = require('lodash');
var path = require('path');
var async = require('async');
var fs = require('fs');
var mongoose = require('mongoose');
var grid = require('gridfs-stream');
var config = require('../../config/environment');

var auth = require('../../auth/auth.service');
var Mdph = require('../../api/mdph/mdph.model');
var DocumentCategoryCtrl = require('../../api/document/document-category.controller');

module.exports = function(request, user, requestTempPdfPath, documentList, callback) {
  if (auth.hasRole(user, 'adminMdph')) {
    buildGroupStructure(request, requestTempPdfPath, documentList, callback);
  } else {
    buildFlatStructure(requestTempPdfPath, documentList, callback);
  }
};

function buildGroupStructure(request, requestTempPdfPath, documentList, callback) {
  Mdph
    .findOne({zipcode: request.mdph})
    .exec(function(err, mdph) {
      if (err) {
        return callback(err);
      }

      async.parallel([
        function(callback) {
          DocumentCategoryCtrl.getPdfCategory(mdph, callback);
        },

        function(callback) {
          DocumentCategoryCtrl.getUnclassifiedCategory(mdph, callback);
        },

        function(callback) {
          DocumentCategoryCtrl.findAndSortCategoriesForMdph(mdph, callback);
        }
      ], function(err, results) {
        if (err) {
          return callback(err);
        }

        // console.log(results);
        const pdfCategory = results[0];
        const unclassifiedCategory = results[1];
        const documentCategories = results[2];
        const pdfStructure = [];
        const gfs = grid(mongoose.connection.db);

        // Main request document
        if (pdfCategory.barcode) {
          pdfStructure.push(gfs.createReadStream({_id: pdfCategory.barcode._id}));
        }

        pdfStructure.push(requestTempPdfPath);

        // Documents sorted by categories
        _.forEach(documentCategories, function(category) {
          let documentFoundForThisCategory = false;

          _.forEach(category.documentTypes, function(documentType) {
            _.forEach(documentList, function(currentDocument) {
              if (currentDocument.type === documentType.id) {
                if (!documentFoundForThisCategory && category.barcode) {
                  pdfStructure.push(gfs.createReadStream({_id: category.barcode._id}));
                  documentFoundForThisCategory = true;
                }

                pdfStructure.push(currentDocument.path);
                currentDocument.___classified = true;
              }
            });
          });
        });

        // Other documents
        var unclassifiedDocuments = _.filter(documentList, function(document) {
          return !document.___classified;
        });

        if (unclassifiedCategory.barcode && unclassifiedDocuments.length > 0) {
          pdfStructure.push(gfs.createReadStream({_id: unclassifiedCategory.barcode._id}));
        }

        _.forEach(unclassifiedDocuments, function(currentDocument) {
          pdfStructure.push(currentDocument.path);
        });

        callback(null, pdfStructure);
      });
    });
}

function buildFlatStructure(requestTempPdfPath, documentList, callback) {
  var pdfStructure = [
    requestTempPdfPath
  ];

  if (documentList.length > 0) {
    documentList.forEach(function(currentDocument) {
      pdfStructure.push(currentDocument.path);
    });
  }

  callback(null, pdfStructure);
}
<|endoftext|>