[#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
CommitLineData
588d6b93 1# -*- encoding: utf-8 -*-
ae075d2c
PP
2import re
3
ff753fa4 4from auf.django.references.models import Etablissement
fa6a2a07 5from django.conf import settings
fa6a2a07
EMS
6from django.contrib.auth import REDIRECT_FIELD_NAME
7from django.contrib.auth import login as auth_login
ff753fa4 8from django.contrib.auth import authenticate
fdcf5874 9from django.contrib.auth.decorators import login_required
ff753fa4 10from django.contrib.auth.forms import PasswordChangeForm
fa6a2a07 11from django.contrib.sites.models import RequestSite, Site
ff753fa4
EMS
12from django.core.urlresolvers import reverse as url
13from django.core.mail import send_mail
2aa2a26c 14from django.http import HttpResponse, Http404
ff753fa4
EMS
15from django.shortcuts import render, get_object_or_404, redirect
16from django.template import Context
17from django.template.loader import get_template
219710da 18from django.utils import simplejson
43ed73e7 19from django.utils.http import int_to_base36, base36_to_int
a7b16ec9 20from django.views.decorators.cache import never_cache
b0609188 21from django.views.decorators.csrf import csrf_protect
ff753fa4
EMS
22
23from chercheurs.decorators import chercheur_required
24from chercheurs.forms import \
25 ChercheurSearchForm, SetPasswordForm, ChercheurFormGroup, \
26 AuthenticationForm, GroupeSearchForm, MessageForm
27from chercheurs.models import \
28 Chercheur, Groupe, Message, AdhesionGroupe, AuthLDAP
29from chercheurs.utils import \
30 get_django_user_for_email, create_ldap_hash, check_ldap_hash
31from savoirs.models import PageStatique
510b5321 32
9aa1d783 33
f0692c02 34def index(request):
ff753fa4
EMS
35 """
36 Répertoire des chercheurs
37 """
fdcf5874 38 search_form = ChercheurSearchForm(request.GET)
2aa2a26c
EMS
39 if search_form.is_valid():
40 search = search_form.save(commit=False)
41 else:
42 raise Http404
fdcf5874 43 chercheurs = search.run().select_related('etablissement')
7020ea3d
EMS
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':
acd5cd8f 51 chercheurs = chercheurs.order_by_nom(direction)
7020ea3d 52 elif sort == 'etablissement':
acd5cd8f 53 chercheurs = chercheurs.order_by_etablissement(direction)
7020ea3d 54 elif sort == 'pays':
acd5cd8f 55 chercheurs = chercheurs.order_by_pays(direction)
7020ea3d
EMS
56 else:
57 chercheurs = chercheurs.order_by('-date_modification')
ff753fa4 58
f09bc1c6
EMS
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>'
7020ea3d 64
9f7c169e 65 nb_chercheurs = chercheurs.count()
fdcf5874 66
ff753fa4
EMS
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
588d6b93 74
f0692c02 75def inscription(request):
932eef9a 76 if request.method == 'POST':
a7b16ec9
EMS
77 forms = ChercheurFormGroup(request.POST)
78 if forms.is_valid():
43ed73e7
EMS
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
ff753fa4
EMS
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')
932eef9a 95 else:
a7b16ec9 96 forms = ChercheurFormGroup()
ff753fa4
EMS
97
98 return render(request, "chercheurs/inscription.html", {
99 'forms': forms
100 })
101
9af73c99 102
43ed73e7
EMS
103def activation(request, id_base36, token):
104 """Activation d'un chercheur"""
105 id = base36_to_int(id_base36)
3e556e66 106 chercheur = get_object_or_404(Chercheur.all_objects, id=id)
43ed73e7
EMS
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
695930dd
EMS
115 user = get_django_user_for_email(email)
116 user.set_password(password)
117 user.save()
b9b3e6ba
PP
118 chercheur.user = user
119 chercheur.save()
43ed73e7
EMS
120
121 # Auto-login
ff753fa4
EMS
122 auth_login(
123 request, authenticate(username=email, password=password)
124 )
125 return redirect('chercheurs.views.perso')
43ed73e7
EMS
126 else:
127 form = SetPasswordForm()
128 else:
129 form = None
130 validlink = False
ff753fa4
EMS
131 return render(request, 'chercheurs/activation.html', {
132 'form': form,
133 'validlink': validlink
134 })
135
43ed73e7 136
b0609188
PP
137@csrf_protect
138@login_required
ff753fa4
EMS
139def password_change(request,
140 template_name='registration/password_change_form.html',
141 post_change_redirect=None,
142 password_change_form=PasswordChangeForm):
b0609188 143 if post_change_redirect is None:
ff753fa4
EMS
144 post_change_redirect = url(
145 'django.contrib.auth.views.password_change_done'
146 )
b0609188
PP
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
ff753fa4
EMS
154 authldap, created = \
155 AuthLDAP.objects.get_or_create(username=username)
b0609188 156 password = form.cleaned_data.get('new_password1')
ae075d2c 157 authldap.ldap_hash = create_ldap_hash(password)
b0609188
PP
158 authldap.save()
159
ff753fa4 160 return redirect(post_change_redirect)
b0609188
PP
161 else:
162 form = password_change_form(user=request.user)
ff753fa4 163 return render(request, template_name, {'form': form})
b0609188
PP
164
165
518d0b44 166@chercheur_required
8baa2a56
EMS
167def desinscription(request):
168 """Désinscription du chercheur"""
518d0b44 169 chercheur = request.chercheur
8baa2a56
EMS
170 if request.method == 'POST':
171 if request.POST.get('confirmer'):
13ec4813
EMS
172 chercheur.actif = False
173 chercheur.save()
ff753fa4
EMS
174 request.flash['message'] = \
175 "Vous avez été désinscrit du répertoire des chercheurs."
176 return redirect('django.contrib.auth.views.logout')
8baa2a56
EMS
177 else:
178 request.flash['message'] = "Opération annulée."
ff753fa4
EMS
179 return redirect('chercheurs.views.perso')
180 return render(request, "chercheurs/desinscription.html")
181
8baa2a56 182
518d0b44 183@chercheur_required
a7b16ec9 184@never_cache
f0692c02 185def edit(request):
b3e1079e 186 """Edition d'un chercheur"""
518d0b44 187 chercheur = request.chercheur
b3e1079e 188 if request.method == 'POST':
a7b16ec9
EMS
189 forms = ChercheurFormGroup(request.POST, chercheur=chercheur)
190 if forms.is_valid():
191 forms.save()
91112855 192 request.flash['message'] = "Votre fiche a bien été enregistrée."
ff753fa4 193 return redirect('chercheurs.views.perso')
b3e1079e 194 else:
a7b16ec9 195 forms = ChercheurFormGroup(chercheur=chercheur)
ff753fa4
EMS
196
197 return render(request, "chercheurs/edit.html", {
198 'forms': forms,
199 'chercheur': chercheur
200 })
201
202
518d0b44 203@chercheur_required
f0692c02 204def perso(request):
0d9d1c4d 205 """Espace chercheur (espace personnel du chercheur)"""
518d0b44 206 chercheur = request.chercheur
2a36714f 207 modification = request.GET.get('modification')
ff753fa4
EMS
208 return render(request, "chercheurs/perso.html", {
209 'chercheur': chercheur,
210 'modification': modification
211 })
212
213
f0692c02 214def retrieve(request, id):
da091176 215 """Fiche du chercheur"""
3eb00212 216 chercheur = get_object_or_404(Chercheur, id=id)
ff753fa4
EMS
217 return render(request, "chercheurs/retrieve.html", {
218 'chercheur': chercheur
219 })
220
221
f0692c02 222def conversion(request):
ff753fa4
EMS
223 return render(request, "chercheurs/conversion.html")
224
8baa2a56 225
e836f6f7 226def etablissements_autocomplete(request, pays=None):
219710da 227 term = request.GET.get('term')
e76f8899 228 noms = Etablissement.objects.all().filter(membre=True, actif=True)
e836f6f7
EMS
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])
219710da
EMS
234 json = simplejson.dumps(noms)
235 return HttpResponse(json, mimetype='application/json')
fa6a2a07 236
ff753fa4
EMS
237
238def login(request, template_name='registration/login.html',
239 redirect_field_name=REDIRECT_FIELD_NAME):
fa6a2a07
EMS
240 "The Django login view, but using a custom form."
241 redirect_to = request.REQUEST.get(redirect_field_name, '')
ff753fa4 242
fa6a2a07
EMS
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
ff753fa4
EMS
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.
fa6a2a07
EMS
254 elif '//' in redirect_to and re.match(r'[^\?]*//', redirect_to):
255 redirect_to = settings.LOGIN_REDIRECT_URL
ff753fa4 256
544dec4f
PP
257 # Mot de passe pour LDAP
258 username = form.cleaned_data.get('username')
ae075d2c 259 password = form.cleaned_data.get('password')
ff753fa4
EMS
260 authldap, created = \
261 AuthLDAP.objects.get_or_create(username=username)
ae075d2c
PP
262 if created or not check_ldap_hash(authldap.ldap_hash, password):
263 authldap.ldap_hash = create_ldap_hash(password)
544dec4f
PP
264 authldap.save()
265
fa6a2a07
EMS
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
ff753fa4 272 return redirect(redirect_to)
fa6a2a07
EMS
273
274 else:
275 form = AuthenticationForm(request)
276 request.session.set_test_cookie()
ff753fa4 277
fa6a2a07
EMS
278 if Site._meta.installed:
279 current_site = Site.objects.get_current()
280 else:
281 current_site = RequestSite(request)
ff753fa4
EMS
282
283 return render(request, template_name, {
fa6a2a07
EMS
284 'form': form,
285 redirect_field_name: redirect_to,
286 'site': current_site,
287 'site_name': current_site.name,
ff753fa4 288 })
fa6a2a07 289login = never_cache(login)
cdaadee3 290
ff753fa4 291
cdaadee3
PP
292# groupes
293def 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:
381cc09a
PP
302 entete = '<h1>Liste des groupes</h1>'
303
96316da7 304 est_chercheur, mesgroupes, messages = False, None, None
381cc09a 305 if request.user.is_authenticated():
6115dba0
PP
306 try:
307 chercheur = Chercheur.objects.get(courriel=request.user.email)
ff753fa4
EMS
308 mesgroupes = chercheur.groupes.filter(
309 membership__statut='accepte', groupe_chercheur=True
310 )
96316da7
PP
311 messages = Message.objects.all().filter(groupe__in=mesgroupes)[:10]
312 est_chercheur = True
6115dba0 313 except Chercheur.DoesNotExist:
96316da7
PP
314 pass
315
ff753fa4 316 return render(request, "chercheurs/groupe_index.html", {
96316da7
PP
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,
ff753fa4
EMS
324 })
325
cdaadee3 326
0eb2476e
PP
327def groupe_adhesion(request, id):
328 try:
329 groupe = get_object_or_404(Groupe, id=id)
330 chercheur = Chercheur.objects.get(courriel=request.user.email)
ff753fa4
EMS
331 adhesion, created = AdhesionGroupe.objects.get_or_create(
332 chercheur=chercheur, groupe=groupe
333 )
0eb2476e 334 if created:
18407f73
PP
335 adhesion.actif = 0
336 adhesion.save()
0eb2476e
PP
337 except:
338 pass
339
ff753fa4
EMS
340 return redirect('groupe_retrieve', id=id)
341
0eb2476e 342
cdaadee3
PP
343def groupe_retrieve(request, id):
344 groupe = get_object_or_404(Groupe, id=id)
ff753fa4
EMS
345 membres = groupe.membership.all() \
346 .filter(statut='accepte').order_by('-date_modification')
ddf7e62e
PP
347 plus_que_20 = True if membres.count() > 20 else False
348 membres_20 = membres[:20]
fd6352ea 349 messages = groupe.message_set.all()[:5]
0c0d997c 350
0eb2476e
PP
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()
ff753fa4
EMS
357 est_membre_actif = bool(len(groupe.membership.filter(
358 chercheur=chercheur, statut='accepte'
359 )))
0eb2476e
PP
360 except Chercheur.DoesNotExist:
361 pass
362
ff753fa4
EMS
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
c8d6b979 373
ddf7e62e
PP
374def groupe_membres(request, id):
375 groupe = get_object_or_404(Groupe, id=id)
ff753fa4
EMS
376 membres = groupe.membership.all() \
377 .filter(statut='accepte').order_by('chercheur__nom')
ddf7e62e 378
ff753fa4
EMS
379 return render(request, "chercheurs/groupe_membres.html", {
380 'groupe': groupe,
381 'membres': membres,
382 })
ddf7e62e 383
fd6352ea 384
ff753fa4 385def groupe_messages(request, id):
fd6352ea
PP
386 groupe = get_object_or_404(Groupe, id=id)
387
9aa1d783
PP
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()
ff753fa4
EMS
394 est_membre_actif = bool(len(groupe.membership.filter(
395 chercheur=chercheur, statut='accepte'
396 )))
9aa1d783
PP
397 except Chercheur.DoesNotExist:
398 pass
399
400 if est_membre_actif and request.method == 'POST':
fd6352ea
PP
401 form = MessageForm(request.POST)
402 if form.is_valid():
fd6352ea
PP
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
ff753fa4
EMS
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 })