From: Scott Baker Date: Thu, 19 Jun 2014 01:22:03 +0000 (-0700) Subject: shell, wip X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=bf1610dc0cf8a5d73f57933b7d7819738a480f10;p=plstackapi.git shell, wip --- diff --git a/planetstack/core/dashboard/shell/constants.js b/planetstack/core/dashboard/shell/constants.js index c7498d8..dd267e2 100644 --- a/planetstack/core/dashboard/shell/constants.js +++ b/planetstack/core/dashboard/shell/constants.js @@ -25,7 +25,7 @@ var UpArrowKeyCode = 38; var DownArrowKeyCode = 40; var PTAG = function(str) { - return "
" + str + "
"; + return '
' + str + '
'; } var BR = function() { @@ -36,4 +36,4 @@ var JavascriptKeywords = ['abstract', 'boolean', 'break', 'byte', 'case', 'catch var JavascriptClassNames = ['Array', 'String', 'Object'] -var MongoKeywords = ['help']; +var MongoKeywords = ['help','tutorial','next','back','t0','t1','t2']; diff --git a/planetstack/core/dashboard/shell/opencloud.js b/planetstack/core/dashboard/shell/opencloud.js new file mode 100644 index 0000000..52c9e5c --- /dev/null +++ b/planetstack/core/dashboard/shell/opencloud.js @@ -0,0 +1,35 @@ +var opencloud_data = []; +var opencloud_data_received = false; + +function updateOpenCloud(onLoaded) { + $.ajax({url: "/admin/shelldata", + dataType: "json", + type: "GET", + success: function(data) { + opencloud_data = data; + if (!opencloud_data_received) { + opencloud_data_received = true; + if (onLoaded!=null) { + onLoaded(); + } + } + // do this again in 30 seconds + setTimeout(function() {updateOpenCloud(onLoaded)}, 10000); + }, + error: function() { + console.log("something went wrong. trying again"); + // do this again in 30 seconds + setTimeout(function() {updateOpenCloud(onLoaded)}, 10000); + } + }); +} + +function Slices() { + this.listAll = function() { return opencloud_data["slices"] } + this.__str__ = function() { return '["listAll"]'; } +} + +function OpenCloud() { + this.slices = new Slices() + this.__str__ = function() { return '["slices"]'; } +}; diff --git a/planetstack/core/dashboard/shell/opencloud_shell.css b/planetstack/core/dashboard/shell/opencloud_shell.css index 1d64961..108004b 100644 --- a/planetstack/core/dashboard/shell/opencloud_shell.css +++ b/planetstack/core/dashboard/shell/opencloud_shell.css @@ -22,15 +22,26 @@ color: #45FF17; font-size: 18px; font-family: Monaco, monospace; + border-radius:0; } -#terminal p, #terminal pre { +#terminal p { margin: 2px; color: #45FF17; font-size: 18px; font-family: Monaco, serif; } +.terminal_help { + margin: 2px; + color: #45FF17; + font-size: 18px; + font-family: Monaco, serif; + background:black; + padding:0; + line-height:normal; +} + #terminal a { color: #6495ED; } diff --git a/planetstack/core/dashboard/shell/opencloud_shell.js b/planetstack/core/dashboard/shell/opencloud_shell.js index 634788a..8d850be 100644 --- a/planetstack/core/dashboard/shell/opencloud_shell.js +++ b/planetstack/core/dashboard/shell/opencloud_shell.js @@ -95,7 +95,7 @@ ReadLine.prototype = { }, insertResponse: function(response) { - if(response.length < 3) { + if((response.length < 1) || (response=='"donotprintme"')) { this.activeLine.parent().append("

"); } else { @@ -116,7 +116,7 @@ var MongoHandler = function() { this._rawCommand = ""; this._commandStack = 0; this._tutorialPtr = 0; - this._tutorialMax = 10; + this._tutorialMax = 2; this._mongo = {}; this._mongo.test = []; @@ -128,7 +128,7 @@ MongoHandler.prototype = { _process: function(inputString, errorCheck) { this._rawCommand += ' ' + inputString; -// try { + try { inputString += ' '; // fixes certain bugs with the tokenizer. var tokens = inputString.tokens(); var mongoFunc = this._getCommand(tokens); @@ -142,19 +142,22 @@ MongoHandler.prototype = { else { return this._evaluator(tokens); } -// } + } -// catch(err) { -// this._resetCurrentCommand(); -// return {stack: 0, result: "JS Error: " + err}; -// } + 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)) { - db = "scott"; + opencloud = new OpenCloud(); print = this.print; // So this eval statement is the heart of the REPL. @@ -165,8 +168,11 @@ MongoHandler.prototype = { result = $htmlFormat(result); } this._resetCurrentCommand(); - console.log(result); - return {stack: this._commandStack, result: result}; + if (isAssignment) { + return {stack: this._commandStack, result: ""}; + } else { + return {stack: this._commandStack, result: result}; + } } else { @@ -233,8 +239,8 @@ MongoHandler.prototype = { // print output to the screen, e.g., in a loop // TODO: remove dependency here print: function() { - $('.readLine.active').parent().append('

' + arguments[0] + '

'); - return ""; + $('.readLine.active').parent().append('

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

'); + return "donotprintme"; }, /* MongoDB */ @@ -242,8 +248,58 @@ MongoHandler.prototype = { // help command _help: function() { - return PTAG('HELP'); + return PTAG('HELP') + + PTAG('opencloud.slices.listAll() get all slices'); + + }, + + _tutorial: function() { + this._tutorialPtr = 0; + return PTAG("This is a self-guided tutorial on the OpenCloud 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. List some slices') + + PTAG('Type this:') + + PTAG(' opencloud.slices.listAll();'); + }, _getCommand: function(tokens) { @@ -251,18 +307,39 @@ MongoHandler.prototype = { 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; } } } }; $htmlFormat = function(obj) { - return tojson(obj, ' ', ' ', true); + result=tojson(obj, ' ', ' ', true); + return result; } -$(document).ready(function() { +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(); +}; + +$(document).ready(function() { + updateOpenCloud(onLoaded = startTerminal); }); diff --git a/planetstack/core/dashboard/shell/shell.html b/planetstack/core/dashboard/shell/shell.html index 416bbd5..968ef99 100644 --- a/planetstack/core/dashboard/shell/shell.html +++ b/planetstack/core/dashboard/shell/shell.html @@ -1,17 +1,19 @@

OpenCloud Shell


-

type "help" for help

-

type "tutorial" to start the tutorial

+ + +

Please wait while we talk to the OpenCloud server...

- - - - - - - + + + + + + + + diff --git a/planetstack/core/dashboard/shell/shell.py b/planetstack/core/dashboard/shell/shell.py new file mode 100644 index 0000000..850dd02 --- /dev/null +++ b/planetstack/core/dashboard/shell/shell.py @@ -0,0 +1,20 @@ +# /opt/planetstack/core/dashboard/views/helloworld.py +import os +import sys +import json +from django.http import HttpResponse, HttpResponseServerError, HttpResponseForbidden +from django.views.generic import TemplateView, View +from core.models import * +from django.forms.models import model_to_dict + +class ShellDataView(View): + url = r'^shelldata/' + + def get(self, request, **kwargs): + allSlices = [] + for slice in Slice.objects.all(): + allSlices.append(model_to_dict(slice)) + + result = {"slices": allSlices} + + return HttpResponse(json.dumps(result), mimetype='application/json') diff --git a/planetstack/core/dashboard/shell/shell_utils.js b/planetstack/core/dashboard/shell/shell_utils.js index 79b9565..8ed5f4f 100644 --- a/planetstack/core/dashboard/shell/shell_utils.js +++ b/planetstack/core/dashboard/shell/shell_utils.js @@ -350,16 +350,20 @@ tojsonObject = function( x, indent , nolint , html){ var lineEnding = nolint ? " " : "\n"; var tabSpace = nolint ? "" : "\t"; } - + assert.eq( ( typeof x ) , "object" , "tojsonObject needs object, not [" + ( typeof x ) + "]" ); - if (!indent) + if (!indent) indent = ""; - + + if ( x.hasOwnProperty("__str__")) { + return x.__str__(); + } + if ( typeof( x.tojson ) == "function" && x.tojson != tojson ) { return x.tojson(indent,nolint,html); } - + if ( typeof( x.constructor.tojson ) == "function" && x.constructor.tojson != tojson ) { return x.constructor.tojson( x, indent , nolint, html ); } @@ -368,12 +372,12 @@ tojsonObject = function( x, indent , nolint , html){ return "{ $maxKey : 1 }"; if ( x.toString() == "[object MinKey]" ) return "{ $minKey : 1 }"; - + var s = "{" + lineEnding; // push one level of indent indent += tabSpace; - + var total = 0; for ( var k in x ) total++; if ( total == 0 ) { @@ -385,7 +389,6 @@ tojsonObject = function( x, indent , nolint , html){ keys = x._simpleKeys(); var num = 1; for ( var k in keys ){ - var val = x[k]; s += indent + "\"" + k + "\" : " + tojson( val, indent , nolint );