Source code for howamidoing.server.main

import json
import os
import sys

from common.course_config import get_course
from common.db import connect_db, transaction_db
from common.oauth_client import create_oauth_client, get_user, is_logged_in, is_staff
from common.rpc.howamidoing import upload_grades as rpc_upload_grades
from common.rpc.secrets import only
from common.rpc.auth import validate_secret
from setup_functions import set_default_config, set_grades

from flask import Flask, redirect, request, jsonify, render_template, Response

CONSUMER_KEY = "61a-grade-view"

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

AUTHORIZED_ROLES = ["staff", "instructor", "grader"]

DEV = os.getenv("ENV") != "prod"

IS_SPHINX = "sphinx" in sys.argv[0]


with connect_db() as db:
    db(
        """CREATE TABLE IF NOT EXISTS configs (
       courseCode varchar(128),
       config LONGBLOB)"""
    )
    db(
        """CREATE TABLE IF NOT EXISTS students (
       courseCode varchar(128),
       email varchar(128),
       shortData varchar(256),
       data BLOB)"""
    )
    db(
        """CREATE TABLE IF NOT EXISTS headers (
       courseCode varchar(128),
       header BLOB)"""
    )
    db(
        """CREATE TABLE IF NOT EXISTS lastUpdated (
       courseCode varchar(128),
       lastUpdated TIMESTAMP)"""
    )

if DEV and not IS_SPHINX:
    with connect_db() as db:
        with open("./public/config/dummy_grade_data.csv") as grades:
            set_grades(grades.read(), "cs61a", db)
        set_default_config(db)


[docs]def last_updated(): """Finds the timestamp of when the current database was last updated for this course. Uses a database query function yielded by :func:`common.db.connect_db` and the course code returned by :func:`common.course_config.get_course` :return: Timestamp or ``Unknown`` (string) if any exceptions occur while fetching from the current database """ try: with connect_db() as db: return db( "SELECT lastUpdated from lastUpdated where courseCode=%s", [get_course()], ).fetchone()[0] except: return "Unknown"
def create_client(app): @app.route("/") def index(): return render_template("index.html", courseCode=get_course()) @app.route("/histogram") def histogram(): return render_template("index.html", courseCode=get_course()) @app.route("/redirect") def ohlord(): return redirect("https://howamidoing.cs61a.org") @app.route("/edit") def config_editor(): return render_template("index.html", courseCode=get_course()) @app.route("/config/config.js") def config(): with connect_db() as db: data = db( "SELECT config FROM configs WHERE courseCode=%s", [get_course()] ).fetchone() print(data) return Response(data, mimetype="application/javascript") @app.route("/query/") def query(): try: if is_logged_in(): user = get_user() email = user["email"] target = request.args.get("target", None) if is_staff(get_course()): if target: email = target else: all_students = [] with connect_db() as db: lookup = db( "SELECT shortData FROM students WHERE courseCode=%s", [get_course()], ).fetchall() for row in lookup: parsed = json.loads(row[0]) all_students.append(parsed) return jsonify( { "success": True, "isStaff": True, "allStudents": all_students, "email": user["email"], "name": user["name"], "lastUpdated": last_updated(), } ) with connect_db() as db: [short_data, data] = db( "SELECT shortData, data FROM students WHERE courseCode=%s AND email=%s", [get_course(), email], ).fetchone() [header] = db( "SELECT header FROM headers WHERE courseCode=%s", [get_course()] ).fetchone() short_data = json.loads(short_data) data = json.loads(data) header = json.loads(header) return jsonify( { "success": True, "header": header, "data": data, "email": short_data["Email"], "name": short_data["Name"], "SID": short_data["SID"], "lastUpdated": last_updated(), } ) else: return jsonify({"success": False, "retry": True}) except Exception: pass return jsonify({"success": False, "retry": False}) @app.route("/allScores", methods=["POST"]) def all_scores(): if not is_staff(get_course()): return jsonify({"success": False}) with connect_db() as db: [header] = db( "SELECT header FROM headers WHERE courseCode=%s", [get_course()] ).fetchone() header = json.loads(header) data = db( "SELECT data FROM students WHERE courseCode=%s", get_course() ).fetchall() scores = [] for [score] in data: score = json.loads(score) scores.append(score) return jsonify({"header": header, "scores": scores}) @app.route("/setConfig", methods=["POST"]) def set_config(): if not is_staff(get_course()): return jsonify({"success": False}) data = request.form.get("data") with connect_db() as db: db("DELETE FROM configs WHERE courseCode=%s", [get_course()]) db("INSERT INTO configs VALUES (%s, %s)", [get_course(), data]) return jsonify({"success": True}) @app.route("/setGrades", methods=["POST"]) def set_grades_route(): if not is_staff(get_course()): return jsonify({"success": False}) data = request.form.get("data") with transaction_db() as db: set_grades(data, get_course(), db) return jsonify({"success": True}) @app.route("/setGradesSecret", methods=["POST"]) def set_grades_secret_route(): if validate_secret(secret=request.form.get("secret")) != "cs61a": return jsonify({"success": False}) data = request.form.get("data") with transaction_db() as db: set_grades(data, get_course(), db) return jsonify({"success": True}) @rpc_upload_grades.bind(app) @only("grade-display", allow_staging=True) def upload_grades(data: str): with transaction_db() as db: set_grades(data, get_course(), db) print = print_to_stderr(print) app = Flask( __name__, static_url_path="", static_folder="static", template_folder="static" ) if __name__ == "__main__": app.debug = True create_client(app) create_oauth_client(app, CONSUMER_KEY) if __name__ == "__main__": app.run(host="127.0.0.1", port=8000, debug=True)