diff --git a/confluent_client/bin/nodeattrib b/confluent_client/bin/nodeattrib
index e47ec164..1195f07e 100755
--- a/confluent_client/bin/nodeattrib
+++ b/confluent_client/bin/nodeattrib
@@ -17,6 +17,7 @@
__author__ = 'alin37'
+from getpass import getpass
import optparse
import os
import signal
@@ -47,6 +48,8 @@ argparser.add_option('-e', '--environment', action='store_true',
'same name')
argparser.add_option('-c', '--clear', action='store_true',
help='Clear attributes')
+argparser.add_option('-p', '--prompt', action='store_true',
+ help='Prompt for attribute values interactively')
(options, args) = argparser.parse_args()
@@ -67,12 +70,24 @@ exitcode = 0
nodetype="noderange"
if len(args) > 1:
- if "=" in args[1] or options.clear or options.environment:
+ if "=" in args[1] or options.clear or options.environment or options.prompt:
if "=" in args[1] and options.clear:
print("Can not clear and set at the same time!")
argparser.print_help()
sys.exit(1)
- exitcode=client.updateattrib(session,args,nodetype, noderange, options)
+ argassign = None
+ if options.prompt:
+ argassign = {}
+ for arg in args[1:]:
+ oneval = 1
+ twoval = 2
+ while oneval != twoval:
+ oneval = getpass('Enter value for {0}: '.format(arg))
+ twoval = getpass('Confirm value for {0}: '.format(arg))
+ if oneval != twoval:
+ print('Values did not match.')
+ argassign[arg] = twoval
+ exitcode=client.updateattrib(session,args,nodetype, noderange, options, argassign)
try:
# setting user output to what the user inputs
if args[1] == 'all':
diff --git a/confluent_client/confluent/client.py b/confluent_client/confluent/client.py
index 40f2e2b7..b8c6c6f9 100644
--- a/confluent_client/confluent/client.py
+++ b/confluent_client/confluent/client.py
@@ -494,7 +494,7 @@ def printgroupattributes(session, requestargs, showtype, nodetype, noderange, op
exitcode = 1
return exitcode
-def updateattrib(session, updateargs, nodetype, noderange, options):
+def updateattrib(session, updateargs, nodetype, noderange, options, dictassign=None):
# update attribute
exitcode = 0
if options.clear:
@@ -527,6 +527,16 @@ def updateattrib(session, updateargs, nodetype, noderange, options):
'attributes/all',
value, key)
sys.exit(exitcode)
+ elif dictassign:
+ for key in dictassign:
+ if nodetype == 'nodegroups':
+ exitcode = session.simp_nodegroups_command(noderange,
+ 'attributes/all',
+ dictassign[key], key)
+ else:
+ exitcode = session.simp_nodegroups_command(noderange,
+ 'attributes/all',
+ dictassign[key], key)
else:
if "=" in updateargs[1]:
try:
diff --git a/confluent_common/setup.cfg b/confluent_common/setup.cfg
deleted file mode 100644
index 88bee033..00000000
--- a/confluent_common/setup.cfg
+++ /dev/null
@@ -1,17 +0,0 @@
-[metadata]
-name = confluent_common
-summary = Confluent Common Libraries
-description-file =
- README.txt
-author = Jarrod Johnson
-author-email = jjohnson2@lenovo.com
-home-page = http://xcat.sf.net/
-classifier =
- Intended Audience :: Information Technology
- Intended Audience :: System Administrators
- License :: OSI Approved :: Apache Software License
- Operating System :: POSIX :: Linux
- Programming Language :: Python :: 2.6
- Programming Language :: Python :: 2.7
-
-[files]
diff --git a/confluent_server/setup.cfg b/confluent_server/setup.cfg
deleted file mode 100644
index c3bf7855..00000000
--- a/confluent_server/setup.cfg
+++ /dev/null
@@ -1,22 +0,0 @@
-[metadata]
-name = confluent_server
-summary = Confluent systems management daemon
-description-file =
- README.txt
-author = Jarrod Johnson
-author-email = jbjohnso@us.ibm.com
-home-page = http://xcat.sf.net/
-classifier =
- Intended Audience :: Information Technology
- Intended Audience :: System Administrators
- License :: OSI Approved :: Apache Software License
- Operating System :: POSIX :: Linux
- Programming Language :: Python :: 2.6
- Programming Language :: Python :: 2.7
-
-[files]
-packages =
- confluent
- confluent/interface
- confluent/config
-
diff --git a/confluent_web/js/consoles.js b/confluent_web/js/consoles.js
deleted file mode 100644
index 6eb82d7b..00000000
--- a/confluent_web/js/consoles.js
+++ /dev/null
@@ -1,38 +0,0 @@
-function getRequest(url, success) {
- var request = new XMLHttpRequest();
- request.open('GET', url, true);
- request.setRequestHeader('Accept', 'application/json');
- request.onload = function() {
- if (this.status >= 200 && this.status <= 400) {
- success(JSON.parse(this.responseText));
- }
- };
- request.send();
-}
-
-document.addEventListener('DOMContentLoaded', function() {
-
- getRequest("/confluent-api/nodes/", function( data) {
- var items = [];
- var options = [];
- var nodename = "";
- data["_links"]["item"].forEach( function( val, key ) {
- console.log(val);
- if (typeof(val) == "object") {
- nodename = val.href;
- } else {
- nodename = val;
- }
- console.log(nodename);
- nodename = nodename.replace('/', '');
- var myrow = document.createElement('div');
- myrow.innerHTML = "
";
- document.getElementById("nodes").appendChild(myrow);
- document.getElementById(nodename).addEventListener("click", function( event ) {
- var tname = this.id;
- var url = "/confluent-api/nodes/" + tname + "/console/session";
- new ConsoleWindow(url, tname);
- });
- });
- });
-}); // end document
diff --git a/confluent_web/js/consolewindow.js b/confluent_web/js/consolewindow.js
deleted file mode 100644
index 9d6e920a..00000000
--- a/confluent_web/js/consolewindow.js
+++ /dev/null
@@ -1,742 +0,0 @@
-/**
- * tty.js
- * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
- * Copyright 2014, IBM Corporation
- * Copyright 2014, Lenovo
- */
-
-;(function() {
-
-'use strict';
-/**
- * Elements
- */
-
-var document = this.document
- , window = this
- , root
- , body
- , h1
- , open
- , lights;
-
-/**
- * Helpers
- */
-
-var EventEmitter = Terminal.EventEmitter
- , inherits = Terminal.inherits
- , on = Terminal.on
- , off = Terminal.off
- , cancel = Terminal.cancel;
-
-function postRequest(url, data, success) {
- var request = new XMLHttpRequest();
- request.open('POST', url, true);
- request.setRequestHeader('Content-Type', 'application/json');
- request.setRequestHeader('Accept', 'application/json');
- request.onload = function() {
- if (this.status >= 200 && this.status < 400) {
- success(JSON.parse(this.responseText));
- }
- };
- if (data) {
- request.send(JSON.stringify(data));
- } else {
- request.send("");
- }
- request = null;
-}
-/**
- * Console
- */
-
-function ConsoleWindow(consoleurl, nodename) {
- var self = this;
-
- if (!(this instanceof ConsoleWindow)) {
- return new ConsoleWindow(consoleurl, nodename);
- }
-
- EventEmitter.call(this);
-
- var el
- , grip
- , bar
- , button
- , title;
-
- el = document.createElement('div');
- el.className = 'window';
-
- grip = document.createElement('div');
- grip.className = 'grip';
-
- bar = document.createElement('div');
- bar.className = 'bar';
-
- button = document.createElement('div');
- button.innerHTML = 'x';
- button.title = 'close';
- button.className = 'tab';
-
- title = document.createElement('div');
- title.className = 'title';
- title.innerHTML = nodename;
-
- this.nodename = nodename;
- this.element = el;
- this.grip = grip;
- this.bar = bar;
- this.button = button;
- this.title = title;
- this.consoleurl = consoleurl;
-
- this.tabs = [];
- this.focused = null;
-
- this.cols = 100; //Terminal.geometry[0];
- this.rows = 30; //Terminal.geometry[1];
-
- el.appendChild(grip);
- el.appendChild(bar);
- bar.appendChild(title);
- bar.appendChild(button);
- document.body.appendChild(el);
-
- //tty.windows.push(this);
-
- this.createTab();
- this.focus();
- this.bind();
-
- this.tabs[0].once('open', function() {
- //tty.emit('open window', self);
- self.emit('open');
- });
-}
-
-inherits(ConsoleWindow, EventEmitter);
-
-ConsoleWindow.prototype.bind = function() {
- var self = this
- , el = this.element
- , bar = this.bar
- , grip = this.grip
- , button = this.button
- , last = 0;
-
- on(button, 'click', function(ev) {
- self.destroy();
- return cancel(ev);
- });
-
- on(grip, 'mousedown', function(ev) {
- self.focus();
- self.resizing(ev);
- return cancel(ev);
- });
-
- on(el, 'mousedown', function(ev) {
- if (ev.target !== el && ev.target !== bar) return;
-
- self.focus();
-
- cancel(ev);
-
- if (new Date - last < 600) {
- return self.maximize();
- }
- last = new Date;
-
- self.drag(ev);
-
- return cancel(ev);
- });
-};
-
-ConsoleWindow.prototype.focus = function() {
- // Restack
- var parent = this.element.parentNode;
- if (parent) {
- parent.removeChild(this.element);
- parent.appendChild(this.element);
- }
-
- // Focus Foreground Tab
- this.focused.focus();
-
- //tty.emit('focus window', this);
- this.emit('focus');
-};
-
-ConsoleWindow.prototype.destroy = function() {
- if (this.destroyed) return;
- this.destroyed = true;
-
- if (this.minimize) this.minimize();
-
- //splice(tty.windows, this);
- //if (tty.windows.length) tty.windows[0].focus();
-
- this.element.parentNode.removeChild(this.element);
-
- this.each(function(term) {
- term.destroy();
- });
-
- //tty.emit('close window', this);
- this.emit('close');
-};
-
-ConsoleWindow.prototype.drag = function(ev) {
- var self = this
- , el = this.element;
-
- if (this.minimize) return;
-
- var drag = {
- left: el.offsetLeft,
- top: el.offsetTop,
- pageX: ev.pageX,
- pageY: ev.pageY
- };
-
- el.style.opacity = '0.60';
- el.style.cursor = 'move';
- document.documentElement.style.cursor = 'move';
-
- function move(ev) {
- el.style.left =
- (drag.left + ev.pageX - drag.pageX) + 'px';
- var tmptop = (drag.top + ev.pageY - drag.pageY);
- if (tmptop < 0) {
- tmptop = 0;
- }
- el.style.top = tmptop + 'px';
- }
-
- function up() {
- el.style.opacity = '';
- el.style.cursor = '';
- document.documentElement.style.cursor = '';
-
- off(document, 'mousemove', move);
- off(document, 'mouseup', up);
-
- var ev = {
- left: el.style.left.replace(/\w+/g, ''),
- top: el.style.top.replace(/\w+/g, '')
- };
-
- //tty.emit('drag window', self, ev);
- self.emit('drag', ev);
- }
-
- on(document, 'mousemove', move);
- on(document, 'mouseup', up);
-};
-
-ConsoleWindow.prototype.resizing = function(ev) {
- var self = this
- , el = this.element
- , term = this.focused;
-
- if (this.minimize) delete this.minimize;
-
- var resize = {
- w: el.clientWidth,
- h: el.clientHeight
- };
-
- el.style.overflow = 'hidden';
- el.style.opacity = '0.70';
- el.style.cursor = 'se-resize';
- document.documentElement.style.cursor = 'se-resize';
- term.element.style.height = '100%';
-
- function move(ev) {
- var x, y;
- y = el.offsetHeight - term.element.clientHeight;
- x = ev.pageX - el.offsetLeft;
- y = (ev.pageY - el.offsetTop) - y;
- el.style.width = x + 'px';
- el.style.height = y + 'px';
- }
-
- function up() {
- var x, y;
-
- x = el.clientWidth / resize.w;
- y = el.clientHeight / resize.h;
- x = (x * term.cols) | 0;
- y = (y * term.rows) | 0;
-
- self.resize(x, y);
-
- el.style.width = '';
- el.style.height = '';
-
- el.style.overflow = '';
- el.style.opacity = '';
- el.style.cursor = '';
- document.documentElement.style.cursor = '';
- term.element.style.height = '';
-
- off(document, 'mousemove', move);
- off(document, 'mouseup', up);
- }
-
- on(document, 'mousemove', move);
- on(document, 'mouseup', up);
-};
-
-ConsoleWindow.prototype.maximize = function() {
- if (this.minimize) return this.minimize();
-
- var self = this
- , el = this.element
- , term = this.focused
- , x
- , y;
-
- var m = {
- cols: term.cols,
- rows: term.rows,
- left: el.offsetLeft,
- top: el.offsetTop,
- root: root.className
- };
-
- this.minimize = function() {
- delete this.minimize;
-
- el.style.left = m.left + 'px';
- el.style.top = m.top + 'px';
- el.style.width = '';
- el.style.height = '';
- term.element.style.width = '';
- term.element.style.height = '';
- el.style.boxSizing = '';
- self.grip.style.display = '';
- root.className = m.root;
-
- self.resize(m.cols, m.rows);
-
- //tty.emit('minimize window', self);
- self.emit('minimize');
- };
-
- window.scrollTo(0, 0);
-
- x = root.clientWidth / term.element.offsetWidth;
- y = root.clientHeight / term.element.offsetHeight;
- x = (x * term.cols) | 0;
- y = (y * term.rows) | 0;
-
- el.style.left = '0px';
- el.style.top = '0px';
- el.style.width = '100%';
- el.style.height = '100%';
- term.element.style.width = '100%';
- term.element.style.height = '100%';
- el.style.boxSizing = 'border-box';
- this.grip.style.display = 'none';
- root.className = 'maximized';
-
- this.resize(x, y);
-
- //tty.emit('maximize window', this);
- this.emit('maximize');
-};
-
-ConsoleWindow.prototype.resize = function(cols, rows) {
- this.cols = cols;
- this.rows = rows;
-
- this.each(function(term) {
- term.resize(cols, rows);
- });
-
- //tty.emit('resize window', this, cols, rows);
- this.emit('resize', cols, rows);
-};
-
-ConsoleWindow.prototype.each = function(func) {
- var i = this.tabs.length;
- while (i--) {
- func(this.tabs[i], i);
- }
-};
-
-ConsoleWindow.prototype.createTab = function() {
- return new Tab(this, this.consoleurl);
-};
-
-ConsoleWindow.prototype.highlight = function() {
- var self = this;
-
- this.element.style.borderColor = 'orange';
- setTimeout(function() {
- self.element.style.borderColor = '';
- }, 200);
-
- this.focus();
-};
-
-ConsoleWindow.prototype.focusTab = function(next) {
- var tabs = this.tabs
- , i = indexOf(tabs, this.focused)
- , l = tabs.length;
-
- if (!next) {
- if (tabs[--i]) return tabs[i].focus();
- if (tabs[--l]) return tabs[l].focus();
- } else {
- if (tabs[++i]) return tabs[i].focus();
- if (tabs[0]) return tabs[0].focus();
- }
-
- return this.focused && this.focused.focus();
-};
-
-ConsoleWindow.prototype.nextTab = function() {
- return this.focusTab(true);
-};
-
-ConsoleWindow.prototype.previousTab = function() {
- return this.focusTab(false);
-};
-
-/**
- * Tab
- */
-
-function Tab(win, consoleurl) {
- var self = this;
-
- var cols = win.cols
- , rows = win.rows;
-
- Terminal.call(this, {
- cols: cols,
- rows: rows
- });
-
- var button = document.createElement('div');
- button.className = 'tab';
- button.innerHTML = '\u2022';
- //win.bar.appendChild(button);
-
- on(button, 'click', function(ev) {
- if (ev.ctrlKey || ev.altKey || ev.metaKey || ev.shiftKey) {
- self.destroy();
- } else {
- self.focus();
- }
- return cancel(ev);
- });
-
- this.id = '';
- this.consoleurl = consoleurl;
- this.clientcount = 0;
- this.connectstate = 'unconnected';
- this.lasterror = ''
- this.window = win;
- this.button = button;
- this.element = null;
- this.process = '';
- this.open();
- this.hookKeys();
- // Now begins the code that will embarass me when I actually know my way
- // around javascript -jbjohnso
- this.sessid = '';
- this.datapending = false;
- this.waitingdata = false;
- this.sentdata = function(data, textStatus, jqXHR) {
- if (this.waitingdata) {
- postRequest(consoleurl, { session: this.sessid, bytes: this.waitingdata }, this.sentdata);
- this.waitingdata = false;
- } else {
- this.datapending = false;
- }
- }.bind(this);
- this.on('data', function(data) {
- // Send data to console from terminal
- if (this.datapending) {
- if (!this.waitingdata) {
- this.waitingdata = data;
- } else {
- this.waitingdata = this.waitingdata + data;
- }
- return;
- }
- this.datapending = true;
- postRequest(consoleurl, { session: this.sessid, bytes: data }, this.sentdata);
- }.bind(this));
- this.gotdata = function(data, textStatus, jqXHR) {
- if ("data" in data) {
- this.write(data.data);
- }
- var updatetitle = false;
- var updateinfo = [];
- if ("connectstate" in data) {
- updatetitle = true;
- this.connectstate = data.connectstate;
- }
- if (this.connectstate != "connected") {
- updateinfo.push(this.connectstate);
- } else {
- self.lasterror = '';
- }
- if ("error" in data) {
- updatetitle = true;
- this.lasterror = data.error
- }
- if (this.lasterror != '') {
- updateinfo.push(this.lasterror);
- }
- if ("clientcount" in data) {
- updatetitle = true;
- this.clientcount = data.clientcount;
- }
- if (this.clientcount > 1) {
- updateinfo.push("clients: " + this.clientcount.toString());
- }
- if (updatetitle == true) {
- if (updateinfo.length > 0) {
- this.window.title.innerHTML = this.window.nodename + " [" + updateinfo.join() + "]";
- } else {
- this.window.title.innerHTML = this.window.nodename;
- }
- }
- postRequest(consoleurl, { session: this.sessid }, this.gotdata);
- }.bind(this);
- this.gotsession = function(data, textStatus, jqXHR) {
- this.sessid = data.session
- postRequest(consoleurl, { session: this.sessid }, this.gotdata);
- }.bind(this);
- postRequest(consoleurl, false, this.gotsession);
-
- win.tabs.push(this);
-};
-
-inherits(Tab, Terminal);
-
-Tab.prototype._write = Tab.prototype.write;
-
-Tab.prototype.write = function(data) {
- if (this.window.focused !== this) this.button.style.color = 'red';
- return this._write(data);
-};
-
-Tab.prototype._focus = Tab.prototype.focus;
-
-Tab.prototype.focus = function() {
- if (Terminal.focus === this) return;
-
- var win = this.window;
-
- // maybe move to Tab.prototype.switch
- if (win.focused !== this) {
- if (win.focused) {
- if (win.focused.element.parentNode) {
- win.focused.element.parentNode.removeChild(win.focused.element);
- }
- win.focused.button.style.fontWeight = '';
- }
-
- win.element.appendChild(this.element);
- win.focused = this;
-
- //win.title.innerHTML = this.process;
- this.button.style.fontWeight = 'bold';
- this.button.style.color = '';
- }
-
- this._focus();
-
- win.focus();
-
- //tty.emit('focus tab', this);
- this.emit('focus');
-};
-
-Tab.prototype._resize = Tab.prototype.resize;
-
-Tab.prototype.resize = function(cols, rows) {
- //this.socket.emit('resize', this.id, cols, rows);
- this._resize(cols, rows);
- //tty.emit('resize tab', this, cols, rows);
- this.emit('resize', cols, rows);
-};
-
-Tab.prototype.__destroy = Tab.prototype.destroy;
-
-Tab.prototype._destroy = function() {
- if (this.destroyed) return;
- this.destroyed = true;
-
- var win = this.window;
-
- this.button.parentNode.removeChild(this.button);
- if (this.element.parentNode) {
- this.element.parentNode.removeChild(this.element);
- }
-
- if (tty.terms[this.id]) delete tty.terms[this.id];
- splice(win.tabs, this);
-
- if (win.focused === this) {
- win.previousTab();
- }
-
- if (!win.tabs.length) {
- win.destroy();
- }
-
- this.__destroy();
-};
-
-Tab.prototype.destroy = function() {
- if (this.destroyed) return;
- //TODO: politely let server know of client closure
- this._destroy();
- //tty.emit('close tab', this);
- this.emit('close');
-};
-
-Tab.prototype.hookKeys = function() {
- var self = this;
-
- // Alt-[jk] to quickly swap between windows.
- this.on('key', function(key, ev) {
- if (Terminal.focusKeys === false) {
- return;
- }
-
- var offset
- , i;
-
- if (key === '\x1bj') {
- offset = -1;
- } else if (key === '\x1bk') {
- offset = +1;
- } else {
- return;
- }
-
- i = indexOf(tty.windows, this.window) + offset;
-
- this._ignoreNext();
-
- if (tty.windows[i]) return tty.windows[i].highlight();
-
- if (offset > 0) {
- if (tty.windows[0]) return tty.windows[0].highlight();
- } else {
- i = tty.windows.length - 1;
- if (tty.windows[i]) return tty.windows[i].highlight();
- }
-
- return this.window.highlight();
- });
-
- this.on('request paste', function(key) {
- this.socket.emit('request paste', function(err, text) {
- if (err) return;
- self.send(text);
- });
- });
-
- this.on('request create', function() {
- this.window.createTab();
- });
-
- this.on('request term', function(key) {
- if (this.window.tabs[key]) {
- this.window.tabs[key].focus();
- }
- });
-
- this.on('request term next', function(key) {
- this.window.nextTab();
- });
-
- this.on('request term previous', function(key) {
- this.window.previousTab();
- });
-};
-
-Tab.prototype._ignoreNext = function() {
- // Don't send the next key.
- var handler = this.handler;
- this.handler = function() {
- this.handler = handler;
- };
- var showCursor = this.showCursor;
- this.showCursor = function() {
- this.showCursor = showCursor;
- };
-};
-
-/**
- * Program-specific Features
- */
-
-Tab.prototype._bindMouse = Tab.prototype.bindMouse;
-
-Tab.prototype.bindMouse = function() {
- if (!Terminal.programFeatures) return this._bindMouse();
-
- var self = this;
-
- var wheelEvent = 'onmousewheel' in window
- ? 'mousewheel'
- : 'DOMMouseScroll';
-
- on(self.element, wheelEvent, function(ev) {
- if (self.mouseEvents) return;
-
- if ((ev.type === 'mousewheel' && ev.wheelDeltaY > 0)
- || (ev.type === 'DOMMouseScroll' && ev.detail < 0)) {
- // page up
- self.keyDown({keyCode: 33});
- } else {
- // page down
- self.keyDown({keyCode: 34});
- }
-
- return cancel(ev);
- });
-
- return this._bindMouse();
-};
-
-/**
- * Helpers
- */
-
-function indexOf(obj, el) {
- var i = obj.length;
- while (i--) {
- if (obj[i] === el) return i;
- }
- return -1;
-}
-
-function splice(obj, el) {
- var i = indexOf(obj, el);
- if (~i) obj.splice(i, 1);
-}
-
-function sanitize(text) {
- if (!text) return '';
- return (text + '').replace(/[&<>]/g, '')
-}
-
-this.ConsoleWindow = ConsoleWindow;
-
-}).call(function() {
- return this;
-}());
diff --git a/confluent_web/js/term.js b/confluent_web/js/term.js
deleted file mode 100644
index f26617dd..00000000
--- a/confluent_web/js/term.js
+++ /dev/null
@@ -1,5771 +0,0 @@
-/**
- * term.js - an xterm emulator
- * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
- * https://github.com/chjj/term.js
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * Originally forked from (with the author's permission):
- * Fabrice Bellard's javascript vt100 for jslinux:
- * http://bellard.org/jslinux/
- * Copyright (c) 2011 Fabrice Bellard
- * The original design remains. The terminal itself
- * has been extended to include xterm CSI codes, among
- * other features.
- */
-
-;(function() {
-
-/**
- * Terminal Emulation References:
- * http://vt100.net/
- * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt
- * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
- * http://invisible-island.net/vttest/
- * http://www.inwap.com/pdp10/ansicode.txt
- * http://linux.die.net/man/4/console_codes
- * http://linux.die.net/man/7/urxvt
- */
-
-'use strict';
-
-/**
- * Shared
- */
-
-var window = this
- , document = this.document;
-
-/**
- * EventEmitter
- */
-
-function EventEmitter() {
- this._events = this._events || {};
-}
-
-EventEmitter.prototype.addListener = function(type, listener) {
- this._events[type] = this._events[type] || [];
- this._events[type].push(listener);
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.removeListener = function(type, listener) {
- if (!this._events[type]) return;
-
- var obj = this._events[type]
- , i = obj.length;
-
- while (i--) {
- if (obj[i] === listener || obj[i].listener === listener) {
- obj.splice(i, 1);
- return;
- }
- }
-};
-
-EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
-
-EventEmitter.prototype.removeAllListeners = function(type) {
- if (this._events[type]) delete this._events[type];
-};
-
-EventEmitter.prototype.once = function(type, listener) {
- function on() {
- var args = Array.prototype.slice.call(arguments);
- this.removeListener(type, on);
- return listener.apply(this, args);
- }
- on.listener = listener;
- return this.on(type, on);
-};
-
-EventEmitter.prototype.emit = function(type) {
- if (!this._events[type]) return;
-
- var args = Array.prototype.slice.call(arguments, 1)
- , obj = this._events[type]
- , l = obj.length
- , i = 0;
-
- for (; i < l; i++) {
- obj[i].apply(this, args);
- }
-};
-
-EventEmitter.prototype.listeners = function(type) {
- return this._events[type] = this._events[type] || [];
-};
-
-/**
- * States
- */
-
-var normal = 0
- , escaped = 1
- , csi = 2
- , osc = 3
- , charset = 4
- , dcs = 5
- , ignore = 6;
-
-/**
- * Terminal
- */
-
-function Terminal(options) {
- var self = this;
-
- if (!(this instanceof Terminal)) {
- return new Terminal(arguments[0], arguments[1], arguments[2]);
- }
-
- EventEmitter.call(this);
-
- if (typeof options === 'number') {
- options = {
- cols: arguments[0],
- rows: arguments[1],
- handler: arguments[2]
- };
- }
-
- options = options || {};
-
- each(keys(Terminal.defaults), function(key) {
- if (options[key] == null) {
- options[key] = Terminal.options[key];
- // Legacy:
- if (Terminal[key] !== Terminal.defaults[key]) {
- options[key] = Terminal[key];
- }
- }
- self[key] = options[key];
- });
-
- if (options.colors.length === 8) {
- options.colors = options.colors.concat(Terminal._colors.slice(8));
- } else if (options.colors.length === 16) {
- options.colors = options.colors.concat(Terminal._colors.slice(16));
- } else if (options.colors.length === 10) {
- options.colors = options.colors.slice(0, -2).concat(
- Terminal._colors.slice(8, -2), options.colors.slice(-2));
- } else if (options.colors.length === 18) {
- options.colors = options.colors.slice(0, -2).concat(
- Terminal._colors.slice(16, -2), options.colors.slice(-2));
- }
- this.colors = options.colors;
-
- this.options = options;
-
- // this.context = options.context || window;
- // this.document = options.document || document;
- this.parent = options.body || options.parent
- || (document ? document.getElementsByTagName('body')[0] : null);
-
- this.cols = options.cols || options.geometry[0];
- this.rows = options.rows || options.geometry[1];
-
- if (options.handler) {
- this.on('data', options.handler);
- }
-
- this.ybase = 0;
- this.ydisp = 0;
- this.x = 0;
- this.y = 0;
- this.cursorState = 0;
- this.cursorHidden = false;
- this.convertEol;
- this.state = 0;
- this.queue = '';
- this.scrollTop = 0;
- this.scrollBottom = this.rows - 1;
-
- // modes
- this.applicationKeypad = false;
- this.applicationCursor = false;
- this.originMode = false;
- this.insertMode = false;
- this.wraparoundMode = false;
- this.normal = null;
-
- // select modes
- this.prefixMode = false;
- this.selectMode = false;
- this.visualMode = false;
- this.searchMode = false;
- this.searchDown;
- this.entry = '';
- this.entryPrefix = 'Search: ';
- this._real;
- this._selected;
- this._textarea;
-
- // charset
- this.charset = null;
- this.gcharset = null;
- this.glevel = 0;
- this.charsets = [null];
-
- // mouse properties
- this.decLocator;
- this.x10Mouse;
- this.vt200Mouse;
- this.vt300Mouse;
- this.normalMouse;
- this.mouseEvents;
- this.sendFocus;
- this.utfMouse;
- this.sgrMouse;
- this.urxvtMouse;
-
- // misc
- this.element;
- this.children;
- this.refreshStart;
- this.refreshEnd;
- this.savedX;
- this.savedY;
- this.savedCols;
-
- // stream
- this.readable = true;
- this.writable = true;
-
- this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);
- this.curAttr = this.defAttr;
-
- this.params = [];
- this.currentParam = 0;
- this.prefix = '';
- this.postfix = '';
-
- this.lines = [];
- var i = this.rows;
- while (i--) {
- this.lines.push(this.blankLine());
- }
-
- this.tabs;
- this.setupStops();
-}
-
-inherits(Terminal, EventEmitter);
-
-// back_color_erase feature for xterm.
-Terminal.prototype.eraseAttr = function() {
- // if (this.is('screen')) return this.defAttr;
- return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);
-};
-
-/**
- * Colors
- */
-
-// Colors 0-15
-Terminal.tangoColors = [
- // dark:
- '#2e3436',
- '#cc0000',
- '#4e9a06',
- '#c4a000',
- '#3465a4',
- '#75507b',
- '#06989a',
- '#d3d7cf',
- // bright:
- '#555753',
- '#ef2929',
- '#8ae234',
- '#fce94f',
- '#729fcf',
- '#ad7fa8',
- '#34e2e2',
- '#eeeeec'
-];
-
-Terminal.xtermColors = [
- // dark:
- '#000000', // black
- '#cd0000', // red3
- '#00cd00', // green3
- '#cdcd00', // yellow3
- '#0000ee', // blue2
- '#cd00cd', // magenta3
- '#00cdcd', // cyan3
- '#e5e5e5', // gray90
- // bright:
- '#7f7f7f', // gray50
- '#ff0000', // red
- '#00ff00', // green
- '#ffff00', // yellow
- '#5c5cff', // rgb:5c/5c/ff
- '#ff00ff', // magenta
- '#00ffff', // cyan
- '#ffffff' // white
-];
-
-// Colors 0-15 + 16-255
-// Much thanks to TooTallNate for writing this.
-Terminal.colors = (function() {
- var colors = Terminal.tangoColors.slice()
- , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]
- , i;
-
- // 16-231
- i = 0;
- for (; i < 216; i++) {
- out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);
- }
-
- // 232-255 (grey)
- i = 0;
- for (; i < 24; i++) {
- r = 8 + i * 10;
- out(r, r, r);
- }
-
- function out(r, g, b) {
- colors.push('#' + hex(r) + hex(g) + hex(b));
- }
-
- function hex(c) {
- c = c.toString(16);
- return c.length < 2 ? '0' + c : c;
- }
-
- return colors;
-})();
-
-// Default BG/FG
-Terminal.colors[256] = '#000000';
-Terminal.colors[257] = '#f0f0f0';
-
-Terminal._colors = Terminal.colors.slice();
-
-Terminal.vcolors = (function() {
- var out = []
- , colors = Terminal.colors
- , i = 0
- , color;
-
- for (; i < 256; i++) {
- color = parseInt(colors[i].substring(1), 16);
- out.push([
- (color >> 16) & 0xff,
- (color >> 8) & 0xff,
- color & 0xff
- ]);
- }
-
- return out;
-})();
-
-/**
- * Options
- */
-
-Terminal.defaults = {
- colors: Terminal.colors,
- convertEol: false,
- termName: 'xterm',
- geometry: [80, 24],
- cursorBlink: true,
- visualBell: false,
- popOnBell: false,
- scrollback: 1000,
- screenKeys: false,
- debug: false,
- useStyle: false
- // programFeatures: false,
- // focusKeys: false,
-};
-
-Terminal.options = {};
-
-each(keys(Terminal.defaults), function(key) {
- Terminal[key] = Terminal.defaults[key];
- Terminal.options[key] = Terminal.defaults[key];
-});
-
-/**
- * Focused Terminal
- */
-
-Terminal.focus = null;
-
-Terminal.prototype.focus = function() {
- if (Terminal.focus === this) return;
-
- if (Terminal.focus) {
- Terminal.focus.blur();
- }
-
- if (this.sendFocus) this.send('\x1b[I');
- this.showCursor();
-
- // try {
- // this.element.focus();
- // } catch (e) {
- // ;
- // }
-
- // this.emit('focus');
-
- Terminal.focus = this;
-};
-
-Terminal.prototype.blur = function() {
- if (Terminal.focus !== this) return;
-
- this.cursorState = 0;
- this.refresh(this.y, this.y);
- if (this.sendFocus) this.send('\x1b[O');
-
- // try {
- // this.element.blur();
- // } catch (e) {
- // ;
- // }
-
- // this.emit('blur');
-
- Terminal.focus = null;
-};
-
-/**
- * Initialize global behavior
- */
-
-Terminal.prototype.initGlobal = function() {
- var document = this.document;
-
- Terminal._boundDocs = Terminal._boundDocs || [];
- if (~indexOf(Terminal._boundDocs, document)) {
- return;
- }
- Terminal._boundDocs.push(document);
-
- Terminal.bindPaste(document);
-
- Terminal.bindKeys(document);
-
- Terminal.bindCopy(document);
-
- if (this.isMobile) {
- this.fixMobile(document);
- }
-
- if (this.useStyle) {
- Terminal.insertStyle(document, this.colors[256], this.colors[257]);
- }
-};
-
-/**
- * Bind to paste event
- */
-
-Terminal.bindPaste = function(document) {
- // This seems to work well for ctrl-V and middle-click,
- // even without the contentEditable workaround.
- var window = document.defaultView;
- on(window, 'paste', function(ev) {
- var term = Terminal.focus;
- if (!term) return;
- if (ev.clipboardData) {
- term.send(ev.clipboardData.getData('text/plain'));
- } else if (term.context.clipboardData) {
- term.send(term.context.clipboardData.getData('Text'));
- }
- // Not necessary. Do it anyway for good measure.
- term.element.contentEditable = 'inherit';
- return cancel(ev);
- });
-};
-
-/**
- * Global Events for key handling
- */
-
-Terminal.bindKeys = function(document) {
- // We should only need to check `target === body` below,
- // but we can check everything for good measure.
- on(document, 'keydown', function(ev) {
- if (!Terminal.focus) return;
- var target = ev.target || ev.srcElement;
- if (!target) return;
- if (target === Terminal.focus.element
- || target === Terminal.focus.context
- || target === Terminal.focus.document
- || target === Terminal.focus.body
- || target === Terminal._textarea
- || target === Terminal.focus.parent) {
- return Terminal.focus.keyDown(ev);
- }
- }, true);
-
- on(document, 'keypress', function(ev) {
- if (!Terminal.focus) return;
- var target = ev.target || ev.srcElement;
- if (!target) return;
- if (target === Terminal.focus.element
- || target === Terminal.focus.context
- || target === Terminal.focus.document
- || target === Terminal.focus.body
- || target === Terminal._textarea
- || target === Terminal.focus.parent) {
- return Terminal.focus.keyPress(ev);
- }
- }, true);
-
- // If we click somewhere other than a
- // terminal, unfocus the terminal.
- on(document, 'mousedown', function(ev) {
- if (!Terminal.focus) return;
-
- var el = ev.target || ev.srcElement;
- if (!el) return;
-
- do {
- if (el === Terminal.focus.element) return;
- } while (el = el.parentNode);
-
- Terminal.focus.blur();
- });
-};
-
-/**
- * Copy Selection w/ Ctrl-C (Select Mode)
- */
-
-Terminal.bindCopy = function(document) {
- var window = document.defaultView;
-
- // if (!('onbeforecopy' in document)) {
- // // Copies to *only* the clipboard.
- // on(window, 'copy', function fn(ev) {
- // var term = Terminal.focus;
- // if (!term) return;
- // if (!term._selected) return;
- // var text = term.grabText(
- // term._selected.x1, term._selected.x2,
- // term._selected.y1, term._selected.y2);
- // term.emit('copy', text);
- // ev.clipboardData.setData('text/plain', text);
- // });
- // return;
- // }
-
- // Copies to primary selection *and* clipboard.
- // NOTE: This may work better on capture phase,
- // or using the `beforecopy` event.
- on(window, 'copy', function(ev) {
- var term = Terminal.focus;
- if (!term) return;
- if (!term._selected) return;
- var textarea = term.getCopyTextarea();
- var text = term.grabText(
- term._selected.x1, term._selected.x2,
- term._selected.y1, term._selected.y2);
- term.emit('copy', text);
- textarea.focus();
- textarea.textContent = text;
- textarea.value = text;
- textarea.setSelectionRange(0, text.length);
- setTimeout(function() {
- term.element.focus();
- term.focus();
- }, 1);
- });
-};
-
-/**
- * Fix Mobile
- */
-
-Terminal.prototype.fixMobile = function(document) {
- var self = this;
-
- var textarea = document.createElement('textarea');
- textarea.style.position = 'absolute';
- textarea.style.left = '-32000px';
- textarea.style.top = '-32000px';
- textarea.style.width = '0px';
- textarea.style.height = '0px';
- textarea.style.opacity = '0';
- textarea.style.backgroundColor = 'transparent';
- textarea.style.borderStyle = 'none';
- textarea.style.outlineStyle = 'none';
- textarea.autocapitalize = 'none';
- textarea.autocorrect = 'off';
-
- document.getElementsByTagName('body')[0].appendChild(textarea);
-
- Terminal._textarea = textarea;
-
- setTimeout(function() {
- textarea.focus();
- }, 1000);
-
- if (this.isAndroid) {
- on(textarea, 'change', function() {
- var value = textarea.textContent || textarea.value;
- textarea.value = '';
- textarea.textContent = '';
- self.send(value + '\r');
- });
- }
-};
-
-/**
- * Insert a default style
- */
-
-Terminal.insertStyle = function(document, bg, fg) {
- var style = document.getElementById('term-style');
- if (style) return;
-
- var head = document.getElementsByTagName('head')[0];
- if (!head) return;
-
- var style = document.createElement('style');
- style.id = 'term-style';
-
- // textContent doesn't work well with IE for