<commit_before>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

// new re-factored Listing object
// removed rarely used functionality
//
// opts:
//   parent

//   method (method to call on server)
//   args (additional args to method)
//   get_args (method to return args as dict)

//   show_filters [false]
//   doctype
//   filter_fields (if given, this list is rendered, else built from doctype)

//   query or get_query (will be deprecated)
//   query_max
//   buttons_in_frame

//   no_result_message ("No result")

//   page_length (20)
//   hide_refresh (False)
//   no_toolbar
//   new_doctype
//   [function] render_row(parent, data)
//   [function] onrun
//   no_loading (no ajax indicator)

wn.provide('wn.ui');
wn.ui.Listing = Class.extend({
	init: function(opts) {
		this.opts = opts || {};
		this.page_length = 20;
		this.start = 0;
		this.data = [];
		if(opts) {
			this.make();
		}
	},
	prepare_opts: function() {
		if(this.opts.new_doctype) {
			if(wn.boot.profile.can_create.indexOf(this.opts.new_doctype)==-1) {
				this.opts.new_doctype = null;
			} else {
				this.opts.new_doctype = this.opts.new_doctype;
			}
		}
		if(!this.opts.no_result_message) {
			this.opts.no_result_message = wn._('Nothing to show');
		}
		this.opts._more = wn._("More");
	},
	make: function(opts) {
		if(opts) {
			this.opts = opts;
		}
		this.prepare_opts();
		$.extend(this, this.opts);

		$(this.parent).html(repl('\

\

%(title)s
\
				\

\

\

\

\
							<button class="btn btn-info search-btn">\
								 \
								Search</button>\
							<button class="btn btn-default add-filter-btn">\
								 \
								Add Filter</button>\

\

\

\
				\

\

\

\

\

\

\
				\

\
					%(no_result_message)s\

\
				\

\

\

\
				\

\
					<button class="btn btn-default btn-more" style="display: none; margin: 15px 0px;">%(_more)s...
\

\

\
		', this.opts));
		this.$w = $(this.parent).find('.wnlist');
		this.set_events();

		if(this.appframe) {
			this.$w.find('.list-toolbar-wrapper').toggle(false);
		}

		if(this.show_filters) {
			this.make_filters();
		}
	},
	add_button: function(label, click, icon) {
		if(this.appframe) {
			return this.appframe.add_button(label, click, icon)
		} else {
			$button = $('<button class="btn btn-default"></button>')
				.appendTo(this.$w.find('.list-toolbar'))
				.html((icon ? (" ") : "") + label)
				.click(click);
			return $button
		}
	},
	show_view: function($btn, $div, $btn_unsel, $div_unsel) {
		$btn_unsel.removeClass('btn-info');
		$btn_unsel.find('i').removeClass('icon-white');
		$div_unsel.toggle(false);

		$btn.addClass('btn-info');
		$btn.find('i').addClass('icon-white');
		$div.toggle(true);
	},
	set_events: function() {
		var me = this;

		// next page
		this.$w.find('.btn-more').click(function() {
			me.run({append: true });
		});

		// title
		if(this.title) {
			this.$w.find('h3').html(this.title).toggle(true);
		}

		// hide-refresh
		if(!(this.hide_refresh || this.no_refresh)) {
			this.add_button('Refresh', function() {
				me.run();
			}, 'icon-refresh');

		}

		// new
		if(this.new_doctype) {
			if(this.appframe) {
				this.appframe.set_title_right(" New", function() {
					(me.custom_new_doc || me.make_new_doc).apply(me, [me.new_doctype]); });
			}
			this.add_button(wn._('New'), function() {
				(me.custom_new_doc || me.make_new_doc).apply(me, [me.new_doctype]);
			}, 'icon-plus');
		}

		// hide-filter
		if(me.show_filters) {
			this.add_button(wn._('Filter'), function() {
				me.filter_list.show_filters();
			}, 'icon-search').addClass('btn-filter');
		}

		if(me.no_toolbar || me.hide_toolbar) {
			me.$w.find('.list-toolbar-wrapper').toggle(false);
		}
	},

	make_new_doc: function(doctype) {
		var me = this;
		wn.model.with_doctype(doctype, function() {
			var doc = wn.model.get_new_doc(doctype);
			if(me.filter_list) {
				$.each(me.filter_list.get_filters(), function(i, f) {
					if(f[0]===doctype && f[2]==="=" && f[1]!=="name")
						doc[f[1]]=f[3];
				})
			}
			wn.set_route("Form", doctype, doc.name);
		});
	},

	make_filters: function() {
		this.filter_list = new wn.ui.FilterList({
			listobj: this,
			$parent: this.$w.find('.list-filters').toggle(true),
			doctype: this.doctype,
			filter_fields: this.filter_fields
		});
	},

	clear: function() {
		this.data = [];
		this.$w.find('.result-list').empty();
		this.$w.find('.result').toggle(true);
		this.$w.find('.no-result').toggle(false);
		this.start = 0;
	},
	run: function(more) {
		var me = this;
		if(!more) {
			this.start = 0;
			if(this.onreset) this.onreset();
		}

		if(!me.opts.no_loading)
			me.set_working(true);

		return wn.call({
			method: this.opts.method || 'webnotes.widgets.query_builder.runquery',
			type: "GET",
			args: this.get_call_args(),
			callback: function(r) {
				if(!me.opts.no_loading)
					me.set_working(false);
				me.dirty = false;
				me.render_results(r);
			},
			no_spinner: this.opts.no_loading
		});
	},
	set_working: function(flag) {
		this.$w.find('.img-load').toggle(flag);
	},
	get_call_args: function() {
		// load query
		if(!this.method) {
			var query = this.get_query ? this.get_query() : this.query;
			query = this.add_limits(query);
			var args={
				query_max: this.query_max,
				as_dict: 1
			}
			args.simple_query = query;
		} else {
			var args = {
				limit_start: this.start,
				limit_page_length: this.page_length
			}
		}

		// append user-defined arguments
		if(this.args)
			$.extend(args, this.args)

		if(this.get_args) {
			$.extend(args, this.get_args());
		}
		return args;
	},
	render_results: function(r) {
		if(this.start===0) this.clear();

		this.$w.find('.btn-more').toggle(false);

		if(r.message) {
			r.values = this.get_values_from_response(r.message);
		}

		if(r.values && r.values.length) {
			this.data = this.data.concat(r.values);
			this.render_list(r.values);
			this.update_paging(r.values);
		} else {
			if(this.start===0) {
				this.$w.find('.result').toggle(false);

				var msg = this.get_no_result_message
					? this.get_no_result_message()
					: (this.no_result_message
						? this.no_result_message
						: wn._("Nothing to show"));

				this.$w.find('.no-result')
					.html(msg)
					.toggle(true);
			}
		}

		// callbacks
		if(this.onrun) this.onrun();
		if(this.callback) this.callback(r);
		this.$w.trigger("render-complete");
	},

	get_values_from_response: function(data) {
		// make dictionaries from keys and values
		if(data.keys) {
			var values = [];
			$.each(data.values, function(row_idx, row) {
				var new_row = {};
				$.each(data.keys, function(key_idx, key) {
					new_row[key] = row[key_idx];
				})
				values.push(new_row);
			});
			return values;
		} else {
			return data;
		}
	},

	render_list: function(values) {
		var m = Math.min(values.length, this.page_length);
		this.data = values;
		if(this.filter_list)
			this.filter_values = this.filter_list.get_filters();

		// render the rows
		for(var i=0; i < m; i++) {
			this.render_row(this.add_row(), values[i], this, i);
		}
	},
	update_paging: function(values) {
		if(values.length >= this.page_length) {
			this.$w.find('.btn-more').toggle(true);
			this.start += this.page_length;
		}
	},
	add_row: function() {
		return $('
').appendTo(this.$w.find('.result-list')).get(0);
	},
	refresh: function() {
		this.run();
	},
	add_limits: function(query) {
		query += ' LIMIT ' + this.start + ',' + (this.page_length+1);
		return query
	},
	set_filter: function(fieldname, label, doctype) {
		if(!doctype) doctype = this.doctype;
		var filter = this.filter_list.get_filter(fieldname);
		if(filter) {
			var v = filter.field.get_parsed_value();
			if(v.indexOf(label)!=-1) {
				// already set
				return false;
			} else {
				// second filter set for this field
				if(fieldname=='_user_tags') {
					// and for tags
					this.filter_list.add_filter(doctype, fieldname,
						'like', '%' + label);
				} else {
					// or for rest using "in"
					filter.set_values(doctype, fieldname, 'in', v + ', ' + label);
				}
			}
		} else {
			// no filter for this item,
			// setup one
			if(['_user_tags', '_comments'].indexOf(fieldname)!==-1) {
				this.filter_list.add_filter(doctype, fieldname,
					'like', '%' + label);
			} else {
				this.filter_list.add_filter(doctype, fieldname, '=', label);
			}
		}
	}
});<commit_msg>Fixed listing.js bug replicated in Firefox<commit_after>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

// new re-factored Listing object
// removed rarely used functionality
//
// opts:
//   parent

//   method (method to call on server)
//   args (additional args to method)
//   get_args (method to return args as dict)

//   show_filters [false]
//   doctype
//   filter_fields (if given, this list is rendered, else built from doctype)

//   query or get_query (will be deprecated)
//   query_max
//   buttons_in_frame

//   no_result_message ("No result")

//   page_length (20)
//   hide_refresh (False)
//   no_toolbar
//   new_doctype
//   [function] render_row(parent, data)
//   [function] onrun
//   no_loading (no ajax indicator)

wn.provide('wn.ui');
wn.ui.Listing = Class.extend({
	init: function(opts) {
		this.opts = opts || {};
		this.page_length = 20;
		this.start = 0;
		this.data = [];
		if(opts) {
			this.make();
		}
	},
	prepare_opts: function() {
		if(this.opts.new_doctype) {
			if(wn.boot.profile.can_create.indexOf(this.opts.new_doctype)==-1) {
				this.opts.new_doctype = null;
			} else {
				this.opts.new_doctype = this.opts.new_doctype;
			}
		}
		if(!this.opts.no_result_message) {
			this.opts.no_result_message = wn._('Nothing to show');
		}
		this.opts._more = wn._("More");
	},
	make: function(opts) {
		if(opts) {
			this.opts = opts;
		}
		this.prepare_opts();
		$.extend(this, this.opts);

		$(this.parent).html(repl('\

\

%(title)s
\
				\

\

\

\

\
							<button class="btn btn-info search-btn">\
								 \
								Search</button>\
							<button class="btn btn-default add-filter-btn">\
								 \
								Add Filter</button>\

\

\

\
				\

\

\

\

\

\

\
				\

\
					%(no_result_message)s\

\
				\

\

\

\
				\

\
					<button class="btn btn-default btn-more" style="display: none; margin: 15px 0px;">%(_more)s...
\

\

\
		', this.opts));
		this.$w = $(this.parent).find('.wnlist');
		this.set_events();

		if(this.appframe) {
			this.$w.find('.list-toolbar-wrapper').toggle(false);
		}

		if(this.show_filters) {
			this.make_filters();
		}
	},
	add_button: function(label, click, icon) {
		if(this.appframe) {
			return this.appframe.add_button(label, click, icon)
		} else {
			$button = $('<button class="btn btn-default"></button>')
				.appendTo(this.$w.find('.list-toolbar'))
				.html((icon ? (" ") : "") + label)
				.click(click);
			return $button
		}
	},
	show_view: function($btn, $div, $btn_unsel, $div_unsel) {
		$btn_unsel.removeClass('btn-info');
		$btn_unsel.find('i').removeClass('icon-white');
		$div_unsel.toggle(false);

		$btn.addClass('btn-info');
		$btn.find('i').addClass('icon-white');
		$div.toggle(true);
	},
	set_events: function() {
		var me = this;

		// next page
		this.$w.find('.btn-more').click(function() {
			me.run({append: true });
		});

		// title
		if(this.title) {
			this.$w.find('h3').html(this.title).toggle(true);
		}

		// hide-refresh
		if(!(this.hide_refresh || this.no_refresh)) {
			this.add_button('Refresh', function() {
				me.run();
			}, 'icon-refresh');

		}

		// new
		if(this.new_doctype) {
			if(this.appframe) {
				this.appframe.set_title_right(" New", function() {
					(me.custom_new_doc || me.make_new_doc).apply(me, [me.new_doctype]); });
			}
			this.add_button(wn._('New'), function() {
				(me.custom_new_doc || me.make_new_doc).apply(me, [me.new_doctype]);
			}, 'icon-plus');
		}

		// hide-filter
		if(me.show_filters) {
			this.add_button(wn._('Filter'), function() {
				me.filter_list.show_filters();
			}, 'icon-search').addClass('btn-filter');
		}

		if(me.no_toolbar || me.hide_toolbar) {
			me.$w.find('.list-toolbar-wrapper').toggle(false);
		}
	},

	make_new_doc: function(doctype) {
		var me = this;
		wn.model.with_doctype(doctype, function() {
			var doc = wn.model.get_new_doc(doctype);
			if(me.filter_list) {
				$.each(me.filter_list.get_filters(), function(i, f) {
					if(f[0]===doctype && f[2]==="=" && f[1]!=="name")
						doc[f[1]]=f[3];
				})
			}
			wn.set_route("Form", doctype, doc.name);
		});
	},

	make_filters: function() {
		this.filter_list = new wn.ui.FilterList({
			listobj: this,
			$parent: this.$w.find('.list-filters').toggle(true),
			doctype: this.doctype,
			filter_fields: this.filter_fields
		});
	},

	clear: function() {
		this.data = [];
		this.$w.find('.result-list').empty();
		this.$w.find('.result').toggle(true);
		this.$w.find('.no-result').toggle(false);
		this.start = 0;
	},
	run: function(more) {
		var me = this;
		if(!more) {
			this.start = 0;
			if(this.onreset) this.onreset();
		}

		if(!me.opts.no_loading)
			me.set_working(true);

		return wn.call({
			method: this.opts.method || 'webnotes.widgets.query_builder.runquery',
			type: "GET",
			args: this.get_call_args(),
			callback: function(r) {
				if(!me.opts.no_loading)
					me.set_working(false);
				me.dirty = false;
				me.render_results(r);
			},
			no_spinner: this.opts.no_loading
		});
	},
	set_working: function(flag) {
		this.$w.find('.img-load').toggle(flag);
	},
	get_call_args: function() {
		// load query
		if(!this.method) {
			var query = this.get_query ? this.get_query() : this.query;
			query = this.add_limits(query);
			var args={
				query_max: this.query_max,
				as_dict: 1
			}
			args.simple_query = query;
		} else {
			var args = {
				limit_start: this.start,
				limit_page_length: this.page_length
			}
		}

		// append user-defined arguments
		if(this.args)
			$.extend(args, this.args)

		if(this.get_args) {
			$.extend(args, this.get_args());
		}
		return args;
	},
	render_results: function(r) {
		if(this.start===0) this.clear();

		this.$w.find('.btn-more').toggle(false);

		if(r.message) {
			r.values = this.get_values_from_response(r.message);
		}

		if(r.values && r.values.length) {
			this.data = this.data.concat(r.values);
			this.render_list(r.values);
			this.update_paging(r.values);
		} else {
			if(this.start===0) {
				this.$w.find('.result').toggle(false);

				var msg = this.get_no_result_message
					? this.get_no_result_message()
					: (this.no_result_message
						? this.no_result_message
						: wn._("Nothing to show"));

				this.$w.find('.no-result')
					.html(msg)
					.toggle(true);
			}
		}

		// callbacks
		if(this.onrun) this.onrun();
		if(this.callback) this.callback(r);
		this.$w.trigger("render-complete");
	},

	get_values_from_response: function(data) {
		// make dictionaries from keys and values
		if(data.keys && $.isArray(data.keys)) {
			var values = [];
			$.each(data.values, function(row_idx, row) {
				var new_row = {};
				$.each(data.keys, function(key_idx, key) {
					new_row[key] = row[key_idx];
				})
				values.push(new_row);
			});
			return values;
		} else {
			return data;
		}
	},

	render_list: function(values) {
		var m = Math.min(values.length, this.page_length);
		this.data = values;
		if(this.filter_list)
			this.filter_values = this.filter_list.get_filters();

		// render the rows
		for(var i=0; i < m; i++) {
			this.render_row(this.add_row(), values[i], this, i);
		}
	},
	update_paging: function(values) {
		if(values.length >= this.page_length) {
			this.$w.find('.btn-more').toggle(true);
			this.start += this.page_length;
		}
	},
	add_row: function() {
		return $('
').appendTo(this.$w.find('.result-list')).get(0);
	},
	refresh: function() {
		this.run();
	},
	add_limits: function(query) {
		query += ' LIMIT ' + this.start + ',' + (this.page_length+1);
		return query
	},
	set_filter: function(fieldname, label, doctype) {
		if(!doctype) doctype = this.doctype;
		var filter = this.filter_list.get_filter(fieldname);
		if(filter) {
			var v = filter.field.get_parsed_value();
			if(v.indexOf(label)!=-1) {
				// already set
				return false;
			} else {
				// second filter set for this field
				if(fieldname=='_user_tags') {
					// and for tags
					this.filter_list.add_filter(doctype, fieldname,
						'like', '%' + label);
				} else {
					// or for rest using "in"
					filter.set_values(doctype, fieldname, 'in', v + ', ' + label);
				}
			}
		} else {
			// no filter for this item,
			// setup one
			if(['_user_tags', '_comments'].indexOf(fieldname)!==-1) {
				this.filter_list.add_filter(doctype, fieldname,
					'like', '%' + label);
			} else {
				this.filter_list.add_filter(doctype, fieldname, '=', label);
			}
		}
	}
});
<|endoftext|>


<commit_before>/*
 *  Copyright © 2010 Ian Langworth
 *
 *  This file is part of JSRoboWar.
 *
 *  JSRoboWar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  JSRoboWar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with JSRoboWar.  If not, see <http://www.gnu.org/licenses/>.
 */

// TODO: Hardware Depot
// TODO: Game speed adjustment
// TODO: Integrated debugger

if (!window.$) alert('`$` object missing. jquery.js is required.');
if (!window._) alert('`_` object missing. underscore.js is required.');

$(document).ready(function() {

  // Navigation tabs ---------------------------------------------------------

  var current_section;

  function set_section(name) {
    $('#nav').attr('class', name);
    $('section#' + name).show();
    $('section#' + current_section).hide();
    current_section = name;
  };

 // $('#container > section').hide();
  set_section(document.location.hash.replace(/\W/g, '') || 'play');

  $('#nav li a').click(function() {
    var name = $(this).attr('href').substr(1);
    set_section(name);
    document.location.hash = name;
    window.scroll(0, 0);
    return false;
  });

  // Robot choices -----------------------------------------------------------

  var ROBOT_SLOTS = 2;
  var ROBOT_COLORS = ['#0ff', '#ff0', '#f99', '#0f0', '#f0f'];
  var ROBOT_CHOICES = [
    ['Development robots', [
      ['target-practice', 'Target Practice']
    ]],
    ['Tutorial robots', [
      ['corner-hopper', 'Corner Hopper'],
      ['dgt-with-probes', 'Defensive Gun Turret'],
      ['shape-changer', 'Shape Changer'],
      ['stationary', 'Stationary Bot'],
      ['wall-hugger', 'Wall-Hugger'],
      ['wall-seeker', 'Wall-Seeker'],
      ['wanderer', 'Wanderer'],
    ]],
    ['Mortal class', [
      ['arachnee', 'Arachnee'],
      ['archivist', 'Archivist'],
      ['existentialist', 'Existentialist'],
      ['ghost', 'Ghost'],
      ['invisible-stalker', 'Invisible Stalker'],
      ['locke', 'Lock v18'],
      ['pearl', 'Pearl'],
      ['silo-iv', 'Silo IV'],
      ['timbot-iv', 'Timbot IV'],
    ]],
    ['Titan class', [
      ['dark-knight-4', 'Dark Knight 4'],
      ['fluffy-3', 'Fluffy 3'],
      ['soul-deliverer-9x', 'Soul Deliverer 9x'],
      ['the-dead-parrot', 'The Dead Parrot'],
      ['zim', 'Zim'],
    ]],
  ];

  function get_robot_name(i) {
    var select = $('#choice' + i);
    return select.val() ? select.find(':selected').text() : 'Custom Robot ' + (i + 1);
  }

  function reveal_editor(i, errors) {
    var name = get_robot_name(i);
    $('#editor h2').text(name);
    if (errors) {
      alert('Error compiling ' + name + ":\n\n" + errors);
      $('#errors').show().text(errors);
    } else {
      $('#errors').hide().text(errors);
    }

    $('#editors textarea').slideUp();
    $('#editor').slideDown();
    $('#code' + i).slideDown();
  }

  _.each(_.range(ROBOT_SLOTS- 1), function(i) {  // Scope i correctly.

    // Create the drop-down menu.
    var select = $('<select/>').attr('id', 'choice' + i);
    select.append($('<option/>').text('Choose a robot...').attr('value', ''));
    for (var j = 0, group; group = ROBOT_CHOICES[j]; j++) {
      var optgroup = $('<optgroup/>').attr('label', group[0]);
      for (var k = 0, choice; choice = group[1][k]; k++) {
        optgroup.append($('<option/>').attr('value', choice[0]).text(choice[1]));
      }
      select.append(optgroup);
    }

    // Create the edit button.
    var edit_button = $('<button/>').text('Edit');

    // Add the menu and the edit button to the page.
    $('#choices ol').append($('<li/>').append(select, ' ', edit_button));

    // Create the robot code editor and add it to the page.
    var textarea = $('<textarea/>').attr('id', 'code' + i);
    textarea.hide();
    $('#editors').append(textarea);

    // Changing resets the bot choice to reflect "a custom bot."
    textarea.change(function() {
      select.val('');
      $('#editor h2').text(get_robot_name(i));
    });

    // Load robot code into the editor when a robot is selected.
    select.change(function() {
      var name = $(this).val();
      if (name) {
        var path = '/jsrobowar/robots/' + name + '.txt';
        textarea.val('(Loading ' + path + ')');
        textarea.attr('disabled', 'disabled');
        $.get(path, function(src) {
          textarea.val(src);
          textarea.attr('disabled', null);
        });
        // TODO: Hardware depot
      }
    });

    // Make the edit button show the editor.
    edit_button.click(function() {
      reveal_editor(i);
    });

    edit_button.hide();

  });

  // Hide the editor initially.
  $('#editor').hide();

  // Game initialization -----------------------------------------------------

  var game = new Game($('#arena')[0], $('#scoreboard')[0]);

  function load_robot(code, name, color) {
    var program = new Program();
    program.parse(code);
    if (program.errors) {
      alert(name + " failed to start\nReason:\n" +program.errors);
      // reveal_editor(i, program.errors);
      return;
    }

    var robot = new Robot(name, color, program);
    return robot;
  }
  function setup_game() {
    // Reset the robots and game state.
    game.clear();

    // Get tested robot code
    // Load each robot. Bail out if one doesn't compile.
    var tested_code = myCodeMirror.getValue();
    var robot_name = $('#robot_name').val();
    var robot = load_robot(tested_code, robot_name, ROBOT_COLORS[1]);
    game.add_robot(robot);
    _.each(_.range(ROBOT_SLOTS -1), function(i) {
      var code = $('#code' + i).val();

      var robot = load_robot(code, get_robot_name(i), ROBOT_COLORS[i]);
      game.add_robot(robot);
    });
  };

  // Play/pause button -------------------------------------------------------

  var show_start_button = function() {
    $('#start').show();
    $('#stop').hide();
  };

  $('#start').click(function(e) {
    e.preventDefault();
    setup_game();
    game.start(show_start_button);
    $(this).hide();
    $('#stop').show();
  });

  $('#stop').click(function(e) {
    e.preventDefault();
    game.stop();
    show_start_button();
  });

  show_start_button();

  // Sound-toggle button -----------------------------------------------------

  $('#sound').change(function() {
    SoundEffects.enable($(this).attr('checked'));
  }).change();

  // Auto-start demo mode ----------------------------------------------------

  $('#choice0').val('target-practice').change();

  //# _.delay(function() {$('#start').click()}, 600);

});
<commit_msg>Allow people to test against 3 bots<commit_after>/*
 *  Copyright © 2010 Ian Langworth
 *
 *  This file is part of JSRoboWar.
 *
 *  JSRoboWar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  JSRoboWar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with JSRoboWar.  If not, see <http://www.gnu.org/licenses/>.
 */

// TODO: Hardware Depot
// TODO: Game speed adjustment
// TODO: Integrated debugger

if (!window.$) alert('`$` object missing. jquery.js is required.');
if (!window._) alert('`_` object missing. underscore.js is required.');

$(document).ready(function() {

  // Navigation tabs ---------------------------------------------------------

  var current_section;

  function set_section(name) {
    $('#nav').attr('class', name);
    $('section#' + name).show();
    $('section#' + current_section).hide();
    current_section = name;
  };

 // $('#container > section').hide();
  set_section(document.location.hash.replace(/\W/g, '') || 'play');

  $('#nav li a').click(function() {
    var name = $(this).attr('href').substr(1);
    set_section(name);
    document.location.hash = name;
    window.scroll(0, 0);
    return false;
  });

  // Robot choices -----------------------------------------------------------

  var ROBOT_SLOTS = 4;
  var ROBOT_COLORS = ['#0ff', '#ff0', '#f99', '#0f0', '#f0f'];
  var ROBOT_CHOICES = [
    ['Development robots', [
      ['target-practice', 'Target Practice']
    ]],
    ['Tutorial robots', [
      ['corner-hopper', 'Corner Hopper'],
      ['dgt-with-probes', 'Defensive Gun Turret'],
      ['shape-changer', 'Shape Changer'],
      ['stationary', 'Stationary Bot'],
      ['wall-hugger', 'Wall-Hugger'],
      ['wall-seeker', 'Wall-Seeker'],
      ['wanderer', 'Wanderer'],
    ]],
    ['Mortal class', [
      ['arachnee', 'Arachnee'],
      ['archivist', 'Archivist'],
      ['existentialist', 'Existentialist'],
      ['ghost', 'Ghost'],
      ['invisible-stalker', 'Invisible Stalker'],
      ['locke', 'Lock v18'],
      ['pearl', 'Pearl'],
      ['silo-iv', 'Silo IV'],
      ['timbot-iv', 'Timbot IV'],
    ]],
    ['Titan class', [
      ['dark-knight-4', 'Dark Knight 4'],
      ['fluffy-3', 'Fluffy 3'],
      ['soul-deliverer-9x', 'Soul Deliverer 9x'],
      ['the-dead-parrot', 'The Dead Parrot'],
      ['zim', 'Zim'],
    ]],
  ];

  function get_robot_name(i) {
    var select = $('#choice' + i);
    return select.val() ? select.find(':selected').text() : 'Custom Robot ' + (i + 1);
  }

  function reveal_editor(i, errors) {
    var name = get_robot_name(i);
    $('#editor h2').text(name);
    if (errors) {
      alert('Error compiling ' + name + ":\n\n" + errors);
      $('#errors').show().text(errors);
    } else {
      $('#errors').hide().text(errors);
    }

    $('#editors textarea').slideUp();
    $('#editor').slideDown();
    $('#code' + i).slideDown();
  }

  _.each(_.range(ROBOT_SLOTS- 1), function(i) {  // Scope i correctly.

    // Create the drop-down menu.
    var select = $('<select/>').attr('id', 'choice' + i);
    select.append($('<option/>').text('Choose a robot...').attr('value', ''));
    for (var j = 0, group; group = ROBOT_CHOICES[j]; j++) {
      var optgroup = $('<optgroup/>').attr('label', group[0]);
      for (var k = 0, choice; choice = group[1][k]; k++) {
        optgroup.append($('<option/>').attr('value', choice[0]).text(choice[1]));
      }
      select.append(optgroup);
    }

    // Create the edit button.
    var edit_button = $('<button/>').text('Edit');

    // Add the menu and the edit button to the page.
    $('#choices ol').append($('<li/>').append(select, ' ', edit_button));

    // Create the robot code editor and add it to the page.
    var textarea = $('<textarea/>').attr('id', 'code' + i);
    textarea.hide();
    $('#editors').append(textarea);

    // Changing resets the bot choice to reflect "a custom bot."
    textarea.change(function() {
      select.val('');
      $('#editor h2').text(get_robot_name(i));
    });

    // Load robot code into the editor when a robot is selected.
    select.change(function() {
      var name = $(this).val();
      if (name) {
        var path = '/jsrobowar/robots/' + name + '.txt';
        textarea.val('(Loading ' + path + ')');
        textarea.attr('disabled', 'disabled');
        $.get(path, function(src) {
          textarea.val(src);
          textarea.attr('disabled', null);
        });
        // TODO: Hardware depot
      }
    });

    // Make the edit button show the editor.
    edit_button.click(function() {
      reveal_editor(i);
    });

    edit_button.hide();

  });

  // Hide the editor initially.
  $('#editor').hide();

  // Game initialization -----------------------------------------------------

  var game = new Game($('#arena')[0], $('#scoreboard')[0]);

  function load_robot(code, name, color) {
    var program = new Program();
    program.parse(code);
    if (program.errors) {
      alert(name + " failed to start\nReason:\n" +program.errors);
      // reveal_editor(i, program.errors);
      return;
    }

    var robot = new Robot(name, color, program);
    return robot;
  }
  function setup_game() {
    // Reset the robots and game state.
    game.clear();

    // Get tested robot code
    // Load each robot. Bail out if one doesn't compile.
    var tested_code = myCodeMirror.getValue();
    var robot_name = $('#robot_name').val();
    var robot = load_robot(tested_code, robot_name, ROBOT_COLORS[1]);
    game.add_robot(robot);
    _.each(_.range(ROBOT_SLOTS -1), function(i) {
      var code = $('#code' + i).val();

      var robot = load_robot(code, get_robot_name(i), ROBOT_COLORS[i]);
      game.add_robot(robot);
    });
  };

  // Play/pause button -------------------------------------------------------

  var show_start_button = function() {
    $('#start').show();
    $('#stop').hide();
  };

  $('#start').click(function(e) {
    e.preventDefault();
    setup_game();
    game.start(show_start_button);
    $(this).hide();
    $('#stop').show();
  });

  $('#stop').click(function(e) {
    e.preventDefault();
    game.stop();
    show_start_button();
  });

  show_start_button();

  // Sound-toggle button -----------------------------------------------------

  $('#sound').change(function() {
    SoundEffects.enable($(this).attr('checked'));
  }).change();

  // Auto-start demo mode ----------------------------------------------------

  $('#choice0').val('target-practice').change();
  $('#choice1').val('target-practice').change();
  $('#choice2').val('target-practice').change();

  //# _.delay(function() {$('#start').click()}, 600);

});
<|endoftext|>


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

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

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

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

  description: String,

  ideaboardName: String,

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

});

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

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

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

};

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

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

}

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

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

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

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

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

  description: String,

  ideaboardName: String,

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

});

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

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

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

};

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

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

}

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

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


<commit_before>import vtkWSLinkClient from 'vtk.js/Sources/IO/Core/WSLinkClient';
import SmartConnect from 'wslink/src/SmartConnect';
import vtkRemoteView from 'vtk.js/Sources/Rendering/Misc/RemoteView';

vtkWSLinkClient.setSmartConnectClass(SmartConnect);

document.body.style.padding = '0';
document.body.style.margin = '0';

const divRenderer = document.createElement('div');
document.body.appendChild(divRenderer);

divRenderer.style.position = 'relative';
divRenderer.style.width = '100vw';
divRenderer.style.height = '100vh';
divRenderer.style.overflow = 'hidden';

const clientToConnect = vtkWSLinkClient.newInstance();

// Error
clientToConnect.onConnectionError((httpReq) => {
  const message =
    (httpReq && httpReq.response && httpReq.response.error) ||
    `Connection error`;
  console.error(message);
  console.log(httpReq);
});

// Close
clientToConnect.onConnectionClose((httpReq) => {
  const message =
    (httpReq && httpReq.response && httpReq.response.error) ||
    `Connection close`;
  console.error(message);
  console.log(httpReq);
});

// hint: if you use the launcher.py and ws-proxy just leave out sessionURL
// (it will be provided by the launcher)
const config = {
  application: 'cone',
  sessionURL: 'ws://localhost:1234/ws',
};

// Connect
clientToConnect
  .connect(config)
  .then((validClient) => {
    const viewStream = this.clientToConnect
      .getImageStream()
      .createViewStream('-1');

    const view = vtkRemoteView.newInstance({
      rpcWheelEvent: 'viewport.mouse.zoom.wheel',
      viewStream,
    });
    const session = validClient.getConnection().getSession();
    view.setSession(session);
    view.setContainer(divRenderer);
    view.setInteractiveRatio(0.7); // the scaled image compared to the clients view resolution
    view.setInteractiveQuality(50); // jpeg quality

    window.addEventListener('resize', view.resize);
  })
  .catch((error) => {
    console.error(error);
  });
<commit_msg>docs(RemoteView): Fix typo in example<commit_after>import vtkWSLinkClient from 'vtk.js/Sources/IO/Core/WSLinkClient';
import SmartConnect from 'wslink/src/SmartConnect';
import vtkRemoteView from 'vtk.js/Sources/Rendering/Misc/RemoteView';

vtkWSLinkClient.setSmartConnectClass(SmartConnect);

document.body.style.padding = '0';
document.body.style.margin = '0';

const divRenderer = document.createElement('div');
document.body.appendChild(divRenderer);

divRenderer.style.position = 'relative';
divRenderer.style.width = '100vw';
divRenderer.style.height = '100vh';
divRenderer.style.overflow = 'hidden';

const clientToConnect = vtkWSLinkClient.newInstance();

// Error
clientToConnect.onConnectionError((httpReq) => {
  const message =
    (httpReq && httpReq.response && httpReq.response.error) ||
    `Connection error`;
  console.error(message);
  console.log(httpReq);
});

// Close
clientToConnect.onConnectionClose((httpReq) => {
  const message =
    (httpReq && httpReq.response && httpReq.response.error) ||
    `Connection close`;
  console.error(message);
  console.log(httpReq);
});

// hint: if you use the launcher.py and ws-proxy just leave out sessionURL
// (it will be provided by the launcher)
const config = {
  application: 'cone',
  sessionURL: 'ws://localhost:1234/ws',
};

// Connect
clientToConnect
  .connect(config)
  .then((validClient) => {
    const viewStream = clientToConnect.getImageStream().createViewStream('-1');

    const view = vtkRemoteView.newInstance({
      rpcWheelEvent: 'viewport.mouse.zoom.wheel',
      viewStream,
    });
    const session = validClient.getConnection().getSession();
    view.setSession(session);
    view.setContainer(divRenderer);
    view.setInteractiveRatio(0.7); // the scaled image compared to the clients view resolution
    view.setInteractiveQuality(50); // jpeg quality

    window.addEventListener('resize', view.resize);
  })
  .catch((error) => {
    console.error(error);
  });
<|endoftext|>


<commit_before>// when document loads
$(document).ready(function () {

  // get User
  var thisUser = this.User
  $.get('/api/whoami', function (data) {
    thisUser = data;
    if (typeof(thisUser.favoriteCourses) != 'undefined')
    {
      getFavorites();
    }
  })

  var getFavorites = function() {
    $('#favs').html('');
    // display favorites
    var toalert = '';
    for (var courseIndex in thisUser.favoriteCourses) {
      var favCourse = thisUser.favoriteCourses[courseIndex];
      toalert += favCourse + ' ';
      // Bensu TODO: append result into #favs list
    }
    alert("Favorite courses are :" + toalert);
  }

  // function for updating search results
  var getCourseData = function () {
    var query = {
      $text: {
        $search: $('#searchbox').val()
      },
      semester: $('#semester').val()
    }

    $.post('/api/courses',
    {
      query: JSON.stringify(query),
      sort: $('#sort').val()
    }, function (courses, status) {
      // Basic error handling
      if (status !== 'success') {
        window.alert('An error occured and your search could not be completed.')
      }

      // clear results
      $('#results').html('')
      $('#search-title').html('')

      $('#search-title').append(courses.length + ' Search Results')

      for (var courseIndex in courses) {
        var thisCourse = courses[courseIndex]

        // append result into results pane
        $('#results').append(newResultEntry(thisCourse))
        //$('#results')[0].appendChild(newResultEntry(thisCourse))

        // attach object to DOM element
        $('#results').children().last()[0].course = thisCourse
      }
    })
  }

  // function for displaying course details
  var dispCourseData = function() {
    $(".search-result").removeClass("active");
    $(this).addClass("active")

    $('#disp-title').html('')
    $('#disp-subtitle').html('')
    $('#disp-profs').html('')
    $('#disp-body').html('')
    $('#evals').html('')
    $('#comments').html('')

    var thisCourse = this.course

    // string for course listings
    var listings =  getListings(thisCourse)

    $('#disp-title').append(thisCourse.title)

    $('#disp-subtitle').append(listings + ' '
                            + (thisCourse.distribution == undefined ? '' : ' ' + thisCourse.distribution + '')
                            + (thisCourse.pdf["required"]  ? ' PDF ONLY'
                            : (thisCourse.pdf["permitted"] ? ' PDF'
                                                                   : ' NPDF'))
                            + (thisCourse.audit ? ' AUDIT' : '')
                            + ' Favorite'
                            + (thisCourse.website == undefined ? '' : ' '))

    //$('#comments').append(thisCourse.evaluations.studentComments)

    // stuff for course evaluations
    var evals = ""
    for (var field in thisCourse.evaluations.scores) {
      var val = thisCourse.evaluations.scores[field]
      evals += '
' + field + '
'
             + '

'
             + val.toFixed(2) + '

' // as percentage of 5
    }
    if (evals == "") {
      $('#evals').append('No course evaluations available.')
    }
    else {
      $('#evals').append(evals)
    }

    // stuff for student comments
    var comments = ""
    for (var studentComment in thisCourse.evaluations.studentComments) {
        var val = thisCourse.evaluations.studentComments[studentComment]
        comments += '
' + val + '
'
    }
    if (comments == "") {
      $('#comments').append('No student comments available.')
    }
    else {
      $('#comments').append(comments)
    }

    var dispbody = ''
    dispbody += '

' +
                '
' + thisCourse.description + '
'
                + (thisCourse.prerequisites == undefined ? '' :
                '
Prerequisites

' + thisCourse.prerequisites + '
')
                + (thisCourse.equivalentcourses == undefined ? '' :
                '
Equivalent Courses

' + thisCourse.equivalentcourses + '
')
                + (thisCourse.otherinformation == undefined ? '' :
                '
Other Information

' + thisCourse.otherinformation + '
')
                + (thisCourse.otherrequirements == undefined ? '' :
                '
Equivalent Courses

' + thisCourse.otherrequirements + '
')
                '
Classes

' + thisCourse.classes[0] + '
'

    var classes = ''
    for (var field in thisCourse.classes) {
      var val = thisCourse.classes[field]
      classes += '
'
              + '' + val['section'] + '	'
              + ''
      for (var day in val.schedule.meetings[0].days) {
        //classes += thisCourse.classes.schedule.meetings[0].days[day]
        classes += val.schedule.meetings[0].days[day] + ' '
      }
      classes += '	'
      classes += (val.schedule.meetings[0] == undefined ? '' :
                '' + (val.schedule.meetings[0].start_time == undefined ? '' :
                  val.schedule.meetings[0].start_time) + ' - '
                + (val.schedule.meetings[0].end_time == undefined ? '' :
                  val.schedule.meetings[0].end_time) + '	'
                + '' + (val.schedule.meetings[0].building == undefined ? '' :
                  val.schedule.meetings[0].building.short_name) + ' '
                + (val.schedule.meetings[0].room == undefined ? '' :
                  val.schedule.meetings[0].room) + '	'
              )
      classes += '' + val['enrollment'] + ' / ' + val['capacity'] + '	'
                + '' + val['status'] + '	'
                + '
'
    }
    dispbody += (classes == ''? '' :
                '
' +
                'Section	Days	Time	Room	Enrolled	Status	' +
                '
Classes
' + classes + '
')

    $('#disp-body').append(dispbody)

    for (var instructor in thisCourse.instructors) {
      var name = thisCourse.instructors[instructor].name['first'] + ' '
               + thisCourse.instructors[instructor].name['last']
        if ($('#disp-profs').html() !== '') {
          $('#disp-profs').append(', ')
        }
        $('#disp-profs').append(name)
    }

    // favorite a course
    $("#fav-button").click(function() {
      var thisCourseId = thisCourse._id;
      if (thisUser.favoriteCourses == undefined) {
        thisUser.favoriteCourses = [];
      }
      thisUser.favoriteCourses.push(thisCourseId);
      getFavorites();
    })
  }

  // Every time a key is pressed inside the #searchbox, call the getCourseData function
  $('#searchbox').keyup(getCourseData)
  $('#semester, #sort').change(getCourseData)

  // displays information in right pane on click of search result
  $('#results').on('click', 'a.search-result', dispCourseData)

  /* SEB' EXAMPLE

  // $('#results div').click(function () {
  //   console.log($(this).text())
  // })

  $('#results').on('click', 'div.course', function () {
    // window.alert('Handler for .click() called.')
    // console.log(this.course)
    window.alert('You just clicked on the course ' + this.course.title + '!')
  })

  */

  // feedback form toggling
  var toggleFeedback = function() {
   $('#feedback-form').slideToggle()
   if ($('#feedback-toggle').hasClass("active")) {
     $('#feedback-toggle').removeClass("active")
   } else {
     $('#feedback-toggle').addClass("active")
   }
 }

 $('#feedback-toggle').click(toggleFeedback)

  // load the semesters for the dropdown
  $.get('/api/semesters', function (semesters) {
    for (var semesterIndex in semesters) {
      var thisSemester = semesters[semesterIndex]
      $('#semester').append('<option value="' + thisSemester.code + '">' + thisSemester.name + '</select>')
    }
  })

  for (var i = 1.0; i < 5.05; i += 0.1) {
    $('#disp-body').append(''
      + i.toFixed(2)
      + '')
  }
  $('#disp-body').append('N/A')
})<commit_msg>very crudely functioning favoriting<commit_after>// when document loads
$(document).ready(function () {

  // get User
  var thisUser = this.User
  $.get('/api/whoami', function (data) {
    thisUser = data;
    if (typeof(thisUser.favoriteCourses) != 'undefined')
    {
      getFavorites();
    }
  })

  var dispFavorites = function() {
    $('#favs').html('');

    // call api to get favorites and display
    $.get('/api/user/favorites', function(courses) {
      for (var courseIndex in courses) {
        var thisCourse = courses[courseIndex];

        // append favorite into favs pane
        $('#favs').append(newResultEntry(thisCourse));

        // attach object to DOM element
        $('#favs').children().last()[0].course = thisCourse;
      }
    });
    /*
    // display favorites
    var toalert = '';
    for (var courseIndex in thisUser.favoriteCourses) {
      var favCourse = thisUser.favoriteCourses[courseIndex];
      toalert.append(favCourse + ' ');
      alert(favCourse);
      // Bensu TODO: append result into #favs list
    }
    alert("Favorite courses are :" + toalert);
    */
  }

  // function for updating search results
  var getCourseData = function () {
    var query = {
      $text: {
        $search: $('#searchbox').val()
      },
      semester: $('#semester').val()
    }

    $.post('/api/courses',
    {
      query: JSON.stringify(query),
      sort: $('#sort').val()
    }, function (courses, status) {
      // Basic error handling
      if (status !== 'success') {
        window.alert('An error occured and your search could not be completed.')
      }

      // clear results
      $('#results').html('')
      $('#search-title').html('')

      $('#search-title').append(courses.length + ' Search Results')

      for (var courseIndex in courses) {
        var thisCourse = courses[courseIndex]

        // append result into results pane
        $('#results').append(newResultEntry(thisCourse))
        //$('#results')[0].appendChild(newResultEntry(thisCourse))

        // attach object to DOM element
        $('#results').children().last()[0].course = thisCourse
      }
    })
  }

  // function for displaying course details
  var dispCourseData = function() {
    $(".search-result").removeClass("active");
    $(this).addClass("active")

    $('#disp-title').html('')
    $('#disp-subtitle').html('')
    $('#disp-profs').html('')
    $('#disp-body').html('')
    $('#evals').html('')
    $('#comments').html('')

    var thisCourse = this.course

    // string for course listings
    var listings =  getListings(thisCourse)

    $('#disp-title').append(thisCourse.title)

    $('#disp-subtitle').append(listings + ' '
                            + (thisCourse.distribution == undefined ? '' : ' ' + thisCourse.distribution + '')
                            + (thisCourse.pdf["required"]  ? ' PDF ONLY'
                            : (thisCourse.pdf["permitted"] ? ' PDF'
                                                                   : ' NPDF'))
                            + (thisCourse.audit ? ' AUDIT' : '')
                            + ' Favorite'
                            + (thisCourse.website == undefined ? '' : ' '))

    $('#fav-button')[0].course = thisCourse;

    //$('#comments').append(thisCourse.evaluations.studentComments)

    // stuff for course evaluations
    var evals = ""
    for (var field in thisCourse.evaluations.scores) {
      var val = thisCourse.evaluations.scores[field]
      evals += '
' + field + '
'
             + '

'
             + val.toFixed(2) + '

' // as percentage of 5
    }
    if (evals == "") {
      $('#evals').append('No course evaluations available.')
    }
    else {
      $('#evals').append(evals)
    }

    // stuff for student comments
    var comments = ""
    for (var studentComment in thisCourse.evaluations.studentComments) {
        var val = thisCourse.evaluations.studentComments[studentComment]
        comments += '
' + val + '
'
    }
    if (comments == "") {
      $('#comments').append('No student comments available.')
    }
    else {
      $('#comments').append(comments)
    }

    var dispbody = ''
    dispbody += '

' +
                '
' + thisCourse.description + '
'
                + (thisCourse.prerequisites == undefined ? '' :
                '
Prerequisites

' + thisCourse.prerequisites + '
')
                + (thisCourse.equivalentcourses == undefined ? '' :
                '
Equivalent Courses

' + thisCourse.equivalentcourses + '
')
                + (thisCourse.otherinformation == undefined ? '' :
                '
Other Information

' + thisCourse.otherinformation + '
')
                + (thisCourse.otherrequirements == undefined ? '' :
                '
Equivalent Courses

' + thisCourse.otherrequirements + '
')
                '
Classes

' + thisCourse.classes[0] + '
'

    var classes = ''
    for (var field in thisCourse.classes) {
      var val = thisCourse.classes[field]
      classes += '
'
              + '' + val['section'] + '	'
              + ''
      for (var day in val.schedule.meetings[0].days) {
        //classes += thisCourse.classes.schedule.meetings[0].days[day]
        classes += val.schedule.meetings[0].days[day] + ' '
      }
      classes += '	'
      classes += (val.schedule.meetings[0] == undefined ? '' :
                '' + (val.schedule.meetings[0].start_time == undefined ? '' :
                  val.schedule.meetings[0].start_time) + ' - '
                + (val.schedule.meetings[0].end_time == undefined ? '' :
                  val.schedule.meetings[0].end_time) + '	'
                + '' + (val.schedule.meetings[0].building == undefined ? '' :
                  val.schedule.meetings[0].building.short_name) + ' '
                + (val.schedule.meetings[0].room == undefined ? '' :
                  val.schedule.meetings[0].room) + '	'
              )
      classes += '' + val['enrollment'] + ' / ' + val['capacity'] + '	'
                + '' + val['status'] + '	'
                + '
'
    }
    dispbody += (classes == ''? '' :
                '
' +
                'Section	Days	Time	Room	Enrolled	Status	' +
                '
Classes
' + classes + '
')

    $('#disp-body').append(dispbody)

    for (var instructor in thisCourse.instructors) {
      var name = thisCourse.instructors[instructor].name['first'] + ' '
               + thisCourse.instructors[instructor].name['last']
        if ($('#disp-profs').html() !== '') {
          $('#disp-profs').append(', ')
        }
        $('#disp-profs').append(name)
    }

    // favorite a course
    $("#fav-button").click(function() {
      var thisCourseId = this.course["_id"];

      // update database
      $.ajax({
        url: '/api/user/favorite',
        type: 'PUT',
        data: {'course': thisCourseId},
        success: function() {dispFavorites();}
      });
    })
    /*
    $.ajax({
      url: '/api/user/favorite/',
      type: 'PUT',
      data: {course: $('#results').children()[0].course},
      success: function (arg, status) {console.log(arg);}})*/
  }

  // Every time a key is pressed inside the #searchbox, call the getCourseData function
  $('#searchbox').keyup(getCourseData)
  $('#semester, #sort').change(getCourseData)

  // displays information in right pane on click of search result
  $('#results').on('click', 'a.search-result', dispCourseData)
  $('#favs').on('click', 'a.search-result', dispCourseData)

  /* SEB' EXAMPLE

  // $('#results div').click(function () {
  //   console.log($(this).text())
  // })

  $('#results').on('click', 'div.course', function () {
    // window.alert('Handler for .click() called.')
    // console.log(this.course)
    window.alert('You just clicked on the course ' + this.course.title + '!')
  })

  */

  // feedback form toggling
  var toggleFeedback = function() {
   $('#feedback-form').slideToggle()
   if ($('#feedback-toggle').hasClass("active")) {
     $('#feedback-toggle').removeClass("active")
   } else {
     $('#feedback-toggle').addClass("active")
   }
 }

 $('#feedback-toggle').click(toggleFeedback)

  // load the semesters for the dropdown
  $.get('/api/semesters', function (semesters) {
    for (var semesterIndex in semesters) {
      var thisSemester = semesters[semesterIndex]
      $('#semester').append('<option value="' + thisSemester.code + '">' + thisSemester.name + '</select>')
    }
  })

  for (var i = 1.0; i < 5.05; i += 0.1) {
    $('#disp-body').append(''
      + i.toFixed(2)
      + '')
  }
  $('#disp-body').append('N/A')

  dispFavorites();
})
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var argscheck = cordova.require('cordova/argscheck');
var Event = require('org.chromium.common.events');
var stubs = require('org.chromium.common.stubs');

var manifestJson;

exports.onSuspend = new Event('onSuspend');
exports.onInstalled = new Event('onInstalled');
exports.onStartup = new Event('onStartup');
exports.onSuspendCanceled = new Event('onSuspendCanceled');
exports.onUpdateAvailable = new Event('onUpdateAvailable');
//exports.onBrowserUpdateAvailable = new Event('onBrowserUpdateAvailable');
//exports.onConnect = new Event('onConnect');
//exports.onConnectExternal = new Event('onConnectExternal');
//exports.onMessage = new Event('onMessage');
//exports.onMessageExternal = new Event('onMessageExternal');

// Uses a trampoline to bind the Cordova pause event on the first call.
var original_onSuspend_addListener = exports.onSuspend.addListener;
exports.onSuspend.addListener = function(f) {
  window.document.addEventListener('pause', function() {
    retval = exports.onSuspend.fire.apply(exports.onSuspend, arguments);
    chrome.storage.internal.set({"shutdownClean":true});
    return retval;
  }, false);
  exports.onSuspend.addListener = original_onSuspend_addListener;
  exports.onSuspend.addListener(f);
};

// Uses a trampoline to bind the Cordova resume event on the first call.
var original_onSuspendCanceled_addListener = exports.onSuspendCanceled.addListener;
exports.onSuspendCanceled.addListener = function(f) {
  window.document.addEventListener('resume', function() {
    chrome.storage.internal.remove("shutdownClean");
    return exports.onSuspendCanceled.fire.apply(exports.onSuspendCanceled, arguments);
  }, false);
  exports.onSuspendCanceled.addListener = original_onSuspendCanceled_addListener;
  exports.onSuspendCanceled.addListener(f);
};

exports.getManifest = function() {
  if (typeof manifestJson == 'undefined') {
    var xhr = new XMLHttpRequest();
    // This is a bit fragile - determine path by whether chromeapp.html is in the URL.
    var path = /chromeapp\.html$/.exec(location.href) ? '../../manifest.json' : 'manifest.json';
    xhr.open('GET', path, false);
    xhr.send(null);
    if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
      // Don't use JSON.parse, since it fails on comments.
      manifestJson = eval('(' + xhr.responseText + ')');
    } else {
      manifestJson = null;
    }
  }
  return manifestJson;
};

// This is an extension for vanilla cordova apps
exports.setManifest = function(manifest) {
  manifestJson = manifest;
  cachedAppId = null;
}

exports.getBackgroundPage = function(callback) {
  try {
    var mobile = require('org.chromium.bootstrap.mobile.impl');
  } catch(e) {}
  argscheck.checkArgs('f', 'chrome.runtime.getBackgroundPage', arguments);
  setTimeout(function() {
    callback(typeof mobile !== 'undefined' ? mobile.bgWindow : undefined);
  }, 0);
};

// Returns a URL relative to the root of the project.
exports.getURL = function(subResource) {
  argscheck.checkArgs('s', 'chrome.runtime.getURL', arguments);
  if (subResource.charAt(0) == '/') {
    subResource = subResource.slice(1);
  }
  return 'chrome-extension://' + getAppId() + '/' + subResource;
};

var origLocation = location.href;
exports.reload = function() {
  history.replaceState(null, null, origLocation);
  location.reload();
};

function getCrypto() {
  var ret = require('./CryptoJS-sha256');
  require('./CryptoJS-enc-base64-min'); // just need to make sure this runs
  return ret;
}

function hexToMPDecimal(hex) {
  var hexToMPDecimalLookupTable = {
    0:'a', 1:'b', 2:'c', 3:'d',
    4:'e', 5:'f', 6:'g', 7:'h',
    8:'i', 9:'j', a:'k', b:'l',
    c:'m', d:'n', e:'o', f:'p',
  };
  return Array.prototype.map.call(hex, function(c) { return hexToMPDecimalLookupTable[c]; }).join('');
}

function mapAppNameToAppId (name) {
  var CryptoJS = getCrypto();
  var idInHex = CryptoJS.SHA256(name).toString(CryptoJS.enc.Hex).slice(0,32).toLowerCase();
  var idInMPDecimal = hexToMPDecimal(idInHex);
  return idInMPDecimal;
}

function mapAppKeyToAppId(key) {
  var CryptoJS = getCrypto();
  // See http://stackoverflow.com/questions/1882981/google-chrome-alphanumeric-hashes-to-identify-extensions/2050916#2050916
  return mapAppNameToAppId(CryptoJS.enc.Base64.parse(key))
}

var cachedAppId = null;
function getAppId() {
  if (!cachedAppId) {
    var manifest = exports.getManifest();
    if (manifest) {
      var key = manifest['key'];
      if (typeof key === 'undefined') {
        // For development, we want a consistent ID even without a public key.  Chrome uses the app path instead of name.
        cachedAppId = mapAppNameToAppId(manifest['name']);
      } else {
        try {
          cachedAppId = mapAppKeyToAppId(key);
        } catch (e) {
          // If you are a Chrome App, and you do have a key in your manifest, and its invalid, we shouldn't pretend to return a valid appId
          console.error('Your manifest file has an invalid \'key\', cannot produce application id.');
          // leaving appId undefined.
        }
      }
    } else {
      // TODO: return fully qualified name given during cordova project creation
      cachedAppId = manifest['name'];
    }
  }
  return cachedAppId;
}
exports.__defineGetter__("id", getAppId);

exports.getPlatformInfo = function(callback) {
  var platformInfo = {};
  platformInfo.os = 'cordova-' + cordova.platformId;

  // The other two expected members do not apply meaningfully here.
  // TODO(maxw): Or do they?
  platformInfo.arch = null;
  platformInfo.nacl_arch = null;

  // Send the platform info to the callback.
  callback(platformInfo);
};

stubs.createStub(exports, 'requestUpdateCheck', function(){});
<commit_msg>Fixed an NPE when getting an app id.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var argscheck = cordova.require('cordova/argscheck');
var Event = require('org.chromium.common.events');
var stubs = require('org.chromium.common.stubs');

var manifestJson;

exports.onSuspend = new Event('onSuspend');
exports.onInstalled = new Event('onInstalled');
exports.onStartup = new Event('onStartup');
exports.onSuspendCanceled = new Event('onSuspendCanceled');
exports.onUpdateAvailable = new Event('onUpdateAvailable');
//exports.onBrowserUpdateAvailable = new Event('onBrowserUpdateAvailable');
//exports.onConnect = new Event('onConnect');
//exports.onConnectExternal = new Event('onConnectExternal');
//exports.onMessage = new Event('onMessage');
//exports.onMessageExternal = new Event('onMessageExternal');

// Uses a trampoline to bind the Cordova pause event on the first call.
var original_onSuspend_addListener = exports.onSuspend.addListener;
exports.onSuspend.addListener = function(f) {
  window.document.addEventListener('pause', function() {
    retval = exports.onSuspend.fire.apply(exports.onSuspend, arguments);
    chrome.storage.internal.set({"shutdownClean":true});
    return retval;
  }, false);
  exports.onSuspend.addListener = original_onSuspend_addListener;
  exports.onSuspend.addListener(f);
};

// Uses a trampoline to bind the Cordova resume event on the first call.
var original_onSuspendCanceled_addListener = exports.onSuspendCanceled.addListener;
exports.onSuspendCanceled.addListener = function(f) {
  window.document.addEventListener('resume', function() {
    chrome.storage.internal.remove("shutdownClean");
    return exports.onSuspendCanceled.fire.apply(exports.onSuspendCanceled, arguments);
  }, false);
  exports.onSuspendCanceled.addListener = original_onSuspendCanceled_addListener;
  exports.onSuspendCanceled.addListener(f);
};

exports.getManifest = function() {
  if (typeof manifestJson == 'undefined') {
    var xhr = new XMLHttpRequest();
    // This is a bit fragile - determine path by whether chromeapp.html is in the URL.
    var path = /chromeapp\.html$/.exec(location.href) ? '../../manifest.json' : 'manifest.json';
    xhr.open('GET', path, false);
    xhr.send(null);
    if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
      // Don't use JSON.parse, since it fails on comments.
      manifestJson = eval('(' + xhr.responseText + ')');
    } else {
      manifestJson = null;
    }
  }
  return manifestJson;
};

// This is an extension for vanilla cordova apps
exports.setManifest = function(manifest) {
  manifestJson = manifest;
  cachedAppId = null;
}

exports.getBackgroundPage = function(callback) {
  try {
    var mobile = require('org.chromium.bootstrap.mobile.impl');
  } catch(e) {}
  argscheck.checkArgs('f', 'chrome.runtime.getBackgroundPage', arguments);
  setTimeout(function() {
    callback(typeof mobile !== 'undefined' ? mobile.bgWindow : undefined);
  }, 0);
};

// Returns a URL relative to the root of the project.
exports.getURL = function(subResource) {
  argscheck.checkArgs('s', 'chrome.runtime.getURL', arguments);
  if (subResource.charAt(0) == '/') {
    subResource = subResource.slice(1);
  }
  return 'chrome-extension://' + getAppId() + '/' + subResource;
};

var origLocation = location.href;
exports.reload = function() {
  history.replaceState(null, null, origLocation);
  location.reload();
};

function getCrypto() {
  var ret = require('./CryptoJS-sha256');
  require('./CryptoJS-enc-base64-min'); // just need to make sure this runs
  return ret;
}

function hexToMPDecimal(hex) {
  var hexToMPDecimalLookupTable = {
    0:'a', 1:'b', 2:'c', 3:'d',
    4:'e', 5:'f', 6:'g', 7:'h',
    8:'i', 9:'j', a:'k', b:'l',
    c:'m', d:'n', e:'o', f:'p',
  };
  return Array.prototype.map.call(hex, function(c) { return hexToMPDecimalLookupTable[c]; }).join('');
}

function mapAppNameToAppId (name) {
  var CryptoJS = getCrypto();
  var idInHex = CryptoJS.SHA256(name).toString(CryptoJS.enc.Hex).slice(0,32).toLowerCase();
  var idInMPDecimal = hexToMPDecimal(idInHex);
  return idInMPDecimal;
}

function mapAppKeyToAppId(key) {
  var CryptoJS = getCrypto();
  // See http://stackoverflow.com/questions/1882981/google-chrome-alphanumeric-hashes-to-identify-extensions/2050916#2050916
  return mapAppNameToAppId(CryptoJS.enc.Base64.parse(key))
}

var cachedAppId = null;
function getAppId() {
  if (!cachedAppId) {
    var manifest = exports.getManifest();
    if (manifest) {
      var key = manifest['key'];
      if (typeof key === 'undefined') {
        // For development, we want a consistent ID even without a public key.  Chrome uses the app path instead of name.
        cachedAppId = mapAppNameToAppId(manifest['name']);
      } else {
        try {
          cachedAppId = mapAppKeyToAppId(key);
        } catch (e) {
          // If you are a Chrome App, and you do have a key in your manifest, and its invalid, we shouldn't pretend to return a valid appId
          console.error('Your manifest file has an invalid \'key\', cannot produce application id.');
          // leaving appId undefined.
        }
      }
    } else {
      // For now, create an app id based on an empty name.
      // This means we yield same app id for any app without a manifest.
      // TODO: Retrieve the package id from config.xml and use that.
      cachedAppId = mapAppNameToAppId('');
    }
  }
  return cachedAppId;
}
exports.__defineGetter__("id", getAppId);

exports.getPlatformInfo = function(callback) {
  var platformInfo = {};
  platformInfo.os = 'cordova-' + cordova.platformId;

  // The other two expected members do not apply meaningfully here.
  // TODO(maxw): Or do they?
  platformInfo.arch = null;
  platformInfo.nacl_arch = null;

  // Send the platform info to the callback.
  callback(platformInfo);
};

stubs.createStub(exports, 'requestUpdateCheck', function(){});
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to you 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.
 */

App.Helpers.jobs = {

  /**
   * Refreshes the latest information for a given job
   *
   * @param {App.AbstractJob} job
   * @param {Function} successCallback
   * @param {Function} errorCallback (errorId) Called in error cases where there is no
   *          data from server. 'errorId' can be one of
   *

   *
job.dag.noId

   *
job.dag.noname

   *
job.dag.id.noDag

   *
job.dag.id.loaderror

   *
job.dag.name.loaderror

   *

   */
  refreshJobDetails: function (job, successCallback, errorCallback) {
    this.refreshHiveJobDetails(job, successCallback, errorCallback);
  },

  /**
   * Refreshes latest information of a Hive Job.
   *
   * @param {App.HiveJob} hiveJob
   * @param {Function} successCallback
   * @param {Function} errorCallback @see #refreshJobDetails()
   * @method refreshHiveJobDetails
   */
  refreshHiveJobDetails: function (hiveJob, successCallback, errorCallback) {
    var  atsURL = App.get('atsURL') || 'http://' + App.HiveJob.store.getById('component', 'APP_TIMELINE_SERVER').get('hostName') +
        ':' + App.HiveJob.store.getById('service', 'YARN').get('ahsWebPort');

    return App.ajax.send({
      name: 'job_details',
      sender: this,
      data: {
        atsURL: atsURL,
        job_id: hiveJob.get('id'),
        successCallback: successCallback,
        errorCallback: errorCallback
      },
      success: 'refreshHiveJobDetailsSuccessCallback'
    });

  },

  refreshHiveJobDetailsSuccessCallback: function (data, opt, params) {
    App.hiveJobMapper.map(data);
    var hiveRecord = App.HiveJob.store.getById('hiveJob', params.job_id),
      tezDagName = hiveRecord.get('tezDag.name'),
      self = this;
    if (!Em.isNone(tezDagName)) {
      var sender = {
        dagNameToIdSuccess: function (data) {
          if (data && data.entities && data.entities.length > 0) {
            var dagId = data.entities[0].entity;
            hiveRecord.get('tezDag').set('instanceId', dagId);
            self.refreshTezDagDetails(tezDagName, params.successCallback, params.errorCallback);
          }
          else {
            params.errorCallback('job.dag.noId');
          }
        },
        dagNameToIdError: function () {
          params.errorCallback('job.dag.name.loaderror');
        }
      };
      App.ajax.send({
        name: 'jobs.tezDag.NametoID',
        sender: sender,
        data: {
          atsURL: params.atsURL,
          tezDagName: tezDagName,
          view: App.get("view"),
          version: App.get("version"),
          instanceName: App.get("instanceName")
        },
        success: 'dagNameToIdSuccess',
        error: 'dagNameToIdError'
      });
    }
    else {
      params.errorCallback('job.dag.noname');
    }
  },

  /**
   * Refreshes runtime information of a Tez DAG based on events generated.
   * The instance ID of the Tez DAG should be set.
   *
   * @param {string} tezDagId ID of the Tez DAG. Example: 'HIVE-Q2:1'
   * @param {Function} successCallback
   * @param {Function} errorCallback @see #refreshJobDetails()
   * @method refreshTezDagDetails
   */
  refreshTezDagDetails: function (tezDagId, successCallback, errorCallback) {
    var self = this,
        atsURL = App.get('atsURL') || 'http://' + App.HiveJob.store.getById('component', 'RESOURCEMANAGER').get('hostName') + ':' + App.HiveJob.store.getById('service', 'YARN').get('ahsWebPort'),
        resourceManager = App.HiveJob.store.getById('component', 'RESOURCEMANAGER'),
        resourceManagerHostName = App.get('resourceManagerURL') || (resourceManager && 'http://' + resourceManager.get('hostName') + ':8088') || '',
        tezDag = App.HiveJob.store.getById('tezDag', tezDagId);
    if (tezDag) {
      var tezDagInstanceId = tezDag.get('instanceId'),
          sender = {
            loadTezDagSuccess: function (data) {
              if (data) {
                var app_id = Em.get(data, 'otherinfo.applicationId');
                if (app_id && resourceManagerHostName) {
                  tezDag.set('yarnApplicationId', app_id);
                  tezDag.set('yarnApplicationLink', resourceManagerHostName + '/cluster/app/' + app_id);
                }
                if (data.relatedentities && data.relatedentities.TEZ_VERTEX_ID != null) {
                  var count = data.relatedentities.TEZ_VERTEX_ID.length;
                  data.relatedentities.TEZ_VERTEX_ID.forEach(function (v) {
                    self.refreshTezDagVertex(tezDagId, v, function () {
                      if (--count <= 0) {
                        // all vertices succeeded
                        successCallback();
                      }
                    });
                  });
                }
              }
            },
            loadTezDagError: function () {
              errorCallback('job.dag.id.loaderror');
            }
          };
      App.ajax.send({
        name: 'jobs.tezDag.tezDagId',
        sender: sender,
        data: {
          tezDagId: tezDagInstanceId,
          atsURL: atsURL,
          view: App.get("view"),
          version: App.get("version"),
          instanceName: App.get("instanceName")
        },
        success: 'loadTezDagSuccess',
        error: 'loadTezDagError'
      });
    }
    else {
      errorCallback('job.dag.id.noDag');
    }
  },

  /**
   * Refreshes runtime information of the given vertex.
   *
   * @param {string} tezDagId ID of the Tez DAG. Exmaple: 'HIVE-Q2:1'
   * @param {string} tezVertexInstanceId Instance ID of the vertex to refresh. Example 'vertex_1390516007863_0001_1_00'
   * @param {Function} successCallback
   * @method refreshTezDagVertex
   */
  refreshTezDagVertex: function (tezDagId, tezVertexInstanceId, successCallback) {
    var atsURL = App.get('atsURL') || 'http://' + App.HiveJob.store.getById('component', 'APP_TIMELINE_SERVER').get('hostName') + ':' + App.HiveJob.store.getById('service', 'YARN').get('ahsWebPort'),
      tezDag = App.HiveJob.store.getById('tezDag', tezDagId),
      hiveJob = App.HiveJob.store.all('hiveJob').findBy('tezDag', tezDag),
      hiveJobFailed = hiveJob.get('failed'),
      hiveJobEndTime = hiveJob.get('endTime'),
      sender = {
        loadTezDagVertexSuccess: function (data) {
          if (data && data.otherinfo) {
            var vertexRecord = App.HiveJob.store.getById('tezDagVertex', tezDagId + "/" + data.otherinfo.vertexName);
            if (vertexRecord != null) {
              vertexRecord.set('startTime', data.otherinfo.startTime);
              if (data.otherinfo.endTime == undefined && hiveJobFailed) {
                vertexRecord.set('endTime', hiveJobEndTime);
              }
              else {
                vertexRecord.set('endTime', data.otherinfo.endTime);
              }
              vertexRecord.set('tasksCount', data.otherinfo.numTasks);
              if (data.otherinfo.status == null && hiveJobFailed) {
                vertexRecord.set('state', Em.I18n.t('jobs.hive.failed'));
              }
              else {
                vertexRecord.set('state', data.otherinfo.status);
              }
              if (data.otherinfo.counters && data.otherinfo.counters.counterGroups) {
                data.otherinfo.counters.counterGroups.forEach(function (cGroup) {
                  var cNameToPropetyMap = {};
                  switch (cGroup.counterGroupName) {
                    case 'org.apache.tez.common.counters.FileSystemCounter':
                      cNameToPropetyMap = {
                        'FILE_BYTES_READ': 'fileReadBytes',
                        'FILE_BYTES_WRITTEN': 'fileWriteBytes',
                        'FILE_READ_OPS': 'fileReadOps',
                        'FILE_WRITE_OPS': 'fileWriteOps',
                        'HDFS_BYTES_READ': 'hdfsReadBytes',
                        'HDFS_BYTES_WRITTEN': 'hdfsWriteBytes',
                        'HDFS_READ_OPS': 'hdfsReadOps',
                        'HDFS_WRITE_OPS': 'hdfsWriteOps'
                      };
                      break;
                    case 'org.apache.tez.common.counters.TaskCounter':
                      cNameToPropetyMap = {
                        'SPILLED_RECORDS': 'spilledRecords'
                      };
                      break;
                    case 'HIVE':
                      cNameToPropetyMap = {
                        'RECORDS_READ': 'recordReadCount',
                        'RECORDS_WRITE': 'recordWriteCount'
                      };
                      break;
                    default:
                      break;
                  }
                  if (cGroup.counters) {
                    cGroup.counters.forEach(function (counter) {
                      var prop = cNameToPropetyMap[counter.counterName];
                      if (prop != null) {
                        vertexRecord.set(prop, counter.counterValue);
                      }
                    });
                  }
                });
              }
              successCallback();
            }
          }
        },
        loadTezDagVertexError: function (jqXHR, url, method, showStatus) {}
      };
    App.ajax.send({
      name: 'jobs.tezDag.tezDagVertexId',
      sender: sender,
      data: {
        atsURL: atsURL,
        tezDagVertexId: tezVertexInstanceId,
        view: App.get("view"),
        version: App.get("version"),
        instanceName: App.get("instanceName")
      },
      success: 'loadTezDagVertexSuccess',
      error: 'loadTezDagVertexError'
    });
  }
};
<commit_msg>AMBARI-7566. Jobs view does not load query info - shows 404 error (alejandro)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to you 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.
 */

App.Helpers.jobs = {

  /**
   * Refreshes the latest information for a given job
   *
   * @param {App.AbstractJob} job
   * @param {Function} successCallback
   * @param {Function} errorCallback (errorId) Called in error cases where there is no
   *          data from server. 'errorId' can be one of
   *

   *
job.dag.noId

   *
job.dag.noname

   *
job.dag.id.noDag

   *
job.dag.id.loaderror

   *
job.dag.name.loaderror

   *

   */
  refreshJobDetails: function (job, successCallback, errorCallback) {
    this.refreshHiveJobDetails(job, successCallback, errorCallback);
  },

  /**
   * Refreshes latest information of a Hive Job.
   *
   * @param {App.HiveJob} hiveJob
   * @param {Function} successCallback
   * @param {Function} errorCallback @see #refreshJobDetails()
   * @method refreshHiveJobDetails
   */
  refreshHiveJobDetails: function (hiveJob, successCallback, errorCallback) {
    var  atsURL = App.get('atsURL') || 'http://' + App.HiveJob.store.getById('component', 'APP_TIMELINE_SERVER').get('hostName') +
        ':' + App.HiveJob.store.getById('service', 'YARN').get('ahsWebPort');

    return App.ajax.send({
      name: 'job_details',
      sender: this,
      data: {
        atsURL: atsURL,
        job_id: hiveJob.get('id'),
        view: App.get("view"),
        version: App.get("version"),
        instanceName: App.get("instanceName"),
        successCallback: successCallback,
        errorCallback: errorCallback
      },
      success: 'refreshHiveJobDetailsSuccessCallback'
    });

  },

  refreshHiveJobDetailsSuccessCallback: function (data, opt, params) {
    App.hiveJobMapper.map(data);
    var hiveRecord = App.HiveJob.store.getById('hiveJob', params.job_id),
      tezDagName = hiveRecord.get('tezDag.name'),
      self = this;
    if (!Em.isNone(tezDagName)) {
      var sender = {
        dagNameToIdSuccess: function (data) {
          if (data && data.entities && data.entities.length > 0) {
            var dagId = data.entities[0].entity;
            hiveRecord.get('tezDag').set('instanceId', dagId);
            self.refreshTezDagDetails(tezDagName, params.successCallback, params.errorCallback);
          }
          else {
            params.errorCallback('job.dag.noId');
          }
        },
        dagNameToIdError: function () {
          params.errorCallback('job.dag.name.loaderror');
        }
      };
      App.ajax.send({
        name: 'jobs.tezDag.NametoID',
        sender: sender,
        data: {
          atsURL: params.atsURL,
          tezDagName: tezDagName,
          view: App.get("view"),
          version: App.get("version"),
          instanceName: App.get("instanceName")
        },
        success: 'dagNameToIdSuccess',
        error: 'dagNameToIdError'
      });
    }
    else {
      params.errorCallback('job.dag.noname');
    }
  },

  /**
   * Refreshes runtime information of a Tez DAG based on events generated.
   * The instance ID of the Tez DAG should be set.
   *
   * @param {string} tezDagId ID of the Tez DAG. Example: 'HIVE-Q2:1'
   * @param {Function} successCallback
   * @param {Function} errorCallback @see #refreshJobDetails()
   * @method refreshTezDagDetails
   */
  refreshTezDagDetails: function (tezDagId, successCallback, errorCallback) {
    var self = this,
        atsURL = App.get('atsURL') || 'http://' + App.HiveJob.store.getById('component', 'RESOURCEMANAGER').get('hostName') + ':' + App.HiveJob.store.getById('service', 'YARN').get('ahsWebPort'),
        resourceManager = App.HiveJob.store.getById('component', 'RESOURCEMANAGER'),
        resourceManagerHostName = App.get('resourceManagerURL') || (resourceManager && 'http://' + resourceManager.get('hostName') + ':8088') || '',
        tezDag = App.HiveJob.store.getById('tezDag', tezDagId);
    if (tezDag) {
      var tezDagInstanceId = tezDag.get('instanceId'),
          sender = {
            loadTezDagSuccess: function (data) {
              if (data) {
                var app_id = Em.get(data, 'otherinfo.applicationId');
                if (app_id && resourceManagerHostName) {
                  tezDag.set('yarnApplicationId', app_id);
                  tezDag.set('yarnApplicationLink', resourceManagerHostName + '/cluster/app/' + app_id);
                }
                if (data.relatedentities && data.relatedentities.TEZ_VERTEX_ID != null) {
                  var count = data.relatedentities.TEZ_VERTEX_ID.length;
                  data.relatedentities.TEZ_VERTEX_ID.forEach(function (v) {
                    self.refreshTezDagVertex(tezDagId, v, function () {
                      if (--count <= 0) {
                        // all vertices succeeded
                        successCallback();
                      }
                    });
                  });
                }
              }
            },
            loadTezDagError: function () {
              errorCallback('job.dag.id.loaderror');
            }
          };
      App.ajax.send({
        name: 'jobs.tezDag.tezDagId',
        sender: sender,
        data: {
          tezDagId: tezDagInstanceId,
          atsURL: atsURL,
          view: App.get("view"),
          version: App.get("version"),
          instanceName: App.get("instanceName")
        },
        success: 'loadTezDagSuccess',
        error: 'loadTezDagError'
      });
    }
    else {
      errorCallback('job.dag.id.noDag');
    }
  },

  /**
   * Refreshes runtime information of the given vertex.
   *
   * @param {string} tezDagId ID of the Tez DAG. Exmaple: 'HIVE-Q2:1'
   * @param {string} tezVertexInstanceId Instance ID of the vertex to refresh. Example 'vertex_1390516007863_0001_1_00'
   * @param {Function} successCallback
   * @method refreshTezDagVertex
   */
  refreshTezDagVertex: function (tezDagId, tezVertexInstanceId, successCallback) {
    var atsURL = App.get('atsURL') || 'http://' + App.HiveJob.store.getById('component', 'APP_TIMELINE_SERVER').get('hostName') + ':' + App.HiveJob.store.getById('service', 'YARN').get('ahsWebPort'),
      tezDag = App.HiveJob.store.getById('tezDag', tezDagId),
      hiveJob = App.HiveJob.store.all('hiveJob').findBy('tezDag', tezDag),
      hiveJobFailed = hiveJob.get('failed'),
      hiveJobEndTime = hiveJob.get('endTime'),
      sender = {
        loadTezDagVertexSuccess: function (data) {
          if (data && data.otherinfo) {
            var vertexRecord = App.HiveJob.store.getById('tezDagVertex', tezDagId + "/" + data.otherinfo.vertexName);
            if (vertexRecord != null) {
              vertexRecord.set('startTime', data.otherinfo.startTime);
              if (data.otherinfo.endTime == undefined && hiveJobFailed) {
                vertexRecord.set('endTime', hiveJobEndTime);
              }
              else {
                vertexRecord.set('endTime', data.otherinfo.endTime);
              }
              vertexRecord.set('tasksCount', data.otherinfo.numTasks);
              if (data.otherinfo.status == null && hiveJobFailed) {
                vertexRecord.set('state', Em.I18n.t('jobs.hive.failed'));
              }
              else {
                vertexRecord.set('state', data.otherinfo.status);
              }
              if (data.otherinfo.counters && data.otherinfo.counters.counterGroups) {
                data.otherinfo.counters.counterGroups.forEach(function (cGroup) {
                  var cNameToPropetyMap = {};
                  switch (cGroup.counterGroupName) {
                    case 'org.apache.tez.common.counters.FileSystemCounter':
                      cNameToPropetyMap = {
                        'FILE_BYTES_READ': 'fileReadBytes',
                        'FILE_BYTES_WRITTEN': 'fileWriteBytes',
                        'FILE_READ_OPS': 'fileReadOps',
                        'FILE_WRITE_OPS': 'fileWriteOps',
                        'HDFS_BYTES_READ': 'hdfsReadBytes',
                        'HDFS_BYTES_WRITTEN': 'hdfsWriteBytes',
                        'HDFS_READ_OPS': 'hdfsReadOps',
                        'HDFS_WRITE_OPS': 'hdfsWriteOps'
                      };
                      break;
                    case 'org.apache.tez.common.counters.TaskCounter':
                      cNameToPropetyMap = {
                        'SPILLED_RECORDS': 'spilledRecords'
                      };
                      break;
                    case 'HIVE':
                      cNameToPropetyMap = {
                        'RECORDS_READ': 'recordReadCount',
                        'RECORDS_WRITE': 'recordWriteCount'
                      };
                      break;
                    default:
                      break;
                  }
                  if (cGroup.counters) {
                    cGroup.counters.forEach(function (counter) {
                      var prop = cNameToPropetyMap[counter.counterName];
                      if (prop != null) {
                        vertexRecord.set(prop, counter.counterValue);
                      }
                    });
                  }
                });
              }
              successCallback();
            }
          }
        },
        loadTezDagVertexError: function (jqXHR, url, method, showStatus) {}
      };
    App.ajax.send({
      name: 'jobs.tezDag.tezDagVertexId',
      sender: sender,
      data: {
        atsURL: atsURL,
        tezDagVertexId: tezVertexInstanceId,
        view: App.get("view"),
        version: App.get("version"),
        instanceName: App.get("instanceName")
      },
      success: 'loadTezDagVertexSuccess',
      error: 'loadTezDagVertexError'
    });
  }
};
<|endoftext|>


<commit_before>'use strict';

import {TimeLine} from "../../../src/TimeLine";
import {data,class_styles} from "../data/test.simple.data";

it('default TimeLine', () => {
    document.body.innerHTML =
        '

';

    let chart = new TimeLine("#time-line-container", {
        data: {
            class_styles: class_styles,
            data: data
        }
    });

    expect(chart.context).toBe("#time-line-container");
    expect(chart.config.data.class_styles).toEqual(class_styles);
    expect(chart.config.data.data).toEqual(data);

    let chart_container = document.getElementById("time-line-container");
    let chart_svgs = chart_container.getElementsByTagName("svg");
    expect(chart_svgs.length).toBe(1);
    let chart_svg = chart_svgs[0];
});<commit_msg>add more test for default timeline.<commit_after>'use strict';
import * as d3selection from 'd3-selection'
import {TimeLine} from "../../../src/TimeLine";
import {data,class_styles} from "../data/test.simple.data";

it('default TimeLine', () => {
    document.body.innerHTML =
        '

';

    let chart = new TimeLine("#time-line-container", {
        data: {
            class_styles: class_styles,
            data: data
        }
    });

    expect(chart.context).toBe("#time-line-container");
    expect(chart.config.data.class_styles).toEqual(class_styles);
    expect(chart.config.data.data).toEqual(data);

    let chart_container = document.getElementById("time-line-container");
    let chart_svgs = chart_container.getElementsByTagName("svg");
    expect(chart_svgs.length).toBe(1);
    let chart_svg = d3selection.select(chart_svgs[0]);
    expect(Number.parseInt(chart_svg.attr('width'))).toBe(TimeLine.default.options.size.width);
    expect(Number.parseInt(chart_svg.attr('height'))).toBe(TimeLine.default.options.size.height);
});<|endoftext|>


<commit_before>
// Command + Enter runs code
document.addEventListener('keydown', ({ metaKey, which }) => {
	if (metaKey && which === 13) convert();
});

// Confirmation (or Failure) Message
const confirmation = (message) => {
	document.getElementById("success").innerHTML = message;
};

// Converter
const convert = () => {
	const testField = document.getElementById('test');
	const messageField = document.getElementById('message');

	const { value: test } = testField;
	const { value: message } = messageField;

	if (!test || !message) {
		confirmation("Failed! Empty input!");
		return;
	}

	const convertedTest = test
		.replace(/\n/g, '; ') // multi-line string to single-line
		.replace(/\s\s+/g, ' ') // replace multiple spaces
		.replace(/\;\;+/g, ';'); // replace multiple semicolons
	const convertedMessage = `message: ${message}`;

	const result = `assert((function() { ${convertedTest} })(), '${convertedMessage}');`;

	document.getElementById("dummy").value = result;
	const copyText = document.querySelector("#dummy");
	copyText.select();
	document.execCommand("Copy");
	confirmation("Copied to clipboard!");
	console.log(result);

	testField.value = '';
	messageField.value = '';
	testField.focus();

}<commit_msg>Updates test converter method<commit_after>
// Confirmation (or Failure) Message
const confirmation = (message) => {
	document.getElementById("success").innerHTML = message;
};

// Converter
const convert = () => {
	const testField = document.getElementById('test');
	const messageField = document.getElementById('message');

	const { value: test } = testField;
	const { value: message } = messageField;

	if (!test || !message) {
		confirmation("Failed! Empty input!");
		return;
	}

	const convertedTest = test
		.replace(/\n/g, ' ') // multi-line string to single-line
		.replace(/\s\s+/g, ' ') // replace multiple spaces
		.replace(/;;+/g, ';'); // replace multiple semicolons
	const convertedMessage = `message: ${message}`;

	const result = `assert((function() { ${convertedTest} })(), '${convertedMessage}');`;

	document.getElementById("dummy").value = result;
	const copyText = document.querySelector("#dummy");
	copyText.select();
	document.execCommand("Copy");
	confirmation("Copied to clipboard!");
	console.log(result);

	testField.value = '';
	messageField.value = '';
	testField.focus();

}

// Command + Enter runs code
document.addEventListener('keydown', ({ metaKey, which }) => {
	if (metaKey && which === 13) convert();
});<|endoftext|>