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