1 # Copyright (C) 2012 W. Trevor King <wking@tremily.us>
3 # This file is part of pygrader.
5 # pygrader is free software: you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation, either version 3 of the License, or (at your option) any later
10 # pygrader is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License along with
15 # pygrader. If not, see <http://www.gnu.org/licenses/>.
17 "Define assorted handlers for use in :py:mod:`~pygrader.mailpipe`."
19 import pgp_mime as _pgp_mime
22 class InvalidMessage (ValueError):
23 def __init__(self, message=None, error=None):
24 super(InvalidMessage, self).__init__(error)
25 self.message = message
29 """Return a short string identifying the invalid message.
31 if self.message is None:
33 subject = self.message['Subject']
34 if subject is not None:
36 message_id = self.message['Message-ID']
37 if message_id is not None:
42 class PermissionViolationMessage (InvalidMessage):
43 def __init__(self, person=None, allowed_groups=None, **kwargs):
44 if 'error' not in kwargs:
45 kwargs['error'] = 'action not permitted'
46 super(PermissionViolationMessage, self).__init__(**kwargs)
48 self.allowed_groups = allowed_groups
51 class InsecureMessage (InvalidMessage):
52 def __init__(self, **kwargs):
53 if 'error' not in kwargs:
54 kwargs['error'] = 'insecure message'
55 super(InsecureMessage, self).__init__(**kwargs)
58 class UnsignedMessage (InsecureMessage):
59 def __init__(self, **kwargs):
60 if 'error' not in kwargs:
61 kwargs['error'] = 'unsigned message'
62 super(UnsignedMessage, self).__init__(**kwargs)
65 class InvalidSubjectMessage (InvalidMessage):
66 def __init__(self, subject=None, **kwargs):
67 if 'error' not in kwargs:
68 kwargs['error'] = 'invalid subject {!r}'.format(subject)
69 super(InvalidSubjectMessage, self).__init__(**kwargs)
70 self.subject = subject
73 class InvalidStudentSubject (InvalidSubjectMessage):
74 def __init__(self, students=None, **kwargs):
75 if 'error' not in kwargs:
77 kwargs['error'] = 'Subject matches multiple students'
79 kwargs['error'] = "Subject doesn't match any student"
80 super(InvalidStudentSubject, self).__init__(**kwargs)
81 self.students = students
84 class InvalidAssignmentSubject (InvalidSubjectMessage):
85 def __init__(self, assignments=None, **kwargs):
86 if 'error' not in kwargs:
88 kwargs['error'] = 'Subject matches multiple assignments'
90 kwargs['error'] = "Subject doesn't match any assignment"
91 super(InvalidAssignmentSubject, self).__init__(kwargs)
92 self.assignments = assignments
95 class Response (Exception):
96 """Exception to bubble out email responses.
98 Rather than sending email responses themselves, handlers should
99 raise this exception. The caller can catch it and mail the email
100 (or take other appropriate action).
102 def __init__(self, message=None, complete=False):
103 super(Response, self).__init__()
104 self.message = message
105 self.complete = complete
108 def get_subject_student(course, subject):
109 lsubject = subject.lower()
110 students = [p for p in course.find_people()
111 if p.name.lower() in lsubject]
112 if len(students) == 1:
114 raise InvalidStudentSubject(students=students, subject=subject)
116 def get_subject_assignment(course, subject):
117 lsubject = subject.lower()
118 assignments = [a for a in course.assignments
119 if a.name.lower() in lsubject]
120 if len(assignments) == 1:
121 return assignments[0]
122 raise InvalidAssignmentSubject(assignments=assignments, subject=subject)