class SubmissionFile

Constants

FILENAME_SANITIZATION_REGEXP

Only allow alphanumeric characters, ‘.’, ‘-’, and ‘_’ as character set for submission files.

SUBSTITUTION_CHAR

Character to be used as a replacement for all characters matching the regular expression above

Public Class Methods

is_binary?(file_contents) click to toggle source

Taken from blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/44936

# File app/models/submission_file.rb, line 77
def self.is_binary?(file_contents)
  return file_contents.size == 0 ||
        file_contents.count('^ -~', "^\r\n") / file_contents.size > 0.3 ||
        file_contents.count("\x00") > 0
end

Public Instance Methods

convert_pdf_to_jpg() click to toggle source
# File app/models/submission_file.rb, line 105
def convert_pdf_to_jpg
  return unless MarkusConfigurator.markus_config_pdf_support && self.is_pdf?
  m_logger = MarkusLogger.instance
  storage_path = File.join(MarkusConfigurator.markus_config_pdf_storage,
    self.submission.grouping.group.repository_name,
    self.path)
  file_path = File.join(storage_path, self.filename.split('.')[0] + '.jpg')
  self.export_file(storage_path)

  # Remove any old copies of this image if they exist
  i = 1
  filePathToRemove = File.join(storage_path,
                               self.filename.split('.')[0] + '_' + sprintf('%04d' % i.to_s()) + '.jpg')
  while File.exists?(filePathToRemove)
    FileUtils.remove_file(filePathToRemove, true)
    i += 1
    filePathToRemove = File.join(storage_path,
                                 self.filename.split('.')[0] + '_' + sprintf('%04d' % i.to_s()) + '.jpg')
  end

  # Convert a pdf file into a an array of jpg files (one jpg file = one page
  # of the pdf file)
  file = RGhost::Convert.new(File.join(storage_path,
                                self.filename))
  results = file.to :jpeg,
                    :filename => file_path,
                    :multipage => true,
                    :resolution => 150
  if file.error
    m_logger.log('rghost: Image conversion error')
  end

  FileUtils.remove_file(File.join(storage_path, self.filename), true)
  self.is_converted = true
  self.save
end
export_file(storage_path) click to toggle source

Export this file from the svn repository into storage_path If a file of the same name as the one we are trying to export exists in the given repository, it will be overwritten by the svn exports

# File app/models/submission_file.rb, line 165
def export_file(storage_path)
  m_logger = MarkusLogger.instance
  m_logger.log("Exporting #{self.filename} from student repository")
  begin
    # Create the storage directories if they dont already exist
    FileUtils.makedirs(storage_path)
    # but deleted the file if it already exists
    if File.exists?(File.join(storage_path, self.filename))
      FileUtils.rm(File.join(storage_path, self.filename))
    end
    repo = submission.grouping.group.repo
    revision_number = submission.revision_number
    repo.export(File.join(storage_path, self.filename),
                File.join(self.path, self.filename),
                revision_number)
  end

  # Let's check the file exists befor claiming the file has been exported
  # properly
  if File.exists?(File.join(storage_path, self.filename))
    m_logger.log("Successfully exported #{self.filename} from student repository to #{File.join(storage_path, self.filename)}")
  else
    m_logger.log("Failed to export #{self.filename} from student
                    repository")
  end
end
get_annotation_grid() click to toggle source

Return an array representing the annotated areas of the submission file

Returns:

An array containing the extracted coordinates of all the annotations associated with this file

Return nil if this SubmissionFile is not a supported image.

# File app/models/submission_file.rb, line 92
def get_annotation_grid
  return unless self.is_supported_image? || self.is_pdf?
  all_annotations = []
  self.annotations.each do |annot|
    if annot.is_a?(ImageAnnotation)
      extracted_coords = annot.extract_coords
      return nil if extracted_coords.nil?
      all_annotations.push(extracted_coords)
    end
  end
  all_annotations
end
get_comment_syntax() click to toggle source
# File app/models/submission_file.rb, line 46
def get_comment_syntax
  # This is where you can add more languages that SubmissionFile will
  # be able to insert comments into, for example when downloading annotations.
  # It will return a list, with the first element being the syntax to start a
  # comment and the second element being the syntax to end a comment.  Use
  #the language's multiple line comment format.
  case File.extname(filename)
  when '.java', '.js', '.c'
    return %w(/* */)
  when '.rb'
    return ["=begin\n", "\n=end"]
  when '.py'
    return %w(""" """)
  when '.scm', '.ss'
    return %w(#| |#)
  else
    return %w(## ##)
  end
end
get_file_type() click to toggle source
# File app/models/submission_file.rb, line 20
def get_file_type
  # This is where you can add more languages that SubmissionFile will
  # recognize.  It will return the name of the language, which
  # SyntaxHighlighter can work with.
  case File.extname(filename)
  when '.sci'
    return 'scilab'
  when '.java'
    return 'java'
  when '.rb'
    return 'ruby'
  when '.py'
    return 'python'
  when '.js'
    return 'javascript'
  when '.c'
    return 'c'
  when '.scm'
    return 'scheme'
  when '.ss'
    return 'scheme'
  else
    return 'unknown'
  end
end
is_pdf?() click to toggle source
# File app/models/submission_file.rb, line 72
def is_pdf?
  File.extname(filename).casecmp('.pdf') == 0
end
is_supported_image?() click to toggle source
# File app/models/submission_file.rb, line 66
def is_supported_image?
  #Here you can add more image types to support
  supported_formats = %w(.jpeg .jpg .gif .png)
  supported_formats.include?(File.extname(filename))
end
retrieve_file(include_annotations=false) click to toggle source

Return the contents of this SubmissionFile. Include annotations in the file if include_annotations is true.

# File app/models/submission_file.rb, line 144
def retrieve_file(include_annotations=false)
  student_group = submission.grouping.group
  repo = student_group.repo
  revision_number = submission.revision_number
  revision = repo.get_revision(revision_number)
  if revision.files_at_path(path)[filename].nil?
    raise I18n.t('results.could_not_find_file',
                 :filename => filename,
                 :repository_name => student_group.repository_name)
  end
  retrieved_file = repo.download_as_string(revision.files_at_path(path)[filename])
  repo.close
  if include_annotations
    retrieved_file = add_annotations(retrieved_file)
  end
  retrieved_file
end