Beispiel #1
0
def watch():
    assignment_list = request.values.get('assignments', '')
    assignments = [int(aid) for aid in assignment_list.split(',') if len(aid) > 0]
    course_id = request.values.get('course_id', g.course.id if 'course' in g else None)
    if course_id == None or course_id == "":
        return ajax_failure("No Course ID given!")
    if g.user is None or not g.user.is_instructor(int(course_id)):
        return ajax_failure("You are not an instructor in this assignments' course.")
    update = request.values.get('update', 'false') == "true"
    if update:
        data = []
        for aid in assignments:
            submissions = Submission.by_assignment(aid, int(course_id))
            completions = sum([int(sua[0].correct) for sua in submissions])
            workings = Submission.get_latest(aid, int(course_id))
            histories = [process_history([h['time'] for h in sua[0].get_history()])
                         for sua in submissions]
            touches = [int(sua[0].version) for sua in submissions]
            feedbacks = [l[0] for l in Log.calculate_feedbacks(aid, course_id)]
            data.append({'id': aid,
                         'Completions': completions,
                         'Workings': workings,
                         'Time': histories,
                         'Touches': touches,
                         'Feedbacks': feedbacks})
        return jsonify(success=True, data=data)
    else:
        assignments = [Assignment.by_id(aid) for aid in assignments]
        return render_template('blockpy/watch.html', course_id=course_id, assignments=assignments,
                               assignment_list=assignment_list)
Beispiel #2
0
    def post(self):
        '''
        creates a new submission instance and inserts it into the db.
        then redirects the user to the blog entry permalink page.
        both subject and content are required to make a blog entry.
        '''
        subject = self.request.get("subject")
        content = self.request.get("content")

        if subject and content:
            submission = Submission(parent=blog_key(),
                                    user=self.user,
                                    subject=subject,
                                    content=content)
            submission.put()
            time.sleep(0.1)

            self.redirect('/%s' % str(submission.key().id()))

        else:
            error = "You must enter both a subject and content"
            self.render("submissions/new.html",
                        subject=subject,
                        content=content,
                        error=error)
Beispiel #3
0
def submissions_filter(course_id):
    ''' List all the users in the course '''
    is_grader = g.user.is_grader(int(course_id))
    if not is_grader:
        return "You are not an instructor or TA in this course!"
    course_id = int(course_id)
    course = Course.by_id(course_id)
    students = natsorted(course.get_students(), key=lambda r: r.name())
    assignments = natsorted(course.get_submitted_assignments(),
                            key=lambda r: r.name)
    criteria = request.values.get("criteria", "none")
    search_key = int(request.values.get("search_key", "-1"))
    submissions = []
    if criteria == "student":
        all_subs = Submission.by_student(search_key, course_id)
        all_subs = {s[0].assignment_id: s for s in all_subs}
        submissions = [
            all_subs.get(assignment.id, (None, None, assignment))
            for assignment in assignments
        ]
    elif criteria == "assignment":
        all_subs = Submission.by_assignment(search_key, course_id)
        all_subs = {s[0].user_id: s for s in all_subs}
        submissions = [
            all_subs.get(student.id, (None, student, None))
            for student in students
        ]
    return render_template('courses/submissions_filter.html',
                           course_id=course_id,
                           assignments=assignments,
                           students=students,
                           submissions=submissions,
                           criteria=criteria,
                           search_key=search_key,
                           is_instructor=is_grader)
def AssignmentMain(assignment_code):
    assignment = Assignment.query.filter_by(code=assignment_code).first()
    if assignment is None:
        flash("No assignment found!", "danger")
        return redirect(url_for("home"))

    user = GetUser(session["email"])
    if not assignment.classroom in user.classrooms:
        flash("Access denied to this assigment!", "warning")
        return redirect(url_for("home"))

    file_name = os.path.join(SUBMISSION_FOLDER, assignment.code,
                             f"{user.id}_{user.name}.txt")
    submission = Submission.query.filter_by(file_name=file_name).first()

    # print(assignment.classroom.students)
    if request.method == "POST":
        if assignment.deadline < datetime.now():
            flash("Assignment deadline execeeded!", "danger")
        else:
            assignment_program = request.form.get('assignment_program')
            assignment_lang = request.form.get('assignment_lang')

            if not os.path.exists(
                    os.path.join(SUBMISSION_FOLDER, assignment.code)):
                flash("Upload folder not found! Please inform administrator",
                      "danger")
            else:
                result = CheckSubmission(assignment_code, assignment_lang,
                                         assignment_program)

                if result is None:
                    flash("Error while submitting assignment!", "warning")
                else:
                    print(file_name)
                    with open(file_name, "w+") as submission_file:
                        for line in assignment_program.split("\n"):
                            submission_file.write(line + "\n")

                    if submission is None:
                        submission = Submission(file_name, assignment, \
                                                    assignment_lang, result, user)
                    else:
                        submission.update(language=assignment_lang,
                                          result=result)
                    flash("Assignment submitted successfully!", "success")

                    db.session.add(submission)
                    db.session.commit()

    submission_program = ""
    if submission:
        with open(file_name, "r") as submission_file:
            for line in submission_file.readlines():
                submission_program += line

    return render_template("assignment/assignment_main.html", assignment=assignment, \
                            submission_program=submission_program, submission=submission, \
                            current_time=datetime.now, strftime=lambda x: x.strftime("%a, %d %b %Y at %I:%M %p"), \
                            os_sep=os.path.sep)
Beispiel #5
0
    def post(self):
        data = self.request.get("url")
        if not data.startswith("data:"):
            self.error(400)
            return
        data = data[5:]
        try:
            metadata, body = data.split(",")
            if not metadata.startswith("image/png"):
                raise ValueError("Image of wrong MIME type.")

            imagedata = base64.standard_b64decode(body)
            if len(imagedata) > 500000:
                raise ValueError("Image too big.")

            image = images.Image(imagedata)
            image.resize(300, 300 / image.width * 300)

            sub = Submission(submitter=str(self.request.remote_addr) or "")
            sub.image = db.Blob(image.execute_transforms())
            sub.put()

        except ValueError:
            self.error(400)
            return

        self.response.write("{error:false}")
Beispiel #6
0
 def add(self):
     submission = Submission(
         contents=self.request.body,
         mime_type=self.request.content_type,
         submitted_by=users.get_current_user()
     )
     key = submission.put()
     return webapp2.Response(key.urlsafe())
Beispiel #7
0
def dashboard(lti=lti, lti_exception=None):
    """
    :type lti: controllers.pylti.flask.lTI
    """
    force_default_assignment = maybe_bool(request.values.get('force_default_assignment', "false"))
    if 'user' not in g and not g.user:
        return "You are not logged in."
    course_id = get_course_id()
    user, user_id = get_user()
    if course_id is None:
        return "You are not in a course context."
    is_grader = user.is_grader(course_id)
    if is_grader and not force_default_assignment:
        return grader_dashboard(user, course_id)

    course = Course.by_id(course_id)
    assignment = course.get_default_assignment()
    if assignment is not None:
        return redirect(url_for("blockpy.load", assignment_id=assignment.id,
                                course_id=course_id, user_id=user_id, force_download=False,
                                embed=True))
    else:
        # No default assignment!
        assignments = natsorted(course.get_submitted_assignments(),
                                key=lambda r: r.name)
        all_subs = Submission.by_student(user_id, course_id)
        all_subs = {s[0].assignment_id: s for s in all_subs}
        submissions = [all_subs.get(assignment.id, (None, None, assignment))
                       for assignment in assignments]
        return render_template('courses/dashboard.html', embed=True,
                               course_id=course_id, user=user, is_grader=is_grader,
                               submissions=submissions, criteria='student')
Beispiel #8
0
def submissions_user(course_id, owner_id):
    ''' List all the users in the course '''
    course_id = int(course_id)
    course = Course.by_id(course_id)
    check_resource_exists(course, "Course", course_id)
    user, user_id = get_user()
    if course_id is not None:
        is_grader = user.is_grader(course_id)
    else:
        is_grader = False
    is_owner = user_id == maybe_int(owner_id)
    if not is_grader and not is_owner:
        return "You are not an instructor or the owner of the assignment!"
    owner = User.by_id(maybe_int(owner_id))
    assignments = natsorted(course.get_submitted_assignments(),
                            key=lambda r: r.name)
    all_subs = Submission.by_student(owner_id, course_id)
    all_subs = {s[0].assignment_id: s for s in all_subs}
    submissions = [all_subs.get(assignment.id, (None, None, assignment))
                   for assignment in assignments]
    return render_template('courses/submissions_user.html',
                           course_id=course_id,
                           assignments=assignments,
                           submissions=submissions,
                           owner=owner,
                           is_instructor=is_grader)
Beispiel #9
0
def dashboard(lti=lti):
    """
    :type lti: controllers.pylti.flask.lTI
    """
    if 'user' not in g and not g.user:
        return "You are not logged in."
    course_id = get_course_id()
    user, user_id = get_user()
    if course_id is None:
        return "You are not in a course context."
    is_grader = user.is_grader(course_id)
    if is_grader:
        return grader_dashboard(user, course_id)

    course = Course.by_id(course_id)
    assignments = natsorted(course.get_submitted_assignments(),
                            key=lambda r: r.name)
    all_subs = Submission.by_student(user_id, course_id)
    all_subs = {s[0].assignment_id: s for s in all_subs}
    submissions = [
        all_subs.get(assignment.id, (None, None, assignment))
        for assignment in assignments
    ]
    return render_template('courses/dashboard.html',
                           embed=True,
                           course_id=course_id,
                           user=user,
                           is_grader=is_grader,
                           submissions=submissions,
                           criteria='student')
Beispiel #10
0
def export_submissions():
    assignment_id = int(request.values.get('assignment_id'))
    assignment = Assignment.by_id(assignment_id)
    course_id = get_course_id(True)
    user, user_id = get_user()
    # Verify exists
    check_resource_exists(assignment, "Assignment", assignment_id)
    # Verify permissions
    assignment = Assignment.by_id(int(assignment_id))
    if course_id is None or not user.is_instructor(int(course_id)):
        return "You are not an instructor or the owner of the assignment!"
    # Get data
    suas = Submission.by_assignment(assignment_id, course_id)
    submissions = [sua[0] for sua in suas]
    users = [sua[1] for sua in suas]
    bundle = export_zip(assignments=[assignment],
                        submissions=submissions,
                        users=users)
    filename = assignment.get_filename(extension='.zip')
    return Response(bundle,
                    mimetype='application/zip',
                    headers={
                        'Content-Disposition':
                        'attachment;filename={}'.format(filename)
                    })
Beispiel #11
0
def get_page_submissions(soup):
    """Returns the list of all submissions in the given page.

    Parameters
    ----------
    soup : BeautifulSoup
        BeautifulSoup object of a page from the hackathon project gallery. 

    Returns
    -------
    list
        List of Submission objects.
    """
    projects_dirty_url = (soup.findAll(
        'a', {'class': 'block-wrapper-link fade link-to-software'}))
    projects_url = [p.get('href') for p in projects_dirty_url]
    projects_title = soup.findAll(
        'div',
        {'class': 'software-entry-name entry-body'})  #.find_next('h5').text
    titles = [p.find_next('h5').text.strip() for p in projects_title]
    submissions = []
    for title, url_project, (url_video, tags) in list(
            zip(titles, projects_url, map(project_data, projects_url))):
        submissions.append(Submission(title, url_project, url_video, tags))
    return submissions
Beispiel #12
0
def update_submission_status(lti, lti_exception=None):
    # Get parameters
    submission_id = maybe_int(request.values.get("submission_id"))
    status = request.values.get('status')
    course_id = get_course_id()
    user, user_id = get_user()
    submission = Submission.by_id(submission_id)
    # Check resource exists
    check_resource_exists(submission, "Submission", submission_id)
    # Verify permissions
    if submission.user_id != user_id and not user.is_grader(
            submission.course_id):
        return ajax_failure(
            "This is not your submission and you are not a grader in its course."
        )
    # Do action
    success = submission.update_submission_status(status)
    make_log_entry(submission.assignment_id,
                   submission.assignment_version,
                   course_id,
                   user_id,
                   "Submit",
                   "answer.py",
                   category=status,
                   message=str(success))
    return ajax_success({"success": success})
Beispiel #13
0
def dump_logs():
    assignment_id = int(request.values.get('assignment_id'))
    course_id = int(request.values.get('course_id'))
    assignment = Assignment.by_id(assignment_id)
    user, user_id = get_user()
    # Verify exists
    check_resource_exists(assignment, "Assignment", assignment_id)
    # Verify permissions
    if not user.is_grader(course_id):
        return "You are not a grader in this course."
    # Get data
    suas = Submission.by_assignment(assignment_id, course_id)
    data = {
        'assignment':
        assignment.encode_json(),
        'submissions': [{
            'user':
            u.encode_json(),
            'submission':
            sub.encode_json(),
            'history':
            Log.get_history(course_id, assignment_id, u.id),
            'reviews':
            sub.get_reviews()
        } for (sub, u, assign) in suas]
    }
    filename = assignment.get_filename() + '_submissions.json'
    return Response(json.dumps(data),
                    mimetype='application/json',
                    headers={
                        'Content-Disposition':
                        'attachment;filename={}'.format(filename)
                    })
Beispiel #14
0
def grader_dashboard(user, course_id):
    pending_review = Submission.by_pending_review(course_id)
    users = {user.email: user.encode_json() for _, user, _ in pending_review}
    is_instructor = user.is_instructor(course_id)
    return render_template('courses/dashboard_grader.html', embed=True,
                           course_id=course_id, user=user, pending_review=pending_review,
                           users=users, is_instructor=is_instructor)
Beispiel #15
0
 def delete(self, review_id):
     user, user_id = get_user()
     review = Review.by_id(review_id)
     check_resource_exists(review, "Review", review_id)
     submission = Submission.by_id(review.submission_id)
     check_resource_exists(submission, "Submission", review.submission_id)
     require_course_grader(user, submission.course_id)
     review.delete()
     return ajax_success(dict(success=True))
Beispiel #16
0
 def get_one(self, review_id):
     user, user_id = get_user()
     review = Review.by_id(review_id)
     check_resource_exists(review, "Review", review_id)
     submission = Submission.by_id(review.submission_id)
     check_resource_exists(submission, "Submission", review.submission_id)
     if submission.user_id != user_id:
         require_course_grader(user, submission.course_id)
     return ajax_success(dict(review=review.encode_json()))
    def decorated_function(self, *args, **kwargs):
        submission_id = args[0]
        submission = Submission.by_id(submission_id)

        if submission:
            kwargs['submission'] = submission
            return f(self, *args, **kwargs)
        else:
            self.error(404)
            return
def run_test():
    cities = Address.get_cities()
    f = open('voter_test.csv', 'r')
    rdr = csv.reader(f)
    submissions = [Submission.from_csv(row, cities, with_contact=False) for row in rdr]
    lookups = Voter.lookup(submissions)
    for lookup in lookups:
        print(str(lookup.name), str(lookup.address))
        for match in lookup.matches:
            print(str(match), str(match.address))
        print('\n')
Beispiel #19
0
def update_grading_status(lti, lti_exception=None):
    submission_id = maybe_int(request.values.get("submission_id"))
    # TODO: Pretty sure multiple assignments are broken for grading
    assignment_group_id = maybe_int(request.values.get('assignment_group_id'))
    new_grading_status = request.values.get("new_grading_status")
    user, user_id = get_user()
    submission = Submission.by_id(submission_id)
    # Check resource exists
    check_resource_exists(submission, "Submission", submission_id)
    # Verify permissions
    if not user.is_grader(submission.course_id):
        return ajax_failure(
            "This is not your submission and you are not a grader in its course."
        )
    submission.update_grading_status(new_grading_status)
    if submission.grading_status != GradingStatuses.FULLY_GRADED:
        return ajax_success({'new_status': new_grading_status})
    # Do action
    if assignment_group_id is None:
        assignment_group_id = submission.assignment_group_id
    error = "Generic LTI Failure - perhaps not logged into LTI session?"
    try:
        success, score = lti_post_grade(lti, submission, None,
                                        assignment_group_id,
                                        submission.user_id,
                                        submission.course_id)
    except LTIPostMessageException as e:
        success = False
        error = str(e)
    if success:
        make_log_entry(submission.assignment_id,
                       submission.assignment_version,
                       submission.course_id,
                       user_id,
                       "X-Submission.LMS",
                       "answer.py",
                       message=str(score))
        return ajax_success({"submitted": True, "new_status": "FullyGraded"})
    else:
        submission.update_grading_status(GradingStatuses.FAILED)
        make_log_entry(submission.assignment_id,
                       submission.assignment_version,
                       submission.course_id,
                       user_id,
                       "X-Submission.LMS.Failure",
                       "answer.py",
                       message=error)
        return ajax_failure({
            "submitted": False,
            "message": error,
            "new_status": "Failed"
        })
Beispiel #20
0
def update_submission_status():
    submission_id = maybe_int(request.values.get("submission_id"))
    new_submission_status = request.values.get("new_submission_status")
    user, user_id = get_user()
    submission = Submission.by_id(submission_id)
    # Check resource exists
    check_resource_exists(submission, "Submission", submission_id)
    # Verify permissions
    if not user.is_grader(submission.course_id):
        return ajax_failure(
            "You are not a grader in this submission's course.")
    submission.update_submission_status(new_submission_status)
    return ajax_success({'new_status': new_submission_status})
Beispiel #21
0
 def get_all(self):
     submission_id = maybe_int(request.values.get('submission_id'))
     user, user_id = get_user()
     if submission_id is None:
         reviews = Review.get_generic_reviews()
     else:
         submission = Submission.by_id(submission_id)
         check_resource_exists(submission, "Submission", submission_id)
         reviews = Review.get_for_submission(submission_id)
         if submission.user_id != user_id:
             require_course_grader(user, submission.course_id)
     return ajax_success(
         dict(reviews=[review.encode_json() for review in reviews]))
Beispiel #22
0
 def put(self, review_id):
     user, user_id = get_user()
     review = Review.by_id(review_id)
     check_resource_exists(review, "Review", review_id)
     submission = Submission.by_id(review.submission_id)
     check_resource_exists(submission, "Submission", review.submission_id)
     require_course_grader(user, submission.course_id)
     review_data = request.json.copy()
     del review_data['id']
     fix_nullables(review_data)
     review_data['author_id'] = user_id
     edited_review = review.edit(review_data)
     return ajax_success(dict(review=edited_review.encode_json()))
def run_test():
    cities = Address.get_cities()
    f = open('voter_test.csv', 'r')
    rdr = csv.reader(f)
    submissions = [
        Submission.from_csv(row, cities, with_contact=False) for row in rdr
    ]
    lookups = Voter.lookup(submissions)
    for lookup in lookups:
        print(str(lookup.name), str(lookup.address))
        for match in lookup.matches:
            print(str(match), str(match.address))
        print('\n')
Beispiel #24
0
def mass_close_assignment():
    assignment_id = maybe_int(request.values.get("assignment_id"))
    course_id = maybe_int(request.values.get("course_id"))
    new_submission_status = request.values.get("new_submission_status")
    user, user_id = get_user()
    submissions = Submission.by_assignment(assignment_id=assignment_id,
                                           course_id=course_id)
    # Verify permissions
    if not user.is_grader(course_id):
        return ajax_failure("You are not a grader in this course.")
    # Do action
    for submission in submissions:
        submission.update_submission_status(new_submission_status)
    return ajax_success({'new_status': new_submission_status})
Beispiel #25
0
 def post(self):
     user, user_id = get_user()
     submission_id = maybe_int(request.values.get('submission_id'))
     submission = Submission.by_id(submission_id)
     check_resource_exists(submission, "Submission", submission_id)
     require_course_grader(user, submission.course_id)
     review_data = request.values.copy()
     del review_data['id']
     review_data['author_id'] = user_id
     review_data['submission_version'] = submission.version
     review_data['assignment_version'] = submission.assignment_version
     fix_nullables(review_data)
     new_review = Review.new(review_data)
     return ajax_success(dict(review=new_review.encode_json()))
Beispiel #26
0
def csv_import():
    from models.turf import Turf
    from models.submission import Submission

    if request.method == 'GET':
        return render_template('voters/voter_import.html',
                               title='Voter Import')

    data = json.loads(request.form['params'])['data']
    cities = Turf.get_cities()
    submissions = [
        Submission.from_web(rec, cities) for rec in data if rec['data0']
    ]
    Voter.batch_lookup(submissions)
    return jsonify(
        lookups=[submission.serialize() for submission in submissions])
Beispiel #27
0
    def post(self, comp_id=None, user_id=None, response=None):
        args = self.parser.parse_args()
        submission = args["submission"]
        
        if comp_id and user_id is not None:
            #TODO: Implement Score evaluation.
            comp = Competition.query.filter_by(id=comp_id).first()
            public_score = accuracy_score_public(comp.solution, submission, comp.public_ids) 
            private_score = accuracy_score_private(comp.solution, submission) 
            submission = Submission(comp_id, user_id, submission, "Submission", public_score, private_score)
            data = save_record(submission)
            response = ("Submission created successfully", 201)

        return make_response(jsonify({
            "message": response[0]
        }), response[1])
Beispiel #28
0
def submissions_specific(submission_id):
    ''' List all the users in the course '''
    submission, user, assignment = Submission.full_by_id(int(submission_id))
    if submission is None:
        return "Submission not found"
    course_id = submission.course_id
    if course_id is not None:
        is_instructor = g.user.is_instructor(int(course_id))
    else:
        is_instructor = False
    is_owner = g.user.id == submission.user_id
    if not is_instructor and not is_owner:
        return "You are not an instructor or the owner of the assignment!"
    return render_template('courses/submissions_specific.html',
                           submission=submission,
                           assignment=assignment,
                           user=user,
                           course_id=course_id)
Beispiel #29
0
def save_image():
    # Get parameters
    submission_id = maybe_int(request.values.get("submission_id"))
    directory = request.values.get('directory')
    image = request.values.get('image')
    course_id = get_course_id()
    user, user_id = get_user()
    submission = Submission.by_id(submission_id)
    # Check resource exists
    check_resource_exists(submission, "Submission", submission_id)
    # Verify permissions
    if submission.user_id != user_id and not user.is_grader(submission.course_id):
        return ajax_failure("This is not your submission and you are not a grader in its course.")
    # Do action
    success = submission.save_image(directory, image)
    make_log_entry(submission.assignment_id, submission.assignment_version,
                   course_id, user_id, "X-Image.Save", directory)
    return ajax_success({"success": success})
Beispiel #30
0
    def new(self, project_path, source_directory):
        if is_directory(project_path) and self.__isvalid_source(source_directory):
            self.__reset()
            self.state['project_path'] = project_path

            for file in os.listdir(source_directory):
                current_path = os.path.join(source_directory, file)
                output_path = os.path.join(project_path, remove_ext(get_uin(file)))

                # TODO: add support for more file types and change this to account for that
                if get_ext(file) == '.zip':
                    unzip(current_path, output_path)
                    flatdir(output_path)
                    self.state['submissions'].append(Submission(output_path))

            return self.save() and len(self.state['submissions']) > 0 and self.state['project_path'] != None
        else:
            return False
Beispiel #31
0
def view_submission():
    submission_id = request.values.get('submission_id')
    viewer, viewer_id = get_user()
    embed = maybe_bool(request.values.get('embed'))
    submission = Submission.by_id(submission_id)
    # Check exists
    check_resource_exists(submission, "Submission", submission_id)
    # Check permissions
    if submission.user_id != viewer_id:
        require_course_grader(viewer, submission.course_id)
    is_grader = viewer.is_grader(submission.course_id)
    tags = []
    if is_grader:
        tags = [tag.encode_json() for tag in AssignmentTag.get_all()]
    # Do action
    return render_template("reports/alone.html", embed=embed,
                           submission=submission, assignment=submission.assignment,
                           is_grader=is_grader, tags=tags,
                           user_id=submission.user_id, course_id=submission.course_id)
Beispiel #32
0
def update_submission(lti, lti_exception=None):
    # Get parameters
    submission_id = maybe_int(request.values.get("submission_id"))
    lis_result_sourcedid = request.values.get('lis_result_sourcedid')
    assignment_group_id = maybe_int(request.values.get('assignment_group_id'))
    score = float(request.values.get('score', '0'))
    correct = maybe_bool(request.values.get("correct"))
    # TODO: Only send image if the assignment settings starts as Block or Split
    image = request.values.get('image', "")
    hidden_override = maybe_bool(request.values.get('hidden_override'))
    force_update = maybe_bool(request.values.get('force_update'))
    course_id = get_course_id()
    user, user_id = get_user()
    submission = Submission.by_id(submission_id)
    # Check resource exists
    check_resource_exists(submission, "Submission", submission_id)
    # Verify permissions
    if submission.user_id != user_id and not user.is_grader(submission.course_id):
        return ajax_failure("This is not your submission and you are not a grader in its course.")
    # Do action
    was_changed = submission.update_submission(score, correct)
    if assignment_group_id is None:
        assignment_group_id = submission.assignment_group_id
    # TODO: Document that we currently only pass back grade if it changed
    # TODO: If failure on previous submission grading, then retry
    if was_changed or force_update:
        submission.save_block_image(image)
        error = "Generic LTI Failure - perhaps not logged into LTI session?"
        try:
            success, score = lti_post_grade(lti, submission, lis_result_sourcedid, assignment_group_id,
                                     submission.user_id, submission.course_id)
        except LTIPostMessageException as e:
            success = False
            error = str(e)
        if success:
            make_log_entry(submission.assignment_id, submission.assignment_version,
                           course_id, user_id, "X-Submission.LMS", "answer.py", message=str(score))
        else:
            submission.update_grading_status(GradingStatuses.FAILED)
            make_log_entry(submission.assignment_id, submission.assignment_version,
                           course_id, user_id, "X-Submission.LMS.Failure", "answer.py", message=error)
            return ajax_failure({"submitted": False, "changed": was_changed, "message": error})
    return ajax_success({"submitted": was_changed or force_update, "changed": was_changed})
Beispiel #33
0
def load_submission(lti=lti):
    submission_id = int(request.args.get('submission_id'))
    embed = maybe_bool(request.values.get('embed'))
    course_id = get_course_id(True)
    user, user_id = get_user()
    submission = Submission.by_id(submission_id)
    read_only = maybe_bool(request.values.get('read_only', "true"))
    # Check that the resource exists
    check_resource_exists(submission, "Submission", submission_id)
    # If it is this user's submission, redirect to load the assignment
    if submission.user_id == user_id:
        if course_id is None:
            course_id = submission.course_id
        return redirect(
            url_for('blockpy.load',
                    assignment_id=submission.assignment.id,
                    course_id=course_id))
    # Check that it is public or you are a grader
    elif user.is_grader(submission.course_id):
        role = 'grader'
    elif not submission.assignment.public:
        # TODO: Handle this more gracefully
        return ajax_failure(
            "Cannot view submission. This is not a public submission, and you do not own the submission, and you are "
            "not an instructor in its course.")
    else:
        role = 'anonymous'
    # Get the assignment
    assignment_data = submission.assignment.for_editor(submission.user_id,
                                                       submission.course_id)
    return load_editor(
        lti, {
            "user": user,
            "user_id": user_id,
            "embed": embed,
            "read_only": read_only,
            "current_submission_id": submission_id,
            "course_id": course_id,
            "role": role,
            "assignment_group_id": None,
            "assignment_data": assignment_data
        })
Beispiel #34
0
def load_history():
    # Get parameters
    course_id = maybe_int(request.values.get('course_id'))
    assignment_id = (request.values.get('assignment_id'))
    student_id = (request.values.get('user_id'))
    page_limit = maybe_int(request.values.get('page_limit'))
    page_offset = maybe_int(request.values.get('page_offset'))
    with_submission = maybe_bool(request.values.get('with_submission'))
    user, user_id = get_user()
    # Verify user can see the submission
    if str(user_id) != str(student_id) and not user.is_grader(course_id):
        return ajax_failure("Only graders can see logs for other people.")
    history = Log.get_history(course_id, assignment_id, student_id,
                                            page_offset=page_offset,
                                            page_limit=page_limit)
    history = list(reversed(history))
    submissions = []
    if with_submission:
        submissions = Submission.get_submissions(course_id, assignment_id, student_id)
    return ajax_success({"history": history, "submissions": submissions})
Beispiel #35
0
def browse_submissions():
    assignment_id = request.values.get('assignment_id', None)
    if assignment_id is None:
        return ajax_failure("No Assignment ID given!")
    assignment_id = int(assignment_id)
    course_id = request.values.get('course_id', g.course.id if 'course' in g else None)
    if course_id == None or course_id == "":
        return ajax_failure("No Course ID given!")
    if g.user is None or not g.user.is_instructor(int(course_id)):
        return ajax_failure("You are not an instructor in this assignments' course.")
    submissions = Submission.by_assignment(assignment_id, int(course_id))
    for submission, user, assignment in submissions:
        submission.highlighted_code = highlight_python_code(submission.code)
        submission.history = process_history([h['time']
                                              for h in reversed(submission.get_history())])
    return render_template('blockpy/browse_submissions.html',
                           course_id=course_id,
                           assignment_id=assignment_id,
                           submissions=submissions,
                           ip=request.remote_addr)