1
|
|
|
from django.contrib.auth.decorators import login_required |
2
|
|
|
from django.views.decorators.csrf import csrf_exempt |
3
|
|
|
from django.core.urlresolvers import reverse, reverse_lazy |
4
|
|
|
# from django.db.models import Q |
5
|
|
|
from django.contrib.sites.models import Site |
6
|
|
|
from django.http import HttpResponseRedirect, JsonResponse |
7
|
|
|
from django.shortcuts import get_object_or_404 |
8
|
|
|
from django.shortcuts import redirect, render |
9
|
|
|
from django.template import loader |
10
|
|
|
from django.views import generic |
11
|
|
|
|
12
|
|
|
from braces import views |
13
|
|
|
from wye.base.emailer_html import send_email_to_list |
14
|
|
|
from wye.organisations.models import Organisation |
15
|
|
|
from wye.profiles.models import Profile |
16
|
|
|
# from wye.regions.models import RegionalLead |
17
|
|
|
from wye.base.constants import WorkshopStatus |
18
|
|
|
|
19
|
|
|
from wye.social.sites.twitter import send_tweet |
20
|
|
|
from wye.base.views import verify_user_profile |
21
|
|
|
from .forms import ( |
22
|
|
|
WorkshopForm, |
23
|
|
|
WorkshopEditForm, |
24
|
|
|
WorkshopFeedbackForm, |
25
|
|
|
WorkshopListForm, |
26
|
|
|
WorkshopVolunteer) |
27
|
|
|
from .mixins import ( |
28
|
|
|
WorkshopEmailMixin, |
29
|
|
|
WorkshopAccessMixin |
30
|
|
|
) |
31
|
|
|
from .models import Workshop, WorkshopFeedBack |
32
|
|
|
|
33
|
|
|
|
34
|
|
|
@login_required |
35
|
|
|
@verify_user_profile |
36
|
|
|
def workshop_list(request): |
37
|
|
|
template_name = 'workshops/workshop_list.html' |
38
|
|
|
user_profile, created = Profile.objects.get_or_create( |
39
|
|
|
user__id=request.user.id) |
40
|
|
|
if not user_profile.is_profile_filled: |
41
|
|
|
return redirect('profiles:profile-edit', slug=request.user.username) |
42
|
|
|
context_dict = {} |
43
|
|
|
workshop_list = Workshop.objects.filter( |
44
|
|
|
is_active=True).order_by('-expected_date') |
45
|
|
|
workshop_list = workshop_list.filter( |
46
|
|
|
requester__location__state__id__in=[ |
47
|
|
|
x.id for x in request.user.profile.interested_states.all()] |
48
|
|
|
) |
49
|
|
|
|
50
|
|
|
location_list = request.GET.getlist("location") |
51
|
|
|
if location_list: |
52
|
|
|
workshop_list = workshop_list.filter( |
53
|
|
|
requester__location__id__in=location_list |
54
|
|
|
) |
55
|
|
|
|
56
|
|
|
presenter_list = request.GET.getlist("presenter") |
57
|
|
|
if presenter_list: |
58
|
|
|
workshop_list = workshop_list.filter( |
59
|
|
|
presenter__id__in=presenter_list |
60
|
|
|
) |
61
|
|
|
|
62
|
|
|
workshop_level_list = request.GET.getlist("level") |
63
|
|
|
if workshop_level_list: |
64
|
|
|
workshop_list = workshop_list.filter( |
65
|
|
|
workshop_level__in=workshop_level_list |
66
|
|
|
) |
67
|
|
|
|
68
|
|
|
workshop_section_list = request.GET.getlist("section") |
69
|
|
|
if workshop_section_list: |
70
|
|
|
workshop_list = workshop_list.filter( |
71
|
|
|
workshop_section__id__in=workshop_section_list |
72
|
|
|
) |
73
|
|
|
|
74
|
|
|
status_list = request.GET.getlist("status") |
75
|
|
|
if status_list: |
76
|
|
|
workshop_list = workshop_list.filter( |
77
|
|
|
status__in=status_list |
78
|
|
|
) |
79
|
|
|
|
80
|
|
|
context_dict['workshop_list'] = workshop_list |
81
|
|
|
context_dict['user'] = request.user |
82
|
|
|
# need to improve the part |
83
|
|
|
context_dict['is_not_tutor'] = False |
84
|
|
|
# as user can be tutor and regional lead hence we need to verify like |
85
|
|
|
# this |
86
|
|
|
if (Profile.is_regional_lead(request.user) or |
87
|
|
|
Profile.is_organiser(request.user) or |
88
|
|
|
Profile.is_admin(request.user)): |
89
|
|
|
context_dict['is_not_tutor'] = True |
90
|
|
|
|
91
|
|
|
context_dict['form'] = WorkshopListForm(user=request.user) |
92
|
|
|
|
93
|
|
|
return render(request, template_name, context_dict) |
94
|
|
|
|
95
|
|
|
|
96
|
|
|
def workshop_details(request, pk): |
97
|
|
|
template_name = 'workshops/workshop_detail.html' |
98
|
|
|
workshop_obj = get_object_or_404(Workshop, id=pk) |
99
|
|
|
show_contact_flag = False |
100
|
|
|
display_edit_button = False |
101
|
|
|
user = request.user |
102
|
|
|
user_is_presenter = [u for u in workshop_obj.presenter.all() if user == u] |
103
|
|
|
user_is_requester = [ |
104
|
|
|
u for u in workshop_obj.requester.user.all() if user == u] |
105
|
|
|
if (user_is_presenter or user_is_requester or |
106
|
|
|
user.is_superuser or ( |
107
|
|
|
(not user.is_anonymous()) and Profile.is_coordinator(user))): |
108
|
|
|
show_contact_flag = True |
109
|
|
|
if (user_is_presenter): |
110
|
|
|
display_edit_button = True |
111
|
|
|
is_admin = True if user.is_superuser else False |
112
|
|
|
form = WorkshopVolunteer(initial={ |
113
|
|
|
'number_of_volunteers': workshop_obj.number_of_volunteers or 0}) |
114
|
|
|
|
115
|
|
|
context_dict = { |
116
|
|
|
'workshop': workshop_obj, |
117
|
|
|
'show_contact_flag': show_contact_flag, |
118
|
|
|
'display_edit_button': display_edit_button, |
119
|
|
|
'is_admin': is_admin, |
120
|
|
|
'form': form |
121
|
|
|
} |
122
|
|
|
return render(request, template_name, context_dict) |
123
|
|
|
|
124
|
|
|
|
125
|
|
|
@login_required |
126
|
|
|
@verify_user_profile |
127
|
|
|
def workshop_create(request): |
128
|
|
|
template_name = 'workshops/workshop_create.html' |
129
|
|
|
context_dict = {} |
130
|
|
|
if not Organisation.list_user_organisations(request.user).exists(): |
131
|
|
|
msg = """ |
132
|
|
|
To request workshop you need to create organisaiton.\n\n |
133
|
|
|
Please use organisation tab above to create your organisation |
134
|
|
|
""" |
135
|
|
|
return render(request, 'error.html', {'message': msg}) |
136
|
|
|
if request.method == 'GET': |
137
|
|
|
form = WorkshopForm(user=request.user) |
138
|
|
|
context_dict['form'] = form |
139
|
|
|
return render(request, template_name, context_dict) |
140
|
|
|
form = WorkshopForm(user=request.user, data=request.POST) |
141
|
|
|
if not form.is_valid(): |
142
|
|
|
context_dict['form'] = form |
143
|
|
|
context_dict['errors'] = form.errors |
144
|
|
|
return render(request, template_name, context_dict) |
145
|
|
|
workshop = form.save() |
146
|
|
|
domain = Site.objects.get_current().domain |
147
|
|
|
if workshop and workshop.id: |
148
|
|
|
context = { |
149
|
|
|
'workshop': workshop, |
150
|
|
|
'date': workshop.expected_date, |
151
|
|
|
'workshop_url': domain + '/workshop/{}/'.format(workshop.id) |
152
|
|
|
} |
153
|
|
|
# Collage POC and admin email |
154
|
|
|
poc_admin_user = Profile.get_user_with_type( |
155
|
|
|
user_type=['Collage POC', 'admin'] |
156
|
|
|
).values_list('email', flat=True) |
157
|
|
|
|
158
|
|
|
org_user_emails = workshop.requester.user.filter( |
159
|
|
|
is_active=True).values_list('email', flat=True) |
160
|
|
|
# all presenter if any |
161
|
|
|
all_presenter_email = workshop.presenter.values_list( |
162
|
|
|
'email', flat=True) |
163
|
|
|
# List of tutor who have shown interest in that location |
164
|
|
|
region_interested_member = Profile.objects.filter( |
165
|
|
|
interested_locations=workshop.requester.location, |
166
|
|
|
usertype__slug='tutor' |
167
|
|
|
).values_list('user__email', flat=True) |
168
|
|
|
all_email = [] |
169
|
|
|
all_email.extend(org_user_emails) |
170
|
|
|
all_email.extend(all_presenter_email) |
171
|
|
|
all_email.extend(poc_admin_user) |
172
|
|
|
all_email.extend(region_interested_member) |
173
|
|
|
all_email = set(all_email) |
174
|
|
|
send_tweet(context) |
175
|
|
|
|
176
|
|
|
subject = '[PythonExpress] Workshop request status.' |
177
|
|
|
email_body = loader.get_template( |
178
|
|
|
'email_messages/workshop/create_workshop/message.html').render(context) |
179
|
|
|
text_body = loader.get_template( |
180
|
|
|
'email_messages/workshop/create_workshop/message.txt').render(context) |
181
|
|
|
send_email_to_list( |
182
|
|
|
subject, |
183
|
|
|
body=email_body, |
184
|
|
|
users_list=all_email, |
185
|
|
|
text_body=text_body) |
186
|
|
|
success_url = reverse_lazy('workshops:workshop_list') |
187
|
|
|
return HttpResponseRedirect(success_url) |
188
|
|
|
|
189
|
|
|
|
190
|
|
|
class WorkshopUpdate(views.LoginRequiredMixin, WorkshopAccessMixin, |
191
|
|
|
generic.UpdateView): |
192
|
|
|
model = Workshop |
193
|
|
|
form_class = WorkshopEditForm |
194
|
|
|
template_name = 'workshops/workshop_update.html' |
195
|
|
|
|
196
|
|
|
def get_success_url(self): |
197
|
|
|
# pk = self.kwargs.get(self.pk_url_kwarg, None) |
198
|
|
|
self.success_url = reverse("workshops:workshop_list") |
199
|
|
|
return super(WorkshopUpdate, self).get_success_url() |
200
|
|
|
|
201
|
|
|
def get_initial(self): |
202
|
|
|
return { |
203
|
|
|
"requester": self.object.requester.name, |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
def get_form_kwargs(self): |
207
|
|
|
kwargs = super(WorkshopUpdate, self).get_form_kwargs() |
208
|
|
|
kwargs['request'] = self.request |
209
|
|
|
return kwargs |
210
|
|
|
|
211
|
|
|
|
212
|
|
|
class WorkshopToggleActive(views.LoginRequiredMixin, views.CsrfExemptMixin, |
213
|
|
|
views.JSONResponseMixin, WorkshopAccessMixin, |
214
|
|
|
generic.UpdateView): |
215
|
|
|
model = Workshop |
216
|
|
|
fields = ('is_active', 'id') |
217
|
|
|
|
218
|
|
|
def post(self, request, *args, **kwargs): |
219
|
|
|
self.object = self.get_object() |
220
|
|
|
response = self.object.toggle_active(request.user, **kwargs) |
221
|
|
|
return self.render_json_response(response) |
222
|
|
|
|
223
|
|
|
|
224
|
|
|
class WorkshopAction(views.CsrfExemptMixin, views.LoginRequiredMixin, |
225
|
|
|
views.JSONResponseMixin, WorkshopEmailMixin, |
226
|
|
|
generic.UpdateView): |
227
|
|
|
|
228
|
|
|
model = Workshop |
229
|
|
|
email_dir = 'email_messages/workshop/assign_me/' |
230
|
|
|
|
231
|
|
|
def post(self, request, *args, **kwargs): |
232
|
|
|
self.object = self.get_object() |
233
|
|
|
response = self.object.manage_action(request.user, **kwargs) |
234
|
|
|
|
235
|
|
|
if response['status'] and response.get('notify') is not None: |
236
|
|
|
self.send_mail(request.user, response['assigned']) |
237
|
|
|
del response['notify'] |
238
|
|
|
return self.render_json_response(response) |
239
|
|
|
|
240
|
|
|
def send_mail(self, user, assigned): |
241
|
|
|
"""Send email to presenter and org users.""" |
242
|
|
|
|
243
|
|
|
workshop = self.object |
244
|
|
|
context = { |
245
|
|
|
'presenter': True, |
246
|
|
|
'assigned': assigned, |
247
|
|
|
'date': workshop.expected_date, |
248
|
|
|
'presenter_name': user.username, |
249
|
|
|
'workshop_organization': workshop.requester, |
250
|
|
|
'workshop_url': self.request.build_absolute_uri(reverse( |
251
|
|
|
'workshops:workshop_detail', args=[workshop.pk] |
252
|
|
|
)) |
253
|
|
|
} |
254
|
|
|
# email to presenter and group |
255
|
|
|
self.send_mail_to_presenter(user, context) |
256
|
|
|
context['presenter'] = False |
257
|
|
|
self.send_mail_to_group(context, exclude_emails=[user.email]) |
258
|
|
|
|
259
|
|
|
|
260
|
|
|
# class WorkshopFeedbackView(views.LoginRequiredMixin, |
261
|
|
|
# generic.FormView): |
262
|
|
|
# form_class = WorkshopFeedbackForm |
263
|
|
|
# template_name = "workshops/workshop_feedback.html" |
264
|
|
|
# success_url = reverse_lazy('workshops:workshop_list') |
265
|
|
|
|
266
|
|
|
# def form_valid(self, form): |
267
|
|
|
# workshop_id = self.kwargs.get('pk') |
268
|
|
|
# form.save(self.request.user, workshop_id) |
269
|
|
|
# return super(WorkshopFeedbackView, self).form_valid(form) |
270
|
|
|
|
271
|
|
|
# def get_context_data(self, *args, **kwargs): |
272
|
|
|
# context = super(WorkshopFeedbackView, self).get_context_data( |
273
|
|
|
# *args, **kwargs) |
274
|
|
|
# context['workshop'] = Workshop.objects.get(pk=self.kwargs.get('pk')) |
275
|
|
|
# return context |
276
|
|
|
|
277
|
|
|
|
278
|
|
|
@login_required |
279
|
|
|
def workshop_feedback_view(request, pk): |
280
|
|
|
context_dict = {} |
281
|
|
|
template_name = "workshops/workshop_feedback.html" |
282
|
|
|
context_dict['workshop'] = Workshop.objects.get(pk=pk) |
283
|
|
|
if request.method == 'POST': |
284
|
|
|
form = WorkshopFeedbackForm( |
285
|
|
|
data=request.POST, user=request.user, id=pk) |
286
|
|
|
if form.is_valid(): |
287
|
|
|
WorkshopFeedBack.save_feedback( |
288
|
|
|
request.user, pk, **request.POST) |
289
|
|
|
success_url = reverse_lazy('workshops:workshop_list') |
290
|
|
|
return HttpResponseRedirect(success_url) |
291
|
|
|
context_dict['form'] = form |
292
|
|
|
context_dict['user'] = request.user |
293
|
|
|
return render(request, template_name, context_dict) |
294
|
|
|
else: |
295
|
|
|
context_dict['form'] = WorkshopFeedbackForm( |
296
|
|
|
user=request.user, id=pk) |
297
|
|
|
context_dict['user'] = request.user |
298
|
|
|
return render(request, template_name, context_dict) |
299
|
|
|
|
300
|
|
|
|
301
|
|
|
def upcoming_workshops(request): |
302
|
|
|
template_name = 'upcoming.html' |
303
|
|
|
workshop_list = Workshop.objects.filter(is_active=True).filter( |
304
|
|
|
status__in=[WorkshopStatus.REQUESTED, |
305
|
|
|
WorkshopStatus.ACCEPTED]).order_by('expected_date') |
306
|
|
|
context_dict = {} |
307
|
|
|
context_dict['workshop_list'] = workshop_list |
308
|
|
|
|
309
|
|
|
return render(request, template_name, context_dict) |
310
|
|
|
|
311
|
|
|
|
312
|
|
|
@csrf_exempt |
313
|
|
|
@login_required |
314
|
|
|
def workshop_update_volunteer(request, pk): |
315
|
|
|
if request.GET: |
316
|
|
|
return JsonResponse({"items": range(1, 6)}) |
317
|
|
|
|
318
|
|
|
if request.POST: |
319
|
|
|
volunteers = request.POST.get('number_of_volunteers') |
320
|
|
|
tutor_reimbursement_flag = request.POST.get('tutor_reimbursement_flag') |
321
|
|
|
comments = request.POST.get('comments') |
322
|
|
|
if volunteers.strip() not in ('', None): |
323
|
|
|
workshop_volunteer = Workshop.objects.filter(pk=pk) |
324
|
|
|
workshop_volunteer.update(number_of_volunteers=volunteers) |
325
|
|
|
if tutor_reimbursement_flag: |
326
|
|
|
workshop_volunteer.update( |
327
|
|
|
tutor_reimbursement_flag=tutor_reimbursement_flag) |
328
|
|
|
if comments: |
329
|
|
|
workshop_volunteer.update(comments=comments) |
330
|
|
|
return JsonResponse({ |
331
|
|
|
"status": True, |
332
|
|
|
"msg": "Updated successfully"}) |
333
|
|
|
return JsonResponse({"status": False, "msg": "Somthing went wrong"}) |
334
|
|
|
|
335
|
|
|
|
336
|
|
|
@csrf_exempt |
337
|
|
|
@login_required |
338
|
|
|
def workshop_accept_as_volunteer(request, pk): |
339
|
|
|
if request.method == 'POST': |
340
|
|
|
workshop = Workshop.objects.get(pk=pk) |
341
|
|
|
user = request.user |
342
|
|
|
|
343
|
|
|
if workshop.number_of_volunteers == 0: |
344
|
|
|
return JsonResponse({ |
345
|
|
|
"status": False, |
346
|
|
|
"msg": "Volunteer not request for this workshop."}) |
347
|
|
|
elif workshop.number_of_volunteers - workshop.volunteer.count() >= 1: |
348
|
|
|
# Check if already registered |
349
|
|
|
if user in workshop.volunteer.all(): |
350
|
|
|
return JsonResponse({ |
351
|
|
|
"status": False, |
352
|
|
|
"msg": "You are already registered as volunteer."}) |
353
|
|
|
else: |
354
|
|
|
workshop.volunteer.add(user) |
355
|
|
|
return JsonResponse({ |
356
|
|
|
"status": True, |
357
|
|
|
"msg": "Registered successfully."}) |
358
|
|
|
else: |
359
|
|
|
return JsonResponse({ |
360
|
|
|
"status": False, |
361
|
|
|
"msg": "Unable to register you, as requirement already fulfilled"}) |
362
|
|
|
return JsonResponse({"status": False, "msg": "Something went wrong"}) |
363
|
|
|
|
364
|
|
|
|
365
|
|
|
@csrf_exempt |
366
|
|
|
@login_required |
367
|
|
|
def workshop_opt_out_as_volunteer(request, pk): |
368
|
|
|
if request.method == 'POST': |
369
|
|
|
workshop = Workshop.objects.get(pk=pk) |
370
|
|
|
user = request.user |
371
|
|
|
|
372
|
|
|
if user in workshop.volunteer.all(): |
373
|
|
|
# remove volunteer |
374
|
|
|
workshop.volunteer.remove(user) |
375
|
|
|
|
376
|
|
|
workshop.save() |
377
|
|
|
return JsonResponse({ |
378
|
|
|
"status": True, |
379
|
|
|
"msg": "Opt-out successfully."}) |
380
|
|
|
else: |
381
|
|
|
return JsonResponse({ |
382
|
|
|
"status": False, |
383
|
|
|
"msg": "You are not registered as volunteer."}) |
384
|
|
|
return JsonResponse({"status": False, "msg": "Something went wrong"}) |
385
|
|
|
|