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.

98 lines
2.2 KiB

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