import users
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / admin_views.py
1 # -*- encoding: utf-8 -*-
2 from django import forms
3 from django.db.models import get_model, Count
4 from django.http import HttpResponseRedirect
5 from django.core.urlresolvers import reverse as url
6 from django.contrib.auth.decorators import login_required, permission_required
7
8 from django.template import Context, RequestContext
9 from django.shortcuts import render_to_response
10
11 from chercheurs.models import Chercheur, Groupe
12 from datamaster_modeles.models import Thematique, Pays, Region
13 from savoirs.models import Record, Discipline, Actualite, Serveur
14 from savoirs.forms import PaysForm, RegionsForm, ThematiquesForm, DisciplinesForm, ConfirmationForm
15
16 # Dashboard
17 class RecordDashboard:
18 """Cette classe permet d'afficher une liste de tâche à faire en fonction de l'usagé"""
19 context = None
20
21 def __init__(self, context):
22 """Récupère le context"""
23 self.context = context
24
25 def get_fitre_serveurs(self,):
26 """Retourner la liste des serveurs sélectionnés.
27 S'il n'y en a pas, tous les serveurs sont retournés."""
28 try:
29 user = self.context.get('user')
30 profile = user.get_profile()
31 serveurs = profile.serveurs.all()
32 except:
33 serveurs = Serveur.objects.all()
34 return [s.nom for s in serveurs]
35
36 def total_a_faire(self,):
37 """Retourne le total des références à traiter"""
38 return len(self.tout_mes_records())
39
40 def tout_mes_records(self,):
41 """Retourne la liste des références à traiter en fonction du filtre"""
42 filtre = self.get_fitre_serveurs()
43 return [r for r in Record.all_objects.filter(server__in=filtre) if not r.est_complet()]
44
45 def mes_records(self,):
46 """Retourne la liste des références à traiter en fonction du filtre"""
47 return self.tout_mes_records()
48
49 def ref_apercu(self, record):
50 return "[%s] %s" % (record.server, record.title)
51
52 def change_url(self, object):
53 """Retourne l'url pour éditer le record"""
54 return url('admin:%s_%s_change' %(object._meta.app_label, object._meta.module_name), args=[object.id])
55
56 def a_traiter(self, ):
57 """Retourne la structure de données nécessaire pour le widget de django-admin-tool"""
58 records = self.mes_records()
59 return [{'title':self.ref_apercu(r), 'url':self.change_url(r), 'external': False} for r in records]
60
61 @login_required
62 def assigner_pays(request):
63 ids = request.GET.get("ids").split(",")
64 records = Record.all_objects.in_bulk(ids)
65 if request.method == 'POST':
66 pays_form = PaysForm(request.POST)
67
68 if pays_form.is_valid():
69
70 # charger tous les objets pays
71 pays = []
72 for pays_id in request.POST.getlist("pays"):
73 pays.append(Pays.objects.get(id=pays_id))
74
75 # assigner chaque pays à chaque référence
76 for r in records.values():
77 for p in pays:
78 r.pays.add(p)
79 r.save()
80
81 # retouner un status à l'utilisateur sur la liste des références
82 pays_noms = u", ".join([p.nom for p in pays])
83 succes = u"Les pays %s ont été assignés à %s références" % (pays_noms, len(ids))
84 request.user.message_set.create(message=succes)
85 return HttpResponseRedirect('/admin/savoirs/record')
86 else:
87 pays_form = PaysForm()
88
89 return render_to_response ("savoirs/assigner.html",
90 Context ({'records': records,
91 'form': pays_form,
92 'titre': u"Assignation de pays par lots",
93 'description': u"Sélectionner les pays qui seront associés aux références suivantes :" ,
94 }),
95 context_instance = RequestContext(request))
96
97 @login_required
98 def assigner_regions(request, app_name, model_name):
99 ids = request.GET.get("ids").split(",")
100 model = get_model(app_name, model_name)
101 objects = model.objects.filter(pk__in=ids)
102 if request.method == 'POST':
103 regions_form = RegionsForm(request.POST)
104
105 if regions_form.is_valid():
106 regions = regions_form.cleaned_data['regions']
107 for o in objects:
108 o.assigner_regions(regions)
109 o.save()
110
111 # retouner un status à l'utilisateur sur la liste des références
112 regions_noms = u", ".join([p.nom for p in regions])
113 succes = u"Les regions %s ont été assignées à %s objets" % (regions_noms, len(ids))
114 request.user.message_set.create(message=succes)
115 return HttpResponseRedirect(url('admin:%s_%s_changelist' % (app_name, model_name)))
116 else:
117 regions_form = RegionsForm()
118 return render_to_response(
119 "savoirs/assigner.html",
120 dict(objects=objects,
121 form=regions_form,
122 titre=u"Assignation de régions par lots",
123 description=u"Sélectionner les régions qui seront associées aux références suivantes :"),
124 context_instance = RequestContext(request)
125 )
126
127 @login_required
128 def assigner_disciplines(request, app_name, model_name):
129 ids = request.GET.get("ids").split(",")
130 model = get_model(app_name, model_name)
131 objects = model.objects.filter(pk__in=ids)
132 if request.method == 'POST':
133 disciplines_form = DisciplinesForm(request.POST)
134
135 if disciplines_form.is_valid():
136 disciplines = disciplines_form.cleaned_data['disciplines']
137 for o in objects:
138 o.assigner_disciplines(disciplines)
139 o.save()
140
141 # retouner un status à l'utilisateur sur la liste des références
142 disciplines_noms = u", ".join([p.nom for p in disciplines])
143 succes = u"Les disciplines %s ont été assignées à %s objets" % (disciplines_noms, len(ids))
144 request.user.message_set.create(message=succes)
145 return HttpResponseRedirect(url('admin:%s_%s_changelist' % (app_name, model_name)))
146 else:
147 disciplines_form = DisciplinesForm()
148
149 return render_to_response(
150 "savoirs/assigner.html",
151 dict(objects=objects,
152 form=disciplines_form,
153 titre=u"Assignation de disciplines par lots",
154 description=u"Sélectionner les disciplines qui seront associées aux références suivantes :"),
155 context_instance = RequestContext(request)
156 )
157
158 @login_required
159 def assigner_thematiques(request):
160 ids = request.GET.get("ids").split(",")
161 records = Record.all_objects.in_bulk(ids)
162 if request.method == 'POST':
163 thematiques_form = ThematiquesForm(request.POST)
164
165 if thematiques_form.is_valid():
166
167 # charger tous les objets thematiques
168 thematiques = []
169 for thematique_id in request.POST.getlist("thematiques"):
170 thematiques.append(Thematique.objects.get(id=thematique_id))
171
172 # assigner chaque thematiques à chaque référence
173 for r in records.values():
174 for p in thematiques:
175 r.thematiques.add(p)
176 r.save()
177
178 # retouner un status à l'utilisateur sur la liste des références
179 thematiques_noms = u", ".join([p.nom for p in thematiques])
180 succes = u"Les thématiques %s ont été assignées à %s références" % (thematiques_noms, len(ids))
181 request.user.message_set.create(message=succes)
182 return HttpResponseRedirect('/admin/savoirs/record')
183 else:
184 thematiques_form = ThematiquesForm()
185
186 return render_to_response ("savoirs/assigner.html",
187 Context ({'records': records,
188 'form': thematiques_form,
189 'titre': u"Assignation de thématiques par lots",
190 'description': u"Sélectionner les thématiques qui seront associées aux références suivantes :" ,
191 }),
192 context_instance = RequestContext(request))
193
194 @login_required
195 def confirmation(request, action):
196 ids = request.GET.get("ids").split(",")
197 type, action = action.split('/')[0:2]
198
199 # determination du contexte de validation
200 if action == u'valider':
201 objects = [r for r in Record.all_objects.in_bulk(ids).values() if r.est_complet()]
202 action = ('validated', True)
203 desc = u'validées'
204 model = u'références'
205
206 elif action == u'invalider':
207 objects = Record.all_objects.in_bulk(ids).values()
208 action = ('validated', False)
209 desc = u'invalidées'
210 model = u'références'
211
212 elif action == u'visible':
213 objects = Actualite.all_objects.in_bulk(ids).values()
214 action = ('visible', True)
215 desc = u'visibles'
216 model = u'actualités'
217
218 elif action == u'invisible':
219 objects = Actualite.all_objects.in_bulk(ids).values()
220 action = ('visible', False)
221 desc = u'invisibles'
222 model = u'actualités'
223
224 else:
225 raise Exception("action invalide %s " % action)
226
227 if request.method == 'POST':
228 confirmation_form = ConfirmationForm(request.POST)
229
230 if confirmation_form.is_valid():
231 for o in objects:
232 setattr(o, action[0], action[1])
233 o.save()
234
235 succes = u""u"Les références ont été %s" % desc
236 request.user.message_set.create(message=succes)
237 return HttpResponseRedirect('/admin/savoirs/%s' % type)
238 else:
239 confirmation_form = ConfirmationForm()
240
241
242 return render_to_response ("savoirs/confirmation.html",
243 Context ({'objects': objects,
244 'action': action,
245 'form': confirmation_form,
246 'titre': u"Validation par lots",
247 'description': u"Les %s suivantes vont être %s:" % (model, desc) ,
248 }),
249 context_instance = RequestContext(request))
250
251 # Stats
252
253 @permission_required('savoirs.statistiques')
254 def stats(request):
255
256 def mises_a_jour(qs):
257 return qs.filter(date_modification__gte='2010-11-17').count()
258
259 def par_region(qs):
260 qs = qs.extra(select={
261 'region': '''(SELECT p.region FROM ref_pays p
262 WHERE p.code = CASE WHEN chercheurs_chercheur.etablissement IS NULL
263 THEN chercheurs_chercheur.etablissement_autre_pays
264 ELSE (SELECT e.pays FROM ref_etablissement e
265 WHERE e.id = chercheurs_chercheur.etablissement) END)'''
266 })
267 return dict(qs.values_list('region').annotate(count=Count('pk')))
268
269 def par_hemisphere(qs):
270 qs = qs.extra(select={
271 'hemisphere': '''(SELECT p.nord_sud FROM ref_pays p
272 WHERE p.code = CASE WHEN chercheurs_chercheur.etablissement IS NULL
273 THEN chercheurs_chercheur.etablissement_autre_pays
274 ELSE (SELECT e.pays FROM ref_etablissement e
275 WHERE e.id = chercheurs_chercheur.etablissement) END)'''
276 })
277 return dict(qs.values_list('hemisphere').annotate(count=Count('pk')))
278
279 def par_discipline(qs):
280 return dict(qs.values_list('discipline').annotate(count=Count('pk')))
281
282 def par_domaine(qs):
283 qs = qs.extra(tables=['chercheurs_chercheurgroupe'],
284 where=['chercheurs_chercheurgroupe.chercheur = chercheurs_chercheur.personne_ptr_id'],
285 select={'groupe': 'chercheurs_chercheurgroupe.groupe'})
286 return dict(qs.values_list('groupe').annotate(count=Count('pk')))
287
288 chercheurs = Chercheur.objects
289 hommes = chercheurs.filter(genre='m')
290 femmes = chercheurs.filter(genre='f')
291 return render_to_response(
292 'savoirs/stats.html', {
293 'nb_chercheurs': chercheurs.count(),
294 'nb_hommes': hommes.count(),
295 'nb_femmes': femmes.count(),
296 'mises_a_jour': mises_a_jour(chercheurs),
297 'mises_a_jour_hommes': mises_a_jour(hommes),
298 'mises_a_jour_femmes': mises_a_jour(femmes),
299 'regions': Region.objects.order_by('nom'),
300 'chercheurs_par_region': par_region(chercheurs),
301 'hommes_par_region': par_region(hommes),
302 'femmes_par_region': par_region(femmes),
303 'hemispheres': ['Nord', 'Sud'],
304 'chercheurs_par_hemisphere': par_hemisphere(chercheurs),
305 'hommes_par_hemisphere': par_hemisphere(hommes),
306 'femmes_par_hemisphere': par_hemisphere(femmes),
307 'disciplines': Discipline.objects.order_by('nom'),
308 'chercheurs_par_discipline': par_discipline(chercheurs),
309 'hommes_par_discipline': par_discipline(hommes),
310 'femmes_par_discipline': par_discipline(femmes),
311 'domaines': Groupe.objects.order_by('nom'),
312 'chercheurs_par_domaine': par_domaine(chercheurs),
313 'hommes_par_domaine': par_domaine(hommes),
314 'femmes_par_domaine': par_domaine(femmes),
315 }, context_instance=RequestContext(request)
316 )