<commit_before>'use strict';

/* =========================================================================
 * Copyright (c) 2016 Eivind Storm Aarnæs
 * Licensed under the MIT license
 *    (see https://github.com/eistaa/parse-terminfo/blob/master/LICENSE)
 * ========================================================================= */

var fs   = require('fs'),
    path = require('path');

var DEFAULT_DB_DIRECTORIES = [
    '/etc/terminfo',
    '/lib/terminfo',
    '/usr/share/terminfo'
]

function pushIfDirExists(directory, array) {
    try {
        if ( fs.statSync(directory).isDirectory() )
            array.push(directory);
    } catch (err) { }
}

function constructDBDirectories(dirs) {
    /*
     * the ordering comes from manpage 'terminfo(5)'
     */

    var directories = [], loc;

    // argument can be array or string
    if ( dirs ) {
        if ( Array.isArray(opts) ) {
            for ( var i = 0; i < dirs.length; i++ )
                pushIfDirExists(path.normalize(dirs[i]), directories);
        } else if ( typeof dirs === 'string' ) {
            pushIfDirExists(path.normalize(dirs), directories);
        }
    }

    // TERMINFO may exist
    if ( process.env.TERMINFO )
        pushIfDirExists(path.normalize(process.env.TERMINFO), directories);

    // there may be a local terminfo directory
    if ( process.env.HOME )
        pushIfDirExists(path.normalize(path.join(process.env.HOME, '.terminfo')), directories);

    // TERMINFO_DIRS can contain a :-separated list of directories
    if ( process.env.TERMINFO_DIRS ) {
        var var_dirs = process.env.TERMINFO_DIRS.split(':');
        for ( var i = 0; i < var_dirs.length; i++ ) {
            if ( var_dirs.strip() !== '' ) {
                pushIfDirExists(var_dirs[i].strip(), directories);
            } else {
                pushIfDirExists('/usr/share/terminfo', directories);
            }
        }
    }

    // default to hardcoded directories
    for ( var i = 0; i < DEFAULT_DB_DIRECTORIES.length; i++ ) {
        pushIfDirExists(DEFAULT_DB_DIRECTORIES[i], directories);
    }

    return directories;
}

function openTerminfoBuffer(term, opts) {
    // determine directories
    var directories = constructDBDirectories(
        (opts && opts.directories) ? opts.directories : undefined
    ), filepath;

    if ( directories.length === 0 )
        throw new Error('no terminfo database directories exist');

    // use first valid directory
    for ( var i = 0; i < directories.length; i++ ) {
        try {
            filepath = path.join(directories[i], term.charAt(0), term);
            if ( fs.statSync(filepath).isFile() ) {
                break;
            }
        } catch (err) {
            filepath = undefined;
        }
    }

    if ( filepath === undefined )
        throw new Error(term+' have no terminfo data');

    // read to buffer
    return {
        path:   filepath,
        buffer: fs.readFileSync(filepath)
    };
}

module.exports = openTerminfoBuffer;
<commit_msg>Fix to agree with terminfo(5).<commit_after>'use strict';

/* =========================================================================
 * Copyright (c) 2016 Eivind Storm Aarnæs
 * Licensed under the MIT license
 *    (see https://github.com/eistaa/parse-terminfo/blob/master/LICENSE)
 * ========================================================================= */

var fs   = require('fs'),
    path = require('path');

var DEFAULT_DB_DIRECTORIES = [
    '/etc/terminfo',
    '/lib/terminfo',
    '/usr/share/terminfo'
]

function pushIfDirExists(directory, array) {
    try {
        if ( fs.statSync(directory).isDirectory() )
            array.push(directory);
    } catch (err) { }
}

function constructDBDirectories(dirs) {
    /*
     * the ordering comes from manpage 'terminfo(5)'
     */

    var directories = [], loc;

    // argument can be array or string
    if ( dirs ) {
        if ( Array.isArray(opts) ) {
            for ( var i = 0; i < dirs.length; i++ )
                pushIfDirExists(path.normalize(dirs[i]), directories);
        } else if ( typeof dirs === 'string' ) {
            pushIfDirExists(path.normalize(dirs), directories);
        }
    }

    // TERMINFO may exist
    if ( process.env.TERMINFO )
        pushIfDirExists(path.normalize(process.env.TERMINFO), directories);

    // there may be a local terminfo directory
    if ( process.env.HOME )
        pushIfDirExists(path.normalize(path.join(process.env.HOME, '.terminfo')), directories);

    // TERMINFO_DIRS can contain a :-separated list of directories
    if ( process.env.TERMINFO_DIRS ) {
        var var_dirs = process.env.TERMINFO_DIRS.split(':');
        for ( var i = 0; i < var_dirs.length; i++ ) {
            if ( var_dirs.strip() !== '' ) {
                pushIfDirExists(var_dirs[i].strip(), directories);
            } else {
                pushIfDirExists('/etc/terminfo', directories);
            }
        }
    }

    // default to hardcoded directories
    for ( var i = 0; i < DEFAULT_DB_DIRECTORIES.length; i++ ) {
        pushIfDirExists(DEFAULT_DB_DIRECTORIES[i], directories);
    }

    return directories;
}

function openTerminfoBuffer(term, opts) {
    // determine directories
    var directories = constructDBDirectories(
        (opts && opts.directories) ? opts.directories : undefined
    ), filepath;

    if ( directories.length === 0 )
        throw new Error('no terminfo database directories exist');

    // use first valid directory
    for ( var i = 0; i < directories.length; i++ ) {
        try {
            filepath = path.join(directories[i], term.charAt(0), term);
            if ( fs.statSync(filepath).isFile() ) {
                break;
            }
        } catch (err) {
            filepath = undefined;
        }
    }

    if ( filepath === undefined )
        throw new Error(term+' have no terminfo data');

    // read to buffer
    return {
        path:   filepath,
        buffer: fs.readFileSync(filepath)
    };
}

module.exports = openTerminfoBuffer;
<|endoftext|>


<commit_before><commit_msg>Debug.<commit_after><|endoftext|>


<commit_before>/*
 * __proto__
 * An awesome project description
 * https://github.com/thanpolas/__proto__
 *
 * Copyright (c) 2014 Thanasis Polychronakis
 * Licensed under the MIT license.
 */

/**
 * @fileOverview __proto__ Base.
 */
module.exports = {};
<commit_msg>work on the KM bootstrap file<commit_after>/*
 * Kansas Metrics
 * Metrics library for Kansas.
 * https://github.com/thanpolas/kansas-metrics
 *
 * Copyright (c) 2014 Thanasis Polychronakis
 * Licensed under the MIT license.
 *
 * @fileOverview Kansas Metrics Base.
 */

/**
 * @fileOverview Kansas Metrics Base.
 */

var setup = require('./setup');
var KansasMetrics = require('kansas-metrics');

/**
 * The Kansas Metrics exported function.
 *
 * @return {KansasMetrics} An instance of Kansas Metrics.
 */
var metrics = module.exports = function() {
  return new KansasMetrics();
};

/** @type {Function} Expose the Setup method. */
metrics.setup = setup;
<|endoftext|>


<commit_before>function addRowListeners(tableIdentifier) {
	$(tableIdentifier + ' tr').click(function() {
		selectDetailCard(this);
	});
	selectDetailCard($(tableIdentifier + ' tr').first());
}

function selectDetailCard(me) {
	$(me).parent().children('tr.active').removeClass('active');
	$(me).addClass('active');
	var rowId = $(me).attr('id');
	var cls = rowId.split('-')[0];
	$('.hidden-cards > .' + cls + '.card:visible').hide();
	$('#' + rowId + '-card').show();
}<commit_msg>Fixed initial card display bug when there are no cards to display.<commit_after>function addRowListeners(tableIdentifier) {
	$(tableIdentifier + ' tr').click(function() {
		selectDetailCard(this);
	});
	if ($(tableIdentifier + ' tr').length) {
		selectDetailCard($(tableIdentifier + ' tr').first());
	}
}

function selectDetailCard(me) {
	$(me).parent().children('tr.active').removeClass('active');
	$(me).addClass('active');
	var rowId = $(me).attr('id');
	var cls = rowId.split('-')[0];
	$('.hidden-cards > .' + cls + '.card:visible').hide();
	$('#' + rowId + '-card').show();
}<|endoftext|>


<commit_before>// Testing

const way = require('./index')
const test = require('tape')

const W0 = [
  [1, 0, 1],
  [0, 1, 1]
]
const W1 = [
  [0, 0, 1],
  [1, 0, 0]
]
const ZEROS = [
  [0, 0, 0],
  [0, 0, 0]
]
const ONES = [
  [1, 1, 1],
  [1, 1, 1]
]
const TWOS = [
  [2, 2, 2],
  [2, 2, 2]
]

test('add', (t) => {
  t.deepEqual(way.add(W0, W1), [
    [1, 0, 2],
    [1, 1, 1]
  ])
  t.end()
})

test('after', (t) => {
  t.deepEqual(way.after(ONES, 2), [
    [1],
    [1]
  ])
  t.end()
})

test('before', (t) => {
  t.deepEqual(way.before(W1, 2), [
    [0, 0],
    [1, 0]
  ])
  t.end()
})

test('channel', (t) => {
  t.deepEqual(way.channel(W0, 1), [
    [0, 1, 1]
  ])
  t.end()
})

test('channels', (t) => {
  t.deepEqual(way.channels(W0, [0, 1]), [
    [1, 0, 1],
    [0, 1, 1]
  ])
  t.end()
})

test('clone', (t) => {
  t.deepEqual(way.clone(W0), W0)
  t.notEqual(way.clone(W0), W0)
  t.end()
})

test('create', (t) => {
  t.deepEqual(way.create(2, 3, 1), ONES)
  t.end()
})

test('equal', (t) => {
  t.true(way.equal(W0, W0))
  t.false(way.equal(W0, W1))
  t.end()
})

test('fill', (t) => {
  t.deepEqual(way.fill(ONES, 0), [
    [0, 0, 0],
    [0, 0, 0]
  ])
  t.end()
})

test('first', (t) => {
  t.deepEqual(way.first(W0, 2), [
    [1, 0],
    [0, 1]
  ])
  t.end()
})

test('frame', (t) => {
  t.deepEqual(way.frame(W0, 1), [
    [0],
    [1]
  ])
  t.end()
})

test('increase', (t) => {
  t.deepEqual(way.increase(ONES, 1), [
    [2, 2, 2],
    [2, 2, 2]
  ])
  t.end()
})

test('join', (t) => {
  t.deepEqual(way.join(ZEROS, ONES), [
    [0, 0, 0, 1, 1, 1],
    [0, 0, 0, 1, 1, 1]
  ])
  t.end()
})

test('last', (t) => {
  t.deepEqual(way.last(W0, 2), [
    [0, 1],
    [1, 1]
  ])
  t.end()
})

test('len', (t) => {
  t.equal(way.len(W0), 3)
  t.end()
})

test('map', (t) => {
  t.deepEqual(way.map(ONES, q => q * 2), [
    [2, 2, 2],
    [2, 2, 2]
  ])
  t.deepEqual(way.map(ONES, (q, c, t) => t * (c + 1)), [
    [0, 1, 2],
    [0, 2, 4]
  ])
  t.end()
})

test('map2', (t) => {
  t.deepEqual(way.map2(ONES, TWOS, (qa, qb) => qa + qb), [
    [3, 3, 3],
    [3, 3, 3]
  ])
  t.end()
})

test('mean', (t) => {
  t.deepEqual(way.mean(ONES), [
    [1],
    [1]
  ])
  t.deepEqual(way.mean(ZEROS), [
    [0],
    [0]
  ])
  t.end()
})

test('mix', (t) => {
  t.deepEqual(way.mix(ZEROS, ONES), [
    [0, 0, 0],
    [0, 0, 0],
    [1, 1, 1],
    [1, 1, 1]
  ])
  t.end()
})

test('multiply', (t) => {
  t.deepEqual(way.multiply(ONES, ZEROS), ZEROS)
  t.end()
})

test('reduce', (t) => {
  t.equal(way.reduce(ONES, (acc, q) => acc + q, 0), 6)
  t.end()
})

test('scale', (t) => {
  t.deepEqual(way.scale(ONES, 2), [
    [2, 2, 2],
    [2, 2, 2]
  ])
  t.end()
})

test('slice', (t) => {
  t.deepEqual(way.slice(W0, 1, 3), [
    [0, 1],
    [1, 1]
  ])
  t.end()
})
<commit_msg>Test way.slice for out of range indices<commit_after>// Testing

const way = require('./index')
const test = require('tape')

const W0 = [
  [1, 0, 1],
  [0, 1, 1]
]
const W1 = [
  [0, 0, 1],
  [1, 0, 0]
]
const ZEROS = [
  [0, 0, 0],
  [0, 0, 0]
]
const ONES = [
  [1, 1, 1],
  [1, 1, 1]
]
const TWOS = [
  [2, 2, 2],
  [2, 2, 2]
]

test('add', (t) => {
  t.deepEqual(way.add(W0, W1), [
    [1, 0, 2],
    [1, 1, 1]
  ])
  t.end()
})

test('after', (t) => {
  t.deepEqual(way.after(ONES, 2), [
    [1],
    [1]
  ])
  t.end()
})

test('before', (t) => {
  t.deepEqual(way.before(W1, 2), [
    [0, 0],
    [1, 0]
  ])
  t.end()
})

test('channel', (t) => {
  t.deepEqual(way.channel(W0, 1), [
    [0, 1, 1]
  ])
  t.end()
})

test('channels', (t) => {
  t.deepEqual(way.channels(W0, [0, 1]), [
    [1, 0, 1],
    [0, 1, 1]
  ])
  t.end()
})

test('clone', (t) => {
  t.deepEqual(way.clone(W0), W0)
  t.notEqual(way.clone(W0), W0)
  t.end()
})

test('create', (t) => {
  t.deepEqual(way.create(2, 3, 1), ONES)
  t.end()
})

test('equal', (t) => {
  t.true(way.equal(W0, W0))
  t.false(way.equal(W0, W1))
  t.end()
})

test('fill', (t) => {
  t.deepEqual(way.fill(ONES, 0), [
    [0, 0, 0],
    [0, 0, 0]
  ])
  t.end()
})

test('first', (t) => {
  t.deepEqual(way.first(W0, 2), [
    [1, 0],
    [0, 1]
  ])
  t.end()
})

test('frame', (t) => {
  t.deepEqual(way.frame(W0, 1), [
    [0],
    [1]
  ])
  t.end()
})

test('increase', (t) => {
  t.deepEqual(way.increase(ONES, 1), [
    [2, 2, 2],
    [2, 2, 2]
  ])
  t.end()
})

test('join', (t) => {
  t.deepEqual(way.join(ZEROS, ONES), [
    [0, 0, 0, 1, 1, 1],
    [0, 0, 0, 1, 1, 1]
  ])
  t.end()
})

test('last', (t) => {
  t.deepEqual(way.last(W0, 2), [
    [0, 1],
    [1, 1]
  ])
  t.end()
})

test('len', (t) => {
  t.equal(way.len(W0), 3)
  t.end()
})

test('map', (t) => {
  t.deepEqual(way.map(ONES, q => q * 2), [
    [2, 2, 2],
    [2, 2, 2]
  ])
  t.deepEqual(way.map(ONES, (q, c, t) => t * (c + 1)), [
    [0, 1, 2],
    [0, 2, 4]
  ])
  t.end()
})

test('map2', (t) => {
  t.deepEqual(way.map2(ONES, TWOS, (qa, qb) => qa + qb), [
    [3, 3, 3],
    [3, 3, 3]
  ])
  t.end()
})

test('mean', (t) => {
  t.deepEqual(way.mean(ONES), [
    [1],
    [1]
  ])
  t.deepEqual(way.mean(ZEROS), [
    [0],
    [0]
  ])
  t.end()
})

test('mix', (t) => {
  t.deepEqual(way.mix(ZEROS, ONES), [
    [0, 0, 0],
    [0, 0, 0],
    [1, 1, 1],
    [1, 1, 1]
  ])
  t.end()
})

test('multiply', (t) => {
  t.deepEqual(way.multiply(ONES, ZEROS), ZEROS)
  t.end()
})

test('reduce', (t) => {
  t.equal(way.reduce(ONES, (acc, q) => acc + q, 0), 6)
  t.end()
})

test('scale', (t) => {
  t.deepEqual(way.scale(ONES, 2), [
    [2, 2, 2],
    [2, 2, 2]
  ])
  t.end()
})

test('slice', (t) => {
  t.deepEqual(way.slice(W0, 1, 3), [
    [0, 1],
    [1, 1]
  ])
  t.deepEqual(way.slice(W0, 1, 50), [
    [0, 1],
    [1, 1]
  ])
  t.end()
})
<|endoftext|>


<commit_before>import fs from 'fs-extra'
import path from 'path'

const cwd = process.cwd()

export const copy = (source, target, options, notify) => {
  notify('copy', [source, target])

  try {
    const sourceStat = fs.statSync(source)

    if (sourceStat.isFile()) {
      if (options.transform) {
        const transform = options.transform
        const file = fs.readFileSync(source)
        const transformed = transform(file, target)

        fs.writeFileSync(transformed.target || target, transformed.data || transformed)
      } else {
        fs.copySync(source, target)
      }
    } else if (sourceStat.isDirectory()) {
      fs.ensureDirSync(target)
    }
    return true
  } catch (e) {
    notify('error', e)
    return false
  }
}

export const destroy = (fileordir, notify) => {
  notify('remove', fileordir)
  try {
    fs.removeSync(fileordir)
    return true
  } catch (e) {
    notify('error', e)
    return false
  }
}

export const deleteExtra = (fileordir, options, notify) => {
  if (options.delete) {
    return destroy(fileordir, notify)
  } else {
    notify('no-delete', fileordir)
    return true
  }
}

const getBase = (file, base) => base.filter((base) => file.indexOf(base) !== -1)
    .reduce((hit, base) => hit.length > base.length ? hit : base, '')

export const resolveTarget = (file, target, options) => {
  const from = path.join(cwd, getBase(file, options.base))

  return path.join(target, path.relative(from, file))
}
<commit_msg>improved logging<commit_after>import fs from 'fs-extra'
import path from 'path'

const cwd = process.cwd()

export const copy = (source, target, options, notify) => {
  try {
    const sourceStat = fs.statSync(source)

    if (sourceStat.isFile()) {
      if (options.transform) {
        const transform = options.transform
        const file = fs.readFileSync(source)
        const transformed = transform(file, target)
        const isObject = typeof transformed === 'object'
        const data = isObject && transformed.data || transformed
        const newTarget = isObject && transformed.target || target

        notify('copy', [source, newTarget])

        fs.writeFileSync(newTarget, data || transformed)
      } else {
        notify('copy', [source, target])
        fs.copySync(source, target)
      }
    } else if (sourceStat.isDirectory()) {
      notify('copy', [source, target])
      fs.ensureDirSync(target)
    }
    return true
  } catch (e) {
    notify('error', e)
    return false
  }
}

export const destroy = (fileordir, notify) => {
  notify('remove', fileordir)
  try {
    fs.removeSync(fileordir)
    return true
  } catch (e) {
    notify('error', e)
    return false
  }
}

export const deleteExtra = (fileordir, options, notify) => {
  if (options.delete) {
    return destroy(fileordir, notify)
  } else {
    notify('no-delete', fileordir)
    return true
  }
}

const getBase = (file, base) => base.filter((base) => file.indexOf(base) !== -1)
    .reduce((hit, base) => hit.length > base.length ? hit : base, '')

export const resolveTarget = (file, target, options) => {
  const from = path.join(cwd, getBase(file, options.base))

  return path.join(target, path.relative(from, file))
}
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var ClosedInterval = function(from,to) {
  return {
    minimum: function() { return from; },
    maximum: function() { return to; }
  };
};

var createClosedInterval = function(from,to) {
  return new ClosedInterval(from, to);
};

var createOpenInterval = function(from,to) {
  return new ClosedInterval(from+1, to-1);
};

describe('range', function() {
  describe('creation', function() {
    it('exists', function() {
      assert(new ClosedInterval);
    });
  });

  describe('closed intervals', function() {

    var defaultRangeForTests = createClosedInterval(1,4);

    it('is created', function() {
      assert(defaultRangeForTests);
    });

    it('minimum', function() {
      assert.equal(1, defaultRangeForTests.minimum());
    });

    it('maximum', function() {
      assert.equal(4, defaultRangeForTests.maximum());
    });
  });

  describe('open intervals', function() {
    var defaultRangeForTests = createOpenInterval(1,4);

    it('is created', function() {
      assert(defaultRangeForTests);
    });

    it('minimum', function() {
      assert.equal(2, defaultRangeForTests.minimum());
    });

    it('maximum', function() {
      assert.equal(3, defaultRangeForTests.maximum());
    });
  });
});
<commit_msg>test the contains function<commit_after>"use strict";

var assert = require('assert');

var ClosedInterval = function(from,to) {
  return {
    minimum: function() { return from; },
    maximum: function() { return to; }
  };
};

var createClosedInterval = function(from,to) {
  return new ClosedInterval(from, to);
};

var createOpenInterval = function(from,to) {
  return new ClosedInterval(from+1, to-1);
};

describe('range', function() {
  describe('creation', function() {
    it('exists', function() {
      assert(new ClosedInterval);
    });
  });

  describe('closed intervals', function() {

    var defaultRangeForTests = createClosedInterval(1,4);

    it('is created', function() {
      assert(defaultRangeForTests);
    });

    it('minimum', function() {
      assert.equal(1, defaultRangeForTests.minimum());
    });

    it('maximum', function() {
      assert.equal(4, defaultRangeForTests.maximum());
    });
  });

  describe('open intervals', function() {
    var defaultRangeForTests = createOpenInterval(1,4);

    it('is created', function() {
      assert(defaultRangeForTests);
    });

    it('minimum', function() {
      assert.equal(2, defaultRangeForTests.minimum());
    });

    it('maximum', function() {
      assert.equal(3, defaultRangeForTests.maximum());
    });
  });

  describe('range contains', function() {
    it('correctly contains', function() {
      var range = createClosedInterval(1,100);

      assert(range.contains(1));
      assert(range.contains(50));
      assert(range.contains(100));
    });
  });
});
<|endoftext|>


<commit_before>var Utils     = require('./utils')
  , DataTypes = require('./data-types')

module.exports = (function() {
  var QueryInterface = function(sequelize) {
    this.sequelize = sequelize
    this.QueryGenerator = require('./dialects/' + this.sequelize.options.dialect + '/query-generator')
   this.QueryGenerator.options = this.sequelize.options;
  }
  Utils.addEventEmitter(QueryInterface)

  QueryInterface.prototype.createTable = function(tableName, attributes, options) {
    var attributeHashes = {}

    Utils._.each(attributes, function(dataTypeOrOptions, attributeName) {
      if(Utils._.values(DataTypes).indexOf(dataTypeOrOptions) > -1)
        attributeHashes[attributeName] = { type: dataTypeOrOptions }
      else
        attributeHashes[attributeName] = dataTypeOrOptions
    })

    attributes = this.QueryGenerator.attributesToSQL(attributeHashes)

    var sql = this.QueryGenerator.createTableQuery(tableName, attributes, options)
    return queryAndEmit.call(this, sql, 'createTable')
  }

  QueryInterface.prototype.dropTable = function(tableName) {
    var sql = this.QueryGenerator.dropTableQuery(tableName)
    return queryAndEmit.call(this, sql, 'dropTable')
  }

  QueryInterface.prototype.dropAllTables = function() {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      var chainer = new Utils.QueryChainer()

      self.showAllTables().success(function(tableNames) {
        tableNames.forEach(function(tableName) {
          chainer.add(self.dropTable(tableName))
        })
        chainer
          .run()
          .success(function() {
            self.emit('dropAllTables', null)
            emitter.emit('success', null)
          })
          .error(function(err) {
            self.emit('dropAllTables', err)
            emitter.emit('error', err)
          })
      }).error(function(err) {
        self.emit('dropAllTables', err)
        emitter.emit('error', err)
      })
    }).run()
  }

  QueryInterface.prototype.renameTable = function(before, after) {
    var sql = this.QueryGenerator.renameTableQuery(before, after)
    return queryAndEmit.call(this, sql, 'renameTable')
  }

  QueryInterface.prototype.showAllTables = function() {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      var showTablesSql = self.QueryGenerator.showTablesQuery()
      self.sequelize.query(showTablesSql, null, { raw: true }).success(function(tableNames) {
        self.emit('showAllTables', null)
        emitter.emit('success', Utils._.flatten(tableNames))
      }).error(function(err) {
        self.emit('showAllTables', err)
        emitter.emit('error', err)
      })
    }).run()
  }

  QueryInterface.prototype.describeTable = function(tableName) {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      var sql;
      if (self.QueryGenerator.describeTableQuery) {
        sql = self.QueryGenerator.describeTableQuery(tableName)
      } else {
        sql = 'DESCRIBE `' + tableName + '`;'
      }
      self.sequelize.query(sql, null, { raw: true }).success(function(data) {
        emitter.emit('success', data)
      }).error(function(err) {
        emitter.emit('error', err)
      })
    }).run()
  }

  QueryInterface.prototype.addColumn = function(tableName, attributeName, dataTypeOrOptions) {
    var attributes = {}

    if(Utils._.values(DataTypes).indexOf(dataTypeOrOptions) > -1)
      attributes[attributeName] = { type: dataTypeOrOptions, allowNull: false }
    else
      attributes[attributeName] = dataTypeOrOptions

    var options = this.QueryGenerator.attributesToSQL(attributes)
      , sql     = this.QueryGenerator.addColumnQuery(tableName, options)

    return queryAndEmit.call(this, sql, 'addColumn')
  }

  QueryInterface.prototype.removeColumn = function(tableName, attributeName) {
    var sql = this.QueryGenerator.removeColumnQuery(tableName, attributeName)
    return queryAndEmit.call(this, sql, 'removeColumn')
  }

  QueryInterface.prototype.changeColumn = function(tableName, attributeName, dataTypeOrOptions) {
    var attributes = {}

    if(Utils._.values(DataTypes).indexOf(dataTypeOrOptions) > -1)
      attributes[attributeName] = { type: dataTypeOrOptions, allowNull: false }
    else
      attributes[attributeName] = dataTypeOrOptions

    var options = this.QueryGenerator.attributesToSQL(attributes)
      , sql     = this.QueryGenerator.changeColumnQuery(tableName, options)

    return queryAndEmit.call(this, sql, 'changeColumn')
  }

  QueryInterface.prototype.renameColumn = function(tableName, attrNameBefore, attrNameAfter) {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      self.describeTable(tableName).success(function(data) {
        data = data.filter(function(h) { return h.Field == attrNameBefore })[0]

        var options =  {}

        options[attrNameAfter] = {
          type: data.Type,
          allowNull: data.Null == 'YES',
          defaultValue: data.Default
        }

        var sql = self.QueryGenerator.renameColumnQuery(tableName,
          attrNameBefore,
          self.QueryGenerator.attributesToSQL(options)
        )

        self.sequelize.query(sql, null, {}).success(function() {
          self.emit('renameColumn', null)
          emitter.emit('success', null)
        }).error(function(err) {
          self.emit('renameColumn', err)
          emitter.emit('error', err)
        })
      }).error(function(err) {
        self.emit('renameColumn', err)
        emitter.emit('error', err)
      })
    }).run()
  }

  QueryInterface.prototype.addIndex = function(tableName, attributes, options) {
    var sql = this.QueryGenerator.addIndexQuery(tableName, attributes, options)
    return queryAndEmit.call(this, sql, 'addIndex')
  }

  QueryInterface.prototype.showIndex = function(tableName, options) {
    var sql = this.QueryGenerator.showIndexQuery(tableName, options)
    return queryAndEmit.call(this, sql, 'showIndex')
  }

  QueryInterface.prototype.removeIndex = function(tableName, indexNameOrAttributes) {
    var sql = this.QueryGenerator.removeIndexQuery(tableName, indexNameOrAttributes)
    return queryAndEmit.call(this, sql, "removeIndex")
  }

  QueryInterface.prototype.insert = function(dao, tableName, values) {
    var sql = this.QueryGenerator.insertQuery(tableName, values)
    return queryAndEmit.call(this, [sql, dao], 'insert', {
      success: function(obj) { obj.isNewRecord = false }
    })
  }

  QueryInterface.prototype.update = function(dao, tableName, values, identifier) {
    var sql = this.QueryGenerator.updateQuery(tableName, values, identifier)
    return queryAndEmit.call(this, [sql, dao], 'update')
  }

  QueryInterface.prototype.delete = function(dao, tableName, identifier) {
    var sql = this.QueryGenerator.deleteQuery(tableName, identifier)
    return queryAndEmit.call(this, [sql, dao], 'delete')
  }

  QueryInterface.prototype.select = function(factory, tableName, options, queryOptions) {
    var sql = this.QueryGenerator.selectQuery(tableName, options)
    return queryAndEmit.call(this, [sql, factory, queryOptions], 'select')
  }

  QueryInterface.prototype.rawSelect = function(tableName, options, attributeSelector) {
    var self = this

    if(attributeSelector == undefined) {
      throw new Error('Please pass an attribute selector!')
    }

    return new Utils.CustomEventEmitter(function(emitter) {
      var sql = self.QueryGenerator.selectQuery(tableName, options)
        , qry = self.sequelize.query(sql, null, { plain: true, raw: true, type: 'SELECT' })

      qry
        .success(function(data) {
          var result = data[attributeSelector]

          if (options && options.parseInt) {
            result = parseInt(result)
          }

          self.emit('rawSelect', null)
          emitter.emit('success', result)
        })
        .error(function(err) {
          self.emit('rawSelect', err)
          emitter.emit('error', err)
        })
        .on('sql', function(sql) {
          emitter.emit('sql', sql)
        })
    }).run()
  }

  // private

  var queryAndEmit = function(sqlOrQueryParams, methodName, options) {
    var self = this

    options = Utils._.extend({
      success: function(){},
      error: function(){}
    }, options || {})

    return new Utils.CustomEventEmitter(function(emitter) {
      var query = null

      if(Array.isArray(sqlOrQueryParams)) {
        if (sqlOrQueryParams.length === 1) {
          sqlOrQueryParams.push(null)
        }

        if (sqlOrQueryParams.length === 2) {
          sqlOrQueryParams.push({})
        }

        query = self.sequelize.query.apply(self.sequelize, sqlOrQueryParams)
      } else {
        query = self.sequelize.query(sqlOrQueryParams, null, {})
      }

      // append the query for better testing
      emitter.query = query

      query.success(function(obj) {
        options.success && options.success(obj)
        self.emit(methodName, null)
        emitter.emit('success', obj)
      }).error(function(err) {
        options.error && options.error(err)
        self.emit(methodName, err)
        emitter.emit('error', err)
      })
      query.on('sql', function(sql) {
        emitter.emit('sql', sql)
      });
    }).run()
  }

  return QueryInterface
})()
<commit_msg>Close issue #400.<commit_after>var Utils     = require('./utils')
  , DataTypes = require('./data-types')

module.exports = (function() {
  var QueryInterface = function(sequelize) {
    this.sequelize = sequelize
    this.QueryGenerator = require('./dialects/' + this.sequelize.options.dialect + '/query-generator')
   this.QueryGenerator.options = this.sequelize.options;
  }
  Utils.addEventEmitter(QueryInterface)

  QueryInterface.prototype.createTable = function(tableName, attributes, options) {
    var attributeHashes = {}

    Utils._.each(attributes, function(dataTypeOrOptions, attributeName) {
      if(Utils._.values(DataTypes).indexOf(dataTypeOrOptions) > -1)
        attributeHashes[attributeName] = { type: dataTypeOrOptions }
      else
        attributeHashes[attributeName] = dataTypeOrOptions
    })

    attributes = this.QueryGenerator.attributesToSQL(attributeHashes)

    var sql = this.QueryGenerator.createTableQuery(tableName, attributes, options)
    return queryAndEmit.call(this, sql, 'createTable')
  }

  QueryInterface.prototype.dropTable = function(tableName) {
    var sql = this.QueryGenerator.dropTableQuery(tableName)
    return queryAndEmit.call(this, sql, 'dropTable')
  }

  QueryInterface.prototype.dropAllTables = function() {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      var chainer = new Utils.QueryChainer()

      self.showAllTables().success(function(tableNames) {
        tableNames.forEach(function(tableName) {
          chainer.add(self.dropTable(tableName))
        })
        chainer
          .run()
          .success(function() {
            self.emit('dropAllTables', null)
            emitter.emit('success', null)
          })
          .error(function(err) {
            self.emit('dropAllTables', err)
            emitter.emit('error', err)
          })
      }).error(function(err) {
        self.emit('dropAllTables', err)
        emitter.emit('error', err)
      })
    }).run()
  }

  QueryInterface.prototype.renameTable = function(before, after) {
    var sql = this.QueryGenerator.renameTableQuery(before, after)
    return queryAndEmit.call(this, sql, 'renameTable')
  }

  QueryInterface.prototype.showAllTables = function() {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      var showTablesSql = self.QueryGenerator.showTablesQuery()
      self.sequelize.query(showTablesSql, null, { raw: true }).success(function(tableNames) {
        self.emit('showAllTables', null)
        emitter.emit('success', Utils._.flatten(tableNames))
      }).error(function(err) {
        self.emit('showAllTables', err)
        emitter.emit('error', err)
      })
    }).run()
  }

  QueryInterface.prototype.describeTable = function(tableName) {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      var sql;
      if (self.QueryGenerator.describeTableQuery) {
        sql = self.QueryGenerator.describeTableQuery(tableName)
      } else {
        sql = 'DESCRIBE `' + tableName + '`;'
      }
      self.sequelize.query(sql, null, { raw: true }).success(function(data) {
        emitter.emit('success', data)
      }).error(function(err) {
        emitter.emit('error', err)
      })
    }).run()
  }

  QueryInterface.prototype.addColumn = function(tableName, attributeName, dataTypeOrOptions) {
    var attributes = {}

    if(Utils._.values(DataTypes).indexOf(dataTypeOrOptions) > -1)
      attributes[attributeName] = { type: dataTypeOrOptions, allowNull: false }
    else
      attributes[attributeName] = dataTypeOrOptions

    var options = this.QueryGenerator.attributesToSQL(attributes)
      , sql     = this.QueryGenerator.addColumnQuery(tableName, options)

    return queryAndEmit.call(this, sql, 'addColumn')
  }

  QueryInterface.prototype.removeColumn = function(tableName, attributeName) {
    var sql = this.QueryGenerator.removeColumnQuery(tableName, attributeName)
    return queryAndEmit.call(this, sql, 'removeColumn')
  }

  QueryInterface.prototype.changeColumn = function(tableName, attributeName, dataTypeOrOptions) {
    var attributes = {}

    if(Utils._.values(DataTypes).indexOf(dataTypeOrOptions) > -1)
      attributes[attributeName] = { type: dataTypeOrOptions, allowNull: false }
    else
      attributes[attributeName] = dataTypeOrOptions

    var options = this.QueryGenerator.attributesToSQL(attributes)
      , sql     = this.QueryGenerator.changeColumnQuery(tableName, options)

    return queryAndEmit.call(this, sql, 'changeColumn')
  }

  QueryInterface.prototype.renameColumn = function(tableName, attrNameBefore, attrNameAfter) {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      self.describeTable(tableName).success(function(data) {
        data = data.filter(function(h) { return h.Field == attrNameBefore })[0] || {}

        var options =  {}

        options[attrNameAfter] = {
          type: data.Type,
          allowNull: data.Null == 'YES',
          defaultValue: data.Default
        }

        var sql = self.QueryGenerator.renameColumnQuery(tableName,
          attrNameBefore,
          self.QueryGenerator.attributesToSQL(options)
        )

        self.sequelize.query(sql, null, {}).success(function() {
          self.emit('renameColumn', null)
          emitter.emit('success', null)
        }).error(function(err) {
          self.emit('renameColumn', err)
          emitter.emit('error', err)
        })
      }).error(function(err) {
        self.emit('renameColumn', err)
        emitter.emit('error', err)
      })
    }).run()
  }

  QueryInterface.prototype.addIndex = function(tableName, attributes, options) {
    var sql = this.QueryGenerator.addIndexQuery(tableName, attributes, options)
    return queryAndEmit.call(this, sql, 'addIndex')
  }

  QueryInterface.prototype.showIndex = function(tableName, options) {
    var sql = this.QueryGenerator.showIndexQuery(tableName, options)
    return queryAndEmit.call(this, sql, 'showIndex')
  }

  QueryInterface.prototype.removeIndex = function(tableName, indexNameOrAttributes) {
    var sql = this.QueryGenerator.removeIndexQuery(tableName, indexNameOrAttributes)
    return queryAndEmit.call(this, sql, "removeIndex")
  }

  QueryInterface.prototype.insert = function(dao, tableName, values) {
    var sql = this.QueryGenerator.insertQuery(tableName, values)
    return queryAndEmit.call(this, [sql, dao], 'insert', {
      success: function(obj) { obj.isNewRecord = false }
    })
  }

  QueryInterface.prototype.update = function(dao, tableName, values, identifier) {
    var sql = this.QueryGenerator.updateQuery(tableName, values, identifier)
    return queryAndEmit.call(this, [sql, dao], 'update')
  }

  QueryInterface.prototype.delete = function(dao, tableName, identifier) {
    var sql = this.QueryGenerator.deleteQuery(tableName, identifier)
    return queryAndEmit.call(this, [sql, dao], 'delete')
  }

  QueryInterface.prototype.select = function(factory, tableName, options, queryOptions) {
    var sql = this.QueryGenerator.selectQuery(tableName, options)
    return queryAndEmit.call(this, [sql, factory, queryOptions], 'select')
  }

  QueryInterface.prototype.rawSelect = function(tableName, options, attributeSelector) {
    var self = this

    if(attributeSelector == undefined) {
      throw new Error('Please pass an attribute selector!')
    }

    return new Utils.CustomEventEmitter(function(emitter) {
      var sql = self.QueryGenerator.selectQuery(tableName, options)
        , qry = self.sequelize.query(sql, null, { plain: true, raw: true, type: 'SELECT' })

      qry
        .success(function(data) {
          var result = data[attributeSelector]

          if (options && options.parseInt) {
            result = parseInt(result)
          }

          self.emit('rawSelect', null)
          emitter.emit('success', result)
        })
        .error(function(err) {
          self.emit('rawSelect', err)
          emitter.emit('error', err)
        })
        .on('sql', function(sql) {
          emitter.emit('sql', sql)
        })
    }).run()
  }

  // private

  var queryAndEmit = function(sqlOrQueryParams, methodName, options) {
    var self = this

    options = Utils._.extend({
      success: function(){},
      error: function(){}
    }, options || {})

    return new Utils.CustomEventEmitter(function(emitter) {
      var query = null

      if(Array.isArray(sqlOrQueryParams)) {
        if (sqlOrQueryParams.length === 1) {
          sqlOrQueryParams.push(null)
        }

        if (sqlOrQueryParams.length === 2) {
          sqlOrQueryParams.push({})
        }

        query = self.sequelize.query.apply(self.sequelize, sqlOrQueryParams)
      } else {
        query = self.sequelize.query(sqlOrQueryParams, null, {})
      }

      // append the query for better testing
      emitter.query = query

      query.success(function(obj) {
        options.success && options.success(obj)
        self.emit(methodName, null)
        emitter.emit('success', obj)
      }).error(function(err) {
        options.error && options.error(err)
        self.emit(methodName, err)
        emitter.emit('error', err)
      })
      query.on('sql', function(sql) {
        emitter.emit('sql', sql)
      });
    }).run()
  }

  return QueryInterface
})()
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

require('jsonminify');

var fs = require('fs');
var lodash = require('lodash');
var RSVP = require('rsvp');
var buildOpenlayers = require('openlayers/tasks/build');

var DEFAULT_CONFIG_PATH = "node_modules/openlayers/config/ol.json";
var APP_CONFIG_PATH = ".ol-build";
var OUTPUT_FILENAME = "ol.js";

module.exports = {

  OUTPUT_FILENAME: OUTPUT_FILENAME,

  normalizeConfig: function(config) {

    if (config.compile) {
      // remove source map
      delete config.compile.create_source_map;
      delete config.compile.source_map_format;

      // remove compile optimizations
      config.compilation_level = "WHITESPACE_ONLY";

      // prettify output
      config.formatting = "PRETTY_PRINT";
    }

    return config;
  },

  loadConfig: function(path) {

    var config = {};

    try {
      var configContent = fs.readFileSync(path, { encoding: 'utf8'} );
      config = JSON.parse( JSON.minify(configContent) );
    } catch(e) {}

    return this.normalizeConfig(config);
  },

  getConfig: function() {
    var config = {};

    var defaultConfig = this.loadConfig(DEFAULT_CONFIG_PATH);
    var appConfig = this.loadConfig(APP_CONFIG_PATH);

    if (appConfig.extend) {
      delete appConfig.extend;
      config = lodash.merge(defaultConfig, appConfig);
    } else if (!lodash.isEmpty(appConfig)) {
      config = appConfig;
    } else {
      config = defaultConfig;
    }

    return config;
  },

  build: function(outputPath) {
    var config = this.getConfig();
    return new RSVP.Promise(function(resolve, reject) {
      buildOpenlayers(config, function(error, compiledLib) {
        if (error) {
          reject(error);
        } else {
          fs.writeFileSync(outputPath, compiledLib, { encoding: 'utf8' });
          resolve();
        }
      });
    });
  }

};
<commit_msg>Fix default config issue<commit_after>/* jshint node: true */
'use strict';

require('jsonminify');

var fs = require('fs');
var path = require('path');
var lodash = require('lodash');
var RSVP = require('rsvp');
var buildOpenlayers = require('openlayers/tasks/build');

var DEFAULT_CONFIG_PATH = path.resolve("./../node_modules/openlayers/config/ol.json");
var APP_CONFIG_PATH = ".ol-build";
var OUTPUT_FILENAME = "ol.js";

module.exports = {

  OUTPUT_FILENAME: OUTPUT_FILENAME,

  normalizeConfig: function(config) {

    if (config.compile) {
      // remove source map
      delete config.compile.create_source_map;
      delete config.compile.source_map_format;

      // remove compile optimizations
      config.compilation_level = "WHITESPACE_ONLY";

      // prettify output
      config.formatting = "PRETTY_PRINT";
    }

    return config;
  },

  loadConfig: function(path) {

    var config = {};

    try {
      var configContent = fs.readFileSync(path, { encoding: 'utf8'} );
      config = JSON.parse( JSON.minify(configContent) );
    } catch(e) {}

    return this.normalizeConfig(config);
  },

  getConfig: function() {
    var config = {};

    var defaultConfig = this.loadConfig(DEFAULT_CONFIG_PATH);
    var appConfig = this.loadConfig(APP_CONFIG_PATH);

    // console.log(defaultConfig);

    if (appConfig.extend) {
      delete appConfig.extend;
      config = lodash.merge(defaultConfig, appConfig);
    } else if (!lodash.isEmpty(appConfig)) {
      config = appConfig;
    } else {
      config = defaultConfig;
    }

    // return config;
  },

  build: function(outputPath) {
    var config = this.getConfig();
    return new RSVP.Promise(function(resolve, reject) {
      buildOpenlayers(config, function(error, compiledLib) {
        if (error) {
          reject(error);
        } else {
          fs.writeFileSync(outputPath, compiledLib, { encoding: 'utf8' });
          resolve();
        }
      });
    });
  }

};
<|endoftext|>


<commit_before><commit_msg>Removed changes.<commit_after><|endoftext|>


<commit_before>import observable from 'riot-observable'
import { parseExpressions, parseAttributes } from './parse'
import RefExpr from './ref'
import update from './update'
import mkdom from './mkdom'
import { mixin } from './core'
import settings from '../../settings'
import { setAttr, remAttr, walkAttrs, setInnerHTML, isSvg } from './../common/util/dom'

import {
  isFunction,
  isString
} from './../common/util/check'

import {
  extend,
  each,
  startsWith,
  toCamel,
  contains,
  defineProperty
} from './../common/util/misc'

import {
  unmountAll,
  arrayishRemove,
  inheritFrom,
  getTagName,
  getImmediateCustomParentTag
} from './../common/util/tags'

import {
  RIOT_EVENTS_KEY,
  GLOBAL_MIXIN,
  __TAGS_CACHE,
  ATTRS_PREFIX
} from './../common/global-variables'

// counter to give a unique id to all the Tag instances
let uid = 0

/**
 * We need to update opts for this tag. That requires updating the expressions
 * in any attributes on the tag, and then copying the result onto opts.
 * @this Tag
 * @param   {Boolean} isLoop - is it a loop tag?
 * @param   { Tag }  parent - parent tag node
 * @param   { Boolean }  isAnonymous - is it a tag without any impl? (a tag not registered)
 * @param   { Object }  opts - tag options
 * @param   { Array }  instAttrs - tag attributes array
 */
function updateOpts(isLoop, parent, isAnonymous, opts, instAttrs) {
  // isAnonymous `each` tags treat `dom` and `root` differently. In this case
  // (and only this case) we don't need to do updateOpts, because the regular parse
  // will update those attrs. Plus, isAnonymous tags don't need opts anyway
  if (isLoop && isAnonymous) return
  const ctx = !isAnonymous && isLoop ? this : parent || this

  each(instAttrs, (attr) => {
    if (attr.expr) update.call(ctx, [attr.expr])
    // normalize the attribute names
    opts[toCamel(attr.name).replace(ATTRS_PREFIX, '')] = attr.expr ? attr.expr.value : attr.value
  })
}

/**
 * Manage the mount state of a tag triggering also the observable events
 * @this Tag
 * @param { Boolean } value - ..of the isMounted flag
 */
function setMountState(value) {
  const { isAnonymous } = this.__

  defineProperty(this, 'isMounted', value)

  if (!isAnonymous) {
    if (value) this.trigger('mount')
    else {
      this.trigger('unmount')
      this.off('*')
      this.__.wasCreated = false
    }
  }
}

/**
 * Tag class
 * @constructor
 * @param { Object } impl - it contains the tag template, and logic
 * @param { Object } conf - tag options
 * @param { String } innerHTML - html that eventually we need to inject in the tag
 */
export default function Tag(impl = {}, conf = {}, innerHTML) {
  var opts = extend({}, conf.opts),
    parent = conf.parent,
    isLoop = conf.isLoop,
    isAnonymous = !!conf.isAnonymous,
    skipAnonymous = settings.skipAnonymousTags && isAnonymous,
    item = conf.item,
    index = conf.index, // available only for the looped nodes
    instAttrs = [], // All attributes on the Tag when it's first parsed
    implAttrs = [], // expressions on this type of Tag
    expressions = [],
    root = conf.root,
    tagName = conf.tagName || getTagName(root),
    isVirtual = tagName === 'virtual',
    isInline = !isVirtual && !impl.tmpl,
    propsInSyncWithParent = [],
    dom

  // make this tag observable
  if (!skipAnonymous) observable(this)
  // only call unmount if we have a valid __TAG_IMPL (has name property)
  if (impl.name && root._tag) root._tag.unmount(true)

  // not yet mounted
  defineProperty(this, 'isMounted', false)

  defineProperty(this, '__', {
    isAnonymous,
    instAttrs,
    innerHTML,
    tagName,
    index,
    isLoop,
    isInline,
    // tags having event listeners
    // it would be better to use weak maps here but we can not introduce breaking changes now
    listeners: [],
    // these vars will be needed only for the virtual tags
    virts: [],
    wasCreated: false,
    tail: null,
    head: null,
    parent: null,
    item: null
  })

  // create a unique id to this tag
  // it could be handy to use it also to improve the virtual dom rendering speed
  defineProperty(this, '_riot_id', ++uid) // base 1 allows test !t._riot_id
  defineProperty(this, 'root', root)
  extend(this, { opts }, item)
  // protect the "tags" and "refs" property from being overridden
  defineProperty(this, 'parent', parent || null)
  defineProperty(this, 'tags', {})
  defineProperty(this, 'refs', {})

  if (isInline || isLoop && isAnonymous) {
    dom = root
  } else {
    if (!isVirtual) root.innerHTML = ''
    dom = mkdom(impl.tmpl, innerHTML, isSvg(root))
  }

  /**
   * Update the tag expressions and options
   * @param   { * }  data - data we want to use to extend the tag properties
   * @returns { Tag } the current tag instance
   */
  defineProperty(this, 'update', function tagUpdate(data) {
    const nextOpts = {},
      canTrigger = this.isMounted && !skipAnonymous

    extend(this, data)
    updateOpts.apply(this, [isLoop, parent, isAnonymous, nextOpts, instAttrs])

    if (
      canTrigger &&
      this.isMounted &&
      isFunction(this.shouldUpdate) && !this.shouldUpdate(data, nextOpts)
    ) {
      return this
    }

    // inherit properties from the parent, but only for isAnonymous tags
    if (isLoop && isAnonymous) inheritFrom.apply(this, [this.parent, propsInSyncWithParent])
    extend(opts, nextOpts)
    if (canTrigger) this.trigger('update', data)
    update.call(this, expressions)
    if (canTrigger) this.trigger('updated')

    return this

  }.bind(this))

  /**
   * Add a mixin to this tag
   * @returns { Tag } the current tag instance
   */
  defineProperty(this, 'mixin', function tagMixin() {
    each(arguments, (mix) => {
      let instance, obj
      let props = []

      // properties blacklisted and will not be bound to the tag instance
      const propsBlacklist = ['init', '__proto__']

      mix = isString(mix) ? mixin(mix) : mix

      // check if the mixin is a function
      if (isFunction(mix)) {
        // create the new mixin instance
        instance = new mix()
      } else instance = mix

      const proto = Object.getPrototypeOf(instance)

      // build multilevel prototype inheritance chain property list
      do props = props.concat(Object.getOwnPropertyNames(obj || instance))
      while (obj = Object.getPrototypeOf(obj || instance))

      // loop the keys in the function prototype or the all object keys
      each(props, (key) => {
        // bind methods to this
        // allow mixins to override other properties/parent mixins
        if (!contains(propsBlacklist, key)) {
          // check for getters/setters
          const descriptor = Object.getOwnPropertyDescriptor(instance, key) || Object.getOwnPropertyDescriptor(proto, key)
          const hasGetterSetter = descriptor && (descriptor.get || descriptor.set)

          // apply method only if it does not already exist on the instance
          if (!this.hasOwnProperty(key) && hasGetterSetter) {
            Object.defineProperty(this, key, descriptor)
          } else {
            this[key] = isFunction(instance[key]) ?
              instance[key].bind(this) :
              instance[key]
          }
        }
      })

      // init method will be called automatically
      if (instance.init)
        instance.init.bind(this)(opts)
    })
    return this
  }.bind(this))

  /**
   * Mount the current tag instance
   * @returns { Tag } the current tag instance
   */
  defineProperty(this, 'mount', function tagMount() {
    root._tag = this // keep a reference to the tag just created

    // Read all the attrs on this instance. This give us the info we need for updateOpts
    parseAttributes.apply(parent, [root, root.attributes, (attr, expr) => {
      if (!isAnonymous && RefExpr.isPrototypeOf(expr)) expr.tag = this
      attr.expr = expr
      instAttrs.push(attr)
    }])

    // update the root adding custom attributes coming from the compiler
    implAttrs = []
    walkAttrs(impl.attrs, (k, v) => { implAttrs.push({name: k, value: v}) })
    parseAttributes.apply(this, [root, implAttrs, (attr, expr) => {
      if (expr) expressions.push(expr)
      else setAttr(root, attr.name, attr.value)
    }])

    // initialiation
    updateOpts.apply(this, [isLoop, parent, isAnonymous, opts, instAttrs])

    // add global mixins
    const globalMixin = mixin(GLOBAL_MIXIN)

    if (globalMixin && !skipAnonymous) {
      for (var i in globalMixin) {
        if (globalMixin.hasOwnProperty(i)) {
          this.mixin(globalMixin[i])
        }
      }
    }

    if (impl.fn) impl.fn.call(this, opts)

    if (!skipAnonymous) this.trigger('before-mount')

    // parse layout after init. fn may calculate args for nested custom tags
    parseExpressions.apply(this, [dom, expressions, isAnonymous])

    this.update(item)

    if (!isAnonymous && !isInline) {
      while (dom.firstChild) root.appendChild(dom.firstChild)
    }

    defineProperty(this, 'root', root)

    // if we need to wait that the parent "mount" or "updated" event gets triggered
    if (!skipAnonymous && this.parent) {
      const p = getImmediateCustomParentTag(this.parent)
      p.one(!p.isMounted ? 'mount' : 'updated', () => {
        setMountState.call(this, true)
      })
    } else {
      // otherwise it's not a child tag we can trigger its mount event
      setMountState.call(this, true)
    }

    this.__.wasCreated = true

    return this

  }.bind(this))

  /**
   * Unmount the tag instance
   * @param { Boolean } mustKeepRoot - if it's true the root node will not be removed
   * @returns { Tag } the current tag instance
   */
  defineProperty(this, 'unmount', function tagUnmount(mustKeepRoot) {
    const el = this.root
    const p = el.parentNode
    const tagIndex = __TAGS_CACHE.indexOf(this)
    let ptag

    if (!skipAnonymous) this.trigger('before-unmount')

    // clear all attributes coming from the mounted tag
    walkAttrs(impl.attrs, (name) => {
      if (startsWith(name, ATTRS_PREFIX))
        name = name.slice(ATTRS_PREFIX.length)

      remAttr(root, name)
    })

    // remove all the event listeners
    this.__.listeners.forEach((dom) => {
      Object.keys(dom[RIOT_EVENTS_KEY]).forEach((eventName) => {
        dom.removeEventListener(eventName, dom[RIOT_EVENTS_KEY][eventName])
      })
    })

    // remove this tag instance from the global virtualDom variable
    if (tagIndex !== -1)
      __TAGS_CACHE.splice(tagIndex, 1)

    if (p || isVirtual) {
      if (parent) {
        ptag = getImmediateCustomParentTag(parent)

        if (isVirtual) {
          Object.keys(this.tags).forEach(tagName => {
            arrayishRemove(ptag.tags, tagName, this.tags[tagName])
          })
        } else {
          arrayishRemove(ptag.tags, tagName, this)
          // remove from _parent too
          if(parent !== ptag) {
            arrayishRemove(parent.tags, tagName, this)
          }
        }
      } else {
        // remove the tag contents
        setInnerHTML(el, '')
      }

      if (p && !mustKeepRoot) p.removeChild(el)
    }

    if (this.__.virts) {
      each(this.__.virts, (v) => {
        if (v.parentNode) v.parentNode.removeChild(v)
      })
    }

    // allow expressions to unmount themselves
    unmountAll(expressions)
    each(instAttrs, a => a.expr && a.expr.unmount && a.expr.unmount())

    // custom internal unmount function to avoid relying on the observable
    if (this.__.onUnmount) this.__.onUnmount()

    // weird fix for a weird edge case #2409
    if (!this.isMounted) setMountState.call(this, true)

    setMountState.call(this, false)

    delete this.root._tag

    return this

  }.bind(this))
}
<commit_msg>updated: comment regarding #2436<commit_after>import observable from 'riot-observable'
import { parseExpressions, parseAttributes } from './parse'
import RefExpr from './ref'
import update from './update'
import mkdom from './mkdom'
import { mixin } from './core'
import settings from '../../settings'
import { setAttr, remAttr, walkAttrs, setInnerHTML, isSvg } from './../common/util/dom'

import {
  isFunction,
  isString
} from './../common/util/check'

import {
  extend,
  each,
  startsWith,
  toCamel,
  contains,
  defineProperty
} from './../common/util/misc'

import {
  unmountAll,
  arrayishRemove,
  inheritFrom,
  getTagName,
  getImmediateCustomParentTag
} from './../common/util/tags'

import {
  RIOT_EVENTS_KEY,
  GLOBAL_MIXIN,
  __TAGS_CACHE,
  ATTRS_PREFIX
} from './../common/global-variables'

// counter to give a unique id to all the Tag instances
let uid = 0

/**
 * We need to update opts for this tag. That requires updating the expressions
 * in any attributes on the tag, and then copying the result onto opts.
 * @this Tag
 * @param   {Boolean} isLoop - is it a loop tag?
 * @param   { Tag }  parent - parent tag node
 * @param   { Boolean }  isAnonymous - is it a tag without any impl? (a tag not registered)
 * @param   { Object }  opts - tag options
 * @param   { Array }  instAttrs - tag attributes array
 */
function updateOpts(isLoop, parent, isAnonymous, opts, instAttrs) {
  // isAnonymous `each` tags treat `dom` and `root` differently. In this case
  // (and only this case) we don't need to do updateOpts, because the regular parse
  // will update those attrs. Plus, isAnonymous tags don't need opts anyway
  if (isLoop && isAnonymous) return
  const ctx = !isAnonymous && isLoop ? this : parent || this

  each(instAttrs, (attr) => {
    if (attr.expr) update.call(ctx, [attr.expr])
    // normalize the attribute names
    opts[toCamel(attr.name).replace(ATTRS_PREFIX, '')] = attr.expr ? attr.expr.value : attr.value
  })
}

/**
 * Manage the mount state of a tag triggering also the observable events
 * @this Tag
 * @param { Boolean } value - ..of the isMounted flag
 */
function setMountState(value) {
  const { isAnonymous } = this.__

  defineProperty(this, 'isMounted', value)

  if (!isAnonymous) {
    if (value) this.trigger('mount')
    else {
      this.trigger('unmount')
      this.off('*')
      this.__.wasCreated = false
    }
  }
}

/**
 * Tag class
 * @constructor
 * @param { Object } impl - it contains the tag template, and logic
 * @param { Object } conf - tag options
 * @param { String } innerHTML - html that eventually we need to inject in the tag
 */
export default function Tag(impl = {}, conf = {}, innerHTML) {
  var opts = extend({}, conf.opts),
    parent = conf.parent,
    isLoop = conf.isLoop,
    isAnonymous = !!conf.isAnonymous,
    skipAnonymous = settings.skipAnonymousTags && isAnonymous,
    item = conf.item,
    index = conf.index, // available only for the looped nodes
    instAttrs = [], // All attributes on the Tag when it's first parsed
    implAttrs = [], // expressions on this type of Tag
    expressions = [],
    root = conf.root,
    tagName = conf.tagName || getTagName(root),
    isVirtual = tagName === 'virtual',
    isInline = !isVirtual && !impl.tmpl,
    propsInSyncWithParent = [],
    dom

  // make this tag observable
  if (!skipAnonymous) observable(this)
  // only call unmount if we have a valid __TAG_IMPL (has name property)
  if (impl.name && root._tag) root._tag.unmount(true)

  // not yet mounted
  defineProperty(this, 'isMounted', false)

  defineProperty(this, '__', {
    isAnonymous,
    instAttrs,
    innerHTML,
    tagName,
    index,
    isLoop,
    isInline,
    // tags having event listeners
    // it would be better to use weak maps here but we can not introduce breaking changes now
    listeners: [],
    // these vars will be needed only for the virtual tags
    virts: [],
    wasCreated: false,
    tail: null,
    head: null,
    parent: null,
    item: null
  })

  // create a unique id to this tag
  // it could be handy to use it also to improve the virtual dom rendering speed
  defineProperty(this, '_riot_id', ++uid) // base 1 allows test !t._riot_id
  defineProperty(this, 'root', root)
  extend(this, { opts }, item)
  // protect the "tags" and "refs" property from being overridden
  defineProperty(this, 'parent', parent || null)
  defineProperty(this, 'tags', {})
  defineProperty(this, 'refs', {})

  if (isInline || isLoop && isAnonymous) {
    dom = root
  } else {
    if (!isVirtual) root.innerHTML = ''
    dom = mkdom(impl.tmpl, innerHTML, isSvg(root))
  }

  /**
   * Update the tag expressions and options
   * @param   { * }  data - data we want to use to extend the tag properties
   * @returns { Tag } the current tag instance
   */
  defineProperty(this, 'update', function tagUpdate(data) {
    const nextOpts = {},
      canTrigger = this.isMounted && !skipAnonymous

    extend(this, data)
    updateOpts.apply(this, [isLoop, parent, isAnonymous, nextOpts, instAttrs])

    if (
      canTrigger &&
      this.isMounted &&
      isFunction(this.shouldUpdate) && !this.shouldUpdate(data, nextOpts)
    ) {
      return this
    }

    // inherit properties from the parent, but only for isAnonymous tags
    if (isLoop && isAnonymous) inheritFrom.apply(this, [this.parent, propsInSyncWithParent])
    extend(opts, nextOpts)
    if (canTrigger) this.trigger('update', data)
    update.call(this, expressions)
    if (canTrigger) this.trigger('updated')

    return this

  }.bind(this))

  /**
   * Add a mixin to this tag
   * @returns { Tag } the current tag instance
   */
  defineProperty(this, 'mixin', function tagMixin() {
    each(arguments, (mix) => {
      let instance, obj
      let props = []

      // properties blacklisted and will not be bound to the tag instance
      const propsBlacklist = ['init', '__proto__']

      mix = isString(mix) ? mixin(mix) : mix

      // check if the mixin is a function
      if (isFunction(mix)) {
        // create the new mixin instance
        instance = new mix()
      } else instance = mix

      const proto = Object.getPrototypeOf(instance)

      // build multilevel prototype inheritance chain property list
      do props = props.concat(Object.getOwnPropertyNames(obj || instance))
      while (obj = Object.getPrototypeOf(obj || instance))

      // loop the keys in the function prototype or the all object keys
      each(props, (key) => {
        // bind methods to this
        // allow mixins to override other properties/parent mixins
        if (!contains(propsBlacklist, key)) {
          // check for getters/setters
          const descriptor = Object.getOwnPropertyDescriptor(instance, key) || Object.getOwnPropertyDescriptor(proto, key)
          const hasGetterSetter = descriptor && (descriptor.get || descriptor.set)

          // apply method only if it does not already exist on the instance
          if (!this.hasOwnProperty(key) && hasGetterSetter) {
            Object.defineProperty(this, key, descriptor)
          } else {
            this[key] = isFunction(instance[key]) ?
              instance[key].bind(this) :
              instance[key]
          }
        }
      })

      // init method will be called automatically
      if (instance.init)
        instance.init.bind(this)(opts)
    })
    return this
  }.bind(this))

  /**
   * Mount the current tag instance
   * @returns { Tag } the current tag instance
   */
  defineProperty(this, 'mount', function tagMount() {
    root._tag = this // keep a reference to the tag just created

    // Read all the attrs on this instance. This give us the info we need for updateOpts
    parseAttributes.apply(parent, [root, root.attributes, (attr, expr) => {
      if (!isAnonymous && RefExpr.isPrototypeOf(expr)) expr.tag = this
      attr.expr = expr
      instAttrs.push(attr)
    }])

    // update the root adding custom attributes coming from the compiler
    implAttrs = []
    walkAttrs(impl.attrs, (k, v) => { implAttrs.push({name: k, value: v}) })
    parseAttributes.apply(this, [root, implAttrs, (attr, expr) => {
      if (expr) expressions.push(expr)
      else setAttr(root, attr.name, attr.value)
    }])

    // initialiation
    updateOpts.apply(this, [isLoop, parent, isAnonymous, opts, instAttrs])

    // add global mixins
    const globalMixin = mixin(GLOBAL_MIXIN)

    if (globalMixin && !skipAnonymous) {
      for (var i in globalMixin) {
        if (globalMixin.hasOwnProperty(i)) {
          this.mixin(globalMixin[i])
        }
      }
    }

    if (impl.fn) impl.fn.call(this, opts)

    if (!skipAnonymous) this.trigger('before-mount')

    // parse layout after init. fn may calculate args for nested custom tags
    parseExpressions.apply(this, [dom, expressions, isAnonymous])

    this.update(item)

    if (!isAnonymous && !isInline) {
      while (dom.firstChild) root.appendChild(dom.firstChild)
    }

    defineProperty(this, 'root', root)

    // if we need to wait that the parent "mount" or "updated" event gets triggered
    if (!skipAnonymous && this.parent) {
      const p = getImmediateCustomParentTag(this.parent)
      p.one(!p.isMounted ? 'mount' : 'updated', () => {
        setMountState.call(this, true)
      })
    } else {
      // otherwise it's not a child tag we can trigger its mount event
      setMountState.call(this, true)
    }

    this.__.wasCreated = true

    return this

  }.bind(this))

  /**
   * Unmount the tag instance
   * @param { Boolean } mustKeepRoot - if it's true the root node will not be removed
   * @returns { Tag } the current tag instance
   */
  defineProperty(this, 'unmount', function tagUnmount(mustKeepRoot) {
    const el = this.root
    const p = el.parentNode
    const tagIndex = __TAGS_CACHE.indexOf(this)
    let ptag

    if (!skipAnonymous) this.trigger('before-unmount')

    // clear all attributes coming from the mounted tag
    walkAttrs(impl.attrs, (name) => {
      if (startsWith(name, ATTRS_PREFIX))
        name = name.slice(ATTRS_PREFIX.length)

      remAttr(root, name)
    })

    // remove all the event listeners
    this.__.listeners.forEach((dom) => {
      Object.keys(dom[RIOT_EVENTS_KEY]).forEach((eventName) => {
        dom.removeEventListener(eventName, dom[RIOT_EVENTS_KEY][eventName])
      })
    })

    // remove this tag instance from the global virtualDom variable
    if (tagIndex !== -1)
      __TAGS_CACHE.splice(tagIndex, 1)

    if (p || isVirtual) {
      if (parent) {
        ptag = getImmediateCustomParentTag(parent)

        if (isVirtual) {
          Object.keys(this.tags).forEach(tagName => {
            arrayishRemove(ptag.tags, tagName, this.tags[tagName])
          })
        } else {
          arrayishRemove(ptag.tags, tagName, this)
          // remove from _parent too
          if(parent !== ptag) {
            arrayishRemove(parent.tags, tagName, this)
          }
        }
      } else {
        // remove the tag contents
        setInnerHTML(el, '')
      }

      if (p && !mustKeepRoot) p.removeChild(el)
    }

    if (this.__.virts) {
      each(this.__.virts, (v) => {
        if (v.parentNode) v.parentNode.removeChild(v)
      })
    }

    // allow expressions to unmount themselves
    unmountAll(expressions)
    each(instAttrs, a => a.expr && a.expr.unmount && a.expr.unmount())

    // custom internal unmount function to avoid relying on the observable
    if (this.__.onUnmount) this.__.onUnmount()

    // weird fix for a weird edge case #2409 and #2436
    // some users might use your software not as you've expected
    // so I need to add these dirty hacks to mitigate unexpected issues
    if (!this.isMounted) setMountState.call(this, true)

    setMountState.call(this, false)

    delete this.root._tag

    return this

  }.bind(this))
}
<|endoftext|>


<commit_before>var http = require('http'),
    sys = require('sys'),
    API_URI = 'http://api.dropbox.com/',
    CONTENT_API_URI = 'https://api-content.dropbox.com/',
    API_VERSION = '0'

// Returns a Dropbox Client, through which API calls can be made.
var DropboxClient = exports.DropboxClient =
  function(oauth, access_token, access_token_secret) {
    this.oauth = oauth
    this.access_token = access_token
    this.access_token_secret = access_token_secret
  }

// Retrieves information about the user's account as a JSON response.
DropboxClient.prototype.getAccountInfo = function(callback) {
  this.oauth.get(API_URI + API_VERSION + '/account/info/',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Retrieves contents of a file specified by path argument, relative to
// user's Dropbox root.
DropboxClient.prototype.getFile = function(path, callback) {
  this.oauth.get(CONTENT_API_URI + API_VERSION + '/files/dropbox/' + path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Uploads contents of a file specified by path argument, relative to
// application's directory.
// TODO: Make this work!
DropboxClient.prototype.putFile = function(file, path, callback) {
  var boundary = 'sAxIqse3tPlHqUIUI9ofVlHvtdt3tpaG',
      content_type = 'multipart/form-data; boundary=' + boundary,
      file_contents = require('fs').readFileSync(file)

  // Build request body.
  var body = '--' + boundary + '\r\n' +
    'Content-Disposition: form-data; name=file; filename=' + file + '\r\n' +
    'Content-type: application/octet-stream\r\n' +
    '\r\n' + file_contents + '\r\n' +
    '--' + boundary + '--'
  this.oauth.post(CONTENT_API_URI + API_VERSION + '/files/dropbox/' + path +
                 '?file=' + file,
                 this.access_token, this.access_token_secret,
                 'test', body,
                 function(err, data, res) {
                   callback(err, data)})
}

// Gets metadata of file/folder specified by path relative to user's
// Dropbox root.
// TODO: Add file_limit param, others?
DropboxClient.prototype.getMetadata = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/metadata/dropbox/' + path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Downloads a minimized jpeg thumbnail for a photo. See
// https://www.dropbox.com/developers/docs#thumbnails for a list of
// valid size specifiers.
DropboxClient.prototype.getThumbnail = function(path, size, callback) {
  if (typeof(size) == 'function') callback = size, size = null
  this.oauth.get(CONTENT_API_URI + API_VERSION + '/thumbnails/dropbox/' +
                 path + ((size) ? '?size=' + size : ''),
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Copies a file or folder to a new location.
// See https://www.dropbox.com/developers/docs#fileops-copy for explanation
// of arguments.
DropboxClient.prototype.copy = function(from_path, to_path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/copy?from_path=' +
                 from_path + '&root=dropbox&to_path=' + to_path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Creates a folder relative to the user's Dropbox root.
// See https://www.dropbox.com/developers/docs#fileops-create-folder
// for explanation of arguments.
DropboxClient.prototype.createFolder = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/create_folder?path='
                 + path +'&root=dropbox',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Deletes a file or folder.
// See https://www.dropbox.com/developers/docs#fileops-delete for
// explanation of arguments.
DropboxClient.prototype.delete = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/delete?path=' +
                 path + '&root=dropbox',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Moves a file or folder.
// See https://www.dropbox.com/developers/docs#fileops-move for
// explanation of arguments.
DropboxClient.prototype.move = function(from_path, to_path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/move?from_path=' +
                 from_path + '&root=dropbox&to_path=' + to_path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}<commit_msg>Got file-uploading to work!<commit_after>var http = require('http'),
    sys = require('sys'),
    API_URI = 'http://api.dropbox.com/',
    CONTENT_API_URI = 'https://api-content.dropbox.com/',
    API_VERSION = '0'

// Returns a Dropbox Client, through which API calls can be made.
var DropboxClient = exports.DropboxClient =
  function(oauth, access_token, access_token_secret) {
    this.oauth = oauth
    this.access_token = access_token
    this.access_token_secret = access_token_secret
  }

// Retrieves information about the user's account as a JSON response.
DropboxClient.prototype.getAccountInfo = function(callback) {
  this.oauth.get(API_URI + API_VERSION + '/account/info/',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Retrieves contents of a file specified by path argument, relative to
// user's Dropbox root.
DropboxClient.prototype.getFile = function(path, callback) {
  this.oauth.get(CONTENT_API_URI + API_VERSION + '/files/dropbox/' + path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Uploads contents of a file specified by path argument, relative to
// application's directory.
DropboxClient.prototype.putFile = function(file, path, callback) {
  var boundary = 'sAxIqse3tPlHqUIUI9ofVlHvtdt3tpaG',
      content_type = 'multipart/form-data; boundary=' + boundary,
      file_contents = require('fs').readFileSync(file)

  // Build request body.
  var body = '--' + boundary + '\r\n' +
    'Content-Disposition: form-data; name=file; filename=' + file + '\r\n' +
    'Content-type: application/octet-stream\r\n' +
    '\r\n' + file_contents + '\r\n' +
    '--' + boundary + '--'
  this.oauth.post(CONTENT_API_URI + API_VERSION + '/files/dropbox/' + path +
                  '?file=' + file,
                  this.access_token, this.access_token_secret,
                  body, content_type,
                  function(err, data, res) {
                    callback(err, data)})
}

// Gets metadata of file/folder specified by path relative to user's
// Dropbox root.
// TODO: Add file_limit param, others?
DropboxClient.prototype.getMetadata = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/metadata/dropbox/' + path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Downloads a minimized jpeg thumbnail for a photo. See
// https://www.dropbox.com/developers/docs#thumbnails for a list of
// valid size specifiers.
DropboxClient.prototype.getThumbnail = function(path, size, callback) {
  if (typeof(size) == 'function') callback = size, size = null
  this.oauth.get(CONTENT_API_URI + API_VERSION + '/thumbnails/dropbox/' +
                 path + ((size) ? '?size=' + size : ''),
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Copies a file or folder to a new location.
// See https://www.dropbox.com/developers/docs#fileops-copy for explanation
// of arguments.
DropboxClient.prototype.copy = function(from_path, to_path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/copy?from_path=' +
                 from_path + '&root=dropbox&to_path=' + to_path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Creates a folder relative to the user's Dropbox root.
// See https://www.dropbox.com/developers/docs#fileops-create-folder
// for explanation of arguments.
DropboxClient.prototype.createFolder = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/create_folder?path='
                 + path +'&root=dropbox',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Deletes a file or folder.
// See https://www.dropbox.com/developers/docs#fileops-delete for
// explanation of arguments.
DropboxClient.prototype.delete = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/delete?path=' +
                 path + '&root=dropbox',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}

// Moves a file or folder.
// See https://www.dropbox.com/developers/docs#fileops-move for
// explanation of arguments.
DropboxClient.prototype.move = function(from_path, to_path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/move?from_path=' +
                 from_path + '&root=dropbox&to_path=' + to_path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data)})
}<|endoftext|>


<commit_before>angular.module('weatherHistory.controllers')
.controller('ListCtrl', function($scope, $filter, settingsFactory, geocoder, forecastFactory) {
  $scope.loadData = loadData;
  $scope.reloadData = reloadData;
  $scope.canLoadData = canLoadData;
  $scope.models = {
    date: forecastFactory.date,
    place: {
      details: {},
      place: null
    }};
  $scope.list = [];
  var expectedLength = 3,
    canLoad = true,
    LENGTH = 3;

  $scope.$on('list:reload', reloadData);
  $scope.$watch('list.length', orderList);
  $scope.$watch('models.place.details', getNewPlace);
  $scope.$watch('models.date', getNewDate);

  /**
   * Load data from forecast.io. Used in infinite scroll and called whenever
   * settings or place change.
   */
  function loadData() {
    settingsFactory.getDeferred()
      .then(function(settings) {
        $scope.city = settings.city;
        $scope.country = settings.country;
        $scope.formattedDate = moment(settings.date).format(settings.dateFormat);
        var interval = settings.interval,
          oldLength = $scope.list.length * interval,
          YYYY = moment(settings.date).format('YYYY'),
          MM = moment(settings.date).format('MM'),
          DD = moment(settings.date).format('DD'),
          HH = moment(settings.date).format('HH'),
          mm = moment(settings.date).format('mm'),
          ss = moment(settings.date).format('ss');

        for (var i = 0; i < LENGTH; i++) {
          var sub = oldLength + i * interval,
            time = YYYY-sub+'-'+MM+'-'+DD+'T'+HH+':'+mm+':'+ss;
          forecastFactory.getForecast(settings.latitude, settings.longitude, time, settings)
            .then(handleData);
        }
      });
  }

  /**
   * Handle data received from api calls in loadData for loop.
   *
   * @param {Object} forecast - Forecast data
   */
  function handleData(forecast) {
    // Check we're still getting data otherwise stop infinite scroll
    if (forecast.data.currently.icon) {
      forecast.data.year = parseInt(moment.unix(forecast.data.currently.time).format('YYYY'), 10);
      forecast.data.currently.icon = forecastFactory.renameIcons(forecast.data.currently.icon);
      $scope.list.push(forecast.data);
    } else {
      canLoad = false;

      // Last two items end up switched so here's a hack
      var listLength = $scope.list,
        penUltimate, ultimate;
      angular.copy($scope.list[listLength-2], ultimate),
      angular.copy($scope.list[listLength-1], penUltimate);
      $scope.list[listLength-1] = penUltimate;
      $scope.list[listLength-2] = ultimate;
    }
  }

  /**
   * Watch to see when api calls are done and list is full of new data. Orders only new data.
   *
   * @param {Number} newLength - New length
   * @param {Number} oldLength - Old length
   */
  function orderList(newLength, oldLength) {
    if (newLength !== oldLength) {
      if (newLength === expectedLength) {
        var recentlyAdded = $scope.list.splice(newLength - LENGTH, LENGTH);
        recentlyAdded = $filter('orderBy')(recentlyAdded, 'year', true);
        $scope.list = $scope.list.concat(recentlyAdded);
        expectedLength = expectedLength + LENGTH;
        $scope.$broadcast('scroll.infiniteScrollComplete');
      }
    }
  }

  /**
   * Reload data. Reset list and its expected length, clear cache, and then load data. Used when
   * setting, date, or place change.
   *
   * @param {Boolean} pulledToRefresh - True if using pull to refresh directive
   */
  function reloadData(pulledToRefresh) {
    $scope.list = [];
    expectedLength = LENGTH;
    canLoad = true;
    forecastFactory.clearCache();
    loadData();

    // Make conditional since it uses javascript to scroll which triggers infinite scroll to
    // call its method (meaning data is duplicated).
    if (pulledToRefresh) {
      $scope.$broadcast('scroll.refreshComplete');
    }
  }

  /**
   * Used when older forecasts can't be retrieved anymore.
   *
   * @return {Boolean} canLoad - Whether data can be loaded
   */
  function canLoadData() {
    return canLoad;
  }

  /**
   * Watch function to handle user getting new location from google maps places search
   *
   * @param {Object} newPlace - New place from google search
   * @param {Object} oldPlace - Old place
   */
  function getNewPlace(newPlace, oldPlace) {
    if (newPlace !== oldPlace) {
      // Put city and country into $scope
      angular.extend($scope, geocoder.parseAddressComponents(newPlace.address_components));
      $scope.latitude = parseFloat(newPlace.geometry.location.A, 10);
      $scope.longitude = parseFloat(newPlace.geometry.location.F, 10);
      settingsFactory.set({
        city: $scope.city,
        country: $scope.country,
        latitude: $scope.latitude,
        longitude: $scope.longitude
      });
      reloadData();
      $scope.models.place.place = '';
    }
  }

  /**
   * Watch function to handle getting new date from datepicker, closing the modal, and
   * getting weather with new date.
   *
   * @param {Date} newDate - New date input
   * @param {Date} oldDate - Old date input
   */
  function getNewDate(newDate, oldDate) {
    if (newDate !== oldDate) {
      // TODO: Doesn't close when picking same day after changing months
      if (moment(newDate).isSame(oldDate, 'month')) {
        settingsFactory.set({date: newDate});
        reloadData();
        $scope.$broadcast('DatepickerModal:closeModal');
      }
    }
  }
});

<commit_msg>Fixed accuracy of time again so that each year gets the same time of the day.<commit_after>angular.module('weatherHistory.controllers')
.controller('ListCtrl', function($scope, $filter, settingsFactory, geocoder, forecastFactory) {
  $scope.loadData = loadData;
  $scope.reloadData = reloadData;
  $scope.canLoadData = canLoadData;
  $scope.models = {
    date: forecastFactory.date,
    place: {
      details: {},
      place: null
    }};
  $scope.list = [];
  var expectedLength = 3,
    canLoad = true,
    LENGTH = 3;

  $scope.$on('list:reload', reloadData);
  $scope.$watch('list.length', orderList);
  $scope.$watch('models.place.details', getNewPlace);
  $scope.$watch('models.date', getNewDate);

  /**
   * Load data from forecast.io. Used in infinite scroll and called whenever
   * settings or place change.
   */
  function loadData() {
    settingsFactory.getDeferred()
      .then(function(settings) {
        $scope.city = settings.city;
        $scope.country = settings.country;
        $scope.formattedDate = moment(settings.date).format(settings.dateFormat);
        var interval = settings.interval,
          oldLength = $scope.list.length * interval,
          YYYY = moment(settings.date).format('YYYY'),
          MM = moment(settings.date).format('MM'),
          DD = moment(settings.date).format('DD'),
          HH = moment(settings.date).format('HH'),
          mm = moment(settings.date).format('mm'),
          ss = moment(settings.date).format('ss');

        for (var i = 0; i < LENGTH; i++) {
          var sub = oldLength + i * interval,
            time = YYYY-sub+'-'+MM+'-'+DD+'T'+HH+':'+mm+':'+ss;
          forecastFactory.getForecast(settings.latitude, settings.longitude, time, settings)
            .then(handleData);
        }
      });
  }

  /**
   * Handle data received from api calls in loadData for loop.
   *
   * @param {Object} forecast - Forecast data
   */
  function handleData(forecast) {
    // Check we're still getting data otherwise stop infinite scroll
    if (forecast.data.currently.icon) {
      forecast.data.year = parseInt(moment.unix(forecast.data.currently.time).format('YYYY'), 10);
      forecast.data.currently.icon = forecastFactory.renameIcons(forecast.data.currently.icon);
      $scope.list.push(forecast.data);
    } else {
      canLoad = false;

      // Last two items end up switched so here's a hack
      var listLength = $scope.list,
        penUltimate, ultimate;
      angular.copy($scope.list[listLength-2], ultimate),
      angular.copy($scope.list[listLength-1], penUltimate);
      $scope.list[listLength-1] = penUltimate;
      $scope.list[listLength-2] = ultimate;
    }
  }

  /**
   * Watch to see when api calls are done and list is full of new data. Orders only new data.
   *
   * @param {Number} newLength - New length
   * @param {Number} oldLength - Old length
   */
  function orderList(newLength, oldLength) {
    if (newLength !== oldLength) {
      if (newLength === expectedLength) {
        var recentlyAdded = $scope.list.splice(newLength - LENGTH, LENGTH);
        recentlyAdded = $filter('orderBy')(recentlyAdded, 'year', true);
        $scope.list = $scope.list.concat(recentlyAdded);
        expectedLength = expectedLength + LENGTH;
        $scope.$broadcast('scroll.infiniteScrollComplete');
      }
    }
  }

  /**
   * Reload data. Reset list and its expected length, clear cache, and then load data. Used when
   * setting, date, or place change.
   *
   * @param {Boolean} pulledToRefresh - True if using pull to refresh directive
   */
  function reloadData(pulledToRefresh) {
    $scope.list = [];
    expectedLength = LENGTH;
    canLoad = true;
    forecastFactory.clearCache();
    loadData();

    // Make conditional since it uses javascript to scroll which triggers infinite scroll to
    // call its method (meaning data is duplicated).
    if (pulledToRefresh) {
      $scope.$broadcast('scroll.refreshComplete');
    }
  }

  /**
   * Used when older forecasts can't be retrieved anymore.
   *
   * @return {Boolean} canLoad - Whether data can be loaded
   */
  function canLoadData() {
    return canLoad;
  }

  /**
   * Watch function to handle user getting new location from google maps places search
   *
   * @param {Object} newPlace - New place from google search
   * @param {Object} oldPlace - Old place
   */
  function getNewPlace(newPlace, oldPlace) {
    if (newPlace !== oldPlace) {
      // Put city and country into $scope
      angular.extend($scope, geocoder.parseAddressComponents(newPlace.address_components));
      $scope.latitude = parseFloat(newPlace.geometry.location.A, 10);
      $scope.longitude = parseFloat(newPlace.geometry.location.F, 10);
      settingsFactory.set({
        city: $scope.city,
        country: $scope.country,
        latitude: $scope.latitude,
        longitude: $scope.longitude
      });
      reloadData();
      $scope.models.place.place = '';
    }
  }

  /**
   * Watch function to handle getting new date from datepicker, closing the modal, and
   * getting weather with new date.
   *
   * @param {Date} newDate - New date input
   * @param {Date} oldDate - Old date input
   */
  function getNewDate(newDate, oldDate) {
    if (newDate !== oldDate) {
      // TODO: Doesn't close when picking same day after changing months
      if (moment(newDate).isSame(oldDate, 'month')) {
        newDate = new Date(newDate);
        var YYYY = newDate.getFullYear(),
          MM = newDate.getMonth(),
          DD = newDate.getDate(),
          // Datepicker sets time to midnight so get back current time for new date
          now = new Date(),
          hh = now.getHours(),
          mm = now.getMinutes(),
          ss = now.getSeconds();

        newDate = new Date(YYYY, MM, DD, hh, mm, ss);
        settingsFactory.set({date: newDate});
        reloadData();
        $scope.$broadcast('DatepickerModal:closeModal');
      }
    }
  }
});

<|endoftext|>


<commit_before>var URL = require("url"),
	http = require("http"),
	https = require("https"),
	fs = require("fs"),
	cp = require("child_process"),
	fc = require("./fetcher.common.js"),
	harel = require("./fetcher.harel.js"),
	CSVWriter = require("./CSVWriter.js"),
	db = require("./db.js"),
	Quarter = require("./quarter"),
	Promise = require("bluebird")
	validUrl = require("valid-url"),
	_ = require("underscore"),
	Utils = require("./utils.js");

var readGoogleDocsFundsFile = function(){

	return new Promise(function(resolve, reject){

		var options = {
			host: "docs.google.com",
			port : 443,
			path : "/spreadsheets/d/1mUsNeb8gD2ELPKGpjD12AqZkuCybJlGCTz62oryLZY4/export?exportFormat=csv&gid=1311761971"
		}

		var data = '';

		https.get(options,function(res){

			res.on('data', function(chunk){
				data = data + chunk.toString();
			});

			res.on('end', function(){
				var parsedLines = data.split("\n");

				parseCsvFetch(parsedLines)
				.then(function(funds){
					resolve(funds);
				});
			});
		})
		.on('error',function(r){
			console.log("error fetching sheet",r);
			process.exit();
			reject("error fetching sheet "+r);
		});

	});
}

var parseCsvFetch = function(parsedLines){

	var reducer = function(out, line){
		var splt = line.split(',');
		var _out = [];
		var startYear = 2012;
		var startQuarter = 4;

		var quarter =  new Quarter(startYear, startQuarter -1);

		for (var i = 8; i < splt.length; i++){

			if (splt[2] && splt[5] && splt[i] && validUrl.isUri(splt[i].trim()))
				_out.push({ body : splt[2], number : splt[5], url : splt[i], year : quarter.year, quarter : quarter.quarter + 1 })

			quarter.increase();
		}
		return out.concat(_out)
	}

	return new Promise(function(resolve, reject){
		resolve(parsedLines.reduce(reducer, []));
	});

}

var getContribFunds = function() {

	return new Promise(function(resolve, reject){

	    var client = (new db.pg(true)).client;

	    client.query("SELECT q.id, q.year, q.quarter, q.url, q.status, f.managing_body, f.id as fund_id, f.name as fund_name, f.url as fund_url FROM admin_funds_quarters as q, admin_funds as f WHERE q.fund_id = f.id AND status = 'validated'", function(err, result) {

	        if(err) {
	            return console.error('error running query', err);
	        }

	        var funds = [];

	        result.rows.forEach(function(f) {
	            funds.push({
	                body: f.managing_body,
	                number: f.fund_id,
	                url: f.url,
	                year: f.year,
	                quarter: f.quarter+1
	            });
	        });

	        resolve(funds);
    	});
	});
};

exports.fetchKnown = function(body, year, quarter, fund_number){

	readGoogleDocsFundsFile()
	.then(function(allFunds){
		return Utils.filterFunds(allFunds, body, year, quarter, fund_number);
	})
	.each(function(fund){
		fc.downloadFundFile(fund);
	})
	.then(function(k){
		console.log(k);
	})
	.catch(function(e){
		console.log(e.stack);
	});
};

exports.fetchContrib = function(){
    getContribFunds()
    // .then(function(funds){
    // 	return filterFunds(funds);
    // })
    .each(function(fund){
    	fc.downloadFundFile(fund);
    });
};

//TODO: not finished... parse query results, sort by instrument type, write csv
exports.dumpFunds = function(body, year, quarter, fund_number){

	readGoogleDocsFundsFile()
	.then(function(allFunds){

		body = 'Migdal';
		year = '2014';
		quarter = '2';
		fund_number = '659';

		//TODO: get chosen attributes from user
		var chosenFunds = allFunds.filter(function(f){
			return (body == undefined? true: f.body == body ||  ( _.isArray(body) && body.indexOf(f.body) > -1 ) )
			&& (fund_number == undefined ? true: f.number == fund_number ||  ( _.isArray(fund_number) && fund_number.indexOf(f.number) > -1 ))
			&& (year == undefined ? true: f.year == year ||  ( _.isArray(year) && year.indexOf(f.year) > -1 ))
			&& (quarter == undefined? true: f.quarter == quarter ||  ( _.isArray(quarter) && quarter.indexOf(f.quarter) > -1 ))
		})

		return chosenFunds;
	})
	.then(function(chosenFunds){

		return chosenFunds.map(function(chosenFund){

			var tableName = "pension_data_all"
			var sql = "SELECT * FROM "+ tableName +" WHERE managing_body='" +chosenFund.body +"'"
						+ " AND report_year='"+chosenFund.year+"' AND report_qurater='"+chosenFund.quarter+"'"
						+ " AND fund='"+chosenFund.number+"' ";
			return db.query(sql);

		});
	})
	.map(function(queryResult){
		console.log("=============================")
		// console.log(queryResult);
		var rowCount = queryResult.rowCount;
		var rows = queryResult.rows;
		var managing_body = rows[0].managing_body;
		var report_year = rows[0].report_year;
		var report_qurater = rows[0].managing_body;
		var fund = rows[0].fund;
		// var instrument_type = rows[0].
		// var instrument_sub_type = rows[0].

		var fundObj = Utils.getFundObj(managing_body, report_year, report_qurater, fund);
		var filename = Utils.filename("./from_db", fundObj, ".csv");

		console.log(rows);

		console.log("=============================")

		CSVWriter.write(managing_body, fund, report_year, report_qurater, instrument, instrumentSub, tabData, headers)
		return;

	});

};

exports.readGoogleDocsFundsFile = readGoogleDocsFundsFile;<commit_msg>fix naming<commit_after>var URL = require("url"),
	http = require("http"),
	https = require("https"),
	fs = require("fs"),
	cp = require("child_process"),
	fc = require("./fetcher.common.js"),
	harel = require("./fetcher.harel.js"),
	CSVWriter = require("./CSVWriter.js"),
	db = require("./db.js"),
	Quarter = require("./quarter"),
	Promise = require("bluebird")
	validUrl = require("valid-url"),
	_ = require("underscore"),
	Utils = require("./utils.js");

var readGoogleDocsFundsFile = function(){

	return new Promise(function(resolve, reject){

		var options = {
			host: "docs.google.com",
			port : 443,
			path : "/spreadsheets/d/1mUsNeb8gD2ELPKGpjD12AqZkuCybJlGCTz62oryLZY4/export?exportFormat=csv&gid=1311761971"
		}

		var data = '';

		https.get(options,function(res){

			res.on('data', function(chunk){
				data = data + chunk.toString();
			});

			res.on('end', function(){
				var parsedLines = data.split("\n");

				parseCsvFetch(parsedLines)
				.then(function(funds){
					resolve(funds);
				});
			});
		})
		.on('error',function(r){
			console.log("error fetching sheet",r);
			process.exit();
			reject("error fetching sheet "+r);
		});

	});
}

var parseCsvFetch = function(parsedLines){

	var reducer = function(out, line){
		var splt = line.split(',');
		var _out = [];
		var startYear = 2012;
		var startQuarter = 4;

		var quarter =  new Quarter(startYear, startQuarter -1);

		for (var i = 8; i < splt.length; i++){

			if (splt[2] && splt[5] && splt[i] && validUrl.isUri(splt[i].trim()))
				_out.push({ body : splt[2], number : splt[5], url : splt[i], year : quarter.year, quarter : quarter.quarter + 1 })

			quarter.increase();
		}
		return out.concat(_out)
	}

	return new Promise(function(resolve, reject){
		resolve(parsedLines.reduce(reducer, []));
	});

}

var getContribFunds = function() {

	return new Promise(function(resolve, reject){

	    var client = (new db.pg(true)).client;

	    client.query("SELECT q.id, q.year, q.quarter, q.url, q.status, f.managing_body, f.id as fund_id, f.name as fund_name, f.url as fund_url FROM admin_funds_quarters as q, admin_funds as f WHERE q.fund_id = f.id AND status = 'validated'", function(err, result) {

	        if(err) {
	            return console.error('error running query', err);
	        }

	        var funds = [];

	        result.rows.forEach(function(f) {
	            funds.push({
	                body: f.managing_body,
	                number: f.fund_id,
	                url: f.url,
	                year: f.year,
	                quarter: f.quarter+1
	            });
	        });

	        resolve(funds);
    	});
	});
};

exports.fetchKnown = function(body, year, quarter, fund_number){

	readGoogleDocsFundsFile()
	.then(function(allFunds){
		return Utils.filterFunds(allFunds, body, year, quarter, fund_number);
	})
	.each(function(fund){
		fc.downloadFundFile(fund);
	})
	.then(function(xlFilename){
		console.log(xlFilename);
	})
	.catch(function(e){
		console.log(e.stack);
	});
};

exports.fetchContrib = function(){
    getContribFunds()
    // .then(function(funds){
    // 	return filterFunds(funds);
    // })
    .each(function(fund){
    	fc.downloadFundFile(fund);
    });
};

//TODO: not finished... parse query results, sort by instrument type, write csv
exports.dumpFunds = function(body, year, quarter, fund_number){

	readGoogleDocsFundsFile()
	.then(function(allFunds){

		body = 'Migdal';
		year = '2014';
		quarter = '2';
		fund_number = '659';

		//TODO: get chosen attributes from user
		var chosenFunds = allFunds.filter(function(f){
			return (body == undefined? true: f.body == body ||  ( _.isArray(body) && body.indexOf(f.body) > -1 ) )
			&& (fund_number == undefined ? true: f.number == fund_number ||  ( _.isArray(fund_number) && fund_number.indexOf(f.number) > -1 ))
			&& (year == undefined ? true: f.year == year ||  ( _.isArray(year) && year.indexOf(f.year) > -1 ))
			&& (quarter == undefined? true: f.quarter == quarter ||  ( _.isArray(quarter) && quarter.indexOf(f.quarter) > -1 ))
		})

		return chosenFunds;
	})
	.then(function(chosenFunds){

		return chosenFunds.map(function(chosenFund){

			var tableName = "pension_data_all"
			var sql = "SELECT * FROM "+ tableName +" WHERE managing_body='" +chosenFund.body +"'"
						+ " AND report_year='"+chosenFund.year+"' AND report_qurater='"+chosenFund.quarter+"'"
						+ " AND fund='"+chosenFund.number+"' ";
			return db.query(sql);

		});
	})
	.map(function(queryResult){
		console.log("=============================")
		// console.log(queryResult);
		var rowCount = queryResult.rowCount;
		var rows = queryResult.rows;
		var managing_body = rows[0].managing_body;
		var report_year = rows[0].report_year;
		var report_qurater = rows[0].managing_body;
		var fund = rows[0].fund;
		// var instrument_type = rows[0].
		// var instrument_sub_type = rows[0].

		var fundObj = Utils.getFundObj(managing_body, report_year, report_qurater, fund);
		var filename = Utils.filename("./from_db", fundObj, ".csv");

		console.log(rows);

		console.log("=============================")

		CSVWriter.write(managing_body, fund, report_year, report_qurater, instrument, instrumentSub, tabData, headers)
		return;

	});

};

exports.readGoogleDocsFundsFile = readGoogleDocsFundsFile;<|endoftext|>