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 DownArrowKeyCode = 40;
var PTAG = function(str) {
- return "<pre>" + str + "</pre>";
+ return '<pre class="terminal_help">' + str + '</pre>';
}
var BR = function() {
@@ -36,4 +36,4 @@
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 @@
},
insertResponse: function(response) {
- if(response.length < 3) {
+ if((response.length < 1) || (response=='"donotprintme"')) {
this.activeLine.parent().append("<p class='response'></p>");
}
else {
@@ -116,7 +116,7 @@
this._rawCommand = "";
this._commandStack = 0;
this._tutorialPtr = 0;
- this._tutorialMax = 10;
+ this._tutorialMax = 2;
this._mongo = {};
this._mongo.test = [];
@@ -128,7 +128,7 @@
_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 @@
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 @@
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 @@
// print output to the screen, e.g., in a loop
// TODO: remove dependency here
print: function() {
- $('.readLine.active').parent().append('<p>' + arguments[0] + '</p>');
- return "";
+ $('.readLine.active').parent().append('<p>' + JSON.stringify(arguments[0]) + '</p>');
+ return "donotprintme";
},
/* MongoDB */
@@ -242,27 +248,98 @@
// 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) {
if(tokens[0] && MongoKeywords.include((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;
}
}
}
};
$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 @@
<div id="terminal">
<p class="response">OpenCloud Shell</p>
<br />
- <p>type "help" for help</p>
- <p>type "tutorial" to start the tutorial</p>
+ <p id="terminal_help1" style="display: none;">type "help" for help</p>
+ <p id="terminal_help2" style="display: none;">type "tutorial" to start the tutorial</p>
+ <p id="terminal_wait">Please wait while we talk to the OpenCloud server...</p>
</div>
- <link rel="stylesheet" type="text/css" href="{% static 'opencloud_shell.css' %}" media="all">
- <script src="{% static 'opencloud_shell.js' %}"></script>
- <script src="{% static 'object_id.js' %}"></script>
- <script src="{% static 'constants.js' %}"></script>
- <script src="{% static 'utils.js' %}"></script>
- <script src="{% static 'shell_utils.js' %}"></script>
- <script src="{% static 'tokens.js' %}"></script>
+ <link rel="stylesheet" type="text/css" href="{% static 'shell/opencloud_shell.css' %}" media="all">
+ <script src="{% static 'shell/opencloud.js' %}"></script>
+ <script src="{% static 'shell/opencloud_shell.js' %}"></script>
+ <script src="{% static 'shell/object_id.js' %}"></script>
+ <script src="{% static 'shell/constants.js' %}"></script>
+ <script src="{% static 'shell/utils.js' %}"></script>
+ <script src="{% static 'shell/shell_utils.js' %}"></script>
+ <script src="{% static 'shell/tokens.js' %}"></script>
<!-- script type="text/javascript" src="js/jquery-1.3.2.min.js"></script-->
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 @@
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 @@
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 @@
keys = x._simpleKeys();
var num = 1;
for ( var k in keys ){
-
var val = x[k];
s += indent + "\"" + k + "\" : " + tojson( val, indent , nolint );