<commit_before>var injector    = require( 'injector' )
  , Sequelize   = require( 'sequelize' )
  , Module      = require( 'classes' ).Module
  , Model       = require( 'classes' ).Model;

module.exports = Module.extend({

    models: {},

    sequelize: null,

    preSetup: function() {
        this.debug( 'Opening database connection to ' + this.config.db.options.dialect + '...' );

        this.sequelize = new Sequelize(
            this.config.db.database,
            this.config.db.username,
            this.config.db.password,
            this.config.db.options
        );
    },

    preInit: function() {
        this.debug( 'Adding Sequelize module and sequelize instance to the injector...' );

        injector.instance( 'Sequelize', Sequelize );
        injector.instance( 'sequelize', this.sequelize );
    },

    modulesLoaded: function() {
        this.defineModelsAssociations();
        this.emit( 'ready' );
    },

    defineModelsAssociations: function() {
        this.debug( 'Defining model assocations' );

        Object.keys( this.config.modelAssociations ).forEach( this.proxy( function( modelName ) {
            Object.keys( this.config.modelAssociations[ modelName ] ).forEach( this.proxy( 'defineModelAssociations', modelName ) );
        }));
    },

    defineModelAssociations: function( modelName, assocType ) {
        var associatedWith = this.config.modelAssociations[ modelName ][ assocType ];
        if ( ! associatedWith instanceof Array ) {
            associatedWith = [ associatedWith ];
        }

        associatedWith.forEach( this.proxy( 'associateModels', modelName, assocType ) );
    },

    associateModels: function( modelName, assocType, assocTo ) {
        // Support second argument
        if ( assocTo instanceof Array ) {
            this.debug( '%s %s %s with second argument of ', modelName, assocType, assocTo[0], assocTo[1] );
            this.models[ modelName ][ assocType ]( this.models[ assocTo[0] ], assocTo[1] );
        } else {
            this.debug( '%s %s %s', modelName, assocType, assocTo );
            this.models[ modelName ][ assocType ]( this.models[assocTo] );
        }
    },

    parseModelSchema: function( Static ) {
        var parseDebug = this.proxy(function( msg ) {
                this.debug( Static._name + 'Model: ' + msg );
            })
          , sequelizeConf = { paranoid: false, timestamps: false }
          , fields = {};

        if ( this.models[ Static._name ] !== undefined ) {
            parseDebug( 'Returning previously parsed and generated model...' );
            return this.models[ Static._name ];
        }

        parseDebug( 'Parsing schema for model...' );
        Object.keys( Static._schema ).forEach( this.proxy( 'parseSchemaField', Static, fields ) );

        parseDebug( 'Configuring static object for sequelize...' );

        this.setupOptions( parseDebug, sequelizeConf, Static );

        this.setupBehaviours( parseDebug, sequelizeConf, Static );

        parseDebug( 'Setting sequelize as the _db (adapter) for the Model...' );
        Static._db = this.sequelize;

        parseDebug( 'Generating new sequelize model using computed schema...' );
        var model = this.sequelize.define( Static._name, fields, sequelizeConf );

        parseDebug( 'Caching completed native model...' );
        this.models[ Static._name ] = model;

        return model;
    },

    setupOptions: function( parseDebug, sequelizeConf, Static ) {
        parseDebug( 'Setup options...' );

        if ( Static.dbName !== false  ) {
            parseDebug( 'Setting dbName=' + Static.dbName + ' (sequelize tableName option)...' );
            sequelizeConf.tableName = Static.dbName;
        }

        if ( Static.freezeDbName !== false ) {
            parseDebug( 'Setting freezeDbName=' + Static.freezeDbName + ' (sequelize freezeTableName option)...' );
            sequelizeConf.freezeTableName = Static.freezeDbName;
        }

        if ( Static.underscored !== undefined ) {
            parseDebug( 'Setting underscored=' + Static.underscored + '...' );
            sequelizeConf.underscored = Static.underscored;
        }

        if ( Static.engine !== false ) {
            parseDebug( 'Setting engine=' + Static.engine + '...' );
            sequelizeConf.engine = Static.engine;
        }

        if ( Static.charset !== false  ) {
            parseDebug( 'Setting charset=' + Static.charset + '...' );
            sequelizeConf.charset = Static.charset;
        }

        if ( Static.comment !== false  ) {
            parseDebug( 'Setting comment=' + Static.comment + '...' );
            sequelizeConf.comment = Static.comment;
        }

        if ( Static.collate !== false  ) {
            parseDebug( 'Setting collate=' + Static.collate + '...' );
            sequelizeConf.collate = Static.collate;
        }
    },

    setupBehaviours: function( parseDebug, sequelizeConf, Static ) {
        parseDebug( 'Setup behaviours...' );

        if ( !!Static.softDeletable ) {
            parseDebug( 'is softDeletable (' + Static.deletedAt + ')' );

            sequelizeConf.paranoid = Static.softDeletable;
            sequelizeConf.deletedAt = Static.deletedAt;
        }

        if ( !!Static.timeStampable ) {
            parseDebug( 'is timeStampable (' + Static.timeStampable + ')' );

            sequelizeConf.timestamps = Static.timeStampable;
            sequelizeConf.createdAt = Static.createdAt;
            sequelizeConf.updatedAt = Static.updatedAt;
        }
    },

    parseSchemaField: function( Static, fields, name ) {
        var options = Static._schema[ name ]
          , fieldDefinition = {};

        // Allow direct syntax
        if ( typeof options !== 'object' || options instanceof Array ) {
            options = {
                type: options
            }
        }

        // Handle array of "Something"
        if ( options.type instanceof Array || options.type === Array ) {
            options.of = ( options.type.length > 0 && options.type[ 0 ] !== undefined ) ? options.type[ 0 ] : String;
            options.type = Array;
        }

        // Get the type
        fieldDefinition.type = this.getFieldType( Static, options );

        // Handle options
        [ 'allowNull', 'primaryKey', 'autoIncrement', 'unique', 'required', 'validate', 'default', 'comment' ].forEach(function( optionName ) {
            if ( options[ optionName ] !== undefined ) {
                if ( optionName === 'primaryKey' ) {
                    Static.primaryKey = name;
                }

                fieldDefinition[ optionName === 'default' ? 'defaultValue' : optionName ] = options[ optionName ];
            }
        });

        fields[ name ] = fieldDefinition;
    },

    getFieldType: function( Static, options ) {
        var field;

        switch( options.type ) {

        case Number:
            field = this.numberType( options );
            break;
        case String:
            field = Sequelize.STRING;
            break;
        case Boolean:
            field = Sequelize.BOOLEAN;
            break;
        case Date:
            field = Sequelize.DATE;
            break;
        case Array:
            field = options.of ? Sequelize.ARRAY( this.getFieldType( Static, { type: options.of } ) ) : Sequelize.ARRAY( Sequelize.STRING );
            break;
        case Buffer:
            field = Sequelize.STRING.BINARY;
            break;
        case Model.Types.ENUM:
            field = Sequelize.ENUM( options.values );
            break;
        case Model.Types.BIGINT:
            field = this.bigIntType( options );
            break;
        case Model.Types.FLOAT:
            field = this.floatType( options );
            break;
        case Model.Types.DECIMAL:
            field = this.decimalType( options );
            break;
        case Model.Types.TEXT:
            field = Sequelize.TEXT;
            break;
        case undefined:
            throw new Error( [ 'You must define the type of field that', '"' + name + '"', 'is on the', '"' + Static.name + '" model' ].join( ' ' ) );
        default:
            throw new Error( [ 'You must define a valid type for the field named', '"' + name + '"', 'on the', '"' + Static.name + '" model' ].join( ' ' ) );
        }

        return field;
    },

    numberType: function( options ) {
        var field = !!options.length ? Sequelize.INTEGER( options.length ) : Sequelize.INTEGER;
        if ( !!options.unsigned && !!options.zerofill ) {
            field = field.UNSIGNED.ZEROFILL;
        } else if ( !!options.unsigned && !options.zerofill ) {
            field = field.UNSIGNED;
        } else if ( !options.unsigned && !!options.zerofill ) {
            field = field.ZEROFILL;
        }
        return field;
    },

    bigIntType: function( options ) {
        var field = !!options.length ? Sequelize.BIGINT( options.length ) : Sequelize.BIGINT;
        if ( !!options.unsigned && !!options.zerofill ) {
            field = bigint.UNSIGNED.ZEROFILL;
        } else if ( !!options.unsigned && !options.zerofill ) {
            field = bigint.UNSIGNED;
        } else if ( !options.unsigned && !!options.zerofill ) {
            field = bigint.ZEROFILL;
        }
        return field;
    },

    floatType: function( options ) {
        var field = Sequelize.FLOAT;
        if ( !!options.decimals ) {
            field = Sequelize.FLOAT( options.length, options.decimals );
        } else if ( !!options.length ) {
            field = Sequelize.FLOAT( options.length );
        }

        if ( !!options.unsigned && !!options.zerofill ) {
            field = field.UNSIGNED.ZEROFILL;
        } else if ( !!options.unsigned && !options.zerofill ) {
            field = field.UNSIGNED;
        } else if ( !options.unsigned && !!options.zerofill ) {
            field = field.ZEROFILL;
        }
        return field;
    },

    decimalType: function( options ) {
        var field = Sequelize.DECIMAL;
        if ( !!options.scale ) {
            field = Sequelize.DECIMAL( options.precision, options.scale );
        } else if ( !!options.precision ) {
            field = Sequelize.DECIMAL( options.precision );
        }
        return field;
    }
});<commit_msg>refactor(validations): No longer use sequelize validations directly<commit_after>var injector    = require( 'injector' )
  , Sequelize   = require( 'sequelize' )
  , Module      = require( 'classes' ).Module
  , Model       = require( 'classes' ).Model;

module.exports = Module.extend({

    models: {},

    sequelize: null,

    preSetup: function() {
        this.debug( 'Opening database connection to ' + this.config.db.options.dialect + '...' );

        this.sequelize = new Sequelize(
            this.config.db.database,
            this.config.db.username,
            this.config.db.password,
            this.config.db.options
        );
    },

    preInit: function() {
        this.debug( 'Adding Sequelize module and sequelize instance to the injector...' );

        injector.instance( 'Sequelize', Sequelize );
        injector.instance( 'sequelize', this.sequelize );
    },

    modulesLoaded: function() {
        this.defineModelsAssociations();
        this.emit( 'ready' );
    },

    defineModelsAssociations: function() {
        this.debug( 'Defining model assocations' );

        Object.keys( this.config.modelAssociations ).forEach( this.proxy( function( modelName ) {
            Object.keys( this.config.modelAssociations[ modelName ] ).forEach( this.proxy( 'defineModelAssociations', modelName ) );
        }));
    },

    defineModelAssociations: function( modelName, assocType ) {
        var associatedWith = this.config.modelAssociations[ modelName ][ assocType ];
        if ( ! associatedWith instanceof Array ) {
            associatedWith = [ associatedWith ];
        }

        associatedWith.forEach( this.proxy( 'associateModels', modelName, assocType ) );
    },

    associateModels: function( modelName, assocType, assocTo ) {
        // Support second argument
        if ( assocTo instanceof Array ) {
            this.debug( '%s %s %s with second argument of ', modelName, assocType, assocTo[0], assocTo[1] );
            this.models[ modelName ][ assocType ]( this.models[ assocTo[0] ], assocTo[1] );
        } else {
            this.debug( '%s %s %s', modelName, assocType, assocTo );
            this.models[ modelName ][ assocType ]( this.models[assocTo] );
        }
    },

    parseModelSchema: function( Static ) {
        var parseDebug = this.proxy(function( msg ) {
                this.debug( Static._name + 'Model: ' + msg );
            })
          , sequelizeConf = { paranoid: false, timestamps: false }
          , fields = {};

        if ( this.models[ Static._name ] !== undefined ) {
            parseDebug( 'Returning previously parsed and generated model...' );
            return this.models[ Static._name ];
        }

        parseDebug( 'Parsing schema for model...' );
        Object.keys( Static._schema ).forEach( this.proxy( 'parseSchemaField', Static, fields ) );

        parseDebug( 'Configuring static object for sequelize...' );

        this.setupOptions( parseDebug, sequelizeConf, Static );

        this.setupBehaviours( parseDebug, sequelizeConf, Static );

        parseDebug( 'Setting sequelize as the _db (adapter) for the Model...' );
        Static._db = this.sequelize;

        parseDebug( 'Generating new sequelize model using computed schema...' );
        var model = this.sequelize.define( Static._name, fields, sequelizeConf );

        parseDebug( 'Caching completed native model...' );
        this.models[ Static._name ] = model;

        return model;
    },

    setupOptions: function( parseDebug, sequelizeConf, Static ) {
        parseDebug( 'Setup options...' );

        if ( Static.dbName !== false  ) {
            parseDebug( 'Setting dbName=' + Static.dbName + ' (sequelize tableName option)...' );
            sequelizeConf.tableName = Static.dbName;
        }

        if ( Static.freezeDbName !== false ) {
            parseDebug( 'Setting freezeDbName=' + Static.freezeDbName + ' (sequelize freezeTableName option)...' );
            sequelizeConf.freezeTableName = Static.freezeDbName;
        }

        if ( Static.underscored !== undefined ) {
            parseDebug( 'Setting underscored=' + Static.underscored + '...' );
            sequelizeConf.underscored = Static.underscored;
        }

        if ( Static.engine !== false ) {
            parseDebug( 'Setting engine=' + Static.engine + '...' );
            sequelizeConf.engine = Static.engine;
        }

        if ( Static.charset !== false  ) {
            parseDebug( 'Setting charset=' + Static.charset + '...' );
            sequelizeConf.charset = Static.charset;
        }

        if ( Static.comment !== false  ) {
            parseDebug( 'Setting comment=' + Static.comment + '...' );
            sequelizeConf.comment = Static.comment;
        }

        if ( Static.collate !== false  ) {
            parseDebug( 'Setting collate=' + Static.collate + '...' );
            sequelizeConf.collate = Static.collate;
        }
    },

    setupBehaviours: function( parseDebug, sequelizeConf, Static ) {
        parseDebug( 'Setup behaviours...' );

        if ( !!Static.softDeletable ) {
            parseDebug( 'is softDeletable (' + Static.deletedAt + ')' );

            sequelizeConf.paranoid = Static.softDeletable;
            sequelizeConf.deletedAt = Static.deletedAt;
        }

        if ( !!Static.timeStampable ) {
            parseDebug( 'is timeStampable (' + Static.timeStampable + ')' );

            sequelizeConf.timestamps = Static.timeStampable;
            sequelizeConf.createdAt = Static.createdAt;
            sequelizeConf.updatedAt = Static.updatedAt;
        }
    },

    parseSchemaField: function( Static, fields, name ) {
        var options = Static._schema[ name ]
          , fieldDefinition = {};

        // Allow direct syntax
        if ( typeof options !== 'object' || options instanceof Array ) {
            options = {
                type: options
            }
        }

        // Handle array of "Something"
        if ( options.type instanceof Array || options.type === Array ) {
            options.of = ( options.type.length > 0 && options.type[ 0 ] !== undefined ) ? options.type[ 0 ] : String;
            options.type = Array;
        }

        // Get the type
        fieldDefinition.type = this.getFieldType( Static, options );

        // Handle options
        [ 'allowNull', 'primaryKey', 'autoIncrement', 'unique', 'default', 'comment' ].forEach(function( optionName ) {
            if ( options[ optionName ] !== undefined ) {
                if ( optionName === 'primaryKey' ) {
                    Static.primaryKey = name;
                }

                fieldDefinition[ optionName === 'default' ? 'defaultValue' : optionName ] = options[ optionName ];
            }
        });

        fields[ name ] = fieldDefinition;
    },

    getFieldType: function( Static, options ) {
        var field;

        switch( options.type ) {

        case Number:
            field = this.numberType( options );
            break;
        case String:
            field = Sequelize.STRING;
            break;
        case Boolean:
            field = Sequelize.BOOLEAN;
            break;
        case Date:
            field = Sequelize.DATE;
            break;
        case Array:
            field = options.of ? Sequelize.ARRAY( this.getFieldType( Static, { type: options.of } ) ) : Sequelize.ARRAY( Sequelize.STRING );
            break;
        case Buffer:
            field = Sequelize.STRING.BINARY;
            break;
        case Model.Types.ENUM:
            field = Sequelize.ENUM( options.values );
            break;
        case Model.Types.BIGINT:
            field = this.bigIntType( options );
            break;
        case Model.Types.FLOAT:
            field = this.floatType( options );
            break;
        case Model.Types.DECIMAL:
            field = this.decimalType( options );
            break;
        case Model.Types.TEXT:
            field = Sequelize.TEXT;
            break;
        case undefined:
            throw new Error( [ 'You must define the type of field that', '"' + name + '"', 'is on the', '"' + Static.name + '" model' ].join( ' ' ) );
        default:
            throw new Error( [ 'You must define a valid type for the field named', '"' + name + '"', 'on the', '"' + Static.name + '" model' ].join( ' ' ) );
        }

        return field;
    },

    numberType: function( options ) {
        var field = !!options.length ? Sequelize.INTEGER( options.length ) : Sequelize.INTEGER;
        if ( !!options.unsigned && !!options.zerofill ) {
            field = field.UNSIGNED.ZEROFILL;
        } else if ( !!options.unsigned && !options.zerofill ) {
            field = field.UNSIGNED;
        } else if ( !options.unsigned && !!options.zerofill ) {
            field = field.ZEROFILL;
        }
        return field;
    },

    bigIntType: function( options ) {
        var field = !!options.length ? Sequelize.BIGINT( options.length ) : Sequelize.BIGINT;
        if ( !!options.unsigned && !!options.zerofill ) {
            field = bigint.UNSIGNED.ZEROFILL;
        } else if ( !!options.unsigned && !options.zerofill ) {
            field = bigint.UNSIGNED;
        } else if ( !options.unsigned && !!options.zerofill ) {
            field = bigint.ZEROFILL;
        }
        return field;
    },

    floatType: function( options ) {
        var field = Sequelize.FLOAT;
        if ( !!options.decimals ) {
            field = Sequelize.FLOAT( options.length, options.decimals );
        } else if ( !!options.length ) {
            field = Sequelize.FLOAT( options.length );
        }

        if ( !!options.unsigned && !!options.zerofill ) {
            field = field.UNSIGNED.ZEROFILL;
        } else if ( !!options.unsigned && !options.zerofill ) {
            field = field.UNSIGNED;
        } else if ( !options.unsigned && !!options.zerofill ) {
            field = field.ZEROFILL;
        }
        return field;
    },

    decimalType: function( options ) {
        var field = Sequelize.DECIMAL;
        if ( !!options.scale ) {
            field = Sequelize.DECIMAL( options.precision, options.scale );
        } else if ( !!options.precision ) {
            field = Sequelize.DECIMAL( options.precision );
        }
        return field;
    }
});<|endoftext|>


<commit_before>/*
Name:          nodejs-mollie
Description:   Node.js module to access the Mollie payments and MessageBird SMS APIs.
Source:        https://github.com/fvdm/nodejs-mollie
Feedback:      https://github.com/fvdm/nodejs-mollie/issues
License:       Public Domain / Unlicense (see UNLICENSE file)
*/

var httpreq = require ('httpreq');
var settings = {
  apikey: null,
  timeout: 5000
};

function talk (method, path, params, callback) {
  var options = {
    url: 'https://api.mollie.nl/v1' + path,
    method: method,
    parameters: params || null,
    timeout: parseInt (settings.timeout, 10) || 5000,
    headers: {
      'Accept': 'application/json',
      'Authorization': 'Bearer ' + settings.apikey,
      'User-Agent': 'mollie.js (https://www.npmjs.com/package/mollie)'
    }
  };

  httpreq.doRequest (options, function (err, res) {
    var data = res && res.body || null;
    var error = null;

    if (err) {
      error = new Error ('request failed');
      error.error = err;
      callback (error);
      return;
    }

    if (res && res.statusCode === 204) {
      callback (null, true);
      return;
    }

    try {
      data = JSON.parse (data);
    } catch (e) {
      error = new Error ('invalid response');
      error.error = e;
    }

    if (data && data.error) {
      error = new Error ('API error');
      error.error = data.error;
      error.statusCode = res && res.statusCode || null;
      data = null;
    }

    callback (error, data);
  });
}

module.exports = function (config) {
  var ckey;

  if (typeof config !== 'object') {
    return null;
  }

  for (ckey in config) {
    settings [ckey] = config [ckey];
  }

  return {
    payments: {
      get: function (id, callback) {
        talk ('GET', '/payments/' + id, {}, callback);
      },

      list: function (params, callback) {
        if (typeof params === 'function') {
          callback = params;
          params = {};
        }
        talk ('GET', '/payments', params, callback);
      },

      create: function (params, callback) {
        var key;

        if (params.metadata instanceof Object) {
          for (key in params.metadata) {
            params ['metadata[' + key + ']'] = params.metadata [key];
          }

          delete params.metadata;
        }

        talk ('POST', '/payments', params, callback);
      }
    },

    refunds: {
      list: function (paymentId, params, callback) {
        if (typeof params === 'function') {
          callback = params;
          params = {};
        }
        talk ('GET', '/payments/' + paymentId + '/refunds', params, callback);
      },

      create: function (paymentId, amount, callback) {
        var params = {};

        if (typeof amount === 'function') {
          callback = amount;
          amount = null;
        }

        if (amount) {
          params.amount = amount;
        }

        talk ('POST', '/payments/' + paymentId + '/refunds', params, callback);
      },

      delete: function (paymentId, refundId, callback) {
        talk ('DELETE', '/payments/' + paymentId + '/refunds/' + refundId, {}, callback);
      }
    },

    issuers: {
      get: function (issuerId, callback) {
        talk ('GET', '/issuers/' + issuerId, {}, callback);
      },

      list: function (params, callback) {
        if (typeof params === 'function') {
          callback = params;
          params = {};
        }
        talk ('GET', '/issuers', params, callback);
      }
    },

    methods: {
      list: function (params, callback) {
        if (typeof params === 'function') {
          callback = params;
          params = {};
        }
        talk ('GET', '/methods', params, callback);
      }
    }
  };
};

<commit_msg>Added statusCode to invalid response error<commit_after>/*
Name:          nodejs-mollie
Description:   Node.js module to access the Mollie payments and MessageBird SMS APIs.
Source:        https://github.com/fvdm/nodejs-mollie
Feedback:      https://github.com/fvdm/nodejs-mollie/issues
License:       Public Domain / Unlicense (see UNLICENSE file)
*/

var httpreq = require ('httpreq');
var settings = {
  apikey: null,
  timeout: 5000
};

function talk (method, path, params, callback) {
  var options = {
    url: 'https://api.mollie.nl/v1' + path,
    method: method,
    parameters: params || null,
    timeout: parseInt (settings.timeout, 10) || 5000,
    headers: {
      'Accept': 'application/json',
      'Authorization': 'Bearer ' + settings.apikey,
      'User-Agent': 'mollie.js (https://www.npmjs.com/package/mollie)'
    }
  };

  httpreq.doRequest (options, function (err, res) {
    var data = res && res.body || null;
    var error = null;

    if (err) {
      error = new Error ('request failed');
      error.error = err;
      callback (error);
      return;
    }

    if (res && res.statusCode === 204) {
      callback (null, true);
      return;
    }

    try {
      data = JSON.parse (data);
    } catch (e) {
      error = new Error ('invalid response');
      error.error = e;
      error.statusCode = res && res.statusCode || null;
    }

    if (data && data.error) {
      error = new Error ('API error');
      error.error = data.error;
      error.statusCode = res && res.statusCode || null;
      data = null;
    }

    callback (error, data);
  });
}

module.exports = function (config) {
  var ckey;

  if (typeof config !== 'object') {
    return null;
  }

  for (ckey in config) {
    settings [ckey] = config [ckey];
  }

  return {
    payments: {
      get: function (id, callback) {
        talk ('GET', '/payments/' + id, {}, callback);
      },

      list: function (params, callback) {
        if (typeof params === 'function') {
          callback = params;
          params = {};
        }
        talk ('GET', '/payments', params, callback);
      },

      create: function (params, callback) {
        var key;

        if (params.metadata instanceof Object) {
          for (key in params.metadata) {
            params ['metadata[' + key + ']'] = params.metadata [key];
          }

          delete params.metadata;
        }

        talk ('POST', '/payments', params, callback);
      }
    },

    refunds: {
      list: function (paymentId, params, callback) {
        if (typeof params === 'function') {
          callback = params;
          params = {};
        }
        talk ('GET', '/payments/' + paymentId + '/refunds', params, callback);
      },

      create: function (paymentId, amount, callback) {
        var params = {};

        if (typeof amount === 'function') {
          callback = amount;
          amount = null;
        }

        if (amount) {
          params.amount = amount;
        }

        talk ('POST', '/payments/' + paymentId + '/refunds', params, callback);
      },

      delete: function (paymentId, refundId, callback) {
        talk ('DELETE', '/payments/' + paymentId + '/refunds/' + refundId, {}, callback);
      }
    },

    issuers: {
      get: function (issuerId, callback) {
        talk ('GET', '/issuers/' + issuerId, {}, callback);
      },

      list: function (params, callback) {
        if (typeof params === 'function') {
          callback = params;
          params = {};
        }
        talk ('GET', '/issuers', params, callback);
      }
    },

    methods: {
      list: function (params, callback) {
        if (typeof params === 'function') {
          callback = params;
          params = {};
        }
        talk ('GET', '/methods', params, callback);
      }
    }
  };
};

<|endoftext|>


<commit_before>var config = require('./config');
var fs = require('fs');
var request = require('request');
var socketClient = null;
var socketIO = null;

module.exports = function (app, http) {
	socketIO = require('socket.io')(http);

	// Web Socket IO for sending gestures to client
	socketIO.of('/motion').on('connection', function(socket){
		socketClient = socket;
	});

	app.get('/motion/gesture', function (req, res) {
		try {
			socketClient.emit('gesture', req.query);
		}  catch(e) {}
		res.sendStatus(200);
	});

	app.get('/motion/takePhoto/:filepath', function (req, res) {
		try {
			fs.unlinkSync("public/" + req.params.filepath); // Removing current photo if found
		}
		catch(e) {}

		request(config.web.motionUrl + req.params.filepath, function(err) {
			res.sendStatus(err ? 404 : 200);
		});
	});

	app.get('/doesFileExist/:filepath', function (req, res) {
		fs.access("public/" + req.params.filepath, fs.R_OK | fs.W_OK, (err) => {
			res.sendStatus(err ? 404 : 200);
		})
	});

	app.get('/motion/uploadPhoto/:filepath', function (req, res) {
		fs.readFile("public/" + req.params.filepath, function read(err, data) {
			if (err) {
				console.log("Could not read photo: ", err);
				res.sendStatus(404);
			}

			content = data;
			request.put('https://api-content.dropbox.com/1/files_put/auto/' + req.params.filepath, {
			headers: { Authorization: 'Bearer ' + config.widget.photo.dropboxKey,  'Content-Type': 'text/plain'},
			body:content},
			function optionalCallback (err, httpResponse, bodymsg) {
				if (err) {
					console.log("Could not upload to dropbox: ", err);
					res.sendStatus(400);
				}

				console.log("Uploaded photo to dropbox: ", bodymsg);
				res.sendStatus(200);
			});
		});
	});
}<commit_msg>Replace arrow function to a basic one for compatibility<commit_after>var config = require('./config');
var fs = require('fs');
var request = require('request');
var socketClient = null;
var socketIO = null;

module.exports = function (app, http) {
	socketIO = require('socket.io')(http);

	// Web Socket IO for sending gestures to client
	socketIO.of('/motion').on('connection', function(socket){
		socketClient = socket;
	});

	app.get('/motion/gesture', function (req, res) {
		try {
			socketClient.emit('gesture', req.query);
		}  catch(e) {}
		res.sendStatus(200);
	});

	app.get('/motion/takePhoto/:filepath', function (req, res) {
		try {
			fs.unlinkSync("public/" + req.params.filepath); // Removing current photo if found
		}
		catch(e) {}

		request(config.web.motionUrl + req.params.filepath, function(err) {
			res.sendStatus(err ? 404 : 200);
		});
	});

	app.get('/doesFileExist/:filepath', function (req, res) {
		fs.access("public/" + req.params.filepath, fs.R_OK | fs.W_OK, function(err) {
			res.sendStatus(err ? 404 : 200);
		})
	});

	app.get('/motion/uploadPhoto/:filepath', function (req, res) {
		fs.readFile("public/" + req.params.filepath, function read(err, data) {
			if (err) {
				console.log("Could not read photo: ", err);
				res.sendStatus(404);
			}

			content = data;
			request.put('https://api-content.dropbox.com/1/files_put/auto/' + req.params.filepath, {
			headers: { Authorization: 'Bearer ' + config.widget.photo.dropboxKey,  'Content-Type': 'text/plain'},
			body:content},
			function optionalCallback (err, httpResponse, bodymsg) {
				if (err) {
					console.log("Could not upload to dropbox: ", err);
					res.sendStatus(400);
				}

				console.log("Uploaded photo to dropbox: ", bodymsg);
				res.sendStatus(200);
			});
		});
	});
}
<|endoftext|>


<commit_before>// Returns _$ with proper context and _$.api
var _$_decorated = function(context) {
  var decorated = context._$.bind(context);
  decorated.api = context.api;
  decorated.routes = context.routes;
  decorated.template = context.template;
  return decorated;
}

// $ (if not jQuery) is just a thin wrapper around doc.qSA
if (typeof(jQuery) == "undefined") {
  window["$"] = function(selector) {
    return [].slice.call(
      document.querySelectorAll(selector)
    );
  }.bind(this)
}

String.prototype.interpolate = function (o) {
  return this.replace(/#\{(.+?)\}/g,
    function (a, b) {
      var r = o[b];
      return typeof r === 'string' || typeof r === 'number' ? r : a;
    }
  );
};

Object.deepExtend = function(destination, source) {
  for (var property in source) {
    if (source[property] && source[property].constructor &&
     source[property].constructor === Object) {
      destination[property] = destination[property] || {};
      arguments.callee(destination[property], source[property]);
    } else {
      destination[property] = source[property];
    }
  }
  return destination;
};

// Mandatory object for storing your components
//    var m$.my_component = new Mozart();
window["m$"] = {}

// Create a new component with
//    var m$.my_component = new Mozart();
var Mozart = function() {
  this.scope = undefined;

  this.api    = {};
  this.routes = {};
  this.events = {};
  this.template = {}
  this.template.clone = function(id) {
    var template = $(this.scope + " template#" + id)[0],
        parent = document.createElement("div");

    if (!template) {
      return console.error("Could not find <template> with id " + id + " in " + this.scope);
    }

    parent.append(document.importNode(template.content, true));
    return (typeof(jQuery) == "undefined") ? parent.childNodes[0] : $(parent.childNodes[0]);
  }.bind(this);
};

Mozart.prototype._$ = function(selector) {
  var subscope = selector ? " " + selector : "";
  return $(this.scope + subscope);
};

Mozart.prototype.set_api = function(apis) {
  // Bind API functions
  for (var api_key in apis) {
    var self = this;
    this.api[api_key] = function(options) {
      return this.api_fn.call(self, _$_decorated(self), options);
    }.bind({api_fn: apis[api_key]});
  }
};

Mozart.prototype.set_routes = function(routes) {
  // Interpolate routes
  for (var route_key in routes) {
    var route_data = JSON.parse(JSON.stringify(routes[route_key]));
    this.routes[route_key] = function(options) {
      route_data.url = route_data.url.interpolate(options)
      route_data.data = route_data.data || {}
      route_data.data = Object.deepExtend(route_data.data, options["data"]);
      return route_data;
    }.bind(this)
  }
};

Mozart.prototype.set_events = function(fn) { this.events = fn; }

// Initialize all components. Don't call this until after all your component code.
// Allows any cross talk between components to happen only when all components have loaded.
Mozart.init = function() {
  // Find all components
  for (var component_name in window["m$"]) {
    var component = m$[component_name],
        _$ = _$_decorated(component);

    if (!component instanceof Mozart) { return; }
    component.scope = '[data-component~="' + component_name + '"]';
    component.events.call(component, _$);
  }
}
<commit_msg>Using correct default type for events<commit_after>// Returns _$ with proper context and _$.api
var _$_decorated = function(context) {
  var decorated = context._$.bind(context);
  decorated.api = context.api;
  decorated.routes = context.routes;
  decorated.template = context.template;
  return decorated;
}

// $ (if not jQuery) is just a thin wrapper around doc.qSA
if (typeof(jQuery) == "undefined") {
  window["$"] = function(selector) {
    return [].slice.call(
      document.querySelectorAll(selector)
    );
  }.bind(this)
}

String.prototype.interpolate = function (o) {
  return this.replace(/#\{(.+?)\}/g,
    function (a, b) {
      var r = o[b];
      return typeof r === 'string' || typeof r === 'number' ? r : a;
    }
  );
};

Object.deepExtend = function(destination, source) {
  for (var property in source) {
    if (source[property] && source[property].constructor &&
     source[property].constructor === Object) {
      destination[property] = destination[property] || {};
      arguments.callee(destination[property], source[property]);
    } else {
      destination[property] = source[property];
    }
  }
  return destination;
};

// Mandatory object for storing your components
//    var m$.my_component = new Mozart();
window["m$"] = {}

// Create a new component with
//    var m$.my_component = new Mozart();
var Mozart = function() {
  this.scope = undefined;

  this.api    = {};
  this.routes = {};
  this.events = new Function;
  this.template = {}
  this.template.clone = function(id) {
    var template = $(this.scope + " template#" + id)[0],
        parent = document.createElement("div");

    if (!template) {
      return console.error("Could not find <template> with id " + id + " in " + this.scope);
    }

    parent.append(document.importNode(template.content, true));
    return (typeof(jQuery) == "undefined") ? parent.childNodes[0] : $(parent.childNodes[0]);
  }.bind(this);
};

Mozart.prototype._$ = function(selector) {
  var subscope = selector ? " " + selector : "";
  return $(this.scope + subscope);
};

Mozart.prototype.set_api = function(apis) {
  // Bind API functions
  for (var api_key in apis) {
    var self = this;
    this.api[api_key] = function(options) {
      return this.api_fn.call(self, _$_decorated(self), options);
    }.bind({api_fn: apis[api_key]});
  }
};

Mozart.prototype.set_routes = function(routes) {
  // Interpolate routes
  for (var route_key in routes) {
    var route_data = JSON.parse(JSON.stringify(routes[route_key]));
    this.routes[route_key] = function(options) {
      route_data.url = route_data.url.interpolate(options)
      route_data.data = route_data.data || {}
      route_data.data = Object.deepExtend(route_data.data, options["data"]);
      return route_data;
    }.bind(this)
  }
};

Mozart.prototype.set_events = function(fn) { this.events = fn; }

// Initialize all components. Don't call this until after all your component code.
// Allows any cross talk between components to happen only when all components have loaded.
Mozart.init = function() {
  // Find all components
  for (var component_name in window["m$"]) {
    var component = m$[component_name],
        _$ = _$_decorated(component);

    if (!component instanceof Mozart) { return; }
    component.scope = '[data-component~="' + component_name + '"]';
    component.events.call(component, _$);
  }
}
<|endoftext|>


<commit_before>
var log = require("./log")
  , path = require("path")
  , hasSSL = false
try {
  hasSSL = !!(process.binding("crypto") && require("crypto"))
} catch (ex) {}

if (!process.execPath) {
  process.execPath = path.join(process.installPrefix, "bin", "node")
}
var stdio = process.binding("stdio")
module.exports =
  { "auto-activate" : "always"
  , "update-dependents" : true
  , "auto-deactivate" : true
  , "tar" : process.env.TAR || "tar"
  , "gzipbin" : process.env.GZIPBIN || "gzip"
  , tag : "latest"
  , proxy : process.env.http_proxy || null
  , root : path.join(process.execPath, "..", "..", "lib", "node")
  , globalconfig : path.join(process.execPath, "..", "..", "etc", "npmrc")
  , userconfig : path.join(process.env.HOME, ".npmrc")
  , binroot : path.dirname(process.execPath)
  , dev : false
  , loglevel : "info"
  , manroot : path.join(process.execPath, "..", "..", "share", "man")
  , editor : process.env.EDITOR
  , tmproot : (process.env.TMPDIR || "/tmp")
  , _exit : true
  // a stream or a file descriptor of a socket
  // a file fd will sorta work too, but not awesomely.
  , logfd : stdio.stderrFD
  , outfd : stdio.stdoutFD
  , color : true
  , recursive : false
  , force : false
  , prune : undefined // if set to boolean false, then that means "never"
  , listopts: ""
  , "must-install" : true
  , "browser" : "open"
  // show the description in npm ls
  , description : true
  //
  // TODO: Fix when node's SSL client can upload properly.
  // , registry : hasSSL ? "https://registry.npmjs.org/"
  //            : "http://registry.npmjs.org/"
  //
  , registry : "http://registry.npmjs.org/"
  }
<commit_msg>sort default configs<commit_after>
var log = require("./log")
  , path = require("path")
  , hasSSL = false
  , sslWorks = false
  , semver = require("./semver")

try {
  hasSSL = !!(process.binding("crypto") && require("crypto"))
} catch (ex) {}

//
// TODO: Change this version when node's SSL client can upload properly.
//
if (hasSSL) {
  sslWorks = require("./semver").gt(process.version, "9999.9999.9999-9999")
}

if (!process.execPath) {
  process.execPath = path.join(process.installPrefix, "bin", "node")
}
var stdio = process.binding("stdio")

module.exports =
  { "auto-activate" : "always"
  , "auto-deactivate" : true
  , binroot : path.dirname(process.execPath)
  , browser : "open"
  , color : true
  , description : true
  , dev : false
  , editor : process.env.EDITOR
  , force : false
  , globalconfig : path.join(process.execPath, "..", "..", "etc", "npmrc")
  , gzipbin : process.env.GZIPBIN || "gzip"
  , listopts: ""
  , logfd : stdio.stderrFD
  , loglevel : "info"
  , manroot : path.join(process.execPath, "..", "..", "share", "man")
  , "must-install" : true
  , outfd : stdio.stdoutFD
  , proxy : process.env.http_proxy || null
  , prune : undefined // if set to boolean false, then that means "never"
  , recursive : false
  , registry : "http"+(sslWorks ? "s" : "")+"://registry.npmjs.org/"
  , root : path.join(process.execPath, "..", "..", "lib", "node")
  , tag : "latest"
  , tar : process.env.TAR || "tar"
  , tmproot : (process.env.TMPDIR || "/tmp")
  , "update-dependents" : true
  , userconfig : path.join(process.env.HOME, ".npmrc")
  , _exit : true
  }
<|endoftext|>


<commit_before>var fs = require( 'fs' )
  , path = require( 'path' )
  , appRoot = path.resolve( [ __dirname, '..', '..' ].join( path.sep ) )
  , packageJson = require( appRoot + '/package.json' );

// Use this function to get module paths
module.exports = function() {
    var paths = []
      , args = [].slice.call(arguments);

    packageJson.bundledDependencies.forEach( function( name ) {
    	var modulePath = [ 'modules', name ].concat( args ).join( path.sep );
    	if ( fs.existsSync( modulePath ) || ( /(.*)+\/\*/.test( modulePath ) && fs.existsSync( RegExp.$1 + '/' ) ) ) {
        	paths.push( modulePath );
        }
    });

    return paths;
}<commit_msg>fixing issue #96, the regex used to match files is hanging in Windows 7 x64, so changing to use path.dirname instead<commit_after>var fs = require( 'fs' )
  , path = require( 'path' )
  , appRoot = path.resolve( [ __dirname, '..', '..' ].join( path.sep ) )
  , packageJson = require( appRoot + '/package.json' );

// Use this function to get module paths
module.exports = function() {
    var paths = []
      , args = [].slice.call(arguments);

    packageJson.bundledDependencies.forEach( function( name ) {
        var modulePath = [ 'modules', name ].concat( args ).join( path.sep );
        if ( fs.existsSync( modulePath ) || fs.existsSync( path.dirname( modulePath ) ) ) {
            paths.push( modulePath );
        }
    });

    return paths;
}<|endoftext|>


<commit_before>import React from 'react';
import {graphql, createRefetchContainer} from 'react-relay';
import PropTypes from 'prop-types';
import cx from 'classnames';
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';

import PrTimelineContainer from '../controllers/pr-timeline-controller';
import PrStatusesView from '../views/pr-statuses-view';
import Octicon from '../atom/octicon';
import IssueishBadge from '../views/issueish-badge';
import GithubDotcomMarkdown from '../views/github-dotcom-markdown';
import EmojiReactionsView from '../views/emoji-reactions-view';
import PeriodicRefresher from '../periodic-refresher';
import {EnableableOperationPropType} from '../prop-types';
import {autobind} from '../helpers';
import {addEvent} from '../reporter-proxy';
import PrCommitsView from '../views/pr-commits-view';

function createCheckoutState(name) {
  return function(cases) {
    return cases[name] || cases.default;
  };
}

export const checkoutStates = {
  HIDDEN: createCheckoutState('hidden'),
  DISABLED: createCheckoutState('disabled'),
  BUSY: createCheckoutState('busy'),
  CURRENT: createCheckoutState('current'),
};

export class BarePullRequestDetailView extends React.Component {
  static propTypes = {
    relay: PropTypes.shape({
      refetch: PropTypes.func.isRequired,
    }),
    switchToIssueish: PropTypes.func.isRequired,
    checkoutOp: EnableableOperationPropType.isRequired,
    repository: PropTypes.shape({
      id: PropTypes.string.isRequired,
      name: PropTypes.string.isRequired,
      owner: PropTypes.shape({
        login: PropTypes.string,
      }),
    }),
    pullRequest: PropTypes.shape({
      __typename: PropTypes.string.isRequired,
      id: PropTypes.string.isRequired,
      title: PropTypes.string,
      countedCommits: PropTypes.shape({
        totalCount: PropTypes.number.isRequired,
      }).isRequired,
      isCrossRepository: PropTypes.bool,
      changedFiles: PropTypes.number.isRequired,
      url: PropTypes.string.isRequired,
      bodyHTML: PropTypes.string,
      number: PropTypes.number,
      state: PropTypes.oneOf([
        'OPEN', 'CLOSED', 'MERGED',
      ]).isRequired,
      author: PropTypes.shape({
        login: PropTypes.string.isRequired,
        avatarUrl: PropTypes.string.isRequired,
        url: PropTypes.string.isRequired,
      }).isRequired,
      reactionGroups: PropTypes.arrayOf(
        PropTypes.shape({
          content: PropTypes.string.isRequired,
          users: PropTypes.shape({
            totalCount: PropTypes.number.isRequired,
          }).isRequired,
        }),
      ).isRequired,
    }).isRequired,
  }

  state = {
    refreshing: false,
  }

  constructor(props) {
    super(props);
    autobind(this, 'handleRefreshClick', 'refresh', 'renderPullRequestBody', 'recordOpenInBrowserEvent');
  }

  componentDidMount() {
    this.refresher = new PeriodicRefresher(BarePullRequestDetailView, {
      interval: () => 5 * 60 * 1000,
      getCurrentId: () => this.props.pullRequest.id,
      refresh: this.refresh,
      minimumIntervalPerId: 2 * 60 * 1000,
    });
    // auto-refresh disabled for now until pagination is handled
    // this.refresher.start();
  }

  componentWillUnmount() {
    this.refresher.destroy();
  }

  renderPrMetadata(pullRequest, repo) {
    return (

          {pullRequest.author.login} wants to merge{' '}
          {pullRequest.countedCommits.totalCount} commits and{' '}
          {pullRequest.changedFiles} changed files into{' '}
          {pullRequest.isCrossRepository ?
            `${repo.owner.login}/${pullRequest.baseRefName}` : pullRequest.baseRefName} from{' '}
          {pullRequest.isCrossRepository ?
            `${pullRequest.author.login}/${pullRequest.headRefName}` : pullRequest.headRefName}

    );
  }

  renderPullRequestBody(pullRequest, childProps) {
    return (
      <Tabs>
        <TabList className="github-IssueishDetailView-tablist">
          <Tab className="github-IssueishDetailView-tab">
            <Octicon icon="info" className="github-IssueishDetailView-tab-icon" />Overview</Tab>
          <Tab className="github-IssueishDetailView-tab">
            <Octicon icon="checklist" className="github-IssueishDetailView-tab-icon" />
            Build Status
          </Tab>
          <Tab className="github-IssueishDetailView-tab">
            <Octicon icon="git-commit"
              className="github-IssueishDetailView-tab-icon"
            />
              Commits
          </Tab>
        </TabList>
        {/* 'Files Changed' and 'Reviews' tabs to be added in the future. */}

        {/* overview */}
        <TabPanel>
          <GithubDotcomMarkdown
            html={pullRequest.bodyHTML || 'No description provided.'}
            switchToIssueish={this.props.switchToIssueish}
          />
          <EmojiReactionsView reactionGroups={pullRequest.reactionGroups} />
          <PrTimelineContainer
            {...childProps}
            switchToIssueish={this.props.switchToIssueish}
          />

        </TabPanel>

        {/* build status */}
        <TabPanel>

            <PrStatusesView pullRequest={pullRequest} displayType="full" />

        </TabPanel>

        {/* commits */}
        <TabPanel>
          <PrCommitsView pullRequest={pullRequest} />
        </TabPanel>
      </Tabs>
    );
  }

  render() {
    console.log(this.props);
    const repo = this.props.repository;
    const pullRequest = this.props.pullRequest;
    const childProps = {
      issue: pullRequest.__typename === 'Issue' ? pullRequest : null,
      pullRequest: pullRequest.__typename === 'PullRequest' ? pullRequest : null,
    };

    return (

                {pullRequest.title}

                <Octicon
                  icon="repo-sync"
                  className={cx('github-IssueishDetailView-headerRefreshButton', {refreshing: this.state.refreshing})}
                  onClick={this.handleRefreshClick}
                />

            {this.renderPrMetadata(pullRequest, repo)}

                <IssueishBadge className="github-IssueishDetailView-headerBadge"
                  type={pullRequest.__typename}
                  state={pullRequest.state}
                />

                  {repo.owner.login}/{repo.name}#{pullRequest.number}

                  <PrStatusesView pullRequest={pullRequest} displayType="check" />

                {this.renderCheckoutButton()}

          {this.renderPullRequestBody(pullRequest, childProps)}

            {repo.owner.login}/{repo.name}#{pullRequest.number}

    );
  }

  renderCheckoutButton() {
    const {checkoutOp} = this.props;
    let extraClass = null;
    let buttonText = 'Checkout';
    let buttonTitle = null;

    if (!checkoutOp.isEnabled()) {
      buttonTitle = checkoutOp.getMessage();
      const reason = checkoutOp.why();
      if (reason({hidden: true, default: false})) {
        return null;
      }

      buttonText = reason({
        current: 'Checked out',
        default: 'Checkout',
      });

      extraClass = 'github-IssueishDetailView-checkoutButton--' + reason({
        disabled: 'disabled',
        busy: 'busy',
        current: 'current',
      });
    }

    const classNames = cx('btn', 'btn-primary', 'github-IssueishDetailView-checkoutButton', extraClass);
    return (
      <button
        className={classNames}
        disabled={!checkoutOp.isEnabled()}
        title={buttonTitle}
        onClick={() => checkoutOp.run()}>
        {buttonText}
      </button>
    );
  }

  handleRefreshClick(e) {
    e.preventDefault();
    this.refresher.refreshNow(true);
  }

  recordOpenInBrowserEvent() {
    addEvent('open-pull-request-in-browser', {package: 'github', component: this.constructor.name});
  }

  refresh() {
    if (this.state.refreshing) {
      return;
    }

    this.setState({refreshing: true});
    this.props.relay.refetch({
      repoId: this.props.repository.id,
      issueishId: this.props.pullRequest.id,
      timelineCount: 100,
      timelineCursor: null,
      commitCount: 100,
      commitCursor: null,
    }, null, () => {
      this.setState({refreshing: false});
    }, {force: true});
  }
}

export default createRefetchContainer(BarePullRequestDetailView, {
  repository: graphql`
    fragment prDetailView_repository on Repository {
      id
      name
      owner {
        login
      }
    }
  `,

  pullRequest: graphql`
    fragment prDetailView_pullRequest on PullRequest
    @argumentDefinitions(
      timelineCount: {type: "Int!"},
      timelineCursor: {type: "String"},
      commitCount: {type: "Int!"},
      commitCursor: {type: "String"},
    ) {
      __typename

      ... on Node {
        id
      }

      ... on PullRequest {
        isCrossRepository
        changedFiles
        ...prCommitsView_pullRequest @arguments(commitCount: $commitCount, commitCursor: $commitCursor)
        countedCommits: commits {
          totalCount
        }
        ...prStatusesView_pullRequest
        state number title bodyHTML baseRefName headRefName
        author {
          login avatarUrl
          ... on User { url }
          ... on Bot { url }
        }

        ...prTimelineController_pullRequest @arguments(timelineCount: $timelineCount, timelineCursor: $timelineCursor)
      }

      ... on UniformResourceLocatable { url }

      ... on Reactable {
        reactionGroups {
          content users { totalCount }
        }
      }
    }
  `,
}, graphql`
  query prDetailViewRefetchQuery
  (
    $repoId: ID!,
    $issueishId: ID!,
    $timelineCount: Int!,
    $timelineCursor: String,
    $commitCount: Int!,
    $commitCursor: String
  ) {
    repository:node(id: $repoId) {
      ...prDetailView_repository @arguments(
        timelineCount: $timelineCount,
        timelineCursor: $timelineCursor
      )
    }

    pullRequest:node(id: $issueishId) {
      ...prDetailView_pullRequest @arguments(
        timelineCount: $timelineCount,
        timelineCursor: $timelineCursor,
        commitCount: $commitCount,
        commitCursor: $commitCursor
      )
    }
  }
`);
<commit_msg>remove `childProps` from `PullRequestDetailView`<commit_after>import React from 'react';
import {graphql, createRefetchContainer} from 'react-relay';
import PropTypes from 'prop-types';
import cx from 'classnames';
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';

import PrTimelineContainer from '../controllers/pr-timeline-controller';
import PrStatusesView from '../views/pr-statuses-view';
import Octicon from '../atom/octicon';
import IssueishBadge from '../views/issueish-badge';
import GithubDotcomMarkdown from '../views/github-dotcom-markdown';
import EmojiReactionsView from '../views/emoji-reactions-view';
import PeriodicRefresher from '../periodic-refresher';
import {EnableableOperationPropType} from '../prop-types';
import {autobind} from '../helpers';
import {addEvent} from '../reporter-proxy';
import PrCommitsView from '../views/pr-commits-view';

function createCheckoutState(name) {
  return function(cases) {
    return cases[name] || cases.default;
  };
}

export const checkoutStates = {
  HIDDEN: createCheckoutState('hidden'),
  DISABLED: createCheckoutState('disabled'),
  BUSY: createCheckoutState('busy'),
  CURRENT: createCheckoutState('current'),
};

export class BarePullRequestDetailView extends React.Component {
  static propTypes = {
    relay: PropTypes.shape({
      refetch: PropTypes.func.isRequired,
    }),
    switchToIssueish: PropTypes.func.isRequired,
    checkoutOp: EnableableOperationPropType.isRequired,
    repository: PropTypes.shape({
      id: PropTypes.string.isRequired,
      name: PropTypes.string.isRequired,
      owner: PropTypes.shape({
        login: PropTypes.string,
      }),
    }),
    pullRequest: PropTypes.shape({
      __typename: PropTypes.string.isRequired,
      id: PropTypes.string.isRequired,
      title: PropTypes.string,
      countedCommits: PropTypes.shape({
        totalCount: PropTypes.number.isRequired,
      }).isRequired,
      isCrossRepository: PropTypes.bool,
      changedFiles: PropTypes.number.isRequired,
      url: PropTypes.string.isRequired,
      bodyHTML: PropTypes.string,
      number: PropTypes.number,
      state: PropTypes.oneOf([
        'OPEN', 'CLOSED', 'MERGED',
      ]).isRequired,
      author: PropTypes.shape({
        login: PropTypes.string.isRequired,
        avatarUrl: PropTypes.string.isRequired,
        url: PropTypes.string.isRequired,
      }).isRequired,
      reactionGroups: PropTypes.arrayOf(
        PropTypes.shape({
          content: PropTypes.string.isRequired,
          users: PropTypes.shape({
            totalCount: PropTypes.number.isRequired,
          }).isRequired,
        }),
      ).isRequired,
    }).isRequired,
  }

  state = {
    refreshing: false,
  }

  constructor(props) {
    super(props);
    autobind(this, 'handleRefreshClick', 'refresh', 'renderPullRequestBody', 'recordOpenInBrowserEvent');
  }

  componentDidMount() {
    this.refresher = new PeriodicRefresher(BarePullRequestDetailView, {
      interval: () => 5 * 60 * 1000,
      getCurrentId: () => this.props.pullRequest.id,
      refresh: this.refresh,
      minimumIntervalPerId: 2 * 60 * 1000,
    });
    // auto-refresh disabled for now until pagination is handled
    // this.refresher.start();
  }

  componentWillUnmount() {
    this.refresher.destroy();
  }

  renderPrMetadata(pullRequest, repo) {
    return (

          {pullRequest.author.login} wants to merge{' '}
          {pullRequest.countedCommits.totalCount} commits and{' '}
          {pullRequest.changedFiles} changed files into{' '}
          {pullRequest.isCrossRepository ?
            `${repo.owner.login}/${pullRequest.baseRefName}` : pullRequest.baseRefName} from{' '}
          {pullRequest.isCrossRepository ?
            `${pullRequest.author.login}/${pullRequest.headRefName}` : pullRequest.headRefName}

    );
  }

  renderPullRequestBody(pullRequest) {
    return (
      <Tabs>
        <TabList className="github-IssueishDetailView-tablist">
          <Tab className="github-IssueishDetailView-tab">
            <Octicon icon="info" className="github-IssueishDetailView-tab-icon" />Overview</Tab>
          <Tab className="github-IssueishDetailView-tab">
            <Octicon icon="checklist" className="github-IssueishDetailView-tab-icon" />
            Build Status
          </Tab>
          <Tab className="github-IssueishDetailView-tab">
            <Octicon icon="git-commit"
              className="github-IssueishDetailView-tab-icon"
            />
              Commits
          </Tab>
        </TabList>
        {/* 'Files Changed' and 'Reviews' tabs to be added in the future. */}

        {/* overview */}
        <TabPanel>
          <GithubDotcomMarkdown
            html={pullRequest.bodyHTML || 'No description provided.'}
            switchToIssueish={this.props.switchToIssueish}
          />
          <EmojiReactionsView reactionGroups={pullRequest.reactionGroups} />
          <PrTimelineContainer
            pullRequest={pullRequest}
            switchToIssueish={this.props.switchToIssueish}
          />

        </TabPanel>

        {/* build status */}
        <TabPanel>

            <PrStatusesView pullRequest={pullRequest} displayType="full" />

        </TabPanel>

        {/* commits */}
        <TabPanel>
          <PrCommitsView pullRequest={pullRequest} />
        </TabPanel>
      </Tabs>
    );
  }

  render() {
    const repo = this.props.repository;
    const pullRequest = this.props.pullRequest;

    return (

                {pullRequest.title}

                <Octicon
                  icon="repo-sync"
                  className={cx('github-IssueishDetailView-headerRefreshButton', {refreshing: this.state.refreshing})}
                  onClick={this.handleRefreshClick}
                />

            {this.renderPrMetadata(pullRequest, repo)}

                <IssueishBadge className="github-IssueishDetailView-headerBadge"
                  type={pullRequest.__typename}
                  state={pullRequest.state}
                />

                  {repo.owner.login}/{repo.name}#{pullRequest.number}

                  <PrStatusesView pullRequest={pullRequest} displayType="check" />

                {this.renderCheckoutButton()}

          {this.renderPullRequestBody(pullRequest)}

            {repo.owner.login}/{repo.name}#{pullRequest.number}

    );
  }

  renderCheckoutButton() {
    const {checkoutOp} = this.props;
    let extraClass = null;
    let buttonText = 'Checkout';
    let buttonTitle = null;

    if (!checkoutOp.isEnabled()) {
      buttonTitle = checkoutOp.getMessage();
      const reason = checkoutOp.why();
      if (reason({hidden: true, default: false})) {
        return null;
      }

      buttonText = reason({
        current: 'Checked out',
        default: 'Checkout',
      });

      extraClass = 'github-IssueishDetailView-checkoutButton--' + reason({
        disabled: 'disabled',
        busy: 'busy',
        current: 'current',
      });
    }

    const classNames = cx('btn', 'btn-primary', 'github-IssueishDetailView-checkoutButton', extraClass);
    return (
      <button
        className={classNames}
        disabled={!checkoutOp.isEnabled()}
        title={buttonTitle}
        onClick={() => checkoutOp.run()}>
        {buttonText}
      </button>
    );
  }

  handleRefreshClick(e) {
    e.preventDefault();
    this.refresher.refreshNow(true);
  }

  recordOpenInBrowserEvent() {
    addEvent('open-pull-request-in-browser', {package: 'github', component: this.constructor.name});
  }

  refresh() {
    if (this.state.refreshing) {
      return;
    }

    this.setState({refreshing: true});
    this.props.relay.refetch({
      repoId: this.props.repository.id,
      issueishId: this.props.pullRequest.id,
      timelineCount: 100,
      timelineCursor: null,
      commitCount: 100,
      commitCursor: null,
    }, null, () => {
      this.setState({refreshing: false});
    }, {force: true});
  }
}

export default createRefetchContainer(BarePullRequestDetailView, {
  repository: graphql`
    fragment prDetailView_repository on Repository {
      id
      name
      owner {
        login
      }
    }
  `,

  pullRequest: graphql`
    fragment prDetailView_pullRequest on PullRequest
    @argumentDefinitions(
      timelineCount: {type: "Int!"},
      timelineCursor: {type: "String"},
      commitCount: {type: "Int!"},
      commitCursor: {type: "String"},
    ) {
      __typename

      ... on Node {
        id
      }

      ... on PullRequest {
        isCrossRepository
        changedFiles
        ...prCommitsView_pullRequest @arguments(commitCount: $commitCount, commitCursor: $commitCursor)
        countedCommits: commits {
          totalCount
        }
        ...prStatusesView_pullRequest
        state number title bodyHTML baseRefName headRefName
        author {
          login avatarUrl
          ... on User { url }
          ... on Bot { url }
        }

        ...prTimelineController_pullRequest @arguments(timelineCount: $timelineCount, timelineCursor: $timelineCursor)
      }

      ... on UniformResourceLocatable { url }

      ... on Reactable {
        reactionGroups {
          content users { totalCount }
        }
      }
    }
  `,
}, graphql`
  query prDetailViewRefetchQuery
  (
    $repoId: ID!,
    $issueishId: ID!,
    $timelineCount: Int!,
    $timelineCursor: String,
    $commitCount: Int!,
    $commitCursor: String
  ) {
    repository:node(id: $repoId) {
      ...prDetailView_repository @arguments(
        timelineCount: $timelineCount,
        timelineCursor: $timelineCursor
      )
    }

    pullRequest:node(id: $issueishId) {
      ...prDetailView_pullRequest @arguments(
        timelineCount: $timelineCount,
        timelineCursor: $timelineCursor,
        commitCount: $commitCount,
        commitCursor: $commitCursor
      )
    }
  }
`);
<|endoftext|>


<commit_before>'use babel';
/**
  Scope Navigator
  @description Marks and sets highlighting on the current debugger scope,
    navigating to the file if necessary

  TODO: decide if we want to keep track of files that we've opened & close
    them when the ScopeNavigator is destroyed() (since ScopeNavigator will
    be active for the entirety of the debugging session)
**/

export default class ScopeNavigator {
  /**
    @constructor
    @desc initialize current position and render it if we have one, opening
      the file if necessary
    @param {Workspace} workspace
    @param {object} opts :optional
    @param {boolean} opts.usePending :default => true
    @param {object} opts.initialPosition => usually will be null
    @param {string} opts.initialPosition.file
    @param {number} opts.initialPosition.line
  **/
  constructor(workspace, opts) {
    this.workspace = workspace;
    this.options = opts;
    if (opts && opts.initialPosition
    && opts.initialPosition.file && opts.initialPosition.line)
      this.setScope(opts.initialPosition);
  }

  /**
    @name ScopeNavigator#navToScope
    @desc move focus to the file & line specified by scope, opening if
      necessary & highlighting the debugger's last known position
    @param {object} scope
    @param {string} scope.file
    @param {number} scope.line
    @returns Promise<TextEditor> holds TextEditor of current scope
  **/
  navToScope(scope) {
    if (this.curMarker) this.curMarker.destroy();

    return this.workspace.open(scope.file, {
      initialLine: scope.line,
      searchAllPanes: true,
      pending: this.options.usePending || true
    })
    .then(editor => {
      const range = editor.getBuffer().rangeForRow(scope.line, true);
      const marker = editor.markBufferRange(range, { invalidate: 'never' });
      this.curMarker = marker;

      editor.decorateMarker(marker, {
        type: 'line',
        class: 'delve-cur-scope',
        onlyNonEmpty: true
      });

      return editor;
    })
    .catch(err => atom.notifications.adddError(
      `Cannot navigate to ${scope.file}:${scope.line}`,
      { detail: err.toString(), dismissable: true }
    ));
  }

  /**
    @name ScopeNavigator#setScope
    @desc sets the scope given the current position, if given scope is null
      then it 'unsets' the current marker
    @param {object} scope
    @param {string} scope.file
    @param {number} scope.line
  **/
  setScope(scope) {
    if (scope) {
      scope.line = scope.line - 1; // correct for Atom 0 index vs Delve 1 index
      this.navToScope(scope);
    } else if (this.curMarker) this.curMarker.destroy();
  }

  destroy() {
    this.workspace = null;
    if (this.curMarker) this.curMarker.destroy();
  }
}
<commit_msg>Copy scope nav markers to new editors<commit_after>'use babel';
/**
  Scope Navigator
  @description Marks and sets highlighting on the current debugger scope,
    navigating to the file if necessary

  TODO: decide if we want to keep track of files that we've opened & close
    them when the ScopeNavigator is destroyed() (since ScopeNavigator will
    be active for the entirety of the debugging session)
**/

import { CompositeDisposable } from 'atom';

export default class ScopeNavigator {
  /**
    @constructor
    @desc initialize current position and render it if we have one, opening
      the file if necessary
    @param {Workspace} workspace
    @param {object} opts :optional
    @param {boolean} opts.usePending :default => true
    @param {object} opts.initialPosition => usually will be null
    @param {string} opts.initialPosition.file
    @param {number} opts.initialPosition.line
  **/
  constructor(workspace, opts) {
    this.disposables = new CompositeDisposable();
    this.workspace = workspace;
    this.options = opts;
    this.curMarker = null;
    this.copyMarkers = [];

    if (opts && opts.initialPosition
    && opts.initialPosition.file && opts.initialPosition.line)
      this.setScope(opts.initialPosition);
  }

  /**
    @name ScopeNavigator#navToScope
    @desc move focus to the file & line specified by scope, opening if
      necessary & highlighting the debugger's last known position
    @param {object} scope
    @param {string} scope.file
    @param {number} scope.line
    @returns Promise<TextEditor> holds TextEditor of current scope
  **/
  navToScope(scope) {
    this.clearMarkers();

    const writeScopeMarker = (editor, curLine) => {
      const range = editor.getBuffer().rangeForRow(curLine, true);
      const marker = editor.markBufferRange(range, { invalidate: 'never' });

      editor.decorateMarker(marker, {
        type: 'line',
        class: 'delve-cur-scope',
        onlyNonEmpty: true
      });

      return marker;
    };

    // Atom seems to enjoy deleting markers on all instances of a file once
    // one of them is closed
    const protectFromMistakenlyDestroyedMarker = (marker, editor, line) => {
      return marker.onDidDestroy(() => {
        if (editor.isAlive()) writeScopeMarker(editor, line);
      });
    };

    return this.workspace.open(scope.file, {
      initialLine: scope.line,
      searchAllPanes: true,
      pending: this.options.usePending || true
    })
    .then(editor => {
      this.curMarker = writeScopeMarker(editor, scope.line);
      this.disposables.add(
        protectFromMistakenlyDestroyedMarker(this.curMarker, editor, scope.line)
      );

      this.curMarkerSub = this.workspace.observeTextEditors(_editor => {
        if (_editor.getPath() !== scope.file) return;

        let markerCopy = writeScopeMarker(_editor, scope.line);
        this.disposables.add(
          protectFromMistakenlyDestroyedMarker(markerCopy, _editor, scope.line)
        );

        this.copyMarkers.push(markerCopy);
      });
    })
    .catch(err => atom.notifications.adddError(
      `Cannot navigate to ${scope.file}:${scope.line}`,
      { detail: err.toString(), dismissable: true }
    ));
  }

  /**
    @name ScopeNavigator#setScope
    @desc sets the scope given the current position, if given scope is null
      then it 'unsets' the current marker
    @param {object} scope
    @param {string} scope.file
    @param {number} scope.line
  **/
  setScope(scope) {
    if (scope) {
      scope.line = scope.line - 1; // correct for Atom 0 index vs Delve 1 index
      this.navToScope(scope);
    } else this.clearMarkers();
  }

  clearMarkers() {
    if (this.curMarker) this.curMarker.destroy();
    if (this.curMarkerSub) this.curMarkerSub.dispose();
    this.copyMarkers.forEach(copy => copy.destroy());
  }

  destroy() {
    this.workspace = null;
    this.clearMarkers();
  }
}
<|endoftext|>


<commit_before>import React from 'react';

import DiffPanel from './DiffPanel';
import CommitMessage from './CommitMessage';

import Promise from 'promise';
import Git from 'nodegit';

const gitFunctions = {

  getRepo: (path) => {
    const pathToRepo = require('path').resolve(path);

    return Git.Repository.open(pathToRepo);
  },
  /* TODO: Create a common Gitfunctions object, this function is
           the exact same as in StagingAreaPanel                 */
  createCommit: (repoPath, oid, commitMsg) => {

    let index;
    let repo;
    let pathToRepo = require('path').resolve(repoPath);
    return Git.Repository.open(pathToRepo)
      .then(function(repoResult) {
        repo = repoResult;
        return Git.Reference.nameToId(repo, "HEAD");
      })
      .then(function(head) {
        return repo.getCommit(head);
      })
      .then(function(parent) {
        const currTimeInSecs = (new Date()).getTime()/1000;
        // TODO: Replace author and committer name with a name which
        // the user chooses
        let author = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);
        let committer = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);

        return repo.createCommit("HEAD", author, committer, commitMsg, oid, [parent]);
      });
  }
};

const constStyles = {
  fontFamily: `apple-system,
          BlinkMacSystemFont,"Segoe UI",
          Roboto,Helvetica,Arial,sans-serif,
          "Apple Color Emoji","Segoe UI Emoji",
          "Segoe UI Symbol"`,
  darkRed: '#b60a0a',
  grey: '#ededed',
  blue: '#9CE8FA',
  darkBlue: '#0C6990'
};

class StageSelective extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      commitMsg: '',
    }
  }

  createCommit = (filesArr, commitMsg) => {

    if(filesArr.length === 0) {
      console.log('Please stage lines which are modified');
      return;
    }

    let repo;
    let oid;
    let promise = gitFunctions.getRepo(this.props.repo.path)
    .then( (repoResult) => {
      repo = repoResult;
    });

    const isStaged = false;
    promise = filesArr.reduce( (prevPromise, file) => {
      return prevPromise.then( () => {
        return repo.stageLines(file.path, file.lines, isStaged);
      });
    }, promise);

    promise.then(() => {
      return repo.refreshIndex();
    })
    .then((updatedIndex) => {
      return updatedIndex.writeTree();
    })
    .then(function(oidResult) {
      oid = oidResult;
    })
    //until here, all entries were added to the index and an index tree was written
    //from here, the new commit is generated using the index tree
    .then( () => {
      let innerPromise = gitFunctions.createCommit(this.props.repo.path, oid, commitMsg);
      innerPromise.done(function(commitId) {
        console.log('Commit Hash:'+commitId);
      });
    })
    .catch( (err) => {
      console.log('err:',err);
    });
  }

  collectCheckedLines = (commitMsg) => {

    const LINESTATUS = {
      UNMODIFIED: 32,
      ADDED: 43,
      DELETED: 45,
    };
    const checked = this.diffPanel.state.checked;
    const diffsArr = this.diffPanel.state.diffsArr;

    let filesArr = [];
    diffsArr.forEach( (diffFile, fileIndex) => {

      let linesArr = [];
      diffFile.diffs.forEach( (diff, diffIndex) => {
        diff.lines.forEach( (line, lineIndex) => {

          // only accept checked and modified lines
          if(checked[fileIndex][diffIndex][lineIndex] &&
          line.origin() !== LINESTATUS.UNMODIFIED)
            linesArr.push(line);
        });
      });

      if(linesArr.length !== 0) {
        filesArr.push({lines: linesArr, path: diffFile.path.old});
      }
    });

    this.createCommit(filesArr, commitMsg);
  }

  render = () => {

    const styles = {
      main: {
        overflow: 'hidden',
        display: 'flex',
        flexDirection: 'column',
        border: '4px solid'+constStyles.blue,
        borderLeft: '2px solid'+constStyles.blue,
      },
      commitmsg: {
        paddingLeft: '5%',
        paddingBottom: 15,
        width: '50%',
      },
      cover: {
        borderBottom: '4px solid'+constStyles.blue,
      },
      title: {
        padding: 10,
        color: constStyles.darkBlue,
        fontFamily: `'Oswald', sans-serif`,
        fontSize: 16,
      },
      diff: {
        overflow: 'auto'
      },
      diffProps: {
        type: {
          color: constStyles.darkBlue,
        },
        file: {
          color: constStyles.darkBlue
        },
        border: {
          color: constStyles.darkBlue
        }
      }
    };

    return (

          Selective Staging: Stage individual lines/hunk (modified files only)

            <CommitMessage buttonMsg='Commit selected lines!' commitCB={this.collectCheckedLines} />

          <DiffPanel
          {...this.props}
          showSelect={true}
          ref={(ref) => this.diffPanel = ref}
          diffStyle={styles.diffProps} />

    );
  }
}

export default StageSelective;<commit_msg>Frontend: Added a snackbar to activate when changes are committed successfully<commit_after>import React from 'react';

import Snackbar from 'material-ui/Snackbar';

import DiffPanel from './DiffPanel';
import CommitMessage from './CommitMessage';

import Promise from 'promise';
import Git from 'nodegit';

const gitFunctions = {

  getRepo: (path) => {
    const pathToRepo = require('path').resolve(path);

    return Git.Repository.open(pathToRepo);
  },
  /* TODO: Create a common Gitfunctions object, this function is
           the exact same as in StagingAreaPanel                 */
  createCommit: (repoPath, oid, commitMsg) => {

    let index;
    let repo;
    let pathToRepo = require('path').resolve(repoPath);
    return Git.Repository.open(pathToRepo)
      .then(function(repoResult) {
        repo = repoResult;
        return Git.Reference.nameToId(repo, "HEAD");
      })
      .then(function(head) {
        return repo.getCommit(head);
      })
      .then(function(parent) {
        const currTimeInSecs = (new Date()).getTime()/1000;
        // TODO: Replace author and committer name with a name which
        // the user chooses
        let author = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);
        let committer = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);

        return repo.createCommit("HEAD", author, committer, commitMsg, oid, [parent]);
      });
  }
};

const constStyles = {
  fontFamily: `apple-system,
          BlinkMacSystemFont,"Segoe UI",
          Roboto,Helvetica,Arial,sans-serif,
          "Apple Color Emoji","Segoe UI Emoji",
          "Segoe UI Symbol"`,
  darkRed: '#b60a0a',
  grey: '#ededed',
  blue: '#9CE8FA',
  darkBlue: '#0C6990'
};

class StageSelective extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      commitMsg: '',
      open: false,
    }
  }

  createCommit = (filesArr, commitMsg) => {

    if(filesArr.length === 0) {
      console.log('Please stage lines which are modified');
      return;
    }

    let repo;
    let oid;
    let promise = gitFunctions.getRepo(this.props.repo.path)
    .then( (repoResult) => {
      repo = repoResult;
    });

    const isStaged = false;
    promise = filesArr.reduce( (prevPromise, file) => {
      return prevPromise.then( () => {
        return repo.stageLines(file.path, file.lines, isStaged);
      });
    }, promise);

    promise.then(() => {
      return repo.refreshIndex();
    })
    .then((updatedIndex) => {
      return updatedIndex.writeTree();
    })
    .then(function(oidResult) {
      oid = oidResult;
    })
    //until here, all entries were added to the index and an index tree was written
    //from here, the new commit is generated using the index tree
    .then( () => {
      let innerPromise = gitFunctions.createCommit(this.props.repo.path, oid, commitMsg);
      innerPromise.done((commitId) => {
        console.log('Commit Hash:'+commitId);
        this.openSnackBar();
      });
    })
    .catch( (err) => {
      console.log('err:',err);
    });
  }

  openSnackBar = () => {
    this.setState({
      open: true,
    });
  };

  collectCheckedLines = (commitMsg) => {

    const LINESTATUS = {
      UNMODIFIED: 32,
      ADDED: 43,
      DELETED: 45,
    };
    const checked = this.diffPanel.state.checked;
    const diffsArr = this.diffPanel.state.diffsArr;

    let filesArr = [];
    diffsArr.forEach( (diffFile, fileIndex) => {

      let linesArr = [];
      diffFile.diffs.forEach( (diff, diffIndex) => {
        diff.lines.forEach( (line, lineIndex) => {

          // only accept checked and modified lines
          if(checked[fileIndex][diffIndex][lineIndex] &&
          line.origin() !== LINESTATUS.UNMODIFIED)
            linesArr.push(line);
        });
      });

      if(linesArr.length !== 0) {
        filesArr.push({lines: linesArr, path: diffFile.path.old});
      }
    });

    this.createCommit(filesArr, commitMsg);
  }

  handleRequestClose = () => {
    this.setState({
      open: false,
    });
  };

  render = () => {

    const styles = {
      main: {
        overflow: 'hidden',
        display: 'flex',
        flexDirection: 'column',
        border: '4px solid'+constStyles.blue,
        borderLeft: '2px solid'+constStyles.blue,
      },
      commitmsg: {
        paddingLeft: '5%',
        paddingBottom: 15,
        width: '50%',
      },
      cover: {
        borderBottom: '4px solid'+constStyles.blue,
      },
      title: {
        padding: 10,
        color: constStyles.darkBlue,
        fontFamily: `'Oswald', sans-serif`,
        fontSize: 16,
      },
      diff: {
        overflow: 'auto'
      },
      diffProps: {
        type: {
          color: constStyles.darkBlue,
        },
        file: {
          color: constStyles.darkBlue
        },
        border: {
          color: constStyles.darkBlue
        }
      }
    };

    return (

          Selective Staging: Stage individual lines/hunk (modified files only)

            <CommitMessage buttonMsg='Commit selected lines!' commitCB={this.collectCheckedLines} />

          <DiffPanel
          {...this.props}
          showSelect={true}
          ref={(ref) => this.diffPanel = ref}
          diffStyle={styles.diffProps} />

        <Snackbar style={{fontFamily: constStyles.fontFamily}}
          open={this.state.open}
          message="Changes committed successfully!"
          autoHideDuration={4000}
          onRequestClose={this.handleRequestClose}
        />

    );
  }
}

export default StageSelective;<|endoftext|>


<commit_before>#!/usr/bin/env node
var http = require("q-io/http")
  , collections = require('gramene-mongodb-config');

var genesURL = process.argv[2];

// read all of the unique ids from the genes collection
// to avoid suggesting them as non-unique terms when they are mentioned as an xref or something in another gene
collections.genes.mongoCollection().then(function(collection) {
  collection.find({},{_id:1}).toArray(function(err,docs) {
    if (err) throw err;
    collections.closeMongoDatabase();
    var uniqueId = {};
    docs.forEach(function(d) {
      uniqueId[d._id.toUpperCase()] = 1;
    });

    // non-unique terms get their own doc with a relevant fq field
    // build a lookup table with the non-unique ids from these
    var url = genesURL + '/query?rows=0&facet=true&facet.limit=-1&json.nl=map&facet.mincount=2&facet.field=_terms';
    console.error(url);
    http.read(url).then(function(data) {
      var term_freq = JSON.parse(data).facet_counts.facet_fields._terms;
      var n=0;
      for (var term in term_freq) {
        var ucTerm = term.toUpperCase();
        term_freq[ucTerm] = term_freq[term];
        if (!uniqueId.hasOwnProperty(ucTerm)) {
          var tf = term_freq[ucTerm];
          var solr = {
            category    : 'Gene',
            id          : '_term_'+ ++n,
            display_name: term,
            name        : term,
            fq_field    : '_terms',
            fq_value    : term,
            num_genes   : tf,
            relevance   : tf > 100 ? 1 : tf/100
          };
          if (n===1) console.log('[');
          else console.log(',');
          console.log(JSON.stringify(solr));
        }
      }
      // read the mongo genes docs and generate suggestions with unique values only
      require('readline').createInterface(
        {
          input: process.stdin,
          terminal: false
        }
      ).on('line', function(line) { // one JSON object per line
        var mongo = JSON.parse(line);

        console.log(',');
        console.log(JSON.stringify({
          category : 'Gene',
          fq_field : 'id',
          fq_value : mongo._id,
          id       : mongo._id,
          display_name : mongo._id,
          num_genes : 1,
          relevance : 0,
          taxon_id : mongo.taxon_id
        }));

        // add uniquely identifying xrefs
        var xref_h = {};
        for (var db in mongo.xrefs) {
          if (!collections.hasOwnProperty(db)) {
            mongo.xrefs[db].forEach(function(xr) {
              xref_h[xr]=db;
            });
          }
        }
        Object.keys(xref_h).filter(function(xr) {
          return !term_freq[xr.toUpperCase()];
        }).forEach(function(xr) {
          console.log(',');
          console.log(JSON.stringify({
            category : 'Gene',
            fq_field : 'id',
            fq_value : mongo._id,
            id       : '_term_'+ ++n,
            xref     : xr,
            display_name : xr,
            num_genes : 1,
            relevance : 0,
            taxon_id : mongo.taxon_id
          }));
        });

        // add uniquely identifying synonyms
        if (mongo.hasOwnProperty('synonyms')) {
          mongo.synonyms.filter(function(syn) {
            return !term_freq[syn.toUpperCase()];
          }).forEach(function(syn) {
            console.log(',');
            console.log(JSON.stringify({
              category : 'Gene',
              fq_field : 'id',
              fq_value : mongo._id,
              id       : '_term_'+ ++n,
              synonym  : syn,
              display_name : syn,
              num_genes : 1,
              relevance : 0,
              taxon_id : mongo.taxon_id
            }));
          });
        }

      }).on('close', function() {
        console.log(']');
      });
    });
  });
});
<commit_msg>added genetree and biotype suggestions<commit_after>#!/usr/bin/env node
var http = require("q-io/http")
  , collections = require('gramene-mongodb-config');

var genesURL = process.argv[2];

// read all of the unique ids from the genes collection
// to avoid suggesting them as non-unique terms when they are mentioned as an xref or something in another gene
collections.genes.mongoCollection().then(function(collection) {
  collection.find({},{_id:1}).toArray(function(err,docs) {
    if (err) throw err;
    collections.closeMongoDatabase();
    var uniqueId = {};
    docs.forEach(function(d) {
      uniqueId[d._id.toUpperCase()] = 1;
    });

    // non-unique terms get their own doc with a relevant fq field
    // build a lookup table with the non-unique ids from these
    var url = genesURL + '/query?rows=0&facet=true&facet.limit=-1&json.nl=map&facet.mincount=2&facet.field=_terms';
    console.error(url);
    http.read(url).then(function(data) {
      var term_freq = JSON.parse(data).facet_counts.facet_fields._terms;
      var n=0;
      for (var term in term_freq) {
        var ucTerm = term.toUpperCase();
        term_freq[ucTerm] = term_freq[term];
        if (!uniqueId.hasOwnProperty(ucTerm)) {
          var tf = term_freq[ucTerm];
          var solr = {
            category    : 'Gene',
            id          : '_term_'+ ++n,
            display_name: term,
            name        : term,
            fq_field    : '_terms',
            fq_value    : term,
            num_genes   : tf,
            relevance   : tf > 100 ? 1 : tf/100
          };
          if (n===1) console.log('[');
          else console.log(',');
          console.log(JSON.stringify(solr));
        }
      }

      // gene tree suggestion
      var url = genesURL + '/query?rows=0&facet=true&facet.limit=-1&json.nl=map&facet.mincount=1&facet.field=grm_gene_tree';
      console.error(url);
      http.read(url).then(function(data) {
        var tree_size = JSON.parse(data).facet_counts.facet_fields.grm_gene_tree;
        for (var tree in tree_size) {
          var solr = {
            category    : 'Gene tree',
            id          : '_term_'+ ++n,
            display_name: tree,
            name        : tree,
            fq_field    : 'grm_gene_tree',
            fq_value    : tree,
            num_genes   : tree_size[tree],
            relevance   : 1
          };
          console.log(',');
          console.log(JSON.stringify(solr));
        }

        // biotype suggestion
        var url = genesURL + '/query?rows=0&facet=true&facet.limit=-1&json.nl=map&facet.mincount=1&facet.field=biotype';
        console.error(url);
        http.read(url).then(function(data) {
          var biotype_count = JSON.parse(data).facet_counts.facet_fields.biotype;
          for (var biotype in biotype_count) {
            var solr = {
              category    : 'Biotype',
              id          : '_term_'+ ++n,
              display_name: biotype,
              name        : biotype,
              fq_field    : 'biotype',
              fq_value    : biotype,
              num_genes   : biotype_count[biotype],
              relevance   : 1
            };
            console.log(',');
            console.log(JSON.stringify(solr));
          }

          // read the mongo genes docs and generate suggestions with unique values only
          require('readline').createInterface(
            {
              input: process.stdin,
              terminal: false
            }
          ).on('line', function(line) { // one JSON object per line
            var mongo = JSON.parse(line);

            console.log(',');
            console.log(JSON.stringify({
              category : 'Gene',
              fq_field : 'id',
              fq_value : mongo._id,
              id       : mongo._id,
              display_name : mongo._id,
              num_genes : 1,
              relevance : 0,
              taxon_id : mongo.taxon_id
            }));

            // add uniquely identifying xrefs
            var xref_h = {};
            for (var db in mongo.xrefs) {
              if (!collections.hasOwnProperty(db)) {
                mongo.xrefs[db].forEach(function(xr) {
                  xref_h[xr]=db;
                });
              }
            }
            Object.keys(xref_h).filter(function(xr) {
              return !term_freq[xr.toUpperCase()];
            }).forEach(function(xr) {
              console.log(',');
              console.log(JSON.stringify({
                category : 'Gene',
                fq_field : 'id',
                fq_value : mongo._id,
                id       : '_term_'+ ++n,
                xref     : xr,
                display_name : xr,
                num_genes : 1,
                relevance : 0,
                taxon_id : mongo.taxon_id
              }));
            });

            // add uniquely identifying synonyms
            if (mongo.hasOwnProperty('synonyms')) {
              mongo.synonyms.filter(function(syn) {
                return !term_freq[syn.toUpperCase()];
              }).forEach(function(syn) {
                console.log(',');
                console.log(JSON.stringify({
                  category : 'Gene',
                  fq_field : 'id',
                  fq_value : mongo._id,
                  id       : '_term_'+ ++n,
                  synonym  : syn,
                  display_name : syn,
                  num_genes : 1,
                  relevance : 0,
                  taxon_id : mongo.taxon_id
                }));
              });
            }

          }).on('close', function() {
            console.log(']');
          });
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>define(['angular'],function(angular) {

  var app = angular.module('Leaf');

  app.register.controller('setupController',['$rootScope','$scope',function($rootScope,$scope) {

  }]);

});<commit_msg>Delete setup.js<commit_after><|endoftext|>


<commit_before>// Aliases for major page elements
var el = {
	number: document.getElementById('number'),
	name: document.getElementById('name'),
	bg: document.getElementById('background'),
	location: document.getElementById('location')
};

// Pick rand team from team array in data.js
var teamNum = teams[parseInt(Math.random() * teams.length)];
// Put team number on page
el.number.innerHTML = '' + teamNum + '';

try {
	// Create request to get data from TBA
	var req = new XMLHttpRequest();
	// Get data for team
	req.open('GET', 'https://www.thebluealliance.com/api/v2/team/frc' + teamNum + '?X-TBA-App-Id=erikboesen:frcnewtab:v1.0');
	// Send empty data for conclusion
	req.send();
	// When the data is ready
	req.onreadystatechange = function() {
		if (req.readyState == 4 && req.status == 200) {
			// Parse the data into JSON to get it ready to be used
			team = JSON.parse(req.responseText);
			// Set team name on page
			el.name.innerHTML = (team.website && team.website !== 'Coming Soon') ? '' + team.nickname + '' : team.nickname;
			el.location.innerHTML = team.location;
		}
	};
} catch (e) {}

// Source it to a random photo in the bg folder.
var src = 'bg/' + (Math.floor(Math.random() * 10) + 1) + '.jpg';

// Make a new request to get list of team media from TBA
var mediaReq = new XMLHttpRequest();
// Set function to be executed when the data is ready
mediaReq.onreadystatechange = function() {
	if (mediaReq.readyState == 4 && mediaReq.status == 200) {
		// Parse data for processing
		var media = [];
		try {
			media = JSON.parse(mediaReq.responseText);
		} catch (e) {}
        console.log(media.length);
		if (media.length > 0) {
			var target;
			// Go through every piece of media
			for (i = 0; i < media.length; i++) {
				// Find media that's an image
				if (media[i].type === 'imgur' || media[i].type === 'cdphotothread') {
					// Set target to that image and break loop.
					target = i;
					break;
				}
			}
			// Check where the media is sourced from. Use this to build a link to the image.
			if (target !== null) {
                console.log('targeted ', media[target].type);
				switch (media[target].type) {
					case 'imgur':
						src = 'http://i.imgur.com/' + media[target].foreign_key + '.png';
						break;
					case 'cdphotothread':
						src = 'https://www.chiefdelphi.com/media/img/' + media[target].details.image_partial;
						break;
				}
			}
		}
        // Log URL of background image
        console.log(src);
        // Put the image into the background (see below).
        renderImage();
	}
};

// Get data
mediaReq.open('GET', 'https://www.thebluealliance.com/api/v2/team/frc' + teamNum + '/media?X-TBA-App-Id=erikboesen:frcnewtab:v1.0');
mediaReq.send();

function renderImage() {
    // Create image. This will be used to check if the image is smaller than the window.
    var img = new Image();
    // Give it the proper source.
    img.src = src;
    // When the source is done loading,
    img.onload = function() {
    	// Check if the image is smaller than the window.
    	if (img.naturalWidth >= window.innerWidth) {
    		// If it is, blur the background image.
    		el.bg.style['-webkit-filter'] = 'none';
    	}
    };

    // Set the src of the real background image.
    el.bg.style.backgroundImage = 'url(' + src + ')';
}

// TODO: This process could probably be way more efficient. Find a way to improve.
<commit_msg>Added support for clock mode<commit_after>// Aliases for major page elements
var el = {
	number: document.getElementById('number'),
	name: document.getElementById('name'),
	bg: document.getElementById('background'),
	location: document.getElementById('location')
};

// TODO get these values from the settings page
var isClockMode = true; // testing clock mode
var isMilitary = true; // testing

// Pick rand team from team array in data.js
if (!isClockMode) {
    var teamNum = teams[parseInt(Math.random() * teams.length)];
} else {
    // Get date
    var d = new Date();
    var hours = d.getHours();
    if (!isMilitary) {
        hours %= 12;
    }
    // Construct team number
    hours *= 100;
    timeTeam = hours + d.getMinutes();
    var teamNum = timeTeam;
}
// Put team number on page
el.number.innerHTML = '' + teamNum + '';

try {
	// Create request to get data from TBA
	var req = new XMLHttpRequest();
	// Get data for team
	req.open('GET', 'https://www.thebluealliance.com/api/v2/team/frc' + teamNum + '?X-TBA-App-Id=erikboesen:frcnewtab:v1.0');
	// Send empty data for conclusion
	req.send();
	// When the data is ready
	req.onreadystatechange = function() {
		if (req.readyState == 4 && req.status == 200) {
			// Parse the data into JSON to get it ready to be used
			team = JSON.parse(req.responseText);
			// Set team name on page
			el.name.innerHTML = (team.website && team.website !== 'Coming Soon') ? '' + team.nickname + '' : team.nickname;
			el.location.innerHTML = team.location;
		}
	};
} catch (e) {}

// Source it to a random photo in the bg folder.
var src = 'bg/' + (Math.floor(Math.random() * 10) + 1) + '.jpg';

// Make a new request to get list of team media from TBA
var mediaReq = new XMLHttpRequest();
// Set function to be executed when the data is ready
mediaReq.onreadystatechange = function() {
	if (mediaReq.readyState == 4 && mediaReq.status == 200) {
		// Parse data for processing
		var media = [];
		try {
			media = JSON.parse(mediaReq.responseText);
		} catch (e) {}
        console.log(media.length);
		if (media.length > 0) {
			var target;
			// Go through every piece of media
			for (i = 0; i < media.length; i++) {
				// Find media that's an image
				if (media[i].type === 'imgur' || media[i].type === 'cdphotothread') {
					// Set target to that image and break loop.
					target = i;
					break;
				}
			}
			// Check where the media is sourced from. Use this to build a link to the image.
			if (target !== null) {
                console.log('targeted ', media[target].type);
				switch (media[target].type) {
					case 'imgur':
						src = 'http://i.imgur.com/' + media[target].foreign_key + '.png';
						break;
					case 'cdphotothread':
						src = 'https://www.chiefdelphi.com/media/img/' + media[target].details.image_partial;
						break;
				}
			}
		}
        // Log URL of background image
        console.log(src);
        // Put the image into the background (see below).
        renderImage();
	}
};

// Get data
mediaReq.open('GET', 'https://www.thebluealliance.com/api/v2/team/frc' + teamNum + '/media?X-TBA-App-Id=erikboesen:frcnewtab:v1.0');
mediaReq.send();

function renderImage() {
    // Create image. This will be used to check if the image is smaller than the window.
    var img = new Image();
    // Give it the proper source.
    img.src = src;
    // When the source is done loading,
    img.onload = function() {
    	// Check if the image is smaller than the window.
    	if (img.naturalWidth >= window.innerWidth) {
    		// If it is, blur the background image.
    		el.bg.style['-webkit-filter'] = 'none';
    	}
    };

    // Set the src of the real background image.
    el.bg.style.backgroundImage = 'url(' + src + ')';
}

// TODO: This process could probably be way more efficient. Find a way to improve.
<|endoftext|>