Skip to content
Snippets Groups Projects
Commit 29c623f2 authored by RABijl's avatar RABijl
Browse files

merges approve shortcut with pregrading

parents f5db63ff 94c32299
No related branches found
No related tags found
1 merge request!28combine precise positioning with pregrading
......@@ -30,6 +30,7 @@ class Grade extends React.Component {
// update the tooltips for the associated widgets (in render()).
this.props.bindShortcut(['left', 'h'], this.prev)
this.props.bindShortcut(['right', 'l'], this.next)
this.props.bindShortcut(['a'], this.approve)
this.props.bindShortcut(['shift+left', 'shift+h'], (event) => {
event.preventDefault()
this.prevUngraded()
......@@ -153,6 +154,20 @@ class Grade extends React.Component {
})
}
approve = () => {
const exam = this.props.exam
const problem = exam.problems[this.state.pIndex]
const optionURI = this.state.examID + '/' +
exam.submissions[this.state.sIndex].id + '/' +
problem.id
api.put('solution/approve/' + optionURI, {
graderID: this.props.graderID
})
.then(result => {
this.props.updateSubmission(this.state.sIndex)
})
}
toggleFullPage = (event) => {
this.setState({
fullPage: event.target.checked
......
......@@ -8,7 +8,7 @@ from .students import Students
from .submissions import Submissions
from .problems import Problems
from .feedback import Feedback
from .solutions import Solutions
from .solutions import Solutions, Approve
from .widgets import Widgets
from .emails import EmailTemplate, RenderedEmailTemplate, Email
from .mult_choice import MultipleChoice
......@@ -50,11 +50,12 @@ api.add_resource(RenderedEmailTemplate,
api.add_resource(Email,
'/email/<int:exam_id>',
'/email/<int:exam_id>/<int:student_id>')
api.add_resource(Approve,
'/solution/approve/<int:exam_id>/<int:submission_id>/<int:problem_id>')
api.add_resource(MultipleChoice,
'/mult-choice/<int:id>',
'/mult-choice/')
# Other resources that don't return JSON
# It is possible to get flask_restful to work with these, but not
# very idiomatic.
......
......@@ -9,7 +9,10 @@ from flask_restful import Resource, reqparse
from werkzeug.datastructures import FileStorage
from sqlalchemy.orm import selectinload
from ..pdf_generation import PAGE_FORMATS, generate_pdfs, output_pdf_filename_format, join_pdfs, page_is_size
from ..pdf_generation import PAGE_FORMATS, generate_pdfs, output_pdf_filename_format
from ..pdf_generation import join_pdfs, page_is_size, make_pages_even
from ..database import db, Exam, ExamWidget, Submission
......@@ -280,10 +283,9 @@ class Exams(Resource):
exam_dir = _get_exam_dir(exam.id)
pdf_path = os.path.join(exam_dir, 'exam.pdf')
os.makedirs(exam_dir, exist_ok=True)
pdf_data.save(pdf_path)
make_pages_even(pdf_path, args['pdf'])
print(f"Added exam {exam.id} (name: {exam_name}, token: {exam.token}) to database")
......
......@@ -147,3 +147,43 @@ class Solutions(Resource):
db.session.commit()
return {'state': state}
class Approve(Resource):
""" add just a grader to a specifc problem on an exam """
put_parser = reqparse.RequestParser()
put_parser.add_argument('graderID', type=int, required=True)
def put(self, exam_id, submission_id, problem_id):
"""Takes an existing feedback checks if it is valid then gives the current graders id to the solution this is
usefull for approving pre graded solutions
Parameters
----------
graderID: int
Returns
-------
state: boolean
"""
args = self.put_parser.parse_args()
grader = Grader.query.get(args.graderID)
sub = Submission.query.filter(Submission.exam_id == exam_id,
Submission.copy_number == submission_id).one_or_none()
if sub is None:
return dict(status=404, message='Submission does not exist.'), 404
solution = Solution.query.filter(Solution.submission_id == sub.id,
Solution.problem_id == problem_id).one_or_none()
if solution is None:
return dict(status=404, message='Solution does not exist.'), 404
graded = len(solution.feedback)
if graded:
solution.graded_at = datetime.now()
solution.graded_by = grader
return {'state': graded}
......@@ -402,3 +402,19 @@ def page_is_size(exam_pdf_file, shape, tolerance=0):
pass
return not invalid
def make_pages_even(output_filename, exam_pdf_file):
exam_pdf = PdfReader(exam_pdf_file)
new = PdfWriter()
new.addpages(exam_pdf.pages)
pagecount = len(exam_pdf.pages)
if (pagecount % 2 == 1):
blank = PageMerge()
box = exam_pdf.pages[0].MediaBox
blank.mbox = box
blank = blank.render()
new.addpage(blank)
new.write(output_filename)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment