zoo/zoo/zoo_data/admin.py

198 lines
6.4 KiB
Python

# zoo - versatile objects management
# Copyright (C) 2016 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.contrib import admin
from django.forms import ModelForm
from django.apps import apps
from django.utils.safestring import mark_safe
from rangefilter.filter import DateTimeRangeFilter
from .models import Transaction, Entity, Relation, Log, Job
from .widgets import JSONEditor
class JSONEditorForm(ModelForm):
def __init__(self, *args, **kwargs):
super(JSONEditorForm, self).__init__(*args, **kwargs)
if self.instance and hasattr(self.instance, 'schema'):
for key in self.fields:
if key == 'content':
self.fields[key].widget = JSONEditor(schema=self.instance.schema.schema)
class JSONEditorMixin(object):
json_fields = ()
form = JSONEditorForm
def get_form(self, request, obj=None, **kwargs):
widgets = kwargs.setdefault('widgets', {})
for field in self.json_fields:
if obj and hasattr(obj, 'schema'):
schema = obj.schema.schema
else:
schema = {}
widgets[field] = JSONEditor(schema=schema)
return super(JSONEditorMixin, self).get_form(request, obj=obj, **kwargs)
class LeftRelationInlineAdmin(JSONEditorMixin, admin.TabularInline):
fk_name = 'left'
fields = ['right', 'schema', 'meta', 'content']
raw_id_fields = ['left', 'right']
model = Relation
extra = 0
json_fields = ['content']
class RightRelationInlineAdmin(JSONEditorMixin, admin.TabularInline):
fk_name = 'right'
fields = ['left', 'schema', 'meta', 'content']
raw_id_fields = ['left', 'right']
model = Relation
extra = 0
json_fields = ['content']
class LogInlineAdmin(JSONEditorMixin, admin.TabularInline):
model = Log
fields = ['timestamp', 'transaction', 'content']
readonly_fields = ['timestamp', 'transaction']
extra = 0
can_delete = False
json_fields = ['content']
class DataAdmin(admin.ModelAdmin):
list_display = ['id', 'schema', 'name', 'created', 'created_ts',
'modified', 'modified_ts', 'deleted', 'deleted_ts']
list_filter = ['schema']
list_select_related = ('schema',)
raw_id_fields = ['modified', 'created', 'deleted']
def name(self, instance):
return instance.schema.make_caption(instance)
def created_ts(self, instance):
return instance.created and instance.created.created
def modified_ts(self, instance):
return instance.modified and instance.modified.created
def deleted_ts(self, instance):
return instance.deleted and instance.deleted.created
def get_form(self, request, obj=None, **kwargs):
if obj and obj.schema:
kwargs['widgets'] = {
'meta': JSONEditor(),
'content': JSONEditor(schema=obj.schema.schema),
}
return super(DataAdmin, self).get_form(request, obj=obj, **kwargs)
class EntityAdmin(DataAdmin):
inlines = [LeftRelationInlineAdmin, RightRelationInlineAdmin, LogInlineAdmin]
def get_actions(self, request):
actions = super(EntityAdmin, self).get_actions(request)
from django.apps import apps
for app_config in apps.get_app_configs():
if hasattr(app_config, 'get_entity_actions'):
actions.update(app_config.get_entity_actions())
return actions
def get_urls(self):
urls = super(EntityAdmin, self).get_urls()
cls_name = self.__class__.__name__.lower()
for app in apps.get_app_configs():
name = 'get_%s_urls' % cls_name
if hasattr(app, name):
urls = getattr(app, name)(self) + urls
return urls
class RelationAdmin(DataAdmin):
raw_id_fields = DataAdmin.raw_id_fields + ['left', 'right']
class JobAdmin(JSONEditorMixin, admin.ModelAdmin):
list_display = ['id', 'created', 'modified', 'state', 'transaction_id', 'classpath']
raw_id_fields = ['transaction']
list_filter = [
'state',
('created', DateTimeRangeFilter),
('modified', DateTimeRangeFilter),
]
date_hierarchy = 'created'
actions = ['make_todo', 'make_unrecoverable_error', 'do']
readonly_fields = ['_description']
json_fields = ['content']
def _description(self, instance):
return mark_safe(instance.description)
def classpath(self, instance):
return instance.content.get('$classpath')
def make_todo(self, request, queryset):
queryset.set_todo()
def make_unrecoverable_error(self, request, queryset):
queryset.set_unrecoverable_error()
def do(self, request, queryset):
for job in queryset:
job.do()
def get_list_filter(self, request):
list_filter = super(JobAdmin, self).get_list_filter(request)
from django.apps import apps
for app_config in apps.get_app_configs():
if hasattr(app_config, 'get_job_list_filter'):
list_filter = app_config.get_job_list_filter() + list_filter
return list_filter
class JobInlineAdmin(JSONEditorMixin, admin.TabularInline):
model = Job
fields = ['created', 'state', 'transaction', 'content']
readonly_fields = ['created', 'transaction']
extra = 0
can_delete = False
json_fields = ['content']
class TransactionAdmin(admin.ModelAdmin):
date_hierarchy = 'created'
list_display = ['id', 'created']
inlines = [LogInlineAdmin, JobInlineAdmin]
def get_form(self, request, obj=None, **kwargs):
kwargs['widgets'] = {
'meta': JSONEditor(),
'content': JSONEditor(),
}
return super(TransactionAdmin, self).get_form(request, obj=obj, **kwargs)
admin.site.register(Transaction, TransactionAdmin)
admin.site.register(Entity, EntityAdmin)
admin.site.register(Relation, RelationAdmin)
admin.site.register(Job, JobAdmin)