Ajustement de la config de sphinx à un nouveau modèle de déploiement dans lequel
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / admin.py
CommitLineData
6ef8ead4 1# -*- encoding: utf-8 -*-
29e2a8fd 2import operator
23b5b3d5 3import re
264a3210 4from django.core.urlresolvers import reverse as url
6a6986bc 5from django.db import models
29e2a8fd 6from django.db.models import Q
5212238e 7from django.db.models.query import QuerySet
6ef8ead4 8from django.contrib import admin
6d885e0c 9from django.contrib.auth.admin import UserAdmin
10from django.contrib.auth.models import User
6a6986bc 11from django.contrib.admin.filterspecs import RelatedFilterSpec, FilterSpec
23b5b3d5 12from django.utils.safestring import mark_safe
6a6986bc 13from django.utils.translation import ugettext as _
14from django.utils.encoding import smart_unicode, iri_to_uri
e3c3296e 15from django.http import HttpResponseRedirect
23b5b3d5 16from savoirs.globals import META
5212238e 17from savoirs.models import SourceActualite, Actualite, Discipline, Evenement, Record, ListSet, HarvestLog, Profile
6ef8ead4 18
79c398f6 19admin.site.register(SourceActualite)
6ef8ead4 20
6a6986bc 21class ListSetFilterSpec(RelatedFilterSpec):
22 """
23 Filtre custom automatiquement lié à un field nommé 'listsets'. Il a pour but de s'afficher
24 lorsqu'un server a déjà été présélectionné. Dans ce cas, il affiche une liste qui contient les
25 listsets de ce server.
26 """
27 def __init__(self, f, request, params, model, model_admin):
28 super(ListSetFilterSpec, self).__init__(f, request, params, model, model_admin)
29 self.server_name = request.GET.get('server', None)
30
31 def has_output(self):
32 return self.server_name is not None
33
6a6986bc 34FilterSpec.filter_specs.insert(0, (lambda f: f.name == 'listsets', ListSetFilterSpec))
35
23b5b3d5 36# Ces deux classes permettent d'implémenter la possibilité d'avoir un champs readonly_fields
37# dans l.administration.
38# Ce champs est devenu natif à partir de la version 1.2
39# http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields
40from django import forms
41class ReadOnlyWidget(forms.Widget):
42 def __init__(self, original_value, display_value):
43 self.original_value = original_value
44 self.display_value = display_value
45
46 super(ReadOnlyWidget, self).__init__()
47
48 def render(self, name, value, attrs=None):
49 if self.display_value is not None:
50 output = self.display_value
51 else:
52 output = unicode(self.original_value)
53
d972b61d 54 # pour les relations
55 try:
56 output = ", ".join([ls.name for ls in self.original_value.get_query_set()])
57 except:
58 pass
59
23b5b3d5 60 is_url = re.match('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', output)
61 if is_url:
62 output = "<a target='_blank' href='%s'>%s</a>" % (output, output)
d972b61d 63
23b5b3d5 64 return mark_safe(output)
65
66 def value_from_datadict(self, data, files, name):
67 return self.original_value
68
69class ReadOnlyAdminFields(object):
70 def get_form(self, request, obj=None):
71 form = super(ReadOnlyAdminFields, self).get_form(request, obj)
72
73 if hasattr(self, 'readonly_fields'):
74 for field_name in self.readonly_fields:
75 if field_name in form.base_fields:
76
77 if hasattr(obj, 'get_%s_display' % field_name):
78 display_value = getattr(obj, 'get_%s_display' % field_name)()
79 else:
80 display_value = None
81
82 form.base_fields[field_name].widget = ReadOnlyWidget(getattr(obj, field_name, ''), display_value)
83 form.base_fields[field_name].required = False
84 return form
85
5212238e
EMS
86class RecordAdminQuerySet(QuerySet):
87
88 def filter(self, *args, **kwargs):
89 """Gère des filtres supplémentaires pour l'admin.
90
91 C'est la seule façon que j'ai trouvée de contourner les mécanismes
92 de recherche de l'admin."""
93 search = kwargs.pop('admin_search', None)
94 search_titre = kwargs.pop('admin_search_titre', None)
95 search_sujet = kwargs.pop('admin_search_sujet', None)
96 search_description = kwargs.pop('admin_search_description', None)
97 search_auteur = kwargs.pop('admin_search_auteur', None)
98
99 if search:
100 qs = self
101 search_all = not (search_titre or search_description or search_sujet or search_auteur)
102 fields = []
103 if search_titre or search_all:
104 fields += ['title', 'alt_title']
105 if search_description or search_all:
106 fields += ['description', 'abstract']
107 if search_sujet or search_all:
108 fields += ['subject']
109 if search_auteur or search_all:
110 fields += ['creator', 'contributor']
111
112 for bit in search.split():
113 or_queries = [Q(**{field + '__icontains': bit}) for field in fields]
114 qs = qs.filter(reduce(operator.or_, or_queries))
115
116 if args or kwargs:
117 qs = super(RecordAdminQuerySet, qs).filter(*args, **kwargs)
118 return qs
119 else:
120 return super(RecordAdminQuerySet, self).filter(*args, **kwargs)
23b5b3d5 121
122class RecordAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
a5f76eb4
EMS
123 fields = ['server', 'title', 'creator', 'description', 'modified',
124 'identifier', 'uri', 'source', 'contributor', 'publisher',
125 'type', 'format', 'language', 'disciplines', 'thematiques',
126 'pays', 'regions', 'validated']
23b5b3d5 127
23b5b3d5 128 readonly_fields = []
da9020f3 129
a5f76eb4
EMS
130 list_filter = ('validated', 'server', 'listsets', 'pays', 'regions',
131 'disciplines', 'thematiques')
18dbd2cf
EMS
132 list_display = ('title', 'subject', 'uri_display', 'creator',
133 'est_complet', 'validated',)
134 list_editable = ('validated',)
135 list_per_page = 25
136
137 actions = ['assigner_pays', 'assigner_regions', 'assigner_disciplines',
e3c3296e 138 'assigner_thematiques']
da9020f3 139
23b5b3d5 140 def __init__(self, *args, **kwargs):
141 """Surcharge l'initialisation pour définir les champs de recherche dynamiquement,
142 et les champs en lecture seule uniquement."""
23b5b3d5 143 self.readonly_fields = META.keys()
d972b61d 144 self.readonly_fields.append('listsets')
23b5b3d5 145 super(RecordAdmin, self).__init__(*args, **kwargs)
6d885e0c 146
29e2a8fd 147 def queryset(self, request):
5212238e 148 return RecordAdminQuerySet(Record)
77b0fac0
EMS
149
150 # Présentation de l'information
18dbd2cf 151
6d885e0c 152 def est_complet(self, obj):
6d885e0c 153 v = obj.est_complet()
154 return '<img src="/admin_media/img/admin/icon-%s.gif" alt="%d"/>' % (('no','yes')[v], v)
155 est_complet.allow_tags = True
18dbd2cf 156 est_complet.short_description = u'complet'
23b5b3d5 157
18dbd2cf 158 def uri_display(self, obj):
da9020f3 159 return "<a target='_blank' href='%s'>%s</a>" % (obj.uri, obj.uri)
18dbd2cf
EMS
160 uri_display.allow_tags = True
161 uri_display.short_description = u'lien'
da9020f3 162
18dbd2cf 163 def description_display(self, obj):
23b5b3d5 164 max = 140
165 if obj.description is not None and len(obj.description) > max:
166 return "%s..." % obj.description[:max]
167 else:
168 return obj.description
18dbd2cf 169 description_display.short_description = u'description'
da9020f3 170
18dbd2cf 171 # Actions
2be148fe 172
e3c3296e 173 def assigner_pays(self, request, queryset):
174 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
175 return HttpResponseRedirect("/admin/assigner_%s?ids=%s" % ('pays', ",".join(selected)))
18dbd2cf 176 assigner_pays.short_description = u'Assigner des pays'
e3c3296e 177
178 def assigner_regions(self, request, queryset):
179 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
264a3210
EMS
180 return HttpResponseRedirect(url('assigner_regions', kwargs=dict(app_name='savoirs', model_name='record')) + '?ids=' + ','.join(selected))
181 assigner_regions.short_description = u'Assigner des régions'
e3c3296e 182
183 def assigner_thematiques(self, request, queryset):
184 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
185 return HttpResponseRedirect("/admin/assigner_%s?ids=%s" % ('thematiques', ",".join(selected)))
18dbd2cf 186 assigner_thematiques.short_description = u'Assigner des thématiques'
e3c3296e 187
188 def assigner_disciplines(self, request, queryset):
189 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
264a3210
EMS
190 return HttpResponseRedirect(url('assigner_disciplines', kwargs=dict(app_name='savoirs', model_name='record')) + '?ids=' + ','.join(selected))
191 assigner_disciplines.short_description = u'Assigner des disciplines'
da9020f3 192admin.site.register(Record, RecordAdmin)
193
d972b61d 194class ListSetAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
9eda5d6c 195 fields = ['spec', 'name', 'server', 'validated' ]
d972b61d 196 list_display = fields
197 readonly_fields = ['spec', 'name', 'server',]
198 list_filter = ('server',)
199
200admin.site.register(ListSet, ListSetAdmin)
201
23b5b3d5 202class HarvestLogAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
a85ba76e 203 fields = ['context', 'name', 'added', 'updated', 'processed', 'record']
23b5b3d5 204 list_display = fields + ['date']
205 admin_order_fields = ['date']
206 search_fields = fields
207 readonly_fields = fields
208 list_filter = ('context',)
209
210admin.site.register(HarvestLog, HarvestLogAdmin)
6d885e0c 211
212class ProfileInline(admin.TabularInline):
213 model = Profile
214 fk_name = 'user'
215 max_num = 1
216
217class UserProfileAdmin(UserAdmin):
218 inlines = [ProfileInline, ]
219
220admin.site.unregister(User)
221admin.site.register(User, UserProfileAdmin)
222
f554ef70 223class ActualiteAdmin(admin.ModelAdmin):
a5f76eb4 224 list_filter = ('visible', 'disciplines', 'regions')
ccbc4363 225 list_display = ('titre', 'source', 'date', 'visible')
264a3210 226 actions = ['rendre_visible', 'rendre_invisible', 'assigner_regions', 'assigner_disciplines']
f554ef70 227
29e2a8fd
EMS
228 def queryset(self, request):
229 return Actualite.all_objects.get_query_set()
230
f554ef70 231 # actions
232 def rendre_visible(self, request, queryset):
233 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
234 return HttpResponseRedirect("/admin/confirmation/%s/%s?ids=%s" % ('actualite', 'visible', ",".join(selected)))
235
236 def rendre_invisible(self, request, queryset):
237 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
238 return HttpResponseRedirect("/admin/confirmation/%s/%s?ids=%s" % ('actualite', 'invisible', ",".join(selected)))
239
264a3210
EMS
240 def assigner_regions(self, request, queryset):
241 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
242 return HttpResponseRedirect(url('assigner_regions', kwargs=dict(app_name='savoirs', model_name='actualite')) + '?ids=' + ','.join(selected))
243 assigner_regions.short_description = u'Assigner des régions'
244
245 def assigner_disciplines(self, request, queryset):
246 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
247 return HttpResponseRedirect(url('assigner_disciplines', kwargs=dict(app_name='savoirs', model_name='actualite')) + '?ids=' + ','.join(selected))
248 assigner_disciplines.short_description = u'Assigner des disciplines'
249
f554ef70 250admin.site.register(Actualite, ActualiteAdmin)
b7a741ad 251
252
73309469 253class EvenementAdminForm(forms.ModelForm):
86983865
EMS
254 mots_cles = forms.CharField(label='Mots-clés', required=False)
255 lieu = forms.CharField(label='Lieu', required=False)
256
73309469 257 class Meta:
258 model = Evenement
259
260 def clean(self,):
261 cleaned_data = self.cleaned_data
262 debut = cleaned_data.get("debut")
263 fin = cleaned_data.get("fin")
7495bc13 264 if debut and fin and debut > fin:
73309469 265 raise forms.ValidationError("La date de fin ne doit pas être antérieure à la date de début")
266 return cleaned_data
267
b7a741ad 268class EvenementAdmin(admin.ModelAdmin):
73309469 269 form = EvenementAdminForm
a5f76eb4 270 list_filter = ('approuve', 'regions', 'discipline', 'discipline_secondaire')
b7a741ad 271 list_display = ('titre', 'debut', 'fin', 'lieu', 'approuve')
264a3210 272 fields = ['titre', 'discipline', 'discipline_secondaire', 'mots_cles',
74b087e5 273 'type', 'fuseau', 'debut', 'fin', 'lieu', 'piece_jointe', 'regions',
264a3210
EMS
274 'description', 'contact', 'url', 'approuve']
275 actions = ['assigner_regions', 'assigner_disciplines']
276
29e2a8fd
EMS
277 def queryset(self, request):
278 return Evenement.all_objects.get_query_set()
279
264a3210
EMS
280 def assigner_regions(self, request, queryset):
281 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
282 return HttpResponseRedirect(url('assigner_regions', kwargs=dict(app_name='savoirs', model_name='evenement')) + '?ids=' + ','.join(selected))
283 assigner_regions.short_description = u'Assigner des régions'
284
285 def assigner_disciplines(self, request, queryset):
286 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
287 return HttpResponseRedirect(url('assigner_disciplines', kwargs=dict(app_name='savoirs', model_name='evenement')) + '?ids=' + ','.join(selected))
288 assigner_disciplines.short_description = u'Assigner des disciplines'
b7a741ad 289
290admin.site.register(Evenement, EvenementAdmin)
291
292
293