from django.contrib import admin
from django.contrib.auth.models import User
from django.forms import ModelForm
from django.urls import NoReverseMatch, reverse, reverse_lazy
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from mptt.admin import DraggableMPTTAdmin
from reversion.admin import VersionAdmin
from reversion_compare.admin import CompareVersionAdmin
from judge.dblock import LockModel
from judge.models import NavigationBar
from judge.widgets import AdminHeavySelect2MultipleWidget, AdminHeavySelect2Widget, HeavyPreviewAdminPageDownWidget
class NavigationBarAdmin(DraggableMPTTAdmin):
list_display = DraggableMPTTAdmin.list_display + ('key', 'linked_path')
fields = ('key', 'label', 'path', 'order', 'regex', 'parent')
list_editable = () # Bug in SortableModelAdmin: 500 without list_editable being set
mptt_level_indent = 20
sortable = 'order'
def __init__(self, *args, **kwargs):
super(NavigationBarAdmin, self).__init__(*args, **kwargs)
self.__save_model_calls = 0
def linked_path(self, obj):
return format_html(u'{0}', obj.path)
linked_path.short_description = _('link path')
def save_model(self, request, obj, form, change):
self.__save_model_calls += 1
return super(NavigationBarAdmin, self).save_model(request, obj, form, change)
def changelist_view(self, request, extra_context=None):
self.__save_model_calls = 0
with NavigationBar.objects.disable_mptt_updates():
result = super(NavigationBarAdmin, self).changelist_view(request, extra_context)
if self.__save_model_calls:
with LockModel(write=(NavigationBar,)):
NavigationBar.objects.rebuild()
return result
class BlogPostForm(ModelForm):
def __init__(self, *args, **kwargs):
super(BlogPostForm, self).__init__(*args, **kwargs)
self.fields['authors'].widget.can_add_related = False
class Meta:
widgets = {
'authors': AdminHeavySelect2MultipleWidget(data_view='profile_select2', attrs={'style': 'width: 100%'}),
'organizations': AdminHeavySelect2MultipleWidget(data_view='organization_select2',
attrs={'style': 'width: 100%'}),
}
if HeavyPreviewAdminPageDownWidget is not None:
widgets['content'] = HeavyPreviewAdminPageDownWidget(preview=reverse_lazy('blog_preview'))
widgets['summary'] = HeavyPreviewAdminPageDownWidget(preview=reverse_lazy('blog_preview'))
class BlogPostAdmin(CompareVersionAdmin):
fieldsets = (
(None, {'fields': ('title', 'slug', 'authors', 'visible', 'sticky', 'publish_on',
'is_organization_private', 'organizations')}),
(_('Content'), {'fields': ('content', 'og_image')}),
(_('Summary'), {'classes': ('collapse',), 'fields': ('summary',)}),
)
prepopulated_fields = {'slug': ('title',)}
list_display = ('id', 'title', 'visible', 'sticky', 'publish_on')
list_display_links = ('id', 'title')
ordering = ('-publish_on',)
form = BlogPostForm
date_hierarchy = 'publish_on'
def has_change_permission(self, request, obj=None):
return (request.user.has_perm('judge.edit_all_post') or
request.user.has_perm('judge.change_blogpost') and (
obj is None or
obj.authors.filter(id=request.profile.id).exists()))
class SolutionForm(ModelForm):
def __init__(self, *args, **kwargs):
super(SolutionForm, self).__init__(*args, **kwargs)
self.fields['authors'].widget.can_add_related = False
class Meta:
widgets = {
'authors': AdminHeavySelect2MultipleWidget(data_view='profile_select2', attrs={'style': 'width: 100%'}),
'problem': AdminHeavySelect2Widget(data_view='problem_select2', attrs={'style': 'width: 250px'}),
}
if HeavyPreviewAdminPageDownWidget is not None:
widgets['content'] = HeavyPreviewAdminPageDownWidget(preview=reverse_lazy('solution_preview'))
class LicenseForm(ModelForm):
class Meta:
if HeavyPreviewAdminPageDownWidget is not None:
widgets = {'text': HeavyPreviewAdminPageDownWidget(preview=reverse_lazy('license_preview'))}
class LicenseAdmin(admin.ModelAdmin):
fields = ('key', 'link', 'name', 'display', 'icon', 'text')
list_display = ('name', 'key')
form = LicenseForm
class UserListFilter(admin.SimpleListFilter):
title = _('user')
parameter_name = 'user'
def lookups(self, request, model_admin):
return User.objects.filter(is_staff=True).values_list('id', 'username')
def queryset(self, request, queryset):
if self.value():
return queryset.filter(user_id=self.value(), user__is_staff=True)
return queryset
class LogEntryAdmin(admin.ModelAdmin):
readonly_fields = ('user', 'content_type', 'object_id', 'object_repr', 'action_flag', 'change_message')
list_display = ('__str__', 'action_time', 'user', 'content_type', 'object_link', 'diff_link')
search_fields = ('object_repr', 'change_message')
list_filter = (UserListFilter, 'content_type')
list_display_links = None
actions = None
def has_add_permission(self, request):
return False
def has_change_permission(self, request, obj=None):
return obj is None and request.user.is_superuser
def has_delete_permission(self, request, obj=None):
return False
def object_link(self, obj):
if obj.is_deletion():
link = obj.object_repr
else:
ct = obj.content_type
try:
link = format_html('{0}', obj.object_repr,
reverse('admin:%s_%s_change' % (ct.app_label, ct.model), args=(obj.object_id,)))
except NoReverseMatch:
link = obj.object_repr
return link
object_link.admin_order_field = 'object_repr'
object_link.short_description = _('object')
def diff_link(self, obj):
if obj.is_deletion():
return None
ct = obj.content_type
try:
url = reverse('admin:%s_%s_history' % (ct.app_label, ct.model), args=(obj.object_id,))
link = format_html('{0}', _('Diff'), url)
except NoReverseMatch:
link = None
return link
diff_link.short_description = _('diff')
def queryset(self, request):
return super().queryset(request).prefetch_related('content_type')