Newer
Older
# enable logging
import workbook_logging
import logging
logger = logging.getLogger("workbook")
# helper functions
from workbook_utilities import run_compute_py, read_project_json, construct_navigation, read_metadata_json, create_new_dir
# flask
from flask import Flask, render_template, jsonify, send_file, send_from_directory, request
# core python libraries
import os
import sys
import json
import traceback
# Create the flask application object
app = Flask(__name__)
# Don't assume a template prefix name (allows for the app to serve templates
# from both templates/ and <project>/web/).
app.template_folder = '.'
# Turn on debug messages, direct them to the console
app.debug = True
app.logger.addHandler(logging.StreamHandler(sys.stdout))
app.logger.setLevel(logging.ERROR)
#
# Route the base URL to the main page
#
@app.route('/', methods=["POST"])
def home_createDir():
logger.info("Processing index POST...")
error = None
success = None
newDirName = request.form["dirName"]
if os.path.isdir(newDirName):
error = "Directory <b>" + newDirName + "</b> already exists!"
else:
create_new_dir(newDirName, request.form["projectName"], request.form["projectType"])
success = "New directory <b>" + newDirName + "</b> created!"
navigation = construct_navigation()
return render_template('static/templates/mainPage.html', navigation=navigation, error=error, success=success)
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
@app.route('/')
def home():
navigation = construct_navigation()
return render_template('static/templates/mainPage.html', navigation=navigation)
#
# Files inside of /exercise/res and /exercise/web should be routed as
# static files.
#
@app.route('/<exerciseName>/res/<path:fileName>')
def fetchRes(exerciseName, fileName):
logger.info(exerciseName + ":Sending static file: " + fileName)
return send_from_directory(os.path.join(exerciseName, 'res'), fileName, cache_timeout=0)
@app.route('/<exerciseName>/web/<path:fileName>')
def fetchWeb(exerciseName, fileName):
logger.info(exerciseName + ":Sending static file: " + fileName)
return send_from_directory(os.path.join(exerciseName, 'web'), fileName, cache_timeout=0)
#
# A call to /exercise/py/ should compute (API)
#
@app.route('/<exerciseName>/py/')
def computePy(exerciseName):
logger.info(exerciseName + ":Running compute.py")
result = {}
# Load and run compute.py
try:
run_compute_py(exerciseName)
result["status"] = "Success"
logger.info(exerciseName + ":compute.py ran without exception")
except Exception as exc:
result["status"] = "Error"
result["error"] = str(exc)
result["trace"] = str(traceback.format_exc())
logger.error(exerciseName + ":compute.py generated an exception")
return jsonify(result)
#
# Route everything else to an exercise:
#
@app.route('/<projectDir>/')
def fetchExercise(projectDir):
logger.info(projectDir + ":Loading project")
# Get the project info
projectInfo = read_project_json(projectDir)
if projectInfo == None:
return "No project.json found."
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
metadata = read_metadata_json(projectDir)
# Figure out what to do based on the value of `show`
show = request.args.get('show')
showViz = False
runPython = False
if show == "viz":
showViz = True
if show == "py_viz":
showViz = True
runPython = True
if runPython:
projectInfo["ranCompute"] = True
run_compute_py(projectDir)
else:
projectInfo["ranCompute"] = False
navigation = construct_navigation()
if showViz:
projectInfo["showingViz"] = True
return render_template(projectDir + '/web/index.html', project=projectInfo, navigation=navigation, metadata=metadata)
else:
# Project landing page
projectInfo["showingViz"] = False
return render_template('static/templates/projectLanding.html', project=projectInfo, navigation=navigation, metadata=metadata)
#
# Start the server with the `run` method
#
if __name__ == '__main__':
app.run()