forked from google/rekall
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Submitting Manuskript library + webconsole implementation.
Adding webconsole-related dependencies to setup.py. NOTE: bower_components folder contains third-party JS libraries. BUG= R=scudette@gmail.com Review URL: https://codereview.appspot.com/87820043
- Loading branch information
Showing
1,189 changed files
with
130,535 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import StringIO | ||
|
||
|
||
class Plugin(object): | ||
ANGULAR_MODULE = None | ||
|
||
JS_FILES = [] | ||
CSS_FILES = [] | ||
|
||
@classmethod | ||
def PlugIntoApp(cls, app): | ||
pass | ||
|
||
@classmethod | ||
def GenerateHTML(cls): | ||
out = StringIO.StringIO() | ||
|
||
for js_file in cls.JS_FILES: | ||
out.write("""<script src="%s"></script>\n""" % js_file) | ||
|
||
for css_file in cls.CSS_FILES: | ||
out.write("""<link rel="stylesheet" href="%s"></link>\n""" % | ||
css_file) | ||
|
||
if cls.ANGULAR_MODULE: | ||
out.write(""" | ||
<script>var manuskriptPluginsList = manuskriptPluginsList || [];\n | ||
manuskriptPluginsList.push("%s");</script>\n""" % cls.ANGULAR_MODULE) | ||
|
||
return out.getvalue() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from manuskript.plugins.plaintext import PlainText | ||
from manuskript.plugins.markdown import Markdown | ||
from manuskript.plugins.pythoncall import PythonCall |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from manuskript import plugin | ||
|
||
|
||
class Markdown(plugin.Plugin): | ||
ANGULAR_MODULE = "manuskript.markdown" | ||
|
||
JS_FILES = ["/static/components/markdown/markdown-controller.js", | ||
"/static/components/markdown/markdown.js"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from manuskript import plugin | ||
|
||
|
||
class PlainText(plugin.Plugin): | ||
ANGULAR_MODULE = "manuskript.plaintext" | ||
|
||
JS_FILES = ["/static/components/plaintext/plaintext-controller.js", | ||
"/static/components/plaintext/plaintext.js"] | ||
CSS_FILES = ["/static/components/plaintext/plaintext.css"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
from flask import jsonify | ||
from flask import request | ||
|
||
from manuskript import plugin | ||
from manuskript import pythonshell | ||
|
||
|
||
class PythonCall(plugin.Plugin): | ||
ANGULAR_MODULE = "manuskript.pythoncall" | ||
|
||
JS_FILES = ["/static/components/pythoncall/renderer-service.js", | ||
"/static/components/pythoncall/pythoncall-controller.js", | ||
"/static/components/pythoncall/pythoncall.js"] | ||
|
||
CSS_FILES = ["/static/components/pythoncall/pythoncall.css"] | ||
|
||
@classmethod | ||
def UpdatePythonShell(cls, app, shell): | ||
pass | ||
|
||
@classmethod | ||
def PlugIntoApp(cls, app): | ||
|
||
@app.route("/session/reset", methods=["POST"]) | ||
def session_reset(): # pylint: disable=unused-variable | ||
app.config[cls.__name__] = shell = pythonshell.PythonShell() | ||
cls.UpdatePythonShell(app, shell) | ||
|
||
@app.route("/controllers/pythoncall", methods=["POST"]) | ||
def python_call(): # pylint: disable=unused-variable | ||
if cls.__name__ not in app.config: | ||
app.config[cls.__name__] = shell = pythonshell.PythonShell() | ||
cls.UpdatePythonShell(app, shell) | ||
shell = app.config[cls.__name__] | ||
|
||
source_code = request.get_json()["source"] | ||
|
||
result = None | ||
error = None | ||
is_parsing_error = False | ||
|
||
try: | ||
stdout, stderr, result = shell.Exec("\n".join(source_code)) | ||
except pythonshell.ParseError as e: | ||
stdout, stderr, error = "", "", e.original_error | ||
is_parsing_error = True | ||
except pythonshell.ExecError as e: | ||
stdout, stderr, error = e.stdout, e.stderr, e.original_error | ||
|
||
stdout_lines = stdout and stdout.split("\n") or [] | ||
stderr_lines = stderr and stderr.split("\n") or [] | ||
if not error: | ||
result_lines = result and str(result).split("\n") or [] | ||
error_lines = [] | ||
else: | ||
result_lines = [] | ||
error_lines = str(error).split("\n") | ||
|
||
response = jsonify(data=dict(stdout=stdout_lines, | ||
stderr=stderr_lines, | ||
result=result_lines, | ||
error=error_lines, | ||
is_parsing_error=is_parsing_error, | ||
execution_count=shell.execution_count)) | ||
return response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import ast | ||
import codegen | ||
import StringIO | ||
import sys | ||
|
||
|
||
class Error(Exception): | ||
"""PythonShell-specific error.""" | ||
|
||
|
||
class ParseError(Error): | ||
"""Thrown when supplied code can't be parsed.""" | ||
|
||
def __init__(self, original_error): | ||
super(ParseError, self).__init__() | ||
self.original_error = original_error | ||
|
||
|
||
class ExecError(Error): | ||
"""Thrown when supplied code raises exception during execution.""" | ||
|
||
def __init__(self, stdout, stderr, original_error): | ||
super(ExecError, self).__init__() | ||
self.stdout = stdout | ||
self.stderr = stderr | ||
self.original_error = original_error | ||
|
||
|
||
class PythonShell(object): | ||
"""Implementation of the python shell.""" | ||
|
||
def __init__(self, global_context=None, local_context=None, | ||
filename="<unknown>"): | ||
super(PythonShell, self).__init__() | ||
self.global_context = global_context or {} | ||
self.local_context = local_context or {} | ||
self.filename = filename | ||
self.execution_count = 0 | ||
|
||
def Exec(self, source): | ||
self.execution_count += 1 | ||
|
||
try: | ||
nodes = ast.parse(source, self.filename) | ||
except IndentationError as e: | ||
raise ParseError(e) | ||
except (OverflowError, SyntaxError, ValueError, | ||
TypeError, MemoryError) as e: | ||
raise ParseError(e) | ||
|
||
stdout = StringIO.StringIO() | ||
stderr = StringIO.StringIO() | ||
prev_stdout = sys.stdout | ||
prev_stderr = sys.stderr | ||
sys.stdout = stdout | ||
sys.stderr = stderr | ||
|
||
try: | ||
if isinstance(nodes.body[-1], ast.Expr): | ||
exec_nodes = nodes.body[:-1] | ||
interactive_nodes = nodes.body[-1:] | ||
else: | ||
exec_nodes, interactive_nodes = nodes.body, [] | ||
|
||
for node in exec_nodes: | ||
mod = ast.Module([node]) | ||
code = compile(mod, self.filename, "exec") | ||
exec(code, self.global_context, self.local_context) | ||
|
||
result = None | ||
for node in interactive_nodes: | ||
source = codegen.to_source(node) | ||
new_node = ast.parse(source, self.filename, mode="eval") | ||
mod = ast.Expression(new_node.body) | ||
code = compile(mod, self.filename, "eval") | ||
result = eval(code, self.global_context, self.local_context) | ||
|
||
sys.stdout = prev_stdout | ||
sys.stderr = prev_stderr | ||
|
||
return stdout.getvalue(), stderr.getvalue(), result | ||
except Exception as e: | ||
raise ExecError(stdout.getvalue(), stderr.getvalue(), e) | ||
|
||
finally: | ||
sys.stdout = prev_stdout | ||
sys.stderr = prev_stderr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import os | ||
import StringIO | ||
|
||
from flask import Flask | ||
from flask import current_app | ||
from flask import helpers | ||
|
||
from manuskript import plugins as manuskript_plugins | ||
|
||
|
||
STATIC_PATH = os.path.join(os.path.dirname(__file__), "static") | ||
|
||
DEFAULT_PLUGINS = [manuskript_plugins.PlainText, | ||
manuskript_plugins.Markdown, | ||
manuskript_plugins.PythonCall] | ||
|
||
|
||
def RunServer(host="localhost", port=5000, debug=False, plugins=None, | ||
config=None): | ||
if not plugins: | ||
plugins = DEFAULT_PLUGINS | ||
|
||
if not config: | ||
config = {} | ||
|
||
app = Flask(__name__, static_folder=STATIC_PATH) | ||
app.config["manuskript_plugins"] = plugins | ||
|
||
# Configure index route | ||
@app.route("/") | ||
def index(): # pylint: disable=unused-variable | ||
plugins_snippets = [p.GenerateHTML() | ||
for p in current_app.config['manuskript_plugins']] | ||
|
||
with open(os.path.join(STATIC_PATH, "index.html")) as fd: | ||
contents = fd.read() | ||
contents = contents.replace("<!-- manuskript-plugins -->", | ||
"\n".join(plugins_snippets)) | ||
|
||
return helpers.send_file(StringIO.StringIO(contents), | ||
mimetype="text/html", | ||
conditional=True) | ||
|
||
# Turn off caching for easier development/debugging | ||
@app.after_request | ||
def add_header(response): # pylint: disable=unused-variable | ||
"""Turn off caching for easier debugging.""" | ||
response.headers['Cache-Control'] = 'no-cache, no-store' | ||
return response | ||
|
||
for plugin_cls in plugins: | ||
plugin_cls.PlugIntoApp(app) | ||
|
||
for k, v in config.items(): | ||
app.config[k] = v | ||
|
||
app.run(host=host, port=port, debug=debug) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import argparse | ||
|
||
from manuskript import server | ||
|
||
|
||
PARSER = argparse.ArgumentParser() | ||
PARSER.add_argument("--host", type=str, | ||
help="Web server host address.") | ||
PARSER.add_argument("--port", type=int, | ||
help="Web server port.") | ||
PARSER.add_argument("--debug", type=bool, | ||
help="If true, reload files on change.") | ||
|
||
|
||
def main(): | ||
args = PARSER.parse_args() | ||
server.RunServer(host=args.host, port=args.port, debug=args.debug) | ||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{ | ||
"node" : true, | ||
"browser" : true, | ||
"es5" : true, | ||
"esnext" : true, | ||
"bitwise" : true, | ||
"camelcase": true, | ||
"curly" : true, | ||
"eqeqeq" : true, | ||
"immed" : true, | ||
"indent" : 2, | ||
"latedef" : true, | ||
"newcap" : true, | ||
"noarg" : true, | ||
"quotmark" : "single", | ||
"regexp" : true, | ||
"undef" : true, | ||
"unused" : true, | ||
"strict" : true, | ||
"trailing" : false, | ||
"smarttabs": true, | ||
"white" : false, | ||
"globals" : { | ||
"$" : false, | ||
"angular" : false, | ||
"browser" : false, | ||
"repeater" : false, | ||
"element" : false, | ||
"inject" : false, | ||
"afterEach" : false, | ||
"beforeEach" : false, | ||
"confirm" : false, | ||
"context" : false, | ||
"describe" : false, | ||
"expect" : false, | ||
"it" : false, | ||
"jasmine" : false, | ||
"JSHINT" : false, | ||
"mostRecentAjaxRequest": false, | ||
"qq" : false, | ||
"runs" : false, | ||
"spyOn" : false, | ||
"spyOnEvent" : false, | ||
"waitsFor" : false, | ||
"xdescribe" : false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
var path = require('path'); | ||
|
||
module.exports = function(grunt) { | ||
grunt.initConfig({ | ||
pkg: grunt.file.readJSON('package.json'), | ||
|
||
jshint: { | ||
files: ['*.js', 'components/**/*.js'], | ||
options: { | ||
jshintrc: true, | ||
} | ||
} | ||
}); | ||
|
||
grunt.loadNpmTasks('grunt-contrib-jshint'); | ||
|
||
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint']); | ||
} |
Oops, something went wrong.