[#3195] Réparé la génération des choix de fuseaux horaires
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / chercheurs / views.py
1 # -*- encoding: utf-8 -*-
2 import re
3
4 from auf.django.references.models import Etablissement
5 from django.conf import settings
6 from django.contrib.auth import REDIRECT_FIELD_NAME
7 from django.contrib.auth import login as auth_login
8 from django.contrib.auth import authenticate
9 from django.contrib.auth.decorators import login_required
10 from django.contrib.auth.forms import PasswordChangeForm
11 from django.contrib.sites.models import RequestSite, Site
12 from django.core.urlresolvers import reverse as url
13 from django.core.mail import send_mail
14 from django.http import HttpResponse, Http404
15 from django.shortcuts import render, get_object_or_404, redirect
16 from django.template import Context
17 from django.template.loader import get_template
18 from django.utils import simplejson
19 from django.utils.http import int_to_base36, base36_to_int
20 from django.views.decorators.cache import never_cache
21 from django.views.decorators.csrf import csrf_protect
22
23 from chercheurs.decorators import chercheur_required
24 from chercheurs.forms import \
25 ChercheurSearchForm, SetPasswordForm, ChercheurFormGroup, \
26 AuthenticationForm, GroupeSearchForm, MessageForm
27 from chercheurs.models import \
28 Chercheur, Groupe, Message, AdhesionGroupe, AuthLDAP
29 from chercheurs.utils import \
30 get_django_user_for_email, create_ldap_hash, check_ldap_hash
31 from savoirs.models import PageStatique
32
33
34 def index(request):
35 """
36 Répertoire des chercheurs
37 """
38 search_form = ChercheurSearchForm(request.GET)
39 if search_form.is_valid():
40 search = search_form.save(commit=False)
41 else:
42 raise Http404
43 chercheurs = search.run().select_related('etablissement')
44 sort = request.GET.get('tri')
45 if sort is not None and sort.endswith('_desc'):
46 sort = sort[:-5]
47 direction = '-'
48 else:
49 direction = ''
50 if sort == 'nom':
51 chercheurs = chercheurs.order_by_nom(direction)
52 elif sort == 'etablissement':
53 chercheurs = chercheurs.order_by_etablissement(direction)
54 elif sort == 'pays':
55 chercheurs = chercheurs.order_by_pays(direction)
56 else:
57 chercheurs = chercheurs.order_by('-date_modification')
58
59 try:
60 p = PageStatique.objects.get(id='repertoire')
61 entete = p.contenu
62 except PageStatique.DoesNotExist:
63 entete = u'<h1>Répertoire des chercheurs</h1>'
64
65 nb_chercheurs = chercheurs.count()
66
67 return render(request, "chercheurs/index.html", {
68 'chercheurs': chercheurs,
69 'nb_chercheurs': nb_chercheurs,
70 'search_form': search_form,
71 'entete': entete
72 })
73
74
75 def inscription(request):
76 if request.method == 'POST':
77 forms = ChercheurFormGroup(request.POST)
78 if forms.is_valid():
79 chercheur = forms.save()
80 id_base36 = int_to_base36(chercheur.id)
81 token = chercheur.activation_token()
82 template = get_template('chercheurs/activation_email.txt')
83 domain = RequestSite(request).domain
84 message = template.render(Context({
85 'chercheur': chercheur,
86 'id_base36': id_base36,
87 'token': token,
88 'domain': domain
89 }))
90 send_mail(
91 'Votre inscription à Savoirs en partage',
92 message, None, [chercheur.courriel]
93 )
94 return redirect('chercheurs-inscription-faite')
95 else:
96 forms = ChercheurFormGroup()
97
98 return render(request, "chercheurs/inscription.html", {
99 'forms': forms
100 })
101
102
103 def activation(request, id_base36, token):
104 """Activation d'un chercheur"""
105 id = base36_to_int(id_base36)
106 chercheur = get_object_or_404(Chercheur.all_objects, id=id)
107 if token == chercheur.activation_token():
108 validlink = True
109 if request.method == 'POST':
110 form = SetPasswordForm(request.POST)
111 if form.is_valid():
112 password = form.cleaned_data['password']
113 email = chercheur.courriel
114 chercheur.actif = True
115 user = get_django_user_for_email(email)
116 user.set_password(password)
117 user.save()
118 chercheur.user = user
119 chercheur.save()
120
121 # Auto-login
122 auth_login(
123 request, authenticate(username=email, password=password)
124 )
125 return redirect('chercheurs.views.perso')
126 else:
127 form = SetPasswordForm()
128 else:
129 form = None
130 validlink = False
131 return render(request, 'chercheurs/activation.html', {
132 'form': form,
133 'validlink': validlink
134 })
135
136
137 @csrf_protect
138 @login_required
139 def password_change(request,
140 template_name='registration/password_change_form.html',
141 post_change_redirect=None,
142 password_change_form=PasswordChangeForm):
143 if post_change_redirect is None:
144 post_change_redirect = url(
145 'django.contrib.auth.views.password_change_done'
146 )
147 if request.method == "POST":
148 form = password_change_form(user=request.user, data=request.POST)
149 if form.is_valid():
150 form.save()
151
152 # Mot de passe pour LDAP
153 username = request.user.email
154 authldap, created = \
155 AuthLDAP.objects.get_or_create(username=username)
156 password = form.cleaned_data.get('new_password1')
157 authldap.ldap_hash = create_ldap_hash(password)
158 authldap.save()
159
160 return redirect(post_change_redirect)
161 else:
162 form = password_change_form(user=request.user)
163 return render(request, template_name, {'form': form})
164
165
166 @chercheur_required
167 def desinscription(request):
168 """Désinscription du chercheur"""
169 chercheur = request.chercheur
170 if request.method == 'POST':
171 if request.POST.get('confirmer'):
172 chercheur.actif = False
173 chercheur.save()
174 request.flash['message'] = \
175 "Vous avez été désinscrit du répertoire des chercheurs."
176 return redirect('django.contrib.auth.views.logout')
177 else:
178 request.flash['message'] = "Opération annulée."
179 return redirect('chercheurs.views.perso')
180 return render(request, "chercheurs/desinscription.html")
181
182
183 @chercheur_required
184 @never_cache
185 def edit(request):
186 """Edition d'un chercheur"""
187 chercheur = request.chercheur
188 if request.method == 'POST':
189 forms = ChercheurFormGroup(request.POST, chercheur=chercheur)
190 if forms.is_valid():
191 forms.save()
192 request.flash['message'] = "Votre fiche a bien été enregistrée."
193 return redirect('chercheurs.views.perso')
194 else:
195 forms = ChercheurFormGroup(chercheur=chercheur)
196
197 return render(request, "chercheurs/edit.html", {
198 'forms': forms,
199 'chercheur': chercheur
200 })
201
202
203 @chercheur_required
204 def perso(request):
205 """Espace chercheur (espace personnel du chercheur)"""
206 chercheur = request.chercheur
207 modification = request.GET.get('modification')
208 return render(request, "chercheurs/perso.html", {
209 'chercheur': chercheur,
210 'modification': modification
211 })
212
213
214 def retrieve(request, id):
215 """Fiche du chercheur"""
216 chercheur = get_object_or_404(Chercheur, id=id)
217 return render(request, "chercheurs/retrieve.html", {
218 'chercheur': chercheur
219 })
220
221
222 def conversion(request):
223 return render(request, "chercheurs/conversion.html")
224
225
226 def etablissements_autocomplete(request, pays=None):
227 term = request.GET.get('term')
228 noms = Etablissement.objects.all().filter(membre=True, actif=True)
229 for word in term.split():
230 noms = noms.filter(nom__icontains=word)
231 if pays:
232 noms = noms.filter(pays=pays)
233 noms = list(noms.values_list('nom', flat=True)[:20])
234 json = simplejson.dumps(noms)
235 return HttpResponse(json, mimetype='application/json')
236
237
238 def login(request, template_name='registration/login.html',
239 redirect_field_name=REDIRECT_FIELD_NAME):
240 "The Django login view, but using a custom form."
241 redirect_to = request.REQUEST.get(redirect_field_name, '')
242
243 if request.method == "POST":
244 form = AuthenticationForm(data=request.POST)
245 if form.is_valid():
246 # Light security check -- make sure redirect_to isn't garbage.
247 if not redirect_to or ' ' in redirect_to:
248 redirect_to = settings.LOGIN_REDIRECT_URL
249
250 # Heavier security check -- redirects to http://example.com
251 # should not be allowed, but things like
252 # /view/?param=http://example.com should be allowed. This regex
253 # checks if there is a '//' *before* a question mark.
254 elif '//' in redirect_to and re.match(r'[^\?]*//', redirect_to):
255 redirect_to = settings.LOGIN_REDIRECT_URL
256
257 # Mot de passe pour LDAP
258 username = form.cleaned_data.get('username')
259 password = form.cleaned_data.get('password')
260 authldap, created = \
261 AuthLDAP.objects.get_or_create(username=username)
262 if created or not check_ldap_hash(authldap.ldap_hash, password):
263 authldap.ldap_hash = create_ldap_hash(password)
264 authldap.save()
265
266 # Okay, security checks complete. Log the user in.
267 auth_login(request, form.get_user())
268
269 if request.session.test_cookie_worked():
270 request.session.delete_test_cookie()
271
272 return redirect(redirect_to)
273
274 else:
275 form = AuthenticationForm(request)
276 request.session.set_test_cookie()
277
278 if Site._meta.installed:
279 current_site = Site.objects.get_current()
280 else:
281 current_site = RequestSite(request)
282
283 return render(request, template_name, {
284 'form': form,
285 redirect_field_name: redirect_to,
286 'site': current_site,
287 'site_name': current_site.name,
288 })
289 login = never_cache(login)
290
291
292 # groupes
293 def groupe_index(request):
294 search_form = GroupeSearchForm(request.GET)
295 search = search_form.save(commit=False)
296 groupes = search.run()
297 nb_resultats = groupes.count()
298 try:
299 p = PageStatique.objects.get(id='groupes')
300 entete = p.contenu
301 except PageStatique.DoesNotExist:
302 entete = '<h1>Liste des groupes</h1>'
303
304 est_chercheur, mesgroupes, messages = False, None, None
305 if request.user.is_authenticated():
306 try:
307 chercheur = Chercheur.objects.get(courriel=request.user.email)
308 mesgroupes = chercheur.groupes.filter(
309 membership__statut='accepte', groupe_chercheur=True
310 )
311 messages = Message.objects.all().filter(groupe__in=mesgroupes)[:10]
312 est_chercheur = True
313 except Chercheur.DoesNotExist:
314 pass
315
316 return render(request, "chercheurs/groupe_index.html", {
317 'search_form': search_form,
318 'groupes': groupes.order_by('nom'),
319 'nb_resultats': nb_resultats,
320 'entete': entete,
321 'mesgroupes': mesgroupes,
322 'messages': messages,
323 'est_chercheur': est_chercheur,
324 })
325
326
327 def groupe_adhesion(request, id):
328 try:
329 groupe = get_object_or_404(Groupe, id=id)
330 chercheur = Chercheur.objects.get(courriel=request.user.email)
331 adhesion, created = AdhesionGroupe.objects.get_or_create(
332 chercheur=chercheur, groupe=groupe
333 )
334 if created:
335 adhesion.actif = 0
336 adhesion.save()
337 except:
338 pass
339
340 return redirect('groupe_retrieve', id=id)
341
342
343 def groupe_retrieve(request, id):
344 groupe = get_object_or_404(Groupe, id=id)
345 membres = groupe.membership.all() \
346 .filter(statut='accepte').order_by('-date_modification')
347 plus_que_20 = True if membres.count() > 20 else False
348 membres_20 = membres[:20]
349 messages = groupe.message_set.all()[:5]
350
351 est_chercheur, est_membre, est_membre_actif = False, False, False
352 if request.user.is_authenticated():
353 try:
354 chercheur = Chercheur.objects.get(courriel=request.user.email)
355 est_chercheur = True
356 est_membre = chercheur in groupe.membres.all()
357 est_membre_actif = bool(len(groupe.membership.filter(
358 chercheur=chercheur, statut='accepte'
359 )))
360 except Chercheur.DoesNotExist:
361 pass
362
363 return render(request, "chercheurs/groupe_retrieve.html", {
364 'groupe': groupe,
365 'membres': membres_20,
366 'plus_que_20': plus_que_20,
367 'messages': messages,
368 'est_chercheur': est_chercheur,
369 'est_membre': est_membre,
370 'est_membre_actif': est_membre_actif,
371 })
372
373
374 def groupe_membres(request, id):
375 groupe = get_object_or_404(Groupe, id=id)
376 membres = groupe.membership.all() \
377 .filter(statut='accepte').order_by('chercheur__nom')
378
379 return render(request, "chercheurs/groupe_membres.html", {
380 'groupe': groupe,
381 'membres': membres,
382 })
383
384
385 def groupe_messages(request, id):
386 groupe = get_object_or_404(Groupe, id=id)
387
388 est_chercheur, est_membre, est_membre_actif = False, False, False
389 if request.user.is_authenticated():
390 try:
391 chercheur = Chercheur.objects.get(courriel=request.user.email)
392 est_chercheur = True
393 est_membre = chercheur in groupe.membres.all()
394 est_membre_actif = bool(len(groupe.membership.filter(
395 chercheur=chercheur, statut='accepte'
396 )))
397 except Chercheur.DoesNotExist:
398 pass
399
400 if est_membre_actif and request.method == 'POST':
401 form = MessageForm(request.POST)
402 if form.is_valid():
403 message = form.save(commit=False)
404 message.groupe = groupe
405 message.chercheur = chercheur
406 message.save()
407
408 form = MessageForm()
409
410 else:
411 form = MessageForm()
412
413 messages = groupe.message_set.all()
414
415 return render(request, "chercheurs/groupe_message.html", {
416 'groupe': groupe,
417 'messages': messages,
418 'form': form,
419 'est_chercheur': est_chercheur,
420 'est_membre': est_membre,
421 'est_membre_actif': est_membre_actif,
422 })