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

define("extensions/charting", function () {

  // For each chart type, we have a constructor name, and optionally a package to load
  // ('script').
  var chartMap = {
    annotation: {name: 'AnnotationChart', script: 'annotationchart'},
    area: {name: 'AreaChart'},
    columns: {name: 'ColumnChart'},
    bars: {name: 'BarChart'},
    bubbles: {name: 'BubbleChart'},
    calendar: {name: 'Calendar', script: 'calendar'},
    candlestick: {name: 'CandlestickChart'},
    combo: {name: 'ComboChart'},
    gauge: {name: 'Gauge', script: 'gauge'},
    geo: {name: 'GeoChart', script: 'geochart'},
    histogram: {name: 'Histogram'},
    line: {name: 'LineChart'},
    map: {name: 'Map', script: 'map'},
    org: {name: 'OrgChart', script: 'orgchart'},
    paged_table: {name: 'Table', script: 'table'},
    pie: {name: 'PieChart'},
    sankey: {name: 'Sankey', script: 'sankey'},
    scatter: {name: 'ScatterChart'},
    stepped_area: {name: 'SteppedAreaChart'},
    table: {name: 'Table', script: 'table'},
    timeline: {name: 'Timeline', script: 'timeline'},
    treemap: {name: 'TreeMap', script: 'treemap'}
  };

  function convertListToDataTable(list) {
    if (!list || !list.length) {
      return { cols: [], rows: [] };
    }

    var firstItem = list[0];
    var names = Object.keys(firstItem);

    var columns = names.map(function(name) {
      return { id: name, label: name, type: typeof firstItem[name] }
    });

    var rows = list.map(function(item) {
      var cells = names.map(function(name) {
        return { v: item[name] };
      });
      return { c: cells };
    });

    return { cols: columns, rows: rows };
  }

  // Convert any string fields that are date type to JS Dates.
  function convertDates(data) {
    for (var i = 0; i < data.cols.length; i++) {
      if (data.cols[i].type == 'datetime') {
        var rows = data.rows;
        for (var j = 0; j < rows.length; j++) {
          rows[j].c[i].v = new Date(rows[j].c[i].v);
        }
      }
    }
  }

  function onError(visualization, dom, error) {
    var message = 'The data could not be retrieved.' + error.toString();
    visualization.errors.addError(dom, 'Unable to render the chart',
        message, {showInTooltip: false});
  }

  // Adjust any necessary options for the paged table and update the chart.
  function chartPage(model, startRow, count) {
    // Adjust the options that affect the page display.
    var options = model.options;
    if (options.showRowNumber == undefined) {
      options.showRowNumber = true;
    }
    options.page = 'event';
    options.firstRowNumber = startRow + 1;
    if (model.totalRows < 0 || startRow + count < model.totalRows) {
      // We either don't know where the end is or we're not at the end, so we can have 'next'.
      options.pagingButtonsConfiguration = startRow > 0 ? 'both' : 'next';
    } else { // no next
      // Reduce count if necessary on the last page.
      count = model.totalRows - startRow;
      options.pagingButtonsConfiguration = startRow > 0 ? 'prev' : 'none';
      if (startRow == 0) {
        // No next or prev so disable page events.
        options.page = 'disable';
      }
    }
    if (options.page != 'disable') {
      // We can't sort if we are paginating.
      options.sort = 'disable';
    }
    model.firstRow = startRow;
    var dt = new model.visualization.DataTable({
      'cols': model.data.cols,
      'rows': model.data.rows.slice(startRow - model.dataOffset,
          startRow - model.dataOffset + count)
    });
    model.chart.draw(dt, model.options);
  }

  // Check if a row is in the table. Note that if we don't know the total number of rows
  // we assume the row is in range as long as it is non-negative.
  function isRowInRange(row, totalRows) {
    return row >= 0 && (totalRows < 0 || row < totalRows);
  }

  // Calculate the number of rows we want to display.
  function getPageRowCount(model, startRow) {
    var count = model.options.pageSize;
    if (model.totalRows >= 0) { // We know how many rows we have.
      var rowsLeft = model.totalRows - startRow;
      if (count > rowsLeft) {
        count = rowsLeft;
      }
    }
    return count;
  }

  // Check if a row range is in the cached data.
  function isCached(model, startRow, count) {
    if (count == 0) {
      return true;
    }
    return startRow >= model.dataOffset &&
        (startRow + count) <= (model.dataOffset + model.data.rows.length);
  }

  // Function to get a range of data and update chart with one page of data.
  function getPagedData(model, startRow) {

    // Calculate the number of rows we want to display.
    var pageCount = getPageRowCount(model, startRow);

    if (isCached(model, startRow, pageCount)) {
      chartPage(model, startRow, pageCount);
    } else {

      // Fetch data. We try fetch up to 20 pages before and 20 pages after the page
      // we are viewing.
      // TODO(gram): At some point we should optimize this more. If the user paginates
      // sequentially - which is all they can do right now with gViz - then we will
      // typically be requesting a new dataset with ~20 pages overlap with the previous
      // dataset. We should recycle the rows we have and ask just for the ones we don't.

      var first = Math.max(startRow - 20 * model.options.pageSize, 0);
      var last = startRow + pageCount + 20 * model.options.pageSize;
      if (model.totalRows >= 0 && last >= model.totalRows) { // Can't go past the end of the data
        last = model.totalRows - 1;
      }
      var fetchCount = last - first + 1;
      var code = model.fetchCode + ' ' + first + ' ' + fetchCount;

      datalab.session.execute(code, function (error, newData) {
        if (error) {
          onError(model.visualization, model.dom, error);
        } else {
          convertDates(newData.data);
          model.data = newData.data;
          model.dataOffset = first;
          // If we didn't know the data length before we do now if we got less than we asked for.
          if (model.totalRows < 0) {
            var len = model.data.rows.length;
            if (len != fetchCount) {
              model.totalRows = first + len;
            }
          }
          chartPage(model, startRow, pageCount);
        }
      });
    }
  }

  // Handle page forward/back events. Page will only be 0 or 1.
  function handlePageEvent(model, page) {
    var offset = (page == 0) ? -1 : 1;
    var newFirstRow = model.firstRow + offset * model.options.pageSize;
    if (isRowInRange(newFirstRow, model.totalRows)) {
      getPagedData(model, newFirstRow);
    }
  }

  // The main render method, called from Python-generated code. dom is the DOM element
  // for the chart, model is a set of parameters from Python, and options is a JSON
  // set of options provided by the user in the cell magic body, which takes precedence over
  // model. An initial set of data can be passed in as a final optional parameter.
  function render(dom, model, options, data) {
    if (model.chartStyle == 'paged_table' && document._in_nbconverted) {
       model.chartStyle = 'table';
       var p = document.createElement("div");
       p.innerHTML = '
(Truncated to first page of results)';
       dom.parentNode.insertBefore(p, dom.nextSibling);
    }
    var chartInfo = chartMap[model.chartStyle];
    var chartScript = chartInfo.script || 'corechart';
    dom.innerHTML = '';

    if (!data.cols && !data.rows) {
      data = convertListToDataTable(data);
    }
    convertDates(data);

    require(['visualization!' + chartScript], function (visualization) {
      var chartType = visualization[chartInfo.name];
      var chart = new chartType(dom);

      options = options || {};
      if ((model.chartStyle == 'paged_table') || (model.chartStyle == 'table')) {
        // Cleanup table rendering
        options.cssClassNames = {
          tableRow: 'gchart-table-row',
          headerRow: 'gchart-table-headerrow',
          oddTableRow: 'gchart-table-oddrow',
          selectedTableRow: 'gchart-table-selectedrow',
          hoverTableRow: 'gchart-table-hoverrow',
          tableCell: 'gchart-table-cell',
          headerCell: 'gchart-table-headercell',
          rowNumberCell: 'gchart-table-rownumcell'
        };
      }

      if (model.chartStyle != 'paged_table') {
        chart.draw(new visualization.DataTable(data), options);
      }
      else {
        if (options.pageSize == undefined) {
          options.pageSize = model.rowsPerPage || 25;
        }
        model.dom = dom;
        model.chart = chart;
        model.visualization = visualization;
        model.fetchCode = '%_get_chart_data ' + model.dataName + ' ' + (model.fields || '*');
        model.options = options;
        model.totalRows = model.totalRows || -1; // Total rows in all (server-side) data.
        model.dataOffset = 0; // Where the cached data[] array starts from.
        model.firstRow = 0;  // Index of first row being displayed in page.

        model.data = data;

        visualization.events.addListener(chart, 'page', function(e) {
          handlePageEvent(model, e.page);
        });

        getPagedData(model, 0);
      }
    });
  }

  return {
    render: render
  };
});
<commit_msg>Charts now add an image/png display output to notebook.<commit_after>/*
 * Copyright 2015 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

define("extensions/charting", function () {

  // For each chart type, we have a constructor name, and optionally a package to load
  // ('script').
  var chartMap = {
    annotation: {name: 'AnnotationChart', script: 'annotationchart'},
    area: {name: 'AreaChart'},
    columns: {name: 'ColumnChart'},
    bars: {name: 'BarChart'},
    bubbles: {name: 'BubbleChart'},
    calendar: {name: 'Calendar', script: 'calendar'},
    candlestick: {name: 'CandlestickChart'},
    combo: {name: 'ComboChart'},
    gauge: {name: 'Gauge', script: 'gauge'},
    geo: {name: 'GeoChart', script: 'geochart'},
    histogram: {name: 'Histogram'},
    line: {name: 'LineChart'},
    map: {name: 'Map', script: 'map'},
    org: {name: 'OrgChart', script: 'orgchart'},
    paged_table: {name: 'Table', script: 'table'},
    pie: {name: 'PieChart'},
    sankey: {name: 'Sankey', script: 'sankey'},
    scatter: {name: 'ScatterChart'},
    stepped_area: {name: 'SteppedAreaChart'},
    table: {name: 'Table', script: 'table'},
    timeline: {name: 'Timeline', script: 'timeline'},
    treemap: {name: 'TreeMap', script: 'treemap'}
  };

  function convertListToDataTable(list) {
    if (!list || !list.length) {
      return { cols: [], rows: [] };
    }

    var firstItem = list[0];
    var names = Object.keys(firstItem);

    var columns = names.map(function(name) {
      return { id: name, label: name, type: typeof firstItem[name] }
    });

    var rows = list.map(function(item) {
      var cells = names.map(function(name) {
        return { v: item[name] };
      });
      return { c: cells };
    });

    return { cols: columns, rows: rows };
  }

  // Convert any string fields that are date type to JS Dates.
  function convertDates(data) {
    for (var i = 0; i < data.cols.length; i++) {
      if (data.cols[i].type == 'datetime') {
        var rows = data.rows;
        for (var j = 0; j < rows.length; j++) {
          rows[j].c[i].v = new Date(rows[j].c[i].v);
        }
      }
    }
  }

  function onError(visualization, dom, error) {
    var message = 'The data could not be retrieved.' + error.toString();
    visualization.errors.addError(dom, 'Unable to render the chart',
        message, {showInTooltip: false});
  }

  // Adjust any necessary options for the paged table and update the chart.
  function chartPage(model, startRow, count) {
    // Adjust the options that affect the page display.
    var options = model.options;
    if (options.showRowNumber == undefined) {
      options.showRowNumber = true;
    }
    options.page = 'event';
    options.firstRowNumber = startRow + 1;
    if (model.totalRows < 0 || startRow + count < model.totalRows) {
      // We either don't know where the end is or we're not at the end, so we can have 'next'.
      options.pagingButtonsConfiguration = startRow > 0 ? 'both' : 'next';
    } else { // no next
      // Reduce count if necessary on the last page.
      count = model.totalRows - startRow;
      options.pagingButtonsConfiguration = startRow > 0 ? 'prev' : 'none';
      if (startRow == 0) {
        // No next or prev so disable page events.
        options.page = 'disable';
      }
    }
    if (options.page != 'disable') {
      // We can't sort if we are paginating.
      options.sort = 'disable';
    }
    model.firstRow = startRow;
    var dt = new model.visualization.DataTable({
      'cols': model.data.cols,
      'rows': model.data.rows.slice(startRow - model.dataOffset,
          startRow - model.dataOffset + count)
    });
    model.chart.draw(dt, model.options);
  }

  // Check if a row is in the table. Note that if we don't know the total number of rows
  // we assume the row is in range as long as it is non-negative.
  function isRowInRange(row, totalRows) {
    return row >= 0 && (totalRows < 0 || row < totalRows);
  }

  // Calculate the number of rows we want to display.
  function getPageRowCount(model, startRow) {
    var count = model.options.pageSize;
    if (model.totalRows >= 0) { // We know how many rows we have.
      var rowsLeft = model.totalRows - startRow;
      if (count > rowsLeft) {
        count = rowsLeft;
      }
    }
    return count;
  }

  // Check if a row range is in the cached data.
  function isCached(model, startRow, count) {
    if (count == 0) {
      return true;
    }
    return startRow >= model.dataOffset &&
        (startRow + count) <= (model.dataOffset + model.data.rows.length);
  }

  // Function to get a range of data and update chart with one page of data.
  function getPagedData(model, startRow) {

    // Calculate the number of rows we want to display.
    var pageCount = getPageRowCount(model, startRow);

    if (isCached(model, startRow, pageCount)) {
      chartPage(model, startRow, pageCount);
    } else {

      // Fetch data. We try fetch up to 20 pages before and 20 pages after the page
      // we are viewing.
      // TODO(gram): At some point we should optimize this more. If the user paginates
      // sequentially - which is all they can do right now with gViz - then we will
      // typically be requesting a new dataset with ~20 pages overlap with the previous
      // dataset. We should recycle the rows we have and ask just for the ones we don't.

      var first = Math.max(startRow - 20 * model.options.pageSize, 0);
      var last = startRow + pageCount + 20 * model.options.pageSize;
      if (model.totalRows >= 0 && last >= model.totalRows) { // Can't go past the end of the data
        last = model.totalRows - 1;
      }
      var fetchCount = last - first + 1;
      var code = model.fetchCode + ' ' + first + ' ' + fetchCount;

      datalab.session.execute(code, function (error, newData) {
        if (error) {
          onError(model.visualization, model.dom, error);
        } else {
          convertDates(newData.data);
          model.data = newData.data;
          model.dataOffset = first;
          // If we didn't know the data length before we do now if we got less than we asked for.
          if (model.totalRows < 0) {
            var len = model.data.rows.length;
            if (len != fetchCount) {
              model.totalRows = first + len;
            }
          }
          chartPage(model, startRow, pageCount);
        }
      });
    }
  }

  // Handle page forward/back events. Page will only be 0 or 1.
  function handlePageEvent(model, page) {
    var offset = (page == 0) ? -1 : 1;
    var newFirstRow = model.firstRow + offset * model.options.pageSize;
    if (isRowInRange(newFirstRow, model.totalRows)) {
      getPagedData(model, newFirstRow);
    }
  }

  function getCell(model) {
    // Get the associated cell
    var cells = IPython.notebook.get_cells();
    for (var cellindex in cells) {
      var cell = cells[cellindex];
      if (cell.element && cell.element.length) {
        var element = cell.element[0];
        var chartDivs = element.getElementsByClassName('bqgc');
        if (chartDivs && chartDivs.length && chartDivs[0].id == model.dom.id) {
          return cell;
        }
      }
    }
    return undefined;
  }

  function removeStaticChart(model) {
    var cell = getCell(model);
    if (cell) {
      var pngDivs = cell.element[0].getElementsByClassName('output_png');
      if (pngDivs) {
        for (var i = 0; i < pngDivs.length; i++) {
          pngDivs[i].innerHTML = '';
        }
      }
      var cell_outputs = cell.output_area.outputs;
      for (var outputindex in cell_outputs) {
        var output = cell_outputs[outputindex];
        if (output.output_type == 'display_data') {
          cell.output_area.outputs.splice(outputindex, 1);
          return;
        }
      }
    }
  }

  function addStaticChart(model, chart) {
    var cell;
    if (chart.getImageURI == undefined || (cell = getCell(model)) == undefined) {
      return;
    }
    var static_chart = chart.getImageURI();
    var img = static_chart.substr(static_chart.indexOf(',') + 1);  // strip leading base64 etc.
    var static_output = {
      metadata: {},
      data: {
        'image/png': img
      },
      output_type: 'display_data'
    };
    cell.output_area.outputs.push(static_output);
  }

  // The main render method, called from Python-generated code. dom is the DOM element
  // for the chart, model is a set of parameters from Python, and options is a JSON
  // set of options provided by the user in the cell magic body, which takes precedence over
  // model. An initial set of data can be passed in as a final optional parameter.
  function render(dom, model, options, data) {
    if (model.chartStyle == 'paged_table' && document._in_nbconverted) {
       model.chartStyle = 'table';
       var p = document.createElement("div");
       p.innerHTML = '
(Truncated to first page of results)';
       dom.parentNode.insertBefore(p, dom.nextSibling);
    }
    var chartInfo = chartMap[model.chartStyle];
    var chartScript = chartInfo.script || 'corechart';
    dom.innerHTML = '';

    if (!data.cols && !data.rows) {
      data = convertListToDataTable(data);
    }
    convertDates(data);
    model.dom = dom;

    removeStaticChart(model);  // Remove any existing chart PNG.
    require(['visualization!' + chartScript], function (visualization) {
      var chartType = visualization[chartInfo.name];
      var chart = new chartType(dom);

      // Generate and add a new static chart once chart is ready.
      google.visualization.events.addListener(chart, 'ready', function () {
        addStaticChart(model, chart);
      });

      options = options || {};
      if ((model.chartStyle == 'paged_table') || (model.chartStyle == 'table')) {
        // Cleanup table rendering
        options.cssClassNames = {
          tableRow: 'gchart-table-row',
          headerRow: 'gchart-table-headerrow',
          oddTableRow: 'gchart-table-oddrow',
          selectedTableRow: 'gchart-table-selectedrow',
          hoverTableRow: 'gchart-table-hoverrow',
          tableCell: 'gchart-table-cell',
          headerCell: 'gchart-table-headercell',
          rowNumberCell: 'gchart-table-rownumcell'
        };
      }

      if (model.chartStyle != 'paged_table') {
        chart.draw(new visualization.DataTable(data), options);
      }
      else {
        if (options.pageSize == undefined) {
          options.pageSize = model.rowsPerPage || 25;
        }
        model.chart = chart;
        model.visualization = visualization;
        model.fetchCode = '%_get_chart_data ' + model.dataName + ' ' + (model.fields || '*');
        model.options = options;
        model.totalRows = model.totalRows || -1; // Total rows in all (server-side) data.
        model.dataOffset = 0; // Where the cached data[] array starts from.
        model.firstRow = 0;  // Index of first row being displayed in page.

        model.data = data;

        visualization.events.addListener(chart, 'page', function(e) {
          handlePageEvent(model, e.page);
        });

        getPagedData(model, 0);
      }
    });
  }

  return {
    render: render
  };
});
<|endoftext|>


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

/* global mongo */
mongo.config = (function () {
  var mwsHost = window.MWS_HOST || '';
  var KEYCODES = {
    enter: 13,
    left: 37,
    up: 38,
    right: 39,
    down: 40
  };

  return {
    keycodes: KEYCODES,
    keepAliveTime: 30000,
    rootElementSelector: '.mongo-web-shell',
    scriptName: 'mongoWebShell',
    shellBatchSize: 20,
    shellHistoryKey: 'mongo.history',
    shellHistorySize: 500,
    mwsHost: mwsHost,
    baseUrl: mwsHost + '/mws/'
  };
}());
<commit_msg>don't check in the change<commit_after>/*    Copyright 2013 10gen Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/* global mongo */
mongo.config = (function () {
  var mwsHost = window.MWS_HOST || '';
  var KEYCODES = {
    enter: 13,
    left: 37,
    up: 38,
    right: 39,
    down: 40
  };

  return {
    keycodes: KEYCODES,
    keepAliveTime: 30000,
    rootElementSelector: '.mongo-web-shell',
    scriptName: 'mongoWebShell',
    shellBatchSize: 20,
    shellHistoryKey: 'mongo.history',
    shellHistorySize: 500,
    mwsHost: mwsHost,
    baseUrl: mwsHost + '/server/mws/'
  };
}());
<|endoftext|>


<commit_before>var _ = require("underscore"),
    Marionette = require("backbone.marionette"),
    NsecScoreboard = require("../nsecScoreboard"),
    ModalView = require("./modal"),
    template = require("../../dist/templates").team;

var TeamView = Marionette.ItemView.extend({
    template: template,

    ui: {
        nameField: "#team-name-input",
        countryField: "#team-country-input",
        websiteField: "#team-website-input",
        submitBtn: "#submit-btn"
    },

    initialize: function(options) {
        _.bindAll(this, "handleGetSuccess", "handleGetError");
        xmlrpc({
	    url: AskgodUrl,
	    methodName: 'teams_getdetails',
	    success: this.handleGetSuccess,
	    error: this.handleGetError
	});
    },

    onRender: function() {
        this.delegateEvents({
            "click @ui.submitBtn": this.handleSubmit
        });

        if(this.team) {
            if(!this.team.name) {
                this.ui.nameField.prop("disabled", false);
                this.ui.submitBtn.prop("disabled", false);
            } else {
                this.ui.nameField.val(this.team.name);
            }

            if(!this.team.country) {
                this.ui.countryField.prop("disabled", false);
                this.ui.submitBtn.prop("disabled", false);
            } else {
                this.ui.countryField.val(this.team.country);
            }

            if(!this.team.website) {
                this.ui.websiteField.prop("disabled", false);
                this.ui.submitBtn.prop("disabled", false);
            } else {
                this.ui.websiteField.val(this.team.website);
            }
        }
    },

    handleSubmit: function() {
        params = {};

        if(!this.team.name) {
            this.team.name = this.ui.nameField.val();
            params["name"] = this.team.name;
        }

        if(!this.team.country) {
            this.team.country = this.ui.countryField.val();
            params["country"] = this.team.country;
        }

        if(!this.team.website) {
            this.team.website = this.ui.websiteField.val();
            params["website"] = this.ui.websiteField.val();
        }

        xmlrpc({
	    url: AskgodUrl,
	    methodName: 'teams_setdetails',
            params: [params],
	    success: this.handleSetSuccess,
	    error: this.handleSetError
	});

        this.render();
    },

    handleGetSuccess: function(response, status, jqXHR) {
        this.team = response[0];
        this.render();
    },

    handleGetError: function(jqXHR, status, error) {
	var msg = error.msg;
        msg = msg.slice(msg.indexOf(":") + 1);
        console.warn(msg);
    },

    handleSetSuccess: function(response, status, jqXHR) {
        var options = {
            title: "Team Info Updated",
            message: "Team information set. Welcome to NSEC 2015"
        }

        NsecScoreboard.modalContainer.show(new ModalView(options));
    },

    handleSetError: function(jqXHR, status, error) {
        var options = {
            title: "Error",
            message: "Team information already set."
        }

        NsecScoreboard.modalContainer.show(new ModalView(options));
    }
});

module.exports = TeamView;
<commit_msg>Update year in team view<commit_after>var _ = require("underscore"),
    Marionette = require("backbone.marionette"),
    NsecScoreboard = require("../nsecScoreboard"),
    ModalView = require("./modal"),
    template = require("../../dist/templates").team;

var TeamView = Marionette.ItemView.extend({
    template: template,

    ui: {
        nameField: "#team-name-input",
        countryField: "#team-country-input",
        websiteField: "#team-website-input",
        submitBtn: "#submit-btn"
    },

    initialize: function(options) {
        _.bindAll(this, "handleGetSuccess", "handleGetError");
        xmlrpc({
	    url: AskgodUrl,
	    methodName: 'teams_getdetails',
	    success: this.handleGetSuccess,
	    error: this.handleGetError
	});
    },

    onRender: function() {
        this.delegateEvents({
            "click @ui.submitBtn": this.handleSubmit
        });

        if(this.team) {
            if(!this.team.name) {
                this.ui.nameField.prop("disabled", false);
                this.ui.submitBtn.prop("disabled", false);
            } else {
                this.ui.nameField.val(this.team.name);
            }

            if(!this.team.country) {
                this.ui.countryField.prop("disabled", false);
                this.ui.submitBtn.prop("disabled", false);
            } else {
                this.ui.countryField.val(this.team.country);
            }

            if(!this.team.website) {
                this.ui.websiteField.prop("disabled", false);
                this.ui.submitBtn.prop("disabled", false);
            } else {
                this.ui.websiteField.val(this.team.website);
            }
        }
    },

    handleSubmit: function() {
        params = {};

        if(!this.team.name) {
            this.team.name = this.ui.nameField.val();
            params["name"] = this.team.name;
        }

        if(!this.team.country) {
            this.team.country = this.ui.countryField.val();
            params["country"] = this.team.country;
        }

        if(!this.team.website) {
            this.team.website = this.ui.websiteField.val();
            params["website"] = this.ui.websiteField.val();
        }

        xmlrpc({
	    url: AskgodUrl,
	    methodName: 'teams_setdetails',
            params: [params],
	    success: this.handleSetSuccess,
	    error: this.handleSetError
	});

        this.render();
    },

    handleGetSuccess: function(response, status, jqXHR) {
        this.team = response[0];
        this.render();
    },

    handleGetError: function(jqXHR, status, error) {
	var msg = error.msg;
        msg = msg.slice(msg.indexOf(":") + 1);
        console.warn(msg);
    },

    handleSetSuccess: function(response, status, jqXHR) {
        var options = {
            title: "Team Info Updated",
            message: "Team information set. Welcome to NSEC 2016"
        }

        NsecScoreboard.modalContainer.show(new ModalView(options));
    },

    handleSetError: function(jqXHR, status, error) {
        var options = {
            title: "Error",
            message: "Team information already set."
        }

        NsecScoreboard.modalContainer.show(new ModalView(options));
    }
});

module.exports = TeamView;
<|endoftext|>


<commit_before>"use strict";
import React, { Component, PropTypes } from 'react';
import Section from './Section';
import VolumeIcon from '../icons/Volume';

function pad(num, size) {
  let s = num + "";
  while (s.length < size) s = "0" + s;
  return s;
}

function friendlyDuration (duration) {
  let remaining = duration;
  let result = '';
  if (remaining > 3600) {
    const hours = Math.floor(remaining / 3600);
    result += `${hours}:`;
    remaining -= hours * 3600;
  }
  if (remaining > 60) {
    const minutes = Math.floor(remaining / 60);
    result += `${pad(minutes, 2)}:`;
    remaining -= minutes * 60;
  }
  if (remaining > 0) {
    const seconds = Math.floor(remaining);
    result += `${pad(seconds, 2)}`;
  }
  return result;
}

export default class Audio extends Component {

  constructor () {
    super();
    this._onTimeUpdate = this._onTimeUpdate.bind(this);
    this._onEnded = this._onEnded.bind(this);
    this._onResize = this._onResize.bind(this);
    this._layout = this._layout.bind(this);
    this._onPlay = this._onPlay.bind(this);
    this._onPause = this._onPause.bind(this);
    this._onSeek = this._onSeek.bind(this);
    this._onVolume = this._onVolume.bind(this);
    this.state = { playing: false, volume: 0.7, start: 0, end: 0, at: 0 };
  }

  componentDidMount () {
    const audio = this.refs.audio;
    audio.volume = this.state.volume;
    audio.addEventListener('timeupdate', this._onTimeUpdate);
    audio.addEventListener('ended', this._onEnded);
    window.addEventListener('resize', this._onResize);
    this._layout();
  }

  componentWillUnmount () {
    const audio = this.refs.audio;
    audio.removeEventListener('timeupdate', this._onTimeUpdate);
    audio.removeEventListener('ended', this._onEnded);
    window.removeEventListener('resize', this._onResize);
  }

  _onTimeUpdate (event) {
    const audio = this.refs.audio;
    this.setState({ at: audio.currentTime });
  }

  _onEnded (event) {
    this.setState({ playing: false });
  }

  _onResize (event) {
    clearTimeout(this._resizeTimer);
    this._resizeTimer = setTimeout(this._layout, 10);
  }

  _layout () {
    // Remove?
  }

  _onPlay () {
    const audio = this.refs.audio;
    audio.play();
    this.setState({ playing: true,
      start: audio.seekable.start(0), end: audio.seekable.end(0) });
  }

  _onPause () {
    const audio = this.refs.audio;
    audio.pause();
    this.setState({ playing: false });
  }

  _onSeek (event) {
    const audio = this.refs.audio;
    const value = event.target.value;
    audio.currentTime = value;
    this.setState({ at: value });
  }

  _onVolume (event) {
    const audio = this.refs.audio;
    const value = event.target.value;
    audio.volume = value;
    this.setState({ volume: value });
  }

  render () {
    const { file, color, full, plain } = this.props;
    const { playing, volume, start, end, at } = this.state;
    const path = `/api/files/${file._id}/${file.name}`;
    const onClick = playing ? this._onPause : this._onPlay;

    let playControl, positionControl, volumeControl;
    if (playing) {
      playControl = (
        <button className="button audio__control" type="button"
          onClick={onClick}>Pause</button>
      );
      positionControl = (

          <input className="audio__position" type="range" min={start} max={end}
            value={at} onChange={this._onSeek} />
          {friendlyDuration(end - at)}

      );
      volumeControl = (

          <VolumeIcon />
          <input className="audio__volume" type="range" min={0} max={1}
            step={0.1} value={volume} onChange={this._onVolume} />

      );
    } else {
      playControl = (
        <button className="button audio__control" type="button"
          onClick={onClick}>Listen</button>
      );
    }

    return (

          {playControl}
          {positionControl}
          {volumeControl}
          <audio ref="audio" preload="metadata">
            <source src={path} type={file.type} />
            No audio with this browser
          </audio>

    );
  }
};

Audio.propTypes = {
  full: PropTypes.bool,
  file: PropTypes.shape({
    _id: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    type: PropTypes.string.isRequired
  }),
  ...Section.propTypes
};
<commit_msg>Code cleanup in Audio.<commit_after>"use strict";
import React, { Component, PropTypes } from 'react';
import Section from './Section';
import VolumeIcon from '../icons/Volume';

function pad(num, size) {
  let s = num + "";
  while (s.length < size) s = "0" + s;
  return s;
}

function friendlyDuration (duration) {
  let remaining = duration;
  let result = '';
  if (remaining > 3600) {
    const hours = Math.floor(remaining / 3600);
    result += `${hours}:`;
    remaining -= hours * 3600;
  }
  if (remaining > 60) {
    const minutes = Math.floor(remaining / 60);
    result += `${pad(minutes, 2)}:`;
    remaining -= minutes * 60;
  }
  if (remaining > 0) {
    const seconds = Math.floor(remaining);
    result += `${pad(seconds, 2)}`;
  }
  return result;
}

export default class Audio extends Component {

  constructor () {
    super();
    this._onTimeUpdate = this._onTimeUpdate.bind(this);
    this._onEnded = this._onEnded.bind(this);
    this._onResize = this._onResize.bind(this);
    this._layout = this._layout.bind(this);
    this._onPlay = this._onPlay.bind(this);
    this._onPause = this._onPause.bind(this);
    this._onSeek = this._onSeek.bind(this);
    this._onVolume = this._onVolume.bind(this);
    this.state = { playing: false, volume: 0.7, start: 0, end: 0, at: 0 };
  }

  componentDidMount () {
    const audio = this.refs.audio;
    audio.volume = this.state.volume;
    audio.addEventListener('timeupdate', this._onTimeUpdate);
    audio.addEventListener('ended', this._onEnded);
    window.addEventListener('resize', this._onResize);
    this._layout();
  }

  componentWillUnmount () {
    const audio = this.refs.audio;
    audio.removeEventListener('timeupdate', this._onTimeUpdate);
    audio.removeEventListener('ended', this._onEnded);
    window.removeEventListener('resize', this._onResize);
  }

  _onTimeUpdate (event) {
    const audio = this.refs.audio;
    this.setState({ at: audio.currentTime });
  }

  _onEnded (event) {
    this.setState({ playing: false });
  }

  _onResize (event) {
    clearTimeout(this._resizeTimer);
    this._resizeTimer = setTimeout(this._layout, 10);
  }

  _layout () {
    // Remove?
  }

  _onPlay () {
    const audio = this.refs.audio;
    audio.play();
    this.setState({ playing: true,
      start: audio.seekable.start(0), end: audio.seekable.end(0) });
  }

  _onPause () {
    const audio = this.refs.audio;
    audio.pause();
    this.setState({ playing: false });
  }

  _onSeek (event) {
    const audio = this.refs.audio;
    const value = event.target.value;
    audio.currentTime = value;
    this.setState({ at: value });
  }

  _onVolume (event) {
    const audio = this.refs.audio;
    const value = event.target.value;
    audio.volume = value;
    this.setState({ volume: value });
  }

  render () {
    const { file, color, full, plain } = this.props;
    const { playing, volume, start, end, at } = this.state;
    const path = `/api/files/${file._id}/${file.name}`;

    let playControl, positionControl, volumeControl;
    if (playing) {
      playControl = (
        <button className="button audio__control" type="button"
          onClick={this._onPause}>Pause</button>
      );
      positionControl = (

          <input className="audio__position" type="range" min={start} max={end}
            value={at} onChange={this._onSeek} />
          {friendlyDuration(end - at)}

      );
      volumeControl = (

          <VolumeIcon />
          <input className="audio__volume" type="range" min={0} max={1}
            step={0.1} value={volume} onChange={this._onVolume} />

      );
    } else {
      playControl = (
        <button className="button audio__control" type="button"
          onClick={this._onPlay}>Listen</button>
      );
    }

    return (

          {playControl}
          {positionControl}
          {volumeControl}
          <audio ref="audio" preload="metadata">
            <source src={path} type={file.type} />
            No audio with this browser
          </audio>

    );
  }
};

Audio.propTypes = {
  full: PropTypes.bool,
  file: PropTypes.shape({
    _id: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    type: PropTypes.string.isRequired
  }),
  ...Section.propTypes
};
<|endoftext|>


<commit_before>module.exports = function (config) {
  'use strict'

  config.set({
    frameworks: ['mocha', 'chai', 'sinon'],
    files: [
      {pattern: 'bower_components/jquery/dist/jquery.js', instrument: false},
      {pattern: 'bower_components/toastr/toastr.js', instrument: false},
      {pattern: 'bower_components/angular/angular.js', instrument: false},
      {pattern: 'node_modules/angular-mocks/angular-mocks.js', instrument: false},
      'src/app/**/*.js',
      'test/stubs.js',
      'test/**/*.spec.js'
    ],

    autoWatchBatchDelay: 10000,
    singleRun: true,
    browsers: ['PhantomJS'],

    preprocessors: {
      'src/app/**/*.js': ['coverage', 'sourcemap']
    },
    reporters: ['progress', 'coverage', 'appveyor'],
    coverageReporter: {
      dir: '../reports',
      reporters: [
        {
          type: 'json',
          subdir: '.',
          file: 'coverage-js.json'
        }
      ]
    }
  })
}
<commit_msg>Add jspm configuration.<commit_after>module.exports = function (config) {
  'use strict'

  config.set({
    frameworks: ['jspm', 'mocha', 'chai', 'sinon'],

    jspm: {
      config: 'src/jspm.conf.js',
      loadFiles: [
        'test/**/*.spec.js'
      ],
      serveFiles: [
        'src/**/*.js',
        'src/**/*.html',
        'test/stubs.js'
      ]
    },
    proxies: {
      '/jspm_packages/': '/base/src/jspm_packages/',
      '/test/': '/base/test/',
      '/src/': '/base/src/'
    },

    autoWatchBatchDelay: 10000,
    singleRun: true,
    browsers: ['PhantomJS'],

    preprocessors: {
      'src/app/**/*.js': ['coverage', 'sourcemap']
    },
    reporters: ['progress', 'coverage', 'appveyor'],
    coverageReporter: {
      dir: '../reports',
      reporters: [
        {
          type: 'json',
          subdir: '.',
          file: 'coverage-js.json'
        }
      ]
    }
  })
}
<|endoftext|>


<commit_before>/**
 * Created by phpNT on 22.03.2016.
 */
var deposite = parseFloat(0.000001050),          // депозит старта
    riskPercentage = 0.20,                      // риск в процентах
    maxWait = 1000;                             // таймаут в милисекундах

/* вычисляем ставку и округляем до 8 знака после нуля */
var startValue = parseFloat((deposite / 1000).toFixed(8));      // ставка

/* Кнопки */
var $loButton = $('#double_your_btc_bet_lo_button'),
    $hiButton = $('#double_your_btc_bet_hi_button');

/* Проверка, что достаточно средств */
function iHaveEnoughMoni(){
    var balance = parseFloat($('#balance').text());          // баланс
    var current = parseFloat($('#double_your_btc_stake').val());         // текущая ставка
    /* закрываем при прибыли */
    var profit = parseFloat((deposite + (deposite * riskPercentage)).toFixed(8));
    if(balance >= profit) {
        console.info('Закрываемся с прибылью в ' + (riskPercentage * 100) + '%. Равной ' + parseFloat((balance - deposite)).toFixed(8) + ' BTC.');
        stopGame();
    }
    /* закрываем при пройгрыше */
    var loss = parseFloat((deposite - (deposite * riskPercentage)).toFixed(8));
    if(balance <= loss) {
        console.info('Закрываемся с потерей в ' + (riskPercentage * 100) + '%. Равной ' + parseFloat((balance - deposite)).toFixed(8) + ' BTC.');
        stopGame();
    }
    return true;
}

function stopGame(){
    stopGame();
}

/* Умножение до 8 знака после запятой */
function multiply(){
    var current = $('#double_your_btc_stake').val();
    var multiply = (current * 2).toFixed(8);
    $('#double_your_btc_stake').val(multiply);
}

function getRandomWait(){
    var wait = Math.floor(Math.random() * maxWait ) + 100;
    //console.info('Ждем ' + wait + ' милисекунд до следующей ставки.');
    return wait ;
}

function reset(){
    $('#double_your_btc_stake').val(startValue);
}
// Unbind old shit
$('#double_your_btc_bet_lose').unbind();
$('#double_your_btc_bet_win').unbind();
/* Если проигрыш */
$('#double_your_btc_bet_lose').bind("DOMSubtreeModified",function(event){
    if( $(event.currentTarget).is(':contains("lose")') )
    {
        console.info('Проигрыш!');
        multiply();
        if(iHaveEnoughMoni()) {
            setTimeout(function () {
                $loButton.trigger('click');
            }, getRandomWait());
        }
    }
});
/* Если выйгрыш */
$('#double_your_btc_bet_win').bind("DOMSubtreeModified",function(event){
    if( $(event.currentTarget).is(':contains("win")') )
    {
        if(iHaveEnoughMoni()) {
            console.info('Выигрыш!');
            reset();
            if( stopped )
            {
                stopped = false;
                return false;
            }
        }
        setTimeout(function(){
            $loButton.trigger('click');
        }, getRandomWait());
    }
});
var balance = parseFloat($('#balance').text());          // баланс
var profit = parseFloat((deposite + (deposite * riskPercentage)).toFixed(8));
var loss = parseFloat((deposite - (deposite * riskPercentage)).toFixed(8));
console.info('Закрываемся если цена больше ' + parseFloat((profit)).toFixed(8) + ' BTC, или меньше ' + parseFloat((loss)).toFixed(8) + ' BTC. Минимальная ставка: ' + startValue);<commit_msg>Edit main motor 14<commit_after>/**
 * Created by phpNT on 22.03.2016.
 */
var deposite = parseFloat(0.00001830),          // депозит старта
    riskPercentage = 0.20,                      // риск в процентах
    maxWait = 1000;                             // таймаут в милисекундах

/* вычисляем ставку и округляем до 8 знака после нуля */
var startValue = parseFloat((deposite / 1000)).toFixed(8);      // ставка

/* Кнопки */
var $loButton = $('#double_your_btc_bet_lo_button'),
    $hiButton = $('#double_your_btc_bet_hi_button');

/* Проверка, что достаточно средств */
function iHaveEnoughMoni(){
    var balance = parseFloat($('#balance').text());          // баланс
    var current = parseFloat($('#double_your_btc_stake').val());         // текущая ставка
    /* закрываем при прибыли */
    var profit = parseFloat((deposite + (deposite * riskPercentage)).toFixed(8));
    if(balance >= profit) {
        console.info('Закрываемся с прибылью в ' + (riskPercentage * 100) + '%. Равной ' + parseFloat((balance - deposite)).toFixed(8) + ' BTC.');
        stopGame();
    }
    /* закрываем при пройгрыше */
    var loss = parseFloat((deposite - (deposite * riskPercentage)).toFixed(8));
    if(balance <= loss) {
        console.info('Закрываемся с потерей в ' + (riskPercentage * 100) + '%. Равной ' + parseFloat((balance - deposite)).toFixed(8) + ' BTC.');
        stopGame();
    }
    return true;
}

function stopGame(){
    stopGame();
}

/* Умножение до 8 знака после запятой */
function multiply(){
    var current = $('#double_your_btc_stake').val();
    var multiply = (current * 2).toFixed(8);
    $('#double_your_btc_stake').val(multiply);
}

function getRandomWait(){
    var wait = Math.floor(Math.random() * maxWait ) + 100;
    //console.info('Ждем ' + wait + ' милисекунд до следующей ставки.');
    return wait ;
}

function reset(){
    $('#double_your_btc_stake').val(startValue);
}
// Unbind old shit
$('#double_your_btc_bet_lose').unbind();
$('#double_your_btc_bet_win').unbind();
/* Если проигрыш */
$('#double_your_btc_bet_lose').bind("DOMSubtreeModified",function(event){
    if( $(event.currentTarget).is(':contains("lose")') )
    {
        console.info('Проигрыш. Ставка равна ' + parseFloat($('#double_your_btc_stake').val()).toFixed(8) + '.');
        multiply();
        if(iHaveEnoughMoni()) {
            setTimeout(function () {
                $loButton.trigger('click');
            }, getRandomWait());
        }
    }
});
/* Если выйгрыш */
$('#double_your_btc_bet_win').bind("DOMSubtreeModified",function(event){
    if( $(event.currentTarget).is(':contains("win")') )
    {
        if(iHaveEnoughMoni()) {
            console.info('Выигрыш!');
            reset();
        }
        setTimeout(function(){
            $loButton.trigger('click');
        }, getRandomWait());
    }
});
var balance = parseFloat($('#balance').text());          // баланс
var profit = parseFloat((deposite + (deposite * riskPercentage)).toFixed(8));
var loss = parseFloat((deposite - (deposite * riskPercentage)).toFixed(8));
console.info('Закрываемся если цена больше ' + parseFloat((profit)).toFixed(8) + ' BTC, или меньше ' + parseFloat((loss)).toFixed(8) + ' BTC. Минимальная ставка: ' + (deposite / 1000).toFixed(8));
$loButton.trigger('click');<|endoftext|>


<commit_before>$.fn.CSelectPicker = function(settings){

	var selectElem = this;

	if (selectElem)
	{
		new CSP(settings);
	}else
		console.error('CSP - Not checked elem in setting');

	function CSP(settings)
	{
		var self = this;

		this.settings = {
			multiple: false,
			placehoder: 'Select you value'
		};

		this.createHtml = function()
		{

			if (selectElem.length)
			{

				selectElem.val("");

				selectElem.wrap('

').hide();

				$('.CSP-wrapper').append('

'+this.settings.placehoder+'

');

				var items = {};

				selectElem.find('option').each(function(index, el)
				{

					items[index] = {

						value: $(this).val(),

						text: $(this).text()

					}

				});

				if (!$.isEmptyObject(items))
				{

					$('.CSP-select-window').append('

');

					$.each(items, function(index, item) {

						$('.CSP-dropdown-window').append('
'+item.text+'
')

					});

					if (self.settings.maxDropdownItemsShow)
					{

						var visibleHeight = 0,
							wrapperHeight = 0;

						$('.CSP-dropdown-item:lt('+self.settings.maxDropdownItemsShow+')').each(function(index, el) {
							visibleHeight +=$(this).outerHeight();
						});
						$('.CSP-dropdown-item').each(function(index, el) {
							wrapperHeight +=$(this).outerHeight();
						});

						var scollBarItemHeight = 100 / (wrapperHeight / visibleHeight);

						if (wrapperHeight != visibleHeight)
						{
							$('.CSP-dropdown-window').height(visibleHeight).append('

');

							var offsetToTop = 0;

							$('.CSP-dropdown-window').on('mousewheel', function(event) {
								var statusToScroll = (event.originalEvent.wheelDelta < 0) ? 'up' : 'down';

								if (statusToScroll == "up") {
									if ( offsetToTop > -(wrapperHeight - visibleHeight) ) {
										offsetToTop -= 29;
									}
								}else{
									if (offsetToTop < 0 ) {
										offsetToTop += 29;
									}
								}

								var offsetToScrollBar = (-offsetToTop) * (100 / wrapperHeight);

								$('.CSP-dropdown-item:first-child').css({'margin-top': offsetToTop+'px'});

								$('.CSP-scrollbar-item').css({'top': offsetToScrollBar+'%'})

							    if (self.settings.onScrollDropdown)
							    	self.settings.onScrollDropdown(statusToScroll);
							});

						}

					}

					$('.CSP-toggle-dropdown').click(function(event) {
						self.toogleDropDown(false);
					});

					$(document).click( function(event) {
					    if( !$(event.target).closest('.CSP-toggle-dropdown').length && !$(event.target).is('.CSP-dropdown-item') && !$(event.target).is('.CSP-toggle-dropdown') && !$(event.target).is('.CSP-scrollbar-item') && $('.CSP-dropdown-window').hasClass('CSP-dropdown-window-show') )
					    {
					        self.toogleDropDown(true);
					    }
					});

					var values = {};

					var label = $('.CSP-label');

					values[selectElem.attr('name')] = [];

					$('.CSP-dropdown-item').click(function(event) {

						var itemValue = $(this).data('value'),

						itemText = $(this).text();

						var option = selectElem.find('option[value="'+itemValue+'"]');

						if (self.settings.multiple)
						{

							if (itemValue) {
								if ($(this).hasClass('CSP-active'))
								{
									var i = values[selectElem.attr('name')].indexOf(''+itemValue+'');

									if(i != -1)
										values[selectElem.attr('name')].splice(i, 1);

									$(this).removeClass('CSP-active')
								}
								else
								{

									values[selectElem.attr('name')].push(''+itemValue+'');

									$(this).addClass('CSP-active');
								}

								if (!values[selectElem.attr('name')].length)
								{
									label.addClass('CSP-placehoder').text(self.settings.placehoder)
								}
								else
								{
									var text = "";

									$.each(values[selectElem.attr('name')], function(index, val) {

										text += ''+selectElem.find('option[value="'+val+'"]').text()+'&#10005';

									});

									label.removeClass('CSP-placehoder').html(text);
								}

								selectElem.val(values[selectElem.attr('name')]);
							}

						}
						else
						{
							$('.CSP-dropdown-item').removeClass('CSP-active');

							if (!itemValue)
								label.addClass('CSP-placehoder').text(self.settings.placehoder)
							else
								label.removeClass('CSP-placehoder').html(''+itemText+'');

							if (option.length)
							{
								selectElem.val(itemValue)
							}
							$(this).addClass('CSP-active');
						}

						if (self.settings.onChange)
						{
							self.settings.onChange(selectElem);
						}

					});

					$(document).on('click', '.CSP-remove-item', function(event) {

						var dataRemove = $(this).data('remove');

						var elementToRemove = $('.CSP-dropdown-item[data-value="'+dataRemove+'"]');

						if (elementToRemove.hasClass('CSP-active'))
						{
							elementToRemove.removeClass('CSP-active');

							var valuesSelect = self.removeToItemInArray(selectElem.val(), ''+dataRemove+'');

							var i = values[selectElem.attr('name')].indexOf(''+dataRemove+'');

							if(i != -1)
								values[selectElem.attr('name')].splice(i, 1);

							if (!values[selectElem.attr('name')].length)
							{
								label.addClass('CSP-placehoder').text(self.settings.placehoder)
							}

							selectElem.val(valuesSelect);

							$(this).parent('.CSP-multiple-item-value').remove();
						}

					});

				}else
					console.warn('CSP - Options is select is empty');

			}else
				console.error('CSP - Not found elem')

		}

		this.removeToItemInArray = function(array, remove){

			var i = array.indexOf(remove);
			if(i != -1)
				array.splice(i, 1);

			return array;
		}

		this.toogleDropDown = function(status)
		{
			var dropdownWrapper = $('.CSP-dropdown-window');

			if (!status)
			{
				dropdownWrapper.toggleClass('CSP-dropdown-window-show');
			}
			else
			{
				dropdownWrapper.removeClass('CSP-dropdown-window-show');
			}

			if (self.settings.dropdownStatus)
			{
				var status = $('.CSP-dropdown-window').hasClass('CSP-dropdown-window-show') ? 'open' : 'close';

				self.settings.dropdownStatus(status);
			}
		}

		construct(settings);

		function construct(settings)
		{
			$.extend(self.settings, settings);

			self.createHtml();

			if (settings.onReady)
				settings.onReady();
		}

	}
};<commit_msg>Update cselectpicker.js<commit_after>$.fn.CSelectPicker = function(settings){

	var selectElem = this;

	if (selectElem)
	{
		new CSP(settings);
	}else
		console.error('CSP - Not checked elem in setting');

	function CSP(settings)
	{
		var self = this;

		this.settings = {
			multiple: false,
			placehoder: 'Select you value'
		};

		this.createHtml = function()
		{

			if (selectElem.length)
			{

				selectElem.val("");

				selectElem.wrap('

').hide();

				$('.CSP-wrapper').append('

'+this.settings.placehoder+'

');

				var items = {};

				selectElem.find('option').each(function(index, el)
				{

					items[index] = {

						value: $(this).val(),

						text: $(this).text()

					}

				});

				if (!$.isEmptyObject(items))
				{

					$('.CSP-select-window').append('

');

					$.each(items, function(index, item) {

						$('.CSP-dropdown-window').append('
'+item.text+'
')

					});

					if (self.settings.maxDropdownItemsShow)
					{

						var visibleHeight = 0,
							wrapperHeight = 0;

						$('.CSP-dropdown-item:lt('+self.settings.maxDropdownItemsShow+')').each(function(index, el) {
							visibleHeight +=$(this).outerHeight();
						});
						$('.CSP-dropdown-item').each(function(index, el) {
							wrapperHeight +=$(this).outerHeight();
						});

						var scollBarItemHeight = 100 / (wrapperHeight / visibleHeight);

						if (wrapperHeight != visibleHeight)
						{
							$('.CSP-dropdown-window').height(visibleHeight).append('

');

							var offsetToTop = 0;

							$('.CSP-dropdown-window').on('mousewheel', function(event) {
								var statusToScroll = (event.originalEvent.wheelDelta < 0) ? 'up' : 'down';

								if (statusToScroll == "up") {
									if ( offsetToTop > -(wrapperHeight - visibleHeight) ) {
										offsetToTop -= 29;
									}
								}else{
									if (offsetToTop < 0 ) {
										offsetToTop += 29;
									}
								}

								var offsetToScrollBar = (-offsetToTop) * (100 / wrapperHeight);

								$('.CSP-dropdown-item:first-child').css({'margin-top': offsetToTop+'px'});

								$('.CSP-scrollbar-item').css({'top': offsetToScrollBar+'%'})

							    if (self.settings.onScrollDropdown)
							    	self.settings.onScrollDropdown(statusToScroll);
							});

						}

					}

					$('.CSP-toggle-dropdown').click(function(event) {
						self.toogleDropDown(false);
					});

					$(document).click( function(event) {
					    if( !$(event.target).closest('.CSP-toggle-dropdown').length && !$(event.target).is('.CSP-dropdown-item') && !$(event.target).is('.CSP-toggle-dropdown') && !$(event.target).is('.CSP-scrollbar-item') && $('.CSP-dropdown-window').hasClass('CSP-dropdown-window-show') )
					    {
					        self.toogleDropDown(true);
					    }
					});

					var values = {};

					var label = $('.CSP-label');

					values[selectElem.attr('name')] = [];

					$('.CSP-dropdown-item').click(function(event) {

						var itemValue = $(this).data('value'),

						itemText = $(this).text();

						var option = selectElem.find('option[value="'+itemValue+'"]');

						if (self.settings.multiple)
						{

							if (itemValue) {
								if ($(this).hasClass('CSP-active'))
								{
									var i = values[selectElem.attr('name')].indexOf(''+itemValue+'');

									if(i != -1)
										values[selectElem.attr('name')].splice(i, 1);

									$(this).removeClass('CSP-active')
								}
								else
								{

									values[selectElem.attr('name')].push(''+itemValue+'');

									$(this).addClass('CSP-active');
								}

								if (!values[selectElem.attr('name')].length)
								{
									label.addClass('CSP-placehoder').text(self.settings.placehoder)
								}
								else
								{
									var text = "";

									$.each(values[selectElem.attr('name')], function(index, val) {

										text += ''+selectElem.find('option[value="'+val+'"]').text()+'&#10005';

									});

									label.removeClass('CSP-placehoder').html(text);
								}

								selectElem.val(values[selectElem.attr('name')]);
							}

						}
						else
						{
							$('.CSP-dropdown-item').removeClass('CSP-active');

							if (!itemValue)
								label.addClass('CSP-placehoder').text(self.settings.placehoder)
							else
								label.removeClass('CSP-placehoder').html(''+itemText+'');

							if (option.length)
							{
								selectElem.val(itemValue)
							}
							$(this).addClass('CSP-active');
						}

						if (self.settings.onChange)
						{
							self.settings.onChange(selectElem);
						}

					});

					$(document).on('click', '.CSP-remove-item', function(event) {

						var dataRemove = $(this).data('remove');

						var elementToRemove = $('.CSP-dropdown-item[data-value="'+dataRemove+'"]');

						if (elementToRemove.hasClass('CSP-active'))
						{
							elementToRemove.removeClass('CSP-active');

							var valuesSelect = self.removeToItemInArray(selectElem.val(), '"'+dataRemove+'"');

							var i = values[selectElem.attr('name')].indexOf(''+dataRemove+'');

							if(i != -1)
								values[selectElem.attr('name')].splice(i, 1);

							if (!values[selectElem.attr('name')].length)
							{
								label.addClass('CSP-placehoder').text(self.settings.placehoder)
							}

							selectElem.val(valuesSelect);

							$(this).parent('.CSP-multiple-item-value').remove();
						}

					});

				}else
					console.warn('CSP - Options is select is empty');

			}else
				console.error('CSP - Not found elem')

		}

		this.removeToItemInArray = function(array, remove){

			var i = array.indexOf(remove);
			if(i != -1)
				array.splice(i, 1);

			return array;
		}

		this.toogleDropDown = function(status)
		{
			var dropdownWrapper = $('.CSP-dropdown-window');

			if (!status)
			{
				dropdownWrapper.toggleClass('CSP-dropdown-window-show');
			}
			else
			{
				dropdownWrapper.removeClass('CSP-dropdown-window-show');
			}

			if (self.settings.dropdownStatus)
			{
				var status = $('.CSP-dropdown-window').hasClass('CSP-dropdown-window-show') ? 'open' : 'close';

				self.settings.dropdownStatus(status);
			}
		}

		construct(settings);

		function construct(settings)
		{
			if (!settings)
				settings = {};

			$.extend(self.settings, settings);

			self.createHtml();

			if (settings.onReady)
				settings.onReady();
		}

	}
};
<|endoftext|>


<commit_before>/**
 * Sets records in the metadata table to be 'ordered'
 * for download if they are not available for download from USGS.
 *
 */

/**
 * TODO
 *  delete old log files
 */

// Libraries
var yaml = require('yamljs')
var pg = require('pg')
var fs = require('fs')
var winston = require('winston')
var axios = require('axios')
var Promise = require('bluebird')
Promise.longStackTraces()

// Modules
var usgs_constants = require("./lib/usgs_api/usgs_constants.js")
var usgs_functions = require("./lib/usgs_api/usgs_functions.js")
var usgs_helpers = require("./lib/usgs_api/usgs_helpers.js")
var pg_handler = require('./lib/postgres/postgres_handlers.js')
var app_helpers = require('./lib/helpers/app_helpers.js')()

// Constants for handling USGS API
const DL_OPTION_DOWNLOAD_CODE = "STANDARD"
const DL_OPTIONS_USGS_RESPONSE_CODE = usgs_helpers.get_usgs_response_code('downloadoptions')

// Maximum scene list size for a single downloadoptions request
const SCENE_BATCH_LIMIT = 10000

// Base URL for http promise library
axios.defaults.baseURL = usgs_constants.USGS_URL

// USGS API key promise
var get_api_key = usgs_helpers.get_api_key()

// Database connection
const db_config = yaml.load("./lib/postgres/config.yaml")
var pg_pool = pg_handler.pg_pool(db_config)

// Logging
const TODAY_DATE = app_helpers.get_date_string()
const LOG_LEVEL_INFO = 'info'
const LOG_LEVEL_ERROR = 'error'
const LOG_FILE = 'update_scenes_to_order_' + TODAY_DATE

app_helpers.delete_old_files(LOG_FILE, 'logs/', '.log')
app_helpers.set_logger_level('debug')
app_helpers.set_logfile(LOG_FILE)
app_helpers.write_message(LOG_LEVEL_INFO, 'START '+LOG_FILE, '')

// Initial SELECT query
const query_text = "SELECT * FROM landsat_metadata "
  + "WHERE needs_ordering = null "
    + "OR needs_ordering = 'YES'"

//////////////////////////////////////////////////////////////////////////////////

/**
 * Main function. Pulls relevant records from the metadata table to be processed,
 * then initiates the processing logic for the query result.
 *
 */
const main = function () {

  pg_handler.pool_query_db(pg_pool, query_text, [], function(query_result) {
    if (query_result.rows && query_result.rows.length) {
      const scenes_by_dataset = usgs_helpers.sort_scene_records_by_dataset(query_result.rows)
      var dataset_names = Object.keys(scenes_by_dataset)
      usgs_helpers.process_scenes_by_dataset(dataset_names, scenes_by_dataset, process_scenes_for_dataset)
    }
    else {
      app_helpers.write_message(LOG_LEVEL_INFO, 'SELECT query returned no rows to process')
    }
  })

}

/**
 * Process the scenes for a single landsat dataset.
 *
 * @param scenes is a list of scene ids all from the same landsat dataset
 * @param dataset_name is the name of the landsat dataset being processed
 *
 */
const process_scenes_for_dataset = function (dataset_name, scenes) {
  return Promise.resolve().then(function () {
    if (scenes && scenes.length) {
      var scene_batch = scenes.slice(0, SCENE_BATCH_LIMIT)
      return process_scene_batch(scene_batch, dataset_name)
    }
  }).then(function () {
    if (scenes && scenes.length) {
      var scenes = scenes.slice(SCENE_BATCH_LIMIT)
      return process_scenes_for_dataset(scenes, dataset_name)
    }
    else {
      app_helpers.write_message(
        LOG_LEVEL_INFO,
        'COMPLETED processing dataset',
        dataset_name
      )
    }
  })
}

const process_scene_batch = function (scenes, dataset_name) {
  return get_dl_options_for_scene_batch(scenes, dataset_name).then(function (response) {
    if (response) {
      return sort_options_by_avail(response).then(function(scenes_by_avail) {
        return update_records(scenes_by_avail)
      })
    }
  })
}

/**
 * Get the download availability for a batch of scenes.
 *
 * @return the response of the DownloadOptions API call to USGS.
 */
const get_dl_options_for_scene_batch = function (scenes, dataset_name) {
  return get_api_key.then(function (apiKey) {
    app_helpers.write_message(
      LOG_LEVEL_INFO,
      'START processing scene batch of size '+scenes.length+' for dataset ',
      dataset_name
    )

    const request_body = usgs_functions.usgsapi_downloadoptions(apiKey, usgs_constants.NODE_EE, dataset_name, scenes)
    return usgs_helpers.get_usgsapi_response(DL_OPTIONS_USGS_RESPONSE_CODE, request_body)
      .catch(function(err) {
        return handle_usgs_dl_options_response_error(err, scenes, dataset_name, num_attempts)
      })
      .then(function(response) {
        return process_usgs_dl_options_response(response, dataset_name)
      })

  })
  .catch(function (err) {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'ERROR obtaining USGS API key',
      err.stack
    )
  })

}

/**
 * Processes the response of a usgs downloadopotions request.
 *
 */
const process_usgs_dl_options_response = function (response, dataset_name) {
  if (response) {
    app_helpers.write_message(
      LOG_LEVEL_INFO,
      'COMPLETED get download options for scene batch of dataset',
      dataset_name
    )
    if (response.length) {
      return response
    }
    else {
      app_helpers.write_message(
        LOG_LEVEL_INFO,
        'No download options returned for scene batch in dataset',
        dataset_name
      )
    }
  }
  else {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'No response data from downloadoptions request'
    )
  }
}

/**
 * Handle errors returned by a usgs downloadoptions request.
 * Initiates another request if we get a simultaenous requests error
 * (up to a certain number of attempts)
 *
 */
const handle_usgs_dl_options_response_error = function (err, scenes, dataset_name, num_attempts) {
  app_helpers.write_message(
    LOG_LEVEL_ERROR,
    'ERROR on downloadoptions request',
    err.stack
  )
}

/**
 * Sort scenes by download availability
 *
 * @param response is the result of a DownloadOptions request to the USGS API.
 *  [
 *    // A single scene
 *    {
 *      downloadOptions: [
 *        {
 *          available: <Boolean>
 *          downloadCode: <String>
 *          filesize: <Number>
 *          productName: <String>
 *          url: <String>
 *          storageLocation: <String>
 *        },
 *        ...
 *      ],
 *      entityId: <String>
 *    },
 *    ...
 *  ]
 *
 * @return an object with two lists: available and unavailable sceneIds
 *
 */
const sort_options_by_avail = function (response) {

  // Mark needs_ordering field as YES if available for download (available is true),
  //   NO if not available for download
  return Promise.resolve().then(function () {
    var avail = []
    var unavail = []

    response.forEach((obj) => {
      var standard_option = obj['downloadOptions'].filter((option) => {
        return option['downloadCode'] === 'STANDARD'
      })
      if (standard_option.length) {
        if (standard_option[0].available) {
          avail.push(obj.entityId)
        }
        else {
          unavail.push(obj.entityId)
        }
      } else {
        app_helpers.write_message(
          LOG_LEVEL_ERROR,
          'ERROR no download option for '
        )

      }
    })

    return { 'available': avail, 'unavailable': unavail }
  })
  .catch(function (err) {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'ERROR sorting downloadoptions response by download availability',
      err.stack
    )
  })

}

/**
 * Update database records for scenes based on download availability
 *
 * @param scenes_by_avail an object with keys 'available' and 'unavailable'
 * with lists of scene ids for each field.
 */
const update_records = function (scenes_by_avail) {
  return update_records_by_availability(scenes_by_avail.available, 'NO').then(function () {
    return update_records_by_availability(scenes_by_avail.unavailable, 'YES')
  })
}
const update_records_by_availability = function (scenes, field_text) {
  return Promise.resolve().then(function () {
    if (scenes.length) {
      sql_list = app_helpers.list_array_to_sql_list(scenes)
      var query_text = build_update_query(sql_list, field_text)
      pg_handler.pool_query_db(pg_pool, query_text, [])
    }
  }).catch(function (err) {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'ERROR updating scene records',
      err.stack
    )

  })
}

/**
 * Build a query to update the records for a batch of scenes.
 *
 */
const build_update_query = function (scenes, needs_ordering_text) {
  const download_available_text = needs_ordering_text === 'NO' ? 'YES' : 'NO'
  return "UPDATE landsat_metadata SET needs_ordering = "
          + "'"+needs_ordering_text+"', "
          + "download_available = "
          + "'"+download_available_text+"' "
          + "WHERE scene_id IN "
          + scenes
}

main()

<commit_msg>Clean up update scenes to order script<commit_after>/**
 * Sets records in the metadata table to be 'ordered'
 * for download if they are not available for download from USGS.
 *
 */

// Libraries
var yaml = require('yamljs')
var pg = require('pg')
var fs = require('fs')
var winston = require('winston')
var axios = require('axios')
var Promise = require('bluebird')
Promise.longStackTraces()

// Modules
var usgs_constants = require("./lib/usgs_api/usgs_constants.js")
var usgs_functions = require("./lib/usgs_api/usgs_functions.js")
var usgs_helpers = require("./lib/usgs_api/usgs_helpers.js")
var pg_handler = require('./lib/postgres/postgres_handlers.js')
var app_helpers = require('./lib/helpers/app_helpers.js')()

// Constants for handling USGS API
const DL_OPTION_DOWNLOAD_CODE = "STANDARD"
const DL_OPTIONS_USGS_RESPONSE_CODE = usgs_helpers.get_usgs_response_code('downloadoptions')

// Maximum scene list size for a single downloadoptions request
const SCENE_BATCH_LIMIT = 10000

// Base URL for http promise library
axios.defaults.baseURL = usgs_constants.USGS_URL

// USGS API key promise
var get_api_key = usgs_helpers.get_api_key()

// Database connection
const db_config = yaml.load("./lib/postgres/config.yaml")
var pg_pool = pg_handler.pg_pool(db_config)

// Logging
const TODAY_DATE = app_helpers.get_date_string()
const LOG_LEVEL_INFO = 'info'
const LOG_LEVEL_ERROR = 'error'
const LOG_FILE = 'update_scenes_to_order'
app_helpers.delete_old_files(LOG_FILE, 'logs/', '.log')
app_helpers.set_logger_level('debug')
app_helpers.set_logfile(LOG_FILE)
app_helpers.write_message(LOG_LEVEL_INFO, 'START '+LOG_FILE, '')

// Initial SELECT query
const query_text = "SELECT * FROM landsat_metadata "
  + "WHERE needs_ordering = null "
    + "OR needs_ordering = 'YES'"

//////////////////////////////////////////////////////////////////////////////////

/**
 * Main function. Pulls relevant records from the metadata table to be processed,
 * then initiates the processing logic for the query result.
 *
 */
const main = function () {

  pg_handler.pool_query_db(pg_pool, query_text, [], function(query_result) {
    if (query_result.rows && query_result.rows.length) {
      const scenes_by_dataset = usgs_helpers.sort_scene_records_by_dataset(query_result.rows)
      var dataset_names = Object.keys(scenes_by_dataset)
      usgs_helpers.process_scenes_by_dataset(dataset_names, scenes_by_dataset, process_scenes_for_dataset)
    }
    else {
      app_helpers.write_message(LOG_LEVEL_INFO, 'SELECT query returned no rows to process')
    }
  })

}

/**
 * Process the scenes for a single landsat dataset.
 *
 * @param scenes is a list of scene ids all from the same landsat dataset
 * @param dataset_name is the name of the landsat dataset being processed
 *
 */
const process_scenes_for_dataset = function (dataset_name, scenes) {
  return Promise.resolve().then(function () {
    if (scenes && scenes.length) {
      var scene_batch = scenes.slice(0, SCENE_BATCH_LIMIT)
      return process_scene_batch(scene_batch, dataset_name)
    }
  }).then(function () {
    if (scenes && scenes.length) {
      var scenes = scenes.slice(SCENE_BATCH_LIMIT)
      return process_scenes_for_dataset(scenes, dataset_name)
    }
    else {
      app_helpers.write_message(
        LOG_LEVEL_INFO,
        'COMPLETED processing dataset',
        dataset_name
      )
    }
  })
}

const process_scene_batch = function (scenes, dataset_name) {
  return get_dl_options_for_scene_batch(scenes, dataset_name).then(function (response) {
    if (response && response.length) {
      return sort_options_by_avail(response).then(function(scenes_by_avail) {
        return update_records(scenes_by_avail)
      })
    }
  })
}

/**
 * Get the download availability for a batch of scenes.
 *
 * @return the response of the DownloadOptions API call to USGS.
 */
const get_dl_options_for_scene_batch = function (scenes, dataset_name) {
  return get_api_key.then(function (apiKey) {
    app_helpers.write_message(
      LOG_LEVEL_INFO,
      'START processing scene batch of size '+scenes.length+' for dataset ',
      dataset_name
    )

    const request_body = usgs_functions.usgsapi_downloadoptions(apiKey, usgs_constants.NODE_EE, dataset_name, scenes)
    return usgs_helpers.get_usgsapi_response(DL_OPTIONS_USGS_RESPONSE_CODE, request_body)
      .catch(function(err) {
        return handle_usgs_dl_options_response_error(err, scenes, dataset_name, num_attempts)
      })
      .then(function(response) {
        return process_usgs_dl_options_response(response, dataset_name)
      })

  })
  .catch(function (err) {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'ERROR obtaining USGS API key',
      err.stack
    )
  })

}

/**
 * Processes the response of a usgs downloadopotions request.
 *
 */
const process_usgs_dl_options_response = function (response, dataset_name) {
  if (response) {
    app_helpers.write_message(
      LOG_LEVEL_INFO,
      'COMPLETED get download options for scene batch of dataset',
      dataset_name
    )
    if (response.length) {
      return response
    }
    else {
      app_helpers.write_message(
        LOG_LEVEL_INFO,
        'No download options returned for scene batch in dataset',
        dataset_name
      )
    }
  }
  else {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'No response data from downloadoptions request'
    )
  }
}

/**
 * Handle errors returned by a usgs downloadoptions request.
 * Initiates another request if we get a simultaenous requests error
 * (up to a certain number of attempts)
 *
 */
const handle_usgs_dl_options_response_error = function (err, scenes, dataset_name, num_attempts) {
  app_helpers.write_message(
    LOG_LEVEL_ERROR,
    'ERROR on downloadoptions request',
    err.stack
  )
}

/**
 * Sort scenes by download availability
 *
 * @param response is the result of a DownloadOptions request to the USGS API.
 *  [
 *    // A single scene
 *    {
 *      downloadOptions: [
 *        {
 *          available: <Boolean>
 *          downloadCode: <String>
 *          filesize: <Number>
 *          productName: <String>
 *          url: <String>
 *          storageLocation: <String>
 *        },
 *        ...
 *      ],
 *      entityId: <String>
 *    },
 *    ...
 *  ]
 *
 * @return an object with two lists: available and unavailable sceneIds
 *
 */
const sort_options_by_avail = function (response) {

  // Mark needs_ordering field as YES if available for download (available is true),
  //   NO if not available for download
  return Promise.resolve().then(function () {
    var avail = []
    var unavail = []

    response.forEach((obj) => {
      var standard_option = obj['downloadOptions'].filter((option) => {
        return option['downloadCode'] === 'STANDARD'
      })
      if (standard_option.length) {
        if (standard_option[0].available) {
          avail.push(obj.entityId)
        }
        else {
          unavail.push(obj.entityId)
        }
      } else {
        app_helpers.write_message(
          LOG_LEVEL_ERROR,
          'ERROR no download option for '
        )

      }
    })

    return { 'available': avail, 'unavailable': unavail }
  })
  .catch(function (err) {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'ERROR sorting downloadoptions response by download availability',
      err.stack
    )
  })

}

/**
 * Update database records for scenes based on download availability
 *
 * @param scenes_by_avail an object with keys 'available' and 'unavailable'
 * with lists of scene ids for each field.
 */
const update_records = function (scenes_by_avail) {
  return update_records_by_availability(scenes_by_avail.available, 'NO').then(function () {
    return update_records_by_availability(scenes_by_avail.unavailable, 'YES')
  })
}
const update_records_by_availability = function (scenes, field_text) {
  return Promise.resolve().then(function () {
    if (scenes.length) {
      sql_list = app_helpers.list_array_to_sql_list(scenes)
      var query_text = build_update_query(sql_list, field_text)
      pg_handler.pool_query_db(pg_pool, query_text, [])
    }
  }).catch(function (err) {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'ERROR updating scene records',
      err.stack
    )

  })
}

/**
 * Build a query to update the records for a batch of scenes.
 *
 */
const build_update_query = function (scenes, needs_ordering_text) {
  const download_available_text = needs_ordering_text === 'NO' ? 'YES' : 'NO'
  return "UPDATE landsat_metadata SET needs_ordering = "
          + "'"+needs_ordering_text+"', "
          + "download_available = "
          + "'"+download_available_text+"' "
          + "WHERE scene_id IN "
          + scenes
}

main()

<|endoftext|>


<commit_before>Ext.ns('Deluge.ux');

Deluge.plugins.UpdatorrPlugin = Ext.extend(Deluge.Plugin, {

	name: 'Updatorr',

	toggleLabel: {
		true: _('Enable autoupdates'),
		false: _('Disable autoupdates')
	},

	onEnable: function() {

		this.tmSep = deluge.menus.torrent.add({
			xtype: 'menuseparator'
		});

		this.tmToggle = deluge.menus.torrent.add({
			text: this.toggleLabel[true],
			handler: this.onToggleClick,
			scope: this
		});

		deluge.menus.torrent.on('beforeshow', this.torrentMenuToShow, this);

		this.registerTorrentStatus('Updatorr', _('Updatorr'), { colCfg: { hidden: true }});
	},

	onDisable: function() {
		deluge.menus.torrent.remove(this.tmSep);
		deluge.menus.torrent.remove(this.tmAdd);
		deluge.menus.torrent.remove(this.tmRemove);
		deluge.menus.torrent.un('beforeshow', this.torrentMenuToShow, this);
		this.deregisterTorrentStatus('Updatorr');
	},

	torrentMenuToShow: function() {
		var any = false;
		var balance = 0;

		deluge.torrents.getSelections().forEach(function(entry) {
			if (entry.data.Updatorr) { any = true; }
			balance += entry.data.Updatorr === "On" ? 1 : -1;
		});

		if (any) {
			this.tmSep.show();
			this.tmToggle.show();
			this.tmToggle.setText(this.toggleLabel[balance < 0]);
		}
		else {
			this.tmSep.hide();
			this.tmToggle.hide();
		}
	},

	onToggleClick: function(item) {
		var enable = item.text == this.toggleLabel[true];
		var ids = deluge.torrents.getSelectedIds();
		Ext.each(ids, function(id, i) {
			if (ids.length == i +1 ) {
				deluge.client.updatorr.set_items_to_update(id, enable, {
					success: function() {
						deluge.ui.update();
					}
				});
			} else {
				deluge.client.updatorr.set_items_to_update(id, enable);
			}
		});
	},

});

Deluge.registerPlugin('Updatorr', Deluge.plugins.UpdatorrPlugin);<commit_msg>WebUI: Add context menu entries for starting walker.<commit_after>Ext.ns('Deluge.ux');

Deluge.plugins.UpdatorrPlugin = Ext.extend(Deluge.Plugin, {

	name: 'Updatorr',

	toggleLabel: {
		true: _('Enable autoupdates'),
		false: _('Disable autoupdates')
	},

	runLabel: {
		true: _('Check updates for selected'),
		false: _('Torrent updates in progress...')
	},

	runAllLabel: {
		true: _('Check for all updates'),
		false: _('Torrent updates in progress...')
	},

	onEnable: function() {

		this.tmSep = deluge.menus.torrent.add({
			xtype: 'menuseparator'
		});

		this.tmToggle = deluge.menus.torrent.add({
			text: this.toggleLabel[true],
			handler: this.onToggleClick,
			scope: this
		});

		this.tmRun = deluge.menus.torrent.add({
			text: this.runLabel[true],
			handler: this.onRunClick,
			scope: this
		});

		this.tmRunAll = deluge.menus.torrent.add({
			text: this.runAllLabel[true],
			handler: this.onRunAllClick,
			scope: this
		});

		deluge.menus.torrent.on('beforeshow', this.torrentMenuToShow, this);

		this.registerTorrentStatus('Updatorr', _('Updatorr'), { colCfg: { hidden: true }});
	},

	onDisable: function() {
		deluge.menus.torrent.remove(this.tmSep);
		deluge.menus.torrent.remove(this.tmToggle);
		deluge.menus.torrent.remove(this.tmRun);
		deluge.menus.torrent.remove(this.tmRunAll);
		deluge.menus.torrent.un('beforeshow', this.torrentMenuToShow, this);
		this.deregisterTorrentStatus('Updatorr');
	},

	torrentMenuToShow: function() {
		var any = false;
		var balance = 0;

		deluge.torrents.getSelections().forEach(function(entry) {
			if (entry.data.Updatorr === "On") { any = true; }
			balance += entry.data.Updatorr === "On" ? 1 : -1;
		});

		this.tmToggle.setText(this.toggleLabel[balance < 0]);
		this.tmRun.setVisible(any);

		deluge.client.updatorr.is_walking({success: function(is_walking) {
			this.tmRun.setText(this.runLabel[!is_walking]);
			this.tmRun.setDisabled(is_walking);
			this.tmRunAll.setText(this.runAllLabel[!is_walking]);
			this.tmRunAll.setDisabled(is_walking);
		}, scope: this });
	},

	onRunClick: function(item) {
		deluge.client.updatorr.run_walker( deluge.torrents.getSelectedIds() );
	},

	onRunAllClick: function(item) {
		deluge.client.updatorr.run_walker(true);
	},

	onToggleClick: function(item) {
		var enable = item.text == this.toggleLabel[true];
		var ids = deluge.torrents.getSelectedIds();
		Ext.each(ids, function(id, i) {
			if (ids.length == i +1 ) {
				deluge.client.updatorr.set_items_to_update(id, enable, {
					success: function() {
						deluge.ui.update();
					}
				});
			} else {
				deluge.client.updatorr.set_items_to_update(id, enable);
			}
		});
	},

});

Deluge.registerPlugin('Updatorr', Deluge.plugins.UpdatorrPlugin);<|endoftext|>


<commit_before>function getPublicCounts() {
	getProtocolCounts();
	getSampleCounts();
	getPublicationCounts();
}

function getProtocolCounts() {
	show("protocolLoaderImg");
	hide("protocolCount");
	ProtocolManager.getPublicCounts(function(data) {
		if (data != null) {
			hide("protocolLoaderImg");
			var link = "" + data
					+ "";
			dwr.util.setValue("protocolCount", link, {
				escapeHtml : false
			});
			show("protocolCount");
		} else {
			show("protocolLoaderImg");
		}
	});
}

function getSampleCounts() {
	show("sampleLoaderImg");
	hide("sampleRelatedCounts");
	hide("sampleCounts");
	SampleManager.getPublicCounts(function(data) {
		if (data != null) {
			hide("sampleLoaderImg");
			var link = "" + data
					+ "";
			dwr.util.setValue("sampleCount", link, {
				escapeHtml : false
			});
			show("sampleCounts");
			show("moreStats");
		} else {
			show("sampleLoaderImg");
			hide("moreStats");
		}
	});
}

function getMoreSamplesStats() {
	hide("sampleRelatedCounts");
	show("sampleRelatedLoaderImg");
	var sampleRelatedCounts = document.getElementById("sampleRelatedCounts");
	// dwr.engine.beginBatch(); //doesn't work properly in IE7
	getSampleSourceCounts();
	getCharacterizationCounts("Characterization");
	getCharacterizationCounts("PhysicoChemicalCharacterization");
	getCharacterizationCounts("InvitroCharacterization");
	getCharacterizationCounts("InvivoCharacterization");
	getCharacterizationCounts("OtherCharacterization");
	/*
	 * dwr.engine.endBatch( { async : false });
	 */
}

function getSampleSourceCounts() {
	SampleManager.getPublicSourceCounts(function(data) {
		if (data != null) {
			dwr.util.setValue("sampleSourceCount", data);
			show("sampleRelatedCounts");
			hide("sampleRelatedLoaderImg");
		}
	});
}

function getCharacterizationCounts(charType) {
	// show an example of how to set async for individual call back
	CharacterizationManager.getPublicCharacterizationCounts(charType, {
		callback : function(data) {
			if (data != null) {
				dwr.util.setValue(charType + "Count", data);
				show("sampleRelatedCounts");
				hide("sampleRelatedLoaderImg");
			}
		},
		async : true
	});
}

function getPublicationCounts() {
	show("publicationLoaderImg");
	hide("publicationCount");
	PublicationManager.getPublicCounts(function(data) {
		if (data != null) {
			hide("publicationLoaderImg");
			var link = "" + data
					+ "";
			dwr.util.setValue("publicationCount", link, {
				escapeHtml : false
			});
			show("publicationCount");
		} else {
			show("publicationLoaderImg");
		}
	});
}

function gotoSamples(dispatch) {
	var url = "/caNanoLab/searchSample.do?dispatch=" + dispatch;
	gotoPage(url);
	return false;
}

function gotoPublications(dispatch) {
	var url = "/caNanoLab/searchPublication.do?dispatch=" + dispatch;
	gotoPage(url);
	return false;
}

function gotoProtocols(dispatch) {
	var url = "/caNanoLab/searchProtocol.do?dispatch=" + dispatch;
	gotoPage(url);
	return false;
}
<commit_msg>add study counts<commit_after>function getPublicCounts() {
	getProtocolCounts();
	getSampleCounts();
	getPublicationCounts();
	getStudyCounts();
}

function getProtocolCounts() {
	show("protocolLoaderImg");
	hide("protocolCount");
	ProtocolManager.getPublicCounts(function(data) {
		if (data != null) {
			hide("protocolLoaderImg");
			var link = "" + data
					+ "";
			dwr.util.setValue("protocolCount", link, {
				escapeHtml : false
			});
			show("protocolCount");
		} else {
			show("protocolLoaderImg");
		}
	});
}

function getSampleCounts() {
	show("sampleLoaderImg");
	hide("sampleRelatedCounts");
	hide("sampleCounts");
	SampleManager.getPublicCounts(function(data) {
		if (data != null) {
			hide("sampleLoaderImg");
			var link = "" + data
					+ "";
			dwr.util.setValue("sampleCount", link, {
				escapeHtml : false
			});
			show("sampleCounts");
			show("moreStats");
		} else {
			show("sampleLoaderImg");
			hide("moreStats");
		}
	});
}

function getMoreSamplesStats() {
	hide("sampleRelatedCounts");
	show("sampleRelatedLoaderImg");
	var sampleRelatedCounts = document.getElementById("sampleRelatedCounts");
	// dwr.engine.beginBatch(); //doesn't work properly in IE7
	getSampleSourceCounts();
	getCharacterizationCounts("Characterization");
	getCharacterizationCounts("PhysicoChemicalCharacterization");
	getCharacterizationCounts("InvitroCharacterization");
	getCharacterizationCounts("InvivoCharacterization");
	getCharacterizationCounts("OtherCharacterization");
	/*
	 * dwr.engine.endBatch( { async : false });
	 */
}

function getSampleSourceCounts() {
	SampleManager.getPublicSourceCounts(function(data) {
		if (data != null) {
			dwr.util.setValue("sampleSourceCount", data);
			show("sampleRelatedCounts");
			hide("sampleRelatedLoaderImg");
		}
	});
}

function getCharacterizationCounts(charType) {
	// show an example of how to set async for individual call back
	CharacterizationManager.getPublicCharacterizationCounts(charType, {
		callback : function(data) {
			if (data != null) {
				dwr.util.setValue(charType + "Count", data);
				show("sampleRelatedCounts");
				hide("sampleRelatedLoaderImg");
			}
		},
		async : true
	});
}

function getPublicationCounts() {
	show("publicationLoaderImg");
	hide("publicationCount");
	PublicationManager.getPublicCounts(function(data) {
		if (data != null) {
			hide("publicationLoaderImg");
			var link = "" + data
					+ "";
			dwr.util.setValue("publicationCount", link, {
				escapeHtml : false
			});
			show("publicationCount");
		} else {
			show("publicationLoaderImg");
		}
	});
}

function getStudyCounts(){
	show("studyLoaderImg");
	hide("studyCount");
	ProtocolManager.getPublicCounts(function(data) {
		if (data != null) {
			hide("studyLoaderImg");
			var link = "" + data
					+ "";
			dwr.util.setValue("studyCount", "0 Studies", {
				escapeHtml : false
			});
			show("studyCount");
		} else {
			show("studyLoaderImg");
		}
	});
}

function gotoSamples(dispatch) {
	var url = "/caNanoLab/searchSample.do?dispatch=" + dispatch;
	gotoPage(url);
	return false;
}

function gotoPublications(dispatch) {
	var url = "/caNanoLab/searchPublication.do?dispatch=" + dispatch;
	gotoPage(url);
	return false;
}

function gotoProtocols(dispatch) {
	var url = "/caNanoLab/searchProtocol.do?dispatch=" + dispatch;
	gotoPage(url);
	return false;
}

function gotoStudy(dispatch) {
	var url = "/caNanoLab/searchStudy.do?dispatch=" + dispatch;
	gotoPage(url);
	return false;
}
<|endoftext|>