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