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