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