A code autograder for student homework submissions
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.4 KiB

  1. require 'json'
  2. require 'yaml'
  3. module KGrader
  4. class Filesystem
  5. def initialize(root)
  6. @root = root
  7. end
  8. def course(name)
  9. File.join spec_dir, name
  10. end
  11. def course_config(name)
  12. File.join course(name), '_config.yml'
  13. end
  14. def assignment(courseid, name)
  15. File.join course(courseid), name
  16. end
  17. def assignment_config(courseid, name)
  18. File.join assignment(courseid, name), '_config.yml'
  19. end
  20. def roster(courseid, semester)
  21. File.join desk_dir, courseid, semester, '_roster.csv'
  22. end
  23. def submission(courseid, semester, assignment, student)
  24. File.join desk_dir, courseid, semester, assignment, student
  25. end
  26. # -------------------------------------------------------------------------
  27. def courses
  28. Dir[File.join spec_dir, '*', '_config.yml'].map! do |fn|
  29. File.basename File.dirname fn
  30. end
  31. end
  32. def assignments(courseid)
  33. Dir[File.join course(courseid), '*', ''].map! { |fn| File.basename fn }
  34. end
  35. def semesters(courseid)
  36. Dir[roster courseid, '*'].map! { |fn| File.basename File.dirname fn }
  37. end
  38. # -------------------------------------------------------------------------
  39. def load(path)
  40. case File.extname path
  41. when '.txt'
  42. File.read path
  43. when '.json'
  44. JSON.parse File.read(path)
  45. when '.yml', '.yaml'
  46. YAML.load File.read(path)
  47. when '.csv'
  48. File.read(path).split("\n").map! { |line| line.split "," }
  49. else
  50. raise FilesystemError, "unknown file type: #{path}"
  51. end
  52. rescue SystemCallError # Errno::ENOENT, etc.
  53. raise FilesystemError, "can't read file: #{path}"
  54. end
  55. def jail
  56. @jail ||= Jail.new jail_dir
  57. end
  58. def reset_desk
  59. FileUtils.rm_rf Dir[File.join desk_dir, '*', '']
  60. end
  61. def clean_desk
  62. Dir[File.join desk_dir, '*', '*', '*', '*', 'status.txt'].each do |fn|
  63. File.write fn, "ungraded" if File.read(fn) == "graded"
  64. end
  65. FileUtils.rm_f Dir[File.join desk_dir, '*', '*', '*', '*', 'pending']
  66. FileUtils.rm_f Dir[File.join desk_dir, '*', '*', '*', '*', '*.log*']
  67. end
  68. # -------------------------------------------------------------------------
  69. private
  70. def desk_dir
  71. File.join @root, 'desk'
  72. end
  73. def jail_dir
  74. File.join @root, 'jail'
  75. end
  76. def spec_dir
  77. File.join @root, 'spec'
  78. end
  79. end
  80. end