class Submission

Handle for getting student submissions. Actual instance depend on whether an assignment is a group or individual assignment. Use Assignment#submission_by to retrieve the correct submission.

Public Class Methods

create_by_revision_number(grouping, revision_number) click to toggle source
# File app/models/submission.rb, line 29
def self.create_by_revision_number(grouping, revision_number)
  repo = grouping.group.repo
  revision = repo.get_revision(revision_number)
  submission = self.generate_new_submission(grouping, revision)
  repo.close
  return submission
end
create_by_timestamp(grouping, timestamp) click to toggle source
# File app/models/submission.rb, line 17
def self.create_by_timestamp(grouping, timestamp)
   unless timestamp.kind_of? Time
     raise 'Expected a timestamp of type Time'
   end
   repo = grouping.group.repo
   path = grouping.assignment.repository_folder
   revision = repo.get_revision_by_timestamp(timestamp, path)
   submission = self.generate_new_submission(grouping, revision)
   repo.close
   return submission
end
generate_new_submission(grouping, revision) click to toggle source
# File app/models/submission.rb, line 37
def self.generate_new_submission(grouping, revision)
   new_submission = Submission.new
   new_submission.grouping = grouping
   new_submission.submission_version = 1
   new_submission.submission_version_used = true
   new_submission.revision_timestamp = revision.timestamp
   new_submission.revision_number = revision.revision_number

   new_submission.transaction do
     begin
       new_submission.populate_with_submission_files(revision)
     rescue Repository::FileDoesNotExist => e
       #populate the submission with no files instead of raising an exception
     end
     new_submission.save
   end
   return new_submission
end
get_submission_by_group_and_assignment(group_n, ass_si) click to toggle source

Description

Helper class method to find a submission by providing a group_name and
and an assignment short identifier.

Returns

nil if no such submission exists.
# File app/models/submission.rb, line 188
def self.get_submission_by_group_and_assignment(group_n, ass_si)
  assignment = Assignment.find_by_short_identifier(ass_si)
  group = Group.find_by_group_name(group_n)
  if !assignment.nil? && !group.nil?
    grouping = group.grouping_for_assignment(assignment.id)
    return grouping.current_submission_used if !grouping.nil?
  end
  return nil
end

Public Instance Methods

assignment() click to toggle source

Query functions ——————————————————- Figure out which assignment this submission is for

# File app/models/submission.rb, line 137
def assignment
  self.grouping.assignment
end
create_remark_result() click to toggle source
# File app/models/submission.rb, line 198
def create_remark_result
  remark_result = Result.new
  results << remark_result
  remark_result.marking_state = Result::MARKING_STATES[:unmarked]
  remark_result.submission_id = self.id
  remark_result.save
  # link remark result id to submission - must be done after remark result is saved (so it has an id)
  self.remark_result_id = remark_result.id
  self.save

  # populate remark result with old marks
  original_result = get_original_result

  old_extra_marks = original_result.extra_marks
  old_extra_marks.each do |old_extra_mark|
    remark_extra_mark = ExtraMark.new(old_extra_mark.attributes.merge(
      {:result_id => self.remark_result_id, :created_at => Time.zone.now}))
    remark_extra_mark.save(:validate => false)
    remark_result.extra_marks << remark_extra_mark
  end

  old_marks = original_result.marks
  old_marks.each do |old_mark|
    remark_mark = Mark.new(old_mark.attributes.merge(
      {:result_id => self.remark_result_id, :created_at => Time.zone.now}))
    remark_mark.save(:validate => false)
    remark_result.marks << remark_mark
  end
end
get_latest_completed_result() click to toggle source

returns the latest completed result - note: will return nil if there is no completed result

# File app/models/submission.rb, line 81
def get_latest_completed_result
  if self.remark_submitted? && self.get_remark_result.marking_state == Result::MARKING_STATES[:complete]
    return self.get_remark_result
  end
  if self.get_original_result.marking_state == Result::MARKING_STATES[:complete]
    return self.get_original_result
  end
  nil
end
get_latest_result() click to toggle source

returns the latest result - remark result if exists and submitted, else original result

# File app/models/submission.rb, line 72
def get_latest_result
  if self.remark_submitted?
    self.get_remark_result
  else
    self.get_original_result
  end
end
get_original_result() click to toggle source

returns the original result

# File app/models/submission.rb, line 57
def get_original_result
  if self.remark_result_id.nil?
    Result.first(:conditions => ['submission_id = ?', self.id])
  else
    Result.first(:conditions => ['submission_id = ? AND id != ?',
                                 self.id, self.remark_result_id])
  end
end
get_remark_result() click to toggle source

returns the remark result if exists, returns nil if does not exist

# File app/models/submission.rb, line 67
def get_remark_result
  Result.first(:conditions => ['id = ?', self.remark_result_id])
end
has_remark?() click to toggle source

Does this submission have a remark result?

# File app/models/submission.rb, line 146
def has_remark?
  !self.remark_result_id.nil?
end
has_result?() click to toggle source
# File app/models/submission.rb, line 141
def has_result?
  results.any?
end
populate_with_submission_files(revision, path='/') click to toggle source

Helper methods

# File app/models/submission.rb, line 161
def populate_with_submission_files(revision, path='/')
  # Remember that assignments have folders within repositories - these
  # will be "spoofed" as root...
  if path == '/'
    path = assignment.repository_folder
  end

  # First, go through directories...
  directories = revision.directories_at_path(path)
  directories.each do |directory_name, directory|
    populate_with_submission_files(revision, File.join(path, directory.name))
  end
  files = revision.files_at_path(path)
  files.each do |filename, file|
    new_file = SubmissionFile.new
    new_file.submission = self
    new_file.filename = file.name
    new_file.path = file.path
    new_file.save
  end
end
remark_submitted?() click to toggle source

Does this submission have a remark request submitted? remark_results in ‘unmarked’ state have not been submitted by the student yet (just saved) Submitted means that the remark request can be viewed by instructors and TAs and is no

longer editable by the student.

Saved means that the remark request cannot be viewed by instructors or TAs yet and

the student can still make changes to the request details.
# File app/models/submission.rb, line 156
def remark_submitted?
  self.has_remark? && self.get_remark_result.marking_state != Result::MARKING_STATES[:unmarked]
end
remove_file(filename) click to toggle source

Delete all records of filename in submissions and store in backup folder (for now, called “BACKUP”)

# File app/models/submission.rb, line 119
def remove_file(filename)
  # get all submissions for this filename
  files = submission_files.all(:conditions => ['filename = ?', filename])
  return unless files && !files.empty?
  files.each { |f| f.destroy }  # destroy all records first

  _adir = submit_dir
  backup_dir = File.join(_adir, 'BACKUP')
  FileUtils.mkdir_p(backup_dir)

  source_file = File.join(_adir, filename)
  dest_file = File.join(backup_dir, filename)
  FileUtils.mv(source_file, dest_file, :force => true)
end
submit(user, file, submission_time, sdir=SUBMISSIONS_PATH) click to toggle source

Handles file submissions. Late submissions have a status of “late”

# File app/models/submission.rb, line 96
def submit(user, file, submission_time, sdir=SUBMISSIONS_PATH)
  filename = file.original_filename

  # create a backup if file already exists
  dir = submit_dir(sdir)
  filepath = File.join(dir, filename)
  create_backup(filename, sdir) if File.exists?(filepath)

  # create a submission_file record
  submission_file = submission_files.create do |f|
    f.user = user
    f.filename = file.original_filename
    f.submitted_at = submission_time
    f.submission_file_status = 'late' if assignment.due_date < submission_time
  end

  # upload file contents to file system
  File.open(filepath, 'wb') { |f| f.write(file.read) } if submission_file.save
  submission_file
end