198 lines
6.4 KiB
Python
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)
|