<commit_before>const fs = require('fs');
const Readable = require('readable-stream').Readable;
const Connection = require('../../src/connection');
const Request = require('../../src/request');
const TYPES = require('../../src/data-type').typeByName;

const debugMode = false;
var useEncryptedConnection = false;

function getConfig() {
  const config = JSON.parse(
    fs.readFileSync(require('os').homedir() + '/.tedious/test-connection.json', 'utf8')
  ).config;
  config.options.tdsVersion = process.env.TEDIOUS_TDS_VERSION;
  config.options.encrypt = useEncryptedConnection;
  if (debugMode) {
    config.options.debug = {
      packet: true,
      data: true,
      payload: true,
      token: true
    };
  }
  return config;
}

exports.setUp = function(setUpDone) {
  const connection = new Connection(getConfig());
  connection.on('connect', (err) => {
    if (err) {
      setUpDone(err);
      return;
    }
    this.connection = connection;
    setUpDone();
  });
  connection.on('end', () => {
    this.connection = undefined;
  });
  if (debugMode) {
    connection.on('debug', (message) => console.log(message));
    connection.on('infoMessage', (info) =>
      console.log('Info: ' + info.number + ' - ' + info.message)
    );
    connection.on('errorMessage', (error) =>
      console.log('Error: ' + error.number + ' - ' + error.message)
    );
  }
};

exports.tearDown = function(tearDownDone) {
  const connection = this.connection;
  if (!connection) {
    tearDownDone();
    return;
  }
  connection.on('end', function() {
    tearDownDone();
  });
  connection.close();
};

exports.bulkLoad = function(test) {
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('#tmpTestTable', function(
    err,
    rowCount
  ) {
    test.ifError(err);
    test.strictEqual(rowCount, 5, 'Incorrect number of rows inserted.');
    test.done();
  });
  bulkLoad.addColumn('nnn', TYPES.Int, {
    nullable: false
  });
  bulkLoad.addColumn('sss', TYPES.NVarChar, {
    length: 50,
    nullable: true
  });
  bulkLoad.addColumn('ddd', TYPES.DateTime, {
    nullable: false
  });
  const request = new Request(bulkLoad.getTableCreationSql(), function(err) {
    test.ifError(err);
    bulkLoad.addRow({
      nnn: 201,
      sss: 'one zero one',
      ddd: new Date(1986, 6, 20)
    });
    bulkLoad.addRow([202, 'one zero two', new Date()]);
    bulkLoad.addRow(203, 'one zero three', new Date(2013, 7, 12));
    bulkLoad.addRow({
      nnn: 204,
      sss: 'one zero four',
      ddd: new Date()
    });
    bulkLoad.addRow({
      nnn: 205,
      sss: 'one zero five',
      ddd: new Date()
    });
    connection.execBulkLoad(bulkLoad);
  });
  connection.execSqlBatch(request);
};

exports.bulkLoadError = function(test) {
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('#tmpTestTable2', function(
    err,
    rowCount
  ) {
    test.ok(
      err,
      'An error should have been thrown to indicate the incorrect table format.'
    );
    test.done();
  });
  bulkLoad.addColumn('x', TYPES.Int, {
    nullable: false
  });
  bulkLoad.addColumn('y', TYPES.Int, {
    nullable: false
  });
  const request = new Request(
    'CREATE TABLE #tmpTestTable2 ([id] int not null)',
    function(err) {
      test.ifError(err);
      bulkLoad.addRow({
        x: 1,
        y: 1
      });
      connection.execBulkLoad(bulkLoad);
    }
  );
  connection.execSqlBatch(request);
};

exports['bulkLoad - verify constraints'] = function(test) {
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('#tmpTestTable3', {checkConstraints: true}, function(
    err,
    rowCount
  ) {
    test.ok(
      err,
      'An error should have been thrown to indicate the conflict with the CHECK constraint.'
    );
    test.done();
  });
  bulkLoad.addColumn('id', TYPES.Int, {
    nullable: true
  });
  const request = new Request(
    'CREATE TABLE #tmpTestTable3 ([id] int,  CONSTRAINT chk_id CHECK (id BETWEEN 0 and 50 ))',
    function(err) {
      test.ifError(err);
      bulkLoad.addRow({
        id: 555
      });
      connection.execBulkLoad(bulkLoad);
    }
  );
  connection.execSqlBatch(request);
};

exports['bulkLoad - verify trigger'] = function(test) {
  test.expect(6);
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('testTable4', {fireTriggers: true}, function(
    err,
    rowCount
  ) {
    test.ifError(err);
    connection.execSql(request_verify);
  });
  bulkLoad.addColumn('id', TYPES.Int, {
    nullable: true
  });
  const createTable = 'CREATE TABLE testTable4 ([id] int);';
  const createTrigger =
    `CREATE TRIGGER bulkLoadTest on testTable4
    AFTER INSERT
    AS
    INSERT INTO testTable4 SELECT * FROM testTable4;`;
  const verifyTrigger = 'SELECT COUNT(*) FROM testTable4';
  const dropTable = 'DROP TABLE testTable4';

  const request_table = new Request(createTable,
    function(err) {
      test.ifError(err);
      connection.execSql(request_trigger);
    }
  );

  const request_trigger = new Request(createTrigger,
    function(err) {
      test.ifError(err);
      bulkLoad.addRow({
        id: 555
      });
      connection.execBulkLoad(bulkLoad);
    }
  );

  const request_verify = new Request(verifyTrigger, function(err) {
    test.ifError(err);
    connection.execSql(request_dropTable);
  });

  const request_dropTable = new Request(dropTable, function(err) {
    test.ifError(err);
    test.done();
  });

  request_verify.on('row', function(columns) {
    test.deepEqual(columns[0].value, 2);
  });

  connection.execSql(request_table);
};

exports['bulkLoad - verify null value'] = function(test) {
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('#tmpTestTable5', {keepNulls: true}, function(
    err,
    rowCount
  ) {
    test.ifError(err);
    connection.execSqlBatch(request_verifyBulkLoad);
  });
  bulkLoad.addColumn('id', TYPES.Int, {
    nullable: true
  });
  const request = new Request(
    'CREATE TABLE #tmpTestTable5 ([id] int NULL DEFAULT 253565)',
    function(err) {
      test.ifError(err);
      bulkLoad.addRow({
        id: null
      });
      connection.execBulkLoad(bulkLoad);
    }
  );
  const request_verifyBulkLoad = new Request('SELECT [id] FROM #tmpTestTable5', function(err) {
    test.ifError(err);
    test.done();
  });
  request_verifyBulkLoad.on('row', function(columns) {
    test.deepEqual(columns[0].value, null);
  });
  connection.execSqlBatch(request);
};

exports.testStreamingBulkLoad = function(test) {
  const totalRows = 500000;
  const connection = this.connection;
  const tableName = '#streamingBulkLoadTest';

  connection.on('error', function(err) {
    test.ifError(err);
  });
  startCreateTable();

  function startCreateTable() {
    const sql = 'create table ' + tableName + ' (i int not null primary key)';
    const request = new Request(sql, completeCreateTable);
    connection.execSqlBatch(request);
  }

  function completeCreateTable(err) {
    test.ifError(err);
    startBulkLoad();
  }

  function startBulkLoad() {
    const bulkLoad = connection.newBulkLoad(tableName, completeBulkLoad);
    bulkLoad.addColumn('i', TYPES.Int, {nullable: false});
    const rowStream = bulkLoad.getRowStream();
    connection.execBulkLoad(bulkLoad);
    const rowSource = new RowSource(totalRows);
    rowSource.pipe(rowStream);
  }

  function completeBulkLoad(err, rowCount) {
    test.ifError(err);
    test.equal(rowCount, totalRows);
    startVerifyTableContent();
  }

  function startVerifyTableContent() {
    const sql =
      'select count(*) ' +
        'from ' + tableName + ' a ' +
          'inner join ' + tableName + ' b on a.i = b.i - 1';
    const request = new Request(sql, completeVerifyTableContent);
    request.on('data', (row) => {
      test.equals(row[0].value, totalRows - 1);
    });
    connection.execSqlBatch(request);
  }

  function completeVerifyTableContent(err, rowCount) {
    test.ifError(err);
    test.equal(rowCount, 1);
    test.done();
  }

  class RowSource extends Readable {
    constructor(totalRows) {
      super({
        objectMode: true
      });
      this.totalRows = totalRows;
      this.rowCount = 0;
    }
    _read() {
      while (this.rowCount < this.totalRows) {
        const i = this.rowCount++;
        const row = [i];
        if (!this.push(row)) {
          return;
        }
      }
      this.push(null);
    }
  }
};

exports.dummyToSwitchToEncryptedConnection = function(test) {
  // (Please let me know if you find a better solution for this.)
  useEncryptedConnection = true;
  test.done();
};

// Executes testStreamingBulkLoad() a second time with an encrypted connection.
// This is important to test data flow control through TLS.
exports.testStreamingBulkLoadEncrypted = function(test) {
  test.ok(useEncryptedConnection);
  exports.testStreamingBulkLoad.call(this, test);
};
<commit_msg>test: remove changing encryption settings in the tests<commit_after>const fs = require('fs');
const Readable = require('readable-stream').Readable;
const Connection = require('../../src/connection');
const Request = require('../../src/request');
const TYPES = require('../../src/data-type').typeByName;

const debugMode = false;

function getConfig() {
  const { config } = JSON.parse(
    fs.readFileSync(require('os').homedir() + '/.tedious/test-connection.json', 'utf8')
  );

  config.options.tdsVersion = process.env.TEDIOUS_TDS_VERSION;

  if (debugMode) {
    config.options.debug = {
      packet: true,
      data: true,
      payload: true,
      token: true
    };
  }

  return config;
}

exports.setUp = function(setUpDone) {
  const connection = new Connection(getConfig());
  connection.on('connect', (err) => {
    if (err) {
      setUpDone(err);
      return;
    }
    this.connection = connection;
    setUpDone();
  });
  connection.on('end', () => {
    this.connection = undefined;
  });
  if (debugMode) {
    connection.on('debug', (message) => console.log(message));
    connection.on('infoMessage', (info) =>
      console.log('Info: ' + info.number + ' - ' + info.message)
    );
    connection.on('errorMessage', (error) =>
      console.log('Error: ' + error.number + ' - ' + error.message)
    );
  }
};

exports.tearDown = function(tearDownDone) {
  const connection = this.connection;
  if (!connection) {
    tearDownDone();
    return;
  }
  connection.on('end', function() {
    tearDownDone();
  });
  connection.close();
};

exports.bulkLoad = function(test) {
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('#tmpTestTable', function(
    err,
    rowCount
  ) {
    test.ifError(err);
    test.strictEqual(rowCount, 5, 'Incorrect number of rows inserted.');
    test.done();
  });
  bulkLoad.addColumn('nnn', TYPES.Int, {
    nullable: false
  });
  bulkLoad.addColumn('sss', TYPES.NVarChar, {
    length: 50,
    nullable: true
  });
  bulkLoad.addColumn('ddd', TYPES.DateTime, {
    nullable: false
  });
  const request = new Request(bulkLoad.getTableCreationSql(), function(err) {
    test.ifError(err);
    bulkLoad.addRow({
      nnn: 201,
      sss: 'one zero one',
      ddd: new Date(1986, 6, 20)
    });
    bulkLoad.addRow([202, 'one zero two', new Date()]);
    bulkLoad.addRow(203, 'one zero three', new Date(2013, 7, 12));
    bulkLoad.addRow({
      nnn: 204,
      sss: 'one zero four',
      ddd: new Date()
    });
    bulkLoad.addRow({
      nnn: 205,
      sss: 'one zero five',
      ddd: new Date()
    });
    connection.execBulkLoad(bulkLoad);
  });
  connection.execSqlBatch(request);
};

exports.bulkLoadError = function(test) {
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('#tmpTestTable2', function(
    err,
    rowCount
  ) {
    test.ok(
      err,
      'An error should have been thrown to indicate the incorrect table format.'
    );
    test.done();
  });
  bulkLoad.addColumn('x', TYPES.Int, {
    nullable: false
  });
  bulkLoad.addColumn('y', TYPES.Int, {
    nullable: false
  });
  const request = new Request(
    'CREATE TABLE #tmpTestTable2 ([id] int not null)',
    function(err) {
      test.ifError(err);
      bulkLoad.addRow({
        x: 1,
        y: 1
      });
      connection.execBulkLoad(bulkLoad);
    }
  );
  connection.execSqlBatch(request);
};

exports['bulkLoad - verify constraints'] = function(test) {
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('#tmpTestTable3', {checkConstraints: true}, function(
    err,
    rowCount
  ) {
    test.ok(
      err,
      'An error should have been thrown to indicate the conflict with the CHECK constraint.'
    );
    test.done();
  });
  bulkLoad.addColumn('id', TYPES.Int, {
    nullable: true
  });
  const request = new Request(
    'CREATE TABLE #tmpTestTable3 ([id] int,  CONSTRAINT chk_id CHECK (id BETWEEN 0 and 50 ))',
    function(err) {
      test.ifError(err);
      bulkLoad.addRow({
        id: 555
      });
      connection.execBulkLoad(bulkLoad);
    }
  );
  connection.execSqlBatch(request);
};

exports['bulkLoad - verify trigger'] = function(test) {
  test.expect(6);
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('testTable4', {fireTriggers: true}, function(
    err,
    rowCount
  ) {
    test.ifError(err);
    connection.execSql(request_verify);
  });
  bulkLoad.addColumn('id', TYPES.Int, {
    nullable: true
  });
  const createTable = 'CREATE TABLE testTable4 ([id] int);';
  const createTrigger =
    `CREATE TRIGGER bulkLoadTest on testTable4
    AFTER INSERT
    AS
    INSERT INTO testTable4 SELECT * FROM testTable4;`;
  const verifyTrigger = 'SELECT COUNT(*) FROM testTable4';
  const dropTable = 'DROP TABLE testTable4';

  const request_table = new Request(createTable,
    function(err) {
      test.ifError(err);
      connection.execSql(request_trigger);
    }
  );

  const request_trigger = new Request(createTrigger,
    function(err) {
      test.ifError(err);
      bulkLoad.addRow({
        id: 555
      });
      connection.execBulkLoad(bulkLoad);
    }
  );

  const request_verify = new Request(verifyTrigger, function(err) {
    test.ifError(err);
    connection.execSql(request_dropTable);
  });

  const request_dropTable = new Request(dropTable, function(err) {
    test.ifError(err);
    test.done();
  });

  request_verify.on('row', function(columns) {
    test.deepEqual(columns[0].value, 2);
  });

  connection.execSql(request_table);
};

exports['bulkLoad - verify null value'] = function(test) {
  const connection = this.connection;
  const bulkLoad = connection.newBulkLoad('#tmpTestTable5', {keepNulls: true}, function(
    err,
    rowCount
  ) {
    test.ifError(err);
    connection.execSqlBatch(request_verifyBulkLoad);
  });
  bulkLoad.addColumn('id', TYPES.Int, {
    nullable: true
  });
  const request = new Request(
    'CREATE TABLE #tmpTestTable5 ([id] int NULL DEFAULT 253565)',
    function(err) {
      test.ifError(err);
      bulkLoad.addRow({
        id: null
      });
      connection.execBulkLoad(bulkLoad);
    }
  );
  const request_verifyBulkLoad = new Request('SELECT [id] FROM #tmpTestTable5', function(err) {
    test.ifError(err);
    test.done();
  });
  request_verifyBulkLoad.on('row', function(columns) {
    test.deepEqual(columns[0].value, null);
  });
  connection.execSqlBatch(request);
};

exports.testStreamingBulkLoad = function(test) {
  const totalRows = 500000;
  const connection = this.connection;
  const tableName = '#streamingBulkLoadTest';

  connection.on('error', function(err) {
    test.ifError(err);
  });
  startCreateTable();

  function startCreateTable() {
    const sql = 'create table ' + tableName + ' (i int not null primary key)';
    const request = new Request(sql, completeCreateTable);
    connection.execSqlBatch(request);
  }

  function completeCreateTable(err) {
    test.ifError(err);
    startBulkLoad();
  }

  function startBulkLoad() {
    const bulkLoad = connection.newBulkLoad(tableName, completeBulkLoad);
    bulkLoad.addColumn('i', TYPES.Int, {nullable: false});
    const rowStream = bulkLoad.getRowStream();
    connection.execBulkLoad(bulkLoad);
    const rowSource = new RowSource(totalRows);
    rowSource.pipe(rowStream);
  }

  function completeBulkLoad(err, rowCount) {
    test.ifError(err);
    test.equal(rowCount, totalRows);
    startVerifyTableContent();
  }

  function startVerifyTableContent() {
    const sql =
      'select count(*) ' +
        'from ' + tableName + ' a ' +
          'inner join ' + tableName + ' b on a.i = b.i - 1';
    const request = new Request(sql, completeVerifyTableContent);
    request.on('data', (row) => {
      test.equals(row[0].value, totalRows - 1);
    });
    connection.execSqlBatch(request);
  }

  function completeVerifyTableContent(err, rowCount) {
    test.ifError(err);
    test.equal(rowCount, 1);
    test.done();
  }

  class RowSource extends Readable {
    constructor(totalRows) {
      super({
        objectMode: true
      });
      this.totalRows = totalRows;
      this.rowCount = 0;
    }
    _read() {
      while (this.rowCount < this.totalRows) {
        const i = this.rowCount++;
        const row = [i];
        if (!this.push(row)) {
          return;
        }
      }
      this.push(null);
    }
  }
};
<|endoftext|>


<commit_before>function Controller()
{
    var self = this; //<- I hate javascript.
    this.setLayout = function(sender)
    {
        switch(sender)
        {
            case model.views.mapLayoutButton:
                model.views.listLayoutButton.deselect();
                model.views.listLayout.style.display = 'none';
                model.views.sortSelector.style.display = 'none';
                model.views.mapLayout.style.display = 'block';
                model.views.mapNoteViewContainer.appendChild(model.views.noteView.html);
                break;
            case model.views.listLayoutButton:
                model.views.mapLayoutButton.deselect();
                model.views.mapLayout.style.display = 'none';
                model.views.sortSelector.style.display = 'block';
                model.views.listLayout.style.display = 'block';
                model.views.listNoteViewContainer.appendChild(model.views.noteView.html);
                break;
        }
    };
    this.setSort = function(sender)
    {
        switch(sender)
        {
            case model.views.contributorSortButton:
                model.views.tagSortButton.deselect();
                model.views.popularitySortButton.deselect();
                model.views.noteListSelector.style.height = '245px';
                model.views.noteListSelector.style.margin = '10px 0px 0px 0px';
                model.views.tagListFilterSelector.style.display = 'none';
                model.views.contributorListFilterSelector.style.display = 'block';
                self.populateNotesByContributor();
                break;
            case model.views.tagSortButton:
                model.views.contributorSortButton.deselect();
                model.views.popularitySortButton.deselect();
                model.views.noteListSelector.style.height = '245px';
                model.views.noteListSelector.style.margin = '10px 0px 0px 0px';
                model.views.contributorListFilterSelector.style.display = 'none';
                model.views.tagListFilterSelector.style.display = 'block';
                self.populateNotesByTag();
                break;
            case model.views.popularitySortButton:
                model.views.contributorSortButton.deselect();
                model.views.tagSortButton.deselect();
                model.views.noteListSelector.style.height = '500px';
                model.views.noteListSelector.style.margin = '0px 0px 0px 0px';
                model.views.contributorListFilterSelector.style.display = 'none';
                model.views.tagListFilterSelector.style.display = 'none';
                self.populateNotesByPopularity();
                break;
        }
    };

    this.mapContributorClicked = function(sender, selected) {};
    this.selectAllMapContributors = function()
    {
        for(var i = 0; i < model.contributorMapCells.length; i++)
            model.contributorMapCells[i].select();
    };
    this.deselectAllMapContributors = function()
    {
        for(var i = 0; i < model.contributorMapCells.length; i++)
            model.contributorMapCells[i].deselect();
    };
    this.mapTagClicked = function(sender,selected) {};
    this.selectAllMapTags = function()
    {
        for(var i = 0; i < model.tagMapCells.length; i++)
            model.tagMapCells[i].select();
    };
    this.deselectAllMapTags = function()
    {
        for(var i = 0; i < model.tagMapCells.length; i++)
            model.tagMapCells[i].deselect();
    };
    this.listContributorClicked = function(sender,selected) {};
    this.selectAllListContributors = function()
    {
        for(var i = 0; i < model.contributorListCells.length; i++)
            model.contributorListCells[i].select();
    };
    this.deselectAllListContributors = function()
    {
        for(var i = 0; i < model.contributorListCells.length; i++)
            model.contributorListCells[i].deselect();
    };
    this.listTagClicked = function(sender,selected) {};
    this.selectAllListTags = function()
    {
        for(var i = 0; i < model.tagListCells.length; i++)
            model.tagListCells[i].select();
    };
    this.deselectAllListTags = function()
    {
        for(var i = 0; i < model.tagListCells.length; i++)
            model.tagListCells[i].deselect();
    };
    this.noteSelected = function(sender)
    {
        var note = sender.object;
        var html = model.views.constructNoteView.cloneNode(true);
        model.views.noteView = new NoteView(html, note);
        model.views.mapNoteViewContainer.innerHTML = '';
        model.views.listNoteViewContainer.innerHTML = '';
        if(model.views.mapLayoutButton.selected) model.views.mapNoteViewContainer.appendChild(model.views.noteView.html);
        if(model.views.listLayoutButton.selected) model.views.listNoteViewContainer.appendChild(model.views.noteView.html);

        if(model.views.contributorSortButton.selected) for(var i = 0; i < model.views.contributorNoteCells.length; i++) model.views.contributorNoteCells[i].deselect();
        if(model.views.tagSortButton.selected) for(var i = 0; i < model.views.tagNoteCells.length; i++) model.views.tagNoteCells[i].deselect();
        if(model.views.popularitySortButton.selected) for(var i = 0; i < model.views.popularNoteCells.length; i++) model.views.popularNoteCells[i].deselect();
    };

    this.populateModel = function(gameData)
    {
        model.gameData = gameData;

        model.backpacks = model.gameData.backpacks;
        for(var i = 0; i < model.backpacks.length; i++)
        {
            for(var j = 0; j < model.backpacks[i].notes.length; j++)
            {
                model.backpacks[i].notes[j].tags.sort();
                model.backpacks[i].notes[j].popularity = 0;

                model.addNote(model.backpacks[i].notes[j]);
                model.addContributorNote(model.backpacks[i].notes[j]);
                model.addTagNote(model.backpacks[i].notes[j]);
                model.addPopularNote(model.backpacks[i].notes[j]);

                model.addContributor(model.backpacks[i].notes[j].username);
                if(model.backpacks[i].notes[j].tags.length == 0)
                    model.backpacks[i].notes[j].tags[0] = '(untagged)';
                for(var k = 0; k < model.backpacks[i].notes[j].tags.length; k++)
                    model.addTag(model.backpacks[i].notes[j].tags[k]);
            }
        }
        this.populateMapContributors();
        this.populateListContributors();
        this.populateMapTags();
        this.populateListTags();
        this.populateNotesByContributor();
        //this.populateNotesByTag();
        //this.populateNotesByPopularity();

        this.selectAllMapContributors();
        this.selectAllMapTags();
        this.selectAllListContributors();
        this.selectAllListTags();
    };

    this.populateMapContributors = function()
    {
        model.views.contributorMapFilterSelector.innerHTML = ''; //Clear the children
        if(model.contributors.length == 0)
            model.views.contributorMapFilterSelector.appendChild(model.views.defaultContributorMapFilterSelectorCell);
        var tmpcell;
        for(var i = 0; i < model.contributors.length; i++)
        {
            tmpcell = new SelectionCell(model.views.constructContributorMapFilterSelectorCell.cloneNode(true), i%2, this.mapContributorClicked, model.contributors[i]);
            tmpcell.html.firstChild.innerHTML = model.contributors[i];
            model.views.contributorMapFilterSelector.appendChild(tmpcell.html);
            model.contributorMapCells[model.contributorMapCells.length] = tmpcell;
        }
        model.views.contributorMapFilterSelector.appendChild(model.views.helperContributorMapFilterSelectorCell);
    };
    this.populateListContributors = function()
    {
        model.views.contributorListFilterSelector.innerHTML = ''; //Clear the children
        if(model.contributors.length == 0)
            model.views.contributorListFilterSelector.appendChild(model.views.defaultContributorListFilterSelectorCell);
        var tmpcell;
        for(var i = 0; i < model.contributors.length; i++)
        {
            tmpcell = new SelectionCell(model.views.constructContributorListFilterSelectorCell.cloneNode(true), i%2, this.listContributorClicked, model.contributors[i]);
            tmpcell.html.firstChild.innerHTML = model.contributors[i];
            model.views.contributorListFilterSelector.appendChild(tmpcell.html);
            model.contributorListCells[model.contributorListCells.length] = tmpcell;
        }
        model.views.contributorListFilterSelector.appendChild(model.views.helperContributorListFilterSelectorCell);
    };
    this.populateMapTags = function()
    {
        model.views.tagMapFilterSelector.innerHTML = ''; //Clear the children
        if(model.tags.length == 0)
            model.views.tagMapFilterSelector.appendChild(model.views.defaultTagMapFilterSelectorCell);
        var tmpcell;
        for(var i = 0; i < model.tags.length; i++)
        {
            tmpcell = new SelectionCell(model.views.constructTagMapFilterSelectorCell.cloneNode(true), i%2, this.mapTagClicked, model.tags[i]);
            tmpcell.html.firstChild.innerHTML = model.tags[i];
            model.views.tagMapFilterSelector.appendChild(tmpcell.html);
            model.tagMapCells[model.tagMapCells.length] = tmpcell;
        }
        model.views.tagMapFilterSelector.appendChild(model.views.helperTagMapFilterSelectorCell);
    };
    this.populateListTags = function()
    {
        model.views.tagListFilterSelector.innerHTML = ''; //Clear the children
        if(model.tags.length == 0)
            model.views.tagListFilterSelector.appendChild(model.views.defaultTagListFilterSelectorCell);
        var tmpcell;
        for(var i = 0; i < model.tags.length; i++)
        {
            tmpcell = new SelectionCell(model.views.constructTagListFilterSelectorCell.cloneNode(true), i%2, this.listTagClicked, model.tags[i]);
            tmpcell.html.firstChild.innerHTML = model.tags[i];
            model.views.tagListFilterSelector.appendChild(tmpcell.html);
            model.tagListCells[model.tagListCells.length] = tmpcell;
        }
        model.views.tagListFilterSelector.appendChild(model.views.helperTagListFilterSelectorCell);
    };
    this.populateNotesByContributor = function()
    {
        model.views.noteListSelector.innerHTML = ''; //Clear the children
        if(model.contributorNotes.length == 0)
            model.views.noteListSelector.appendChild(model.views.defaultNoteListSelectorCell);
        var tmpcell;
        model.views.contributorNoteCells = [];
        for(var i = 0; i < model.contributorNotes.length; i++)
        {
            tmpcell = new SingleSelectionCell(model.views.constructNoteListSelectorCell.cloneNode(true), i%2, this.noteSelected, model.contributorNotes[i]);
            tmpcell.html.firstChild.innerHTML = ''+model.contributorNotes[i].title+' - '+model.contributorNotes[i].username+'';
            model.views.noteListSelector.appendChild(tmpcell.html);
            model.views.contributorNoteCells[model.views.contributorNoteCells.length] = tmpcell;
        }
    };
    this.populateNotesByTag = function()
    {
        model.views.noteListSelector.innerHTML = ''; //Clear the children
        if(model.tagNotes.length == 0)
            model.views.noteListSelector.appendChild(model.views.defaultNoteListSelectorCell);
        var tmpcell;
        model.views.tagNoteCells = [];
        for(var i = 0; i < model.tagNotes.length; i++)
        {
            tmpcell = new SingleSelectionCell(model.views.constructNoteListSelectorCell.cloneNode(true), i%2, this.noteSelected, model.tagNotes[i]);
            tmpcell.html.firstChild.innerHTML = ''+model.tagNotes[i].title+' - '+model.tagNotes[i].username+'';
            model.views.noteListSelector.appendChild(tmpcell.html);
            model.views.tagNoteCells[model.views.tagNoteCells.length] = tmpcell;
        }
    };
    this.populateNotesByPopularity = function()
    {
        model.views.noteListSelector.innerHTML = ''; //Clear the children
        if(model.popularNotes.length == 0)
            model.views.noteListSelector.appendChild(model.views.defaultNoteListSelectorCell);
        var tmpcell;
        model.views.popularNoteCells = [];
        for(var i = 0; i < model.popularNotes.length; i++)
        {
            tmpcell = new SingleSelectionCell(model.views.constructNoteListSelectorCell.cloneNode(true), i%2, this.noteSelected, model.popularNotes[i]);
            tmpcell.html.firstChild.innerHTML = ''+model.popularNotes[i].title+' - '+model.popularNotes[i].username+'';
            model.views.noteListSelector.appendChild(tmpcell.html);
            model.views.popularNoteCells[model.views.popularNoteCells.length] = tmpcell;
        }
    }
}
<commit_msg>fixed tag population<commit_after>function Controller()
{
    var self = this; //<- I hate javascript.
    this.setLayout = function(sender)
    {
        switch(sender)
        {
            case model.views.mapLayoutButton:
                model.views.listLayoutButton.deselect();
                model.views.listLayout.style.display = 'none';
                model.views.sortSelector.style.display = 'none';
                model.views.mapLayout.style.display = 'block';
                model.views.mapNoteViewContainer.appendChild(model.views.noteView.html);
                break;
            case model.views.listLayoutButton:
                model.views.mapLayoutButton.deselect();
                model.views.mapLayout.style.display = 'none';
                model.views.sortSelector.style.display = 'block';
                model.views.listLayout.style.display = 'block';
                model.views.listNoteViewContainer.appendChild(model.views.noteView.html);
                break;
        }
    };
    this.setSort = function(sender)
    {
        switch(sender)
        {
            case model.views.contributorSortButton:
                model.views.tagSortButton.deselect();
                model.views.popularitySortButton.deselect();
                model.views.noteListSelector.style.height = '245px';
                model.views.noteListSelector.style.margin = '10px 0px 0px 0px';
                model.views.tagListFilterSelector.style.display = 'none';
                model.views.contributorListFilterSelector.style.display = 'block';
                self.populateNotesByContributor();
                break;
            case model.views.tagSortButton:
                model.views.contributorSortButton.deselect();
                model.views.popularitySortButton.deselect();
                model.views.noteListSelector.style.height = '245px';
                model.views.noteListSelector.style.margin = '10px 0px 0px 0px';
                model.views.contributorListFilterSelector.style.display = 'none';
                model.views.tagListFilterSelector.style.display = 'block';
                self.populateNotesByTag();
                break;
            case model.views.popularitySortButton:
                model.views.contributorSortButton.deselect();
                model.views.tagSortButton.deselect();
                model.views.noteListSelector.style.height = '500px';
                model.views.noteListSelector.style.margin = '0px 0px 0px 0px';
                model.views.contributorListFilterSelector.style.display = 'none';
                model.views.tagListFilterSelector.style.display = 'none';
                self.populateNotesByPopularity();
                break;
        }
    };

    this.mapContributorClicked = function(sender, selected) {};
    this.selectAllMapContributors = function()
    {
        for(var i = 0; i < model.contributorMapCells.length; i++)
            model.contributorMapCells[i].select();
    };
    this.deselectAllMapContributors = function()
    {
        for(var i = 0; i < model.contributorMapCells.length; i++)
            model.contributorMapCells[i].deselect();
    };
    this.mapTagClicked = function(sender,selected) {};
    this.selectAllMapTags = function()
    {
        for(var i = 0; i < model.tagMapCells.length; i++)
            model.tagMapCells[i].select();
    };
    this.deselectAllMapTags = function()
    {
        for(var i = 0; i < model.tagMapCells.length; i++)
            model.tagMapCells[i].deselect();
    };
    this.listContributorClicked = function(sender,selected) {};
    this.selectAllListContributors = function()
    {
        for(var i = 0; i < model.contributorListCells.length; i++)
            model.contributorListCells[i].select();
    };
    this.deselectAllListContributors = function()
    {
        for(var i = 0; i < model.contributorListCells.length; i++)
            model.contributorListCells[i].deselect();
    };
    this.listTagClicked = function(sender,selected) {};
    this.selectAllListTags = function()
    {
        for(var i = 0; i < model.tagListCells.length; i++)
            model.tagListCells[i].select();
    };
    this.deselectAllListTags = function()
    {
        for(var i = 0; i < model.tagListCells.length; i++)
            model.tagListCells[i].deselect();
    };
    this.noteSelected = function(sender)
    {
        var note = sender.object;
        var html = model.views.constructNoteView.cloneNode(true);
        model.views.noteView = new NoteView(html, note);
        model.views.mapNoteViewContainer.innerHTML = '';
        model.views.listNoteViewContainer.innerHTML = '';
        if(model.views.mapLayoutButton.selected) model.views.mapNoteViewContainer.appendChild(model.views.noteView.html);
        if(model.views.listLayoutButton.selected) model.views.listNoteViewContainer.appendChild(model.views.noteView.html);

        if(model.views.contributorSortButton.selected) for(var i = 0; i < model.views.contributorNoteCells.length; i++) model.views.contributorNoteCells[i].deselect();
        if(model.views.tagSortButton.selected) for(var i = 0; i < model.views.tagNoteCells.length; i++) model.views.tagNoteCells[i].deselect();
        if(model.views.popularitySortButton.selected) for(var i = 0; i < model.views.popularNoteCells.length; i++) model.views.popularNoteCells[i].deselect();
    };

    this.populateModel = function(gameData)
    {
        model.gameData = gameData;

        model.backpacks = model.gameData.backpacks;
        for(var i = 0; i < model.backpacks.length; i++)
        {
            for(var j = 0; j < model.backpacks[i].notes.length; j++)
            {
                model.backpacks[i].notes[j].tags.sort();
                model.backpacks[i].notes[j].popularity = 0;

                model.addNote(model.backpacks[i].notes[j]);
                model.addContributorNote(model.backpacks[i].notes[j]);
                model.addTagNote(model.backpacks[i].notes[j]);
                model.addPopularNote(model.backpacks[i].notes[j]);

                model.addContributor(model.backpacks[i].notes[j].username);
                if(model.backpacks[i].notes[j].tags.length == 0)
                    model.backpacks[i].notes[j].tags[0] = '(untagged)';
                for(var k = 0; k < model.backpacks[i].notes[j].tags.length; k++)
                    model.addTag(model.backpacks[i].notes[j].tags[k].tag);
            }
        }
        this.populateMapContributors();
        this.populateListContributors();
        this.populateMapTags();
        this.populateListTags();
        this.populateNotesByContributor();
        //this.populateNotesByTag();
        //this.populateNotesByPopularity();

        this.selectAllMapContributors();
        this.selectAllMapTags();
        this.selectAllListContributors();
        this.selectAllListTags();
    };

    this.populateMapContributors = function()
    {
        model.views.contributorMapFilterSelector.innerHTML = ''; //Clear the children
        if(model.contributors.length == 0)
            model.views.contributorMapFilterSelector.appendChild(model.views.defaultContributorMapFilterSelectorCell);
        var tmpcell;
        for(var i = 0; i < model.contributors.length; i++)
        {
            tmpcell = new SelectionCell(model.views.constructContributorMapFilterSelectorCell.cloneNode(true), i%2, this.mapContributorClicked, model.contributors[i]);
            tmpcell.html.firstChild.innerHTML = model.contributors[i];
            model.views.contributorMapFilterSelector.appendChild(tmpcell.html);
            model.contributorMapCells[model.contributorMapCells.length] = tmpcell;
        }
        model.views.contributorMapFilterSelector.appendChild(model.views.helperContributorMapFilterSelectorCell);
    };
    this.populateListContributors = function()
    {
        model.views.contributorListFilterSelector.innerHTML = ''; //Clear the children
        if(model.contributors.length == 0)
            model.views.contributorListFilterSelector.appendChild(model.views.defaultContributorListFilterSelectorCell);
        var tmpcell;
        for(var i = 0; i < model.contributors.length; i++)
        {
            tmpcell = new SelectionCell(model.views.constructContributorListFilterSelectorCell.cloneNode(true), i%2, this.listContributorClicked, model.contributors[i]);
            tmpcell.html.firstChild.innerHTML = model.contributors[i];
            model.views.contributorListFilterSelector.appendChild(tmpcell.html);
            model.contributorListCells[model.contributorListCells.length] = tmpcell;
        }
        model.views.contributorListFilterSelector.appendChild(model.views.helperContributorListFilterSelectorCell);
    };
    this.populateMapTags = function()
    {
        model.views.tagMapFilterSelector.innerHTML = ''; //Clear the children
        if(model.tags.length == 0)
            model.views.tagMapFilterSelector.appendChild(model.views.defaultTagMapFilterSelectorCell);
        var tmpcell;
        for(var i = 0; i < model.tags.length; i++)
        {
            tmpcell = new SelectionCell(model.views.constructTagMapFilterSelectorCell.cloneNode(true), i%2, this.mapTagClicked, model.tags[i]);
            tmpcell.html.firstChild.innerHTML = model.tags[i];
            model.views.tagMapFilterSelector.appendChild(tmpcell.html);
            model.tagMapCells[model.tagMapCells.length] = tmpcell;
        }
        model.views.tagMapFilterSelector.appendChild(model.views.helperTagMapFilterSelectorCell);
    };
    this.populateListTags = function()
    {
        model.views.tagListFilterSelector.innerHTML = ''; //Clear the children
        if(model.tags.length == 0)
            model.views.tagListFilterSelector.appendChild(model.views.defaultTagListFilterSelectorCell);
        var tmpcell;
        for(var i = 0; i < model.tags.length; i++)
        {
            tmpcell = new SelectionCell(model.views.constructTagListFilterSelectorCell.cloneNode(true), i%2, this.listTagClicked, model.tags[i]);
            tmpcell.html.firstChild.innerHTML = model.tags[i];
            model.views.tagListFilterSelector.appendChild(tmpcell.html);
            model.tagListCells[model.tagListCells.length] = tmpcell;
        }
        model.views.tagListFilterSelector.appendChild(model.views.helperTagListFilterSelectorCell);
    };
    this.populateNotesByContributor = function()
    {
        model.views.noteListSelector.innerHTML = ''; //Clear the children
        if(model.contributorNotes.length == 0)
            model.views.noteListSelector.appendChild(model.views.defaultNoteListSelectorCell);
        var tmpcell;
        model.views.contributorNoteCells = [];
        for(var i = 0; i < model.contributorNotes.length; i++)
        {
            tmpcell = new SingleSelectionCell(model.views.constructNoteListSelectorCell.cloneNode(true), i%2, this.noteSelected, model.contributorNotes[i]);
            tmpcell.html.firstChild.innerHTML = ''+model.contributorNotes[i].title+' - '+model.contributorNotes[i].username+'';
            model.views.noteListSelector.appendChild(tmpcell.html);
            model.views.contributorNoteCells[model.views.contributorNoteCells.length] = tmpcell;
        }
    };
    this.populateNotesByTag = function()
    {
        model.views.noteListSelector.innerHTML = ''; //Clear the children
        if(model.tagNotes.length == 0)
            model.views.noteListSelector.appendChild(model.views.defaultNoteListSelectorCell);
        var tmpcell;
        model.views.tagNoteCells = [];
        for(var i = 0; i < model.tagNotes.length; i++)
        {
            tmpcell = new SingleSelectionCell(model.views.constructNoteListSelectorCell.cloneNode(true), i%2, this.noteSelected, model.tagNotes[i]);
            tmpcell.html.firstChild.innerHTML = ''+model.tagNotes[i].title+' - '+model.tagNotes[i].username+'';
            model.views.noteListSelector.appendChild(tmpcell.html);
            model.views.tagNoteCells[model.views.tagNoteCells.length] = tmpcell;
        }
    };
    this.populateNotesByPopularity = function()
    {
        model.views.noteListSelector.innerHTML = ''; //Clear the children
        if(model.popularNotes.length == 0)
            model.views.noteListSelector.appendChild(model.views.defaultNoteListSelectorCell);
        var tmpcell;
        model.views.popularNoteCells = [];
        for(var i = 0; i < model.popularNotes.length; i++)
        {
            tmpcell = new SingleSelectionCell(model.views.constructNoteListSelectorCell.cloneNode(true), i%2, this.noteSelected, model.popularNotes[i]);
            tmpcell.html.firstChild.innerHTML = ''+model.popularNotes[i].title+' - '+model.popularNotes[i].username+'';
            model.views.noteListSelector.appendChild(tmpcell.html);
            model.views.popularNoteCells[model.views.popularNoteCells.length] = tmpcell;
        }
    }
}
<|endoftext|>


<commit_before>var productMgr=(function(config,functions){

    return {
        searchParams:{
            dataCategory:-1,//-1表示所有数据，0表示搜索标签，1表示搜索状态和货号
            brand:[],
            category:[],
            date:[],
            color:[],
            size:[]
        },
        loadedData:{},
        showDetail:function(id){
            var data=this.loadedData[id];
            $(".mustSetValue").each(function(index,el){
                $(this).text(data[$(this).data("name")]);
            })
            $(".mustSetSrc").each(function(index,el){
                $(this).attr("src",data[$(this).data("name")]);
            })
            $("#showDetailModal").modal("show");
        }
    }
})(config,functions);

$(document).ready(function(){

    var table=new ZYTableHandler({
        removeUrl:"#",
        ownTable:function(){
            var ownTable=$("#myTable").dataTable({
                "bServerSide": true,
                "sAjaxSource": config.ajaxUrls.productGetAll,
                "bInfo":true,
                "bProcessing":true,
                "bLengthChange": false,
                "bFilter": false,
                "bSort":false,
                "bAutoWidth": false,
                "iDisplayLength":config.perLoadCounts.table,
                "sPaginationType":"full_numbers",
                "oLanguage": {
                    "sUrl":config.dataTable.langUrl
                },
                "aoColumns": [
                    { "mDataProp": "imageUrl1"},
                    { "mDataProp": "hp_num"},
                    { "mDataProp": "brandList"},
                    { "mDataProp": "categoryList"},
                    { "mDataProp": "timeCategoryList"},
                    { "mDataProp": "dataStatus",
                        "fnRender":function(oObj){
                            return  config.status.product[oObj.aData.dataStatus];
                        }
                    },
                    { "mDataProp": "opt",
                        "fnRender":function(oObj){
                            return  '查看  '+
                                '编辑  '+
                                '作废';
                        }
                    }
                ] ,
                "fnServerParams": function ( aoData ) {
                    aoData.push({
                        name:"dataCategory",
                        value:productMgr.searchParams.dataCategory
                    },{
                        name:"dataStatus",
                        value:$("#searchStatus").val()
                    },{
                        name:"hp_num",
                        value:$("#searchNo").val()
                    },{
                        name:"brand",
                        value:productMgr.searchParams.brand.join(",")
                    },{
                        name:"category",
                        value:productMgr.searchParams.category.join(",")
                    },{
                        name:"date",
                        value:productMgr.searchParams.date.join(",")
                    },{
                        name:"size",
                        value:productMgr.searchParams.size.join(",")
                    },{
                        name:"color",
                        value:productMgr.searchParams.color.join(",")
                    })
                },
                "fnServerData": function(sSource, aoData, fnCallback) {

                    //回调函数
                    $.ajax({
                        "dataType":'json',
                        "type":"get",
                        "url":sSource,
                        "data":aoData,
                        "success": function (response) {
                            if(response.success===false){
                                functions.ajaxReturnErrorHandler(response.message);
                            }else{
                                var json = {
                                    "sEcho" : response.sEcho
                                };

                                productMgr.loadedData={};

                                for (var i = 0, iLen = response.aaData.length; i < iLen; i++) {
                                    response.aaData[i].opt="opt";
                                    productMgr.loadedData[response.aaData[i].id]=response.aaData[i];
                                }

                                json.aaData=response.aaData;
                                json.iTotalRecords = response.iTotalRecords;
                                json.iTotalDisplayRecords = response.iTotalDisplayRecords;
                                fnCallback(json);
                            }

                        }
                    });
                },
                "fnFormatNumber":function(iIn){
                    return iIn;
                }
            });

            return ownTable;
        }
    });

    $("#myTable").on("click","a.remove",function(){
        if(confirm(config.messages.confirmDelete)){
            table.delete($(this).attr("href"));
        }
        return false;
    }).on("click","a.check",function(){
            productMgr.showDetail($(this).attr("href"));
            return false;
        });

    $("#searchBtn").click(function(){
        productMgr.searchParams={
            dataCategory:1,
            brand:[],
            category:[],
            date:[],
            color:[],
            size:[]
        };

        //后台没有处理dataStatus为-1（全部）的情况，如果status为-1，并且No为空，那就是直接查所有数据
        if($("#searchStatus").val()==-1&&!$("#searchNo").val()){
            productMgr.searchParams.dataCategory=-1;
        }

        $("#searchPanel .active").removeClass("active");
        table.tableRedraw();
    });

    $("#searchPanel").on("click",".item",function(){
        var el=$(this);
        var type=el.data("type");
        var id= el.data("id");
        var index;

        $("#searchNo").val("");
        $("#searchStatus").val(-1);

        if(el.hasClass("active")){
            index=productMgr.searchParams[type].indexOf(id);
            productMgr.searchParams[type].splice(index,1);
            el.removeClass("active");
        }else{
            productMgr.searchParams[type].push(id);
            el.addClass("active");
        }

        if($("#searchPanel .active").length==0){
            productMgr.searchParams.dataCategory=-1;
        }else{
            productMgr.searchParams.dataCategory=0;
        }
        table.tableRedraw();
    });

    $("#searchPanelCtrl").click(function(){
        if($(this).data("target").indexOf("down")!=-1){
            $("#searchPanel .row").hide(400);
            $(this).find(".glyphicon").removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
            $(this).data("target","up");
            $(this).find(".text").text("展开选项");
        }else{
            $("#searchPanel .row").show(400);
            $(this).find(".glyphicon").removeClass("glyphicon-chevron-down").addClass("glyphicon-chevron-up");
            $(this).data("target","down");
            $(this).find(".text").text("收起选项");
        }

    });

});<commit_msg>update<commit_after>var productMgr = (function (config, functions) {

    return {
        searchParams: {
            dataCategory: -1,//-1表示所有数据，0表示搜索标签，1表示搜索状态和货号
            brand: [],
            category: [],
            date: [],
            color: [],
            size: []
        },
        loadedData: {},
        showDetail: function (id) {
            var data = this.loadedData[id];
            $(".mustSetValue").each(function (index, el) {
                $(this).text(data[$(this).data("name")]);
            })
            $(".mustSetSrc").each(function (index, el) {
                $(this).attr("src", data[$(this).data("name")]);
            })
            $("#showDetailModal").modal("show");
        }
    }
})(config, functions);

$(document).ready(function () {

    var table = new ZYTableHandler({
        removeUrl: "#",
        ownTable: function () {
            var ownTable = $("#myTable").dataTable({
                "bServerSide": true,
                "sAjaxSource": config.ajaxUrls.productGetAll,
                "bInfo": true,
                "bProcessing": true,
                "bLengthChange": false,
                "bFilter": false,
                "bSort": false,
                "bAutoWidth": false,
                "iDisplayLength": config.perLoadCounts.table,
                "sPaginationType": "full_numbers",
                "oLanguage": {
                    "sUrl": config.dataTable.langUrl
                },
                "aoColumns": [
                    { "mDataProp": "imageUrl1"},
                    { "mDataProp": "hp_num"},
                    { "mDataProp": "brandList"},
                    { "mDataProp": "categoryList"},
                    { "mDataProp": "timeCategoryList"},
                    { "mDataProp": "dataStatus",
                        "fnRender": function (oObj) {
                            return  config.status.product[oObj.aData.dataStatus];
                        }
                    },
                    { "mDataProp": "opt",
                        "fnRender": function (oObj) {
                            return  '查看  ' +
                                '编辑  ' +
                                '作废';
                        }
                    }
                ],
                "fnServerParams": function (aoData) {
                    aoData.push({
                        name: "dataCategory",
                        value: productMgr.searchParams.dataCategory
                    }, {
                        name: "dataStatus",
                        value: $("#searchStatus").val()
                    }, {
                        name: "hp_num",
                        value: $("#searchNo").val()
                    }, {
                        name: "brand",
                        value: productMgr.searchParams.brand.join(",")
                    }, {
                        name: "category",
                        value: productMgr.searchParams.category.join(",")
                    }, {
                        name: "date",
                        value: productMgr.searchParams.date.join(",")
                    }, {
                        name: "size",
                        value: productMgr.searchParams.size.join(",")
                    }, {
                        name: "color",
                        value: productMgr.searchParams.color.join(",")
                    })
                },
                "fnServerData": function (sSource, aoData, fnCallback) {

                    //回调函数
                    $.ajax({
                        "dataType": 'json',
                        "type": "get",
                        "url": sSource,
                        "data": aoData,
                        "success": function (response) {
                            if (response.success === false) {
                                functions.ajaxReturnErrorHandler(response.message);
                            } else {
                                var json = {
                                    "sEcho": response.sEcho
                                };

                                productMgr.loadedData = {};

                                for (var i = 0, iLen = response.aaData.length; i < iLen; i++) {
                                    response.aaData[i].opt = "opt";
                                    productMgr.loadedData[response.aaData[i].id] = response.aaData[i];
                                }

                                json.aaData = response.aaData;
                                json.iTotalRecords = response.iTotalRecords;
                                json.iTotalDisplayRecords = response.iTotalDisplayRecords;
                                fnCallback(json);
                            }

                        }
                    });
                },
                "fnFormatNumber": function (iIn) {
                    return iIn;
                }
            });

            return ownTable;
        }
    });

    $("#myTable").on("click", "a.remove",function () {
        if (confirm(config.messages.confirmDelete)) {
            table.delete($(this).attr("href"));
        }
        return false;
    }).on("click", "a.check", function () {
            productMgr.showDetail($(this).attr("href"));
            return false;
        });

    $("#searchBtn").click(function () {
        productMgr.searchParams = {
            dataCategory: 1,
            brand: [],
            category: [],
            date: [],
            color: [],
            size: []
        };

        //后台没有处理dataStatus为-1（全部）的情况，如果status为-1，并且No为空，那就是直接查所有数据
        if ($("#searchStatus").val() == -1 && !$("#searchNo").val()) {
            productMgr.searchParams.dataCategory = -1;
        }

        $("#searchPanel .active").removeClass("active");
        table.tableRedraw();
    });

    $("#searchPanel").on("click", ".item", function () {
        var el = $(this),
            type = el.data("type"),
            id = el.data("id"),
            index;

        $("#searchNo").val("");
        $("#searchStatus").val(-1);

        if (el.hasClass("active")) {
            index = productMgr.searchParams[type].indexOf(id);
            productMgr.searchParams[type].splice(index, 1);
            el.removeClass("active");
        } else {
            productMgr.searchParams[type].push(id);
            el.addClass("active");
        }

        if ($("#searchPanel .active").length == 0) {
            productMgr.searchParams.dataCategory = -1;
        } else {
            productMgr.searchParams.dataCategory = 0;
        }
        table.tableRedraw();
    });

    $("#searchPanelCtrl").click(function () {
        if ($(this).data("target").indexOf("down") != -1) {
            $("#searchPanel .row").hide(400);
            $(this).find(".glyphicon").removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
            $(this).data("target", "up");
            $(this).find(".text").text("展开选项");
        } else {
            $("#searchPanel .row").show(400);
            $(this).find(".glyphicon").removeClass("glyphicon-chevron-down").addClass("glyphicon-chevron-up");
            $(this).data("target", "down");
            $(this).find(".text").text("收起选项");
        }

    });

});<|endoftext|>


<commit_before>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define(function() {

    return [
        {
            name: 'Backbone.js',
            url: 'http://backbonejs.org/',
            version: '1.2.3',
            license: 'MIT',
            edited: false
        }, {
            name: 'Bootstrap',
            url: 'http://twitter.github.com/bootstrap/',
            version: '3.3.5',
            license: 'Apache License v2.0',
            edited: true
        }, {
            name: 'Bootstrap Date Time Picker',
            url: 'http://eonasdan.github.io/bootstrap-datetimepicker/',
            version: '4.14.30',
            license: 'MIT',
            edited: false
        }, {
            name: 'DataTables',
            url: 'http://www.datatables.net/download/',
            version: '1.10.2',
            license: 'BSD',
            edited: false
        }, {
            name: 'Font Awesome by Dave Gandy',
            url: 'http://fontawesome.io',
            version: '3.2.1',
            license: 'MIT/SIL OFL 1.1', // icons are SIL OFL 1.1, css is MIT
            edited: false // remove parameter from css url
        }, {
            name: 'jQuery',
            url: 'http://jquery.com/',
            version: '1.10.2',
            license: 'MIT',
            edited: false
        }, {
            name: 'json2.js',
            url: 'https://github.com/douglascrockford/JSON-js',
            version: '2012-10-08',
            license: 'Public Domain',
            edited: false
        }, {
            name: 'Leaflet',
            url: 'http://leafletjs.com',
            version: '0.7.7',
            license: 'BSD',
            edited: false
        }, {
            name: 'Moment.js',
            url: 'http://momentjs.com',
            version: '2.10.3',
            license: 'MIT',
            edited: false
        }, {
            name: 'RequireJS',
            url: 'http://requirejs.org/',
            version: '2.1.15',
            license: 'BSD',
            edited: false
        }, {
            name: 'Underscore.js',
            url: 'http://underscorejs.org/',
            version: '1.8.3',
            license: 'MIT',
            edited: false
        }
    ];

});
<commit_msg>[BIFHI-254] Updating about page library list with latest library usage [rev: Matt Gordon]<commit_after>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define(function() {

    return [
        {
            name: 'Backbone.js',
            url: 'http://backbonejs.org/',
            version: '1.2.3',
            license: 'MIT',
            edited: false
        }, {
            name: 'Bootstrap',
            url: 'http://twitter.github.com/bootstrap/',
            version: '3.3.5',
            license: 'Apache License v2.0',
            edited: true
        }, {
            name: 'Bootstrap Date Time Picker',
            url: 'http://eonasdan.github.io/bootstrap-datetimepicker/',
            version: '4.14.30',
            license: 'MIT',
            edited: false
        },  {
            name: 'Bootstrap Slider',
            url: 'https://github.com/seiyria/bootstrap-slider',
            version: '6.0.8',
            license: 'MIT',
            edited: false
        }, {
            name: 'Chosen',
            url: 'https://harvesthq.github.io/chosen/',
            version: '1.4.2',
            license: 'MIT',
            edited: false
        }, {
            name: 'd3',
            url: 'https://d3js.org/',
            version: '3.3.8',
            license: 'BSD',
            edited: false
        }, {
            name: 'DataTables',
            url: 'http://www.datatables.net/download/',
            version: '1.10.11',
            license: 'BSD',
            edited: false
        }, {
            name: 'Font Awesome by Dave Gandy',
            url: 'http://fontawesome.io',
            version: '4.5.0',
            license: 'MIT/SIL OFL 1.1', // icons are SIL OFL 1.1, css is MIT
            edited: false // remove parameter from css url
        }, {
            name: 'iCheck',
            url: 'http://icheck.fronteed.com/',
            version: '1.0.1',
            license: 'MIT',
            edited: false
        }, {
            name: 'jQuery',
            url: 'http://jquery.com/',
            version: '1.10.2',
            license: 'MIT',
            edited: false
        }, {
            name: 'json2.js',
            url: 'https://github.com/douglascrockford/JSON-js',
            version: '2012-10-08',
            license: 'Public Domain',
            edited: false
        }, {
            name: 'Leaflet',
            url: 'http://leafletjs.com',
            version: '0.7.7',
            license: 'BSD',
            edited: false
        }, {
            name: 'Moment.js',
            url: 'http://momentjs.com',
            version: '2.10.3',
            license: 'MIT',
            edited: false
        }, {
            name: 'Raphaël',
            url: 'http://raphaeljs.com/',
            version: '2.1.2',
            license: 'MIT',
            edited: false
        }, {
            name: 'RequireJS',
            url: 'http://requirejs.org/',
            version: '2.1.15',
            license: 'BSD',
            edited: false
        }, {
            name: 'typeahead.js',
            url: 'https://typeahead.js.org/',
            version: '#3d2a7eb',
            license: 'MIT',
            edited: false
        }, {
            name: 'Underscore.js',
            url: 'http://underscorejs.org/',
            version: '1.8.3',
            license: 'MIT',
            edited: false
        }
    ];

});
<|endoftext|>


<commit_before>import { curry, includes, isEmpty, values } from 'lodash'
import moment from 'moment'
import addTermToQueryBuilder from './addTermToQueryBuilder'

export const filterAndSortPosts = curry((opts, q) => {
  const {
    afterTime,
    beforeTime,
    boundingBox,
    isAnnouncement,
    isFulfilled,
    order = 'desc',
    search,
    showPinnedFirst,
    sortBy = 'updated',
    topic,
    type,
    types
  } = opts

  let { topics = [] } = opts

  const sortColumns = {
    votes: 'posts.num_votes',
    updated: 'posts.updated_at',
    created: 'posts.created_at',
    start_time: 'posts.start_time'
  }

  const sort = sortColumns[sortBy] || values(sortColumns).find(v => v === 'posts.' + sortBy || v === sortBy)
  if (!sort) {
    throw new Error(`Cannot sort by "${sortBy}"`)
  }

  const { DISCUSSION, REQUEST, OFFER, PROJECT, EVENT, RESOURCE } = Post.Type

  if (isAnnouncement) {
    q.where('announcement', true).andWhere('posts.created_at', '>=', moment().subtract(1, 'month').toDate())
  }

  if (isFulfilled === true) {
    q.where(q2 => {
      q2.whereNotNull('posts.fulfilled_at')
      .orWhere('posts.end_time', '<', moment().toDate())
    })
  } else if (isFulfilled === false) {
    q.whereNull('posts.fulfilled_at')
    .andWhere(q2 => {
      q2.whereNull('posts.end_time')
      .orWhere('posts.end_time', '>=', moment().toDate())
    })
  }

  if (afterTime) {
    q.where(q2 =>
      q2.where('posts.start_time', '>=', afterTime)
      .orWhere('posts.end_time', '>=', afterTime)
    )
  }

  if (beforeTime) {
    q.where(q2 =>
      q2.where('posts.start_time', '<', beforeTime)
      .andWhere('posts.end_time', '<', beforeTime)
    )
  }

  if (types) {
    q.whereIn('posts.type', types)
  } else if (!type || type === 'all' || type === 'all+welcome') {
    q.whereIn('posts.type', [DISCUSSION, REQUEST, OFFER, PROJECT, EVENT, RESOURCE])
  } else {
    if (!includes(values(Post.Type), type)) {
      throw new Error(`unknown post type: "${type}"`)
    }
    q.where({'posts.type': type})
  }

  if (!isEmpty(search)) {
    addTermToQueryBuilder(search, q, {
      columns: ['posts.name', 'posts.description']
    })
  }

  if (topic) {
    topics = topics.concat(topic)
  }

  if (!isEmpty(topics)) {
    q.join('posts_tags', 'posts_tags.post_id', 'posts.id')
    if (/^\d+$/.test(topics[0])) { // topic ID
      q.whereIn('posts_tags.tag_id', topics)
    } else { // topic name
      q.join('tags', 'posts_tags.tag_id', 'tags.id')
      q.whereIn('tags.name', topics)
    }
  }

  if (boundingBox) {
    q.join('locations', 'locations.id', '=', 'posts.location_id')
    q.whereRaw('locations.center && ST_MakeEnvelope(?, ?, ?, ?, 4326)', [boundingBox[0].lng, boundingBox[0].lat, boundingBox[1].lng, boundingBox[1].lat])
  }

  if (sort === 'posts.updated_at' && showPinnedFirst) {
    q.orderByRaw('groups_posts.pinned_at is null asc, groups_posts.pinned_at desc, posts.updated_at desc')
  } else if (sort) {
    q.orderBy(sort, order || 'desc')
  }

})

export const filterAndSortUsers = curry(({ autocomplete, boundingBox, order, search, sortBy }, q) => {
  if (autocomplete) {
    addTermToQueryBuilder(autocomplete, q, {
      columns: ['users.name']
    })
  }

  if (search) {
    q.whereIn('users.id', FullTextSearch.search({
      term: search,
      type: 'person',
      subquery: true
    }))
  }

  if (sortBy && !['name', 'location', 'join', 'last_active_at'].includes(sortBy)) {
    throw new Error(`Cannot sort by "${sortBy}"`)
  }

  if (order && !['asc', 'desc'].includes(order.toLowerCase())) {
    throw new Error(`Cannot use sort order "${order}"`)
  }

  if (sortBy === 'join') {
    q.orderBy('group_memberships.created_at', order || 'desc')
  } else if (!sortBy || sortBy === 'name') {
    q.orderByRaw(`lower("users"."name") ${order || 'asc'}`)
  } else {
    q.orderBy(sortBy, order || 'asc')
  }

  if (boundingBox) {
    q.join('locations', 'locations.id', '=', 'users.location_id')
    q.whereRaw('locations.center && ST_MakeEnvelope(?, ?, ?, ?, 4326)', [boundingBox[0].lng, boundingBox[0].lat, boundingBox[1].lng, boundingBox[1].lat])
  }
})

export const filterAndSortGroups = curry((opts, q) => {
  const { search, sortBy = 'name', boundingBox, order } = opts

  if (search) {
    addTermToQueryBuilder(search, q, {
      columns: ['groups.name', 'groups.description', 'groups.location']
    })
  }

  if (boundingBox) {
    q.join('locations', 'locations.id', '=', 'groups.location_id')
    q.whereRaw('locations.center && ST_MakeEnvelope(?, ?, ?, ?, 4326)', [boundingBox[0].lng, boundingBox[0].lat, boundingBox[1].lng, boundingBox[1].lat])
  }

  if (sortBy === 'size') {
    q.with('member_count', bookshelf.knex.raw(`
      SELECT group_id, COUNT(group_id) as size from group_memberships GROUP BY group_id
    `))
    q.join('member_count', 'groups.id', '=', 'member_count.group_id')
  }

  q.orderBy(sortBy || 'name', order || sortBy === 'size' ? 'desc' : 'asc')
})
<commit_msg>Arbitrary change to force tests to run again<commit_after>import { curry, includes, isEmpty, values } from 'lodash'
import moment from 'moment'
import addTermToQueryBuilder from './addTermToQueryBuilder'

export const filterAndSortPosts = curry((opts, q) => {
  const {
    afterTime,
    beforeTime,
    boundingBox,
    isAnnouncement,
    isFulfilled,
    order = 'desc',
    search,
    showPinnedFirst,
    sortBy = 'updated',
    topic,
    type,
    types
  } = opts

  let { topics = [] } = opts

  const sortColumns = {
    votes: 'posts.num_votes',
    updated: 'posts.updated_at',
    created: 'posts.created_at',
    start_time: 'posts.start_time'
  }

  const sort = sortColumns[sortBy] || values(sortColumns).find(v => v === 'posts.' + sortBy || v === sortBy)
  if (!sort) {
    throw new Error(`Cannot sort by "${sortBy}"`)
  }

  const { DISCUSSION, REQUEST, OFFER, PROJECT, EVENT, RESOURCE } = Post.Type

  if (isAnnouncement) {
    q.where('announcement', true).andWhere('posts.created_at', '>=', moment().subtract(1, 'month').toDate())
  }

  if (isFulfilled === true) {
    q.where(q2 => {
      q2.whereNotNull('posts.fulfilled_at')
      .orWhere('posts.end_time', '<', moment().toDate())
    })
  } else if (isFulfilled === false) {
    q.whereNull('posts.fulfilled_at')
    .andWhere(q2 => {
      q2.whereNull('posts.end_time')
      .orWhere('posts.end_time', '>=', moment().toDate())
    })
  }

  if (afterTime) {
    q.where(q2 =>
      q2.where('posts.start_time', '>=', afterTime)
      .orWhere('posts.end_time', '>=', afterTime)
    )
  }

  if (beforeTime) {
    q.where(q2 =>
      q2.where('posts.start_time', '<', beforeTime)
      .andWhere('posts.end_time', '<', beforeTime)
    )
  }

  if (types) {
    q.whereIn('posts.type', types)
  } else if (!type || type === 'all' || type === 'all+welcome') {
    q.whereIn('posts.type', [DISCUSSION, REQUEST, OFFER, PROJECT, EVENT, RESOURCE])
  } else {
    if (!includes(values(Post.Type), type)) {
      throw new Error(`unknown post type: "${type}"`)
    }
    q.where({'posts.type': type})
  }

  if (!isEmpty(search)) {
    addTermToQueryBuilder(search, q, {
      columns: ['posts.name', 'posts.description']
    })
  }

  if (topic) {
    topics = topics.concat(topic)
  }

  if (!isEmpty(topics)) {
    q.join('posts_tags', 'posts_tags.post_id', 'posts.id')
    if (/^\d+$/.test(topics[0])) { // topic ID
      q.whereIn('posts_tags.tag_id', topics)
    } else { // topic name
      q.join('tags', 'posts_tags.tag_id', 'tags.id')
      q.whereIn('tags.name', topics)
    }
  }

  if (boundingBox) {
    q.join('locations', 'locations.id', '=', 'posts.location_id')
    q.whereRaw('locations.center && ST_MakeEnvelope(?, ?, ?, ?, 4326)', [boundingBox[0].lng, boundingBox[0].lat, boundingBox[1].lng, boundingBox[1].lat])
  }

  if (sort === 'posts.updated_at' && showPinnedFirst) {
    q.orderByRaw('groups_posts.pinned_at is null asc, groups_posts.pinned_at desc, posts.updated_at desc')
  } else if (sort) {
    q.orderBy(sort, order || 'desc')
  }

})

export const filterAndSortUsers = curry(({ autocomplete, boundingBox, order, search, sortBy }, q) => {
  if (autocomplete) {
    addTermToQueryBuilder(autocomplete, q, {
      columns: ['users.name']
    })
  }

  if (search) {
    q.whereIn('users.id', FullTextSearch.search({
      term: search,
      type: 'person',
      subquery: true
    }))
  }

  if (sortBy && !['name', 'location', 'join', 'last_active_at'].includes(sortBy)) {
    throw new Error(`Cannot sort by "${sortBy}"`)
  }

  if (order && !['asc', 'desc'].includes(order.toLowerCase())) {
    throw new Error(`Cannot use sort order "${order}"`)
  }

  if (sortBy === 'join') {
    q.orderBy('group_memberships.created_at', order || 'desc')
  } else if (!sortBy || sortBy === 'name') {
    q.orderByRaw(`lower("users"."name") ${order || 'asc'}`)
  } else {
    q.orderBy(sortBy, order || 'asc')
  }

  if (boundingBox) {
    q.join('locations', 'locations.id', '=', 'users.location_id')
    q.whereRaw('locations.center && ST_MakeEnvelope(?, ?, ?, ?, 4326)', [boundingBox[0].lng, boundingBox[0].lat, boundingBox[1].lng, boundingBox[1].lat])
  }
})

export const filterAndSortGroups = curry((opts, q) => {

  const { search, sortBy = 'name', boundingBox, order } = opts

  if (search) {
    addTermToQueryBuilder(search, q, {
      columns: ['groups.name', 'groups.description', 'groups.location']
    })
  }

  if (boundingBox) {
    q.join('locations', 'locations.id', '=', 'groups.location_id')
    q.whereRaw('locations.center && ST_MakeEnvelope(?, ?, ?, ?, 4326)', [boundingBox[0].lng, boundingBox[0].lat, boundingBox[1].lng, boundingBox[1].lat])
  }

  if (sortBy === 'size') {
    q.with('member_count', bookshelf.knex.raw(`
      SELECT group_id, COUNT(group_id) as size from group_memberships GROUP BY group_id
    `))
    q.join('member_count', 'groups.id', '=', 'member_count.group_id')
  }

  q.orderBy(sortBy || 'name', order || sortBy === 'size' ? 'desc' : 'asc')
})
<|endoftext|>


<commit_before>import React from "react"

import Button from "../../Button"

const formSectionStyle = {
  display: "flex",
  flexDirection: "row"
}
const mailchimpURL = "//club.us2.list-manage.com/subscribe/post?u=2659100f5014c16e6b9ba2742&id=cf213912a3"

export default function Newsletter () {
  return <form data-componet="Newsletter" action={mailchimpURL} method="post" target="_blank">

      Your email
      <input id="email" name="email" type="email" required />

      Your name
      <input id="name" name="name" type="text" required />

        <input type="text" name="b_2659100f5014c16e6b9ba2742_cf213912a3" tabIndex="-1" value="" />

      <Button type="submit" kind="primary">
        We'll let you know when we're open.
      </Button>

  </form>
}
<commit_msg>Don't need this much markup<commit_after>import React from "react"

import Button from "../../Button"

const formSectionStyle = {
  display: "flex",
  flexDirection: "row"
}
const mailchimpURL = "//club.us2.list-manage.com/subscribe/post?u=2659100f5014c16e6b9ba2742&id=cf213912a3"

export default function Newsletter () {
  return <form data-componet="Newsletter" action={mailchimpURL} method="post" target="_blank">

      Your email
      <input id="email" name="email" type="email" required />

      Your name
      <input id="name" name="name" type="text" required />

      <input type="text" name="b_2659100f5014c16e6b9ba2742_cf213912a3" tabIndex="-1" value="" />

      <Button type="submit" kind="primary">
        We'll let you know when we're open.
      </Button>

  </form>
}
<|endoftext|>


<commit_before>var Promise = require('promise');
var log4js = require('log4js');
var logger = log4js.getLogger();
var SlackWebhook = require('slack-webhook');
var slack = process.env.SLACK_WEBHOOK ? new SlackWebhook(process.env.SLACK_WEBHOOK, {
  defaults: {
    username: 'JukeBot'
  }
}) : null;

module.exports = {
  addVideo: addVideo,
  sendAddMessages: sendAddMessages
};

function addVideo(video) {
  logger.info('Adding video ' + video.key);
  return new Promise(function(resolve, reject) {
    Video.findOne({
      playing: true
    }).exec(function(err, current) {
      if (!current) {
        video.startTime = new Date();
        video.playing = true;
        video.played = true;
        setTimeout(endCurrentVideo, video.duration);
        video.save(function() {
          resolve(video);
        });
      } else {
        resolve(video);
      }
    });
  });
}

function sendAddMessages(video) {
  return new Promise(function(resolve, reject) {
    Video.publishCreate(video);
    if (slack) {
      slack.send({
        text: video.user + ' added a song to the playlist' + (video.playing ? ' and it\'s playing now' : '') + '! <' + sails.config.serverUrl + '|Listen to JukeBot>',
        attachments: [formatSlackAttachment(video)]
      }).then(function() {
        resolve(video);
      });
    } else {
      resolve(video);
    }
  });
}

function formatSlackAttachment(video) {
  return {
    title: video.title,
    title_link: 'https://www.youtube.com/watch?v=' + video.key,
    thumb_url: video.thumbnail
  };
}

function endCurrentVideo() {
  Video.findOne({
    playing: true
  }).exec(function(err, current) {
    current.playing = false;
    current.save(function() {
      logger.info('Publishing end song ' + current.key);
      Video.publishUpdate(current.id, current);
      findNextVideo();
    });
  });
}

function findNextVideo() {
  Video.find({
    played: false
  }).sort('createdAt ASC').exec(function(err, upcoming) {
    if (upcoming.length > 0) {
      startVideo(upcoming[0]);
    }
  });
}

function startVideo(video) {
  video.playing = true;
  video.played = true;
  video.startTime = new Date();
  logger.info('Setting timeout');
  setTimeout(endCurrentVideo, video.durationSeconds * 1000);
  video.save(() => {
      logger.info('Stopping video ' + video.key);
      Video.publishUpdate(video.id, video);
      if (slack) {
        slack.send({
          text: '*' + video.title + '* is now playing! <' + sails.config.serverUrl + '|Listen to JukeBot>',
          'mrkdwn': true
        }).then(function() {
          logger.info('Started playing video ' + video.key);
        });
      } else {
        logger.info('Started playing video ' + video.key);
      }
    });
}
<commit_msg>Fix ending current video timeout merge bug<commit_after>var Promise = require('promise');
var log4js = require('log4js');
var logger = log4js.getLogger();
var SlackWebhook = require('slack-webhook');
var slack = process.env.SLACK_WEBHOOK ? new SlackWebhook(process.env.SLACK_WEBHOOK, {
  defaults: {
    username: 'JukeBot'
  }
}) : null;

module.exports = {
  addVideo: addVideo,
  sendAddMessages: sendAddMessages
};

function addVideo(video) {
  logger.info('Adding video ' + video.key);
  return new Promise(function(resolve, reject) {
    Video.findOne({
      playing: true
    }).exec(function(err, current) {
      if (!current) {
        video.startTime = new Date();
        video.playing = true;
        video.played = true;
        setTimeout(endCurrentVideo, video.duration);
        video.save(function() {
          resolve(video);
        });
      } else {
        resolve(video);
      }
    });
  });
}

function sendAddMessages(video) {
  return new Promise(function(resolve, reject) {
    Video.publishCreate(video);
    if (slack) {
      slack.send({
        text: video.user + ' added a song to the playlist' + (video.playing ? ' and it\'s playing now' : '') + '! <' + sails.config.serverUrl + '|Listen to JukeBot>',
        attachments: [formatSlackAttachment(video)]
      }).then(function() {
        resolve(video);
      });
    } else {
      resolve(video);
    }
  });
}

function formatSlackAttachment(video) {
  return {
    title: video.title,
    title_link: 'https://www.youtube.com/watch?v=' + video.key,
    thumb_url: video.thumbnail
  };
}

function endCurrentVideo() {
  Video.findOne({
    playing: true
  }).exec(function(err, current) {
    current.playing = false;
    current.save(function() {
      logger.info('Publishing end song ' + current.key);
      Video.publishUpdate(current.id, current);
      findNextVideo();
    });
  });
}

function findNextVideo() {
  Video.find({
    played: false
  }).sort('createdAt ASC').exec(function(err, upcoming) {
    if (upcoming.length > 0) {
      startVideo(upcoming[0]);
    }
  });
}

function startVideo(video) {
  video.playing = true;
  video.played = true;
  video.startTime = new Date();
  logger.info('Setting timeout');
  setTimeout(endCurrentVideo, video.duration);
  video.save(() => {
      logger.info('Stopping video ' + video.key);
      Video.publishUpdate(video.id, video);
      if (slack) {
        slack.send({
          text: '*' + video.title + '* is now playing! <' + sails.config.serverUrl + '|Listen to JukeBot>',
          'mrkdwn': true
        }).then(function() {
          logger.info('Started playing video ' + video.key);
        });
      } else {
        logger.info('Started playing video ' + video.key);
      }
    });
}
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */

const { assign, chain, find, isEmpty } = require('lodash');
const Octokit = require('@octokit/rest');
const Promise = require('bluebird');
const moment = require('moment');

/**
 * `ChangelogFetcher` class.
 */

class ChangelogFetcher {
  /**
   * Constructor.
   */

  constructor({ base, futureRelease, futureReleaseTag, labels, owner, repo, token }) {
    this.base = base;
    this.futureRelease = futureRelease;
    this.futureReleaseTag = futureReleaseTag || futureRelease;
    this.labels = labels;
    this.owner = owner;
    this.repo = repo;
    this.client = new Octokit({
      auth: `token ${token}`
    });
  }

  /**
   * Assign pull request to release.
   */

  assignPullRequestToRelease(releases, pr) {
    const release = find(releases, release => pr.merged_at.isSameOrBefore(release.created_at));

    if (release) {
      release.prs.unshift(pr);
    }
  }

  /**
   * Fetch changelog.
   */

  async fetchChangelog() {
    const [releases, prs] = await Promise.all([this.getAllReleases(), this.getAllPullRequests()]);

    prs.forEach(pr => this.assignPullRequestToRelease(releases, pr));

    return releases.reverse();
  }

  /**
   * Get all pull requests.
   */

  async getAllPullRequests() {
    const options = this.client.pulls.list.endpoint.merge({
      base: this.base,
      owner: this.owner,
      page: 1,
      per_page: 100,
      repo: this.repo,
      state: 'closed'
    });

    const prs = await this.client.paginate(options);

    return chain(prs)
      .filter(
        ({ labels }) =>
          isEmpty(this.labels) ||
          !chain(labels)
            .map('name')
            .intersection(this.labels)
            .isEmpty()
            .value()
      )
      .map(pr => assign(pr, { merged_at: moment.utc(pr.merged_at) }))
      .sortBy(pr => pr.merged_at.unix())
      .value();
  }

  /**
   * Get all releases.
   */

  async getAllReleases() {
    const options = this.client.repos.listReleases.endpoint.merge({
      owner: this.owner,
      page: 1,
      per_page: 100,
      repo: this.repo
    });

    const releases = await this.client.paginate(options);

    if (this.futureRelease) {
      releases.unshift({
        created_at: moment().format(),
        html_url: `https://github.com/${this.owner}/${this.repo}/releases/tag/${this.futureReleaseTag}`,
        name: this.futureRelease
      });
    }

    return chain(releases)
      .map(release => assign(release, { created_at: moment.utc(release.created_at), prs: [] }))
      .sortBy(release => release.created_at.unix())
      .value();
  }
}

/**
 * Export `ChangelogFetcher`.
 */

module.exports = ChangelogFetcher;
<commit_msg>Remove lodash destructuring<commit_after>'use strict';

/**
 * Module dependencies.
 */

const _ = require('lodash');
const Promise = require('bluebird');
const Octokit = require('@octokit/rest');
const moment = require('moment');

/**
 * `ChangelogFetcher` class.
 */

class ChangelogFetcher {
  /**
   * Constructor.
   */

  constructor({ base, futureRelease, futureReleaseTag, labels, owner, repo, token }) {
    this.base = base;
    this.futureRelease = futureRelease;
    this.futureReleaseTag = futureReleaseTag || futureRelease;
    this.labels = labels;
    this.owner = owner;
    this.repo = repo;
    this.client = new Octokit({
      auth: `token ${token}`
    });
  }

  /**
   * Assign pull request to release.
   */

  assignPullRequestToRelease(releases, pr) {
    const release = releases.find(release => pr.merged_at.isSameOrBefore(release.created_at));

    if (release) {
      release.prs.unshift(pr);
    }
  }

  /**
   * Fetch changelog.
   */

  async fetchChangelog() {
    const [releases, prs] = await Promise.all([this.getAllReleases(), this.getAllPullRequests()]);

    prs.forEach(pr => this.assignPullRequestToRelease(releases, pr));

    return releases.reverse();
  }

  /**
   * Get all pull requests.
   */

  async getAllPullRequests() {
    const prs = await this.client.paginate(
      this.client.pulls.list.endpoint.merge({
        base: this.base,
        owner: this.owner,
        page: 1,
        per_page: 100,
        repo: this.repo,
        state: 'closed'
      })
    );

    return _(prs)
      .filter(
        ({ labels }) =>
          _.isEmpty(this.labels) ||
          !_(labels)
            .map('name')
            .intersection(this.labels)
            .isEmpty()
      )
      .map(pr => ({ ...pr, merged_at: moment.utc(pr.merged_at) }))
      .sortBy(pr => pr.merged_at.unix())
      .value();
  }

  /**
   * Get all releases.
   */

  async getAllReleases() {
    const releases = await this.client.paginate(
      this.client.repos.listReleases.endpoint.merge({
        owner: this.owner,
        page: 1,
        per_page: 100,
        repo: this.repo
      })
    );

    if (this.futureRelease) {
      releases.unshift({
        created_at: moment().format(),
        html_url: `https://github.com/${this.owner}/${this.repo}/releases/tag/${this.futureReleaseTag}`,
        name: this.futureRelease
      });
    }

    return _(releases)
      .map(release => ({ ...release, created_at: moment.utc(release.created_at), prs: [] }))
      .sortBy(release => release.created_at.unix())
      .value();
  }
}

/**
 * Export `ChangelogFetcher`.
 */

module.exports = ChangelogFetcher;
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    chai = require('chai'),
    expect = chai.expect,
    through = require('through2'),
    styleguide = require('requirefrom')('lib')('styleguide'),
    assertions = require('./assertions'),
    defaultSource = 'test/projects/scss-project/source/**/*.scss',
    defaultConfig = require('./test-config');

chai.config.includeStack = true;

function styleguideGenerateStream(source, config) {
  return gulp.src(source || defaultSource)
    .pipe(styleguide.generate(config || defaultConfig));
}

function styleguideApplyStylesStream() {
  return gulp.src('test/projects/shared-css/*')
    .pipe(styleguide.applyStyles());
}

// This collector collects all files from the stream to the array passed as parameter
function collector(collection) {
  return function(file, enc, cb) {
    if (!file.path) {
      return;
    }
    collection.push(file);
    cb();
  };
}

function findFile(files, name) {
  for (var i = files.length - 1; i >= 0; i--) {
    if (files[i].relative === name) {
      return files[i];
    }
  }
}

describe('index.html', function() {

  assertions.indexHtml.register();

  var indexHtml;

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideGenerateStream().pipe(
      through.obj(collector(files), function(callback) {
        indexHtml = findFile(files, 'index.html');
        assertions.indexHtml.set(indexHtml);
        callback();
        done();
      })
    );
  });

  it('should contain filesConfig passed as parameter and in correct format', function() {
    expect(indexHtml.contents.toString()).to.contain('var filesConfig = []');
  });

  it('should contain serialized styleguide configuration', function() {
    expect(indexHtml.contents.toString()).to.contain('var _styleguideConfig = {"title":"Test Styleguide"');
  });

  it('should not add extraHead to serialized configuration', function() {
    expect(indexHtml.contents.toString()).not.to.contain('"extreHead":');
  });
});

describe('styleguide_pseudo_styles.css', function() {

  assertions.pseudoStyles.register();

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideApplyStylesStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'styleguide_pseudo_styles.css');
        assertions.pseudoStyles.set(css);
        callback();
        done();
      })
    );
  });

});

describe('styleguide_at_rules.css', function() {

  assertions.atRules.register();

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideApplyStylesStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'styleguide_at_rules.css');
        assertions.atRules.set(css);
        callback();
        done();
      })
    );
  });

});

describe('sass/_styleguide_custom_variables.scss', function() {

  assertions.styleguideCustomVariables.register();

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideGenerateStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'sass/_styleguide_custom_variables.scss');
        assertions.styleguideCustomVariables.set(css);
        callback();
        done();
      })
    );
  });

});

describe('overview.html', function() {

  assertions.overviewHtml.register();

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideGenerateStream().pipe(
      through.obj(collector(files), function(callback) {
        var overviewHtml = findFile(files, 'overview.html');
        assertions.overviewHtml.set(overviewHtml);
        callback();
        done();
      })
    );
  });

});

describe('styleguide.css', function() {

  assertions.styleguideCss.register();

  before(function(done) {
    var files = [];
    styleguideApplyStylesStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'styleguide.css');
        assertions.styleguideCss.set(css);
        callback();
        done();
      })
    );
  });

});

describe('app.css', function() {
  assertions.appCss.register();

  before(function(done) {
    var files = [];
    styleguideGenerateStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'app.css');
        assertions.appCss.set(css);
        callback();
        done();
      })
    );
  });
});

describe('styleguide.json for SCSS project', function() {

  var source = 'test/projects/scss-project/source/**/*.scss',
      variablesFile = 'test/projects/scss-project/source/styles/_styleguide_variables.scss';

  assertions.styleguideJson.register();

  before(function(done) {
    var json = {};
    createStyleGuideJson(source, variablesFile, json, function() {
      assertions.styleguideJson.setJson(json.jsonData);
      assertions.styleguideJson.setVariablesFile(variablesFile);
      done();
    });
  });

});

describe('styleguide.json for LESS project', function() {

  var source = 'test/projects/less-project/source/**/*.less',
      variablesFile = 'test/projects/less-project/source/styles/_styleguide_variables.less';

  assertions.styleguideJson.register();

  before(function(done) {
    var json = {};
    createStyleGuideJson(source, variablesFile, json, function() {
      assertions.styleguideJson.setJson(json.jsonData);
      assertions.styleguideJson.setVariablesFile(variablesFile);
      done();
    });
  });

});

function createStyleGuideJson(source, variablesFile, _this, done) {
  var files = [],
    config = defaultConfig;

  config.styleVariables = variablesFile;
  styleguideGenerateStream(source, config).pipe(
    through.obj(collector(files), function(callback) {
      _this.jsonData = JSON.parse(findFile(files, 'styleguide.json').contents);
      callback();
      done();
    })
  );
}
<commit_msg>Fixed tests<commit_after>var gulp = require('gulp'),
    chai = require('chai'),
    expect = chai.expect,
    through = require('through2'),
    styleguide = require('requirefrom')('lib')('styleguide'),
    assertions = require('./assertions'),
    defaultSource = 'test/projects/scss-project/source/**/*.scss',
    defaultConfig = require('./test-config');

chai.config.includeStack = true;

function styleguideGenerateStream(source, config) {
  return gulp.src(source || defaultSource)
    .pipe(styleguide.generate(config || defaultConfig));
}

function styleguideApplyStylesStream() {
  return gulp.src('test/projects/shared-css/*')
    .pipe(styleguide.applyStyles());
}

// This collector collects all files from the stream to the array passed as parameter
function collector(collection) {
  return function(file, enc, cb) {
    if (!file.path) {
      return;
    }
    collection.push(file);
    cb();
  };
}

function findFile(files, name) {
  for (var i = files.length - 1; i >= 0; i--) {
    if (files[i].relative === name) {
      return files[i];
    }
  }
}

describe('index.html', function() {

  assertions.indexHtml.register();

  var indexHtml;

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideGenerateStream().pipe(
      through.obj(collector(files), function(callback) {
        indexHtml = findFile(files, 'index.html');
        assertions.indexHtml.set(indexHtml);
        callback();
        done();
      })
    );
  });

  it('should contain filesConfig passed as parameter and in correct format', function() {
    expect(indexHtml.contents.toString()).to.contain('var filesConfig = []');
  });

  it('should contain serialized styleguide configuration', function() {
    expect(indexHtml.contents.toString()).to.contain('var _styleguideConfig = {"title":"Test Styleguide"');
  });

  it('should not add extraHead to serialized configuration', function() {
    expect(indexHtml.contents.toString()).not.to.contain('"extreHead":');
  });
});

describe('styleguide_pseudo_styles.css', function() {

  assertions.pseudoStyles.register();

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideApplyStylesStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'styleguide_pseudo_styles.css');
        assertions.pseudoStyles.set(css);
        callback();
        done();
      })
    );
  });

});

describe('styleguide_at_rules.css', function() {

  assertions.atRules.register();

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideApplyStylesStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'styleguide_at_rules.css');
        assertions.atRules.set(css);
        callback();
        done();
      })
    );
  });

});

describe('sass/_styleguide_custom_variables.scss', function() {

  assertions.styleguideCustomVariables.register();

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideGenerateStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'sass/_styleguide_custom_variables.scss');
        assertions.styleguideCustomVariables.set(css);
        callback();
        done();
      })
    );
  });

});

describe('overview.html', function() {

  assertions.overviewHtml.register();

  before(function(done) {
    this.timeout(5000);
    var files = [];
    styleguideGenerateStream().pipe(
      through.obj(collector(files), function(callback) {
        var overviewHtml = findFile(files, 'overview.html');
        assertions.overviewHtml.set(overviewHtml);
        callback();
        done();
      })
    );
  });

});

describe('styleguide.css', function() {

  assertions.styleguideCss.register();

  before(function(done) {
    var files = [];
    styleguideApplyStylesStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'styleguide.css');
        assertions.styleguideCss.set(css);
        callback();
        done();
      })
    );
  });

});

describe('styleguide-app.css', function() {
  assertions.appCss.register();

  before(function(done) {
    var files = [];
    styleguideGenerateStream().pipe(
      through.obj(collector(files), function(callback) {
        var css = findFile(files, 'styleguide-app.css');
        assertions.appCss.set(css);
        callback();
        done();
      })
    );
  });
});

describe('styleguide.json for SCSS project', function() {

  var source = 'test/projects/scss-project/source/**/*.scss',
      variablesFile = 'test/projects/scss-project/source/styles/_styleguide_variables.scss';

  assertions.styleguideJson.register();

  before(function(done) {
    var json = {};
    createStyleGuideJson(source, variablesFile, json, function() {
      assertions.styleguideJson.setJson(json.jsonData);
      assertions.styleguideJson.setVariablesFile(variablesFile);
      done();
    });
  });

});

describe('styleguide.json for LESS project', function() {

  var source = 'test/projects/less-project/source/**/*.less',
      variablesFile = 'test/projects/less-project/source/styles/_styleguide_variables.less';

  assertions.styleguideJson.register();

  before(function(done) {
    var json = {};
    createStyleGuideJson(source, variablesFile, json, function() {
      assertions.styleguideJson.setJson(json.jsonData);
      assertions.styleguideJson.setVariablesFile(variablesFile);
      done();
    });
  });

});

function createStyleGuideJson(source, variablesFile, _this, done) {
  var files = [],
    config = defaultConfig;

  config.styleVariables = variablesFile;
  styleguideGenerateStream(source, config).pipe(
    through.obj(collector(files), function(callback) {
      _this.jsonData = JSON.parse(findFile(files, 'styleguide.json').contents);
      callback();
      done();
    })
  );
}
<|endoftext|>