class AssignmentsController

Constants

DEFAULT_FIELDS

Copy of API::AssignmentController without the id and order changed to put first the 4 required fields

Public Instance Methods

create() click to toggle source

Called after a new assignment form is submitted.

# File app/controllers/assignments_controller.rb, line 253
def create
  @assignment = Assignment.new
  @assignment.build_assignment_stat
  @assignment.transaction do
    begin
      @assignment = process_assignment_form(@assignment, params)
    rescue Exception, RuntimeError => e
      @assignment.errors.add(:base, e.message)
    end
    unless @assignment.save
      @assignments = Assignment.all
      @sections = Section.all
      render :new
      return
    end
    if params[:persist_groups_assignment]
      @assignment.clone_groupings_from(params[:persist_groups_assignment])
    end
    if @assignment.save
      flash[:success] = I18n.t('assignment.create_success')
    end
  end

  redirect_to :action => 'edit', :id => @assignment.id
end
creategroup() click to toggle source
# File app/controllers/assignments_controller.rb, line 341
def creategroup
  @assignment = Assignment.find(params[:id])
  @student = @current_user
  m_logger = MarkusLogger.instance

  begin
    # We do not allow group creations by students after the due date
    # and the grace period for an assignment
    if @assignment.past_collection_date?
      raise I18n.t('create_group.fail.due_date_passed')
    end
    if !@assignment.student_form_groups ||
         @assignment.invalid_override
      raise I18n.t('create_group.fail.not_allow_to_form_groups')
    end
    if @student.has_accepted_grouping_for?(@assignment.id)
      raise I18n.t('create_group.fail.already_have_a_group')
    end
    if params[:workalone]
      if @assignment.group_min != 1
        raise I18n.t('create_group.fail.can_not_work_alone',
                      :group_min => @assignment.group_min)
      end
      # fix for issue #627
      # currently create_group_for_working_alone_student only returns false
      # when saving a grouping throws an exception
      unless @student.create_group_for_working_alone_student(@assignment.id)
        # if create_group_for_working_alone_student returned false then the student
        # must have an ( empty ) existing grouping that he is not a member of.
        # we must delete this grouping for the transaction to succeed.
        Grouping.find_by_group_id_and_assignment_id( Group.find_by_group_name(@student.user_name), @assignment.id).destroy
      end
    else
      @student.create_autogenerated_name_group(@assignment.id)
    end
    m_logger.log("Student '#{@student.user_name}' created group.",
                 MarkusLogger::INFO)
  rescue RuntimeError => e
    flash[:fail_notice] = e.message
    m_logger.log("Failed to create group. User: '#{@student.user_name}', Error: '" +
                 "#{e.message}'.", MarkusLogger::ERROR)
  end
  redirect_to :action => 'student_interface', :id => @assignment.id
end
decline_invitation() click to toggle source
# File app/controllers/assignments_controller.rb, line 330
def decline_invitation
  @assignment = Assignment.find(params[:id])
  @grouping = Grouping.find(params[:grouping_id])
  @user = Student.find(session[:uid])
  @grouping.decline_invitation(@user)
  m_logger = MarkusLogger.instance
  m_logger.log("Student '#{@user.user_name}' declined invitation for group '" +
               "#{@grouping.group.group_name}'.")
  redirect_to :action => 'student_interface', :id => params[:id]
end
delete_rejected() click to toggle source

Deletes memberships which have been declined by students

# File app/controllers/assignments_controller.rb, line 466
def delete_rejected
  @assignment = Assignment.find(params[:id])
  membership = StudentMembership.find(params[:membership])
  grouping = membership.grouping
  if current_user != grouping.inviter
    raise I18n.t('invite_student.fail.only_inviter')
  end
  membership.delete
  membership.save
  redirect_to :action => 'student_interface', :id => params[:id]
end
deletegroup() click to toggle source
# File app/controllers/assignments_controller.rb, line 386
def deletegroup
  @assignment = Assignment.find(params[:id])
  @grouping = @current_user.accepted_grouping_for(@assignment.id)
  m_logger = MarkusLogger.instance
  begin
    if @grouping.nil?
      raise I18n.t('create_group.fail.do_not_have_a_group')
    end
    # If grouping is not deletable for @current_user for whatever reason, fail.
    unless @grouping.deletable_by?(@current_user)
      raise I18n.t('groups.cant_delete')
    end
    if @grouping.has_submission?
      raise I18n.t('groups.cant_delete_already_submitted')
    end
    @grouping.student_memberships.all(:include => :user).each do |member|
      member.destroy
    end
    # update repository permissions
    @grouping.update_repository_permissions
    @grouping.destroy
    flash[:edit_notice] = I18n.t('assignment.group.deleted')
    m_logger.log("Student '#{current_user.user_name}' deleted group '" +
                 "#{@grouping.group.group_name}'.", MarkusLogger::INFO)

  rescue RuntimeError => e
    flash[:fail_notice] = e.message
    if @grouping.nil?
      m_logger.log(
         'Failed to delete group, since no accepted group for this user existed.' +
         "User: '#{current_user.user_name}', Error: '#{e.message}'.", MarkusLogger::ERROR)
    else
      m_logger.log("Failed to delete group '#{@grouping.group.group_name}'. User: '" +
                   "#{current_user.user_name}', Error: '#{e.message}'.", MarkusLogger::ERROR)
    end
  end
  redirect_to :action => 'student_interface', :id => params[:id]
end
disinvite_member() click to toggle source

Called by clicking the cancel link in the student’s interface i.e. cancels invitations

# File app/controllers/assignments_controller.rb, line 450
def disinvite_member
  @assignment = Assignment.find(params[:id])
  membership = StudentMembership.find(params[:membership])
  disinvited_student = membership.user
  membership.delete
  membership.save
  # update repository permissions
  grouping = current_user.accepted_grouping_for(@assignment.id)
  grouping.update_repository_permissions
  m_logger = MarkusLogger.instance
  m_logger.log("Student '#{current_user.user_name}' cancelled invitation for " +
               "'#{disinvited_student.user_name}'.")
  flash[:edit_notice] = I18n.t('student.member_disinvited')
end
download_assignment_list() click to toggle source
# File app/controllers/assignments_controller.rb, line 489
def download_assignment_list
  assignments = Assignment.all

  case params[:file_format]
    when 'yml'
      map = {}
      map[:assignments] = []
      assignments.map do |assignment|
        m = {}
        DEFAULT_FIELDS.length.times do |i|
          m[DEFAULT_FIELDS[i]] = assignment.send(DEFAULT_FIELDS[i])
        end
        map[:assignments] << m
      end
      output = map.to_yaml
      format = 'text/yml'
    when 'csv'
      output = CsvHelper::Csv.generate do |csv|
        assignments.map do |ass|
          array = []
          DEFAULT_FIELDS.map do |f|
            array << ass.send(f.to_s)
          end
          csv << array
        end
      end
      format = 'text/csv'
    else
      flash[:error] = t(:incorrect_format)
      redirect_to :action => 'index'
      return
  end

  send_data(output,
            :filename => "assignments_#{Time.
                now.strftime('%Y%m%dT%H%M%S')}.#{params[:file_format]}",
            :type => format, :disposition => 'inline')
end
download_csv_grades_report() click to toggle source
# File app/controllers/assignments_controller.rb, line 283
def download_csv_grades_report
  assignments = Assignment.all(:order => 'id')
  students = Student.all
  csv_string = CsvHelper::Csv.generate do |csv|
    students.each do |student|
      row = []
      row.push(student.user_name)
      assignments.each do |assignment|
        out_of = assignment.total_mark
        grouping = student.accepted_grouping_for(assignment.id)
        if grouping.nil?
          row.push('')
        else
          submission = grouping.current_submission_used
          if submission.nil?
            row.push('')
          else
            total_mark_percentage = submission.get_latest_result.total_mark / out_of * 100
            if total_mark_percentage.nan?
              row.push('')
            else
              row.push(total_mark_percentage)
            end
          end
        end
      end
      csv << row
    end
  end
  send_data csv_string, :disposition => 'attachment',
                        :filename => "#{COURSE_NAME} grades report.csv"
end
edit() click to toggle source

Called on editing assignments (GET)

# File app/controllers/assignments_controller.rb, line 180
def edit
  @assignment = Assignment.find_by_id(params[:id])

  @past_date = @assignment.what_past_due_date
  @assignments = Assignment.all
  @sections = Section.all

  unless @past_date.nil? || @past_date.empty?
    flash[:notice] = t('past_due_date_notice') + @past_date.join(', ')
  end

  # build section_due_dates for each section that doesn't already have a due date
  Section.all.each do |s|
    unless SectionDueDate.find_by_assignment_id_and_section_id(@assignment.id, s.id)
      @assignment.section_due_dates.build(:section => s)
    end
  end
end
index() click to toggle source

Displays “Manage Assignments” page for creating and editing assignment information

# File app/controllers/assignments_controller.rb, line 137
def index
  @assignments = Assignment.all(:order => :id)
  @grade_entry_forms = GradeEntryForm.all(:order => :id)
  @default_fields = DEFAULT_FIELDS
  if current_user.student?
    #get the section of current user
    @section = current_user.section
    # get results for assignments for the current user
    @a_id_results = Hash.new()
    @assignments.each do |a|
      if current_user.has_accepted_grouping_for?(a)
        grouping = current_user.accepted_grouping_for(a)
        if grouping.has_submission?
          submission = grouping.current_submission_used
          if submission.has_remark? && submission.get_remark_result.released_to_students
            @a_id_results[a.id] = submission.get_remark_result
          elsif submission.has_result? && submission.get_original_result.released_to_students
            @a_id_results[a.id] = submission.get_original_result
          end
        end
      end
    end

    # Get the grades for grade entry forms for the current user
    @g_id_entries = Hash.new()
    @grade_entry_forms.each do |g|
      grade_entry_student = g.grade_entry_students.find_by_user_id(
                                  current_user.id )
      if !grade_entry_student.nil? &&
           grade_entry_student.released_to_student
        @g_id_entries[g.id] = grade_entry_student
      end
    end

    render :student_assignment_list
  elsif current_user.ta?
    render :grader_index
  else
    render :index
  end
end
invite_member() click to toggle source
# File app/controllers/assignments_controller.rb, line 425
def invite_member
  return unless request.post?
  @assignment = Assignment.find(params[:id])
  # if instructor formed group return
  return if @assignment.invalid_override

  @student = @current_user
  @grouping = @student.accepted_grouping_for(@assignment.id)
  if @grouping.nil?
    raise I18n.t('invite_student.fail.need_to_create_group')
  end

  to_invite = params[:invite_member].split(',')
  flash[:fail_notice] = []
  MarkusLogger.instance
  @grouping.invite(to_invite)
  flash[:fail_notice] = @grouping.errors['base']
  if flash[:fail_notice].blank?
    flash[:success] = I18n.t('invite_student.success')
  end
  redirect_to :action => 'student_interface', :id => @assignment.id
end
join_group() click to toggle source

Methods for the student interface

# File app/controllers/assignments_controller.rb, line 319
def join_group
  @assignment = Assignment.find(params[:id])
  @grouping = Grouping.find(params[:grouping_id])
  @user = Student.find(session[:uid])
  @user.join(@grouping.id)
  m_logger = MarkusLogger.instance
  m_logger.log("Student '#{@user.user_name}' joined group '#{@grouping.group.group_name}'" +
               '(accepted invitation).')
  redirect_to :action => 'student_interface', :id => params[:id]
end
new() click to toggle source

Called in order to generate a form for creating a new assignment. i.e. GET request on assignments/new

# File app/controllers/assignments_controller.rb, line 236
def new
  @assignments = Assignment.all
  @assignment = Assignment.new
  @sections = Section.all
  @assignment.build_submission_rule
  @assignment.build_assignment_stat

  # build section_due_dates for each section
  Section.all.each { |s| @assignment.section_due_dates.build(:section => s)}

  # set default value if web submits are allowed
  @assignment.allow_web_submits =
      !MarkusConfigurator.markus_config_repository_external_submits_only?
  render :new
end
refresh_graph() click to toggle source

Refreshes the grade distribution graphs and reloads the page

# File app/controllers/assignments_controller.rb, line 483
def refresh_graph
  assignment = Assignment.find(params[:id])
  assignment.assignment_stat.refresh_grade_distribution
  redirect_to :controller => 'main'
end
render_test_result() click to toggle source

Description

Action called via Rails' remote_function from the test_result_window partial
Prepares test result and updates content in window.
# File app/controllers/assignments_controller.rb, line 46
def render_test_result
  @assignment = Assignment.find(params[:aid])
  @test_result = TestResult.find(params[:test_result_id])

  # Students can use this action only, when marks have been released
  if current_user.student? &&
      (@test_result.submission.grouping.membership_status(current_user).nil? ||
      @test_result.submission.get_latest_result.released_to_students == false)
    render :partial => 'shared/handle_error',
     :locals => {:error => I18n.t('test_result.error.no_access', :test_result_id => @test_result.id)}
    return
  end

  render :template => 'assignments/render_test_result', :layout => 'plain'
end
student_interface() click to toggle source
# File app/controllers/assignments_controller.rb, line 62
def student_interface
  @assignment = Assignment.find(params[:id])
  @student = current_user
  @grouping = @student.accepted_grouping_for(@assignment.id)

  if @student.section &&
     !@student.section.section_due_date_for(@assignment.id).nil?
    @due_date =
      @student.section.section_due_date_for(@assignment.id).due_date
  end
  if @due_date.nil?
    @due_date = @assignment.due_date
  end
  if @student.has_pending_groupings_for?(@assignment.id)
    @pending_grouping = @student.pending_groupings_for(@assignment.id)
  end
  if @grouping.nil?
    if @assignment.group_max == 1
      begin
        # fix for issue #627
        # currently create_group_for_working_alone_student only returns false
        # when saving a grouping throws an exception
        unless @student.create_group_for_working_alone_student(@assignment.id)
          # if create_group_for_working_alone_student returned false then the student
          # must have an ( empty ) existing grouping that he is not a member of.
          # we must delete this grouping for the transaction to succeed.
          Grouping.find_by_group_id_and_assignment_id( Group.find_by_group_name(@student.user_name), @assignment.id).destroy
        end
      rescue RuntimeError => @error
        render 'shared/generic_error', :layout => 'error'
        return
      end
      redirect_to :action => 'student_interface', :id => @assignment.id
    else
      render :student_interface
    end
  else
    # We look for the information on this group...
    # The members
    @studentmemberships =  @grouping.student_memberships
    # The group name
    @group = @grouping.group
    # The inviter
    @inviter = @grouping.inviter

    # Look up submission information
    repo = @grouping.group.repo
    @revision  = repo.get_latest_revision
    @revision_number = @revision.revision_number

    # For running tests
    if params[:collect]
      @result = manually_collect_and_prepare_test(@grouping, @revision.revision_number)
    else
      @result = automatically_collect_and_prepare_test(@grouping, @revision.revision_number)
    end
    #submission = @grouping.submissions.find_by_submission_version_used(true)
    if @result
      @test_result_files = @result.submission.test_results
    else
      @test_result_files = nil
    end
    @token = Token.find_by_grouping_id(@grouping.id)
    if @token
      @token.reassign_tokens_if_new_day()
    end
    @last_modified_date = @grouping.assignment_folder_last_modified_date
    @num_submitted_files = @grouping.number_of_submitted_files
    @num_missing_assignment_files = @grouping.missing_assignment_files.length
    repo.close
  end
end
update() click to toggle source

Called when editing assignments form is submitted (PUT).

# File app/controllers/assignments_controller.rb, line 200
def update
  @assignment = Assignment.find_by_id(params[:id])
  @assignments = Assignment.all
  @sections = Section.all

  unless params[:assignment].nil?
    @oldcriteria = @assignment.marking_scheme_type
    @newcriteria = params[:assignment][:marking_scheme_type]
    if @oldcriteria != @newcriteria and !@assignment.get_criteria.nil?
      #TODO use @assignment.criteria.destroy_all when the refactor of
      # criteria structure finished
      @assignment.get_criteria.each do |criterion|
        criterion.destroy
      end
    end
  end

  begin
    @assignment = process_assignment_form(@assignment, params)
    rescue Exception, RuntimeError => e
      @assignment.errors.add(:base, I18n.t('assignment.error',
                                            :message => e.message))
      render :edit, :id => @assignment.id
    return
  end

  if @assignment.save
    flash[:success] = I18n.t('assignment.update_success')
    redirect_to :action => 'edit', :id => params[:id]
  else
    render :edit, :id => @assignment.id
  end
end
update_collected_submissions() click to toggle source
# File app/controllers/assignments_controller.rb, line 478
def update_collected_submissions
  @assignments = Assignment.all
end
update_group_properties_on_persist() click to toggle source
# File app/controllers/assignments_controller.rb, line 279
def update_group_properties_on_persist
  @assignment = Assignment.find(params[:assignment_id])
end
upload_assignment_list() click to toggle source
# File app/controllers/assignments_controller.rb, line 528
def upload_assignment_list
  assignment_list = params[:assignment_list]

  if assignment_list.blank?
    redirect_to :action => 'index'
    return
  end

  encoding = params[:encoding]
  assignment_list = if encoding != nil
                      StringIO.new(Iconv.iconv('UTF-8', encoding,
                                               assignment_list.read).join)
                    else
                      assignment_list.read
                    end

  case params[:file_format]
    when 'csv'
      begin
        CsvHelper::Csv.parse(assignment_list) do |row|
          map = {}
          row.length.times do |i|
            map[DEFAULT_FIELDS[i]] = row[i]
          end
          map.delete(nil)
          update_assignment!(map)
        end
      rescue ActiveRecord::ActiveRecordError, ArgumentError => e
        flash[:error] = e.message
        redirect_to :action => 'index'
        return
      end
    when 'yml'
      begin
        map = YAML::load(assignment_list)
        map[:assignments].map do |row|
          update_assignment!(row)
        end
      rescue ActiveRecord::ActiveRecordError, ArgumentError => e
        flash[:error] = e.message
        redirect_to :action => 'index'
        return
      end
    else
      return
  end

  redirect_to :action => 'index'
end