-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcoaches.py
237 lines (193 loc) · 8.99 KB
/
coaches.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# use json in Python 2.7, fallback to simplejson for Python 2.5
try:
import json
except ImportError:
import simplejson as json
import custom_exceptions
import util
import user_util
import request_handler
from user_models import UserData, StudentList
from coach_resources.coach_request_model import CoachRequest
import profiles.util_profile as util_profile
def update_coaches_and_requests(user_data, coaches_json):
""" Update the user's coaches and requests.
Expects a list of jsonified UserProfiles, where an
isCoachingLoggedInUser value of True indicates a coach relationship,
and a value of False indicates a pending request.
Any extant coach or request relationships not represented in
coaches_json will be deleted.
"""
requester_emails = update_coaches(user_data, coaches_json)
update_requests(user_data, requester_emails)
return util_profile.UserProfile.get_coach_and_requester_profiles_for_student(user_data)
def update_coaches(user_data, coaches_json):
""" Add as coaches those in coaches_json with isCoachingLoggedInUser
value True, and remove any old coaches not in coaches_json.
Return a list of requesters' emails.
"""
updated_coach_key_emails = []
current_coaches_data = user_data.get_coaches_data()
outstanding_coaches_dict = dict([(coach.email, coach.key_email)
for coach in current_coaches_data])
requester_emails = []
for coach_json in coaches_json:
email = coach_json['email']
is_coaching_logged_in_user = coach_json['isCoachingLoggedInUser']
if is_coaching_logged_in_user:
if email in outstanding_coaches_dict:
# Email corresponds to a current coach
updated_coach_key_emails.append(outstanding_coaches_dict[email])
del outstanding_coaches_dict[email]
else:
# Look up this new coach's key_email
coach_user_data = UserData.get_from_username_or_email(email)
if coach_user_data is not None:
updated_coach_key_emails.append(coach_user_data.key_email)
else:
raise custom_exceptions.InvalidEmailException()
else:
requester_emails.append(email)
user_data.remove_student_lists(outstanding_coaches_dict.keys())
user_data.coaches = updated_coach_key_emails
user_data.put()
return requester_emails
def update_requests(user_data, requester_emails):
""" Remove all CoachRequests not represented by requester_emails.
"""
current_requests = CoachRequest.get_for_student(user_data)
for current_request in current_requests:
coach_email = current_request.coach_requesting_data.email
if coach_email not in requester_emails:
current_request.delete()
class ViewCoaches(request_handler.RequestHandler):
@user_util.login_required_and(phantom_user_allowed=False)
def get(self):
""" Redirect legacy /coaches to profile page's coaches tab.
"""
user_data = UserData.current()
self.redirect(user_data.profile_root + "coaches")
class ViewStudents(request_handler.RequestHandler):
@user_util.login_required_and(phantom_user_allowed=False)
def get(self):
user_data = UserData.current()
user_data_override = self.request_user_data("coach_email")
if user_util.is_current_user_developer() and user_data_override:
user_data = user_data_override
invalid_student = self.request_bool("invalid_student", default = False)
coach_requests = [x.student_requested_data.email for x in CoachRequest.get_for_coach(user_data) if x.student_requested_data]
student_lists_models = StudentList.get_for_coach(user_data.key())
student_lists_list = [];
for student_list in student_lists_models:
student_lists_list.append({
'key': str(student_list.key()),
'name': student_list.name,
})
student_lists_dict = dict((g['key'], g) for g in student_lists_list)
students_data = user_data.get_students_data()
students = map(lambda s: {
'key': str(s.key()),
'email': s.email,
'nickname': s.nickname,
'profile_root': s.profile_root,
'studentLists': [l for l in [student_lists_dict.get(str(list_id)) for list_id in s.student_lists] if l],
}, students_data)
students.sort(key=lambda s: s['nickname'])
template_values = {
'students': students,
'students_json': json.dumps(students),
'student_lists': student_lists_list,
'student_lists_json': json.dumps(student_lists_list),
'invalid_student': invalid_student,
'coach_requests': coach_requests,
'coach_requests_json': json.dumps(coach_requests),
'selected_nav_link': 'coach',
'email': user_data.email,
}
self.render_jinja2_template('viewstudentlists.html', template_values)
class RequestStudent(request_handler.RequestHandler):
@user_util.login_required_and(phantom_user_allowed=False)
def post(self):
user_data = UserData.current()
user_data_student = self.request_student_user_data()
if user_data_student:
if not user_data_student.is_coached_by(user_data):
coach_request = CoachRequest.get_or_insert_for(user_data, user_data_student)
if coach_request:
if not self.is_ajax_request():
self.redirect("/students")
return
if self.is_ajax_request():
self.response.set_status(404)
else:
self.redirect("/students?invalid_student=1")
class AcceptCoach(request_handler.RequestHandler):
@user_util.login_required_and(phantom_user_allowed=False)
@request_handler.RequestHandler.exceptions_to_http(400)
def get(self):
""" Only used when a coach deletes a request in studentlists.js.
"""
user_data = UserData.current()
accept_coach = self.request_bool("accept", default = False)
user_data_student = self.request_student_user_data()
if user_data_student:
user_data_coach = user_data
if (user_data_coach and
not user_data_student.is_coached_by(user_data_coach)):
coach_request = CoachRequest.get_for(user_data_coach, user_data_student)
if coach_request:
coach_request.delete()
if user_data.key_email == user_data_student.key_email and accept_coach:
user_data_student.coaches.append(user_data_coach.key_email)
user_data_student.put()
if not self.is_ajax_request():
self.redirect("/coaches")
class UnregisterStudentCoach(request_handler.RequestHandler):
@staticmethod
def remove_student_from_coach(student, coach):
if student.student_lists:
actual_lists = StudentList.get(student.student_lists)
student.student_lists = [l.key() for l in actual_lists if coach.key() not in l.coaches]
try:
student.coaches.remove(coach.key_email)
except ValueError:
pass
try:
student.coaches.remove(coach.key_email.lower())
except ValueError:
pass
student.put()
def do_request(self, student, coach, redirect_to):
if not UserData.current():
self.redirect(util.create_login_url(self.request.uri))
return
if student and coach:
self.remove_student_from_coach(student, coach)
if not self.is_ajax_request():
self.redirect(redirect_to)
class UnregisterStudent(UnregisterStudentCoach):
@user_util.login_required_and(phantom_user_allowed=False)
def get(self):
return self.do_request(
self.request_student_user_data(),
UserData.current(),
"/students"
)
class AddStudentToList(request_handler.RequestHandler):
@user_util.login_required_and(phantom_user_allowed=False)
@request_handler.RequestHandler.exceptions_to_http(400)
def post(self):
coach_data, student_data, student_list = util_profile.get_coach_student_and_student_list(self)
if student_list.key() in student_data.student_lists:
raise Exception("Student %s is already in list %s" % (student_data.key(), student_list.key()))
student_data.student_lists.append(student_list.key())
student_data.put()
class RemoveStudentFromList(request_handler.RequestHandler):
@user_util.login_required_and(phantom_user_allowed=False)
@request_handler.RequestHandler.exceptions_to_http(400)
def post(self):
coach_data, student_data, student_list = util_profile.get_coach_student_and_student_list(self)
# due to a bug, we have duplicate lists in the collection. fix this:
student_data.student_lists = list(set(student_data.student_lists))
student_data.student_lists.remove(student_list.key())
student_data.put()