Coverage for model/homework.py: 100%

95 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2024-11-05 04:22 +0000

1from typing import List 

2from flask import Blueprint, request 

3from mongo import * 

4from mongo import engine 

5from .utils import * 

6from .auth import login_required 

7from .course import course_api 

8 

9__all__ = ['homework_api'] 

10 

11homework_api = Blueprint('homework_api', __name__) 

12 

13 

14@homework_api.route('/', methods=['POST']) 

15@homework_api.route('/<homework_id>', methods=['PUT', 'DELETE', 'GET']) 

16@login_required 

17def homework_entry(user, homework_id=None): 

18 ''' 

19 apply a operation to single homework 

20 ''' 

21 

22 @Request.json('name', 'course_name', 'markdown', 'start', 'end', 

23 'problem_ids', 'scoreboard_status', 'penalty') 

24 def add_homework(course_name, name, markdown, start, end, problem_ids, 

25 scoreboard_status, penalty): 

26 try: 

27 homework = Homework.add( 

28 user=user, 

29 hw_name=name, 

30 markdown=markdown, 

31 scoreboard_status=scoreboard_status, 

32 course_name=course_name, 

33 problem_ids=problem_ids or [], 

34 start=start, 

35 end=end, 

36 penalty=penalty, 

37 ) 

38 except NameError: 

39 return HTTPError('user must be the teacher or ta of this course', 

40 403) 

41 except FileExistsError: 

42 return HTTPError('homework exists in this course', 400) 

43 return HTTPResponse('Add homework Success') 

44 

45 @Request.json('name', 'markdown', 'start', 'end', 'problem_ids', 

46 'scoreboard_status', 'penalty') 

47 def update_homework(name, markdown, start, end, problem_ids, 

48 scoreboard_status, penalty): 

49 homework = Homework.update( 

50 user=user, 

51 homework_id=homework_id, 

52 markdown=markdown, 

53 new_hw_name=name, 

54 start=start, 

55 end=end, 

56 problem_ids=problem_ids, 

57 scoreboard_status=scoreboard_status, 

58 penalty=penalty, 

59 ) 

60 return HTTPResponse('Update homework Success') 

61 

62 def delete_homework(): 

63 homework = Homework(homework_id) 

64 homework = homework.delete_problems(user=user, 

65 course=homework.course_id) 

66 return HTTPResponse('Delete homework Success') 

67 

68 def get_homework(): 

69 homework = Homework.get_by_id(homework_id) 

70 ret = { 

71 'name': 

72 homework.homework_name, 

73 'start': 

74 int(homework.duration.start.timestamp()), 

75 'end': 

76 int(homework.duration.end.timestamp()), 

77 'problemIds': 

78 homework.problem_ids, 

79 'markdown': 

80 homework.markdown, 

81 'studentStatus': 

82 homework.student_status 

83 if user.role < 2 else homework.student_status.get(user.username), 

84 'penalty': 

85 homework.penalty if hasattr(homework, 'penalty') else None, 

86 } 

87 return HTTPResponse('get homework', data=ret) 

88 

89 handler = { 

90 'GET': get_homework, 

91 'POST': add_homework, 

92 'PUT': update_homework, 

93 'DELETE': delete_homework 

94 } 

95 

96 try: 

97 return handler[request.method]() 

98 except engine.DoesNotExist as e: 

99 return HTTPError(str(e), 404) 

100 except (PermissionError, engine.NotUniqueError) as e: 

101 return HTTPError(str(e), 403) 

102 

103 

104@course_api.route('/<course_name>/homework', methods=['GET']) 

105@login_required 

106def get_homework_list(user, course_name): 

107 ''' 

108 get a list of homework 

109 ''' 

110 try: 

111 homeworks = Homework.get_homeworks(course_name=course_name) 

112 data = [] 

113 for homework in homeworks: 

114 new = { 

115 'name': homework.homework_name, 

116 'start': int(homework.duration.start.timestamp()), 

117 'end': int(homework.duration.end.timestamp()), 

118 'problemIds': homework.problem_ids, 

119 'markdown': homework.markdown, 

120 'id': str(homework.id) 

121 } 

122 # normal user can not view other's status 

123 if user.role < 2: 

124 new.update({'studentStatus': homework.student_status}) 

125 else: 

126 new.update({ 

127 'studentStatus': 

128 homework.student_status.get(user.username) 

129 }) 

130 data.append(new) 

131 except DoesNotExist: 

132 return HTTPError('course not exists', 

133 404, 

134 data={'courseName': course_name}) 

135 return HTTPResponse('get homeworks', data=data) 

136 

137 

138@homework_api.route('/<course>/<homework_name>/ip-filters', methods=['GET']) 

139@login_required 

140def get_ip_filters( 

141 user, 

142 course: str, 

143 homework_name: str, 

144): 

145 if user.role != 0: 

146 return HTTPError('Not admin!', 403) 

147 try: 

148 hw = Homework.get_by_name(course, homework_name) 

149 except DoesNotExist: 

150 return HTTPError('Homework does not exist', 404) 

151 return HTTPResponse(data={'ipFilters': hw.ip_filters}) 

152 

153 

154@homework_api.route('/<course>/<homework_name>/ip-filters', methods=['PATCH']) 

155@login_required 

156@Request.json('patches:list') 

157def patch_ip_filters( 

158 user, 

159 course: str, 

160 homework_name: str, 

161 patches: List, 

162): 

163 if user.role != 0: 

164 return HTTPError('Not admin!', 403) 

165 try: 

166 hw = Homework.get_by_name(course, homework_name) 

167 except DoesNotExist: 

168 return HTTPError('Homework does not exist', 404) 

169 adds = [] 

170 dels = [] 

171 for patch in patches: 

172 op = patch.get('op') 

173 if op not in {'add', 'del'}: 

174 return HTTPError('Invalid operation', 400, data={'op': op}) 

175 value = patch.get('value') 

176 if value is None: 

177 return HTTPError('Value not found', 400) 

178 if op == 'add': 

179 adds.append(value) 

180 else: 

181 dels.append(value) 

182 # Validate filter format 

183 try: 

184 IPFilter(value) 

185 except ValueError as e: 

186 return HTTPError(str(e), 400) 

187 

188 hw.update(push_all__ip_filters=adds) 

189 hw.update(pull_all__ip_filters=dels) 

190 return HTTPResponse()