Skip to content
This repository has been archived by the owner on Jun 30, 2024. It is now read-only.

Commit

Permalink
Initial support for viewing attachments when grading
Browse files Browse the repository at this point in the history
  • Loading branch information
bnmnetp committed Dec 18, 2022
1 parent 02dd938 commit a368700
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 13 deletions.
34 changes: 33 additions & 1 deletion controllers/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

# Third Party library
# -------------------
import boto3, botocore
from dateutil.parser import parse
from rs_grading import _get_assignment, send_lti_grades
from runestone import cmap
Expand Down Expand Up @@ -1618,7 +1619,38 @@ def htmlsrc():
htmlsrc and htmlsrc[0:2] == "\\x"
): # Workaround Python3/Python2 SQLAlchemy/DAL incompatibility with text columns
htmlsrc = htmlsrc.decode("hex")
return json.dumps(htmlsrc)

result = {"htmlsrc": htmlsrc}
logger.debug("htmlsrc = {htmlsrc}")
if "data-attachment" in htmlsrc:
# get the URL for the attachment, but we need the course, the user and the divid
session = boto3.session.Session()
client = session.client(
"s3",
config=botocore.config.Config(s3={"addressing_style": "virtual"}),
region_name=settings.region,
endpoint_url="https://nyc3.digitaloceanspaces.com",
aws_access_key_id=settings.spaces_key,
aws_secret_access_key=settings.spaces_secret,
)

prepath = f"{auth.user.course_name}/{acid}/{studentId}"
logger.debug(f"checking path {prepath}")
response = client.list_objects(Bucket=settings.bucket, Prefix=prepath)
logger.debug(f"response = {response}")
if response and "Contents" in response:
obj = response["Contents"][0]
logger.debug("key = {obj['Key']}")
url = client.generate_presigned_url(
ClientMethod="get_object",
Params={"Bucket": settings.bucket, "Key": obj["Key"]},
ExpiresIn=300,
)

else:
url = ""
result["attach_url"] = url
return json.dumps(result)


@auth.requires(
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,7 @@ services:
ADS_FILE: '${ADS_FILE}'
QUICK_START: ${QUICK_START}
WORKER_NAME: ${HOSTNAME}
SPACES_KEY: ${SPACES_KEY}
SPACES_SECRET: ${SPACES_SECRET}
links:
- jobe
2 changes: 2 additions & 0 deletions docker/nginx/sites-available/runestone.template
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ server {
#
# _`gunicorn socket`: This matches the ``--bind`` parameter when `gunicorn is run <run_bookserver>`.
proxy_pass http://unix:/run/fastapi.sock:/;
# For file uploads we need a larger limit than 1M for whiteboard pictures and pdf uploads
client_max_body_size 25M;
}

location / {
Expand Down
80 changes: 75 additions & 5 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions production/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@ services:
LOGIN_URL: "/runestone/default/user"
ADS_FILE: '${ADS_FILE}'
WORKER_NAME: ${HOSTNAME}
SPACES_KEY: ${SPACES_KEY}
SPACES_SECRET: ${SPACES_SECRET}


1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pretext = "^1.0.0"

# Development dependencies
# ========================
boto3 = "^1.26.30"
[tool.poetry.dev-dependencies]
black = "~= 22.0"
bookserver = { path = "../BookServer", develop = true }
Expand Down
11 changes: 8 additions & 3 deletions static/js/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@ function createGradingPanel(element, acid, studentId, multiGrader) {
}
}
$.getJSON("/runestone/admin/htmlsrc", data, async function (result) {
var htmlsrc = result;
var htmlsrc = result.htmlsrc;
const attachURL = result.attach_url;
var enforceDeadline = $("#enforceDeadline").is(":checked");
var dl = showDeadline();
await renderRunestoneComponent(htmlsrc, elementID + ">#questiondisplay", {
Expand All @@ -367,6 +368,7 @@ function createGradingPanel(element, acid, studentId, multiGrader) {
tzoff: new Date().getTimezoneOffset() / 60,
multiGrader: multiGrader,
gradingContainer: elementID,
attachURL: attachURL,
});
});

Expand Down Expand Up @@ -1816,14 +1818,17 @@ function create_question(formdata) {
}

// Given a question ID, preview it.
// This is NOT the function used to generate the grading panel on the grades page
// this is used in other places.
function preview_question_id(question_id, preview_div, sid, gradeit) {
if (arguments.length == 1) {
preview_div = "component-preview";
}
// Request the preview HTML from the server.
$.getJSON("/runestone/admin/htmlsrc", {
acid: question_id,
}).done(function (html_src) {
}).done(function (jsonData) {
html_src = jsonData.htmlsrc
// Render it.
data = { acid: question_id };
if (sid) {
Expand Down Expand Up @@ -2058,7 +2063,7 @@ async function renderRunestoneComponent(componentSrc, whereDiv, moreOpts) {
}
// $(`#${whereDiv}`).css("background-color", "white");
}
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
MathJax.typeset([document.querySelector(`#${whereDiv}`)])
}

// Called by the "Search" button in the "Search question bank" panel.
Expand Down
4 changes: 0 additions & 4 deletions views/assignments/doAssignment.html
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,6 @@ <h5 style='text-align:center;'>Not yet graded</h5>
selfGrade({{=assignment['id']}})
});

$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});

</script>
<script src="/runestone/static/js/selfgrade.js" type="text/javascript"></script>
<script src="/runestone/static/js/markcomplete.js" type="text/javascript"></script>

0 comments on commit a368700

Please sign in to comment.