Coverage for e2xgrader/exchange/fetch_feedback.py: 12%

57 statements  

« prev     ^ index     » next       coverage.py v7.4.2, created at 2024-03-14 13:22 +0100

1import glob 

2import os 

3 

4from nbgrader.exchange.default import ExchangeFetchFeedback 

5from nbgrader.utils import check_mode, get_username, make_unique_key, notebook_hash 

6 

7from .exchange import E2xExchange 

8 

9 

10class E2xExchangeFetchFeedback(E2xExchange, ExchangeFetchFeedback): 

11 def init_src(self): 

12 if self.coursedir.course_id == "": 

13 self.fail("No course id specified. Re-run with --course flag.") 

14 

15 self.course_path = os.path.join(self.root, self.coursedir.course_id) 

16 self.outbound_path = os.path.join(self.course_path, self.feedback_directory) 

17 self.src_path = os.path.join(self.outbound_path) 

18 self.cache_path = os.path.join(self.cache, self.coursedir.course_id) 

19 

20 if self.coursedir.student_id != "*": 

21 # An explicit student id has been specified on the command line; we use it as student_id 

22 if "*" in self.coursedir.student_id or "+" in self.coursedir.student_id: 

23 self.fail( 

24 "The student ID should contain no '*' nor '+'; got {}".format( 

25 self.coursedir.student_id 

26 ) 

27 ) 

28 student_id = self.coursedir.student_id 

29 else: 

30 student_id = get_username() 

31 

32 if not os.path.isdir(self.src_path): 

33 self._assignment_not_found( 

34 self.src_path, os.path.join(self.outbound_path, "*") 

35 ) 

36 if not check_mode(self.src_path, execute=True): 

37 self.fail( 

38 "You don't have execute permissions for the directory: {}".format( 

39 self.src_path 

40 ) 

41 ) 

42 

43 assignment_id = ( 

44 self.coursedir.assignment_id if self.coursedir.assignment_id else "*" 

45 ) 

46 pattern = os.path.join(self.cache_path, "*+{}+*".format(assignment_id)) 

47 self.log.debug("Looking for submissions with pattern: {}".format(pattern)) 

48 

49 self.feedback_files = [] 

50 submissions = [os.path.split(x)[-1] for x in glob.glob(pattern)] 

51 for submission in submissions: 

52 _, assignment_id, timestamp = submission.split("/")[-1].split("+") 

53 

54 self.log.debug( 

55 "Looking for feedback for '{}/{}' submitted at {}".format( 

56 self.coursedir.course_id, assignment_id, timestamp 

57 ) 

58 ) 

59 

60 pattern = os.path.join(self.cache_path, submission, "*.ipynb") 

61 notebooks = glob.glob(pattern) 

62 for notebook in notebooks: 

63 notebook_id = os.path.splitext(os.path.split(notebook)[-1])[0] 

64 

65 # Check if personalized_feedback is used 

66 if self.personalized_feedback: 

67 feedbackpath = os.path.join( 

68 self.outbound_path, 

69 student_id, 

70 assignment_id, 

71 "{}.html".format(notebook_id), 

72 ) 

73 self.log.debug("Feedback file: ", feedbackpath) 

74 if os.path.exists(feedbackpath): 

75 self.feedback_files.append( 

76 (notebook_id, timestamp, feedbackpath) 

77 ) 

78 self.log.info( 

79 "Found feedback for '{}/{}/{}' submitted at {}".format( 

80 self.coursedir.course_id, 

81 assignment_id, 

82 notebook_id, 

83 timestamp, 

84 ) 

85 ) 

86 continue 

87 

88 # If we reached here, then there's no feedback available 

89 self.log.warning( 

90 "Could not find feedback for '{}/{}/{}' submitted at {}".format( 

91 self.coursedir.course_id, 

92 assignment_id, 

93 notebook_id, 

94 timestamp, 

95 ) 

96 ) 

97 else: 

98 unique_key = make_unique_key( 

99 self.coursedir.course_id, 

100 assignment_id, 

101 notebook_id, 

102 student_id, 

103 timestamp, 

104 ) 

105 

106 # Look for the feedback using new-style of feedback 

107 self.log.debug("Unique key is: {}".format(unique_key)) 

108 nb_hash = notebook_hash(notebook, unique_key) 

109 feedbackpath = os.path.join( 

110 self.outbound_path, "{0}.html".format(nb_hash) 

111 ) 

112 if os.path.exists(feedbackpath): 

113 self.feedback_files.append( 

114 (notebook_id, timestamp, feedbackpath) 

115 ) 

116 self.log.info( 

117 "Found feedback for '{}/{}/{}' submitted at {}".format( 

118 self.coursedir.course_id, 

119 assignment_id, 

120 notebook_id, 

121 timestamp, 

122 ) 

123 ) 

124 continue 

125 

126 # If it doesn't exist, try the legacy hashing 

127 nb_hash = notebook_hash(notebook) 

128 feedbackpath = os.path.join( 

129 self.outbound_path, "{0}.html".format(nb_hash) 

130 ) 

131 if os.path.exists(feedbackpath): 

132 self.feedback_files.append( 

133 (notebook_id, timestamp, feedbackpath) 

134 ) 

135 self.log.warning( 

136 "Found legacy feedback for '{}/{}/{}' submitted at {}".format( 

137 self.coursedir.course_id, 

138 assignment_id, 

139 notebook_id, 

140 timestamp, 

141 ) 

142 ) 

143 continue 

144 

145 # If we reached here, then there's no feedback available 

146 self.log.warning( 

147 "Could not find feedback for '{}/{}/{}' submitted at {}".format( 

148 self.coursedir.course_id, 

149 assignment_id, 

150 notebook_id, 

151 timestamp, 

152 ) 

153 )