Add language template

This commit is contained in:
cuom1999 2022-06-12 14:57:46 +07:00
parent 0b6031eef7
commit 3dfd3a5dab
8 changed files with 129 additions and 16 deletions

View file

@ -77,15 +77,17 @@
mode = widget.getAttribute('data-mode'), mode = widget.getAttribute('data-mode'),
theme = widget.getAttribute('data-theme'), theme = widget.getAttribute('data-theme'),
wordwrap = widget.getAttribute('data-wordwrap'), wordwrap = widget.getAttribute('data-wordwrap'),
toolbar = prev(widget), toolbar = prev(widget);
main_block = toolbar.parentNode; var main_block = div.parentNode.parentNode;
if (toolbar != null) {
// Toolbar maximize/minimize button // Toolbar maximize/minimize button
var min_max = toolbar.getElementsByClassName('django-ace-max_min'); var min_max = toolbar.getElementsByClassName('django-ace-max_min');
min_max[0].onclick = function () { min_max[0].onclick = function () {
minimizeMaximize(widget, main_block, editor); minimizeMaximize(widget, main_block, editor);
return false; return false;
}; };
}
editor.getSession().setValue(textarea.value); editor.getSession().setValue(textarea.value);

View file

@ -19,6 +19,7 @@ class AceWidget(forms.Textarea):
width="100%", width="100%",
height="300px", height="300px",
no_ace_media=False, no_ace_media=False,
toolbar=True,
*args, *args,
**kwargs **kwargs
): ):
@ -28,6 +29,7 @@ class AceWidget(forms.Textarea):
self.width = width self.width = width
self.height = height self.height = height
self.ace_media = not no_ace_media self.ace_media = not no_ace_media
self.toolbar = toolbar
super(AceWidget, self).__init__(*args, **kwargs) super(AceWidget, self).__init__(*args, **kwargs)
@property @property
@ -61,10 +63,14 @@ class AceWidget(forms.Textarea):
html = "<div%s><div></div></div>%s" % (flatatt(ace_attrs), textarea) html = "<div%s><div></div></div>%s" % (flatatt(ace_attrs), textarea)
# add toolbar if self.toolbar:
html = ( toolbar = (
'<div class="django-ace-editor"><div style="width: 100%%" class="django-ace-toolbar">' '<div style="width: {}" class="django-ace-toolbar">'
'<a href="./" class="django-ace-max_min"></a></div>%s</div>' '<a href="./" class="django-ace-max_min"></a>'
) % html "</div>"
).format(self.width)
html = toolbar + html
html = '<div class="django-ace-editor">{}</div>'.format(html)
return mark_safe(html) return mark_safe(html)

View file

@ -9,12 +9,15 @@ from django.forms import ModelForm
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.translation import gettext, gettext_lazy as _, ungettext from django.utils.translation import gettext, gettext_lazy as _, ungettext
from django_ace import AceWidget
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from reversion_compare.admin import CompareVersionAdmin from reversion_compare.admin import CompareVersionAdmin
from judge.models import ( from judge.models import (
LanguageLimit, LanguageLimit,
LanguageTemplate,
Problem, Problem,
ProblemClarification, ProblemClarification,
ProblemTranslation, ProblemTranslation,
@ -100,6 +103,20 @@ class LanguageLimitInline(admin.TabularInline):
form = LanguageLimitInlineForm form = LanguageLimitInlineForm
class LanguageTemplateInlineForm(ModelForm):
class Meta:
widgets = {
"language": AdminSelect2Widget,
"source": AceWidget(width="600px", height="200px", toolbar=False),
}
class LanguageTemplateInline(admin.TabularInline):
model = LanguageTemplate
fields = ("language", "source")
form = LanguageTemplateInlineForm
class ProblemClarificationForm(ModelForm): class ProblemClarificationForm(ModelForm):
class Meta: class Meta:
if HeavyPreviewPageDownWidget is not None: if HeavyPreviewPageDownWidget is not None:
@ -208,6 +225,7 @@ class ProblemAdmin(CompareVersionAdmin):
) )
inlines = [ inlines = [
LanguageLimitInline, LanguageLimitInline,
LanguageTemplateInline,
ProblemClarificationInline, ProblemClarificationInline,
ProblemSolutionInline, ProblemSolutionInline,
ProblemTranslationInline, ProblemTranslationInline,

View file

@ -0,0 +1,54 @@
# Generated by Django 2.2.25 on 2022-06-12 06:59
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("judge", "0125_auto_20220602_1216"),
]
operations = [
migrations.CreateModel(
name="LanguageTemplate",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"source",
models.TextField(max_length=65536, verbose_name="source code"),
),
(
"language",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="judge.Language",
verbose_name="language",
),
),
(
"problem",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="language_templates",
to="judge.Problem",
verbose_name="problem",
),
),
],
options={
"verbose_name": "language-specific template",
"verbose_name_plural": "language-specific templates",
"unique_together": {("problem", "language")},
},
),
]

View file

@ -20,6 +20,7 @@ from judge.models.interface import BlogPost, MiscConfig, NavigationBar, validate
from judge.models.message import PrivateMessage, PrivateMessageThread from judge.models.message import PrivateMessage, PrivateMessageThread
from judge.models.problem import ( from judge.models.problem import (
LanguageLimit, LanguageLimit,
LanguageTemplate,
License, License,
Problem, Problem,
ProblemClarification, ProblemClarification,

View file

@ -639,6 +639,24 @@ class LanguageLimit(models.Model):
verbose_name_plural = _("language-specific resource limits") verbose_name_plural = _("language-specific resource limits")
class LanguageTemplate(models.Model):
problem = models.ForeignKey(
Problem,
verbose_name=_("problem"),
related_name="language_templates",
on_delete=CASCADE,
)
language = models.ForeignKey(
Language, verbose_name=_("language"), on_delete=CASCADE
)
source = models.TextField(verbose_name=_("source code"), max_length=65536)
class Meta:
unique_together = ("problem", "language")
verbose_name = _("language-specific template")
verbose_name_plural = _("language-specific templates")
class Solution(models.Model): class Solution(models.Model):
problem = models.OneToOneField( problem = models.OneToOneField(
Problem, Problem,

View file

@ -53,6 +53,7 @@ from judge.models import (
Organization, Organization,
VolunteerProblemVote, VolunteerProblemVote,
Profile, Profile,
LanguageTemplate,
) )
from judge.pdf_problems import DefaultPdfMaker, HAS_PDF from judge.pdf_problems import DefaultPdfMaker, HAS_PDF
from judge.utils.diggpaginator import DiggPaginator from judge.utils.diggpaginator import DiggPaginator
@ -895,10 +896,21 @@ class ProblemFeed(ProblemList):
class LanguageTemplateAjax(View): class LanguageTemplateAjax(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try: try:
language = get_object_or_404(Language, id=int(request.GET.get("id", 0))) problem = request.GET.get("problem", None)
lang_id = int(request.GET.get("id", 0))
res = None
if problem:
try:
res = LanguageTemplate.objects.get(
language__id=lang_id, problem__id=problem
).source
except ObjectDoesNotExist:
pass
if not res:
res = get_object_or_404(Language, id=lang_id).template
except ValueError: except ValueError:
raise Http404() raise Http404()
return HttpResponse(language.template, content_type="text/plain") return HttpResponse(res, content_type="text/plain")
class RandomProblem(ProblemList): class RandomProblem(ProblemList):
@ -1107,6 +1119,7 @@ def problem_submit(request, problem, submission=None):
"submissions_left": submissions_left, "submissions_left": submissions_left,
"ACE_URL": settings.ACE_URL, "ACE_URL": settings.ACE_URL,
"default_lang": default_lang, "default_lang": default_lang,
"problem_id": problem.id,
}, },
) )

View file

@ -30,7 +30,8 @@
update_submit_area(code); update_submit_area(code);
} else { } else {
$.get('{{ url('language_template_ajax') }}', { $.get('{{ url('language_template_ajax') }}', {
id: lang_id id: lang_id,
problem: {{problem_id}}
}).done(function (template) { }).done(function (template) {
update_submit_area(template); update_submit_area(template);
}); });