Add language template
This commit is contained in:
parent
0b6031eef7
commit
3dfd3a5dab
8 changed files with 129 additions and 16 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
54
judge/migrations/0126_languagetemplate.py
Normal file
54
judge/migrations/0126_languagetemplate.py
Normal 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")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue