4fb8a2ab646b9bd2e85f102b4c7c7b8de9f59d22
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / admin.py
1 # -*- encoding: utf-8 -*-
2 import operator
3
4 from auf.django.references import models as ref
5 from django import forms
6 from django.core.urlresolvers import reverse as url
7 from django.contrib import admin
8 from django.contrib.auth.admin import UserAdmin
9 from django.contrib.auth.models import User
10 from django.db.models import Q
11 from django.db.models.query import QuerySet
12 from django.http import HttpResponseRedirect
13
14 from auf_savoirs_en_partage.savoirs.globals import META
15 from auf_savoirs_en_partage.savoirs.models import \
16 SourceActualite, Actualite, ActualiteVoir, \
17 Evenement, EvenementVoir, Record, RecordEdit, \
18 RecordCategorie, ListSet, HarvestLog, Profile, PageStatique
19
20
21 class ListSetListFilter(admin.RelatedFieldListFilter):
22 """
23 Filtre custom automatiquement lié à un field nommé 'listsets'. Il a pour
24 but de s'afficher lorsqu'un server a déjà été présélectionné. Dans ce
25 cas, il affiche une liste qui contient les listsets de ce server.
26 """
27 def __init__(self, field, request, params, model, model_admin, field_path):
28 super(ListSetListFilter, self).__init__(
29 field, request, params, model, model_admin, field_path
30 )
31 self.server_name = request.GET.get('server', None)
32
33 def has_output(self):
34 return self.server_name is not None
35
36
37 class AllRegionsListFilter(admin.SimpleListFilter):
38 """
39 Filtre qui offre aussi les régions inactives dans ses choix.
40 """
41 title = u'région'
42 parameter_name = 'regions'
43
44 def lookups(self, request, model_admin):
45 return [(r.id, r.nom) for r in ref.Region.avec_inactifs.all()]
46
47 def queryset(self, request, queryset):
48 return queryset.filter(regions=self.value())
49
50
51 class RecordAdminQuerySet(QuerySet):
52
53 def filter(self, *args, **kwargs):
54 """Gère des filtres supplémentaires pour l'admin.
55
56 C'est la seule façon que j'ai trouvée de contourner les mécanismes
57 de recherche de l'admin."""
58 search = kwargs.pop('admin_search', None)
59 search_titre = kwargs.pop('admin_search_titre', None)
60 search_sujet = kwargs.pop('admin_search_sujet', None)
61 search_description = kwargs.pop('admin_search_description', None)
62 search_auteur = kwargs.pop('admin_search_auteur', None)
63
64 if search:
65 qs = self
66 search_all = not (search_titre or search_description or
67 search_sujet or search_auteur)
68 fields = []
69 if search_titre or search_all:
70 fields += ['title', 'alt_title']
71 if search_description or search_all:
72 fields += ['description', 'abstract']
73 if search_sujet or search_all:
74 fields += ['subject']
75 if search_auteur or search_all:
76 fields += ['creator', 'contributor']
77
78 for bit in search.split():
79 or_queries = [Q(**{field + '__icontains': bit})
80 for field in fields]
81 qs = qs.filter(reduce(operator.or_, or_queries))
82
83 if args or kwargs:
84 qs = super(RecordAdminQuerySet, qs).filter(*args, **kwargs)
85 return qs
86 else:
87 return super(RecordAdminQuerySet, self).filter(*args, **kwargs)
88
89
90 class RecordAdmin(admin.ModelAdmin):
91 fields = ('server', 'title', 'creator', 'description', 'modified',
92 'identifier', 'uri', 'source', 'contributor', 'publisher',
93 'type', 'format', 'language', 'categorie', 'disciplines',
94 'thematiques', 'pays', 'regions', 'validated')
95
96 list_filter = (
97 'validated', 'server', ('listsets', ListSetListFilter), 'pays',
98 AllRegionsListFilter, 'disciplines', 'thematiques', 'categorie'
99 )
100 list_display = (
101 'title', 'subject', 'uri_display', 'creator', 'categorie',
102 'est_complet', 'validated'
103 )
104 list_editable = ('validated',)
105 list_per_page = 25
106
107 actions = ('assigner_pays', 'assigner_regions', 'assigner_disciplines',
108 'assigner_thematiques', 'assigner_categorie')
109
110 def __init__(self, *args, **kwargs):
111 """
112 Surcharge l'initialisation pour définir les champs de recherche
113 dynamiquement, et les champs en lecture seule uniquement.
114 """
115 self.readonly_fields = META.keys()
116 self.readonly_fields.append('listsets')
117 super(RecordAdmin, self).__init__(*args, **kwargs)
118
119 def queryset(self, request):
120 return RecordAdminQuerySet(Record)
121
122 # Présentation de l'information
123
124 def est_complet(self, obj):
125 v = obj.est_complet()
126 return '<img src="/admin_media/img/admin/icon-%s.gif" alt="%d"/>' % (
127 ('no', 'yes')[v], v
128 )
129 est_complet.allow_tags = True
130 est_complet.short_description = u'complet'
131
132 def uri_display(self, obj):
133 return "<a target='_blank' href='%s'>%s</a>" % (obj.uri, obj.uri)
134 uri_display.allow_tags = True
135 uri_display.short_description = u'lien'
136
137 def description_display(self, obj):
138 max = 140
139 if obj.description is not None and len(obj.description) > max:
140 return "%s..." % obj.description[:max]
141 else:
142 return obj.description
143 description_display.short_description = u'description'
144
145 # Actions
146
147 def assigner_pays(self, request, queryset):
148 selected = queryset.values_list('id', flat=True)
149 selected = ",".join("%s" % val for val in selected)
150 return HttpResponseRedirect(
151 "/admin/assigner_%s?ids=%s" % ('pays', selected)
152 )
153 assigner_pays.short_description = u'Assigner des pays'
154
155 def assigner_regions(self, request, queryset):
156 selected = queryset.values_list('id', flat=True)
157 selected = ",".join("%s" % val for val in selected)
158 return HttpResponseRedirect(url(
159 'assigner_regions',
160 kwargs={'app_name': 'savoirs', 'model_name': 'record'}
161 ) + '?ids=' + selected)
162 assigner_regions.short_description = u'Assigner des régions'
163
164 def assigner_thematiques(self, request, queryset):
165 selected = queryset.values_list('id', flat=True)
166 selected = ",".join("%s" % val for val in selected)
167 return HttpResponseRedirect(
168 "/admin/assigner_%s?ids=%s" % ('thematiques', selected)
169 )
170 assigner_thematiques.short_description = u'Assigner des thématiques'
171
172 def assigner_disciplines(self, request, queryset):
173 selected = queryset.values_list('id', flat=True)
174 selected = ",".join("%s" % val for val in selected)
175 return HttpResponseRedirect(url(
176 'assigner_disciplines',
177 kwargs={'app_name': 'savoirs', 'model_name': 'record'}
178 ) + '?ids=' + selected)
179 assigner_disciplines.short_description = u'Assigner des disciplines'
180
181 def assigner_categorie(self, request, queryset):
182 selected = queryset.values_list('id', flat=True)
183 selected = ",".join("%s" % val for val in selected)
184 return HttpResponseRedirect(
185 "/admin/assigner_%s?ids=%s" % ('categorie', selected)
186 )
187 assigner_categorie.short_description = u'Assigner une catégorie'
188
189 admin.site.register(Record, RecordAdmin)
190
191
192 class RecordEditAdmin(RecordAdmin):
193 list_editable = ()
194 change_list_template = "admin/savoirs/record/change_list.html"
195
196 def __init__(self, model, admin_site):
197 super(RecordEditAdmin, self).__init__(model, admin_site)
198 self.readonly_fields = self.fields
199
200 def get_actions(self, request):
201 actions = super(RecordEditAdmin, self).get_actions(request)
202 del actions['assigner_pays']
203 del actions['assigner_thematiques']
204 del actions['assigner_categorie']
205
206 return actions
207
208 def assigner_disciplines(self, request, queryset):
209 selected = queryset.values_list('id', flat=True)
210 selected = ",".join("%s" % val for val in selected)
211 return HttpResponseRedirect(url(
212 'assigner_disciplines',
213 kwargs={'app_name': 'savoirs', 'model_name': 'recordedit'}
214 ) + '?ids=' + selected)
215 assigner_disciplines.short_description = u'Assigner des disciplines'
216
217 def assigner_regions(self, request, queryset):
218 selected = queryset.values_list('id', flat=True)
219 selected = ",".join("%s" % val for val in selected)
220 return HttpResponseRedirect(url(
221 'assigner_regions',
222 kwargs={'app_name': 'savoirs', 'model_name': 'recordedit'}
223 ) + '?ids=' + selected)
224 assigner_regions.short_description = u'Assigner des régions'
225
226 admin.site.register(RecordEdit, RecordEditAdmin)
227
228
229 class ListSetAdmin(admin.ModelAdmin):
230 fields = ('spec', 'name', 'server', 'validated')
231 list_display = fields
232 readonly_fields = ('spec', 'name', 'server')
233 list_filter = ('server',)
234
235 admin.site.register(ListSet, ListSetAdmin)
236
237
238 class HarvestLogAdmin(admin.ModelAdmin):
239 fields = ('context', 'name', 'added', 'updated', 'processed', 'record')
240 list_display = fields + ('date',)
241 admin_order_fields = ('date',)
242 search_fields = (
243 'context', 'name', 'added', 'updated', 'processed', 'record__title'
244 )
245 readonly_fields = fields
246 list_filter = ('context',)
247
248 admin.site.register(HarvestLog, HarvestLogAdmin)
249
250
251 class ProfileInline(admin.TabularInline):
252 model = Profile
253 fk_name = 'user'
254 max_num = 1
255
256
257 class UserProfileAdmin(UserAdmin):
258 inlines = (ProfileInline,)
259
260 admin.site.unregister(User)
261 admin.site.register(User, UserProfileAdmin)
262
263
264 class ActualiteAdmin(admin.ModelAdmin):
265 list_filter = ('visible', 'disciplines', AllRegionsListFilter)
266 list_display = ('titre', 'source', 'date', 'visible')
267 list_editable = ('visible',)
268 actions = (
269 'rendre_visible', 'rendre_invisible', 'assigner_regions',
270 'assigner_disciplines'
271 )
272
273 def queryset(self, request):
274 return Actualite.all_objects.get_query_set()
275
276 # actions
277 def rendre_visible(self, request, queryset):
278 selected = queryset.values_list('id', flat=True)
279 selected = ",".join("%s" % val for val in selected)
280 return HttpResponseRedirect(
281 "/admin/confirmation/%s/%s?ids=%s" %
282 ('actualite', 'visible', selected)
283 )
284
285 def rendre_invisible(self, request, queryset):
286 selected = queryset.values_list('id', flat=True)
287 selected = ",".join("%s" % val for val in selected)
288 return HttpResponseRedirect(
289 "/admin/confirmation/%s/%s?ids=%s" %
290 ('actualite', 'invisible', selected)
291 )
292
293 def assigner_regions(self, request, queryset):
294 selected = queryset.values_list('id', flat=True)
295 selected = ",".join("%s" % val for val in selected)
296 return HttpResponseRedirect(url(
297 'assigner_regions',
298 kwargs={'app_name': 'savoirs', 'model_name': 'actualite'}
299 ) + '?ids=' + selected)
300 assigner_regions.short_description = u'Assigner des régions'
301
302 def assigner_disciplines(self, request, queryset):
303 selected = queryset.values_list('id', flat=True)
304 selected = ",".join("%s" % val for val in selected)
305 return HttpResponseRedirect(url(
306 'assigner_disciplines',
307 kwargs={'app_name': 'savoirs', 'model_name': 'actualite'}
308 ) + '?ids=' + selected)
309 assigner_disciplines.short_description = u'Assigner des disciplines'
310
311 admin.site.register(Actualite, ActualiteAdmin)
312
313
314 class ActualiteVoirAdmin(ActualiteAdmin):
315
316 actions = None
317 list_editable = ()
318 fields = (
319 'titre', 'texte', 'url', 'date', 'visible', 'ancienid', 'source',
320 'disciplines', 'regions'
321 )
322
323 def __init__(self, model, admin_site):
324 super(ActualiteVoirAdmin, self).__init__(model, admin_site)
325 self.readonly_fields = self.fields
326
327
328 admin.site.register(ActualiteVoir, ActualiteVoirAdmin)
329
330
331 class SourceActualiteAdmin(admin.ModelAdmin):
332 actions = ('update_sources',)
333 list_display = ('nom', 'url', 'type')
334 list_filter = ('type',)
335
336 def update_sources(self, request, queryset):
337 for source in queryset:
338 source.update()
339 update_sources.short_description = u'Mettre à jour les fils sélectionnés'
340
341 admin.site.register(SourceActualite, SourceActualiteAdmin)
342
343
344 class EvenementAdminForm(forms.ModelForm):
345 mots_cles = forms.CharField(label='Mots-clés', required=False)
346
347 class Meta:
348 model = Evenement
349
350 def clean(self,):
351 cleaned_data = self.cleaned_data
352 debut = cleaned_data.get("debut")
353 fin = cleaned_data.get("fin")
354 if debut and fin and debut > fin:
355 raise forms.ValidationError(
356 "La date de fin ne doit pas être antérieure à la date de début"
357 )
358 return cleaned_data
359
360
361 class EvenementAdmin(admin.ModelAdmin):
362 form = EvenementAdminForm
363 list_filter = (
364 'approuve', AllRegionsListFilter, 'discipline', 'discipline_secondaire'
365 )
366 list_display = ('titre', 'debut', 'fin', 'ville', 'pays', 'approuve')
367 fields = ('titre', 'discipline', 'discipline_secondaire', 'mots_cles',
368 'type', 'adresse', 'ville', 'pays', 'fuseau', 'debut', 'fin',
369 'piece_jointe', 'regions', 'description', 'prenom', 'nom',
370 'courriel', 'url', 'approuve')
371 actions = ('assigner_regions', 'assigner_disciplines')
372
373 def queryset(self, request):
374 return Evenement.all_objects.get_query_set()
375
376 def assigner_regions(self, request, queryset):
377 selected = queryset.values_list('id', flat=True)
378 selected = ",".join("%s" % val for val in selected)
379 return HttpResponseRedirect(url(
380 'assigner_regions',
381 kwargs={'app_name': 'savoirs', 'model_name': 'evenement'}
382 ) + '?ids=' + selected)
383 assigner_regions.short_description = u'Assigner des régions'
384
385 def assigner_disciplines(self, request, queryset):
386 selected = queryset.values_list('id', flat=True)
387 selected = ",".join("%s" % val for val in selected)
388 return HttpResponseRedirect(url(
389 'assigner_disciplines',
390 kwargs={'app_name': 'savoirs', 'model_name': 'evenement'}
391 ) + '?ids=' + selected)
392 assigner_disciplines.short_description = u'Assigner des disciplines'
393
394 admin.site.register(Evenement, EvenementAdmin)
395
396
397 class EvenementVoirAdmin(EvenementAdmin):
398
399 actions = None
400 list_editable = ()
401
402 def __init__(self, model, admin_site):
403 super(EvenementVoirAdmin, self).__init__(model, admin_site)
404 self.readonly_fields = self.fields
405
406 admin.site.register(EvenementVoir, EvenementVoirAdmin)
407
408
409 class PageStatiqueAdmin(admin.ModelAdmin):
410 list_display = ('titre', 'id')
411 list_display_links = ('titre', 'id')
412
413 class Media:
414 js = ('js/tiny_mce/tiny_mce.js', 'js/tiny_mce_textareas.js')
415
416 admin.site.register(PageStatique, PageStatiqueAdmin)
417
418
419 admin.site.register(RecordCategorie)