-
Wade Fagen-Ulmschneider (waf) authoredWade Fagen-Ulmschneider (waf) authored
workbook.py 3.99 KiB
# 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)
@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."
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()