from django.conf.urls import url from django.db.models import TextField from django.forms import ModelForm, ModelMultipleChoiceField, TextInput from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404 from django.urls import reverse from django.utils.html import format_html from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ from reversion.admin import VersionAdmin from django_ace import AceWidget from judge.models import Judge, Problem from judge.widgets import AdminHeavySelect2MultipleWidget, AdminPagedownWidget class LanguageForm(ModelForm): problems = ModelMultipleChoiceField( label=_('Disallowed problems'), queryset=Problem.objects.all(), required=False, help_text=_('These problems are NOT allowed to be submitted in this language'), widget=AdminHeavySelect2MultipleWidget(data_view='problem_select2')) class Meta: if AdminPagedownWidget is not None: widgets = {'description': AdminPagedownWidget} class LanguageAdmin(VersionAdmin): fields = ('key', 'name', 'short_name', 'common_name', 'ace', 'pygments', 'info', 'description', 'template', 'problems') list_display = ('key', 'name', 'common_name', 'info') form = LanguageForm def save_model(self, request, obj, form, change): super(LanguageAdmin, self).save_model(request, obj, form, change) obj.problem_set.set(Problem.objects.exclude(id__in=form.cleaned_data['problems'].values('id'))) def get_form(self, request, obj=None, **kwargs): self.form.base_fields['problems'].initial = \ Problem.objects.exclude(id__in=obj.problem_set.values('id')).values_list('pk', flat=True) if obj else [] form = super(LanguageAdmin, self).get_form(request, obj, **kwargs) if obj is not None: form.base_fields['template'].widget = AceWidget(obj.ace, request.profile.ace_theme) return form class GenerateKeyTextInput(TextInput): def render(self, name, value, attrs=None, renderer=None): text = super(TextInput, self).render(name, value, attrs) return mark_safe(text + format_html( '''\ Regenerate ''', name)) class JudgeAdminForm(ModelForm): class Meta: widgets = {'auth_key': GenerateKeyTextInput} if AdminPagedownWidget is not None: widgets['description'] = AdminPagedownWidget class JudgeAdmin(VersionAdmin): form = JudgeAdminForm readonly_fields = ('created', 'online', 'start_time', 'ping', 'load', 'last_ip', 'runtimes', 'problems') fieldsets = ( (None, {'fields': ('name', 'auth_key', 'is_blocked')}), (_('Description'), {'fields': ('description',)}), (_('Information'), {'fields': ('created', 'online', 'last_ip', 'start_time', 'ping', 'load')}), (_('Capabilities'), {'fields': ('runtimes', 'problems')}), ) list_display = ('name', 'online', 'start_time', 'ping', 'load', 'last_ip') ordering = ['-online', 'name'] def get_urls(self): return ([url(r'^(\d+)/disconnect/$', self.disconnect_view, name='judge_judge_disconnect'), url(r'^(\d+)/terminate/$', self.terminate_view, name='judge_judge_terminate')] + super(JudgeAdmin, self).get_urls()) def disconnect_judge(self, id, force=False): judge = get_object_or_404(Judge, id=id) judge.disconnect(force=force) return HttpResponseRedirect(reverse('admin:judge_judge_changelist')) def disconnect_view(self, request, id): return self.disconnect_judge(id) def terminate_view(self, request, id): return self.disconnect_judge(id, force=True) def get_readonly_fields(self, request, obj=None): if obj is not None and obj.online: return self.readonly_fields + ('name',) return self.readonly_fields def has_delete_permission(self, request, obj=None): result = super(JudgeAdmin, self).has_delete_permission(request, obj) if result and obj is not None: return not obj.online return result if AdminPagedownWidget is not None: formfield_overrides = { TextField: {'widget': AdminPagedownWidget}, }