[#4773] Lien vers chercheurs et ressources similaire
[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, slug=None):
215 """Fiche du chercheur"""
216 chercheur = get_object_or_404(Chercheur, id=id)
217
218 seo_keywords = []
219 seo_keywords.append(chercheur.discipline.nom)
220 seo_keywords.extend(re.split(',\s*', chercheur.theme_recherche))
221
222 semblables_discipline = Chercheur.objects.filter(discipline=chercheur.discipline).order_by('?')[:5]
223 semblables_etablissement = Chercheur.objects.filter(etablissement=chercheur.etablissement).order_by('?')[:5]
224
225 return render(request, "chercheurs/retrieve.html", {
226 'chercheur': chercheur,
227 'canonical_url': chercheur.canonical_url,
228 'seo_keywords': seo_keywords,
229 'semblables_discipline': semblables_discipline,
230 'semblables_etablissement': semblables_etablissement,
231 })
232
233
234 def conversion(request):
235 return render(request, "chercheurs/conversion.html")
236
237
238 def etablissements_autocomplete(request, pays=None):
239 term = request.GET.get('term')
240 if term:
241 noms = Etablissement.objects.all().filter(membre=True, actif=True)
242 for word in term.split():
243 noms = noms.filter(nom__icontains=word)
244 if pays:
245 noms = noms.filter(pays=pays)
246 noms = list(noms.values_list('nom', flat=True)[:20])
247 else:
248 noms = []
249 json = simplejson.dumps(noms)
250 return HttpResponse(json, mimetype='application/json')
251
252
253 def login(request, template_name='registration/login.html',
254 redirect_field_name=REDIRECT_FIELD_NAME):
255 "The Django login view, but using a custom form."
256 redirect_to = request.REQUEST.get(redirect_field_name, '')
257
258 if request.method == "POST":
259 form = AuthenticationForm(data=request.POST)
260 if form.is_valid():
261 # Light security check -- make sure redirect_to isn't garbage.
262 if not redirect_to or ' ' in redirect_to:
263 redirect_to = settings.LOGIN_REDIRECT_URL
264
265 # Heavier security check -- redirects to http://example.com
266 # should not be allowed, but things like
267 # /view/?param=http://example.com should be allowed. This regex
268 # checks if there is a '//' *before* a question mark.
269 elif '//' in redirect_to and re.match(r'[^\?]*//', redirect_to):
270 redirect_to = settings.LOGIN_REDIRECT_URL
271
272 # Mot de passe pour LDAP
273 username = form.cleaned_data.get('username')
274 password = form.cleaned_data.get('password')
275 authldap, created = \
276 AuthLDAP.objects.get_or_create(username=username)
277 if created or not check_ldap_hash(authldap.ldap_hash, password):
278 authldap.ldap_hash = create_ldap_hash(password)
279 authldap.save()
280
281 # Okay, security checks complete. Log the user in.
282 auth_login(request, form.get_user())
283
284 if request.session.test_cookie_worked():
285 request.session.delete_test_cookie()
286
287 return redirect(redirect_to)
288
289 else:
290 form = AuthenticationForm(request)
291 request.session.set_test_cookie()
292
293 if Site._meta.installed:
294 current_site = Site.objects.get_current()
295 else:
296 current_site = RequestSite(request)
297
298 return render(request, template_name, {
299 'form': form,
300 redirect_field_name: redirect_to,
301 'site': current_site,
302 'site_name': current_site.name,
303 })
304 login = never_cache(login)
305
306
307 # groupes
308 def groupe_index(request):
309 search_form = GroupeSearchForm(request.GET)
310 search = search_form.save(commit=False)
311 groupes = search.run()
312 nb_resultats = groupes.count()
313 try:
314 p = PageStatique.objects.get(id='groupes')
315 entete = p.contenu
316 except PageStatique.DoesNotExist:
317 entete = '<h1>Liste des groupes</h1>'
318
319 est_chercheur, mesgroupes, messages = False, None, None
320 if request.user.is_authenticated():
321 try:
322 chercheur = Chercheur.objects.get(courriel=request.user.email)
323 mesgroupes = chercheur.groupes.filter(
324 membership__statut='accepte', groupe_chercheur=True
325 )
326 messages = Message.objects.all().filter(groupe__in=mesgroupes)[:10]
327 est_chercheur = True
328 except Chercheur.DoesNotExist:
329 pass
330
331 return render(request, "chercheurs/groupe_index.html", {
332 'search_form': search_form,
333 'groupes': groupes.order_by('nom'),
334 'nb_resultats': nb_resultats,
335 'entete': entete,
336 'mesgroupes': mesgroupes,
337 'messages': messages,
338 'est_chercheur': est_chercheur,
339 })
340
341
342 def groupe_adhesion(request, id):
343 try:
344 groupe = get_object_or_404(Groupe, id=id)
345 chercheur = Chercheur.objects.get(courriel=request.user.email)
346 adhesion, created = AdhesionGroupe.objects.get_or_create(
347 chercheur=chercheur, groupe=groupe
348 )
349 if created:
350 adhesion.actif = 0
351 adhesion.save()
352 except:
353 pass
354
355 return redirect('groupe_retrieve', id=id)
356
357
358 def groupe_retrieve(request, id):
359 groupe = get_object_or_404(Groupe, id=id)
360 membres = groupe.membership.all() \
361 .filter(statut='accepte').order_by('-date_modification')
362 plus_que_20 = True if membres.count() > 20 else False
363 membres_20 = membres[:20]
364 messages = groupe.message_set.all()[:5]
365
366 est_chercheur, est_membre, est_membre_actif = False, False, False
367 if request.user.is_authenticated():
368 try:
369 chercheur = Chercheur.objects.get(courriel=request.user.email)
370 est_chercheur = True
371 est_membre = chercheur in groupe.membres.all()
372 est_membre_actif = bool(len(groupe.membership.filter(
373 chercheur=chercheur, statut='accepte'
374 )))
375 except Chercheur.DoesNotExist:
376 pass
377
378 return render(request, "chercheurs/groupe_retrieve.html", {
379 'groupe': groupe,
380 'membres': membres_20,
381 'plus_que_20': plus_que_20,
382 'messages': messages,
383 'est_chercheur': est_chercheur,
384 'est_membre': est_membre,
385 'est_membre_actif': est_membre_actif,
386 })
387
388
389 def groupe_membres(request, id):
390 groupe = get_object_or_404(Groupe, id=id)
391 membres = groupe.membership.all() \
392 .filter(statut='accepte').order_by('chercheur__nom')
393
394 return render(request, "chercheurs/groupe_membres.html", {
395 'groupe': groupe,
396 'membres': membres,
397 })
398
399
400 def groupe_messages(request, id):
401 groupe = get_object_or_404(Groupe, id=id)
402
403 est_chercheur, est_membre, est_membre_actif = False, False, False
404 if request.user.is_authenticated():
405 try:
406 chercheur = Chercheur.objects.get(courriel=request.user.email)
407 est_chercheur = True
408 est_membre = chercheur in groupe.membres.all()
409 est_membre_actif = bool(len(groupe.membership.filter(
410 chercheur=chercheur, statut='accepte'
411 )))
412 except Chercheur.DoesNotExist:
413 pass
414
415 if est_membre_actif and request.method == 'POST':
416 form = MessageForm(request.POST)
417 if form.is_valid():
418 message = form.save(commit=False)
419 message.groupe = groupe
420 message.chercheur = chercheur
421 message.save()
422
423 form = MessageForm()
424
425 else:
426 form = MessageForm()
427
428 messages = groupe.message_set.all()
429
430 return render(request, "chercheurs/groupe_message.html", {
431 'groupe': groupe,
432 'messages': messages,
433 'form': form,
434 'est_chercheur': est_chercheur,
435 'est_membre': est_membre,
436 'est_membre_actif': est_membre_actif,
437 })