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.

99 lines
2.3 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, '*', ''].map! { |fn| File.basename fn }
  29. end
  30. def assignments(courseid)
  31. Dir[File.join course(courseid), '*', ''].map! { |fn| File.basename fn }
  32. end
  33. def semesters(courseid)
  34. Dir[roster courseid, '*'].map! { |fn| File.basename File.dirname fn }
  35. end
  36. # -------------------------------------------------------------------------
  37. def load(path)
  38. case File.extname path
  39. when '.txt'
  40. File.read path
  41. when '.json'
  42. JSON.parse File.read(path)
  43. when '.yml', '.yaml'
  44. YAML.load File.read(path)
  45. when '.csv'
  46. File.read(path).split("\n").map! { |line| line.split "," }
  47. else
  48. raise FilesystemError, "unknown file type: #{path}"
  49. end
  50. rescue SystemCallError # Errno::ENOENT, etc.
  51. raise FilesystemError, "can't read file: #{path}"
  52. end
  53. def jail
  54. @jail ||= Jail.new jail_dir
  55. end
  56. def reset_desk
  57. FileUtils.rm_rf Dir[File.join desk_dir, '*', '']
  58. end
  59. def clean_desk
  60. Dir[File.join desk_dir, '*', '*', '*', '*', 'status.txt'].each do |fn|
  61. File.write fn, "ungraded" if File.read(fn) == "graded"
  62. end
  63. FileUtils.rm_rf Dir[File.join desk_dir, '*', '*', '*', '*', 'pending']
  64. end
  65. # -------------------------------------------------------------------------
  66. private
  67. def desk_dir
  68. File.join @root, 'desk'
  69. end
  70. def jail_dir
  71. File.join @root, 'jail'
  72. end
  73. def spec_dir
  74. File.join @root, 'spec'
  75. end
  76. end
  77. end