From: Scott Baker Date: Tue, 8 Jul 2014 04:54:35 +0000 (-0700) Subject: xoslib wip X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;ds=sidebyside;h=95d6c5cb91712cc881691f1754fc2f77a73003f7;p=plstackapi.git xoslib wip --- diff --git a/planetstack/core/xoslib/dashboards/sliverListTest.html b/planetstack/core/xoslib/dashboards/sliverListTest.html index 7a5b2d4..61c54cf 100644 --- a/planetstack/core/xoslib/dashboards/sliverListTest.html +++ b/planetstack/core/xoslib/dashboards/sliverListTest.html @@ -3,7 +3,6 @@ - diff --git a/planetstack/core/xoslib/dashboards/xsh.html b/planetstack/core/xoslib/dashboards/xsh.html new file mode 100644 index 0000000..6e5103a --- /dev/null +++ b/planetstack/core/xoslib/dashboards/xsh.html @@ -0,0 +1,21 @@ +
+

XSH - The XOS Shell

+
+ + + +
+ + + + + + + + + + + + + + diff --git a/planetstack/core/xoslib/static/js/sliverListTest.js b/planetstack/core/xoslib/static/js/sliverListTest.js index 2365aa2..59970d8 100644 --- a/planetstack/core/xoslib/static/js/sliverListTest.js +++ b/planetstack/core/xoslib/static/js/sliverListTest.js @@ -110,7 +110,7 @@ window.Router = Backbone.Router.extend({ $(function(){ window.app = window.app || {}; app.router = new Router(); - app.slivers = XOSLib.slivers; //new XOSLib.slivers(); + app.slivers = xos.slivers; //new XOSLib.slivers(); app.list = new ListApp({ el: $("#app"), collection: app.slivers diff --git a/planetstack/core/xoslib/static/js/xos-backbone.js b/planetstack/core/xoslib/static/js/xos-backbone.js index 1633768..c4f1a33 100644 --- a/planetstack/core/xoslib/static/js/xos-backbone.js +++ b/planetstack/core/xoslib/static/js/xos-backbone.js @@ -1,4 +1,5 @@ SLIVER_API = "/plstackapi/slivers/"; +SLICE_API = "/plstackapi/slices/"; XOSModel = Backbone.Model.extend({ /* from backbone-tastypie.js */ @@ -93,6 +94,11 @@ function xoslib() { this.sliverCollection = XOSCollection.extend({ urlRoot: SLIVER_API, model: this.sliver}); this.slivers = new this.sliverCollection(); + + this.slice = XOSModel.extend({ urlRoot: SLICE_API }); + this.sliceCollection = XOSCollection.extend({ urlRoot: SLICE_API, + model: this.slice}); + this.slices = new this.sliceCollection(); }; -XOSLib = new xoslib(); +xos = new xoslib(); diff --git a/planetstack/core/xoslib/static/xsh/constants.js b/planetstack/core/xoslib/static/xsh/constants.js new file mode 100644 index 0000000..97b690a --- /dev/null +++ b/planetstack/core/xoslib/static/xsh/constants.js @@ -0,0 +1,39 @@ +// TryMongo +// +// Copyright (c) 2009 Kyle Banker +// Licensed under the MIT Licence. +// http://www.opensource.org/licenses/mit-license.php + +var DefaultInputHtml = function(stack) { + var linePrompt = ""; + if(stack == 0) { + linePrompt += " >"; + } + else { + for(var i=0; i <= stack; i++) { + linePrompt += "."; + } + } + return "
" + + linePrompt + + "" + + "
"; +} + +var EnterKeyCode = 13; +var UpArrowKeyCode = 38; +var DownArrowKeyCode = 40; + +var PTAG = function(str) { + return '
' + str + '
'; +} + +var BR = function() { + return "
"; +} + +var JavascriptKeywords = ['abstract', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else', 'enum', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface', 'long', 'native', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'alert', 'date', 'eval']; + +var JavascriptClassNames = ['Array', 'String', 'Object'] + +var MongoKeywords = ['help','tutorial','next','back','t0','t1','t2','t3','t4']; diff --git a/planetstack/core/xoslib/static/xsh/object_id.js b/planetstack/core/xoslib/static/xsh/object_id.js new file mode 100644 index 0000000..15cbbb9 --- /dev/null +++ b/planetstack/core/xoslib/static/xsh/object_id.js @@ -0,0 +1,12 @@ +var ObjectIdCounter = 0; + +var ObjectId = function() { + this.counter = (ObjectIdCounter += 1); + this.str = this.counter; + this.initialize(); + return this.counter; +}; + +ObjectId.prototype.initialize = function() { + return this.counter; +} diff --git a/planetstack/core/xoslib/static/xsh/shell_utils.js b/planetstack/core/xoslib/static/xsh/shell_utils.js new file mode 100644 index 0000000..8ed5f4f --- /dev/null +++ b/planetstack/core/xoslib/static/xsh/shell_utils.js @@ -0,0 +1,548 @@ +DB = function() { +} + +print = function(msg) { + //console.log(msg); +} + + +friendlyEqual = function( a , b ){ + if ( a == b ) + return true; + + if ( tojson( a ) == tojson( b ) ) + return true; + + return false; +} + + +doassert = function( msg ){ + print( "assert: " + msg ); + throw msg; +} + +assert = function( b , msg ){ + if ( assert._debug && msg ) print( "in assert for: " + msg ); + + if ( b ) + return; + + doassert( "assert failed : " + msg ); +} + +assert.eq = function( a , b , msg ){ + if ( assert._debug && msg ) print( "in assert for: " + msg ); + + if ( a == b ) + return; + + if ( ( a != null && b != null ) && friendlyEqual( a , b ) ) + return; + + doassert( "[" + tojson( a ) + "] != [" + tojson( b ) + "] are not equal : " + msg ); +} + +assert.neq = function( a , b , msg ){ + if ( assert._debug && msg ) print( "in assert for: " + msg ); + if ( a != b ) + return; + + doassert( "[" + a + "] != [" + b + "] are equal : " + msg ); +} + +assert.soon = function( f, msg, timeout, interval ) { + if ( assert._debug && msg ) print( "in assert for: " + msg ); + + var start = new Date(); + timeout = timeout || 30000; + interval = interval || 200; + var last; + while( 1 ) { + + if ( typeof( f ) == "string" ){ + if ( eval( f ) ) + return; + } + else { + if ( f() ) + return; + } + + if ( ( new Date() ).getTime() - start.getTime() > timeout ) + doassert( "assert.soon failed: " + f + ", msg:" + msg ); + sleep( interval ); + } +} + +assert.throws = function( func , params , msg ){ + if ( assert._debug && msg ) print( "in assert for: " + msg ); + try { + func.apply( null , params ); + } + catch ( e ){ + return e; + } + + doassert( "did not throw exception: " + msg ); +} + +assert.commandWorked = function( res , msg ){ + if ( assert._debug && msg ) print( "in assert for: " + msg ); + + if ( res.ok == 1 ) + return; + + doassert( "command failed: " + tojson( res ) + " : " + msg ); +} + +assert.commandFailed = function( res , msg ){ + if ( assert._debug && msg ) print( "in assert for: " + msg ); + + if ( res.ok == 0 ) + return; + + doassert( "command worked when it should have failed: " + tojson( res ) + " : " + msg ); +} + +assert.isnull = function( what , msg ){ + if ( assert._debug && msg ) print( "in assert for: " + msg ); + + if ( what == null ) + return; + + doassert( "supposed to null (" + ( msg || "" ) + ") was: " + tojson( what ) ); +} + +assert.lt = function( a , b , msg ){ + if ( assert._debug && msg ) print( "in assert for: " + msg ); + + if ( a < b ) + return; + doassert( a + " is not less than " + b + " : " + msg ); +} + +assert.gt = function( a , b , msg ){ + if ( assert._debug && msg ) print( "in assert for: " + msg ); + + if ( a > b ) + return; + doassert( a + " is not greater than " + b + " : " + msg ); +} + +Object.extend = function( dst , src , deep ){ + for ( var k in src ){ + var v = src[k]; + if ( deep && typeof(v) == "object" ){ + v = Object.extend( typeof ( v.length ) == "number" ? [] : {} , v , true ); + } + dst[k] = v; + } + return dst; +} + +argumentsToArray = function( a ){ + var arr = []; + for ( var i=0; i= 1ms"); + print( "\t" + "use set curent database to " ); + print( "\t" + "db.help() help on DB methods"); + print( "\t" + "db.foo.help() help on collection methods"); + print( "\t" + "db.foo.find() list objects in collection foo" ); + print( "\t" + "db.foo.find( { a : 1 } ) list objects in foo where a == 1" ); + print( "\t" + "it result of the last line evaluated; use to further iterate"); +} + +if ( typeof( Map ) == "undefined" ){ + Map = function(){ + this._data = {}; + } +} + +Map.hash = function( val ){ + if ( ! val ) + return val; + + switch ( typeof( val ) ){ + case 'string': + case 'number': + case 'date': + return val.toString(); + case 'object': + case 'array': + var s = ""; + for ( var k in val ){ + s += k + val[k]; + } + return s; + } + + throw "can't hash : " + typeof( val ); +} + +Map.prototype.put = function( key , value ){ + var o = this._get( key ); + var old = o.value; + o.value = value; + return old; +} + +Map.prototype.get = function( key ){ + return this._get( key ).value; +} + +Map.prototype._get = function( key ){ + var h = Map.hash( key ); + var a = this._data[h]; + if ( ! a ){ + a = []; + this._data[h] = a; + } + + for ( var i=0; i+-&', '=>&:' +// will match any of these: +// <= >> >>> <> >= +: -: &: &&: && + + + +String.prototype.tokens = function (prefix, suffix) { + var c; // The current character. + var from; // The index of the start of the token. + var i = 0; // The index of the current character. + var length = this.length; + var n; // The number value. + var q; // The quote character. + var str; // The string value. + + var result = []; // An array to hold the results. + + var make = function (type, value) { + +// Make a token object. + + return { + type: type, + value: value, + from: from, + to: i + }; + }; + +// Begin tokenization. If the source string is empty, return nothing. + + if (!this) { + return; + } + +// If prefix and suffix strings are not provided, supply defaults. + + if (typeof prefix !== 'string') { + prefix = '<>+-&'; + } + if (typeof suffix !== 'string') { + suffix = '=>&:'; + } + + +// Loop through this text, one character at a time. + + c = this.charAt(i); + while (c) { + from = i; + +// Ignore whitespace. + + if (c <= ' ') { + i += 1; + c = this.charAt(i); + +// name. + + } else if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') { + str = c; + i += 1; + for (;;) { + c = this.charAt(i); + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c === '_') { + str += c; + i += 1; + } else { + break; + } + } + result.push(make('name', str)); + +// number. + +// A number cannot start with a decimal point. It must start with a digit, +// possibly '0'. + + } else if (c >= '0' && c <= '9') { + str = c; + i += 1; + +// Look for more digits. + + for (;;) { + c = this.charAt(i); + if (c < '0' || c > '9') { + break; + } + i += 1; + str += c; + } + +// Look for a decimal fraction part. + + if (c === '.') { + i += 1; + str += c; + for (;;) { + c = this.charAt(i); + if (c < '0' || c > '9') { + break; + } + i += 1; + str += c; + } + } + +// Look for an exponent part. + + if (c === 'e' || c === 'E') { + i += 1; + str += c; + c = this.charAt(i); + if (c === '-' || c === '+') { + i += 1; + str += c; + c = this.charAt(i); + } + if (c < '0' || c > '9') { + make('number', str).error("Bad exponent"); + } + do { + i += 1; + str += c; + c = this.charAt(i); + } while (c >= '0' && c <= '9'); + } + +// Make sure the next character is not a letter. + + if (c >= 'a' && c <= 'z') { + str += c; + i += 1; + make('number', str).error("Bad number"); + } + +// Convert the string value to a number. If it is finite, then it is a good +// token. + + n = +str; + if (isFinite(n)) { + result.push(make('number', n)); + } else { + make('number', str).error("Bad number"); + } + +// string + + } else if (c === '\'' || c === '"') { + str = ''; + q = c; + i += 1; + for (;;) { + c = this.charAt(i); + if (c < ' ') { + make('string', str).error(c === '\n' || c === '\r' || c === '' ? + "Unterminated string." : + "Control character in string.", make('', str)); + } + +// Look for the closing quote. + + if (c === q) { + break; + } + +// Look for escapement. + + if (c === '\\') { + i += 1; + if (i >= length) { + make('string', str).error("Unterminated string"); + } + c = this.charAt(i); + switch (c) { + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'u': + if (i >= length) { + make('string', str).error("Unterminated string"); + } + c = parseInt(this.substr(i + 1, 4), 16); + if (!isFinite(c) || c < 0) { + make('string', str).error("Unterminated string"); + } + c = String.fromCharCode(c); + i += 4; + break; + } + } + str += c; + i += 1; + } + i += 1; + result.push(make('string', str)); + c = this.charAt(i); + +// comment. + + } else if (c === '/' && this.charAt(i + 1) === '/') { + i += 1; + for (;;) { + c = this.charAt(i); + if (c === '\n' || c === '\r' || c === '') { + break; + } + i += 1; + } + +// combining + + } else if (prefix.indexOf(c) >= 0) { + str = c; + i += 1; + while (i < length) { + c = this.charAt(i); + if (suffix.indexOf(c) < 0) { + break; + } + str += c; + i += 1; + } + result.push(make('operator', str)); + +// single-character operator + + } else { + i += 1; + result.push(make('operator', c)); + c = this.charAt(i); + } + } + return result; +}; + diff --git a/planetstack/core/xoslib/static/xsh/utils.js b/planetstack/core/xoslib/static/xsh/utils.js new file mode 100644 index 0000000..1ded27e --- /dev/null +++ b/planetstack/core/xoslib/static/xsh/utils.js @@ -0,0 +1,81 @@ +// Try Mongo +// +// Copyright (c) 2009 Kyle Banker +// Licensed under the MIT licence. +// http://www.opensource.org/licenses/mit-license.php + +// extending array like this is breaking datatables + +/*Array.prototype.include = function(value) { + for(var i=0; i < this.length; i++) { + if(this[i] == value) { + return this[i]; + } + } + return false; +}; + +Array.prototype.empty = function() { + return (this.length == 0); +};*/ + +function ArrayInclude(arr,value) { + for(var i=0; i < arr.length; i++) { + if(arr[i] == value) { + return arr[i]; + } + } + return false; +}; + +Function.prototype.bind = function() { + var __method = this, object = arguments[0], args = []; + + for(i = 1; i < arguments.length; i++) { + args.push(arguments[i]); + } + + return function() { + return __method.apply(object, args); + }; +}; + +String.prototype.trim = function() { + return this.replace(/^\s+|\s+$/g,""); +}; + +// Prints javascript types as readable strings. +Inspect = function(obj) { + if(typeof(obj) != 'object') { + return obj; + } + + else if (obj instanceof Array) { + var objRep = []; + for(var prop in obj) { + if(obj.hasOwnProperty(prop)) { + objRep.push(obj[prop]); + } + } + return '[' + objRep.join(', ') + ']'; + } + + else { + var objRep = []; + for(var prop in obj) { + if(obj.hasOwnProperty(prop)) { + objRep.push(prop + ': ' + ((typeof(obj[prop]) == 'object') ? Inspect(obj[prop]) : obj[prop])); + } + } + return '{' + objRep.join(', ') + '}'; + } +}; + +// Prints an array of javascript objects. +CollectionInspect = function(coll) { + var str = ''; + for(var i=0; i'; + } + return str; +}; diff --git a/planetstack/core/xoslib/static/xsh/xsh.js b/planetstack/core/xoslib/static/xsh/xsh.js new file mode 100644 index 0000000..c2073e4 --- /dev/null +++ b/planetstack/core/xoslib/static/xsh/xsh.js @@ -0,0 +1,405 @@ +// TryMongo +// +// Copyright (c) 2009 Kyle Banker +// Licensed under the MIT Licence. +// http://www.opensource.org/licenses/mit-license.php + +// Readline class to handle line input. +var ReadLine = function(options) { + this.options = options || {}; + this.htmlForInput = this.options.htmlForInput; + this.inputHandler = this.options.handler || this.mockHandler; + this.scoper = this.options.scoper; + this.terminal = $(this.options.terminalId || "#terminal"); + this.lineClass = this.options.lineClass || '.readLine'; + this.history = []; + this.historyPtr = 0; + + this.initialize(); +}; + +ReadLine.prototype = { + + initialize: function() { + this.addInputLine(); + }, + + // Enter a new input line with proper behavior. + addInputLine: function(stackLevel) { + stackLevel = stackLevel || 0; + this.terminal.append(this.htmlForInput(stackLevel)); + var ctx = this; + ctx.activeLine = $(this.lineClass + '.active'); + + // Bind key events for entering and navigting history. + ctx.activeLine.bind("keydown", function(ev) { + switch (ev.keyCode) { + case EnterKeyCode: + ctx.processInput(this.value); + break; + case UpArrowKeyCode: + ctx.getCommand('previous'); + break; + case DownArrowKeyCode: + ctx.getCommand('next'); + break; + } + }); + + this.activeLine.focus(); + }, + + // Returns the 'next' or 'previous' command in this history. + getCommand: function(direction) { + if(this.history.length === 0) { + return; + } + this.adjustHistoryPointer(direction); + this.activeLine[0].value = this.history[this.historyPtr]; + $(this.activeLine[0]).focus(); + //this.activeLine[0].value = this.activeLine[0].value; + }, + + // Moves the history pointer to the 'next' or 'previous' position. + adjustHistoryPointer: function(direction) { + if(direction == 'previous') { + if(this.historyPtr - 1 >= 0) { + this.historyPtr -= 1; + } + } + else { + if(this.historyPtr + 1 < this.history.length) { + this.historyPtr += 1; + } + } + }, + + // Return the handler's response. + processInput: function(value) { + var response = this.inputHandler.apply(this.scoper, [value]); + this.insertResponse(response.result); + + // Save to the command history... + if((lineValue = value.trim()) !== "") { + this.history.push(lineValue); + this.historyPtr = this.history.length; + } + + // deactivate the line... + this.activeLine.value = ""; + this.activeLine.attr({disabled: true}); + this.activeLine.removeClass('active'); + + // and add add a new command line. + this.addInputLine(response.stack); + }, + + insertResponse: function(response) { + if((response.length < 1) || (response=='"donotprintme"') || (response=='donotprintme')) { + this.activeLine.parent().append("

"); + } + else { + this.activeLine.parent().append("

" + response + "

"); + } + }, + + // Simply return the entered string if the user hasn't specified a smarter handler. + mockHandler: function(inputString) { + return function() { + this._process = function() { return inputString; }; + }; + } +}; + +var MongoHandler = function() { + this._currentCommand = ""; + this._rawCommand = ""; + this._commandStack = 0; + this._tutorialPtr = 0; + this._tutorialMax = 4; + + this._mongo = {}; + this._mongo.test = []; + this.collections = []; +}; + +MongoHandler.prototype = { + + _process: function(inputString, errorCheck) { + this._rawCommand += ' ' + inputString; + + try { + inputString += ' '; // fixes certain bugs with the tokenizer. + var tokens = inputString.tokens(); + var mongoFunc = this._getCommand(tokens); + if(this._commandStack === 0 && inputString.match(/^\s*$/)) { + return {stack: 0, result: ''}; + } + else if(this._commandStack === 0 && mongoFunc) { + this._resetCurrentCommand(); + return {stack: 0, result: mongoFunc.apply(this, [tokens])}; + } + else { + return this._evaluator(tokens); + } + } + + catch(err) { + this._resetCurrentCommand(); + console.trace(); + return {stack: 0, result: "JS Error: " + err}; + } + }, + + // Calls eval on the input string when ready. + _evaluator: function(tokens) { + isAssignment = tokens.length>=2 && tokens[0].type=="name" && tokens[1].type=="operator" && tokens[1].value=="="; + + this._currentCommand += " " + this._massageTokens(tokens); + if(this._shouldEvaluateCommand(tokens)) { + print = this.print; + + // So this eval statement is the heart of the REPL. + var result = eval(this._currentCommand.trim()); + if(result === undefined) { + throw('result is undefined'); + } else if (typeof(result) === 'function') { + throw('result is a function. did you mean to call it?'); + } else { + result = $htmlFormat(result); + } + this._resetCurrentCommand(); + if (isAssignment) { + return {stack: this._commandStack, result: ""}; + } else { + return {stack: this._commandStack, result: result}; + } + } + + else { + return {stack: this._commandStack, result: ""}; + } + }, + + _resetCurrentCommand: function() { + this._currentCommand = ''; + this._rawCommand = ''; + }, + + // Evaluate only when we've exited any blocks. + _shouldEvaluateCommand: function(tokens) { + for(var i=0; i < tokens.length; i++) { + var token = tokens[i]; + if(token.type == 'operator') { + if(token.value == '(' || token.value == '{') { + this._commandStack += 1; + } + else if(token.value == ')' || token.value == '}') { + this._commandStack -= 1; + } + } + } + + if(this._commandStack === 0) { + return true; + } + else { + return false; + } + }, + + _massageTokens: function(tokens) { + for(var i=0; i < tokens.length; i++) { + if(tokens[i].type == 'name') { + if(tokens[i].value == 'var') { + tokens[i].value = ''; + } + } + } + return this._collectTokens(tokens); + }, + + // Collects tokens into a string, placing spaces between variables. + // This methods is called after we scope the vars. + _collectTokens: function(tokens) { + var result = ""; + for(var i=0; i < tokens.length; i++) { + if(tokens[i].type == "name" && tokens[i+1] && tokens[i+1].type == 'name') { + result += tokens[i].value + ' '; + } + else if (tokens[i].type == 'string') { + result += "'" + tokens[i].value + "'"; + } + else { + result += tokens[i].value; + } + } + return result; + }, + + // print output to the screen, e.g., in a loop + // TODO: remove dependency here + print: function() { + $('.readLine.active').parent().append('

' + JSON.stringify(arguments[0]) + '

'); + return "donotprintme"; + }, + + /* MongoDB */ + /* ________________________________________ */ + + // help command + _help: function() { + return PTAG('HELP') + + PTAG('xos list xos API object types') + + PTAG('xos.slices list methods to can call on slices') + + PTAG('xos.slices.all() get all slices') + + PTAG('xos.slices.filter({key: "value"}) filter using dictionary') + + PTAG('xos.slices.get({key: "value"}) get using dictionary') + + }, + + _tutorial: function() { + this._tutorialPtr = 0; + return PTAG("This is a self-guided tutorial on the xos shell.") + + PTAG("The tutorial is simple, more or less a few basic commands to try.") + + PTAG("To go directly to any part tutorial, enter one of the commands t0, t1, t2...t10") + + PTAG("Otherwise, use 'next' and 'back'. Start by typing 'next' and pressing enter."); + }, + + // go to the next step in the tutorial. + _next: function() { + if(this._tutorialPtr < this._tutorialMax) { + return this['_t' + (this._tutorialPtr + 1)](); + } + else { + return "You've reached the end of the tutorial. To go to the beginning, type 'tutorial'"; + } + }, + + // go to the previous step in the tutorial. + _back: function() { + if(this._tutorialPtr > 1) { + return this['_t' + (this._tutorialPtr - 1)](); + } + else { + return this._tutorial(); + } + }, + + _t1: function() { + this._tutorialPtr = 1; + return PTAG('1. JavaScript Shell') + + PTAG('The first thing to notice is that the MongoDB shell is JavaScript-based.') + + PTAG('So you can do things like:') + + PTAG(' a = 5; ') + + PTAG(' a * 10; ') + + PTAG(' print(a); ') + + PTAG(" for(i=0; i<10; i++) { print('hello'); }; ") + + PTAG("Try a few JS commands; when you're ready to move on, enter 'next'"); + + }, + + _t2: function() { + this._tutorialPtr = 2; + return PTAG('2. The API is asynchronous') + + PTAG('Try these:') + + PTAG(' xos.slices.fetch();') + + PTAG(' // wait a second or two...') + + PTAG(' xos.slices.objects();'); + + }, + + _t3: function() { + this._tutorialPtr = 3; + return PTAG('3. Filter some objects') + + PTAG('Try these:'); + + }, + + _t4: function() { + this._tutorialPtr = 4; + return PTAG('4. Available xos objects and methods') + + PTAG('Try these:') + + PTAG(' xos;') + + PTAG(' xos.slices;'); + + }, + + _getCommand: function(tokens) { + if(tokens[0] && ArrayInclude(MongoKeywords,(tokens[0].value + '').toLowerCase())) { + switch(tokens[0].value.toLowerCase()) { + case 'help': + return this._help; + + case 'tutorial': + return this._tutorial; + case 'next': + return this._next; + case 'back': + return this._back; + case 't0': + return this._tutorial; + case 't1': + return this._t1; + case 't2': + return this._t2; + case 't3': + return this._t3; + case 't4': + return this._t4; + } + } + } +}; + +function replaceAll(find, replace, str) { + return str.replace(new RegExp(find, 'g'), replace); +} + +/* stackoverflow: http://stackoverflow.com/questions/4810841/how-can-i-pretty-print-json-using-javascript */ +function syntaxHighlight(json) { + if ( json.hasOwnProperty("__str__")) { + return syntaxHighlight(json.__str__()); + } + if (typeof json != 'string') { + json = JSON.stringify(json, undefined, "\t"); + } + json = json.replace(/&/g, '&').replace(//g, '>'); + return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { + var cls = 'terminal_number'; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = 'terminal_key'; + } else { + cls = 'terminal_string'; + } + } else if (/true|false/.test(match)) { + cls = 'terminal_boolean'; + } else if (/null/.test(match)) { + cls = 'terminal_null'; + } + return '' + match + ''; + }); +} + +$htmlFormat = function(obj) { + //JSON.stringify(obj,undefined,2) + result=replaceAll("\t"," ",replaceAll("\n","
",syntaxHighlight(obj))); //tojson(obj, ' ', ' ', true); + return result; +} + +function startTerminal() { + var mongo = new MongoHandler(); + var terminal = new ReadLine({htmlForInput: DefaultInputHtml, + handler: mongo._process, + scoper: mongo}); + $("#terminal_help1").show(); + $("#terminal_help2").show(); + $("#terminal_wait").hide(); + + $("#terminal").bind('click', function() { $(".readLine.active").focus(); }); +}; + +$(document).ready(function() { + startTerminal(); +}); diff --git a/planetstack/core/xoslib/up.sh b/planetstack/core/xoslib/up.sh index 1121892..bc2d469 100755 --- a/planetstack/core/xoslib/up.sh +++ b/planetstack/core/xoslib/up.sh @@ -1,3 +1,4 @@ scp static/js/*.js princeton_planetstack@node43.princeton.vicci.org:/opt/planetstack/core/xoslib/static/js/ scp templates/mustache/*.mustache princeton_planetstack@node43.princeton.vicci.org:/opt/planetstack/core/xoslib/templates/mustache/ +scp static/xsh/*.js princeton_planetstack@node43.princeton.vicci.org:/opt/planetstack/core/xoslib/static/xsh/ scp dashboards/*.html princeton_planetstack@node43.princeton.vicci.org:/opt/planetstack/templates/admin/dashboard/